src/ant/.ant.properties100644 0 0 3322 11224570760 12540 0ustar 0 0 releasenumber=2.1.7 releasedate=2009-07-07 itext.home=../.. itext.src=${itext.home}/src itext.www=${itext.home}/www itext.build=${itext.home}/build itext.lib=${itext.home}/lib itext.jar=${itext.lib}/iText.jar jfreechart.jar=${itext.lib}/jfreechart.jar jcommon.jar=${itext.lib}/jcommon.jar servlet.jar=${itext.lib}/servlet.jar bc.jdk=jdk14 bc.version=138 lib.bcmail=bcmail-${bc.jdk}-${bc.version}.jar lib.bcprov=bcprov-${bc.jdk}-${bc.version}.jar lib.bctsp=bctsp-${bc.jdk}-${bc.version}.jar lib.dom4j=pdf-renderer.jar lib.pdf-renderer=dom4j-1.6.1.jar itext.src.lowagie=${itext.www}/lowagie itext.src.tutorial=${itext.www}/tutorial itext.src.examples=${itext.www}/examples itext.bin=${itext.build}/bin itext.docs=${itext.build}/docs itext.lowagie=${itext.build}/lowagie itext.tutorial=${itext.build}/tutorial itext.examples=${itext.build}/examples itext.webapp=${itext.build}/webapp itext.release=${itext.build}/release itext.downloads=${itext.build}/downloads itext.dist=${itext.release}/dist itext.sf=${itext.release}/sf itext.maven=${itext.release}/maven itext.bin.temp=${itext.build}/bin.temp itext.jnlp=${itext.build}/jnlp itext.rups.src=${itext.src}/rups itext.rups.bin=${itext.build}/bin.rups itext.rups.jar=${itext.lib}/iText-rups.jar itext.toolbox.src=${itext.src}/toolbox itext.toolbox.bin=${itext.build}/bin.toolbox itext.toolbox.jar=${itext.lib}/iText-toolbox.jar itext.rtf.src=${itext.src}/rtf itext.rtf.bin=${itext.build}/bin.rtf itext.rtf.jar=${itext.lib}/iText-rtf.jar itext.keystore.filename=${itext.lib}/.keystore itext.keystore.password=dummypass itext.keystore.alias=itext itext.keystore.storetype=jks itext.keystore.dname=CN=iText Self-Signed Certificate itext.jdk.core=1.4 itext.jdk.rups=1.5 itext.jdk.toolbox=1.5src/ant/.ant.test.properties100644 0 0 627 11000354002 13460 0ustar 0 0 itext.home=.. itext.build=${itext.home}/build itext.lib=${itext.home}/lib junit.jar=${itext.lib}/junit-4.4.jar itext.src.test=${itext.home}/test itext.bin.examples=${itext.build}/bin.examples itext.bin.test=${itext.build}/test itext.bin.data=${itext.build}/test.data itext.reports=${itext.build}/reports itext.rtf.test=${itext.build}/test.rtf itext.jdk.examples=1.4 itext.jdk.test=1.5 src/ant/compile.xml100644 0 0 21223 11213370067 11750 0ustar 0 0 COMPILING AND JARRING THE CODE (compile.xml) ant compile: compiles iText (core) ant compile.rtf: compiles iText RTF ant compile.rups: compiles iText RUPS ant jar: compiles and jars iText ant jar.rtf: compiles and jars iText RTF ant jar.rups: compiles and jars iText RUPS src/ant/pom.xml100644 0 0 6005 11213370067 11074 0ustar 0 0 4.0.0 com.lowagie itext jar iText, a Free Java-PDF library releasenumber iText, a free Java-PDF library http://www.lowagie.com/iText/ iText Questions http://lists.sourceforge.net/lists/listinfo/itext-questions itext-questions@lists.sourceforge.net http://news.gmane.org/gmane.comp.java.lib.itext.general http://www.nabble.com/iText---General-f2701.html http://www.junlu.com/2.html http://sourceforge.net/mailarchive/forum.php?forum_id=3273 http://www.mail-archive.com/itext-questions%40lists.sourceforge.net/ blowagie Bruno Lowagie bruno@lowagie.com http://www.lowagie.com psoares33 Paulo Soares psoares33@users.sourceforge.net hallm Mark Hall hallm@users.sourceforge.net xlv Xavier Le Vourch xlv@users.sourceforge.net Mozilla Public License http://www.mozilla.org/MPL/MPL-1.1.html iText was originally published under the LGPLicense. LGPL can be used as an alternative license for the MPL. scm:svn:http://itext.svn.sourceforge.net/svnroot/itext http://itext.svn.sourceforge.net/viewvc/itext bouncycastle bcmail-bc.jdk bc.version bouncycastle bcprov-bc.jdk bc.version bouncycastle bctsp-bc.jdk bc.version org.apache.maven.plugins maven-jar-plugin com.lowagie.tools.ToolboxAvailable src/ant/release.xml100644 0 0 34050 11213370067 11742 0ustar 0 0 MAKING A NEW RELEASE (release.xml) ant clean: cleans up all the files that were generated archive.src: archiving the source (zip and tar.gz) asian.jar: creates a new version of iTextAsian.jar and iTextAsianCmaps.jar src/ant/site.xml100644 0 0 17672 11213370067 11301 0ustar 0 0 BUILDING THE iText SITE (site.xml) ant lowagie.com: Building the lowagie.com pages ant javadoc: Building the API documentation ant docs.tar.gz: Building and jarring the API documentation ant tutorial: creates the tutorial pages (without the examples) ant tutorial.tar.gz: creates the tutorial and makes tar.gz files
<a href="http://www.1t3xt.com/docs/book.php" target="_blank"><img src="http://www.1t3xt.com/img/book/lowagie_3d.jpg" border="0" /></a>
Hosted by <a href="http://www.hostbasket.com/">Hostbasket</a>
src/build.xml100644 0 0 11035 11000354146 10627 0ustar 0 0 Using ANT for ${ant.project.name} release: making the all the files needed for a release (except tutorial) src/core/com/lowagie/text/Anchor.java100644 0 0 21620 11012562273 15212 0ustar 0 0 /* * $Id: Anchor.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; /** * An Anchor can be a reference or a destination of a reference. *

* An Anchor is a special kind of Phrase. * It is constructed in the same way. *

* Example: *

 * Anchor anchor = new Anchor("this is a link");
 * anchor.setName("LINK");
 * anchor.setReference("http://www.lowagie.com");
 * 
* * @see Element * @see Phrase */ public class Anchor extends Phrase { // constant private static final long serialVersionUID = -852278536049236911L; // membervariables /** This is the name of the Anchor. */ protected String name = null; /** This is the reference of the Anchor. */ protected String reference = null; // constructors /** * Constructs an Anchor without specifying a leading. */ public Anchor() { super(16); } /** * Constructs an Anchor with a certain leading. * * @param leading the leading */ public Anchor(float leading) { super(leading); } /** * Constructs an Anchor with a certain Chunk. * * @param chunk a Chunk */ public Anchor(Chunk chunk) { super(chunk); } /** * Constructs an Anchor with a certain String. * * @param string a String */ public Anchor(String string) { super(string); } /** * Constructs an Anchor with a certain String * and a certain Font. * * @param string a String * @param font a Font */ public Anchor(String string, Font font) { super(string, font); } /** * Constructs an Anchor with a certain Chunk * and a certain leading. * * @param leading the leading * @param chunk a Chunk */ public Anchor(float leading, Chunk chunk) { super(leading, chunk); } /** * Constructs an Anchor with a certain leading * and a certain String. * * @param leading the leading * @param string a String */ public Anchor(float leading, String string) { super(leading, string); } /** * Constructs an Anchor with a certain leading, * a certain String and a certain Font. * * @param leading the leading * @param string a String * @param font a Font */ public Anchor(float leading, String string, Font font) { super(leading, string, font); } /** * Constructs an Anchor with a certain Phrase. * * @param phrase a Phrase */ public Anchor(Phrase phrase) { super(phrase); if (phrase instanceof Anchor) { Anchor a = (Anchor) phrase; setName(a.name); setReference(a.reference); } } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { Chunk chunk; Iterator i = getChunks().iterator(); boolean localDestination = (reference != null && reference.startsWith("#")); boolean notGotoOK = true; while (i.hasNext()) { chunk = (Chunk) i.next(); if (name != null && notGotoOK && !chunk.isEmpty()) { chunk.setLocalDestination(name); notGotoOK = false; } if (localDestination) { chunk.setLocalGoto(reference.substring(1)); } listener.add(chunk); } return true; } catch(DocumentException de) { return false; } } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); Chunk chunk; Iterator i = iterator(); boolean localDestination = (reference != null && reference.startsWith("#")); boolean notGotoOK = true; while (i.hasNext()) { chunk = (Chunk) i.next(); if (name != null && notGotoOK && !chunk.isEmpty()) { chunk.setLocalDestination(name); notGotoOK = false; } if (localDestination) { chunk.setLocalGoto(reference.substring(1)); } else if (reference != null) chunk.setAnchor(reference); tmp.add(chunk); } return tmp; } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.ANCHOR; } // methods /** * Sets the name of this Anchor. * * @param name a new name */ public void setName(String name) { this.name = name; } /** * Sets the reference of this Anchor. * * @param reference a new reference */ public void setReference(String reference) { this.reference = reference; } // methods to retrieve information /** * Returns the name of this Anchor. * * @return a name */ public String getName() { return name; } /** * Gets the reference of this Anchor. * * @return a reference */ public String getReference() { return reference; } /** * Gets the reference of this Anchor. * * @return an URL */ public URL getUrl() { try { return new URL(reference); } catch(MalformedURLException mue) { return null; } } } src/core/com/lowagie/text/Annotation.java100644 0 0 35422 11012562273 16117 0ustar 0 0 /* * $Id: Annotation.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; /** * An Annotation is a little note that can be added to a page on * a document. * * @see Element * @see Anchor */ public class Annotation implements Element { // membervariables /** This is a possible annotation type. */ public static final int TEXT = 0; /** This is a possible annotation type. */ public static final int URL_NET = 1; /** This is a possible annotation type. */ public static final int URL_AS_STRING = 2; /** This is a possible annotation type. */ public static final int FILE_DEST = 3; /** This is a possible annotation type. */ public static final int FILE_PAGE = 4; /** This is a possible annotation type. */ public static final int NAMED_DEST = 5; /** This is a possible annotation type. */ public static final int LAUNCH = 6; /** This is a possible annotation type. */ public static final int SCREEN = 7; /** This is a possible attribute. */ public static final String TITLE = "title"; /** This is a possible attribute. */ public static final String CONTENT = "content"; /** This is a possible attribute. */ public static final String URL = "url"; /** This is a possible attribute. */ public static final String FILE = "file"; /** This is a possible attribute. */ public static final String DESTINATION = "destination"; /** This is a possible attribute. */ public static final String PAGE = "page"; /** This is a possible attribute. */ public static final String NAMED = "named"; /** This is a possible attribute. */ public static final String APPLICATION = "application"; /** This is a possible attribute. */ public static final String PARAMETERS = "parameters"; /** This is a possible attribute. */ public static final String OPERATION = "operation"; /** This is a possible attribute. */ public static final String DEFAULTDIR = "defaultdir"; /** This is a possible attribute. */ public static final String LLX = "llx"; /** This is a possible attribute. */ public static final String LLY = "lly"; /** This is a possible attribute. */ public static final String URX = "urx"; /** This is a possible attribute. */ public static final String URY = "ury"; /** This is a possible attribute. */ public static final String MIMETYPE = "mime"; /** This is the type of annotation. */ protected int annotationtype; /** This is the title of the Annotation. */ protected HashMap annotationAttributes = new HashMap(); /** This is the lower left x-value */ protected float llx = Float.NaN; /** This is the lower left y-value */ protected float lly = Float.NaN; /** This is the upper right x-value */ protected float urx = Float.NaN; /** This is the upper right y-value */ protected float ury = Float.NaN; // constructors /** * Constructs an Annotation with a certain title and some * text. * * @param llx * lower left x coordinate * @param lly * lower left y coordinate * @param urx * upper right x coordinate * @param ury * upper right y coordinate */ private Annotation(float llx, float lly, float urx, float ury) { this.llx = llx; this.lly = lly; this.urx = urx; this.ury = ury; } /** * Copy constructor. */ public Annotation(Annotation an) { annotationtype = an.annotationtype; annotationAttributes = an.annotationAttributes; llx = an.llx; lly = an.lly; urx = an.urx; ury = an.ury; } /** * Constructs an Annotation with a certain title and some * text. * * @param title * the title of the annotation * @param text * the content of the annotation */ public Annotation(String title, String text) { annotationtype = TEXT; annotationAttributes.put(TITLE, title); annotationAttributes.put(CONTENT, text); } /** * Constructs an Annotation with a certain title and some * text. * * @param title * the title of the annotation * @param text * the content of the annotation * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value */ public Annotation(String title, String text, float llx, float lly, float urx, float ury) { this(llx, lly, urx, ury); annotationtype = TEXT; annotationAttributes.put(TITLE, title); annotationAttributes.put(CONTENT, text); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param url * the external reference */ public Annotation(float llx, float lly, float urx, float ury, URL url) { this(llx, lly, urx, ury); annotationtype = URL_NET; annotationAttributes.put(URL, url); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param url * the external reference */ public Annotation(float llx, float lly, float urx, float ury, String url) { this(llx, lly, urx, ury); annotationtype = URL_AS_STRING; annotationAttributes.put(FILE, url); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param file * an external PDF file * @param dest * the destination in this file */ public Annotation(float llx, float lly, float urx, float ury, String file, String dest) { this(llx, lly, urx, ury); annotationtype = FILE_DEST; annotationAttributes.put(FILE, file); annotationAttributes.put(DESTINATION, dest); } /** * Creates a Screen annotation to embed media clips * * @param llx * @param lly * @param urx * @param ury * @param moviePath * path to the media clip file * @param mimeType * mime type of the media * @param showOnDisplay * if true play on display of the page */ public Annotation(float llx, float lly, float urx, float ury, String moviePath, String mimeType, boolean showOnDisplay) { this(llx, lly, urx, ury); annotationtype = SCREEN; annotationAttributes.put(FILE, moviePath); annotationAttributes.put(MIMETYPE, mimeType); annotationAttributes.put(PARAMETERS, new boolean[] { false /* embedded */, showOnDisplay }); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param file * an external PDF file * @param page * a page number in this file */ public Annotation(float llx, float lly, float urx, float ury, String file, int page) { this(llx, lly, urx, ury); annotationtype = FILE_PAGE; annotationAttributes.put(FILE, file); annotationAttributes.put(PAGE, new Integer(page)); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param named * a named destination in this file */ public Annotation(float llx, float lly, float urx, float ury, int named) { this(llx, lly, urx, ury); annotationtype = NAMED_DEST; annotationAttributes.put(NAMED, new Integer(named)); } /** * Constructs an Annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value * @param application * an external application * @param parameters * parameters to pass to this application * @param operation * the operation to pass to this application * @param defaultdir * the default directory to run this application in */ public Annotation(float llx, float lly, float urx, float ury, String application, String parameters, String operation, String defaultdir) { this(llx, lly, urx, ury); annotationtype = LAUNCH; annotationAttributes.put(APPLICATION, application); annotationAttributes.put(PARAMETERS, parameters); annotationAttributes.put(OPERATION, operation); annotationAttributes.put(DEFAULTDIR, defaultdir); } // implementation of the Element-methods /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.ANNOTATION; } /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener * an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch (DocumentException de) { return false; } } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } // methods /** * Sets the dimensions of this annotation. * * @param llx * the lower left x-value * @param lly * the lower left y-value * @param urx * the upper right x-value * @param ury * the upper right y-value */ public void setDimensions(float llx, float lly, float urx, float ury) { this.llx = llx; this.lly = lly; this.urx = urx; this.ury = ury; } // methods to retrieve information /** * Returns the lower left x-value. * * @return a value */ public float llx() { return llx; } /** * Returns the lower left y-value. * * @return a value */ public float lly() { return lly; } /** * Returns the upper right x-value. * * @return a value */ public float urx() { return urx; } /** * Returns the upper right y-value. * * @return a value */ public float ury() { return ury; } /** * Returns the lower left x-value. * * @param def * the default value * @return a value */ public float llx(float def) { if (Float.isNaN(llx)) return def; return llx; } /** * Returns the lower left y-value. * * @param def * the default value * @return a value */ public float lly(float def) { if (Float.isNaN(lly)) return def; return lly; } /** * Returns the upper right x-value. * * @param def * the default value * @return a value */ public float urx(float def) { if (Float.isNaN(urx)) return def; return urx; } /** * Returns the upper right y-value. * * @param def * the default value * @return a value */ public float ury(float def) { if (Float.isNaN(ury)) return def; return ury; } /** * Returns the type of this Annotation. * * @return a type */ public int annotationType() { return annotationtype; } /** * Returns the title of this Annotation. * * @return a name */ public String title() { String s = (String) annotationAttributes.get(TITLE); if (s == null) s = ""; return s; } /** * Gets the content of this Annotation. * * @return a reference */ public String content() { String s = (String) annotationAttributes.get(CONTENT); if (s == null) s = ""; return s; } /** * Gets the content of this Annotation. * * @return a reference */ public HashMap attributes() { return annotationAttributes; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } }src/core/com/lowagie/text/BadElementException.java100644 0 0 6576 11012562273 17654 0ustar 0 0 /* * $Id: BadElementException.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * Signals an attempt to create an Element that hasn't got the right form. * * @see DocumentException * @see Cell * @see Table */ public class BadElementException extends DocumentException { private static final long serialVersionUID = -799006030723822254L; // constructors /** * Constructs a BadElementException * @param ex an Exception object that has to be turned into a BadElementException */ public BadElementException(Exception ex) { super(ex); } /** * Constructs a BadElementException without a message. */ BadElementException() { super(); } /** * Constructs a BadElementException with a message. * @param message a message describing the exception */ public BadElementException(String message) { super(message); } }src/core/com/lowagie/text/Cell.java100644 0 0 52540 11012562273 14664 0ustar 0 0 /* * $Id: Cell.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.pdf.PdfPCell; /** * A Cell is a Rectangle containing other * Elements. *

* A Cell must be added to a Table. * The Table will place the Cell in * a Row. *

* Example: *

 * Table table = new Table(3);
 * table.setBorderWidth(1);
 * table.setBorderColor(new Color(0, 0, 255));
 * table.setCellpadding(5);
 * table.setCellspacing(5);
 * Cell cell = new Cell("header");
 * cell.setHeader(true);
 * cell.setColspan(3);
 * table.addCell(cell);
 * cell = new Cell("example cell with colspan 1 and rowspan 2");
 * cell.setRowspan(2);
 * cell.setBorderColor(new Color(255, 0, 0));
 * table.addCell(cell);
 * table.addCell("1.1");
 * table.addCell("2.1");
 * table.addCell("1.2");
 * table.addCell("2.2");
 * 
* * @see Rectangle * @see Element * @see Table * @see Row */ public class Cell extends Rectangle implements TextElementArray { // membervariables /** * The ArrayList of Elements * that are part of the content of the Cell. */ protected ArrayList arrayList = null; /** The horizontal alignment of the cell content. */ protected int horizontalAlignment = Element.ALIGN_UNDEFINED; /** The vertical alignment of the cell content. */ protected int verticalAlignment = Element.ALIGN_UNDEFINED; /** * The width of the cell as a String. * It can be an absolute value "100" or a percentage "20%". */ protected float width; protected boolean percentage = false; /** The colspan of the cell. */ protected int colspan = 1; /** The rowspan of the cell. */ protected int rowspan = 1; /** The leading of the content inside the cell. */ float leading = Float.NaN; /** Is this Cell a header? */ protected boolean header; /** * Maximum number of lines allowed in the cell. * The default value of this property is not to limit the maximum number of lines * (contributed by dperezcar@fcc.es) */ protected int maxLines = Integer.MAX_VALUE; /** * If a truncation happens due to the maxLines property, then this text will * be added to indicate a truncation has happened. * Default value is null, and means avoiding marking the truncation. * A useful value of this property could be e.g. "..." * (contributed by dperezcar@fcc.es) */ String showTruncation; /** * Indicates that the largest ascender height should be used to determine the * height of the first line. Note that this only has an effect when rendered * to PDF. Setting this to true can help with vertical alignment problems. */ protected boolean useAscender = false; /** * Indicates that the largest descender height should be added to the height of * the last line (so characters like y don't dip into the border). Note that * this only has an effect when rendered to PDF. */ protected boolean useDescender = false; /** * Adjusts the cell contents to compensate for border widths. Note that * this only has an effect when rendered to PDF. */ protected boolean useBorderPadding; /** Does this Cell force a group change? */ protected boolean groupChange = true; // constructors /** Constructs an empty Cell. */ public Cell() { // creates a Rectangle with BY DEFAULT a border of 0.5 super(0, 0, 0, 0); setBorder(UNDEFINED); setBorderWidth(0.5f); // initializes the arraylist arrayList = new ArrayList(); } /** * Constructs an empty Cell (for internal use only). * * @param dummy a dummy value */ public Cell(boolean dummy) { this(); arrayList.add(new Paragraph(0)); } /** * Constructs a Cell with a certain content.

* The String will be converted into a Paragraph. * @param content a String */ public Cell(String content) { this(); try { addElement(new Paragraph(content)); } catch(BadElementException bee) { } } /** * Constructs a Cell with a certain Element.

* if the element is a ListItem, Row or * Cell, an exception will be thrown. * * @param element the element * @throws BadElementException when the creator was called with a ListItem, Row or Cell */ public Cell(Element element) throws BadElementException { this(); if(element instanceof Phrase) { setLeading(((Phrase)element).getLeading()); } addElement(element); } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.CELL; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); for (Iterator i = arrayList.iterator(); i.hasNext(); ) { tmp.addAll(((Element) i.next()).getChunks()); } return tmp; } // Getters and setters /** * Gets the horizontal alignment. * * @return a value */ public int getHorizontalAlignment() { return horizontalAlignment; } /** * Sets the horizontal alignment. * @param value the new value */ public void setHorizontalAlignment(int value) { horizontalAlignment = value; } /** * Sets the alignment of this cell. * This methods allows you to set the alignment as a String. * @param alignment the new alignment as a String */ public void setHorizontalAlignment(String alignment) { setHorizontalAlignment(ElementTags.alignmentValue(alignment)); } /** * Gets the vertical alignment. * @return a value */ public int getVerticalAlignment() { return verticalAlignment; } /** * Sets the vertical alignment. * @param value the new value */ public void setVerticalAlignment(int value) { verticalAlignment = value; } /** * Sets the alignment of this paragraph. * * @param alignment the new alignment as a String */ public void setVerticalAlignment(String alignment) { setVerticalAlignment(ElementTags.alignmentValue(alignment)); } /** * Sets the width. * * @param value the new value */ public void setWidth(float value) { this.width = value; } /** * Sets the width. * It can be an absolute value "100" or a percentage "20%" * * @param value the new value */ public void setWidth(String value) { if (value.endsWith("%")) { value = value.substring(0, value.length() - 1); percentage = true; } width = Integer.parseInt(value); } /** * Gets the width. */ public float getWidth() { return width; } /** * Gets the width as a String. * * @return a value */ public String getWidthAsString() { String w = String.valueOf(width); if (w.endsWith(".0")) w = w.substring(0, w.length() - 2); if (percentage) w += "%"; return w; } /** * Sets the colspan. * * @param value the new value */ public void setColspan(int value) { colspan = value; } /** * Gets the colspan. * @return a value */ public int getColspan() { return colspan; } /** * Sets the rowspan. * * @param value the new value */ public void setRowspan(int value) { rowspan = value; } /** * Gets the rowspan. * @return a value */ public int getRowspan() { return rowspan; } /** * Sets the leading. * * @param value the new value */ public void setLeading(float value) { leading = value; } /** * Gets the leading. * * @return a value */ public float getLeading() { if (Float.isNaN(leading)) { return 16; } return leading; } /** * Sets header. * * @param value the new value */ public void setHeader(boolean value) { header = value; } /** * Is this Cell a header? * * @return a value */ public boolean isHeader() { return header; } /** * Setter for maxLines * @param value the maximum number of lines */ public void setMaxLines(int value) { maxLines = value; } /** * Getter for maxLines * @return the maxLines value */ public int getMaxLines() { return maxLines; } /** * Setter for showTruncation * @param value Can be null for avoiding marking the truncation. */ public void setShowTruncation(String value) { showTruncation = value; } /** * Getter for showTruncation * @return the showTruncation value */ public String getShowTruncation() { return showTruncation; } /** * Sets the value of useAscender. * @param use use ascender height if true */ public void setUseAscender(boolean use) { useAscender = use; } /** * Gets the value of useAscender * @return useAscender */ public boolean isUseAscender() { return useAscender; } /** * Sets the value of useDescender. * @param use use descender height if true */ public void setUseDescender(boolean use) { useDescender = use; } /** * gets the value of useDescender * @return useDescender */ public boolean isUseDescender() { return useDescender; } /** * Sets the value of useBorderPadding. * @param use adjust layout for borders if true */ public void setUseBorderPadding(boolean use) { useBorderPadding = use; } /** * Gets the value of useBorderPadding. * @return useBorderPadding */ public boolean isUseBorderPadding() { return useBorderPadding; } /** * Does this Cell force a group change? * * @return a value */ public boolean getGroupChange() { return groupChange; } /** * Sets group change. * * @param value the new value */ public void setGroupChange(boolean value) { groupChange = value; } // arraylist stuff /** * Gets the number of Elements in the Cell. * * @return a size. */ public int size() { return arrayList.size(); } /** * Gets an iterator of Elements. * * @return an Iterator. */ public Iterator getElements() { return arrayList.iterator(); } /** * Clears all the Elements of this Cell. */ public void clear() { arrayList.clear(); } /** * Checks if the Cell is empty. * * @return false if there are non-empty Elements in the Cell. */ public boolean isEmpty() { switch(size()) { case 0: return true; case 1: Element element = (Element) arrayList.get(0); switch (element.type()) { case Element.CHUNK: return ((Chunk) element).isEmpty(); case Element.ANCHOR: case Element.PHRASE: case Element.PARAGRAPH: return ((Phrase) element).isEmpty(); case Element.LIST: return ((List) element).isEmpty(); } return false; default: return false; } } /** * Makes sure there is at least 1 object in the Cell. * * Otherwise it might not be shown in the table. */ void fill() { if (size() == 0) arrayList.add(new Paragraph(0)); } /** * Checks if this Cell is a placeholder for a (nested) table. * * @return true if the only element in this cell is a table */ public boolean isTable() { return (size() == 1) && (((Element)arrayList.get(0)).type() == Element.TABLE); } /** * Adds an element to this Cell. *

* Remark: you can't add ListItems, Rows, Cells, * JPEGs, GIFs or PNGs to a Cell. * * @param element The Element to add * @throws BadElementException if the method was called with a ListItem, Row or Cell */ public void addElement(Element element) throws BadElementException { if (isTable()) { Table table = (Table) arrayList.get(0); Cell tmp = new Cell(element); tmp.setBorder(NO_BORDER); tmp.setColspan(table.getColumns()); table.addCell(tmp); return; } switch(element.type()) { case Element.LISTITEM: case Element.ROW: case Element.CELL: throw new BadElementException("You can't add listitems, rows or cells to a cell."); case Element.LIST: List list = (List)element; if (Float.isNaN(leading)) { setLeading(list.getTotalLeading()); } if (list.isEmpty()) return; arrayList.add(element); return; case Element.ANCHOR: case Element.PARAGRAPH: case Element.PHRASE: Phrase p = (Phrase)element; if (Float.isNaN(leading)) { setLeading(p.getLeading()); } if (p.isEmpty()) return; arrayList.add(element); return; case Element.CHUNK: if (((Chunk) element).isEmpty()) return; arrayList.add(element); return; case Element.TABLE: Table table = new Table(3); float[] widths = new float[3]; widths[1] = ((Table)element).getWidth(); switch(((Table)element).getAlignment()) { case Element.ALIGN_LEFT: widths[0] = 0f; widths[2] = 100f - widths[1]; break; case Element.ALIGN_CENTER: widths[0] = (100f - widths[1]) / 2f; widths[2] = widths[0]; break; case Element.ALIGN_RIGHT: widths[0] = 100f - widths[1]; widths[2] = 0f; } table.setWidths(widths); Cell tmp; if (arrayList.isEmpty()) { table.addCell(getDummyCell()); } else { tmp = new Cell(); tmp.setBorder(NO_BORDER); tmp.setColspan(3); for (Iterator i = arrayList.iterator(); i.hasNext(); ) { tmp.add(i.next()); } table.addCell(tmp); } tmp = new Cell(); tmp.setBorder(NO_BORDER); table.addCell(tmp); table.insertTable((Table)element); tmp = new Cell(); tmp.setBorder(NO_BORDER); table.addCell(tmp); table.addCell(getDummyCell()); clear(); arrayList.add(table); return; default: arrayList.add(element); } } /** * Add an Object to this cell. * * @param o the object to add * @return always true */ public boolean add(Object o) { try { this.addElement((Element) o); return true; } catch(ClassCastException cce) { throw new ClassCastException("You can only add objects that implement the Element interface."); } catch(BadElementException bee) { throw new ClassCastException(bee.getMessage()); } } // helper methods /** * Get dummy cell used when merging inner tables. * @return a cell with colspan 3 and no border */ private static Cell getDummyCell() { Cell cell = new Cell(true); cell.setColspan(3); cell.setBorder(NO_BORDER); return cell; } /** * Creates a PdfPCell based on this Cell object. * @return a PdfPCell * @throws BadElementException */ public PdfPCell createPdfPCell() throws BadElementException { if (rowspan > 1) throw new BadElementException("PdfPCells can't have a rowspan > 1"); if (isTable()) return new PdfPCell(((Table)arrayList.get(0)).createPdfPTable()); PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(verticalAlignment); cell.setHorizontalAlignment(horizontalAlignment); cell.setColspan(colspan); cell.setUseBorderPadding(useBorderPadding); cell.setUseDescender(useDescender); cell.setLeading(getLeading(), 0); cell.cloneNonPositionParameters(this); cell.setNoWrap(getMaxLines() == 1); for (Iterator i = getElements(); i.hasNext(); ) { Element e = (Element)i.next(); if (e.type() == Element.PHRASE || e.type() == Element.PARAGRAPH) { Paragraph p = new Paragraph((Phrase)e); p.setAlignment(horizontalAlignment); e = p; } cell.addElement(e); } return cell; } // unsupported Rectangle methods /** * This method throws an UnsupportedOperationException. * @return NA */ public float getTop() { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @return NA */ public float getBottom() { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @return NA */ public float getLeft() { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @return NA */ public float getRight() { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param margin * @return NA */ public float top(int margin) { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param margin * @return NA */ public float bottom(int margin) { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param margin * @return NA */ public float left(int margin) { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param margin NA * @return NA */ public float right(int margin) { throw new UnsupportedOperationException("Dimensions of a Cell can't be calculated. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param value NA */ public void setTop(int value) { throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param value NA */ public void setBottom(int value) { throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param value NA */ public void setLeft(int value) { throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ."); } /** * This method throws an UnsupportedOperationException. * @param value NA */ public void setRight(int value) { throw new UnsupportedOperationException("Dimensions of a Cell are attributed automagically. See the FAQ."); } } src/core/com/lowagie/text/Chapter.java100644 0 0 12031 11012562273 15362 0ustar 0 0 /* * $Id: Chapter.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * */ package com.lowagie.text; import java.util.ArrayList; /** * A Chapter is a special Section. *

* A chapter number has to be created using a Paragraph as title * and an int as chapter number. The chapter number is shown be * default. If you don't want to see the chapter number, you have to set the * numberdepth to 0. *

* Example: *

 * Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
 * Chapter chapter2 = new Chapter(title2, 2);
 * chapter2.setNumberDepth(0);
 * Paragraph someText = new Paragraph("This is some text");
 * chapter2.add(someText);
 * Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
 * Section section1 = chapter2.addSection(title21);
 * Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
 * section1.add(someSectionText);
 * 
*/ public class Chapter extends Section { // constant private static final long serialVersionUID = 1791000695779357361L; /** * Constructs a new Chapter. * @param number the Chapter number */ public Chapter(int number) { super(null, 1); numbers = new ArrayList(); numbers.add(new Integer(number)); triggerNewPage = true; } /** * Constructs a new Chapter. * * @param title the Chapter title (as a Paragraph) * @param number the Chapter number */ public Chapter(Paragraph title, int number) { super(title, 1); numbers = new ArrayList(); numbers.add(new Integer(number)); triggerNewPage = true; } /** * Constructs a new Chapter. * * @param title the Chapter title (as a String) * @param number the Chapter number */ public Chapter(String title, int number) { this(new Paragraph(title), number); } // implementation of the Element-methods /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.CHAPTER; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } }src/core/com/lowagie/text/ChapterAutoNumber.java100644 0 0 10431 11106243445 17367 0ustar 0 0 /* * Copyright 2005 by Michael Niedermair. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * Chapter with auto numbering. * * @author Michael Niedermair */ public class ChapterAutoNumber extends Chapter { // constant private static final long serialVersionUID = -9217457637987854167L; /** * Is the chapter number already set? * @since 2.1.4 */ protected boolean numberSet = false; /** * Create a new object. * * @param para the Chapter title (as a Paragraph) */ public ChapterAutoNumber(final Paragraph para) { super(para, 0); } /** * Create a new object. * * @param title the Chapter title (as a String) */ public ChapterAutoNumber(final String title) { super(title, 0); } /** * Create a new section for this chapter and ad it. * * @param title the Section title (as a String) * @return Returns the new section. */ public Section addSection(final String title) { if (isAddedCompletely()) { throw new IllegalStateException("This LargeElement has already been added to the Document."); } return addSection(title, 2); } /** * Create a new section for this chapter and add it. * * @param title the Section title (as a Paragraph) * @return Returns the new section. */ public Section addSection(final Paragraph title) { if (isAddedCompletely()) { throw new IllegalStateException("This LargeElement has already been added to the Document."); } return addSection(title, 2); } /** * Changes the Chapter number. * @param number the new chapter number * @since 2.1.4 */ public int setAutomaticNumber(int number) { if (!numberSet) { number++; super.setChapterNumber(number); numberSet = true; } return number; } } src/core/com/lowagie/text/Chunk.java100644 0 0 57071 11036112746 15063 0ustar 0 0 /* * $Id: Chunk.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import com.lowagie.text.pdf.HyphenationEvent; import com.lowagie.text.pdf.PdfAction; import com.lowagie.text.pdf.PdfAnnotation; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.draw.DrawInterface; /** * This is the smallest significant part of text that can be added to a * document. *

* Most elements can be divided in one or more Chunks. A chunk * is a String with a certain Font. All other * layout parameters should be defined in the object to which this chunk of text * is added. *

* Example:

* *
 * 
 * Chunk chunk = new Chunk("Hello world",
 * FontFactory.getFont(FontFactory.COURIER, 20, Font.ITALIC, new Color(255, 0,
 * 0)));  document.add(chunk);
 * 
 * 
* *
*/ public class Chunk implements Element { // public static membervariables /** The character stand in for an image or a separator. */ public static final String OBJECT_REPLACEMENT_CHARACTER = "\ufffc"; /** This is a Chunk containing a newline. */ public static final Chunk NEWLINE = new Chunk("\n"); /** This is a Chunk containing a newpage. */ public static final Chunk NEXTPAGE = new Chunk(""); static { NEXTPAGE.setNewPage(); } // member variables /** This is the content of this chunk of text. */ protected StringBuffer content = null; /** This is the Font of this chunk of text. */ protected Font font = null; /** Contains some of the attributes for this Chunk. */ protected HashMap attributes = null; // constructors /** * Empty constructor. */ public Chunk() { this.content = new StringBuffer(); this.font = new Font(); } /** * A Chunk copy constructor. * @param ck the Chunk to be copied */ public Chunk(Chunk ck) { if (ck.content != null) { content = new StringBuffer(ck.content.toString()); } if (ck.font != null) { font = new Font(ck.font); } if (ck.attributes != null) { attributes = new HashMap(ck.attributes); } } /** * Constructs a chunk of text with a certain content and a certain * Font. * * @param content * the content * @param font * the font */ public Chunk(String content, Font font) { this.content = new StringBuffer(content); this.font = font; } /** * Constructs a chunk of text with a certain content, without specifying a * Font. * * @param content * the content */ public Chunk(String content) { this(content, new Font()); } /** * Constructs a chunk of text with a char and a certain Font. * * @param c * the content * @param font * the font */ public Chunk(char c, Font font) { this.content = new StringBuffer(); this.content.append(c); this.font = font; } /** * Constructs a chunk of text with a char, without specifying a Font * . * * @param c * the content */ public Chunk(char c) { this(c, new Font()); } /** * Constructs a chunk containing an Image. * * @param image * the image * @param offsetX * the image offset in the x direction * @param offsetY * the image offset in the y direction */ public Chunk(Image image, float offsetX, float offsetY) { this(OBJECT_REPLACEMENT_CHARACTER, new Font()); Image copyImage = Image.getInstance(image); copyImage.setAbsolutePosition(Float.NaN, Float.NaN); setAttribute(IMAGE, new Object[] { copyImage, new Float(offsetX), new Float(offsetY), Boolean.FALSE }); } /** * Key for drawInterface of the Separator. * @since 2.1.2 */ public static final String SEPARATOR = "SEPARATOR"; /** * Creates a separator Chunk. * Note that separator chunks can't be used in combination with tab chunks! * @param separator the drawInterface to use to draw the separator. * @since 2.1.2 */ public Chunk(DrawInterface separator) { this(separator, false); } /** * Creates a separator Chunk. * Note that separator chunks can't be used in combination with tab chunks! * @param separator the drawInterface to use to draw the separator. * @param vertical true if this is a vertical separator * @since 2.1.2 */ public Chunk(DrawInterface separator, boolean vertical) { this(OBJECT_REPLACEMENT_CHARACTER, new Font()); setAttribute(SEPARATOR, new Object[] {separator, Boolean.valueOf(vertical)}); } /** * Key for drawInterface of the tab. * @since 2.1.2 */ public static final String TAB = "TAB"; /** * Creates a tab Chunk. * Note that separator chunks can't be used in combination with tab chunks! * @param separator the drawInterface to use to draw the tab. * @param tabPosition an X coordinate that will be used as start position for the next Chunk. * @since 2.1.2 */ public Chunk(DrawInterface separator, float tabPosition) { this(separator, tabPosition, false); } /** * Creates a tab Chunk. * Note that separator chunks can't be used in combination with tab chunks! * @param separator the drawInterface to use to draw the tab. * @param tabPosition an X coordinate that will be used as start position for the next Chunk. * @param newline if true, a newline will be added if the tabPosition has already been reached. * @since 2.1.2 */ public Chunk(DrawInterface separator, float tabPosition, boolean newline) { this(OBJECT_REPLACEMENT_CHARACTER, new Font()); if (tabPosition < 0) { throw new IllegalArgumentException("A tab position may not be lower than 0; yours is " + tabPosition); } setAttribute(TAB, new Object[] {separator, new Float(tabPosition), Boolean.valueOf(newline), new Float(0)}); } /** * Constructs a chunk containing an Image. * * @param image * the image * @param offsetX * the image offset in the x direction * @param offsetY * the image offset in the y direction * @param changeLeading * true if the leading has to be adapted to the image */ public Chunk(Image image, float offsetX, float offsetY, boolean changeLeading) { this(OBJECT_REPLACEMENT_CHARACTER, new Font()); setAttribute(IMAGE, new Object[] { image, new Float(offsetX), new Float(offsetY), Boolean.valueOf(changeLeading) }); } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener * an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch (DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.CHUNK; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); tmp.add(this); return tmp; } // methods that change the member variables /** * appends some text to this Chunk. * * @param string * String * @return a StringBuffer */ public StringBuffer append(String string) { return content.append(string); } /** * Sets the font of this Chunk. * * @param font * a Font */ public void setFont(Font font) { this.font = font; } // methods to retrieve information /** * Gets the font of this Chunk. * * @return a Font */ public Font getFont() { return font; } /** * Returns the content of this Chunk. * * @return a String */ public String getContent() { return content.toString(); } /** * Returns the content of this Chunk. * * @return a String */ public String toString() { return getContent(); } /** * Checks is this Chunk is empty. * * @return false if the Chunk contains other characters than * space. */ public boolean isEmpty() { return (content.toString().trim().length() == 0) && (content.toString().indexOf("\n") == -1) && (attributes == null); } /** * Gets the width of the Chunk in points. * * @return a width in points */ public float getWidthPoint() { if (getImage() != null) { return getImage().getScaledWidth(); } return font.getCalculatedBaseFont(true).getWidthPoint(getContent(), font.getCalculatedSize()) * getHorizontalScaling(); } // attributes /** * Checks the attributes of this Chunk. * * @return false if there aren't any. */ public boolean hasAttributes() { return attributes != null; } /** * Gets the attributes for this Chunk. *

* It may be null. * * @return the attributes for this Chunk */ public HashMap getAttributes() { return attributes; } /** * Sets the attributes all at once. * @param attributes the attributes of a Chunk */ public void setAttributes(HashMap attributes) { this.attributes = attributes; } /** * Sets an arbitrary attribute. * * @param name * the key for the attribute * @param obj * the value of the attribute * @return this Chunk */ private Chunk setAttribute(String name, Object obj) { if (attributes == null) attributes = new HashMap(); attributes.put(name, obj); return this; } // the attributes are ordered as they appear in the book 'iText in Action' /** Key for text horizontal scaling. */ public static final String HSCALE = "HSCALE"; /** * Sets the text horizontal scaling. A value of 1 is normal and a value of * 0.5f shrinks the text to half it's width. * * @param scale * the horizontal scaling factor * @return this Chunk */ public Chunk setHorizontalScaling(float scale) { return setAttribute(HSCALE, new Float(scale)); } /** * Gets the horizontal scaling. * * @return a percentage in float */ public float getHorizontalScaling() { if (attributes == null) return 1f; Float f = (Float) attributes.get(HSCALE); if (f == null) return 1f; return f.floatValue(); } /** Key for underline. */ public static final String UNDERLINE = "UNDERLINE"; /** * Sets an horizontal line that can be an underline or a strikethrough. * Actually, the line can be anywhere vertically and has always the * Chunk width. Multiple call to this method will produce multiple * lines. * * @param thickness * the absolute thickness of the line * @param yPosition * the absolute y position relative to the baseline * @return this Chunk */ public Chunk setUnderline(float thickness, float yPosition) { return setUnderline(null, thickness, 0f, yPosition, 0f, PdfContentByte.LINE_CAP_BUTT); } /** * Sets an horizontal line that can be an underline or a strikethrough. * Actually, the line can be anywhere vertically and has always the * Chunk width. Multiple call to this method will produce multiple * lines. * * @param color * the color of the line or null to follow the * text color * @param thickness * the absolute thickness of the line * @param thicknessMul * the thickness multiplication factor with the font size * @param yPosition * the absolute y position relative to the baseline * @param yPositionMul * the position multiplication factor with the font size * @param cap * the end line cap. Allowed values are * PdfContentByte.LINE_CAP_BUTT, PdfContentByte.LINE_CAP_ROUND * and PdfContentByte.LINE_CAP_PROJECTING_SQUARE * @return this Chunk */ public Chunk setUnderline(Color color, float thickness, float thicknessMul, float yPosition, float yPositionMul, int cap) { if (attributes == null) attributes = new HashMap(); Object obj[] = { color, new float[] { thickness, thicknessMul, yPosition, yPositionMul, cap } }; Object unders[][] = Utilities.addToArray((Object[][]) attributes.get(UNDERLINE), obj); return setAttribute(UNDERLINE, unders); } /** Key for sub/superscript. */ public static final String SUBSUPSCRIPT = "SUBSUPSCRIPT"; /** * Sets the text displacement relative to the baseline. Positive values rise * the text, negative values lower the text. *

* It can be used to implement sub/superscript. * * @param rise * the displacement in points * @return this Chunk */ public Chunk setTextRise(float rise) { return setAttribute(SUBSUPSCRIPT, new Float(rise)); } /** * Gets the text displacement relative to the baseline. * * @return a displacement in points */ public float getTextRise() { if (attributes != null && attributes.containsKey(SUBSUPSCRIPT)) { Float f = (Float) attributes.get(SUBSUPSCRIPT); return f.floatValue(); } return 0.0f; } /** Key for text skewing. */ public static final String SKEW = "SKEW"; /** * Skews the text to simulate italic and other effects. Try alpha=0 * and beta=12. * * @param alpha * the first angle in degrees * @param beta * the second angle in degrees * @return this Chunk */ public Chunk setSkew(float alpha, float beta) { alpha = (float) Math.tan(alpha * Math.PI / 180); beta = (float) Math.tan(beta * Math.PI / 180); return setAttribute(SKEW, new float[] { alpha, beta }); } /** Key for background. */ public static final String BACKGROUND = "BACKGROUND"; /** * Sets the color of the background Chunk. * * @param color * the color of the background * @return this Chunk */ public Chunk setBackground(Color color) { return setBackground(color, 0, 0, 0, 0); } /** * Sets the color and the size of the background Chunk. * * @param color * the color of the background * @param extraLeft * increase the size of the rectangle in the left * @param extraBottom * increase the size of the rectangle in the bottom * @param extraRight * increase the size of the rectangle in the right * @param extraTop * increase the size of the rectangle in the top * @return this Chunk */ public Chunk setBackground(Color color, float extraLeft, float extraBottom, float extraRight, float extraTop) { return setAttribute(BACKGROUND, new Object[] { color, new float[] { extraLeft, extraBottom, extraRight, extraTop } }); } /** Key for text rendering mode. */ public static final String TEXTRENDERMODE = "TEXTRENDERMODE"; /** * Sets the text rendering mode. It can outline text, simulate bold and make * text invisible. * * @param mode * the text rendering mode. It can be * PdfContentByte.TEXT_RENDER_MODE_FILL, * PdfContentByte.TEXT_RENDER_MODE_STROKE, * PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE and * PdfContentByte.TEXT_RENDER_MODE_INVISIBLE. * @param strokeWidth * the stroke line width for the modes * PdfContentByte.TEXT_RENDER_MODE_STROKE and * PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE. * @param strokeColor * the stroke color or null to follow the text * color * @return this Chunk */ public Chunk setTextRenderMode(int mode, float strokeWidth, Color strokeColor) { return setAttribute(TEXTRENDERMODE, new Object[] { new Integer(mode), new Float(strokeWidth), strokeColor }); } /** Key for split character. */ public static final String SPLITCHARACTER = "SPLITCHARACTER"; /** * Sets the split characters. * * @param splitCharacter * the SplitCharacter interface * @return this Chunk */ public Chunk setSplitCharacter(SplitCharacter splitCharacter) { return setAttribute(SPLITCHARACTER, splitCharacter); } /** Key for hyphenation. */ public static final String HYPHENATION = "HYPHENATION"; /** * sets the hyphenation engine to this Chunk. * * @param hyphenation * the hyphenation engine * @return this Chunk */ public Chunk setHyphenation(HyphenationEvent hyphenation) { return setAttribute(HYPHENATION, hyphenation); } /** Key for remote goto. */ public static final String REMOTEGOTO = "REMOTEGOTO"; /** * Sets a goto for a remote destination for this Chunk. * * @param filename * the file name of the destination document * @param name * the name of the destination to go to * @return this Chunk */ public Chunk setRemoteGoto(String filename, String name) { return setAttribute(REMOTEGOTO, new Object[] { filename, name }); } /** * Sets a goto for a remote destination for this Chunk. * * @param filename * the file name of the destination document * @param page * the page of the destination to go to. First page is 1 * @return this Chunk */ public Chunk setRemoteGoto(String filename, int page) { return setAttribute(REMOTEGOTO, new Object[] { filename, new Integer(page) }); } /** Key for local goto. */ public static final String LOCALGOTO = "LOCALGOTO"; /** * Sets a local goto for this Chunk. *

* There must be a local destination matching the name. * * @param name * the name of the destination to go to * @return this Chunk */ public Chunk setLocalGoto(String name) { return setAttribute(LOCALGOTO, name); } /** Key for local destination. */ public static final String LOCALDESTINATION = "LOCALDESTINATION"; /** * Sets a local destination for this Chunk. * * @param name * the name for this destination * @return this Chunk */ public Chunk setLocalDestination(String name) { return setAttribute(LOCALDESTINATION, name); } /** Key for generic tag. */ public static final String GENERICTAG = "GENERICTAG"; /** * Sets the generic tag Chunk. *

* The text for this tag can be retrieved with PdfPageEvent. * * @param text * the text for the tag * @return this Chunk */ public Chunk setGenericTag(String text) { return setAttribute(GENERICTAG, text); } /** Key for image. */ public static final String IMAGE = "IMAGE"; /** * Returns the image. * * @return the image */ public Image getImage() { if (attributes == null) return null; Object obj[] = (Object[]) attributes.get(Chunk.IMAGE); if (obj == null) return null; else { return (Image) obj[0]; } } /** Key for Action. */ public static final String ACTION = "ACTION"; /** * Sets an action for this Chunk. * * @param action * the action * @return this Chunk */ public Chunk setAction(PdfAction action) { return setAttribute(ACTION, action); } /** * Sets an anchor for this Chunk. * * @param url * the URL to link to * @return this Chunk */ public Chunk setAnchor(URL url) { return setAttribute(ACTION, new PdfAction(url.toExternalForm())); } /** * Sets an anchor for this Chunk. * * @param url * the url to link to * @return this Chunk */ public Chunk setAnchor(String url) { return setAttribute(ACTION, new PdfAction(url)); } /** Key for newpage. */ public static final String NEWPAGE = "NEWPAGE"; /** * Sets a new page tag.. * * @return this Chunk */ public Chunk setNewPage() { return setAttribute(NEWPAGE, null); } /** Key for annotation. */ public static final String PDFANNOTATION = "PDFANNOTATION"; /** * Sets a generic annotation to this Chunk. * * @param annotation * the annotation * @return this Chunk */ public Chunk setAnnotation(PdfAnnotation annotation) { return setAttribute(PDFANNOTATION, annotation); } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } /** * Returns the hyphenation (if present). * @since 2.1.2 */ public HyphenationEvent getHyphenation() { if (attributes == null) return null; return (HyphenationEvent) attributes.get(Chunk.HYPHENATION); } // keys used in PdfChunk /** Key for color. */ public static final String COLOR = "COLOR"; /** Key for encoding. */ public static final String ENCODING = "ENCODING"; }src/core/com/lowagie/text/DocListener.java100644 0 0 12543 11213370070 16212 0ustar 0 0 /* * $Id: DocListener.java 3939 2009-05-27 13:09:45Z blowagie $ * * Copyright (c) 1999, 2000, 2001, 2002 Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * A class that implements DocListener will perform some * actions when some actions are performed on a Document. * * @see ElementListener * @see Document * @see DocWriter */ public interface DocListener extends ElementListener { // methods /** * Signals that the Document has been opened and that * Elements can be added. */ public void open(); // [L1] /** * Signals that the Document was closed and that no other * Elements will be added. *

* The outputstream of every writer implementing DocListener will be closed. */ public void close(); // [L2] /** * Signals that an new page has to be started. * * @return true if the page was added, false if not. */ public boolean newPage(); // [L3] /** * Sets the pagesize. * * @param pageSize the new pagesize * @return a boolean */ public boolean setPageSize(Rectangle pageSize); // [L4] /** * Sets the margins. * * @param marginLeft the margin on the left * @param marginRight the margin on the right * @param marginTop the margin on the top * @param marginBottom the margin on the bottom * @return a boolean */ public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom); // [L5] /** * Parameter that allows you to do left/right margin mirroring (odd/even pages) * @param marginMirroring * @return true if successful */ public boolean setMarginMirroring(boolean marginMirroring); // [L6] /** * Parameter that allows you to do top/bottom margin mirroring (odd/even pages) * @param marginMirroringTopBottom * @return true if successful * @since 2.1.6 */ public boolean setMarginMirroringTopBottom(boolean marginMirroringTopBottom); // [L6] /** * Sets the page number. * * @param pageN the new page number */ public void setPageCount(int pageN); // [L7] /** * Sets the page number to 0. */ public void resetPageCount(); // [L8] /** * Changes the header of this document. * * @param header the new header */ public void setHeader(HeaderFooter header); // [L9] /** * Resets the header of this document. */ public void resetHeader(); // [L10] /** * Changes the footer of this document. * * @param footer the new footer */ public void setFooter(HeaderFooter footer); // [L11] /** * Resets the footer of this document. */ public void resetFooter(); // [L12] }src/core/com/lowagie/text/DocWriter.java100644 0 0 31646 11213370070 15706 0ustar 0 0 /* * $Id: DocWriter.java 3937 2009-05-27 12:56:48Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import java.util.Properties; import com.lowagie.text.pdf.OutputStreamCounter; /** * An abstract Writer class for documents. *

* DocWriter is the abstract class of several writers such * as PdfWriter and HtmlWriter. * A DocWriter can be added as a DocListener * to a certain Document by getting an instance (see method * getInstance() in the specific writer-classes). * Every Element added to the original Document * will be written to the OutputStream of the listening * DocWriter. * * @see Document * @see DocListener */ public abstract class DocWriter implements DocListener { /** This is some byte that is often used. */ public static final byte NEWLINE = (byte)'\n'; /** This is some byte that is often used. */ public static final byte TAB = (byte)'\t'; /** This is some byte that is often used. */ public static final byte LT = (byte)'<'; /** This is some byte that is often used. */ public static final byte SPACE = (byte)' '; /** This is some byte that is often used. */ public static final byte EQUALS = (byte)'='; /** This is some byte that is often used. */ public static final byte QUOTE = (byte)'\"'; /** This is some byte that is often used. */ public static final byte GT = (byte)'>'; /** This is some byte that is often used. */ public static final byte FORWARD = (byte)'/'; // membervariables /** The pageSize. */ protected Rectangle pageSize; /** This is the document that has to be written. */ protected Document document; /** The outputstream of this writer. */ protected OutputStreamCounter os; /** Is the writer open for writing? */ protected boolean open = false; /** Do we have to pause all writing actions? */ protected boolean pause = false; /** Closes the stream on document close */ protected boolean closeStream = true; // constructor protected DocWriter() { } /** * Constructs a DocWriter. * * @param document The Document that has to be written * @param os The OutputStream the writer has to write to. */ protected DocWriter(Document document, OutputStream os) { this.document = document; this.os = new OutputStreamCounter(new BufferedOutputStream(os)); } // implementation of the DocListener methods /** * Signals that an Element was added to the Document. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class. * * @param element A high level object to add * @return false * @throws DocumentException when a document isn't open yet, or has been closed */ public boolean add(Element element) throws DocumentException { return false; } /** * Signals that the Document was opened. */ public void open() { open = true; } /** * Sets the pagesize. * * @param pageSize the new pagesize * @return a boolean */ public boolean setPageSize(Rectangle pageSize) { this.pageSize = pageSize; return true; } /** * Sets the margins. *

* This does nothing. Has to be overridden if needed. * * @param marginLeft the margin on the left * @param marginRight the margin on the right * @param marginTop the margin on the top * @param marginBottom the margin on the bottom * @return false */ public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { return false; } /** * Signals that an new page has to be started. *

* This does nothing. Has to be overridden if needed. * * @return true if the page was added, false if not. */ public boolean newPage() { if (!open) { return false; } return true; } /** * Changes the header of this document. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * headers. * * @param header the new header */ public void setHeader(HeaderFooter header) { } /** * Resets the header of this document. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * headers. */ public void resetHeader() { } /** * Changes the footer of this document. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * footers. * * @param footer the new footer */ public void setFooter(HeaderFooter footer) { } /** * Resets the footer of this document. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * footers. */ public void resetFooter() { } /** * Sets the page number to 0. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * pagenumbers. */ public void resetPageCount() { } /** * Sets the page number. *

* This method should be overridden in the specific DocWriter classes * derived from this abstract class if they actually support the use of * pagenumbers. * * @param pageN the new page number */ public void setPageCount(int pageN) { } /** * Signals that the Document was closed and that no other * Elements will be added. */ public void close() { open = false; try { os.flush(); if (closeStream) os.close(); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } // methods /** Converts a String into a Byte array * according to the ISO-8859-1 codepage. * @param text the text to be converted * @return the conversion result */ public static final byte[] getISOBytes(String text) { if (text == null) return null; int len = text.length(); byte b[] = new byte[len]; for (int k = 0; k < len; ++k) b[k] = (byte)text.charAt(k); return b; } /** * Let the writer know that all writing has to be paused. */ public void pause() { pause = true; } /** * Checks if writing is paused. * * @return true if writing temporarily has to be paused, false otherwise. */ public boolean isPaused() { return pause; } /** * Let the writer know that writing may be resumed. */ public void resume() { pause = false; } /** * Flushes the BufferedOutputStream. */ public void flush() { try { os.flush(); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Writes a String to the OutputStream. * * @param string the String to write * @throws IOException */ protected void write(String string) throws IOException { os.write(getISOBytes(string)); } /** * Writes a number of tabs. * * @param indent the number of tabs to add * @throws IOException */ protected void addTabs(int indent) throws IOException { os.write(NEWLINE); for (int i = 0; i < indent; i++) { os.write(TAB); } } /** * Writes a key-value pair to the outputstream. * * @param key the name of an attribute * @param value the value of an attribute * @throws IOException */ protected void write(String key, String value) throws IOException { os.write(SPACE); write(key); os.write(EQUALS); os.write(QUOTE); write(value); os.write(QUOTE); } /** * Writes a starttag to the outputstream. * * @param tag the name of the tag * @throws IOException */ protected void writeStart(String tag) throws IOException { os.write(LT); write(tag); } /** * Writes an endtag to the outputstream. * * @param tag the name of the tag * @throws IOException */ protected void writeEnd(String tag) throws IOException { os.write(LT); os.write(FORWARD); write(tag); os.write(GT); } /** * Writes an endtag to the outputstream. * @throws IOException */ protected void writeEnd() throws IOException { os.write(SPACE); os.write(FORWARD); os.write(GT); } /** * Writes the markup attributes of the specified MarkupAttributes * object to the OutputStream. * @param markup a Properties collection to write. * @return true, if writing the markup attributes succeeded * @throws IOException */ protected boolean writeMarkupAttributes(Properties markup) throws IOException { if (markup == null) return false; Iterator attributeIterator = markup.keySet().iterator(); String name; while (attributeIterator.hasNext()) { name = String.valueOf(attributeIterator.next()); write(name, markup.getProperty(name)); } markup.clear(); return true; } /** Checks if the stream is to be closed on document close * @return true if the stream is closed on document close * */ public boolean isCloseStream() { return closeStream; } /** Sets the close state of the stream after document close * @param closeStream true if the stream is closed on document close * */ public void setCloseStream(boolean closeStream) { this.closeStream = closeStream; } /** * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) */ public boolean setMarginMirroring(boolean MarginMirroring) { return false; } /** * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) * @since 2.1.6 */ public boolean setMarginMirroringTopBottom(boolean MarginMirroring) { return false; } } src/core/com/lowagie/text/Document.java100644 0 0 60611 11224570760 15566 0ustar 0 0 /* * $Id: Document.java 4007 2009-07-07 09:43:40Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; /** * A generic Document class. *

* All kinds of Text-elements can be added to a HTMLDocument. * The Document signals all the listeners when an element has * been added. *

* Remark: *

    *
  1. Once a document is created you can add some meta information. *
  2. You can also set the headers/footers. *
  3. You have to open the document before you can write content. *
  4. You can only write content (no more meta-formation!) once a document is * opened. *
  5. When you change the header/footer on a certain page, this will be * effective starting on the next page. *
  6. After closing the document, every listener (as well as its * OutputStream) is closed too. *
* Example:
* *
// creation of the document with a certain size and certain margins
 * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
 *  try { 
 *   // creation of the different writers 
 *   HtmlWriter.getInstance(document , System.out);
 *   PdfWriter.getInstance(document , new FileOutputStream("text.pdf"));
 *   // we add some meta information to the document
 *   document.addAuthor("Bruno Lowagie"); 
 *   document.addSubject("This is the result of a Test."); 
 *   // we open the document for writing
 *   document.open(); 
 *   document.add(new Paragraph("Hello world"));
 *  } catch(DocumentException de) {
 *   System.err.println(de.getMessage());
 *  }
 *  document.close();
 * 
* *
*/ public class Document implements DocListener { // membervariables /** * This constant may only be changed by Paulo Soares and/or Bruno Lowagie. * @since 2.1.6 */ private static final String ITEXT = "iText"; /** * This constant may only be changed by Paulo Soares and/or Bruno Lowagie. * @since 2.1.6 */ private static final String RELEASE = "2.1.7"; /** This constant may only be changed by Paulo Soares and/or Bruno Lowagie. */ private static final String ITEXT_VERSION = ITEXT + " " + RELEASE + " by 1T3XT"; /** * Allows the pdf documents to be produced without compression for debugging * purposes. */ public static boolean compress = true; /** * When true the file access is not done through a memory mapped file. Use it if the file * is too big to be mapped in your address space. */ public static boolean plainRandomAccess = false; /** Scales the WMF font size. The default value is 0.86. */ public static float wmfFontCorrection = 0.86f; /** The DocListener. */ private ArrayList listeners = new ArrayList(); /** Is the document open or not? */ protected boolean open; /** Has the document already been closed? */ protected boolean close; // membervariables concerning the layout /** The size of the page. */ protected Rectangle pageSize; /** margin in x direction starting from the left */ protected float marginLeft = 0; /** margin in x direction starting from the right */ protected float marginRight = 0; /** margin in y direction starting from the top */ protected float marginTop = 0; /** margin in y direction starting from the bottom */ protected float marginBottom = 0; /** mirroring of the left/right margins */ protected boolean marginMirroring = false; /** * mirroring of the top/bottom margins * @since 2.1.6 */ protected boolean marginMirroringTopBottom = false; /** Content of JavaScript onLoad function */ protected String javaScript_onLoad = null; /** Content of JavaScript onUnLoad function */ protected String javaScript_onUnLoad = null; /** Style class in HTML body tag */ protected String htmlStyleClass = null; // headers, footers /** Current pagenumber */ protected int pageN = 0; /** This is the textual part of a Page; it can contain a header */ protected HeaderFooter header = null; /** This is the textual part of the footer */ protected HeaderFooter footer = null; /** This is a chapter number in case ChapterAutoNumber is used. */ protected int chapternumber = 0; // constructor /** * Constructs a new Document -object. */ public Document() { this(PageSize.A4); } /** * Constructs a new Document -object. * * @param pageSize * the pageSize */ public Document(Rectangle pageSize) { this(pageSize, 36, 36, 36, 36); } /** * Constructs a new Document -object. * * @param pageSize * the pageSize * @param marginLeft * the margin on the left * @param marginRight * the margin on the right * @param marginTop * the margin on the top * @param marginBottom * the margin on the bottom */ public Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom) { this.pageSize = pageSize; this.marginLeft = marginLeft; this.marginRight = marginRight; this.marginTop = marginTop; this.marginBottom = marginBottom; } // listener methods /** * Adds a DocListener to the Document. * * @param listener * the new DocListener. */ public void addDocListener(DocListener listener) { listeners.add(listener); } /** * Removes a DocListener from the Document. * * @param listener * the DocListener that has to be removed. */ public void removeDocListener(DocListener listener) { listeners.remove(listener); } // methods implementing the DocListener interface /** * Adds an Element to the Document. * * @param element * the Element to add * @return true if the element was added, false * if not * @throws DocumentException * when a document isn't open yet, or has been closed */ public boolean add(Element element) throws DocumentException { if (close) { throw new DocumentException( "The document has been closed. You can't add any Elements."); } if (!open && element.isContent()) { throw new DocumentException( "The document is not open yet; you can only add Meta information."); } boolean success = false; DocListener listener; if (element instanceof ChapterAutoNumber) { chapternumber = ((ChapterAutoNumber)element).setAutomaticNumber(chapternumber); } for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); success |= listener.add(element); } if (element instanceof LargeElement) { LargeElement e = (LargeElement)element; if (!e.isComplete()) e.flushContent(); } return success; } /** * Opens the document. *

* Once the document is opened, you can't write any Header- or * Meta-information anymore. You have to open the document before you can * begin to add content to the body of the document. */ public void open() { if (!close) { open = true; } DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setPageSize(pageSize); listener.setMargins(marginLeft, marginRight, marginTop, marginBottom); listener.open(); } } /** * Sets the pagesize. * * @param pageSize * the new pagesize * @return a boolean */ public boolean setPageSize(Rectangle pageSize) { this.pageSize = pageSize; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setPageSize(pageSize); } return true; } /** * Sets the margins. * * @param marginLeft * the margin on the left * @param marginRight * the margin on the right * @param marginTop * the margin on the top * @param marginBottom * the margin on the bottom * @return a boolean */ public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { this.marginLeft = marginLeft; this.marginRight = marginRight; this.marginTop = marginTop; this.marginBottom = marginBottom; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setMargins(marginLeft, marginRight, marginTop, marginBottom); } return true; } /** * Signals that an new page has to be started. * * @return true if the page was added, false * if not. */ public boolean newPage() { if (!open || close) { return false; } DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.newPage(); } return true; } /** * Changes the header of this document. * * @param header * the new header */ public void setHeader(HeaderFooter header) { this.header = header; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setHeader(header); } } /** * Resets the header of this document. */ public void resetHeader() { this.header = null; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.resetHeader(); } } /** * Changes the footer of this document. * * @param footer * the new footer */ public void setFooter(HeaderFooter footer) { this.footer = footer; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setFooter(footer); } } /** * Resets the footer of this document. */ public void resetFooter() { this.footer = null; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.resetFooter(); } } /** * Sets the page number to 0. */ public void resetPageCount() { pageN = 0; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.resetPageCount(); } } /** * Sets the page number. * * @param pageN * the new page number */ public void setPageCount(int pageN) { this.pageN = pageN; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setPageCount(pageN); } } /** * Returns the current page number. * * @return the current page number */ public int getPageNumber() { return this.pageN; } /** * Closes the document. *

* Once all the content has been written in the body, you have to close the * body. After that nothing can be written to the body anymore. */ public void close() { if (!close) { open = false; close = true; } DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.close(); } } // methods concerning the header or some meta information /** * Adds a user defined header to the document. * * @param name * the name of the header * @param content * the content of the header * @return true if successful, false otherwise */ public boolean addHeader(String name, String content) { try { return add(new Header(name, content)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the title to a Document. * * @param title * the title * @return true if successful, false otherwise */ public boolean addTitle(String title) { try { return add(new Meta(Element.TITLE, title)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the subject to a Document. * * @param subject * the subject * @return true if successful, false otherwise */ public boolean addSubject(String subject) { try { return add(new Meta(Element.SUBJECT, subject)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the keywords to a Document. * * @param keywords * adds the keywords to the document * @return true if successful, false otherwise */ public boolean addKeywords(String keywords) { try { return add(new Meta(Element.KEYWORDS, keywords)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the author to a Document. * * @param author * the name of the author * @return true if successful, false otherwise */ public boolean addAuthor(String author) { try { return add(new Meta(Element.AUTHOR, author)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the creator to a Document. * * @param creator * the name of the creator * @return true if successful, false otherwise */ public boolean addCreator(String creator) { try { return add(new Meta(Element.CREATOR, creator)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the producer to a Document. * * @return true if successful, false otherwise */ public boolean addProducer() { try { return add(new Meta(Element.PRODUCER, getVersion())); } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Adds the current date and time to a Document. * * @return true if successful, false otherwise */ public boolean addCreationDate() { try { /* bugfix by 'taqua' (Thomas) */ final SimpleDateFormat sdf = new SimpleDateFormat( "EEE MMM dd HH:mm:ss zzz yyyy"); return add(new Meta(Element.CREATIONDATE, sdf.format(new Date()))); } catch (DocumentException de) { throw new ExceptionConverter(de); } } // methods to get the layout of the document. /** * Returns the left margin. * * @return the left margin */ public float leftMargin() { return marginLeft; } /** * Return the right margin. * * @return the right margin */ public float rightMargin() { return marginRight; } /** * Returns the top margin. * * @return the top margin */ public float topMargin() { return marginTop; } /** * Returns the bottom margin. * * @return the bottom margin */ public float bottomMargin() { return marginBottom; } /** * Returns the lower left x-coordinate. * * @return the lower left x-coordinate */ public float left() { return pageSize.getLeft(marginLeft); } /** * Returns the upper right x-coordinate. * * @return the upper right x-coordinate */ public float right() { return pageSize.getRight(marginRight); } /** * Returns the upper right y-coordinate. * * @return the upper right y-coordinate */ public float top() { return pageSize.getTop(marginTop); } /** * Returns the lower left y-coordinate. * * @return the lower left y-coordinate */ public float bottom() { return pageSize.getBottom(marginBottom); } /** * Returns the lower left x-coordinate considering a given margin. * * @param margin * a margin * @return the lower left x-coordinate */ public float left(float margin) { return pageSize.getLeft(marginLeft + margin); } /** * Returns the upper right x-coordinate, considering a given margin. * * @param margin * a margin * @return the upper right x-coordinate */ public float right(float margin) { return pageSize.getRight(marginRight + margin); } /** * Returns the upper right y-coordinate, considering a given margin. * * @param margin * a margin * @return the upper right y-coordinate */ public float top(float margin) { return pageSize.getTop(marginTop + margin); } /** * Returns the lower left y-coordinate, considering a given margin. * * @param margin * a margin * @return the lower left y-coordinate */ public float bottom(float margin) { return pageSize.getBottom(marginBottom + margin); } /** * Gets the pagesize. * * @return the page size */ public Rectangle getPageSize() { return this.pageSize; } /** * Checks if the document is open. * * @return true if the document is open */ public boolean isOpen() { return open; } /** * Gets the product name. * This method may only be changed by Paulo Soares and/or Bruno Lowagie. * @return the product name * @since 2.1.6 */ public static final String getProduct() { return ITEXT; } /** * Gets the release number. * This method may only be changed by Paulo Soares and/or Bruno Lowagie. * @return the product name * @since 2.1.6 */ public static final String getRelease() { return RELEASE; } /** * Gets the iText version. * This method may only be changed by Paulo Soares and/or Bruno Lowagie. * @return iText version */ public static final String getVersion() { return ITEXT_VERSION; } /** * Adds a JavaScript onLoad function to the HTML body tag * * @param code * the JavaScript code to be executed on load of the HTML page */ public void setJavaScript_onLoad(String code) { this.javaScript_onLoad = code; } /** * Gets the JavaScript onLoad command. * * @return the JavaScript onLoad command */ public String getJavaScript_onLoad() { return this.javaScript_onLoad; } /** * Adds a JavaScript onUnLoad function to the HTML body tag * * @param code * the JavaScript code to be executed on unload of the HTML page */ public void setJavaScript_onUnLoad(String code) { this.javaScript_onUnLoad = code; } /** * Gets the JavaScript onUnLoad command. * * @return the JavaScript onUnLoad command */ public String getJavaScript_onUnLoad() { return this.javaScript_onUnLoad; } /** * Adds a style class to the HTML body tag * * @param htmlStyleClass * the style class for the HTML body tag */ public void setHtmlStyleClass(String htmlStyleClass) { this.htmlStyleClass = htmlStyleClass; } /** * Gets the style class of the HTML body tag * * @return the style class of the HTML body tag */ public String getHtmlStyleClass() { return this.htmlStyleClass; } /** * Set the margin mirroring. It will mirror right/left margins for odd/even pages. *

* Note: it will not work with {@link Table}. * * @param marginMirroring * true to mirror the margins * @return always true */ public boolean setMarginMirroring(boolean marginMirroring) { this.marginMirroring = marginMirroring; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setMarginMirroring(marginMirroring); } return true; } /** * Set the margin mirroring. It will mirror top/bottom margins for odd/even pages. *

* Note: it will not work with {@link Table}. * * @param marginMirroringTopBottom * true to mirror the margins * @return always true * @since 2.1.6 */ public boolean setMarginMirroringTopBottom(boolean marginMirroringTopBottom) { this.marginMirroringTopBottom = marginMirroringTopBottom; DocListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (DocListener) iterator.next(); listener.setMarginMirroringTopBottom(marginMirroringTopBottom); } return true; } /** * Gets the margin mirroring flag. * * @return the margin mirroring flag */ public boolean isMarginMirroring() { return marginMirroring; } } src/core/com/lowagie/text/DocumentException.java100644 0 0 6637 11213370070 17423 0ustar 0 0 /* * $Id: DocumentException.java 3831 2009-04-01 16:31:17Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * */ package com.lowagie.text; /** * Signals that an error has occurred in a Document. * * @see BadElementException * @see Document * @see DocWriter * @see DocListener */ public class DocumentException extends Exception { /** A serial version UID */ private static final long serialVersionUID = -2191131489390840739L; /** * Creates a Document exception. * @param ex an exception that has to be turned into a DocumentException */ public DocumentException(Exception ex) { super(ex); } // constructors /** * Constructs a DocumentException without a message. */ public DocumentException() { super(); } /** * Constructs a DocumentException with a message. * * @param message a message describing the exception */ public DocumentException(String message) { super(message); } } src/core/com/lowagie/text/Element.java100644 0 0 24603 11154165267 15406 0ustar 0 0 /* * $Id: Element.java 3672 2009-02-01 15:32:09Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; /** * Interface for a text element. *

* Remark: I looked at the interface javax.swing.text.Element, but I decided to * write my own text-classes for two reasons: *

    *
  1. The javax.swing.text-classes may be very generic, I think they are * overkill: they are to heavy for what they have to do. *
  2. A lot of people using iText (formerly known as rugPdf), still use * JDK1.1.x. I try to keep the Java2 requirements limited to the Collection * classes (I think they're really great). However, if I use the * javax.swing.text classes, it will become very difficult to downgrade rugPdf. *
* * @see Anchor * @see Cell * @see Chapter * @see Chunk * @see Header * @see Image * @see Jpeg * @see List * @see ListItem * @see Meta * @see Paragraph * @see Phrase * @see Rectangle * @see Row * @see Section * @see Table */ public interface Element { // static membervariables (meta information) /** This is a possible type of Element. */ public static final int HEADER = 0; /** This is a possible type of Element. */ public static final int TITLE = 1; /** This is a possible type of Element. */ public static final int SUBJECT = 2; /** This is a possible type of Element. */ public static final int KEYWORDS = 3; /** This is a possible type of Element . */ public static final int AUTHOR = 4; /** This is a possible type of Element . */ public static final int PRODUCER = 5; /** This is a possible type of Element . */ public static final int CREATIONDATE = 6; /** This is a possible type of Element . */ public static final int CREATOR = 7; // static membervariables (content) /** This is a possible type of Element. */ public static final int CHUNK = 10; /** This is a possible type of Element. */ public static final int PHRASE = 11; /** This is a possible type of Element. */ public static final int PARAGRAPH = 12; /** This is a possible type of Element */ public static final int SECTION = 13; /** This is a possible type of Element */ public static final int LIST = 14; /** This is a possible type of Element */ public static final int LISTITEM = 15; /** This is a possible type of Element */ public static final int CHAPTER = 16; /** This is a possible type of Element */ public static final int ANCHOR = 17; // static membervariables (tables) /** This is a possible type of Element. */ public static final int CELL = 20; /** This is a possible type of Element. */ public static final int ROW = 21; /** This is a possible type of Element. */ public static final int TABLE = 22; /** This is a possible type of Element. */ public static final int PTABLE = 23; // static membervariables (annotations) /** This is a possible type of Element. */ public static final int ANNOTATION = 29; // static membervariables (geometric figures) /** This is a possible type of Element. */ public static final int RECTANGLE = 30; /** This is a possible type of Element. */ public static final int JPEG = 32; /** This is a possible type of Element. */ public static final int JPEG2000 = 33; /** This is a possible type of Element. */ public static final int IMGRAW = 34; /** This is a possible type of Element. */ public static final int IMGTEMPLATE = 35; /** * This is a possible type of Element. * @since 2.1.5 */ public static final int JBIG2 = 36; /** This is a possible type of Element. */ public static final int MULTI_COLUMN_TEXT = 40; /** This is a possible type of Element. */ public static final int MARKED = 50; /** This is a possible type of Element. * @since 2.1.2 */ public static final int YMARK = 55; // static membervariables (alignment) /** * A possible value for paragraph alignment. This specifies that the text is * aligned to the left indent and extra whitespace should be placed on the * right. */ public static final int ALIGN_UNDEFINED = -1; /** * A possible value for paragraph alignment. This specifies that the text is * aligned to the left indent and extra whitespace should be placed on the * right. */ public static final int ALIGN_LEFT = 0; /** * A possible value for paragraph alignment. This specifies that the text is * aligned to the center and extra whitespace should be placed equally on * the left and right. */ public static final int ALIGN_CENTER = 1; /** * A possible value for paragraph alignment. This specifies that the text is * aligned to the right indent and extra whitespace should be placed on the * left. */ public static final int ALIGN_RIGHT = 2; /** * A possible value for paragraph alignment. This specifies that extra * whitespace should be spread out through the rows of the paragraph with * the text lined up with the left and right indent except on the last line * which should be aligned to the left. */ public static final int ALIGN_JUSTIFIED = 3; /** * A possible value for vertical alignment. */ public static final int ALIGN_TOP = 4; /** * A possible value for vertical alignment. */ public static final int ALIGN_MIDDLE = 5; /** * A possible value for vertical alignment. */ public static final int ALIGN_BOTTOM = 6; /** * A possible value for vertical alignment. */ public static final int ALIGN_BASELINE = 7; /** * Does the same as ALIGN_JUSTIFIED but the last line is also spread out. */ public static final int ALIGN_JUSTIFIED_ALL = 8; // static member variables for CCITT compression /** * Pure two-dimensional encoding (Group 4) */ public static final int CCITTG4 = 0x100; /** * Pure one-dimensional encoding (Group 3, 1-D) */ public static final int CCITTG3_1D = 0x101; /** * Mixed one- and two-dimensional encoding (Group 3, 2-D) */ public static final int CCITTG3_2D = 0x102; /** * A flag indicating whether 1-bits are to be interpreted as black pixels * and 0-bits as white pixels, */ public static final int CCITT_BLACKIS1 = 1; /** * A flag indicating whether the filter expects extra 0-bits before each * encoded line so that the line begins on a byte boundary. */ public static final int CCITT_ENCODEDBYTEALIGN = 2; /** * A flag indicating whether end-of-line bit patterns are required to be * present in the encoding. */ public static final int CCITT_ENDOFLINE = 4; /** * A flag indicating whether the filter expects the encoded data to be * terminated by an end-of-block pattern, overriding the Rows parameter. The * use of this flag will set the key /EndOfBlock to false. */ public static final int CCITT_ENDOFBLOCK = 8; // methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener * an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener); /** * Gets the type of the text element. * * @return a type */ public int type(); /** * Checks if this element is a content object. * If not, it's a metadata object. * @since iText 2.0.8 * @return true if this is a 'content' element; false if this is a 'metadata' element */ public boolean isContent(); /** * Checks if this element is nestable. * @since iText 2.0.8 * @return true if this element can be nested inside other elements. */ public boolean isNestable(); /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks(); /** * Gets the content of the text element. * * @return a type */ public String toString(); }src/core/com/lowagie/text/ElementListener.java100644 0 0 6157 11012562273 17067 0ustar 0 0 /* * $Id: ElementListener.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.EventListener; /** * A class that implements ElementListener will perform some * actions when an Element is added. * * @see DocListener */ public interface ElementListener extends EventListener { // methods /** * Signals that an Element was added to the Document. * * @param element a high level object * @return true if the element was added, false if not. * @throws DocumentException when a document isn't open yet, or has been closed */ public boolean add(Element element) throws DocumentException; // [L0] }src/core/com/lowagie/text/ElementTags.java100644 0 0 42656 11036112746 16226 0ustar 0 0 /* * $Id: ElementTags.java 3533 2008-07-07 21:27:13Z Howard_s $ * * Copyright (c) 2001, 2002 Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * A class that contains all the possible tagnames and their attributes. */ public class ElementTags { /** the root tag. */ public static final String ITEXT = "itext"; /** attribute of the root and annotation tag (also a special tag within a chapter or section) */ public static final String TITLE = "title"; /** attribute of the root tag */ public static final String SUBJECT = "subject"; /** attribute of the root tag */ public static final String KEYWORDS = "keywords"; /** attribute of the root tag */ public static final String AUTHOR = "author"; /** attribute of the root tag */ public static final String CREATIONDATE = "creationdate"; /** attribute of the root tag */ public static final String PRODUCER = "producer"; // Chapters and Sections /** the chapter tag */ public static final String CHAPTER = "chapter"; /** the section tag */ public static final String SECTION = "section"; /** attribute of section/chapter tag */ public static final String NUMBERDEPTH = "numberdepth"; /** attribute of section/chapter tag */ public static final String DEPTH = "depth"; /** attribute of section/chapter tag */ public static final String NUMBER = "number"; /** attribute of section/chapter tag */ public static final String INDENT = "indent"; /** attribute of chapter/section/paragraph/table/cell tag */ public static final String LEFT = "left"; /** attribute of chapter/section/paragraph/table/cell tag */ public static final String RIGHT = "right"; // Phrases, Anchors, Lists and Paragraphs /** the phrase tag */ public static final String PHRASE = "phrase"; /** the anchor tag */ public static final String ANCHOR = "anchor"; /** the list tag */ public static final String LIST = "list"; /** the listitem tag */ public static final String LISTITEM = "listitem"; /** the paragraph tag */ public static final String PARAGRAPH = "paragraph"; /** attribute of phrase/paragraph/cell tag */ public static final String LEADING = "leading"; /** attribute of paragraph/image/table tag */ public static final String ALIGN = "align"; /** attribute of paragraph */ public static final String KEEPTOGETHER = "keeptogether"; /** attribute of anchor tag */ public static final String NAME = "name"; /** attribute of anchor tag */ public static final String REFERENCE = "reference"; /** attribute of list tag */ public static final String LISTSYMBOL = "listsymbol"; /** attribute of list tag */ public static final String NUMBERED = "numbered"; /** attribute of the list tag */ public static final String LETTERED = "lettered"; /** attribute of list tag */ public static final String FIRST = "first"; /** attribute of list tag */ public static final String SYMBOLINDENT = "symbolindent"; /** attribute of list tag */ public static final String INDENTATIONLEFT = "indentationleft"; /** attribute of list tag */ public static final String INDENTATIONRIGHT = "indentationright"; // Chunks /** the chunk tag */ public static final String IGNORE = "ignore"; /** the chunk tag */ public static final String ENTITY = "entity"; /** the chunk tag */ public static final String ID = "id"; /** the chunk tag */ public static final String CHUNK = "chunk"; /** attribute of the chunk tag */ public static final String ENCODING = "encoding"; /** attribute of the chunk tag */ public static final String EMBEDDED = "embedded"; /** attribute of the chunk/table/cell tag */ public static final String COLOR = "color"; /** attribute of the chunk/table/cell tag */ public static final String RED = "red"; /** attribute of the chunk/table/cell tag */ public static final String GREEN = "green"; /** attribute of the chunk/table/cell tag */ public static final String BLUE = "blue"; /** attribute of the chunk tag */ public static final String SUBSUPSCRIPT = Chunk.SUBSUPSCRIPT.toLowerCase(); /** attribute of the chunk tag */ public static final String LOCALGOTO = Chunk.LOCALGOTO.toLowerCase(); /** attribute of the chunk tag */ public static final String REMOTEGOTO = Chunk.REMOTEGOTO.toLowerCase(); /** attribute of the chunk tag */ public static final String LOCALDESTINATION = Chunk.LOCALDESTINATION.toLowerCase(); /** attribute of the chunk tag */ public static final String GENERICTAG = Chunk.GENERICTAG.toLowerCase(); // tables/cells /** the table tag */ public static final String TABLE = "table"; /** the cell tag */ public static final String ROW = "row"; /** the cell tag */ public static final String CELL = "cell"; /** attribute of the table tag */ public static final String COLUMNS = "columns"; /** attribute of the table tag */ public static final String LASTHEADERROW = "lastHeaderRow"; /** attribute of the table tag */ public static final String CELLPADDING = "cellpadding"; /** attribute of the table tag */ public static final String CELLSPACING = "cellspacing"; /** attribute of the table tag */ public static final String OFFSET = "offset"; /** attribute of the table tag */ public static final String WIDTHS = "widths"; /** attribute of the table tag */ public static final String TABLEFITSPAGE = "tablefitspage"; /** attribute of the table tag */ public static final String CELLSFITPAGE = "cellsfitpage"; /** attribute of the table tag */ public static final String CONVERT2PDFP = "convert2pdfp"; /** attribute of the cell tag */ public static final String HORIZONTALALIGN = "horizontalalign"; /** attribute of the cell tag */ public static final String VERTICALALIGN = "verticalalign"; /** attribute of the cell tag */ public static final String COLSPAN = "colspan"; /** attribute of the cell tag */ public static final String ROWSPAN = "rowspan"; /** attribute of the cell tag */ public static final String HEADER = "header"; /** attribute of the cell tag */ public static final String NOWRAP = "nowrap"; /** attribute of the table/cell tag */ public static final String BORDERWIDTH = "borderwidth"; /** attribute of the table/cell tag */ public static final String TOP = "top"; /** attribute of the table/cell tag */ public static final String BOTTOM = "bottom"; /** attribute of the table/cell tag */ public static final String WIDTH = "width"; /** attribute of the table/cell tag */ public static final String BORDERCOLOR = "bordercolor"; /** attribute of the table/cell tag */ public static final String BACKGROUNDCOLOR = "backgroundcolor"; /** attribute of the table/cell tag */ public static final String BGRED = "bgred"; /** attribute of the table/cell tag */ public static final String BGGREEN = "bggreen"; /** attribute of the table/cell tag */ public static final String BGBLUE = "bgblue"; /** attribute of the table/cell tag */ public static final String GRAYFILL = "grayfill"; // Misc /** the image tag */ public static final String IMAGE = "image"; /** attribute of the image and annotation tag */ public static final String URL = "url"; /** attribute of the image tag */ public static final String UNDERLYING = "underlying"; /** attribute of the image tag */ public static final String TEXTWRAP = "textwrap"; /** attribute of the image tag */ public static final String ALT = "alt"; /** attribute of the image tag */ public static final String ABSOLUTEX = "absolutex"; /** attribute of the image tag */ public static final String ABSOLUTEY = "absolutey"; /** attribute of the image tag */ public static final String PLAINWIDTH = "plainwidth"; /** attribute of the image tag */ public static final String PLAINHEIGHT = "plainheight"; /** attribute of the image tag */ public static final String SCALEDWIDTH = "scaledwidth"; /** attribute of the image tag */ public static final String SCALEDHEIGHT = "scaledheight"; /** attribute of the image tag */ public static final String ROTATION = "rotation"; /** the newpage tag */ public static final String NEWPAGE = "newpage"; /** the newpage tag */ public static final String NEWLINE = "newline"; /** the annotation tag */ public static final String ANNOTATION = "annotation"; /** attribute of the annotation tag */ public static final String FILE = "file"; /** attribute of the annotation tag */ public static final String DESTINATION = "destination"; /** attribute of the annotation tag */ public static final String PAGE = "page"; /** attribute of the annotation tag */ public static final String NAMED = "named"; /** attribute of the annotation tag */ public static final String APPLICATION = "application"; /** attribute of the annotation tag */ public static final String PARAMETERS = "parameters"; /** attribute of the annotation tag */ public static final String OPERATION = "operation"; /** attribute of the annotation tag */ public static final String DEFAULTDIR = "defaultdir"; /** attribute of the annotation tag */ public static final String LLX = "llx"; /** attribute of the annotation tag */ public static final String LLY = "lly"; /** attribute of the annotation tag */ public static final String URX = "urx"; /** attribute of the annotation tag */ public static final String URY = "ury"; /** attribute of the annotation tag */ public static final String CONTENT = "content"; // alignment attribute values /** the possible value of an alignment attribute */ public static final String ALIGN_LEFT = "Left"; /** the possible value of an alignment attribute */ public static final String ALIGN_CENTER = "Center"; /** the possible value of an alignment attribute */ public static final String ALIGN_RIGHT = "Right"; /** the possible value of an alignment attribute */ public static final String ALIGN_JUSTIFIED = "Justify"; /** the possible value of an alignment attribute */ public static final String ALIGN_JUSTIFIED_ALL = "JustifyAll"; /** the possible value of an alignment attribute */ public static final String ALIGN_TOP = "Top"; /** the possible value of an alignment attribute */ public static final String ALIGN_MIDDLE = "Middle"; /** the possible value of an alignment attribute */ public static final String ALIGN_BOTTOM = "Bottom"; /** the possible value of an alignment attribute */ public static final String ALIGN_BASELINE = "Baseline"; /** the possible value of an alignment attribute */ public static final String DEFAULT = "Default"; /** the possible value of an alignment attribute */ public static final String UNKNOWN = "unknown"; /** the possible value of an alignment attribute */ public static final String FONT = "font"; /** the possible value of an alignment attribute */ public static final String SIZE = "size"; /** the possible value of an alignment attribute */ public static final String STYLE = "fontstyle"; /** the possible value of a tag */ public static final String HORIZONTALRULE = "horizontalrule"; /** the possible value of a tag */ public static final String PAGE_SIZE = "pagesize"; /** the possible value of a tag */ public static final String ORIENTATION = "orientation"; /** a possible list attribute */ public static final String ALIGN_INDENTATION_ITEMS = "alignindent"; /** a possible list attribute */ public static final String AUTO_INDENT_ITEMS = "autoindent"; /** a possible list attribute */ public static final String LOWERCASE = "lowercase"; /** * a possible list attribute * @since 2.1.3 */ public static final String FACE = "face"; /** attribute of the image or iframe tag * @since 2.1.3 */ public static final String SRC = "src"; // methods /** * Translates the alignment value to a String value. * * @param alignment the alignment value * @return the translated value */ public static String getAlignment(int alignment) { switch(alignment) { case Element.ALIGN_LEFT: return ALIGN_LEFT; case Element.ALIGN_CENTER: return ALIGN_CENTER; case Element.ALIGN_RIGHT: return ALIGN_RIGHT; case Element.ALIGN_JUSTIFIED: case Element.ALIGN_JUSTIFIED_ALL: return ALIGN_JUSTIFIED; case Element.ALIGN_TOP: return ALIGN_TOP; case Element.ALIGN_MIDDLE: return ALIGN_MIDDLE; case Element.ALIGN_BOTTOM: return ALIGN_BOTTOM; case Element.ALIGN_BASELINE: return ALIGN_BASELINE; default: return DEFAULT; } } /** * Translates a String value to an alignment value. * (written by Norman Richards, integrated into iText by Bruno) * @param alignment a String (one of the ALIGN_ constants of this class) * @return an alignment value (one of the ALIGN_ constants of the Element interface) */ public static int alignmentValue(String alignment) { if (alignment == null) return Element.ALIGN_UNDEFINED; if (ALIGN_CENTER.equalsIgnoreCase(alignment)) { return Element.ALIGN_CENTER; } if (ALIGN_LEFT.equalsIgnoreCase(alignment)) { return Element.ALIGN_LEFT; } if (ALIGN_RIGHT.equalsIgnoreCase(alignment)) { return Element.ALIGN_RIGHT; } if (ALIGN_JUSTIFIED.equalsIgnoreCase(alignment)) { return Element.ALIGN_JUSTIFIED; } if (ALIGN_JUSTIFIED_ALL.equalsIgnoreCase(alignment)) { return Element.ALIGN_JUSTIFIED_ALL; } if (ALIGN_TOP.equalsIgnoreCase(alignment)) { return Element.ALIGN_TOP; } if (ALIGN_MIDDLE.equalsIgnoreCase(alignment)) { return Element.ALIGN_MIDDLE; } if (ALIGN_BOTTOM.equalsIgnoreCase(alignment)) { return Element.ALIGN_BOTTOM; } if (ALIGN_BASELINE.equalsIgnoreCase(alignment)) { return Element.ALIGN_BASELINE; } return Element.ALIGN_UNDEFINED; } }src/core/com/lowagie/text/ExceptionConverter.java100644 0 0 13254 11213370070 17625 0ustar 0 0 /* * The original version of this class was published in an article by professor Heinz Kabutz. * Read http://www.javaspecialists.co.za/archive/newsletter.do?issue=033&print=yes&locale=en_US * "This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). * Please contact Maximum Solutions for more information." * * Copyright (C) 2001 Dr. Heinz M. Kabutz */ /* * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * The ExceptionConverter changes a checked exception into an * unchecked exception. */ public class ExceptionConverter extends RuntimeException { private static final long serialVersionUID = 8657630363395849399L; /** we keep a handle to the wrapped exception */ private Exception ex; /** prefix for the exception */ private String prefix; /** * Construct a RuntimeException based on another Exception * @param ex the exception that has to be turned into a RuntimeException */ public ExceptionConverter(Exception ex) { this.ex = ex; prefix = (ex instanceof RuntimeException) ? "" : "ExceptionConverter: "; } /** * Convert an Exception into an unchecked exception. Return the exception if it is * already an unchecked exception or return an ExceptionConverter wrapper otherwise * * @param ex the exception to convert * @return an unchecked exception * @since 2.1.6 */ public static final RuntimeException convertException(Exception ex) { if (ex instanceof RuntimeException) { return (RuntimeException) ex; } return new ExceptionConverter(ex); } /** * and allow the user of ExceptionConverter to get a handle to it. * @return the original exception */ public Exception getException() { return ex; } /** * We print the message of the checked exception * @return message of the original exception */ public String getMessage() { return ex.getMessage(); } /** * and make sure we also produce a localized version * @return localized version of the message */ public String getLocalizedMessage() { return ex.getLocalizedMessage(); } /** * The toString() is changed to be prefixed with ExceptionConverter * @return String version of the exception */ public String toString() { return prefix + ex; } /** we have to override this as well */ public void printStackTrace() { printStackTrace(System.err); } /** * here we prefix, with s.print(), not s.println(), the stack * trace with "ExceptionConverter:" * @param s */ public void printStackTrace(java.io.PrintStream s) { synchronized (s) { s.print(prefix); ex.printStackTrace(s); } } /** * Again, we prefix the stack trace with "ExceptionConverter:" * @param s */ public void printStackTrace(java.io.PrintWriter s) { synchronized (s) { s.print(prefix); ex.printStackTrace(s); } } /** * requests to fill in the stack trace we will have to ignore. * We can't throw an exception here, because this method * is called by the constructor of Throwable * @return a Throwable */ public Throwable fillInStackTrace() { return this; } }src/core/com/lowagie/text/Font.java100644 0 0 43366 11154165267 14732 0ustar 0 0 /* * $Id: Font.java 3678 2009-02-07 14:46:01Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; import com.lowagie.text.html.Markup; import com.lowagie.text.pdf.BaseFont; /** * Contains all the specifications of a font: fontfamily, size, style and color. *

* Example:

* *
 * 
 * Paragraph p = new Paragraph("This is a paragraph", new
 * Font(Font.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)) );
 * 
 * 
* *
*/ public class Font implements Comparable { // static membervariables for the different families /** a possible value of a font family. */ public static final int COURIER = 0; /** a possible value of a font family. */ public static final int HELVETICA = 1; /** a possible value of a font family. */ public static final int TIMES_ROMAN = 2; /** a possible value of a font family. */ public static final int SYMBOL = 3; /** a possible value of a font family. */ public static final int ZAPFDINGBATS = 4; // static membervariables for the different styles /** this is a possible style. */ public static final int NORMAL = 0; /** this is a possible style. */ public static final int BOLD = 1; /** this is a possible style. */ public static final int ITALIC = 2; /** this is a possible style. */ public static final int UNDERLINE = 4; /** this is a possible style. */ public static final int STRIKETHRU = 8; /** this is a possible style. */ public static final int BOLDITALIC = BOLD | ITALIC; // static membervariables /** the value of an undefined attribute. */ public static final int UNDEFINED = -1; /** the value of the default size. */ public static final int DEFAULTSIZE = 12; // membervariables /** the value of the fontfamily. */ private int family = UNDEFINED; /** the value of the fontsize. */ private float size = UNDEFINED; /** the value of the style. */ private int style = UNDEFINED; /** the value of the color. */ private Color color = null; /** the external font */ private BaseFont baseFont = null; // constructors /** * Copy constructor of a Font * * @param other * the font that has to be copied */ public Font(Font other) { this.family = other.family; this.size = other.size; this.style = other.style; this.color = other.color; this.baseFont = other.baseFont; } /** * Constructs a Font. * * @param family * the family to which this font belongs * @param size * the size of this font * @param style * the style of this font * @param color * the Color of this font. */ public Font(int family, float size, int style, Color color) { this.family = family; this.size = size; this.style = style; this.color = color; } /** * Constructs a Font. * * @param bf * the external font * @param size * the size of this font * @param style * the style of this font * @param color * the Color of this font. */ public Font(BaseFont bf, float size, int style, Color color) { this.baseFont = bf; this.size = size; this.style = style; this.color = color; } /** * Constructs a Font. * * @param bf * the external font * @param size * the size of this font * @param style * the style of this font */ public Font(BaseFont bf, float size, int style) { this(bf, size, style, null); } /** * Constructs a Font. * * @param bf * the external font * @param size * the size of this font */ public Font(BaseFont bf, float size) { this(bf, size, UNDEFINED, null); } /** * Constructs a Font. * * @param bf * the external font */ public Font(BaseFont bf) { this(bf, UNDEFINED, UNDEFINED, null); } /** * Constructs a Font. * * @param family * the family to which this font belongs * @param size * the size of this font * @param style * the style of this font */ public Font(int family, float size, int style) { this(family, size, style, null); } /** * Constructs a Font. * * @param family * the family to which this font belongs * @param size * the size of this font */ public Font(int family, float size) { this(family, size, UNDEFINED, null); } /** * Constructs a Font. * * @param family * the family to which this font belongs */ public Font(int family) { this(family, UNDEFINED, UNDEFINED, null); } /** * Constructs a Font. */ public Font() { this(UNDEFINED, UNDEFINED, UNDEFINED, null); } // implementation of the Comparable interface /** * Compares this Font with another * * @param object * the other Font * @return a value */ public int compareTo(Object object) { if (object == null) { return -1; } Font font; try { font = (Font) object; if (baseFont != null && !baseFont.equals(font.getBaseFont())) { return -2; } if (this.family != font.getFamily()) { return 1; } if (this.size != font.getSize()) { return 2; } if (this.style != font.getStyle()) { return 3; } if (this.color == null) { if (font.color == null) { return 0; } return 4; } if (font.color == null) { return 4; } if (this.color.equals(font.getColor())) { return 0; } return 4; } catch (ClassCastException cce) { return -3; } } // FAMILY /** * Gets the family of this font. * * @return the value of the family */ public int getFamily() { return family; } /** * Gets the familyname as a String. * * @return the familyname */ public String getFamilyname() { String tmp = "unknown"; switch (getFamily()) { case Font.COURIER: return FontFactory.COURIER; case Font.HELVETICA: return FontFactory.HELVETICA; case Font.TIMES_ROMAN: return FontFactory.TIMES_ROMAN; case Font.SYMBOL: return FontFactory.SYMBOL; case Font.ZAPFDINGBATS: return FontFactory.ZAPFDINGBATS; default: if (baseFont != null) { String[][] names = baseFont.getFamilyFontName(); for (int i = 0; i < names.length; i++) { if ("0".equals(names[i][2])) { return names[i][3]; } if ("1033".equals(names[i][2])) { tmp = names[i][3]; } if ("".equals(names[i][2])) { tmp = names[i][3]; } } } } return tmp; } /** * Sets the family using a String ("Courier", "Helvetica", * "Times New Roman", "Symbol" or "ZapfDingbats"). * * @param family * A String representing a certain font-family. */ public void setFamily(String family) { this.family = getFamilyIndex(family); } /** * Translates a String -value of a certain family into the * index that is used for this family in this class. * * @param family * A String representing a certain font-family * @return the corresponding index */ public static int getFamilyIndex(String family) { if (family.equalsIgnoreCase(FontFactory.COURIER)) { return COURIER; } if (family.equalsIgnoreCase(FontFactory.HELVETICA)) { return HELVETICA; } if (family.equalsIgnoreCase(FontFactory.TIMES_ROMAN)) { return TIMES_ROMAN; } if (family.equalsIgnoreCase(FontFactory.SYMBOL)) { return SYMBOL; } if (family.equalsIgnoreCase(FontFactory.ZAPFDINGBATS)) { return ZAPFDINGBATS; } return UNDEFINED; } // SIZE /** * Gets the size of this font. * * @return a size */ public float getSize() { return size; } /** * Gets the size that can be used with the calculated BaseFont * . * * @return the size that can be used with the calculated BaseFont * */ public float getCalculatedSize() { float s = this.size; if (s == UNDEFINED) { s = DEFAULTSIZE; } return s; } /** * Gets the leading that can be used with this font. * * @param linespacing * a certain linespacing * @return the height of a line */ public float getCalculatedLeading(float linespacing) { return linespacing * getCalculatedSize(); } /** * Sets the size. * * @param size * The new size of the font. */ public void setSize(float size) { this.size = size; } // STYLE /** * Gets the style of this font. * * @return a size */ public int getStyle() { return style; } /** * Gets the style that can be used with the calculated BaseFont * . * * @return the style that can be used with the calculated BaseFont * */ public int getCalculatedStyle() { int style = this.style; if (style == UNDEFINED) { style = NORMAL; } if (baseFont != null) return style; if (family == SYMBOL || family == ZAPFDINGBATS) return style; else return style & (~BOLDITALIC); } /** * checks if this font is Bold. * * @return a boolean */ public boolean isBold() { if (style == UNDEFINED) { return false; } return (style & BOLD) == BOLD; } /** * checks if this font is Bold. * * @return a boolean */ public boolean isItalic() { if (style == UNDEFINED) { return false; } return (style & ITALIC) == ITALIC; } /** * checks if this font is underlined. * * @return a boolean */ public boolean isUnderlined() { if (style == UNDEFINED) { return false; } return (style & UNDERLINE) == UNDERLINE; } /** * checks if the style of this font is STRIKETHRU. * * @return a boolean */ public boolean isStrikethru() { if (style == UNDEFINED) { return false; } return (style & STRIKETHRU) == STRIKETHRU; } /** * Sets the style. * * @param style * the style. */ public void setStyle(int style) { this.style = style; } /** * Sets the style using a String containing one of more of * the following values: normal, bold, italic, underline, strike. * * @param style * A String representing a certain style. */ public void setStyle(String style) { if (this.style == UNDEFINED) this.style = NORMAL; this.style |= getStyleValue(style); } /** * Translates a String -value of a certain style into the * index value is used for this style in this class. * * @param style * A String * @return the corresponding value */ public static int getStyleValue(String style) { int s = 0; if (style.indexOf(Markup.CSS_VALUE_NORMAL) != -1) { s |= NORMAL; } if (style.indexOf(Markup.CSS_VALUE_BOLD) != -1) { s |= BOLD; } if (style.indexOf(Markup.CSS_VALUE_ITALIC) != -1) { s |= ITALIC; } if (style.indexOf(Markup.CSS_VALUE_OBLIQUE) != -1) { s |= ITALIC; } if (style.indexOf(Markup.CSS_VALUE_UNDERLINE) != -1) { s |= UNDERLINE; } if (style.indexOf(Markup.CSS_VALUE_LINETHROUGH) != -1) { s |= STRIKETHRU; } return s; } // COLOR /** * Gets the color of this font. * * @return a color */ public Color getColor() { return color; } /** * Sets the color. * * @param color * the new color of the font */ public void setColor(Color color) { this.color = color; } /** * Sets the color. * * @param red * the red-value of the new color * @param green * the green-value of the new color * @param blue * the blue-value of the new color */ public void setColor(int red, int green, int blue) { this.color = new Color(red, green, blue); } // BASEFONT /** * Gets the BaseFont inside this object. * * @return the BaseFont */ public BaseFont getBaseFont() { return baseFont; } /** * Gets the BaseFont this class represents. For the built-in * fonts a BaseFont is calculated. * * @param specialEncoding * true to use the special encoding for Symbol and * ZapfDingbats, false to always use Cp1252 * * @return the BaseFont this class represents */ public BaseFont getCalculatedBaseFont(boolean specialEncoding) { if (baseFont != null) return baseFont; int style = this.style; if (style == UNDEFINED) { style = NORMAL; } String fontName = BaseFont.HELVETICA; String encoding = BaseFont.WINANSI; BaseFont cfont = null; switch (family) { case COURIER: switch (style & BOLDITALIC) { case BOLD: fontName = BaseFont.COURIER_BOLD; break; case ITALIC: fontName = BaseFont.COURIER_OBLIQUE; break; case BOLDITALIC: fontName = BaseFont.COURIER_BOLDOBLIQUE; break; default: //case NORMAL: fontName = BaseFont.COURIER; break; } break; case TIMES_ROMAN: switch (style & BOLDITALIC) { case BOLD: fontName = BaseFont.TIMES_BOLD; break; case ITALIC: fontName = BaseFont.TIMES_ITALIC; break; case BOLDITALIC: fontName = BaseFont.TIMES_BOLDITALIC; break; default: case NORMAL: fontName = BaseFont.TIMES_ROMAN; break; } break; case SYMBOL: fontName = BaseFont.SYMBOL; if (specialEncoding) encoding = BaseFont.SYMBOL; break; case ZAPFDINGBATS: fontName = BaseFont.ZAPFDINGBATS; if (specialEncoding) encoding = BaseFont.ZAPFDINGBATS; break; default: case Font.HELVETICA: switch (style & BOLDITALIC) { case BOLD: fontName = BaseFont.HELVETICA_BOLD; break; case ITALIC: fontName = BaseFont.HELVETICA_OBLIQUE; break; case BOLDITALIC: fontName = BaseFont.HELVETICA_BOLDOBLIQUE; break; default: case NORMAL: fontName = BaseFont.HELVETICA; break; } break; } try { cfont = BaseFont.createFont(fontName, encoding, false); } catch (Exception ee) { throw new ExceptionConverter(ee); } return cfont; } // Helper methods /** * Checks if the properties of this font are undefined or null. *

* If so, the standard should be used. * * @return a boolean */ public boolean isStandardFont() { return (family == UNDEFINED && size == UNDEFINED && style == UNDEFINED && color == null && baseFont == null); } /** * Replaces the attributes that are equal to null with the * attributes of a given font. * * @param font * the font of a bigger element class * @return a Font */ public Font difference(Font font) { if (font == null) return this; // size float dSize = font.size; if (dSize == UNDEFINED) { dSize = this.size; } // style int dStyle = UNDEFINED; int style1 = this.style; int style2 = font.getStyle(); if (style1 != UNDEFINED || style2 != UNDEFINED) { if (style1 == UNDEFINED) style1 = 0; if (style2 == UNDEFINED) style2 = 0; dStyle = style1 | style2; } // color Color dColor = font.color; if (dColor == null) { dColor = this.color; } // family if (font.baseFont != null) { return new Font(font.baseFont, dSize, dStyle, dColor); } if (font.getFamily() != UNDEFINED) { return new Font(font.family, dSize, dStyle, dColor); } if (this.baseFont != null) { if (dStyle == style1) { return new Font(this.baseFont, dSize, dStyle, dColor); } else { return FontFactory.getFont(this.getFamilyname(), dSize, dStyle, dColor); } } return new Font(this.family, dSize, dStyle, dColor); } } src/core/com/lowagie/text/FontFactory.java100644 0 0 36701 11012562273 16244 0ustar 0 0 /* * $Id: FontFactory.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; import java.util.Properties; import java.util.Set; import com.lowagie.text.pdf.BaseFont; /** * If you are using True Type fonts, you can declare the paths of the different ttf- and ttc-files * to this static class first and then create fonts in your code using one of the static getFont-method * without having to enter a path as parameter. * * @author Bruno Lowagie */ public final class FontFactory { /** This is a possible value of a base 14 type 1 font */ public static final String COURIER = BaseFont.COURIER; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_BOLD = BaseFont.COURIER_BOLD; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_OBLIQUE = BaseFont.COURIER_OBLIQUE; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_BOLDOBLIQUE = BaseFont.COURIER_BOLDOBLIQUE; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA = BaseFont.HELVETICA; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_BOLD = BaseFont.HELVETICA_BOLD; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_OBLIQUE = BaseFont.HELVETICA_OBLIQUE; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_BOLDOBLIQUE = BaseFont.HELVETICA_BOLDOBLIQUE; /** This is a possible value of a base 14 type 1 font */ public static final String SYMBOL = BaseFont.SYMBOL; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES = "Times"; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_ROMAN = BaseFont.TIMES_ROMAN; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_BOLD = BaseFont.TIMES_BOLD; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_ITALIC = BaseFont.TIMES_ITALIC; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_BOLDITALIC = BaseFont.TIMES_BOLDITALIC; /** This is a possible value of a base 14 type 1 font */ public static final String ZAPFDINGBATS = BaseFont.ZAPFDINGBATS; private static FontFactoryImp fontImp = new FontFactoryImp(); /** This is the default encoding to use. */ public static String defaultEncoding = BaseFont.WINANSI; /** This is the default value of the embedded variable. */ public static boolean defaultEmbedding = BaseFont.NOT_EMBEDDED; /** Creates new FontFactory */ private FontFactory() { } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color) { return fontImp.getFont(fontname, encoding, embedded, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @param cached true if the font comes from the cache or is added to * the cache if new, false if the font is always created new * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color, boolean cached) { return fontImp.getFont(fontname, encoding, embedded, size, style, color, cached); } /** * Constructs a Font-object. * * @param attributes the attributes of a Font object. * @return the Font constructed based on the attributes */ public static Font getFont(Properties attributes) { fontImp.defaultEmbedding = defaultEmbedding; fontImp.defaultEncoding = defaultEncoding; return fontImp.getFont(attributes); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, boolean embedded, float size, int style) { return getFont(fontname, encoding, embedded, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, boolean embedded, float size) { return getFont(fontname, encoding, embedded, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, boolean embedded) { return getFont(fontname, encoding, embedded, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, float size, int style, Color color) { return getFont(fontname, encoding, defaultEmbedding, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, float size, int style) { return getFont(fontname, encoding, defaultEmbedding, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding, float size) { return getFont(fontname, encoding, defaultEmbedding, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, String encoding) { return getFont(fontname, encoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, float size, int style, Color color) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param color the Color of this font. * @return the Font constructed based on the parameters * @since 2.1.0 */ public static Font getFont(String fontname, float size, Color color) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, float size, int style) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname, float size) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @return the Font constructed based on the parameters */ public static Font getFont(String fontname) { return getFont(fontname, defaultEncoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Register a font by giving explicitly the font family and name. * @param familyName the font family * @param fullName the font name * @param path the font path */ public void registerFamily(String familyName, String fullName, String path) { fontImp.registerFamily(familyName, fullName, path); } /** * Register a ttf- or a ttc-file. * * @param path the path to a ttf- or ttc-file */ public static void register(String path) { register(path, null); } /** * Register a font file and use an alias for the font contained in it. * * @param path the path to a font file * @param alias the alias you want to use for the font */ public static void register(String path, String alias) { fontImp.register(path, alias); } /** Register all the fonts in a directory. * @param dir the directory * @return the number of fonts registered */ public static int registerDirectory(String dir) { return fontImp.registerDirectory(dir); } /** * Register all the fonts in a directory and possibly its subdirectories. * @param dir the directory * @param scanSubdirectories recursively scan subdirectories if true * @return the number of fonts registered * @since 2.1.2 */ public static int registerDirectory(String dir, boolean scanSubdirectories) { return fontImp.registerDirectory(dir, scanSubdirectories); } /** Register fonts in some probable directories. It usually works in Windows, * Linux and Solaris. * @return the number of fonts registered */ public static int registerDirectories() { return fontImp.registerDirectories(); } /** * Gets a set of registered fontnames. * @return a set of registered fonts */ public static Set getRegisteredFonts() { return fontImp.getRegisteredFonts(); } /** * Gets a set of registered fontnames. * @return a set of registered font families */ public static Set getRegisteredFamilies() { return fontImp.getRegisteredFamilies(); } /** * Gets a set of registered fontnames. * @param fontname of a font that may or may not be registered * @return true if a given font is registered */ public static boolean contains(String fontname) { return fontImp.isRegistered(fontname); } /** * Checks if a certain font is registered. * * @param fontname the name of the font that has to be checked. * @return true if the font is found */ public static boolean isRegistered(String fontname) { return fontImp.isRegistered(fontname); } /** * Gets the font factory implementation. * @return the font factory implementation */ public static FontFactoryImp getFontImp() { return fontImp; } /** * Sets the font factory implementation. * @param fontImp the font factory implementation */ public static void setFontImp(FontFactoryImp fontImp) { if (fontImp == null) throw new NullPointerException("FontFactoryImp cannot be null."); FontFactory.fontImp = fontImp; } } src/core/com/lowagie/text/FontFactoryImp.java100644 0 0 67660 11036112746 16724 0ustar 0 0 /* * $Id: FontFactoryImp.java 3548 2008-07-12 11:15:35Z blowagie $ * * Copyright 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Properties; import java.util.Set; import com.lowagie.text.html.Markup; import com.lowagie.text.pdf.BaseFont; /** * If you are using True Type fonts, you can declare the paths of the different ttf- and ttc-files * to this class first and then create fonts in your code using one of the getFont method * without having to enter a path as parameter. * * @author Bruno Lowagie */ public class FontFactoryImp { /** This is a map of postscriptfontnames of True Type fonts and the path of their ttf- or ttc-file. */ private Properties trueTypeFonts = new Properties(); private static String[] TTFamilyOrder = { "3", "1", "1033", "3", "0", "1033", "1", "0", "0", "0", "3", "0" }; /** This is a map of fontfamilies. */ private Hashtable fontFamilies = new Hashtable(); /** This is the default encoding to use. */ public String defaultEncoding = BaseFont.WINANSI; /** This is the default value of the embedded variable. */ public boolean defaultEmbedding = BaseFont.NOT_EMBEDDED; /** Creates new FontFactory */ public FontFactoryImp() { trueTypeFonts.setProperty(FontFactory.COURIER.toLowerCase(), FontFactory.COURIER); trueTypeFonts.setProperty(FontFactory.COURIER_BOLD.toLowerCase(), FontFactory.COURIER_BOLD); trueTypeFonts.setProperty(FontFactory.COURIER_OBLIQUE.toLowerCase(), FontFactory.COURIER_OBLIQUE); trueTypeFonts.setProperty(FontFactory.COURIER_BOLDOBLIQUE.toLowerCase(), FontFactory.COURIER_BOLDOBLIQUE); trueTypeFonts.setProperty(FontFactory.HELVETICA.toLowerCase(), FontFactory.HELVETICA); trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLD.toLowerCase(), FontFactory.HELVETICA_BOLD); trueTypeFonts.setProperty(FontFactory.HELVETICA_OBLIQUE.toLowerCase(), FontFactory.HELVETICA_OBLIQUE); trueTypeFonts.setProperty(FontFactory.HELVETICA_BOLDOBLIQUE.toLowerCase(), FontFactory.HELVETICA_BOLDOBLIQUE); trueTypeFonts.setProperty(FontFactory.SYMBOL.toLowerCase(), FontFactory.SYMBOL); trueTypeFonts.setProperty(FontFactory.TIMES_ROMAN.toLowerCase(), FontFactory.TIMES_ROMAN); trueTypeFonts.setProperty(FontFactory.TIMES_BOLD.toLowerCase(), FontFactory.TIMES_BOLD); trueTypeFonts.setProperty(FontFactory.TIMES_ITALIC.toLowerCase(), FontFactory.TIMES_ITALIC); trueTypeFonts.setProperty(FontFactory.TIMES_BOLDITALIC.toLowerCase(), FontFactory.TIMES_BOLDITALIC); trueTypeFonts.setProperty(FontFactory.ZAPFDINGBATS.toLowerCase(), FontFactory.ZAPFDINGBATS); ArrayList tmp; tmp = new ArrayList(); tmp.add(FontFactory.COURIER); tmp.add(FontFactory.COURIER_BOLD); tmp.add(FontFactory.COURIER_OBLIQUE); tmp.add(FontFactory.COURIER_BOLDOBLIQUE); fontFamilies.put(FontFactory.COURIER.toLowerCase(), tmp); tmp = new ArrayList(); tmp.add(FontFactory.HELVETICA); tmp.add(FontFactory.HELVETICA_BOLD); tmp.add(FontFactory.HELVETICA_OBLIQUE); tmp.add(FontFactory.HELVETICA_BOLDOBLIQUE); fontFamilies.put(FontFactory.HELVETICA.toLowerCase(), tmp); tmp = new ArrayList(); tmp.add(FontFactory.SYMBOL); fontFamilies.put(FontFactory.SYMBOL.toLowerCase(), tmp); tmp = new ArrayList(); tmp.add(FontFactory.TIMES_ROMAN); tmp.add(FontFactory.TIMES_BOLD); tmp.add(FontFactory.TIMES_ITALIC); tmp.add(FontFactory.TIMES_BOLDITALIC); fontFamilies.put(FontFactory.TIMES.toLowerCase(), tmp); fontFamilies.put(FontFactory.TIMES_ROMAN.toLowerCase(), tmp); tmp = new ArrayList(); tmp.add(FontFactory.ZAPFDINGBATS); fontFamilies.put(FontFactory.ZAPFDINGBATS.toLowerCase(), tmp); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color) { return getFont(fontname, encoding, embedded, size, style, color, true); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @param cached true if the font comes from the cache or is added to * the cache if new, false if the font is always created new * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, Color color, boolean cached) { if (fontname == null) return new Font(Font.UNDEFINED, size, style, color); String lowercasefontname = fontname.toLowerCase(); ArrayList tmp = (ArrayList) fontFamilies.get(lowercasefontname); if (tmp != null) { // some bugs were fixed here by Daniel Marczisovszky int s = style == Font.UNDEFINED ? Font.NORMAL : style; int fs = Font.NORMAL; boolean found = false; for (Iterator i = tmp.iterator(); i.hasNext(); ) { String f = (String) i.next(); String lcf = f.toLowerCase(); fs = Font.NORMAL; if (lcf.toLowerCase().indexOf("bold") != -1) fs |= Font.BOLD; if (lcf.toLowerCase().indexOf("italic") != -1 || lcf.toLowerCase().indexOf("oblique") != -1) fs |= Font.ITALIC; if ((s & Font.BOLDITALIC) == fs) { fontname = f; found = true; break; } } if (style != Font.UNDEFINED && found) { style &= ~fs; } } BaseFont basefont = null; try { try { // the font is a type 1 font or CJK font basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null, true); } catch(DocumentException de) { } if (basefont == null) { // the font is a true type font or an unknown font fontname = trueTypeFonts.getProperty(fontname.toLowerCase()); // the font is not registered as truetype font if (fontname == null) return new Font(Font.UNDEFINED, size, style, color); // the font is registered as truetype font basefont = BaseFont.createFont(fontname, encoding, embedded, cached, null, null); } } catch(DocumentException de) { // this shouldn't happen throw new ExceptionConverter(de); } catch(IOException ioe) { // the font is registered as a true type font, but the path was wrong return new Font(Font.UNDEFINED, size, style, color); } catch(NullPointerException npe) { // null was entered as fontname and/or encoding return new Font(Font.UNDEFINED, size, style, color); } return new Font(basefont, size, style, color); } /** * Constructs a Font-object. * * @param attributes the attributes of a Font object. * @return the Font constructed based on the attributes */ public Font getFont(Properties attributes) { String fontname = null; String encoding = defaultEncoding; boolean embedded = defaultEmbedding; float size = Font.UNDEFINED; int style = Font.NORMAL; Color color = null; String value = attributes.getProperty(Markup.HTML_ATTR_STYLE); if (value != null && value.length() > 0) { Properties styleAttributes = Markup.parseAttributes(value); if (styleAttributes.isEmpty()) { attributes.put(Markup.HTML_ATTR_STYLE, value); } else { fontname = styleAttributes.getProperty(Markup.CSS_KEY_FONTFAMILY); if (fontname != null) { String tmp; while (fontname.indexOf(',') != -1) { tmp = fontname.substring(0, fontname.indexOf(',')); if (isRegistered(tmp)) { fontname = tmp; } else { fontname = fontname.substring(fontname.indexOf(',') + 1); } } } if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSIZE)) != null) { size = Markup.parseLength(value); } if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTWEIGHT)) != null) { style |= Font.getStyleValue(value); } if ((value = styleAttributes.getProperty(Markup.CSS_KEY_FONTSTYLE)) != null) { style |= Font.getStyleValue(value); } if ((value = styleAttributes.getProperty(Markup.CSS_KEY_COLOR)) != null) { color = Markup.decodeColor(value); } attributes.putAll(styleAttributes); for (Enumeration e = styleAttributes.keys(); e.hasMoreElements();) { Object o = e.nextElement(); attributes.put(o, styleAttributes.get(o)); } } } if ((value = attributes.getProperty(ElementTags.ENCODING)) != null) { encoding = value; } if ("true".equals(attributes.getProperty(ElementTags.EMBEDDED))) { embedded = true; } if ((value = attributes.getProperty(ElementTags.FONT)) != null) { fontname = value; } if ((value = attributes.getProperty(ElementTags.SIZE)) != null) { size = Markup.parseLength(value); } if ((value = attributes.getProperty(Markup.HTML_ATTR_STYLE)) != null) { style |= Font.getStyleValue(value); } if ((value = attributes.getProperty(ElementTags.STYLE)) != null) { style |= Font.getStyleValue(value); } String r = attributes.getProperty(ElementTags.RED); String g = attributes.getProperty(ElementTags.GREEN); String b = attributes.getProperty(ElementTags.BLUE); if (r != null || g != null || b != null) { int red = 0; int green = 0; int blue = 0; if (r != null) red = Integer.parseInt(r); if (g != null) green = Integer.parseInt(g); if (b != null) blue = Integer.parseInt(b); color = new Color(red, green, blue); } else if ((value = attributes.getProperty(ElementTags.COLOR)) != null) { color = Markup.decodeColor(value); } if (fontname == null) { return getFont(null, encoding, embedded, size, style, color); } return getFont(fontname, encoding, embedded, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, boolean embedded, float size, int style) { return getFont(fontname, encoding, embedded, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @param size the size of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, boolean embedded, float size) { return getFont(fontname, encoding, embedded, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param embedded true if the font is to be embedded in the PDF * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, boolean embedded) { return getFont(fontname, encoding, embedded, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, float size, int style, Color color) { return getFont(fontname, encoding, defaultEmbedding, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, float size, int style) { return getFont(fontname, encoding, defaultEmbedding, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @param size the size of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding, float size) { return getFont(fontname, encoding, defaultEmbedding, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param color the Color of this font. * @return the Font constructed based on the parameters * @since 2.1.0 */ public Font getFont(String fontname, float size, Color color) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param encoding the encoding of the font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, String encoding) { return getFont(fontname, encoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param style the style of this font * @param color the Color of this font. * @return the Font constructed based on the parameters */ public Font getFont(String fontname, float size, int style, Color color) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, color); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @param style the style of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, float size, int style) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, style, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @param size the size of this font * @return the Font constructed based on the parameters */ public Font getFont(String fontname, float size) { return getFont(fontname, defaultEncoding, defaultEmbedding, size, Font.UNDEFINED, null); } /** * Constructs a Font-object. * * @param fontname the name of the font * @return the Font constructed based on the parameters */ public Font getFont(String fontname) { return getFont(fontname, defaultEncoding, defaultEmbedding, Font.UNDEFINED, Font.UNDEFINED, null); } /** * Register a font by giving explicitly the font family and name. * @param familyName the font family * @param fullName the font name * @param path the font path */ public void registerFamily(String familyName, String fullName, String path) { if (path != null) trueTypeFonts.setProperty(fullName, path); ArrayList tmp = (ArrayList) fontFamilies.get(familyName); if (tmp == null) { tmp = new ArrayList(); tmp.add(fullName); fontFamilies.put(familyName, tmp); } else { int fullNameLength = fullName.length(); boolean inserted = false; for (int j = 0; j < tmp.size(); ++j) { if (((String)tmp.get(j)).length() >= fullNameLength) { tmp.add(j, fullName); inserted = true; break; } } if (!inserted) tmp.add(fullName); } } /** * Register a ttf- or a ttc-file. * * @param path the path to a ttf- or ttc-file */ public void register(String path) { register(path, null); } /** * Register a font file and use an alias for the font contained in it. * * @param path the path to a font file * @param alias the alias you want to use for the font */ public void register(String path, String alias) { try { if (path.toLowerCase().endsWith(".ttf") || path.toLowerCase().endsWith(".otf") || path.toLowerCase().indexOf(".ttc,") > 0) { Object allNames[] = BaseFont.getAllFontNames(path, BaseFont.WINANSI, null); trueTypeFonts.setProperty(((String)allNames[0]).toLowerCase(), path); if (alias != null) { trueTypeFonts.setProperty(alias.toLowerCase(), path); } // register all the font names with all the locales String[][] names = (String[][])allNames[2]; //full name for (int i = 0; i < names.length; i++) { trueTypeFonts.setProperty(names[i][3].toLowerCase(), path); } String fullName = null; String familyName = null; names = (String[][])allNames[1]; //family name for (int k = 0; k < TTFamilyOrder.length; k += 3) { for (int i = 0; i < names.length; i++) { if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) { familyName = names[i][3].toLowerCase(); k = TTFamilyOrder.length; break; } } } if (familyName != null) { String lastName = ""; names = (String[][])allNames[2]; //full name for (int i = 0; i < names.length; i++) { for (int k = 0; k < TTFamilyOrder.length; k += 3) { if (TTFamilyOrder[k].equals(names[i][0]) && TTFamilyOrder[k + 1].equals(names[i][1]) && TTFamilyOrder[k + 2].equals(names[i][2])) { fullName = names[i][3]; if (fullName.equals(lastName)) continue; lastName = fullName; registerFamily(familyName, fullName, null); break; } } } } } else if (path.toLowerCase().endsWith(".ttc")) { if (alias != null) System.err.println("class FontFactory: You can't define an alias for a true type collection."); String[] names = BaseFont.enumerateTTCNames(path); for (int i = 0; i < names.length; i++) { register(path + "," + i); } } else if (path.toLowerCase().endsWith(".afm") || path.toLowerCase().endsWith(".pfm")) { BaseFont bf = BaseFont.createFont(path, BaseFont.CP1252, false); String fullName = bf.getFullFontName()[0][3].toLowerCase(); String familyName = bf.getFamilyFontName()[0][3].toLowerCase(); String psName = bf.getPostscriptFontName().toLowerCase(); registerFamily(familyName, fullName, null); trueTypeFonts.setProperty(psName, path); trueTypeFonts.setProperty(fullName, path); } } catch(DocumentException de) { // this shouldn't happen throw new ExceptionConverter(de); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** Register all the fonts in a directory. * @param dir the directory * @return the number of fonts registered */ public int registerDirectory(String dir) { return registerDirectory(dir, false); } /** * Register all the fonts in a directory and possibly its subdirectories. * @param dir the directory * @param scanSubdirectories recursively scan subdirectories if true * @return the number of fonts registered * @since 2.1.2 */ public int registerDirectory(String dir, boolean scanSubdirectories) { int count = 0; try { File file = new File(dir); if (!file.exists() || !file.isDirectory()) return 0; String files[] = file.list(); if (files == null) return 0; for (int k = 0; k < files.length; ++k) { try { file = new File(dir, files[k]); if (file.isDirectory()) { if (scanSubdirectories) { count += registerDirectory(file.getAbsolutePath(), true); } } else { String name = file.getPath(); String suffix = name.length() < 4 ? null : name.substring(name.length() - 4).toLowerCase(); if (".afm".equals(suffix) || ".pfm".equals(suffix)) { /* Only register Type 1 fonts with matching .pfb files */ File pfb = new File(name.substring(0, name.length() - 4) + ".pfb"); if (pfb.exists()) { register(name, null); ++count; } } else if (".ttf".equals(suffix) || ".otf".equals(suffix) || ".ttc".equals(suffix)) { register(name, null); ++count; } } } catch (Exception e) { //empty on purpose } } } catch (Exception e) { //empty on purpose } return count; } /** Register fonts in some probable directories. It usually works in Windows, * Linux and Solaris. * @return the number of fonts registered */ public int registerDirectories() { int count = 0; count += registerDirectory("c:/windows/fonts"); count += registerDirectory("c:/winnt/fonts"); count += registerDirectory("d:/windows/fonts"); count += registerDirectory("d:/winnt/fonts"); count += registerDirectory("/usr/share/X11/fonts", true); count += registerDirectory("/usr/X/lib/X11/fonts", true); count += registerDirectory("/usr/openwin/lib/X11/fonts", true); count += registerDirectory("/usr/share/fonts", true); count += registerDirectory("/usr/X11R6/lib/X11/fonts", true); count += registerDirectory("/Library/Fonts"); count += registerDirectory("/System/Library/Fonts"); return count; } /** * Gets a set of registered fontnames. * @return a set of registered fonts */ public Set getRegisteredFonts() { return Utilities.getKeySet(trueTypeFonts); } /** * Gets a set of registered fontnames. * @return a set of registered font families */ public Set getRegisteredFamilies() { return Utilities.getKeySet(fontFamilies); } /** * Checks if a certain font is registered. * * @param fontname the name of the font that has to be checked. * @return true if the font is found */ public boolean isRegistered(String fontname) { return trueTypeFonts.containsKey(fontname.toLowerCase()); } } src/core/com/lowagie/text/GreekList.java100644 0 0 10304 11000354131 15653 0ustar 0 0 /* * Copyright 2003 by Michael Niedermair and 2007 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import com.lowagie.text.factories.GreekAlphabetFactory; /** * * A special-version of LIST which use greek-letters. * * @see com.lowagie.text.List */ public class GreekList extends List { // constructors /** * Initialization */ public GreekList() { super(true); setGreekFont(); } /** * Initialization * * @param symbolIndent indent */ public GreekList(int symbolIndent) { super(true, symbolIndent); setGreekFont(); } /** * Initialization * @param greeklower greek-char in lowercase * @param symbolIndent indent */ public GreekList(boolean greeklower, int symbolIndent) { super(true, symbolIndent); lowercase = greeklower; setGreekFont(); } // helper method /** * change the font to SYMBOL */ protected void setGreekFont() { float fontsize = symbol.getFont().getSize(); symbol.setFont(FontFactory.getFont(FontFactory.SYMBOL, fontsize, Font.NORMAL)); } // overridden method /** * Adds an Object to the List. * * @param o the object to add. * @return true if adding the object succeeded */ public boolean add(Object o) { if (o instanceof ListItem) { ListItem item = (ListItem) o; Chunk chunk = new Chunk(preSymbol, symbol.getFont()); chunk.append(GreekAlphabetFactory.getString(first + list.size(), lowercase)); chunk.append(postSymbol); item.setListSymbol(chunk); item.setIndentationLeft(symbolIndent, autoindent); item.setIndentationRight(0); list.add(item); } else if (o instanceof List) { List nested = (List) o; nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent); first--; return list.add(nested); } else if (o instanceof String) { return this.add(new ListItem((String) o)); } return false; } } src/core/com/lowagie/text/Header.java100644 0 0 6727 11012562273 15163 0ustar 0 0 /* * $Id: Header.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * This is an Element that contains * some user defined meta information about the document. *

* Example: *

 * Header header = new Header("inspired by", "William Shakespeare");
 * 
* * @see Element * @see Meta */ public class Header extends Meta { // membervariables /** This is the content of this chunk of text. */ private StringBuffer name; // constructors /** * Constructs a Meta. * * @param name the name of the meta-information * @param content the content */ public Header(String name, String content) { super(Element.HEADER, content); this.name = new StringBuffer(name); } // methods to retrieve information /** * Returns the name of the meta information. * * @return a String */ public String getName() { return name.toString(); } }src/core/com/lowagie/text/HeaderFooter.java100644 0 0 13641 11012562273 16353 0ustar 0 0 /* * $Id: HeaderFooter.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * A HeaderFooter-object is a Rectangle with text * that can be put above and/or below every page. *

* Example: *

 * HeaderFooter header = new HeaderFooter(new Phrase("This is a header."), false);
 * HeaderFooter footer = new HeaderFooter(new Phrase("This is page "), new Phrase("."));
 * document.setHeader(header);
 * document.setFooter(footer);
 * 
*/ public class HeaderFooter extends Rectangle { // membervariables /** Does the page contain a pagenumber? */ private boolean numbered; /** This is the Phrase that comes before the pagenumber. */ private Phrase before = null; /** This is number of the page. */ private int pageN; /** This is the Phrase that comes after the pagenumber. */ private Phrase after = null; /** This is alignment of the header/footer. */ private int alignment; // constructors /** * Constructs a HeaderFooter-object. * * @param before the Phrase before the pagenumber * @param after the Phrase before the pagenumber */ public HeaderFooter(Phrase before, Phrase after) { super(0, 0, 0, 0); setBorder(TOP + BOTTOM); setBorderWidth(1); numbered = true; this.before = before; this.after = after; } /** * Constructs a Header-object with a pagenumber at the end. * * @param before the Phrase before the pagenumber * @param numbered true if the page has to be numbered */ public HeaderFooter(Phrase before, boolean numbered) { super(0, 0, 0, 0); setBorder(TOP + BOTTOM); setBorderWidth(1); this.numbered = numbered; this.before = before; } // methods /** * Checks if the HeaderFooter contains a page number. * * @return true if the page has to be numbered */ public boolean isNumbered() { return numbered; } /** * Gets the part that comes before the pageNumber. * * @return a Phrase */ public Phrase getBefore() { return before; } /** * Gets the part that comes after the pageNumber. * * @return a Phrase */ public Phrase getAfter() { return after; } /** * Sets the page number. * * @param pageN the new page number */ public void setPageNumber(int pageN) { this.pageN = pageN; } /** * Sets the alignment. * * @param alignment the new alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } // methods to retrieve the membervariables /** * Gets the Paragraph that can be used as header or footer. * * @return a Paragraph */ public Paragraph paragraph() { Paragraph paragraph = new Paragraph(before.getLeading()); paragraph.add(before); if (numbered) { paragraph.addSpecial(new Chunk(String.valueOf(pageN), before.getFont())); } if (after != null) { paragraph.addSpecial(after); } paragraph.setAlignment(alignment); return paragraph; } /** * Gets the alignment of this HeaderFooter. * * @return alignment */ public int alignment() { return alignment; } }src/core/com/lowagie/text/Image.java100644 0 0 150040 11213370070 15034 0ustar 0 0 /* * $Id: Image.java 3941 2009-05-28 14:52:26Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Graphics2D; import java.awt.color.ICC_Profile; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import com.lowagie.text.pdf.PRIndirectReference; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfIndirectReference; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfOCG; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStream; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.RandomAccessFileOrArray; import com.lowagie.text.pdf.codec.BmpImage; import com.lowagie.text.pdf.codec.CCITTG4Encoder; import com.lowagie.text.pdf.codec.GifImage; import com.lowagie.text.pdf.codec.JBIG2Image; import com.lowagie.text.pdf.codec.PngImage; import com.lowagie.text.pdf.codec.TiffImage; /** * An Image is the representation of a graphic element (JPEG, PNG * or GIF) that has to be inserted into the document * * @see Element * @see Rectangle */ public abstract class Image extends Rectangle { // static final membervariables /** this is a kind of image alignment. */ public static final int DEFAULT = 0; /** this is a kind of image alignment. */ public static final int RIGHT = 2; /** this is a kind of image alignment. */ public static final int LEFT = 0; /** this is a kind of image alignment. */ public static final int MIDDLE = 1; /** this is a kind of image alignment. */ public static final int TEXTWRAP = 4; /** this is a kind of image alignment. */ public static final int UNDERLYING = 8; /** This represents a coordinate in the transformation matrix. */ public static final int AX = 0; /** This represents a coordinate in the transformation matrix. */ public static final int AY = 1; /** This represents a coordinate in the transformation matrix. */ public static final int BX = 2; /** This represents a coordinate in the transformation matrix. */ public static final int BY = 3; /** This represents a coordinate in the transformation matrix. */ public static final int CX = 4; /** This represents a coordinate in the transformation matrix. */ public static final int CY = 5; /** This represents a coordinate in the transformation matrix. */ public static final int DX = 6; /** This represents a coordinate in the transformation matrix. */ public static final int DY = 7; /** type of image */ public static final int ORIGINAL_NONE = 0; /** type of image */ public static final int ORIGINAL_JPEG = 1; /** type of image */ public static final int ORIGINAL_PNG = 2; /** type of image */ public static final int ORIGINAL_GIF = 3; /** type of image */ public static final int ORIGINAL_BMP = 4; /** type of image */ public static final int ORIGINAL_TIFF = 5; /** type of image */ public static final int ORIGINAL_WMF = 6; /** type of image */ public static final int ORIGINAL_PS = 7; /** type of image */ public static final int ORIGINAL_JPEG2000 = 8; /** * type of image * @since 2.1.5 */ public static final int ORIGINAL_JBIG2 = 9; // member variables /** The image type. */ protected int type; /** The URL of the image. */ protected URL url; /** The raw data of the image. */ protected byte rawData[]; /** The bits per component of the raw image. It also flags a CCITT image. */ protected int bpc = 1; /** The template to be treated as an image. */ protected PdfTemplate template[] = new PdfTemplate[1]; /** The alignment of the Image. */ protected int alignment; /** Text that can be shown instead of the image. */ protected String alt; /** This is the absolute X-position of the image. */ protected float absoluteX = Float.NaN; /** This is the absolute Y-position of the image. */ protected float absoluteY = Float.NaN; /** This is the width of the image without rotation. */ protected float plainWidth; /** This is the width of the image without rotation. */ protected float plainHeight; /** This is the scaled width of the image taking rotation into account. */ protected float scaledWidth; /** This is the original height of the image taking rotation into account. */ protected float scaledHeight; /** * The compression level of the content streams. * @since 2.1.3 */ protected int compressionLevel = PdfStream.DEFAULT_COMPRESSION; /** an iText attributed unique id for this image. */ protected Long mySerialId = getSerialId(); // image from file or URL /** * Constructs an Image -object, using an url . * * @param url * the URL where the image can be found. */ public Image(URL url) { super(0, 0); this.url = url; this.alignment = DEFAULT; rotationRadians = 0; } /** * Gets an instance of an Image. * * @param url * an URL * @return an Image * @throws BadElementException * @throws MalformedURLException * @throws IOException */ public static Image getInstance(URL url) throws BadElementException, MalformedURLException, IOException { InputStream is = null; try { is = url.openStream(); int c1 = is.read(); int c2 = is.read(); int c3 = is.read(); int c4 = is.read(); // jbig2 int c5 = is.read(); int c6 = is.read(); int c7 = is.read(); int c8 = is.read(); is.close(); is = null; if (c1 == 'G' && c2 == 'I' && c3 == 'F') { GifImage gif = new GifImage(url); Image img = gif.getImage(1); return img; } if (c1 == 0xFF && c2 == 0xD8) { return new Jpeg(url); } if (c1 == 0x00 && c2 == 0x00 && c3 == 0x00 && c4 == 0x0c) { return new Jpeg2000(url); } if (c1 == 0xff && c2 == 0x4f && c3 == 0xff && c4 == 0x51) { return new Jpeg2000(url); } if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { return PngImage.getImage(url); } if (c1 == 0xD7 && c2 == 0xCD) { return new ImgWMF(url); } if (c1 == 'B' && c2 == 'M') { return BmpImage.getImage(url); } if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { RandomAccessFileOrArray ra = null; try { if (url.getProtocol().equals("file")) { String file = url.getFile(); file = Utilities.unEscapeURL(file); ra = new RandomAccessFileOrArray(file); } else ra = new RandomAccessFileOrArray(url); Image img = TiffImage.getTiffImage(ra, 1); img.url = url; return img; } finally { if (ra != null) ra.close(); } } if ( c1 == 0x97 && c2 == 'J' && c3 == 'B' && c4 == '2' && c5 == '\r' && c6 == '\n' && c7 == 0x1a && c8 == '\n' ) { RandomAccessFileOrArray ra = null; try { if (url.getProtocol().equals("file")) { String file = url.getFile(); file = Utilities.unEscapeURL(file); ra = new RandomAccessFileOrArray(file); } else ra = new RandomAccessFileOrArray(url); Image img = JBIG2Image.getJbig2Image(ra, 1); img.url = url; return img; } finally { if (ra != null) ra.close(); } } throw new IOException(url.toString() + " is not a recognized imageformat."); } finally { if (is != null) { is.close(); } } } /** * Gets an instance of an Image. * * @param filename * a filename * @return an object of type Gif,Jpeg or * Png * @throws BadElementException * @throws MalformedURLException * @throws IOException */ public static Image getInstance(String filename) throws BadElementException, MalformedURLException, IOException { return getInstance(Utilities.toURL(filename)); } /** * gets an instance of an Image * * @param imgb * raw image date * @return an Image object * @throws BadElementException * @throws MalformedURLException * @throws IOException */ public static Image getInstance(byte imgb[]) throws BadElementException, MalformedURLException, IOException { InputStream is = null; try { is = new java.io.ByteArrayInputStream(imgb); int c1 = is.read(); int c2 = is.read(); int c3 = is.read(); int c4 = is.read(); is.close(); is = null; if (c1 == 'G' && c2 == 'I' && c3 == 'F') { GifImage gif = new GifImage(imgb); return gif.getImage(1); } if (c1 == 0xFF && c2 == 0xD8) { return new Jpeg(imgb); } if (c1 == 0x00 && c2 == 0x00 && c3 == 0x00 && c4 == 0x0c) { return new Jpeg2000(imgb); } if (c1 == 0xff && c2 == 0x4f && c3 == 0xff && c4 == 0x51) { return new Jpeg2000(imgb); } if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1] && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) { return PngImage.getImage(imgb); } if (c1 == 0xD7 && c2 == 0xCD) { return new ImgWMF(imgb); } if (c1 == 'B' && c2 == 'M') { return BmpImage.getImage(imgb); } if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42) || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { RandomAccessFileOrArray ra = null; try { ra = new RandomAccessFileOrArray(imgb); Image img = TiffImage.getTiffImage(ra, 1); if (img.getOriginalData() == null) img.setOriginalData(imgb); return img; } finally { if (ra != null) ra.close(); } } if ( c1 == 0x97 && c2 == 'J' && c3 == 'B' && c4 == '2' ) { is = new java.io.ByteArrayInputStream(imgb); is.skip(4); int c5 = is.read(); int c6 = is.read(); int c7 = is.read(); int c8 = is.read(); if ( c5 == '\r' && c6 == '\n' && c7 == 0x1a && c8 == '\n' ) { int file_header_flags = is.read(); int number_of_pages = -1; if ( (file_header_flags & 0x2) == 0x2 ) { number_of_pages = (is.read() << 24) | (is.read() << 16) | (is.read() << 8) | is.read(); } is.close(); // a jbig2 file with a file header. the header is the only way we know here. // embedded jbig2s don't have a header, have to create them by explicit use of Jbig2Image? // nkerr, 2008-12-05 see also the getInstance(URL) RandomAccessFileOrArray ra = null; try { ra = new RandomAccessFileOrArray(imgb); Image img = JBIG2Image.getJbig2Image(ra, 1); if (img.getOriginalData() == null) img.setOriginalData(imgb); return img; } finally { if (ra != null) ra.close(); } } } throw new IOException( "The byte array is not a recognized imageformat."); } finally { if (is != null) { is.close(); } } } /** * Gets an instance of an Image in raw mode. * * @param width * the width of the image in pixels * @param height * the height of the image in pixels * @param components * 1,3 or 4 for GrayScale, RGB and CMYK * @param data * the image data * @param bpc * bits per component * @return an object of type ImgRaw * @throws BadElementException * on error */ public static Image getInstance(int width, int height, int components, int bpc, byte data[]) throws BadElementException { return Image.getInstance(width, height, components, bpc, data, null); } /** * Creates a JBIG2 Image. * @param width the width of the image * @param height the height of the image * @param data the raw image data * @param globals JBIG2 globals * @since 2.1.5 */ public static Image getInstance(int width, int height, byte[] data, byte[] globals) { Image img = new ImgJBIG2(width, height, data, globals); return img; } /** * Creates an Image with CCITT G3 or G4 compression. It assumes that the * data bytes are already compressed. * * @param width * the exact width of the image * @param height * the exact height of the image * @param reverseBits * reverses the bits in data. Bit 0 is swapped * with bit 7 and so on * @param typeCCITT * the type of compression in data. It can be * CCITTG4, CCITTG31D, CCITTG32D * @param parameters * parameters associated with this stream. Possible values are * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and * CCITT_ENDOFBLOCK or a combination of them * @param data * the image data * @return an Image object * @throws BadElementException * on error */ public static Image getInstance(int width, int height, boolean reverseBits, int typeCCITT, int parameters, byte[] data) throws BadElementException { return Image.getInstance(width, height, reverseBits, typeCCITT, parameters, data, null); } /** * Creates an Image with CCITT G3 or G4 compression. It assumes that the * data bytes are already compressed. * * @param width * the exact width of the image * @param height * the exact height of the image * @param reverseBits * reverses the bits in data. Bit 0 is swapped * with bit 7 and so on * @param typeCCITT * the type of compression in data. It can be * CCITTG4, CCITTG31D, CCITTG32D * @param parameters * parameters associated with this stream. Possible values are * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and * CCITT_ENDOFBLOCK or a combination of them * @param data * the image data * @param transparency * transparency information in the Mask format of the image * dictionary * @return an Image object * @throws BadElementException * on error */ public static Image getInstance(int width, int height, boolean reverseBits, int typeCCITT, int parameters, byte[] data, int transparency[]) throws BadElementException { if (transparency != null && transparency.length != 2) throw new BadElementException( "Transparency length must be equal to 2 with CCITT images"); Image img = new ImgCCITT(width, height, reverseBits, typeCCITT, parameters, data); img.transparency = transparency; return img; } /** * Gets an instance of an Image in raw mode. * * @param width * the width of the image in pixels * @param height * the height of the image in pixels * @param components * 1,3 or 4 for GrayScale, RGB and CMYK * @param data * the image data * @param bpc * bits per component * @param transparency * transparency information in the Mask format of the image * dictionary * @return an object of type ImgRaw * @throws BadElementException * on error */ public static Image getInstance(int width, int height, int components, int bpc, byte data[], int transparency[]) throws BadElementException { if (transparency != null && transparency.length != components * 2) throw new BadElementException( "Transparency length must be equal to (componentes * 2)"); if (components == 1 && bpc == 1) { byte g4[] = CCITTG4Encoder.compress(data, width, height); return Image.getInstance(width, height, false, Image.CCITTG4, Image.CCITT_BLACKIS1, g4, transparency); } Image img = new ImgRaw(width, height, components, bpc, data); img.transparency = transparency; return img; } // images from a PdfTemplate /** * gets an instance of an Image * * @param template * a PdfTemplate that has to be wrapped in an Image object * @return an Image object * @throws BadElementException */ public static Image getInstance(PdfTemplate template) throws BadElementException { return new ImgTemplate(template); } // images from a java.awt.Image /** * Gets an instance of an Image from a java.awt.Image. * * @param image * the java.awt.Image to convert * @param color * if different from null the transparency pixels * are replaced by this color * @param forceBW * if true the image is treated as black and white * @return an object of type ImgRaw * @throws BadElementException * on error * @throws IOException * on error */ public static Image getInstance(java.awt.Image image, java.awt.Color color, boolean forceBW) throws BadElementException, IOException { if(image instanceof BufferedImage){ BufferedImage bi = (BufferedImage) image; if(bi.getType()==BufferedImage.TYPE_BYTE_BINARY) { forceBW=true; } } java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber(image, 0, 0, -1, -1, true); try { pg.grabPixels(); } catch (InterruptedException e) { throw new IOException( "java.awt.Image Interrupted waiting for pixels!"); } if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) { throw new IOException("java.awt.Image fetch aborted or errored"); } int w = pg.getWidth(); int h = pg.getHeight(); int[] pixels = (int[]) pg.getPixels(); if (forceBW) { int byteWidth = (w / 8) + ((w & 7) != 0 ? 1 : 0); byte[] pixelsByte = new byte[byteWidth * h]; int index = 0; int size = h * w; int transColor = 1; if (color != null) { transColor = (color.getRed() + color.getGreen() + color.getBlue() < 384) ? 0 : 1; } int transparency[] = null; int cbyte = 0x80; int wMarker = 0; int currByte = 0; if (color != null) { for (int j = 0; j < size; j++) { int alpha = (pixels[j] >> 24) & 0xff; if (alpha < 250) { if (transColor == 1) currByte |= cbyte; } else { if ((pixels[j] & 0x888) != 0) currByte |= cbyte; } cbyte >>= 1; if (cbyte == 0 || wMarker + 1 >= w) { pixelsByte[index++] = (byte) currByte; cbyte = 0x80; currByte = 0; } ++wMarker; if (wMarker >= w) wMarker = 0; } } else { for (int j = 0; j < size; j++) { if (transparency == null) { int alpha = (pixels[j] >> 24) & 0xff; if (alpha == 0) { transparency = new int[2]; /* bugfix by M.P. Liston, ASC, was: ... ? 1: 0; */ transparency[0] = transparency[1] = ((pixels[j] & 0x888) != 0) ? 0xff : 0; } } if ((pixels[j] & 0x888) != 0) currByte |= cbyte; cbyte >>= 1; if (cbyte == 0 || wMarker + 1 >= w) { pixelsByte[index++] = (byte) currByte; cbyte = 0x80; currByte = 0; } ++wMarker; if (wMarker >= w) wMarker = 0; } } return Image.getInstance(w, h, 1, 1, pixelsByte, transparency); } else { byte[] pixelsByte = new byte[w * h * 3]; byte[] smask = null; int index = 0; int size = h * w; int red = 255; int green = 255; int blue = 255; if (color != null) { red = color.getRed(); green = color.getGreen(); blue = color.getBlue(); } int transparency[] = null; if (color != null) { for (int j = 0; j < size; j++) { int alpha = (pixels[j] >> 24) & 0xff; if (alpha < 250) { pixelsByte[index++] = (byte) red; pixelsByte[index++] = (byte) green; pixelsByte[index++] = (byte) blue; } else { pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff); pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff); pixelsByte[index++] = (byte) ((pixels[j]) & 0xff); } } } else { int transparentPixel = 0; smask = new byte[w * h]; boolean shades = false; for (int j = 0; j < size; j++) { byte alpha = smask[j] = (byte) ((pixels[j] >> 24) & 0xff); /* bugfix by Chris Nokleberg */ if (!shades) { if (alpha != 0 && alpha != -1) { shades = true; } else if (transparency == null) { if (alpha == 0) { transparentPixel = pixels[j] & 0xffffff; transparency = new int[6]; transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff; transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff; transparency[4] = transparency[5] = transparentPixel & 0xff; } } else if ((pixels[j] & 0xffffff) != transparentPixel) { shades = true; } } pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff); pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff); pixelsByte[index++] = (byte) ((pixels[j]) & 0xff); } if (shades) transparency = null; else smask = null; } Image img = Image.getInstance(w, h, 3, 8, pixelsByte, transparency); if (smask != null) { Image sm = Image.getInstance(w, h, 1, 8, smask); try { sm.makeMask(); img.setImageMask(sm); } catch (DocumentException de) { throw new ExceptionConverter(de); } } return img; } } /** * Gets an instance of an Image from a java.awt.Image. * * @param image * the java.awt.Image to convert * @param color * if different from null the transparency pixels * are replaced by this color * @return an object of type ImgRaw * @throws BadElementException * on error * @throws IOException * on error */ public static Image getInstance(java.awt.Image image, java.awt.Color color) throws BadElementException, IOException { return Image.getInstance(image, color, false); } /** * Gets an instance of a Image from a java.awt.Image. * The image is added as a JPEG with a user defined quality. * * @param writer * the PdfWriter object to which the image will be added * @param awtImage * the java.awt.Image to convert * @param quality * a float value between 0 and 1 * @return an object of type PdfTemplate * @throws BadElementException * on error * @throws IOException */ public static Image getInstance(PdfWriter writer, java.awt.Image awtImage, float quality) throws BadElementException, IOException { return getInstance(new PdfContentByte(writer), awtImage, quality); } /** * Gets an instance of a Image from a java.awt.Image. * The image is added as a JPEG with a user defined quality. * * @param cb * the PdfContentByte object to which the image will be added * @param awtImage * the java.awt.Image to convert * @param quality * a float value between 0 and 1 * @return an object of type PdfTemplate * @throws BadElementException * on error * @throws IOException */ public static Image getInstance(PdfContentByte cb, java.awt.Image awtImage, float quality) throws BadElementException, IOException { java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber(awtImage, 0, 0, -1, -1, true); try { pg.grabPixels(); } catch (InterruptedException e) { throw new IOException( "java.awt.Image Interrupted waiting for pixels!"); } if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) { throw new IOException("java.awt.Image fetch aborted or errored"); } int w = pg.getWidth(); int h = pg.getHeight(); PdfTemplate tp = cb.createTemplate(w, h); Graphics2D g2d = tp.createGraphics(w, h, true, quality); g2d.drawImage(awtImage, 0, 0, null); g2d.dispose(); return getInstance(tp); } // image from indirect reference /** * Holds value of property directReference. * An image is embedded into a PDF as an Image XObject. * This object is referenced by a PdfIndirectReference object. */ private PdfIndirectReference directReference; /** * Getter for property directReference. * @return Value of property directReference. */ public PdfIndirectReference getDirectReference() { return this.directReference; } /** * Setter for property directReference. * @param directReference New value of property directReference. */ public void setDirectReference(PdfIndirectReference directReference) { this.directReference = directReference; } /** * Reuses an existing image. * @param ref the reference to the image dictionary * @throws BadElementException on error * @return the image */ public static Image getInstance(PRIndirectReference ref) throws BadElementException { PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObjectRelease(ref); int width = ((PdfNumber)PdfReader.getPdfObjectRelease(dic.get(PdfName.WIDTH))).intValue(); int height = ((PdfNumber)PdfReader.getPdfObjectRelease(dic.get(PdfName.HEIGHT))).intValue(); Image imask = null; PdfObject obj = dic.get(PdfName.SMASK); if (obj != null && obj.isIndirect()) { imask = getInstance((PRIndirectReference)obj); } else { obj = dic.get(PdfName.MASK); if (obj != null && obj.isIndirect()) { PdfObject obj2 = PdfReader.getPdfObjectRelease(obj); if (obj2 instanceof PdfDictionary) imask = getInstance((PRIndirectReference)obj); } } Image img = new ImgRaw(width, height, 1, 1, null); img.imageMask = imask; img.directReference = ref; return img; } // copy constructor /** * Constructs an Image -object, using an url . * * @param image * another Image object. */ protected Image(Image image) { super(image); this.type = image.type; this.url = image.url; this.rawData = image.rawData; this.bpc = image.bpc; this.template = image.template; this.alignment = image.alignment; this.alt = image.alt; this.absoluteX = image.absoluteX; this.absoluteY = image.absoluteY; this.plainWidth = image.plainWidth; this.plainHeight = image.plainHeight; this.scaledWidth = image.scaledWidth; this.scaledHeight = image.scaledHeight; this.mySerialId = image.mySerialId; this.directReference = image.directReference; this.rotationRadians = image.rotationRadians; this.initialRotation = image.initialRotation; this.indentationLeft = image.indentationLeft; this.indentationRight = image.indentationRight; this.spacingBefore = image.spacingBefore; this.spacingAfter = image.spacingAfter; this.widthPercentage = image.widthPercentage; this.annotation = image.annotation; this.layer = image.layer; this.interpolation = image.interpolation; this.originalType = image.originalType; this.originalData = image.originalData; this.deflated = image.deflated; this.dpiX = image.dpiX; this.dpiY = image.dpiY; this.XYRatio = image.XYRatio; this.colorspace = image.colorspace; this.invert = image.invert; this.profile = image.profile; this.additional = image.additional; this.mask = image.mask; this.imageMask = image.imageMask; this.smask = image.smask; this.transparency = image.transparency; } /** * gets an instance of an Image * * @param image * an Image object * @return a new Image object */ public static Image getInstance(Image image) { if (image == null) return null; try { Class cs = image.getClass(); Constructor constructor = cs .getDeclaredConstructor(new Class[] { Image.class }); return (Image) constructor.newInstance(new Object[] { image }); } catch (Exception e) { throw new ExceptionConverter(e); } } // implementation of the Element interface /** * Returns the type. * * @return a type */ public int type() { return type; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } // checking the type of Image /** * Returns true if the image is a Jpeg * -object. * * @return a boolean */ public boolean isJpeg() { return type == JPEG; } /** * Returns true if the image is a ImgRaw * -object. * * @return a boolean */ public boolean isImgRaw() { return type == IMGRAW; } /** * Returns true if the image is an ImgTemplate * -object. * * @return a boolean */ public boolean isImgTemplate() { return type == IMGTEMPLATE; } // getters and setters /** * Gets the String -representation of the reference to the * image. * * @return a String */ public URL getUrl() { return url; } /** * Sets the url of the image * * @param url * the url of the image */ public void setUrl(URL url) { this.url = url; } /** * Gets the raw data for the image. *

* Remark: this only makes sense for Images of the type RawImage * . * * @return the raw data */ public byte[] getRawData() { return rawData; } /** * Gets the bpc for the image. *

* Remark: this only makes sense for Images of the type RawImage * . * * @return a bpc value */ public int getBpc() { return bpc; } /** * Gets the template to be used as an image. *

* Remark: this only makes sense for Images of the type ImgTemplate * . * * @return the template */ public PdfTemplate getTemplateData() { return template[0]; } /** * Sets data from a PdfTemplate * * @param template * the template with the content */ public void setTemplateData(PdfTemplate template) { this.template[0] = template; } /** * Gets the alignment for the image. * * @return a value */ public int getAlignment() { return alignment; } /** * Sets the alignment for the image. * * @param alignment * the alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * Gets the alternative text for the image. * * @return a String */ public String getAlt() { return alt; } /** * Sets the alternative information for the image. * * @param alt * the alternative information */ public void setAlt(String alt) { this.alt = alt; } /** * Sets the absolute position of the Image. * * @param absoluteX * @param absoluteY */ public void setAbsolutePosition(float absoluteX, float absoluteY) { this.absoluteX = absoluteX; this.absoluteY = absoluteY; } /** * Checks if the Images has to be added at an absolute X * position. * * @return a boolean */ public boolean hasAbsoluteX() { return !Float.isNaN(absoluteX); } /** * Returns the absolute X position. * * @return a position */ public float getAbsoluteX() { return absoluteX; } /** * Checks if the Images has to be added at an absolute * position. * * @return a boolean */ public boolean hasAbsoluteY() { return !Float.isNaN(absoluteY); } /** * Returns the absolute Y position. * * @return a position */ public float getAbsoluteY() { return absoluteY; } // width and height /** * Gets the scaled width of the image. * * @return a value */ public float getScaledWidth() { return scaledWidth; } /** * Gets the scaled height of the image. * * @return a value */ public float getScaledHeight() { return scaledHeight; } /** * Gets the plain width of the image. * * @return a value */ public float getPlainWidth() { return plainWidth; } /** * Gets the plain height of the image. * * @return a value */ public float getPlainHeight() { return plainHeight; } /** * Scale the image to an absolute width and an absolute height. * * @param newWidth * the new width * @param newHeight * the new height */ public void scaleAbsolute(float newWidth, float newHeight) { plainWidth = newWidth; plainHeight = newHeight; float[] matrix = matrix(); scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; setWidthPercentage(0); } /** * Scale the image to an absolute width. * * @param newWidth * the new width */ public void scaleAbsoluteWidth(float newWidth) { plainWidth = newWidth; float[] matrix = matrix(); scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; setWidthPercentage(0); } /** * Scale the image to an absolute height. * * @param newHeight * the new height */ public void scaleAbsoluteHeight(float newHeight) { plainHeight = newHeight; float[] matrix = matrix(); scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; setWidthPercentage(0); } /** * Scale the image to a certain percentage. * * @param percent * the scaling percentage */ public void scalePercent(float percent) { scalePercent(percent, percent); } /** * Scale the width and height of an image to a certain percentage. * * @param percentX * the scaling percentage of the width * @param percentY * the scaling percentage of the height */ public void scalePercent(float percentX, float percentY) { plainWidth = (getWidth() * percentX) / 100f; plainHeight = (getHeight() * percentY) / 100f; float[] matrix = matrix(); scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; setWidthPercentage(0); } /** * Scales the image so that it fits a certain width and height. * * @param fitWidth * the width to fit * @param fitHeight * the height to fit */ public void scaleToFit(float fitWidth, float fitHeight) { scalePercent(100); float percentX = (fitWidth * 100) / getScaledWidth(); float percentY = (fitHeight * 100) / getScaledHeight(); scalePercent(percentX < percentY ? percentX : percentY); setWidthPercentage(0); } /** * Returns the transformation matrix of the image. * * @return an array [AX, AY, BX, BY, CX, CY, DX, DY] */ public float[] matrix() { float[] matrix = new float[8]; float cosX = (float) Math.cos(rotationRadians); float sinX = (float) Math.sin(rotationRadians); matrix[AX] = plainWidth * cosX; matrix[AY] = plainWidth * sinX; matrix[BX] = (-plainHeight) * sinX; matrix[BY] = plainHeight * cosX; if (rotationRadians < Math.PI / 2f) { matrix[CX] = matrix[BX]; matrix[CY] = 0; matrix[DX] = matrix[AX]; matrix[DY] = matrix[AY] + matrix[BY]; } else if (rotationRadians < Math.PI) { matrix[CX] = matrix[AX] + matrix[BX]; matrix[CY] = matrix[BY]; matrix[DX] = 0; matrix[DY] = matrix[AY]; } else if (rotationRadians < Math.PI * 1.5f) { matrix[CX] = matrix[AX]; matrix[CY] = matrix[AY] + matrix[BY]; matrix[DX] = matrix[BX]; matrix[DY] = 0; } else { matrix[CX] = 0; matrix[CY] = matrix[AY]; matrix[DX] = matrix[AX] + matrix[BX]; matrix[DY] = matrix[BY]; } return matrix; } // serial stamping /** a static that is used for attributing a unique id to each image. */ static long serialId = 0; /** Creates a new serial id. */ static protected synchronized Long getSerialId() { ++serialId; return new Long(serialId); } /** * Returns a serial id for the Image (reuse the same image more than once) * * @return a serialId */ public Long getMySerialId() { return mySerialId; } // rotation, note that the superclass also has a rotation value. /** This is the rotation of the image in radians. */ protected float rotationRadians; /** Holds value of property initialRotation. */ private float initialRotation; /** * Gets the current image rotation in radians. * @return the current image rotation in radians */ public float getImageRotation() { double d = 2.0 * Math.PI; float rot = (float) ((rotationRadians - initialRotation) % d); if (rot < 0) { rot += d; } return rot; } /** * Sets the rotation of the image in radians. * * @param r * rotation in radians */ public void setRotation(float r) { double d = 2.0 * Math.PI; rotationRadians = (float) ((r + initialRotation) % d); if (rotationRadians < 0) { rotationRadians += d; } float[] matrix = matrix(); scaledWidth = matrix[DX] - matrix[CX]; scaledHeight = matrix[DY] - matrix[CY]; } /** * Sets the rotation of the image in degrees. * * @param deg * rotation in degrees */ public void setRotationDegrees(float deg) { double d = Math.PI; setRotation(deg / 180 * (float) d); } /** * Getter for property initialRotation. * @return Value of property initialRotation. */ public float getInitialRotation() { return this.initialRotation; } /** * Some image formats, like TIFF may present the images rotated that have * to be compensated. * @param initialRotation New value of property initialRotation. */ public void setInitialRotation(float initialRotation) { float old_rot = rotationRadians - this.initialRotation; this.initialRotation = initialRotation; setRotation(old_rot); } // indentations /** the indentation to the left. */ protected float indentationLeft = 0; /** the indentation to the right. */ protected float indentationRight = 0; /** The spacing before the image. */ protected float spacingBefore; /** The spacing after the image. */ protected float spacingAfter; /** * Gets the left indentation. * * @return the left indentation */ public float getIndentationLeft() { return indentationLeft; } /** * Sets the left indentation. * * @param f */ public void setIndentationLeft(float f) { indentationLeft = f; } /** * Gets the right indentation. * * @return the right indentation */ public float getIndentationRight() { return indentationRight; } /** * Sets the right indentation. * * @param f */ public void setIndentationRight(float f) { indentationRight = f; } /** * Gets the spacing before this image. * * @return the spacing */ public float getSpacingBefore() { return spacingBefore; } /** * Sets the spacing before this image. * * @param spacing * the new spacing */ public void setSpacingBefore(float spacing) { this.spacingBefore = spacing; } /** * Gets the spacing before this image. * * @return the spacing */ public float getSpacingAfter() { return spacingAfter; } /** * Sets the spacing after this image. * * @param spacing * the new spacing */ public void setSpacingAfter(float spacing) { this.spacingAfter = spacing; } // widthpercentage (for the moment only used in ColumnText) /** * Holds value of property widthPercentage. */ private float widthPercentage = 100; /** * Getter for property widthPercentage. * * @return Value of property widthPercentage. */ public float getWidthPercentage() { return this.widthPercentage; } /** * Setter for property widthPercentage. * * @param widthPercentage * New value of property widthPercentage. */ public void setWidthPercentage(float widthPercentage) { this.widthPercentage = widthPercentage; } // annotation /** if the annotation is not null the image will be clickable. */ protected Annotation annotation = null; /** * Sets the annotation of this Image. * * @param annotation * the annotation */ public void setAnnotation(Annotation annotation) { this.annotation = annotation; } /** * Gets the annotation. * * @return the annotation that is linked to this image */ public Annotation getAnnotation() { return annotation; } // Optional Content /** Optional Content layer to which we want this Image to belong. */ protected PdfOCG layer; /** * Gets the layer this image belongs to. * * @return the layer this image belongs to or null for no * layer defined */ public PdfOCG getLayer() { return layer; } /** * Sets the layer this image belongs to. * * @param layer * the layer this image belongs to */ public void setLayer(PdfOCG layer) { this.layer = layer; } // interpolation /** Holds value of property interpolation. */ protected boolean interpolation; /** * Getter for property interpolation. * * @return Value of property interpolation. */ public boolean isInterpolation() { return interpolation; } /** * Sets the image interpolation. Image interpolation attempts to produce a * smooth transition between adjacent sample values. * * @param interpolation * New value of property interpolation. */ public void setInterpolation(boolean interpolation) { this.interpolation = interpolation; } // original type and data /** Holds value of property originalType. */ protected int originalType = ORIGINAL_NONE; /** Holds value of property originalData. */ protected byte[] originalData; /** * Getter for property originalType. * * @return Value of property originalType. * */ public int getOriginalType() { return this.originalType; } /** * Setter for property originalType. * * @param originalType * New value of property originalType. * */ public void setOriginalType(int originalType) { this.originalType = originalType; } /** * Getter for property originalData. * * @return Value of property originalData. * */ public byte[] getOriginalData() { return this.originalData; } /** * Setter for property originalData. * * @param originalData * New value of property originalData. * */ public void setOriginalData(byte[] originalData) { this.originalData = originalData; } // the following values are only set for specific types of images. /** Holds value of property deflated. */ protected boolean deflated = false; /** * Getter for property deflated. * * @return Value of property deflated. * */ public boolean isDeflated() { return this.deflated; } /** * Setter for property deflated. * * @param deflated * New value of property deflated. */ public void setDeflated(boolean deflated) { this.deflated = deflated; } // DPI info /** Holds value of property dpiX. */ protected int dpiX = 0; /** Holds value of property dpiY. */ protected int dpiY = 0; /** * Gets the dots-per-inch in the X direction. Returns 0 if not available. * * @return the dots-per-inch in the X direction */ public int getDpiX() { return dpiX; } /** * Gets the dots-per-inch in the Y direction. Returns 0 if not available. * * @return the dots-per-inch in the Y direction */ public int getDpiY() { return dpiY; } /** * Sets the dots per inch value * * @param dpiX * dpi for x coordinates * @param dpiY * dpi for y coordinates */ public void setDpi(int dpiX, int dpiY) { this.dpiX = dpiX; this.dpiY = dpiY; } // XY Ratio /** Holds value of property XYRatio. */ private float XYRatio = 0; /** * Gets the X/Y pixel dimensionless aspect ratio. * * @return the X/Y pixel dimensionless aspect ratio */ public float getXYRatio() { return this.XYRatio; } /** * Sets the X/Y pixel dimensionless aspect ratio. * * @param XYRatio * the X/Y pixel dimensionless aspect ratio */ public void setXYRatio(float XYRatio) { this.XYRatio = XYRatio; } // color, colorspaces and transparency /** this is the colorspace of a jpeg-image. */ protected int colorspace = -1; /** * Gets the colorspace for the image. *

* Remark: this only makes sense for Images of the type Jpeg. * * @return a colorspace value */ public int getColorspace() { return colorspace; } /** Image color inversion */ protected boolean invert = false; /** * Getter for the inverted value * * @return true if the image is inverted */ public boolean isInverted() { return invert; } /** * Sets inverted true or false * * @param invert * true or false */ public void setInverted(boolean invert) { this.invert = invert; } /** ICC Profile attached */ protected ICC_Profile profile = null; /** * Tags this image with an ICC profile. * * @param profile * the profile */ public void tagICC(ICC_Profile profile) { this.profile = profile; } /** * Checks is the image has an ICC profile. * * @return the ICC profile or null */ public boolean hasICCProfile() { return (this.profile != null); } /** * Gets the images ICC profile. * * @return the ICC profile */ public ICC_Profile getICCProfile() { return profile; } /** a dictionary with additional information */ private PdfDictionary additional = null; /** * Getter for the dictionary with additional information. * * @return a PdfDictionary with additional information. */ public PdfDictionary getAdditional() { return this.additional; } /** * Sets the /Colorspace key. * * @param additional * a PdfDictionary with additional information. */ public void setAdditional(PdfDictionary additional) { this.additional = additional; } /** * Replaces CalRGB and CalGray colorspaces with DeviceRGB and DeviceGray. */ public void simplifyColorspace() { if (additional == null) return; PdfArray value = additional.getAsArray(PdfName.COLORSPACE); if (value == null) return; PdfObject cs = simplifyColorspace(value); PdfObject newValue; if (cs.isName()) newValue = cs; else { newValue = value; PdfName first = value.getAsName(0); if (PdfName.INDEXED.equals(first)) { if (value.size() >= 2) { PdfArray second = value.getAsArray(1); if (second != null) { value.set(1, simplifyColorspace(second)); } } } } additional.put(PdfName.COLORSPACE, newValue); } /** * Gets a PDF Name from an array or returns the object that was passed. */ private PdfObject simplifyColorspace(PdfArray obj) { if (obj == null) return obj; PdfName first = obj.getAsName(0); if (PdfName.CALGRAY.equals(first)) return PdfName.DEVICEGRAY; else if (PdfName.CALRGB.equals(first)) return PdfName.DEVICERGB; else return obj; } /** Is this image a mask? */ protected boolean mask = false; /** The image that serves as a mask for this image. */ protected Image imageMask; /** Holds value of property smask. */ private boolean smask; /** * Returns true if this Image is a mask. * * @return true if this Image is a mask */ public boolean isMask() { return mask; } /** * Make this Image a mask. * * @throws DocumentException * if this Image can not be a mask */ public void makeMask() throws DocumentException { if (!isMaskCandidate()) throw new DocumentException("This image can not be an image mask."); mask = true; } /** * Returns true if this Image has the * requisites to be a mask. * * @return true if this Image can be a mask */ public boolean isMaskCandidate() { if (type == IMGRAW) { if (bpc > 0xff) return true; } return colorspace == 1; } /** * Gets the explicit masking. * * @return the explicit masking */ public Image getImageMask() { return imageMask; } /** * Sets the explicit masking. * * @param mask * the mask to be applied * @throws DocumentException * on error */ public void setImageMask(Image mask) throws DocumentException { if (this.mask) throw new DocumentException( "An image mask cannot contain another image mask."); if (!mask.mask) throw new DocumentException( "The image mask is not a mask. Did you do makeMask()?"); imageMask = mask; smask = (mask.bpc > 1 && mask.bpc <= 8); } /** * Getter for property smask. * * @return Value of property smask. * */ public boolean isSmask() { return this.smask; } /** * Setter for property smask. * * @param smask * New value of property smask. */ public void setSmask(boolean smask) { this.smask = smask; } /** this is the transparency information of the raw image */ protected int transparency[]; /** * Returns the transparency. * * @return the transparency values */ public int[] getTransparency() { return transparency; } /** * Sets the transparency values * * @param transparency * the transparency values */ public void setTransparency(int transparency[]) { this.transparency = transparency; } /** * Returns the compression level used for images written as a compressed stream. * @return the compression level (0 = best speed, 9 = best compression, -1 is default) * @since 2.1.3 */ public int getCompressionLevel() { return compressionLevel; } /** * Sets the compression level to be used if the image is written as a compressed stream. * @param compressionLevel a value between 0 (best speed) and 9 (best compression) * @since 2.1.3 */ public void setCompressionLevel(int compressionLevel) { if (compressionLevel < PdfStream.NO_COMPRESSION || compressionLevel > PdfStream.BEST_COMPRESSION) this.compressionLevel = PdfStream.DEFAULT_COMPRESSION; else this.compressionLevel = compressionLevel; } }src/core/com/lowagie/text/ImgCCITT.java100644 0 0 10232 11012562273 15300 0ustar 0 0 /* * $Id: ImgCCITT.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import com.lowagie.text.pdf.codec.TIFFFaxDecoder; import java.net.URL; /** * CCITT Image data that has to be inserted into the document * * @see Element * @see Image * * @author Paulo Soares */ public class ImgCCITT extends Image { ImgCCITT(Image image) { super(image); } /** Creates an Image with CCITT compression. * * @param width the exact width of the image * @param height the exact height of the image * @param reverseBits reverses the bits in data. * Bit 0 is swapped with bit 7 and so on. * @param typeCCITT the type of compression in data. It can be * CCITTG4, CCITTG31D, CCITTG32D * @param parameters parameters associated with this stream. Possible values are * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and CCITT_ENDOFBLOCK or a * combination of them * @param data the image data * @throws BadElementException on error */ public ImgCCITT(int width, int height, boolean reverseBits, int typeCCITT, int parameters, byte[] data) throws BadElementException{ super((URL)null); if (typeCCITT != CCITTG4 && typeCCITT != CCITTG3_1D && typeCCITT != CCITTG3_2D) throw new BadElementException("The CCITT compression type must be CCITTG4, CCITTG3_1D or CCITTG3_2D"); if (reverseBits) TIFFFaxDecoder.reverseBits(data); type = IMGRAW; scaledHeight = height; setTop(scaledHeight); scaledWidth = width; setRight(scaledWidth); colorspace = parameters; bpc = typeCCITT; rawData = data; plainWidth = getWidth(); plainHeight = getHeight(); } }src/core/com/lowagie/text/ImgJBIG2.java100644 0 0 10102 11215636056 15231 0ustar 0 0 /* * $Id: ImgJBIG2.java 3962 2009-06-10 11:43:19Z psoares33 $ * * Copyright 2009 by Nigel Kerr. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.net.URL; import java.security.MessageDigest; /** * Support for JBIG2 images. * @since 2.1.5 */ public class ImgJBIG2 extends Image { /** JBIG2 globals */ private byte[] global; /** A unique hash */ private byte[] globalHash; /** * Copy contstructor. * @param image another Image */ ImgJBIG2(Image image) { super(image); } /** * Empty constructor. */ public ImgJBIG2() { super((Image) null); } /** * Actual constructor for ImgJBIG2 images. * @param width the width of the image * @param height the height of the image * @param data the raw image data * @param globals JBIG2 globals */ public ImgJBIG2(int width, int height, byte[] data, byte[] globals) { super((URL) null); type = JBIG2; originalType = ORIGINAL_JBIG2; scaledHeight = height; setTop(scaledHeight); scaledWidth = width; setRight(scaledWidth); bpc = 1; colorspace = 1; rawData = data; plainWidth = getWidth(); plainHeight = getHeight(); if ( globals != null ) { this.global = globals; MessageDigest md; try { md = MessageDigest.getInstance("MD5"); md.update(this.global); this.globalHash = md.digest(); } catch (Exception e) { //ignore } } } /** * Getter for the JBIG2 global data. * @return an array of bytes */ public byte[] getGlobalBytes() { return this.global; } /** * Getter for the unique hash. * @return an array of bytes */ public byte[] getGlobalHash() { return this.globalHash; } } src/core/com/lowagie/text/ImgRaw.java100644 0 0 7357 11012562273 15161 0ustar 0 0 /* * $Id: ImgRaw.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.net.URL; /** * Raw Image data that has to be inserted into the document * * @see Element * @see Image * * @author Paulo Soares */ public class ImgRaw extends Image { ImgRaw(Image image) { super(image); } /** Creates an Image in raw mode. * * @param width the exact width of the image * @param height the exact height of the image * @param components 1,3 or 4 for GrayScale, RGB and CMYK * @param bpc bits per component. Must be 1,2,4 or 8 * @param data the image data * @throws BadElementException on error */ public ImgRaw(int width, int height, int components, int bpc, byte[] data) throws BadElementException{ super((URL)null); type = IMGRAW; scaledHeight = height; setTop(scaledHeight); scaledWidth = width; setRight(scaledWidth); if (components != 1 && components != 3 && components != 4) throw new BadElementException("Components must be 1, 3, or 4."); if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8) throw new BadElementException("Bits-per-component must be 1, 2, 4, or 8."); colorspace = components; this.bpc = bpc; rawData = data; plainWidth = getWidth(); plainHeight = getHeight(); } }src/core/com/lowagie/text/ImgTemplate.java100644 0 0 7103 11036112746 16172 0ustar 0 0 /* * $Id: ImgTemplate.java 3517 2008-06-29 10:37:16Z blowagie $ * * Copyright 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.net.URL; import com.lowagie.text.pdf.PdfTemplate; /** * PdfTemplate that has to be inserted into the document * * @see Element * @see Image * * @author Paulo Soares */ public class ImgTemplate extends Image { ImgTemplate(Image image) { super(image); } /** Creates an Image from a PdfTemplate. * * @param template the PdfTemplate * @throws BadElementException on error */ public ImgTemplate(PdfTemplate template) throws BadElementException{ super((URL)null); if (template == null) throw new BadElementException("The template can not be null."); if (template.getType() == PdfTemplate.TYPE_PATTERN) throw new BadElementException("A pattern can not be used as a template to create an image."); type = IMGTEMPLATE; scaledHeight = template.getHeight(); setTop(scaledHeight); scaledWidth = template.getWidth(); setRight(scaledWidth); setTemplateData(template); plainWidth = getWidth(); plainHeight = getHeight(); } }src/core/com/lowagie/text/ImgWMF.java100644 0 0 14753 11012562273 15077 0ustar 0 0 /* * $Id: ImgWMF.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.codec.wmf.InputMeta; import com.lowagie.text.pdf.codec.wmf.MetaDo; /** * An ImgWMF is the representation of a windows metafile * that has to be inserted into the document * * @see Element * @see Image */ public class ImgWMF extends Image { // Constructors ImgWMF(Image image) { super(image); } /** * Constructs an ImgWMF-object, using an url. * * @param url the URL where the image can be found * @throws BadElementException on error * @throws IOException on error */ public ImgWMF(URL url) throws BadElementException, IOException { super(url); processParameters(); } /** * Constructs an ImgWMF-object, using a filename. * * @param filename a String-representation of the file that contains the image. * @throws BadElementException on error * @throws MalformedURLException on error * @throws IOException on error */ public ImgWMF(String filename) throws BadElementException, MalformedURLException, IOException { this(Utilities.toURL(filename)); } /** * Constructs an ImgWMF-object from memory. * * @param img the memory image * @throws BadElementException on error * @throws IOException on error */ public ImgWMF(byte[] img) throws BadElementException, IOException { super((URL)null); rawData = img; originalData = img; processParameters(); } /** * This method checks if the image is a valid WMF and processes some parameters. * @throws BadElementException * @throws IOException */ private void processParameters() throws BadElementException, IOException { type = IMGTEMPLATE; originalType = ORIGINAL_WMF; InputStream is = null; try { String errorID; if (rawData == null){ is = url.openStream(); errorID = url.toString(); } else{ is = new java.io.ByteArrayInputStream(rawData); errorID = "Byte array"; } InputMeta in = new InputMeta(is); if (in.readInt() != 0x9AC6CDD7) { throw new BadElementException(errorID + " is not a valid placeable windows metafile."); } in.readWord(); int left = in.readShort(); int top = in.readShort(); int right = in.readShort(); int bottom = in.readShort(); int inch = in.readWord(); dpiX = 72; dpiY = 72; scaledHeight = (float)(bottom - top) / inch * 72f; setTop(scaledHeight); scaledWidth = (float)(right - left) / inch * 72f; setRight(scaledWidth); } finally { if (is != null) { is.close(); } plainWidth = getWidth(); plainHeight = getHeight(); } } /** Reads the WMF into a template. * @param template the template to read to * @throws IOException on error * @throws DocumentException on error */ public void readWMF(PdfTemplate template) throws IOException, DocumentException { setTemplateData(template); template.setWidth(getWidth()); template.setHeight(getHeight()); InputStream is = null; try { if (rawData == null){ is = url.openStream(); } else{ is = new java.io.ByteArrayInputStream(rawData); } MetaDo meta = new MetaDo(is, template); meta.readAll(); } finally { if (is != null) { is.close(); } } } } src/core/com/lowagie/text/Jpeg.java100644 0 0 31241 11215636056 14673 0ustar 0 0 /* * $Id: Jpeg.java 3970 2009-06-16 08:09:54Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.color.ICC_Profile; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * An Jpeg is the representation of a graphic element (JPEG) * that has to be inserted into the document * * @see Element * @see Image */ public class Jpeg extends Image { // public static final membervariables /** This is a type of marker. */ public static final int NOT_A_MARKER = -1; /** This is a type of marker. */ public static final int VALID_MARKER = 0; /** Acceptable Jpeg markers. */ public static final int[] VALID_MARKERS = {0xC0, 0xC1, 0xC2}; /** This is a type of marker. */ public static final int UNSUPPORTED_MARKER = 1; /** Unsupported Jpeg markers. */ public static final int[] UNSUPPORTED_MARKERS = {0xC3, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF}; /** This is a type of marker. */ public static final int NOPARAM_MARKER = 2; /** Jpeg markers without additional parameters. */ public static final int[] NOPARAM_MARKERS = {0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0x01}; /** Marker value */ public static final int M_APP0 = 0xE0; /** Marker value */ public static final int M_APP2 = 0xE2; /** Marker value */ public static final int M_APPE = 0xEE; /** sequence that is used in all Jpeg files */ public static final byte JFIF_ID[] = {0x4A, 0x46, 0x49, 0x46, 0x00}; private byte[][] icc; // Constructors Jpeg(Image image) { super(image); } /** * Constructs a Jpeg-object, using an url. * * @param url the URL where the image can be found * @throws BadElementException * @throws IOException */ public Jpeg(URL url) throws BadElementException, IOException { super(url); processParameters(); } /** * Constructs a Jpeg-object from memory. * * @param img the memory image * @throws BadElementException * @throws IOException */ public Jpeg(byte[] img) throws BadElementException, IOException { super((URL)null); rawData = img; originalData = img; processParameters(); } /** * Constructs a Jpeg-object from memory. * * @param img the memory image. * @param width the width you want the image to have * @param height the height you want the image to have * @throws BadElementException * @throws IOException */ public Jpeg(byte[] img, float width, float height) throws BadElementException, IOException { this(img); scaledWidth = width; scaledHeight = height; } // private static methods /** * Reads a short from the InputStream. * * @param is the InputStream * @return an int * @throws IOException */ private static final int getShort(InputStream is) throws IOException { return (is.read() << 8) + is.read(); } /** * Returns a type of marker. * * @param marker an int * @return a type: VALID_MARKER, UNSUPPORTED_MARKER or NOPARAM_MARKER */ private static final int marker(int marker) { for (int i = 0; i < VALID_MARKERS.length; i++) { if (marker == VALID_MARKERS[i]) { return VALID_MARKER; } } for (int i = 0; i < NOPARAM_MARKERS.length; i++) { if (marker == NOPARAM_MARKERS[i]) { return NOPARAM_MARKER; } } for (int i = 0; i < UNSUPPORTED_MARKERS.length; i++) { if (marker == UNSUPPORTED_MARKERS[i]) { return UNSUPPORTED_MARKER; } } return NOT_A_MARKER; } // private methods /** * This method checks if the image is a valid JPEG and processes some parameters. * @throws BadElementException * @throws IOException */ private void processParameters() throws BadElementException, IOException { type = JPEG; originalType = ORIGINAL_JPEG; InputStream is = null; try { String errorID; if (rawData == null){ is = url.openStream(); errorID = url.toString(); } else{ is = new java.io.ByteArrayInputStream(rawData); errorID = "Byte array"; } if (is.read() != 0xFF || is.read() != 0xD8) { throw new BadElementException(errorID + " is not a valid JPEG-file."); } boolean firstPass = true; int len; while (true) { int v = is.read(); if (v < 0) throw new IOException("Premature EOF while reading JPG."); if (v == 0xFF) { int marker = is.read(); if (firstPass && marker == M_APP0) { firstPass = false; len = getShort(is); if (len < 16) { Utilities.skip(is, len - 2); continue; } byte bcomp[] = new byte[JFIF_ID.length]; int r = is.read(bcomp); if (r != bcomp.length) throw new BadElementException(errorID + " corrupted JFIF marker."); boolean found = true; for (int k = 0; k < bcomp.length; ++k) { if (bcomp[k] != JFIF_ID[k]) { found = false; break; } } if (!found) { Utilities.skip(is, len - 2 - bcomp.length); continue; } Utilities.skip(is, 2); int units = is.read(); int dx = getShort(is); int dy = getShort(is); if (units == 1) { dpiX = dx; dpiY = dy; } else if (units == 2) { dpiX = (int)(dx * 2.54f + 0.5f); dpiY = (int)(dy * 2.54f + 0.5f); } Utilities.skip(is, len - 2 - bcomp.length - 7); continue; } if (marker == M_APPE) { len = getShort(is) - 2; byte[] byteappe = new byte[len]; for (int k = 0; k < len; ++k) { byteappe[k] = (byte)is.read(); } if (byteappe.length >= 12) { String appe = new String(byteappe, 0, 5, "ISO-8859-1"); if (appe.equals("Adobe")) { invert = true; } } continue; } if (marker == M_APP2) { len = getShort(is) - 2; byte[] byteapp2 = new byte[len]; for (int k = 0; k < len; ++k) { byteapp2[k] = (byte)is.read(); } if (byteapp2.length >= 14) { String app2 = new String(byteapp2, 0, 11, "ISO-8859-1"); if (app2.equals("ICC_PROFILE")) { int order = byteapp2[12] & 0xff; int count = byteapp2[13] & 0xff; if (icc == null) icc = new byte[count][]; icc[order - 1] = byteapp2; } } continue; } firstPass = false; int markertype = marker(marker); if (markertype == VALID_MARKER) { Utilities.skip(is, 2); if (is.read() != 0x08) { throw new BadElementException(errorID + " must have 8 bits per component."); } scaledHeight = getShort(is); setTop(scaledHeight); scaledWidth = getShort(is); setRight(scaledWidth); colorspace = is.read(); bpc = 8; break; } else if (markertype == UNSUPPORTED_MARKER) { throw new BadElementException(errorID + ": unsupported JPEG marker: " + marker); } else if (markertype != NOPARAM_MARKER) { Utilities.skip(is, getShort(is) - 2); } } } } finally { if (is != null) { is.close(); } } plainWidth = getWidth(); plainHeight = getHeight(); if (icc != null) { int total = 0; for (int k = 0; k < icc.length; ++k) { if (icc[k] == null) { icc = null; return; } total += icc[k].length - 14; } byte[] ficc = new byte[total]; total = 0; for (int k = 0; k < icc.length; ++k) { System.arraycopy(icc[k], 14, ficc, total, icc[k].length - 14); total += icc[k].length - 14; } try { ICC_Profile icc_prof = ICC_Profile.getInstance(ficc); tagICC(icc_prof); } catch(IllegalArgumentException e) { // ignore ICC profile if it's invalid. } icc = null; } } } src/core/com/lowagie/text/Jpeg2000.java100644 0 0 20655 11106243445 15177 0ustar 0 0 /* * $Id: Jpeg2000.java 3583 2008-08-12 00:00:09Z xlv $ * * Copyright 2007 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * An Jpeg2000 is the representation of a graphic element (JPEG) * that has to be inserted into the document * * @see Element * @see Image */ public class Jpeg2000 extends Image { // public static final membervariables public static final int JP2_JP = 0x6a502020; public static final int JP2_IHDR = 0x69686472; public static final int JPIP_JPIP = 0x6a706970; public static final int JP2_FTYP = 0x66747970; public static final int JP2_JP2H = 0x6a703268; public static final int JP2_COLR = 0x636f6c72; public static final int JP2_JP2C = 0x6a703263; public static final int JP2_URL = 0x75726c20; public static final int JP2_DBTL = 0x6474626c; public static final int JP2_BPCC = 0x62706363; public static final int JP2_JP2 = 0x6a703220; InputStream inp; int boxLength; int boxType; // Constructors Jpeg2000(Image image) { super(image); } /** * Constructs a Jpeg2000-object, using an url. * * @param url the URL where the image can be found * @throws BadElementException * @throws IOException */ public Jpeg2000(URL url) throws BadElementException, IOException { super(url); processParameters(); } /** * Constructs a Jpeg2000-object from memory. * * @param img the memory image * @throws BadElementException * @throws IOException */ public Jpeg2000(byte[] img) throws BadElementException, IOException { super((URL)null); rawData = img; originalData = img; processParameters(); } /** * Constructs a Jpeg2000-object from memory. * * @param img the memory image. * @param width the width you want the image to have * @param height the height you want the image to have * @throws BadElementException * @throws IOException */ public Jpeg2000(byte[] img, float width, float height) throws BadElementException, IOException { this(img); scaledWidth = width; scaledHeight = height; } private int cio_read(int n) throws IOException { int v = 0; for (int i = n - 1; i >= 0; i--) { v += inp.read() << (i << 3); } return v; } public void jp2_read_boxhdr() throws IOException { boxLength = cio_read(4); boxType = cio_read(4); if (boxLength == 1) { if (cio_read(4) != 0) { throw new IOException("Cannot handle box sizes higher than 2^32"); } boxLength = cio_read(4); if (boxLength == 0) throw new IOException("Unsupported box size == 0"); } else if (boxLength == 0) { throw new IOException("Unsupported box size == 0"); } } /** * This method checks if the image is a valid JPEG and processes some parameters. * @throws IOException */ private void processParameters() throws IOException { type = JPEG2000; originalType = ORIGINAL_JPEG2000; inp = null; try { String errorID; if (rawData == null){ inp = url.openStream(); errorID = url.toString(); } else{ inp = new java.io.ByteArrayInputStream(rawData); errorID = "Byte array"; } boxLength = cio_read(4); if (boxLength == 0x0000000c) { boxType = cio_read(4); if (JP2_JP != boxType) { throw new IOException("Expected JP Marker"); } if (0x0d0a870a != cio_read(4)) { throw new IOException("Error with JP Marker"); } jp2_read_boxhdr(); if (JP2_FTYP != boxType) { throw new IOException("Expected FTYP Marker"); } Utilities.skip(inp, boxLength - 8); jp2_read_boxhdr(); do { if (JP2_JP2H != boxType) { if (boxType == JP2_JP2C) { throw new IOException("Expected JP2H Marker"); } Utilities.skip(inp, boxLength - 8); jp2_read_boxhdr(); } } while(JP2_JP2H != boxType); jp2_read_boxhdr(); if (JP2_IHDR != boxType) { throw new IOException("Expected IHDR Marker"); } scaledHeight = cio_read(4); setTop(scaledHeight); scaledWidth = cio_read(4); setRight(scaledWidth); bpc = -1; } else if (boxLength == 0xff4fff51) { Utilities.skip(inp, 4); int x1 = cio_read(4); int y1 = cio_read(4); int x0 = cio_read(4); int y0 = cio_read(4); Utilities.skip(inp, 16); colorspace = cio_read(2); bpc = 8; scaledHeight = y1 - y0; setTop(scaledHeight); scaledWidth = x1 - x0; setRight(scaledWidth); } else { throw new IOException("Not a valid Jpeg2000 file"); } } finally { if (inp != null) { try{inp.close();}catch(Exception e){} inp = null; } } plainWidth = getWidth(); plainHeight = getHeight(); } } src/core/com/lowagie/text/LargeElement.java100644 0 0 7305 11036112746 16332 0ustar 0 0 /* * $Id: LargeElement.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * Interface implemented by Element objects that can potentially consume * a lot of memory. Objects implementing the LargeElement interface can * be added to a Document more than once. If you have invoked setComplete(false), * they will be added partially and the content that was added will be * removed until you've invoked setComplete(true); * @since iText 2.0.8 */ public interface LargeElement extends Element { /** * If you invoke setComplete(false), you indicate that the content * of the object isn't complete yet; it can be added to the document * partially, but more will follow. If you invoke setComplete(true), * you indicate that you won't add any more data to the object. * @since iText 2.0.8 * @param complete false if you'll be adding more data after * adding the object to the document. */ public void setComplete(boolean complete); /** * Indicates if the element is complete or not. * @since iText 2.0.8 * @return indicates if the element is complete according to the user. */ public boolean isComplete(); /** * Flushes the content that has been added. */ public void flushContent(); } src/core/com/lowagie/text/List.java100644 0 0 41136 11012562273 14717 0ustar 0 0 /* * $Id: List.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.factories.RomanAlphabetFactory; /** * A List contains several ListItems. *

* Example 1: *

 * List list = new List(true, 20);
 * list.add(new ListItem("First line"));
 * list.add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));
 * list.add(new ListItem("Third line"));
 * 
* * The result of this code looks like this: *
    *
  1. * First line *
  2. *
  3. * The second line is longer to see what happens once the end of the line is reached. Will it start on a new line? *
  4. *
  5. * Third line *
  6. *
* * Example 2: *
 * List overview = new List(false, 10);
 * overview.add(new ListItem("This is an item"));
 * overview.add("This is another item");
 * 
* * The result of this code looks like this: *
    *
  • * This is an item *
  • *
  • * This is another item *
  • *
* * @see Element * @see ListItem */ public class List implements TextElementArray { // constants /** a possible value for the numbered parameter */ public static final boolean ORDERED = true; /** a possible value for the numbered parameter */ public static final boolean UNORDERED = false; /** a possible value for the lettered parameter */ public static final boolean NUMERICAL = false; /** a possible value for the lettered parameter */ public static final boolean ALPHABETICAL = true; /** a possible value for the lettered parameter */ public static final boolean UPPERCASE = false; /** a possible value for the lettered parameter */ public static final boolean LOWERCASE = true; // member variables /** This is the ArrayList containing the different ListItems. */ protected ArrayList list = new ArrayList(); /** Indicates if the list has to be numbered. */ protected boolean numbered = false; /** Indicates if the listsymbols are numerical or alphabetical. */ protected boolean lettered = false; /** Indicates if the listsymbols are lowercase or uppercase. */ protected boolean lowercase = false; /** Indicates if the indentation has to be set automatically. */ protected boolean autoindent = false; /** Indicates if the indentation of all the items has to be aligned. */ protected boolean alignindent = false; /** This variable indicates the first number of a numbered list. */ protected int first = 1; /** This is the listsymbol of a list that is not numbered. */ protected Chunk symbol = new Chunk("- "); /** * In case you are using numbered/lettered lists, this String is added before the number/letter. * @since iText 2.1.1 */ protected String preSymbol = ""; /** * In case you are using numbered/lettered lists, this String is added after the number/letter. * @since iText 2.1.1 */ protected String postSymbol = ". "; /** The indentation of this list on the left side. */ protected float indentationLeft = 0; /** The indentation of this list on the right side. */ protected float indentationRight = 0; /** The indentation of the listitems. */ protected float symbolIndent = 0; // constructors /** Constructs a List. */ public List() { this(false, false); } /** * Constructs a List with a specific symbol indentation. * @param symbolIndent the symbol indentation * @since iText 2.0.8 */ public List(float symbolIndent) { this.symbolIndent = symbolIndent; } /** * Constructs a List. * @param numbered a boolean */ public List(boolean numbered) { this(numbered, false); } /** * Constructs a List. * @param numbered a boolean * @param lettered has the list to be 'numbered' with letters */ public List(boolean numbered, boolean lettered) { this.numbered = numbered; this.lettered = lettered; this.autoindent = true; this.alignindent = true; } /** * Constructs a List. *

* Remark: the parameter symbolIndent is important for instance when * generating PDF-documents; it indicates the indentation of the listsymbol. * It is not important for HTML-documents. * * @param numbered a boolean * @param symbolIndent the indentation that has to be used for the listsymbol */ public List(boolean numbered, float symbolIndent) { this(numbered, false, symbolIndent); } /** * Creates a list * @param numbered has the list to be numbered? * @param lettered has the list to be 'numbered' with letters * @param symbolIndent the indentation of the symbol */ public List(boolean numbered, boolean lettered, float symbolIndent) { this.numbered = numbered; this.lettered = lettered; this.symbolIndent = symbolIndent; } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { for (Iterator i = list.iterator(); i.hasNext(); ) { listener.add((Element) i.next()); } return true; } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.LIST; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); for (Iterator i = list.iterator(); i.hasNext(); ) { tmp.addAll(((Element) i.next()).getChunks()); } return tmp; } // methods to set the membervariables /** * Adds an Object to the List. * * @param o the object to add. * @return true if adding the object succeeded */ public boolean add(Object o) { if (o instanceof ListItem) { ListItem item = (ListItem) o; if (numbered || lettered) { Chunk chunk = new Chunk(preSymbol, symbol.getFont()); int index = first + list.size(); if ( lettered ) chunk.append(RomanAlphabetFactory.getString(index, lowercase)); else chunk.append(String.valueOf(index)); chunk.append(postSymbol); item.setListSymbol(chunk); } else { item.setListSymbol(symbol); } item.setIndentationLeft(symbolIndent, autoindent); item.setIndentationRight(0); return list.add(item); } else if (o instanceof List) { List nested = (List) o; nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent); first--; return list.add(nested); } else if (o instanceof String) { return this.add(new ListItem((String) o)); } return false; } // extra methods /** Makes sure all the items in the list have the same indentation. */ public void normalizeIndentation() { float max = 0; Element o; for (Iterator i = list.iterator(); i.hasNext(); ) { o = (Element)i.next(); if (o instanceof ListItem) { max = Math.max(max, ((ListItem)o).getIndentationLeft()); } } for (Iterator i = list.iterator(); i.hasNext(); ) { o = (Element)i.next(); if (o instanceof ListItem) { ((ListItem)o).setIndentationLeft(max); } } } // setters /** * @param numbered the numbered to set */ public void setNumbered(boolean numbered) { this.numbered = numbered; } /** * @param lettered the lettered to set */ public void setLettered(boolean lettered) { this.lettered = lettered; } /** * @param uppercase the uppercase to set */ public void setLowercase(boolean uppercase) { this.lowercase = uppercase; } /** * @param autoindent the autoindent to set */ public void setAutoindent(boolean autoindent) { this.autoindent = autoindent; } /** * @param alignindent the alignindent to set */ public void setAlignindent(boolean alignindent) { this.alignindent = alignindent; } /** * Sets the number that has to come first in the list. * * @param first a number */ public void setFirst(int first) { this.first = first; } /** * Sets the listsymbol. * * @param symbol a Chunk */ public void setListSymbol(Chunk symbol) { this.symbol = symbol; } /** * Sets the listsymbol. *

* This is a shortcut for setListSymbol(Chunk symbol). * * @param symbol a String */ public void setListSymbol(String symbol) { this.symbol = new Chunk(symbol); } /** * Sets the indentation of this paragraph on the left side. * * @param indentation the new indentation */ public void setIndentationLeft(float indentation) { this.indentationLeft = indentation; } /** * Sets the indentation of this paragraph on the right side. * * @param indentation the new indentation */ public void setIndentationRight(float indentation) { this.indentationRight = indentation; } /** * @param symbolIndent the symbolIndent to set */ public void setSymbolIndent(float symbolIndent) { this.symbolIndent = symbolIndent; } // methods to retrieve information /** * Gets all the items in the list. * * @return an ArrayList containing ListItems. */ public ArrayList getItems() { return list; } /** * Gets the size of the list. * * @return a size */ public int size() { return list.size(); } /** * Returns true if the list is empty. * * @return true if the list is empty */ public boolean isEmpty() { return list.isEmpty(); } /** * Gets the leading of the first listitem. * * @return a leading */ public float getTotalLeading() { if (list.size() < 1) { return -1; } ListItem item = (ListItem) list.get(0); return item.getTotalLeading(); } // getters /** * Checks if the list is numbered. * @return true if the list is numbered, false otherwise. */ public boolean isNumbered() { return numbered; } /** * Checks if the list is lettered. * @return true if the list is lettered, false otherwise. */ public boolean isLettered() { return lettered; } /** * Checks if the list lettering is lowercase. * @return true if it is lowercase, false otherwise. */ public boolean isLowercase() { return lowercase; } /** * Checks if the indentation of list items is done automatically. * @return the autoindent */ public boolean isAutoindent() { return autoindent; } /** * Checks if all the listitems should be aligned. * @return the alignindent */ public boolean isAlignindent() { return alignindent; } /** * Gets the first number . * @return a number */ public int getFirst() { return first; } /** * Gets the Chunk containing the symbol. * @return a Chunk with a symbol */ public Chunk getSymbol() { return symbol; } /** * Gets the indentation of this paragraph on the left side. * @return the indentation */ public float getIndentationLeft() { return indentationLeft; } /** * Gets the indentation of this paragraph on the right side. * @return the indentation */ public float getIndentationRight() { return indentationRight; } /** * Gets the symbol indentation. * @return the symbol indentation */ public float getSymbolIndent() { return symbolIndent; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } /** * Returns the String that is after a number or letter in the list symbol. * @return the String that is after a number or letter in the list symbol * @since iText 2.1.1 */ public String getPostSymbol() { return postSymbol; } /** * Sets the String that has to be added after a number or letter in the list symbol. * @since iText 2.1.1 * @param postSymbol the String that has to be added after a number or letter in the list symbol. */ public void setPostSymbol(String postSymbol) { this.postSymbol = postSymbol; } /** * Returns the String that is before a number or letter in the list symbol. * @return the String that is before a number or letter in the list symbol * @since iText 2.1.1 */ public String getPreSymbol() { return preSymbol; } /** * Sets the String that has to be added before a number or letter in the list symbol. * @since iText 2.1.1 * @param preSymbol the String that has to be added before a number or letter in the list symbol. */ public void setPreSymbol(String preSymbol) { this.preSymbol = preSymbol; } }src/core/com/lowagie/text/ListItem.java100644 0 0 16241 11012562273 15535 0ustar 0 0 /* * $Id: ListItem.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * A ListItem is a Paragraph * that can be added to a List. *

* Example 1: *

 * List list = new List(true, 20);
 * list.add(new ListItem("First line"));
 * list.add(new ListItem("The second line is longer to see what happens once the end of the line is reached. Will it start on a new line?"));
 * list.add(new ListItem("Third line"));
 * 
* * The result of this code looks like this: *
    *
  1. * First line *
  2. *
  3. * The second line is longer to see what happens once the end of the line is reached. Will it start on a new line? *
  4. *
  5. * Third line *
  6. *
* * Example 2: *
 * List overview = new List(false, 10);
 * overview.add(new ListItem("This is an item"));
 * overview.add("This is another item");
 * 
* * The result of this code looks like this: *
    *
  • * This is an item *
  • *
  • * This is another item *
  • *
* * @see Element * @see List * @see Paragraph */ public class ListItem extends Paragraph { // constants private static final long serialVersionUID = 1970670787169329006L; // member variables /** this is the symbol that will precede the listitem. */ private Chunk symbol; // constructors /** * Constructs a ListItem. */ public ListItem() { super(); } /** * Constructs a ListItem with a certain leading. * * @param leading the leading */ public ListItem(float leading) { super(leading); } /** * Constructs a ListItem with a certain Chunk. * * @param chunk a Chunk */ public ListItem(Chunk chunk) { super(chunk); } /** * Constructs a ListItem with a certain String. * * @param string a String */ public ListItem(String string) { super(string); } /** * Constructs a ListItem with a certain String * and a certain Font. * * @param string a String * @param font a String */ public ListItem(String string, Font font) { super(string, font); } /** * Constructs a ListItem with a certain Chunk * and a certain leading. * * @param leading the leading * @param chunk a Chunk */ public ListItem(float leading, Chunk chunk) { super(leading, chunk); } /** * Constructs a ListItem with a certain String * and a certain leading. * * @param leading the leading * @param string a String */ public ListItem(float leading, String string) { super(leading, string); } /** * Constructs a ListItem with a certain leading, String * and Font. * * @param leading the leading * @param string a String * @param font a Font */ public ListItem(float leading, String string, Font font) { super(leading, string, font); } /** * Constructs a ListItem with a certain Phrase. * * @param phrase a Phrase */ public ListItem(Phrase phrase) { super(phrase); } // implementation of the Element-methods /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.LISTITEM; } // methods /** * Sets the listsymbol. * * @param symbol a Chunk */ public void setListSymbol(Chunk symbol) { if (this.symbol == null) { this.symbol = symbol; if (this.symbol.getFont().isStandardFont()) { this.symbol.setFont(font); } } } /** * Sets the indentation of this paragraph on the left side. * * @param indentation the new indentation */ public void setIndentationLeft(float indentation, boolean autoindent) { if (autoindent) { setIndentationLeft(getListSymbol().getWidthPoint()); } else { setIndentationLeft(indentation); } } // methods to retrieve information /** * Returns the listsymbol. * * @return a Chunk */ public Chunk getListSymbol() { return symbol; } } src/core/com/lowagie/text/MPL-1.1.txt100644 0 0 62233 11000354131 14615 0ustar 0 0 MOZILLA PUBLIC LICENSE Version 1.1 --------------- 1. Definitions. 1.0.1. "Commercial Use" means distribution or otherwise making the Covered Code available to a third party. 1.1. "Contributor" means each entity that creates or contributes to the creation of Modifications. 1.2. "Contributor Version" means the combination of the Original Code, prior Modifications used by a Contributor, and the Modifications made by that particular Contributor. 1.3. "Covered Code" means the Original Code or Modifications or the combination of the Original Code and Modifications, in each case including portions thereof. 1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted in the software development community for the electronic transfer of data. 1.5. "Executable" means Covered Code in any form other than Source Code. 1.6. "Initial Developer" means the individual or entity identified as the Initial Developer in the Source Code notice required by Exhibit A. 1.7. "Larger Work" means a work which combines Covered Code or portions thereof with code not governed by the terms of this License. 1.8. "License" means this document. 1.8.1. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein. 1.9. "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications. When Covered Code is released as a series of files, a Modification is: A. Any addition to or deletion from the contents of a file containing Original Code or previous Modifications. B. Any new file that contains any part of the Original Code or previous Modifications. 1.10. "Original Code" means Source Code of computer software code which is described in the Source Code notice required by Exhibit A as Original Code, and which, at the time of its release under this License is not already Covered Code governed by this License. 1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor. 1.11. "Source Code" means the preferred form of the Covered Code for making modifications to it, including all modules it contains, plus any associated interface definition files, scripts used to control compilation and installation of an Executable, or source code differential comparisons against either the Original Code or another well known, available Covered Code of the Contributor's choice. The Source Code can be in a compressed or archival form, provided the appropriate decompression or de-archiving software is widely available for no charge. 1.12. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License or a future version of this License issued under Section 6.1. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. Source Code License. 2.1. The Initial Developer Grant. The Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims: (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer to use, reproduce, modify, display, perform, sublicense and distribute the Original Code (or portions thereof) with or without Modifications, and/or as part of a Larger Work; and (b) under Patents Claims infringed by the making, using or selling of Original Code, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Code (or portions thereof). (c) the licenses granted in this Section 2.1(a) and (b) are effective on the date Initial Developer first distributes Original Code under the terms of this License. (d) Notwithstanding Section 2.1(b) above, no patent license is granted: 1) for code that You delete from the Original Code; 2) separate from the Original Code; or 3) for infringements caused by: i) the modification of the Original Code or ii) the combination of the Original Code with other software or devices. 2.2. Contributor Grant. Subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor, to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof) either on an unmodified basis, with other Modifications, as Covered Code and/or as part of a Larger Work; and (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: 1) Modifications made by that Contributor (or portions thereof); and 2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination). (c) the licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first makes Commercial Use of the Covered Code. (d) Notwithstanding Section 2.2(b) above, no patent license is granted: 1) for any code that Contributor has deleted from the Contributor Version; 2) separate from the Contributor Version; 3) for infringements caused by: i) third party modifications of Contributor Version or ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or 4) under Patent Claims infringed by Covered Code in the absence of Modifications made by that Contributor. 3. Distribution Obligations. 3.1. Application of License. The Modifications which You create or to which You contribute are governed by the terms of this License, including without limitation Section 2.2. The Source Code version of Covered Code may be distributed only under the terms of this License or a future version of this License released under Section 6.1, and You must include a copy of this License with every copy of the Source Code You distribute. You may not offer or impose any terms on any Source Code version that alters or restricts the applicable version of this License or the recipients' rights hereunder. However, You may include an additional document offering the additional rights described in Section 3.5. 3.2. Availability of Source Code. Any Modification which You create or to which You contribute must be made available in Source Code form under the terms of this License either on the same media as an Executable version or via an accepted Electronic Distribution Mechanism to anyone to whom you made an Executable version available; and if made available via Electronic Distribution Mechanism, must remain available for at least twelve (12) months after the date it initially became available, or at least six (6) months after a subsequent version of that particular Modification has been made available to such recipients. You are responsible for ensuring that the Source Code version remains available even if the Electronic Distribution Mechanism is maintained by a third party. 3.3. Description of Modifications. You must cause all Covered Code to which You contribute to contain a file documenting the changes You made to create that Covered Code and the date of any change. You must include a prominent statement that the Modification is derived, directly or indirectly, from Original Code provided by the Initial Developer and including the name of the Initial Developer in (a) the Source Code, and (b) in any notice in an Executable version or related documentation in which You describe the origin or ownership of the Covered Code. 3.4. Intellectual Property Matters (a) Third Party Claims. If Contributor has knowledge that a license under a third party's intellectual property rights is required to exercise the rights granted by such Contributor under Sections 2.1 or 2.2, Contributor must include a text file with the Source Code distribution titled "LEGAL" which describes the claim and the party making the claim in sufficient detail that a recipient will know whom to contact. If Contributor obtains such knowledge after the Modification is made available as described in Section 3.2, Contributor shall promptly modify the LEGAL file in all copies Contributor makes available thereafter and shall take other steps (such as notifying appropriate mailing lists or newsgroups) reasonably calculated to inform those who received the Covered Code that new knowledge has been obtained. (b) Contributor APIs. If Contributor's Modifications include an application programming interface and Contributor has knowledge of patent licenses which are reasonably necessary to implement that API, Contributor must also include this information in the LEGAL file. (c) Representations. Contributor represents that, except as disclosed pursuant to Section 3.4(a) above, Contributor believes that Contributor's Modifications are Contributor's original creation(s) and/or Contributor has sufficient rights to grant the rights conveyed by this License. 3.5. Required Notices. You must duplicate the notice in Exhibit A in each file of the Source Code. If it is not possible to put such notice in a particular Source Code file due to its structure, then You must include such notice in a location (such as a relevant directory) where a user would be likely to look for such a notice. If You created one or more Modification(s) You may add your name as a Contributor to the notice described in Exhibit A. You must also duplicate this License in any documentation for the Source Code where You describe recipients' rights or ownership rights relating to Covered Code. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear than any such warranty, support, indemnity or liability obligation is offered by You alone, and You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of warranty, support, indemnity or liability terms You offer. 3.6. Distribution of Executable Versions. You may distribute Covered Code in Executable form only if the requirements of Section 3.1-3.5 have been met for that Covered Code, and if You include a notice stating that the Source Code version of the Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You may distribute the Executable version of Covered Code or ownership rights under a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable version does not attempt to limit or alter the recipient's rights in the Source Code version from the rights set forth in this License. If You distribute the Executable version under a different license You must make it absolutely clear that any terms which differ from this License are offered by You alone, not by the Initial Developer or any Contributor. You hereby agree to indemnify the Initial Developer and every Contributor for any liability incurred by the Initial Developer or such Contributor as a result of any such terms You offer. 3.7. Larger Works. You may create a Larger Work by combining Covered Code with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Code. 4. Inability to Comply Due to Statute or Regulation. If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Code due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) describe the limitations and the code they affect. Such description must be included in the LEGAL file described in Section 3.4 and must be included with all distributions of the Source Code. Except to the extent prohibited by statute or regulation, such description must be sufficiently detailed for a recipient of ordinary skill to be able to understand it. 5. Application of this License. This License applies to code to which the Initial Developer has attached the notice in Exhibit A and to related Covered Code. 6. Versions of the License. 6.1. New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number. 6.2. Effect of New Versions. Once Covered Code has been published under a particular version of the License, You may always continue to use it under the terms of that version. You may also choose to use such Covered Code under the terms of any subsequent version of the License published by Netscape. No one other than Netscape has the right to modify the terms applicable to Covered Code created under this License. 6.3. Derivative Works. If You create or use a modified version of this License (which you may only do in order to apply it to code which is not already Covered Code governed by this License), You must (a) rename Your license so that the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar phrase do not appear in your license (except to note that your license differs from this License) and (b) otherwise make it clear that Your version of the license contains terms which differ from the Mozilla Public License and Netscape Public License. (Filling in the name of the Initial Developer, Original Code or Contributor in the notice described in Exhibit A shall not of themselves be deemed to be modifications of this License.) 7. DISCLAIMER OF WARRANTY. COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. 8. TERMINATION. 8.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. All sublicenses to the Covered Code which are properly granted shall survive any termination of this License. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive. 8.2. If You initiate litigation by asserting a patent infringement claim (excluding declatory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You file such action is referred to as "Participant") alleging that: (a) such Participant's Contributor Version directly or indirectly infringes any patent, then any and all rights granted by such Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant terminate prospectively, unless if within 60 days after receipt of notice You either: (i) agree in writing to pay Participant a mutually agreeable reasonable royalty for Your past and future use of Modifications made by such Participant, or (ii) withdraw Your litigation claim with respect to the Contributor Version against such Participant. If within 60 days of notice, a reasonable royalty and payment arrangement are not mutually agreed upon in writing by the parties or the litigation claim is not withdrawn, the rights granted by Participant to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of the 60 day notice period specified above. (b) any software, hardware, or device, other than such Participant's Contributor Version, directly or indirectly infringes any patent, then any rights granted to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, sold, distributed, or had made, Modifications made by that Participant. 8.3. If You assert a patent infringement claim against Participant alleging that such Participant's Contributor Version directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license. 8.4. In the event of termination under Sections 8.1 or 8.2 above, all end user license agreements (excluding distributors and resellers) which have been validly granted by You or any distributor hereunder prior to termination shall survive termination. 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. 10. U.S. GOVERNMENT END USERS. The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code with only those rights set forth herein. 11. MISCELLANEOUS. This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by California law provisions (except to the extent applicable law, if any, provides otherwise), excluding its conflict-of-law provisions. With respect to disputes in which at least one party is a citizen of, or an entity chartered or registered to do business in the United States of America, any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs and reasonable attorneys' fees and expenses. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any law or regulation which provides that the language of a contract shall be construed against the drafter shall not apply to this License. 12. RESPONSIBILITY FOR CLAIMS. As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability. 13. MULTIPLE-LICENSED CODE. Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". "Multiple-Licensed" means that the Initial Developer permits you to utilize portions of the Covered Code under Your choice of the NPL or the alternative licenses, if any, specified by the Initial Developer in the file described in Exhibit A. EXHIBIT A -Mozilla Public License. ``The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is ______________________________________. The Initial Developer of the Original Code is ________________________. Portions created by ______________________ are Copyright (C) ______ _______________________. All Rights Reserved. Contributor(s): ______________________________________. Alternatively, the contents of this file may be used under the terms of the _____ license (the "[___] License"), in which case the provisions of [______] License are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the [____] License and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the [___] License. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the [___] License." [NOTE: The text of this Exhibit A may differ slightly from the text of the notices in the Source Code files of the Original Code. You should use the text of this Exhibit A rather than the text found in the Original Code Source Code for Your Modifications.] src/core/com/lowagie/text/MarkedObject.java100644 0 0 11217 11012562273 16333 0ustar 0 0 /* * $Id: MarkedObject.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Properties; /** * Wrapper that allows to add properties to 'basic building block' objects. * Before iText 1.5 every 'basic building block' implemented the MarkupAttributes interface. * By setting attributes, you could add markup to the corresponding XML and/or HTML tag. * This functionality was hardly used by anyone, so it was removed, and replaced by * the MarkedObject functionality. */ public class MarkedObject implements Element { /** The element that is wrapped in a MarkedObject. */ protected Element element; /** Contains extra markupAttributes */ protected Properties markupAttributes = new Properties(); /** * This constructor is for internal use only. */ protected MarkedObject() { element = null; } /** * Creates a MarkedObject. */ public MarkedObject(Element element) { this.element = element; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return element.getChunks(); } /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(element); } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return MARKED; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } /** * Getter for the markup attributes. * @return the markupAttributes */ public Properties getMarkupAttributes() { return markupAttributes; } /** * Adds one markup attribute. */ public void setMarkupAttribute(String key, String value) { markupAttributes.setProperty(key, value); } }src/core/com/lowagie/text/MarkedSection.java100644 0 0 23220 11012562273 16526 0ustar 0 0 /* * $Id: MarkedSection.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.Collection; import java.util.Iterator; /** * Wrapper that allows to add properties to a Chapter/Section object. * Before iText 1.5 every 'basic building block' implemented the MarkupAttributes interface. * By setting attributes, you could add markup to the corresponding XML and/or HTML tag. * This functionality was hardly used by anyone, so it was removed, and replaced by * the MarkedObject functionality. */ public class MarkedSection extends MarkedObject { /** This is the title of this section. */ protected MarkedObject title = null; /** * Creates a MarkedObject with a Section or Chapter object. * @param section the marked section */ public MarkedSection(Section section) { super(); if (section.title != null) { title = new MarkedObject(section.title); section.setTitle(null); } this.element = section; } /** * Adds a Paragraph, List or Table * to this Section. * * @param index index at which the specified element is to be inserted * @param o an object of type Paragraph, List or Table= * @throws ClassCastException if the object is not a Paragraph, List or Table */ public void add(int index, Object o) { ((Section)element).add(index, o); } /** * Adds a Paragraph, List, Table or another Section * to this Section. * * @param o an object of type Paragraph, List, Table or another Section * @return a boolean * @throws ClassCastException if the object is not a Paragraph, List, Table or Section */ public boolean add(Object o) { return ((Section)element).add(o); } /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { Element element; for (Iterator i = ((Section)this.element).iterator(); i.hasNext(); ) { element = (Element)i.next(); listener.add(element); } return true; } catch(DocumentException de) { return false; } } /** * Adds a collection of Elements * to this Section. * * @param collection a collection of Paragraphs, Lists and/or Tables * @return true if the action succeeded, false if not. * @throws ClassCastException if one of the objects isn't a Paragraph, List, Table */ public boolean addAll(Collection collection) { return ((Section)element).addAll(collection); } /** * Creates a Section, adds it to this Section and returns it. * * @param indentation the indentation of the new section * @param numberDepth the numberDepth of the section * @return a new Section object */ public MarkedSection addSection(float indentation, int numberDepth) { MarkedSection section = ((Section)element).addMarkedSection(); section.setIndentation(indentation); section.setNumberDepth(numberDepth); return section; } /** * Creates a Section, adds it to this Section and returns it. * * @param indentation the indentation of the new section * @return a new Section object */ public MarkedSection addSection(float indentation) { MarkedSection section = ((Section)element).addMarkedSection(); section.setIndentation(indentation); return section; } /** * Creates a Section, add it to this Section and returns it. * * @param numberDepth the numberDepth of the section * @return a new Section object */ public MarkedSection addSection(int numberDepth) { MarkedSection section = ((Section)element).addMarkedSection(); section.setNumberDepth(numberDepth); return section; } /** * Creates a Section, adds it to this Section and returns it. * * @return a new Section object */ public MarkedSection addSection() { return ((Section)element).addMarkedSection(); } // public methods /** * Sets the title of this section. * * @param title the new title */ public void setTitle(MarkedObject title) { if (title.element instanceof Paragraph) this.title = title; } /** * Gets the title of this MarkedSection. * @return a MarkObject with a Paragraph containing the title of a Section * @since iText 2.0.8 */ public MarkedObject getTitle() { Paragraph result = Section.constructTitle((Paragraph)title.element, ((Section)element).numbers, ((Section)element).numberDepth, ((Section)element).numberStyle); MarkedObject mo = new MarkedObject(result); mo.markupAttributes = title.markupAttributes; return mo; } /** * Sets the depth of the sectionnumbers that will be shown preceding the title. *

* If the numberdepth is 0, the sections will not be numbered. If the numberdepth * is 1, the section will be numbered with their own number. If the numberdepth is * higher (for instance x > 1), the numbers of x - 1 parents will be shown. * * @param numberDepth the new numberDepth */ public void setNumberDepth(int numberDepth) { ((Section)element).setNumberDepth(numberDepth); } /** * Sets the indentation of this Section on the left side. * * @param indentation the indentation */ public void setIndentationLeft(float indentation) { ((Section)element).setIndentationLeft(indentation); } /** * Sets the indentation of this Section on the right side. * * @param indentation the indentation */ public void setIndentationRight(float indentation) { ((Section)element).setIndentationRight(indentation); } /** * Sets the indentation of the content of this Section. * * @param indentation the indentation */ public void setIndentation(float indentation) { ((Section)element).setIndentation(indentation); } /** Setter for property bookmarkOpen. * @param bookmarkOpen false if the bookmark children are not * visible. */ public void setBookmarkOpen(boolean bookmarkOpen) { ((Section)element).setBookmarkOpen(bookmarkOpen); } /** * Setter for property triggerNewPage. * @param triggerNewPage true if a new page has to be triggered. */ public void setTriggerNewPage(boolean triggerNewPage) { ((Section)element).setTriggerNewPage(triggerNewPage); } /** * Sets the bookmark title. The bookmark title is the same as the section title but * can be changed with this method. * @param bookmarkTitle the bookmark title */ public void setBookmarkTitle(String bookmarkTitle) { ((Section)element).setBookmarkTitle(bookmarkTitle); } /** * Adds a new page to the section. * @since 2.1.1 */ public void newPage() { ((Section)element).newPage(); } } src/core/com/lowagie/text/Meta.java100644 0 0 15573 11012562273 14700 0ustar 0 0 /* * $Id: Meta.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; /** * This is an Element that contains * some meta information about the document. *

* An object of type Meta can not be constructed by the user. * User defined meta information should be placed in a Header-object. * Meta is reserved for: Subject, Keywords, Author, Title, Producer * and Creationdate information. * * @see Element * @see Header */ public class Meta implements Element { // membervariables /** This is the type of Meta-information this object contains. */ private int type; /** This is the content of the Meta-information. */ private StringBuffer content; // constructors /** * Constructs a Meta. * * @param type the type of meta-information * @param content the content */ Meta(int type, String content) { this.type = type; this.content = new StringBuffer(content); } /** * Constructs a Meta. * * @param tag the tagname of the meta-information * @param content the content */ public Meta(String tag, String content) { this.type = Meta.getType(tag); this.content = new StringBuffer(content); } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to a * ElementListener. * * @param listener the ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return type; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return false; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } // methods /** * appends some text to this Meta. * * @param string a String * @return a StringBuffer */ public StringBuffer append(String string) { return content.append(string); } // methods to retrieve information /** * Returns the content of the meta information. * * @return a String */ public String getContent() { return content.toString(); } /** * Returns the name of the meta information. * * @return a String */ public String getName() { switch (type) { case Element.SUBJECT: return ElementTags.SUBJECT; case Element.KEYWORDS: return ElementTags.KEYWORDS; case Element.AUTHOR: return ElementTags.AUTHOR; case Element.TITLE: return ElementTags.TITLE; case Element.PRODUCER: return ElementTags.PRODUCER; case Element.CREATIONDATE: return ElementTags.CREATIONDATE; default: return ElementTags.UNKNOWN; } } /** * Returns the name of the meta information. * * @param tag iText tag for meta information * @return the Element value corresponding with the given tag */ public static int getType(String tag) { if (ElementTags.SUBJECT.equals(tag)) { return Element.SUBJECT; } if (ElementTags.KEYWORDS.equals(tag)) { return Element.KEYWORDS; } if (ElementTags.AUTHOR.equals(tag)) { return Element.AUTHOR; } if (ElementTags.TITLE.equals(tag)) { return Element.TITLE; } if (ElementTags.PRODUCER.equals(tag)) { return Element.PRODUCER; } if (ElementTags.CREATIONDATE.equals(tag)) { return Element.CREATIONDATE; } return Element.HEADER; } }src/core/com/lowagie/text/PageSize.java100644 0 0 23510 11012562273 15507 0ustar 0 0 /* * $Id: PageSize.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.lang.reflect.Field; /** * The PageSize-object contains a number of rectangles representing the most common paper sizes. * * @see Rectangle */ public class PageSize { // membervariables /** This is the letter format */ public static final Rectangle LETTER = new RectangleReadOnly(612,792); /** This is the note format */ public static final Rectangle NOTE = new RectangleReadOnly(540,720); /** This is the legal format */ public static final Rectangle LEGAL = new RectangleReadOnly(612,1008); /** This is the tabloid format */ public static final Rectangle TABLOID = new RectangleReadOnly(792,1224); /** This is the executive format */ public static final Rectangle EXECUTIVE = new RectangleReadOnly(522,756); /** This is the postcard format */ public static final Rectangle POSTCARD = new RectangleReadOnly(283,416); /** This is the a0 format */ public static final Rectangle A0 = new RectangleReadOnly(2384,3370); /** This is the a1 format */ public static final Rectangle A1 = new RectangleReadOnly(1684,2384); /** This is the a2 format */ public static final Rectangle A2 = new RectangleReadOnly(1191,1684); /** This is the a3 format */ public static final Rectangle A3 = new RectangleReadOnly(842,1191); /** This is the a4 format */ public static final Rectangle A4 = new RectangleReadOnly(595,842); /** This is the a5 format */ public static final Rectangle A5 = new RectangleReadOnly(420,595); /** This is the a6 format */ public static final Rectangle A6 = new RectangleReadOnly(297,420); /** This is the a7 format */ public static final Rectangle A7 = new RectangleReadOnly(210,297); /** This is the a8 format */ public static final Rectangle A8 = new RectangleReadOnly(148,210); /** This is the a9 format */ public static final Rectangle A9 = new RectangleReadOnly(105,148); /** This is the a10 format */ public static final Rectangle A10 = new RectangleReadOnly(73,105); /** This is the b0 format */ public static final Rectangle B0 = new RectangleReadOnly(2834,4008); /** This is the b1 format */ public static final Rectangle B1 = new RectangleReadOnly(2004,2834); /** This is the b2 format */ public static final Rectangle B2 = new RectangleReadOnly(1417,2004); /** This is the b3 format */ public static final Rectangle B3 = new RectangleReadOnly(1000,1417); /** This is the b4 format */ public static final Rectangle B4 = new RectangleReadOnly(708,1000); /** This is the b5 format */ public static final Rectangle B5 = new RectangleReadOnly(498,708); /** This is the b6 format */ public static final Rectangle B6 = new RectangleReadOnly(354,498); /** This is the b7 format */ public static final Rectangle B7 = new RectangleReadOnly(249,354); /** This is the b8 format */ public static final Rectangle B8 = new RectangleReadOnly(175,249); /** This is the b9 format */ public static final Rectangle B9 = new RectangleReadOnly(124,175); /** This is the b10 format */ public static final Rectangle B10 = new RectangleReadOnly(87,124); /** This is the archE format */ public static final Rectangle ARCH_E = new RectangleReadOnly(2592,3456); /** This is the archD format */ public static final Rectangle ARCH_D = new RectangleReadOnly(1728,2592); /** This is the archC format */ public static final Rectangle ARCH_C = new RectangleReadOnly(1296,1728); /** This is the archB format */ public static final Rectangle ARCH_B = new RectangleReadOnly(864,1296); /** This is the archA format */ public static final Rectangle ARCH_A = new RectangleReadOnly(648,864); /** This is the American Foolscap format */ public static final Rectangle FLSA = new RectangleReadOnly(612,936); /** This is the European Foolscap format */ public static final Rectangle FLSE = new RectangleReadOnly(648,936); /** This is the halfletter format */ public static final Rectangle HALFLETTER = new RectangleReadOnly(396,612); /** This is the 11x17 format */ public static final Rectangle _11X17 = new RectangleReadOnly(792,1224); /** This is the ISO 7810 ID-1 format (85.60 x 53.98 mm or 3.370 x 2.125 inch) */ public static final Rectangle ID_1 = new RectangleReadOnly(242.65f,153); /** This is the ISO 7810 ID-2 format (A7 rotated) */ public static final Rectangle ID_2 = new RectangleReadOnly(297,210); /** This is the ISO 7810 ID-3 format (B7 rotated) */ public static final Rectangle ID_3 = new RectangleReadOnly(354,249); /** This is the ledger format */ public static final Rectangle LEDGER = new RectangleReadOnly(1224,792); /** This is the Crown Quarto format */ public static final Rectangle CROWN_QUARTO = new RectangleReadOnly(535,697); /** This is the Large Crown Quarto format */ public static final Rectangle LARGE_CROWN_QUARTO = new RectangleReadOnly(569,731); /** This is the Demy Quarto format. */ public static final Rectangle DEMY_QUARTO = new RectangleReadOnly(620,782); /** This is the Royal Quarto format. */ public static final Rectangle ROYAL_QUARTO = new RectangleReadOnly(671,884); /** This is the Crown Octavo format */ public static final Rectangle CROWN_OCTAVO = new RectangleReadOnly(348,527); /** This is the Large Crown Octavo format */ public static final Rectangle LARGE_CROWN_OCTAVO = new RectangleReadOnly(365,561); /** This is the Demy Octavo format */ public static final Rectangle DEMY_OCTAVO = new RectangleReadOnly(391,612); /** This is the Royal Octavo format. */ public static final Rectangle ROYAL_OCTAVO = new RectangleReadOnly(442,663); /** This is the small paperback format. */ public static final Rectangle SMALL_PAPERBACK = new RectangleReadOnly(314,504); /** This is the Pengiun small paperback format. */ public static final Rectangle PENGUIN_SMALL_PAPERBACK = new RectangleReadOnly(314,513); /** This is the Penguin large paperback format. */ public static final Rectangle PENGUIN_LARGE_PAPERBACK = new RectangleReadOnly(365,561); /** * This method returns a Rectangle based on a String. * Possible values are the the names of a constant in this class * (for instance "A4", "LETTER",...) or a value like "595 842" */ public static Rectangle getRectangle(String name) { name = name.trim().toUpperCase(); int pos = name.indexOf(' '); if (pos == -1) { try { Field field = PageSize.class.getDeclaredField(name.toUpperCase()); return (Rectangle) field.get(null); } catch (Exception e) { throw new RuntimeException("Can't find page size " + name); } } else { try { String width = name.substring(0, pos); String height = name.substring(pos + 1); return new Rectangle(Float.parseFloat(width), Float.parseFloat(height)); } catch(Exception e) { throw new RuntimeException(name + " is not a valid page size format; " + e.getMessage()); } } } }src/core/com/lowagie/text/Paragraph.java100644 0 0 35351 11154165267 15724 0ustar 0 0 /* * $Id: Paragraph.java 3668 2009-02-01 09:08:50Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * A Paragraph is a series of Chunks and/or Phrases. *

* A Paragraph has the same qualities of a Phrase, but also * some additional layout-parameters: *

    *
  • the indentation *
  • the alignment of the text *
* * Example: *
 * Paragraph p = new Paragraph("This is a paragraph",
 *               FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
 * 
* * @see Element * @see Phrase * @see ListItem */ public class Paragraph extends Phrase { // constants private static final long serialVersionUID = 7852314969733375514L; // membervariables /** The alignment of the text. */ protected int alignment = Element.ALIGN_UNDEFINED; /** The text leading that is multiplied by the biggest font size in the line. */ protected float multipliedLeading = 0; /** The indentation of this paragraph on the left side. */ protected float indentationLeft; /** The indentation of this paragraph on the right side. */ protected float indentationRight; /** Holds value of property firstLineIndent. */ private float firstLineIndent = 0; /** The spacing before the paragraph. */ protected float spacingBefore; /** The spacing after the paragraph. */ protected float spacingAfter; /** Holds value of property extraParagraphSpace. */ private float extraParagraphSpace = 0; /** Does the paragraph has to be kept together on 1 page. */ protected boolean keeptogether = false; // constructors /** * Constructs a Paragraph. */ public Paragraph() { super(); } /** * Constructs a Paragraph with a certain leading. * * @param leading the leading */ public Paragraph(float leading) { super(leading); } /** * Constructs a Paragraph with a certain Chunk. * * @param chunk a Chunk */ public Paragraph(Chunk chunk) { super(chunk); } /** * Constructs a Paragraph with a certain Chunk * and a certain leading. * * @param leading the leading * @param chunk a Chunk */ public Paragraph(float leading, Chunk chunk) { super(leading, chunk); } /** * Constructs a Paragraph with a certain String. * * @param string a String */ public Paragraph(String string) { super(string); } /** * Constructs a Paragraph with a certain String * and a certain Font. * * @param string a String * @param font a Font */ public Paragraph(String string, Font font) { super(string, font); } /** * Constructs a Paragraph with a certain String * and a certain leading. * * @param leading the leading * @param string a String */ public Paragraph(float leading, String string) { super(leading, string); } /** * Constructs a Paragraph with a certain leading, String * and Font. * * @param leading the leading * @param string a String * @param font a Font */ public Paragraph(float leading, String string, Font font) { super(leading, string, font); } /** * Constructs a Paragraph with a certain Phrase. * * @param phrase a Phrase */ public Paragraph(Phrase phrase) { super(phrase); if (phrase instanceof Paragraph) { Paragraph p = (Paragraph)phrase; setAlignment(p.alignment); setLeading(phrase.getLeading(), p.multipliedLeading); setIndentationLeft(p.getIndentationLeft()); setIndentationRight(p.getIndentationRight()); setFirstLineIndent(p.getFirstLineIndent()); setSpacingAfter(p.spacingAfter()); setSpacingBefore(p.spacingBefore()); setExtraParagraphSpace(p.getExtraParagraphSpace()); } } // implementation of the Element-methods /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.PARAGRAPH; } // methods /** * Adds an Object to the Paragraph. * * @param o object the object to add. * @return true is adding the object succeeded */ public boolean add(Object o) { if (o instanceof List) { List list = (List) o; list.setIndentationLeft(list.getIndentationLeft() + indentationLeft); list.setIndentationRight(indentationRight); return super.add(list); } else if (o instanceof Image) { super.addSpecial(o); return true; } else if (o instanceof Paragraph) { super.add(o); java.util.List chunks = getChunks(); if (!chunks.isEmpty()) { Chunk tmp = ((Chunk) chunks.get(chunks.size() - 1)); super.add(new Chunk("\n", tmp.getFont())); } else { super.add(Chunk.NEWLINE); } return true; } return super.add(o); } // setting the membervariables /** * Sets the alignment of this paragraph. * * @param alignment the new alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * Sets the alignment of this paragraph. * * @param alignment the new alignment as a String */ public void setAlignment(String alignment) { if (ElementTags.ALIGN_CENTER.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_CENTER; return; } if (ElementTags.ALIGN_RIGHT.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_RIGHT; return; } if (ElementTags.ALIGN_JUSTIFIED.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_JUSTIFIED; return; } if (ElementTags.ALIGN_JUSTIFIED_ALL.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_JUSTIFIED_ALL; return; } this.alignment = Element.ALIGN_LEFT; } /** * @see com.lowagie.text.Phrase#setLeading(float) */ public void setLeading(float fixedLeading) { this.leading = fixedLeading; this.multipliedLeading = 0; } /** * Sets the variable leading. The resultant leading will be * multipliedLeading*maxFontSize where maxFontSize is the * size of the biggest font in the line. * @param multipliedLeading the variable leading */ public void setMultipliedLeading(float multipliedLeading) { this.leading = 0; this.multipliedLeading = multipliedLeading; } /** * Sets the leading fixed and variable. The resultant leading will be * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the * size of the biggest font in the line. * @param fixedLeading the fixed leading * @param multipliedLeading the variable leading */ public void setLeading(float fixedLeading, float multipliedLeading) { this.leading = fixedLeading; this.multipliedLeading = multipliedLeading; } /** * Sets the indentation of this paragraph on the left side. * * @param indentation the new indentation */ public void setIndentationLeft(float indentation) { this.indentationLeft = indentation; } /** * Sets the indentation of this paragraph on the right side. * * @param indentation the new indentation */ public void setIndentationRight(float indentation) { this.indentationRight = indentation; } /** * Setter for property firstLineIndent. * @param firstLineIndent New value of property firstLineIndent. */ public void setFirstLineIndent(float firstLineIndent) { this.firstLineIndent = firstLineIndent; } /** * Sets the spacing before this paragraph. * * @param spacing the new spacing */ public void setSpacingBefore(float spacing) { this.spacingBefore = spacing; } /** * Sets the spacing after this paragraph. * * @param spacing the new spacing */ public void setSpacingAfter(float spacing) { this.spacingAfter = spacing; } /** * Indicates that the paragraph has to be kept together on one page. * * @param keeptogether true of the paragraph may not be split over 2 pages */ public void setKeepTogether(boolean keeptogether) { this.keeptogether = keeptogether; } /** * Checks if this paragraph has to be kept together on one page. * * @return true if the paragraph may not be split over 2 pages. */ public boolean getKeepTogether() { return keeptogether; } // methods to retrieve information /** * Gets the alignment of this paragraph. * * @return alignment */ public int getAlignment() { return alignment; } /** * Gets the variable leading * @return the leading */ public float getMultipliedLeading() { return multipliedLeading; } /** * Gets the total leading. * This method is based on the assumption that the * font of the Paragraph is the font of all the elements * that make part of the paragraph. This isn't necessarily * true. * @return the total leading (fixed and multiplied) */ public float getTotalLeading() { float m = font == null ? Font.DEFAULTSIZE * multipliedLeading : font.getCalculatedLeading(multipliedLeading); if (m > 0 && !hasLeading()) { return m; } return getLeading() + m; } /** * Gets the indentation of this paragraph on the left side. * * @return the indentation */ public float getIndentationLeft() { return indentationLeft; } /** * Gets the indentation of this paragraph on the right side. * * @return the indentation */ public float getIndentationRight() { return indentationRight; } /** * Getter for property firstLineIndent. * @return Value of property firstLineIndent. */ public float getFirstLineIndent() { return this.firstLineIndent; } /** * Gets the spacing before this paragraph. * @return the spacing * @since 2.1.5 */ public float getSpacingBefore() { return spacingBefore; } /** * Gets the spacing after this paragraph. * @return the spacing * @since 2.1.5 */ public float getSpacingAfter() { return spacingAfter; } /** * Getter for property extraParagraphSpace. * @return Value of property extraParagraphSpace. */ public float getExtraParagraphSpace() { return this.extraParagraphSpace; } /** * Setter for property extraParagraphSpace. * @param extraParagraphSpace New value of property extraParagraphSpace. */ public void setExtraParagraphSpace(float extraParagraphSpace) { this.extraParagraphSpace = extraParagraphSpace; } // scheduled for removal /** * Gets the spacing before this paragraph. * * @return the spacing * @deprecated As of iText 2.1.5, replaced by {@link #getSpacingBefore()}, * scheduled for removal at 2.3.0 */ public float spacingBefore() { return getSpacingBefore(); } /** * Gets the spacing after this paragraph. * * @return the spacing * @deprecated As of iText 2.1.5, replaced by {@link #getSpacingAfter()}, * scheduled for removal at 2.3.0 */ public float spacingAfter() { return spacingAfter; } } src/core/com/lowagie/text/Phrase.java100644 0 0 47046 11213370070 15227 0ustar 0 0 /* * $Id: Phrase.java 3942 2009-05-28 18:14:10Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.lowagie.text.pdf.HyphenationEvent; /** * A Phrase is a series of Chunks. *

* A Phrase has a main Font, but some chunks * within the phrase can have a Font that differs from the * main Font. All the Chunks in a Phrase * have the same leading. *

* Example: *

 * // When no parameters are passed, the default leading = 16
 * Phrase phrase0 = new Phrase();
 * Phrase phrase1 = new Phrase("this is a phrase");
 * // In this example the leading is passed as a parameter
 * Phrase phrase2 = new Phrase(16, "this is a phrase with leading 16");
 * // When a Font is passed (explicitly or embedded in a chunk), the default leading = 1.5 * size of the font
 * Phrase phrase3 = new Phrase("this is a phrase with a red, normal font Courier, size 12", FontFactory.getFont(FontFactory.COURIER, 12, Font.NORMAL, new Color(255, 0, 0)));
 * Phrase phrase4 = new Phrase(new Chunk("this is a phrase"));
 * Phrase phrase5 = new Phrase(18, new Chunk("this is a phrase", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
 * 
* * @see Element * @see Chunk * @see Paragraph * @see Anchor */ public class Phrase extends ArrayList implements TextElementArray { // constants private static final long serialVersionUID = 2643594602455068231L; // membervariables /** This is the leading of this phrase. */ protected float leading = Float.NaN; /** This is the font of this phrase. */ protected Font font; /** Null, unless the Phrase has to be hyphenated. * @since 2.1.2 */ protected HyphenationEvent hyphenation = null; // constructors /** * Constructs a Phrase without specifying a leading. */ public Phrase() { this(16); } /** * Copy constructor for Phrase. */ public Phrase(Phrase phrase) { super(); this.addAll(phrase); leading = phrase.getLeading(); font = phrase.getFont(); setHyphenation(phrase.getHyphenation()); } /** * Constructs a Phrase with a certain leading. * * @param leading the leading */ public Phrase(float leading) { this.leading = leading; font = new Font(); } /** * Constructs a Phrase with a certain Chunk. * * @param chunk a Chunk */ public Phrase(Chunk chunk) { super.add(chunk); font = chunk.getFont(); setHyphenation(chunk.getHyphenation()); } /** * Constructs a Phrase with a certain Chunk * and a certain leading. * * @param leading the leading * @param chunk a Chunk */ public Phrase(float leading, Chunk chunk) { this.leading = leading; super.add(chunk); font = chunk.getFont(); setHyphenation(chunk.getHyphenation()); } /** * Constructs a Phrase with a certain String. * * @param string a String */ public Phrase(String string) { this(Float.NaN, string, new Font()); } /** * Constructs a Phrase with a certain String and a certain Font. * * @param string a String * @param font a Font */ public Phrase(String string, Font font) { this(Float.NaN, string, font); } /** * Constructs a Phrase with a certain leading and a certain String. * * @param leading the leading * @param string a String */ public Phrase(float leading, String string) { this(leading, string, new Font()); } /** * Constructs a Phrase with a certain leading, a certain String * and a certain Font. * * @param leading the leading * @param string a String * @param font a Font */ public Phrase(float leading, String string, Font font) { this.leading = leading; this.font = font; /* bugfix by August Detlefsen */ if (string != null && string.length() != 0) { super.add(new Chunk(string, font)); } } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { for (Iterator i = iterator(); i.hasNext(); ) { listener.add((Element) i.next()); } return true; } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.PHRASE; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); for (Iterator i = iterator(); i.hasNext(); ) { tmp.addAll(((Element) i.next()).getChunks()); } return tmp; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } // overriding some of the ArrayList-methods /** * Adds a Chunk, an Anchor or another Phrase * to this Phrase. * * @param index index at which the specified element is to be inserted * @param o an object of type Chunk, Anchor or Phrase * @throws ClassCastException when you try to add something that isn't a Chunk, Anchor or Phrase */ public void add(int index, Object o) { if (o == null) return; try { Element element = (Element) o; if (element.type() == Element.CHUNK) { Chunk chunk = (Chunk) element; if (!font.isStandardFont()) { chunk.setFont(font.difference(chunk.getFont())); } if (hyphenation != null && chunk.getHyphenation() == null && !chunk.isEmpty()) { chunk.setHyphenation(hyphenation); } super.add(index, chunk); } else if (element.type() == Element.PHRASE || element.type() == Element.ANCHOR || element.type() == Element.ANNOTATION || element.type() == Element.TABLE || // line added by David Freels element.type() == Element.YMARK || element.type() == Element.MARKED) { super.add(index, element); } else { throw new ClassCastException(String.valueOf(element.type())); } } catch(ClassCastException cce) { throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage()); } } /** * Adds a Chunk, Anchor or another Phrase * to this Phrase. * * @param o an object of type Chunk, Anchor or Phrase * @return a boolean * @throws ClassCastException when you try to add something that isn't a Chunk, Anchor or Phrase */ public boolean add(Object o) { if (o == null) return false; if (o instanceof String) { return super.add(new Chunk((String) o, font)); } if (o instanceof RtfElementInterface) { return super.add(o); } try { Element element = (Element) o; switch(element.type()) { case Element.CHUNK: return addChunk((Chunk) o); case Element.PHRASE: case Element.PARAGRAPH: Phrase phrase = (Phrase) o; boolean success = true; Element e; for (Iterator i = phrase.iterator(); i.hasNext(); ) { e = (Element) i.next(); if (e instanceof Chunk) { success &= addChunk((Chunk)e); } else { success &= this.add(e); } } return success; case Element.MARKED: case Element.ANCHOR: case Element.ANNOTATION: case Element.TABLE: // case added by David Freels case Element.PTABLE: // case added by mr. Karen Vardanyan // This will only work for PDF!!! Not for RTF/HTML case Element.LIST: case Element.YMARK: return super.add(o); default: throw new ClassCastException(String.valueOf(element.type())); } } catch(ClassCastException cce) { throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage()); } } /** * Adds a collection of Chunks * to this Phrase. * * @param collection a collection of Chunks, Anchors and Phrases. * @return true if the action succeeded, false if not. * @throws ClassCastException when you try to add something that isn't a Chunk, Anchor or Phrase */ public boolean addAll(Collection collection) { for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) { this.add(iterator.next()); } return true; } /** * Adds a Chunk. *

* This method is a hack to solve a problem I had with phrases that were split between chunks * in the wrong place. * @param chunk a Chunk to add to the Phrase * @return true if adding the Chunk succeeded */ protected boolean addChunk(Chunk chunk) { Font f = chunk.getFont(); String c = chunk.getContent(); if (font != null && !font.isStandardFont()) { f = font.difference(chunk.getFont()); } if (size() > 0 && !chunk.hasAttributes()) { try { Chunk previous = (Chunk) get(size() - 1); if (!previous.hasAttributes() && (f == null || f.compareTo(previous.getFont()) == 0) && !"".equals(previous.getContent().trim()) && !"".equals(c.trim())) { previous.append(c); return true; } } catch(ClassCastException cce) { } } Chunk newChunk = new Chunk(c, f); newChunk.setAttributes(chunk.getAttributes()); if (hyphenation != null && newChunk.getHyphenation() == null && !newChunk.isEmpty()) { newChunk.setHyphenation(hyphenation); } return super.add(newChunk); } /** * Adds a Object to the Paragraph. * * @param object the object to add. */ protected void addSpecial(Object object) { super.add(object); } // other methods that change the member variables /** * Sets the leading of this phrase. * * @param leading the new leading */ public void setLeading(float leading) { this.leading = leading; } /** * Sets the main font of this phrase. * @param font the new font */ public void setFont(Font font) { this.font = font; } // methods to retrieve information /** * Gets the leading of this phrase. * * @return the linespacing */ public float getLeading() { if (Float.isNaN(leading) && font != null) { return font.getCalculatedLeading(1.5f); } return leading; } /** * Checks you if the leading of this phrase is defined. * * @return true if the leading is defined */ public boolean hasLeading() { if (Float.isNaN(leading)) { return false; } return true; } /** * Gets the font of the first Chunk that appears in this Phrase. * * @return a Font */ public Font getFont() { return font; } /** * Returns the content as a String object. * This method differs from toString because toString will return an ArrayList with the toString value of the Chunks in this Phrase. */ public String getContent() { StringBuffer buf = new StringBuffer(); for (Iterator i = getChunks().iterator(); i.hasNext(); ) { buf.append(i.next().toString()); } return buf.toString(); } /** * Checks is this Phrase contains no or 1 empty Chunk. * * @return false if the Phrase * contains more than one or more non-emptyChunks. */ public boolean isEmpty() { switch(size()) { case 0: return true; case 1: Element element = (Element) get(0); if (element.type() == Element.CHUNK && ((Chunk) element).isEmpty()) { return true; } return false; default: return false; } } /** * Getter for the hyphenation settings. * @return a HyphenationEvent * @since 2.1.2 */ public HyphenationEvent getHyphenation() { return hyphenation; } /** * Setter for the hyphenation. * @param hyphenation a HyphenationEvent instance * @since 2.1.2 */ public void setHyphenation(HyphenationEvent hyphenation) { this.hyphenation = hyphenation; } // kept for historical reasons; people should use FontSelector // eligible for deprecation, but the methods are mentioned in the book p277. /** * Constructs a Phrase that can be used in the static getInstance() method. * @param dummy a dummy parameter */ private Phrase(boolean dummy) { } /** * Gets a special kind of Phrase that changes some characters into corresponding symbols. * @param string * @return a newly constructed Phrase */ public static final Phrase getInstance(String string) { return getInstance(16, string, new Font()); } /** * Gets a special kind of Phrase that changes some characters into corresponding symbols. * @param leading * @param string * @return a newly constructed Phrase */ public static final Phrase getInstance(int leading, String string) { return getInstance(leading, string, new Font()); } /** * Gets a special kind of Phrase that changes some characters into corresponding symbols. * @param leading * @param string * @param font * @return a newly constructed Phrase */ public static final Phrase getInstance(int leading, String string, Font font) { Phrase p = new Phrase(true); p.setLeading(leading); p.font = font; if (font.getFamily() != Font.SYMBOL && font.getFamily() != Font.ZAPFDINGBATS && font.getBaseFont() == null) { int index; while((index = SpecialSymbol.index(string)) > -1) { if (index > 0) { String firstPart = string.substring(0, index); ((ArrayList)p).add(new Chunk(firstPart, font)); string = string.substring(index); } Font symbol = new Font(Font.SYMBOL, font.getSize(), font.getStyle(), font.getColor()); StringBuffer buf = new StringBuffer(); buf.append(SpecialSymbol.getCorrespondingSymbol(string.charAt(0))); string = string.substring(1); while (SpecialSymbol.index(string) == 0) { buf.append(SpecialSymbol.getCorrespondingSymbol(string.charAt(0))); string = string.substring(1); } ((ArrayList)p).add(new Chunk(buf.toString(), symbol)); } } if (string != null && string.length() != 0) { ((ArrayList)p).add(new Chunk(string, font)); } return p; } }src/core/com/lowagie/text/Rectangle.java100644 0 0 52132 11154165267 15717 0ustar 0 0 /* * $Id: Rectangle.java 3742 2009-03-03 16:42:09Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; import java.util.ArrayList; import com.lowagie.text.pdf.GrayColor; /** * A Rectangle is the representation of a geometric figure. * * Rectangles support constant width borders using * {@link #setBorderWidth(float)}and {@link #setBorder(int)}. * They also support borders that vary in width/color on each side using * methods like {@link #setBorderWidthLeft(float)}or * {@link #setBorderColorLeft(java.awt.Color)}. * * @see Element * @see Table * @see Cell * @see HeaderFooter */ public class Rectangle implements Element { // CONSTANTS: /** This is the value that will be used as undefined . */ public static final int UNDEFINED = -1; /** This represents one side of the border of the Rectangle. */ public static final int TOP = 1; /** This represents one side of the border of the Rectangle. */ public static final int BOTTOM = 2; /** This represents one side of the border of the Rectangle. */ public static final int LEFT = 4; /** This represents one side of the border of the Rectangle. */ public static final int RIGHT = 8; /** This represents a rectangle without borders. */ public static final int NO_BORDER = 0; /** This represents a type of border. */ public static final int BOX = TOP + BOTTOM + LEFT + RIGHT; // MEMBER VARIABLES: /** the lower left x-coordinate. */ protected float llx; /** the lower left y-coordinate. */ protected float lly; /** the upper right x-coordinate. */ protected float urx; /** the upper right y-coordinate. */ protected float ury; /** The rotation of the Rectangle */ protected int rotation = 0; /** This is the color of the background of this rectangle. */ protected Color backgroundColor = null; /** This represents the status of the 4 sides of the rectangle. */ protected int border = UNDEFINED; /** Whether variable width/color borders are used. */ protected boolean useVariableBorders = false; /** This is the width of the border around this rectangle. */ protected float borderWidth = UNDEFINED; /** The width of the left border of this rectangle. */ protected float borderWidthLeft = UNDEFINED; /** The width of the right border of this rectangle. */ protected float borderWidthRight = UNDEFINED; /** The width of the top border of this rectangle. */ protected float borderWidthTop = UNDEFINED; /** The width of the bottom border of this rectangle. */ protected float borderWidthBottom = UNDEFINED; /** The color of the border of this rectangle. */ protected Color borderColor = null; /** The color of the left border of this rectangle. */ protected Color borderColorLeft = null; /** The color of the right border of this rectangle. */ protected Color borderColorRight = null; /** The color of the top border of this rectangle. */ protected Color borderColorTop = null; /** The color of the bottom border of this rectangle. */ protected Color borderColorBottom = null; // CONSTRUCTORS: /** * Constructs a Rectangle -object. * * @param llx lower left x * @param lly lower left y * @param urx upper right x * @param ury upper right y */ public Rectangle(float llx, float lly, float urx, float ury) { this.llx = llx; this.lly = lly; this.urx = urx; this.ury = ury; } /** * Constructs a Rectangle -object starting from the origin * (0, 0). * * @param urx upper right x * @param ury upper right y */ public Rectangle(float urx, float ury) { this(0, 0, urx, ury); } /** * Constructs a Rectangle -object. * * @param rect another Rectangle */ public Rectangle(Rectangle rect) { this(rect.llx, rect.lly, rect.urx, rect.ury); cloneNonPositionParameters(rect); } // IMPLEMENTATION OF THE ELEMENT INTERFACE:e /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch (DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.RECTANGLE; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } // METHODS TO GET/SET THE DIMENSIONS: /** * Sets the lower left x-coordinate. * * @param llx the new value */ public void setLeft(float llx) { this.llx = llx; } /** * Returns the lower left x-coordinate. * * @return the lower left x-coordinate */ public float getLeft() { return llx; } /** * Returns the lower left x-coordinate, considering a given margin. * * @param margin a margin * @return the lower left x-coordinate */ public float getLeft(float margin) { return llx + margin; } /** * Sets the upper right x-coordinate. * * @param urx the new value */ public void setRight(float urx) { this.urx = urx; } /** * Returns the upper right x-coordinate. * * @return the upper right x-coordinate */ public float getRight() { return urx; } /** * Returns the upper right x-coordinate, considering a given margin. * * @param margin a margin * @return the upper right x-coordinate */ public float getRight(float margin) { return urx - margin; } /** * Returns the width of the rectangle. * * @return the width */ public float getWidth() { return urx - llx; } /** * Sets the upper right y-coordinate. * * @param ury the new value */ public void setTop(float ury) { this.ury = ury; } /** * Returns the upper right y-coordinate. * * @return the upper right y-coordinate */ public float getTop() { return ury; } /** * Returns the upper right y-coordinate, considering a given margin. * * @param margin a margin * @return the upper right y-coordinate */ public float getTop(float margin) { return ury - margin; } /** * Sets the lower left y-coordinate. * * @param lly the new value */ public void setBottom(float lly) { this.lly = lly; } /** * Returns the lower left y-coordinate. * * @return the lower left y-coordinate */ public float getBottom() { return lly; } /** * Returns the lower left y-coordinate, considering a given margin. * * @param margin a margin * @return the lower left y-coordinate */ public float getBottom(float margin) { return lly + margin; } /** * Returns the height of the rectangle. * * @return the height */ public float getHeight() { return ury - lly; } /** * Normalizes the rectangle. * Switches lower left with upper right if necessary. */ public void normalize() { if (llx > urx) { float a = llx; llx = urx; urx = a; } if (lly > ury) { float a = lly; lly = ury; ury = a; } } // METHODS TO GET/SET THE ROTATION: /** * Gets the rotation of the rectangle * * @return a rotation value */ public int getRotation() { return rotation; } /** * Rotates the rectangle. * Swaps the values of llx and lly and of urx and ury. * * @return the rotated Rectangle */ public Rectangle rotate() { Rectangle rect = new Rectangle(lly, llx, ury, urx); rect.rotation = rotation + 90; rect.rotation %= 360; return rect; } // METHODS TO GET/SET THE BACKGROUND COLOR: /** * Gets the backgroundcolor. * * @return a Color */ public Color getBackgroundColor() { return backgroundColor; } /** * Sets the backgroundcolor of the rectangle. * * @param backgroundColor a Color */ public void setBackgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; } /** * Gets the grayscale. * * @return the grayscale color of the background * or 0 if the background has no grayscale color. */ public float getGrayFill() { if (backgroundColor instanceof GrayColor) return ((GrayColor)backgroundColor).getGray(); return 0; } /** * Sets the the background color to a grayscale value. * * @param value the new grayscale value */ public void setGrayFill(float value) { backgroundColor = new GrayColor(value); } // METHODS TO GET/SET THE BORDER: /** * Returns the exact type of the border. * * @return a value */ public int getBorder() { return border; } /** * Indicates whether some type of border is set. * * @return a boolean */ public boolean hasBorders() { switch (border) { case UNDEFINED: case NO_BORDER: return false; default: return borderWidth > 0 || borderWidthLeft > 0 || borderWidthRight > 0 || borderWidthTop > 0 || borderWidthBottom > 0; } } /** * Indicates whether the specified type of border is set. * * @param type the type of border * @return a boolean */ public boolean hasBorder(int type) { if (border == UNDEFINED) return false; return (border & type) == type; } /** * Enables/Disables the border on the specified sides. * The border is specified as an integer bitwise combination of * the constants: LEFT, RIGHT, TOP, BOTTOM. * * @see #enableBorderSide(int) * @see #disableBorderSide(int) * @param border the new value */ public void setBorder(int border) { this.border = border; } /** * Indicates whether variable width borders are being used. * Returns true if setBorderWidthLeft, setBorderWidthRight, * setBorderWidthTop, or setBorderWidthBottom has been called. * * @return true if variable width borders are in use */ public boolean isUseVariableBorders() { return useVariableBorders; } /** * Sets a parameter indicating if the rectangle has variable borders * * @param useVariableBorders indication if the rectangle has variable borders */ public void setUseVariableBorders(boolean useVariableBorders) { this.useVariableBorders = useVariableBorders; } /** * Enables the border on the specified side. * * @param side the side to enable. * One of LEFT, RIGHT, TOP, BOTTOM */ public void enableBorderSide(int side) { if (border == UNDEFINED) border = 0; border |= side; } /** * Disables the border on the specified side. * * @param side the side to disable. * One of LEFT, RIGHT, TOP, BOTTOM */ public void disableBorderSide(int side) { if (border == UNDEFINED) border = 0; border &= ~side; } // METHODS TO GET/SET THE BORDER WIDTH: /** * Gets the borderwidth. * * @return a value */ public float getBorderWidth() { return borderWidth; } /** * Sets the borderwidth of the table. * * @param borderWidth the new value */ public void setBorderWidth(float borderWidth) { this.borderWidth = borderWidth; } /** * Helper function returning the border width of a specific side. * * @param variableWidthValue a variable width (could be undefined) * @param side the border you want to check * @return the variableWidthValue if not undefined, otherwise the borderWidth */ private float getVariableBorderWidth(float variableWidthValue, int side) { if ((border & side) != 0) return variableWidthValue != UNDEFINED ? variableWidthValue : borderWidth; return 0; } /** * Helper function updating the border flag for a side * based on the specified width. * A width of 0 will disable the border on that side. * Any other width enables it. * * @param width width of border * @param side border side constant */ private void updateBorderBasedOnWidth(float width, int side) { useVariableBorders = true; if (width > 0) enableBorderSide(side); else disableBorderSide(side); } /** * Gets the width of the left border. * * @return a width */ public float getBorderWidthLeft() { return getVariableBorderWidth(borderWidthLeft, LEFT); } /** * Sets the width of the left border. * * @param borderWidthLeft a width */ public void setBorderWidthLeft(float borderWidthLeft) { this.borderWidthLeft = borderWidthLeft; updateBorderBasedOnWidth(borderWidthLeft, LEFT); } /** * Gets the width of the right border. * * @return a width */ public float getBorderWidthRight() { return getVariableBorderWidth(borderWidthRight, RIGHT); } /** * Sets the width of the right border. * * @param borderWidthRight a width */ public void setBorderWidthRight(float borderWidthRight) { this.borderWidthRight = borderWidthRight; updateBorderBasedOnWidth(borderWidthRight, RIGHT); } /** * Gets the width of the top border. * * @return a width */ public float getBorderWidthTop() { return getVariableBorderWidth(borderWidthTop, TOP); } /** * Sets the width of the top border. * * @param borderWidthTop a width */ public void setBorderWidthTop(float borderWidthTop) { this.borderWidthTop = borderWidthTop; updateBorderBasedOnWidth(borderWidthTop, TOP); } /** * Gets the width of the bottom border. * * @return a width */ public float getBorderWidthBottom() { return getVariableBorderWidth(borderWidthBottom, BOTTOM); } /** * Sets the width of the bottom border. * * @param borderWidthBottom a width */ public void setBorderWidthBottom(float borderWidthBottom) { this.borderWidthBottom = borderWidthBottom; updateBorderBasedOnWidth(borderWidthBottom, BOTTOM); } // METHODS TO GET/SET THE BORDER COLOR: /** * Gets the color of the border. * * @return a Color */ public Color getBorderColor() { return borderColor; } /** * Sets the color of the border. * * @param borderColor a Color */ public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } /** * Gets the color of the left border. * * @return a Color */ public Color getBorderColorLeft() { if (borderColorLeft == null) return borderColor; return borderColorLeft; } /** * Sets the color of the left border. * * @param borderColorLeft a Color */ public void setBorderColorLeft(Color borderColorLeft) { this.borderColorLeft = borderColorLeft; } /** * Gets the color of the right border. * * @return a Color */ public Color getBorderColorRight() { if (borderColorRight == null) return borderColor; return borderColorRight; } /** * Sets the color of the right border. * * @param borderColorRight a Color */ public void setBorderColorRight(Color borderColorRight) { this.borderColorRight = borderColorRight; } /** * Gets the color of the top border. * * @return a Color */ public Color getBorderColorTop() { if (borderColorTop == null) return borderColor; return borderColorTop; } /** * Sets the color of the top border. * * @param borderColorTop a Color */ public void setBorderColorTop(Color borderColorTop) { this.borderColorTop = borderColorTop; } /** * Gets the color of the bottom border. * * @return a Color */ public Color getBorderColorBottom() { if (borderColorBottom == null) return borderColor; return borderColorBottom; } /** * Sets the color of the bottom border. * * @param borderColorBottom a Color */ public void setBorderColorBottom(Color borderColorBottom) { this.borderColorBottom = borderColorBottom; } // SPECIAL METHODS: /** * Gets a Rectangle that is altered to fit on the page. * * @param top the top position * @param bottom the bottom position * @return a Rectangle */ public Rectangle rectangle(float top, float bottom) { Rectangle tmp = new Rectangle(this); if (getTop() > top) { tmp.setTop(top); tmp.disableBorderSide(TOP); } if (getBottom() < bottom) { tmp.setBottom(bottom); tmp.disableBorderSide(BOTTOM); } return tmp; } /** * Copies each of the parameters, except the position, from a * Rectangle object * * @param rect Rectangle to copy from */ public void cloneNonPositionParameters(Rectangle rect) { this.rotation = rect.rotation; this.backgroundColor = rect.backgroundColor; this.border = rect.border; this.useVariableBorders = rect.useVariableBorders; this.borderWidth = rect.borderWidth; this.borderWidthLeft = rect.borderWidthLeft; this.borderWidthRight = rect.borderWidthRight; this.borderWidthTop = rect.borderWidthTop; this.borderWidthBottom = rect.borderWidthBottom; this.borderColor = rect.borderColor; this.borderColorLeft = rect.borderColorLeft; this.borderColorRight = rect.borderColorRight; this.borderColorTop = rect.borderColorTop; this.borderColorBottom = rect.borderColorBottom; } /** * Copies each of the parameters, except the position, from a * Rectangle object if the value is set there * * @param rect Rectangle to copy from */ public void softCloneNonPositionParameters(Rectangle rect) { if (rect.rotation != 0) this.rotation = rect.rotation; if (rect.backgroundColor != null) this.backgroundColor = rect.backgroundColor; if (rect.border != UNDEFINED) this.border = rect.border; if (useVariableBorders) this.useVariableBorders = rect.useVariableBorders; if (rect.borderWidth != UNDEFINED) this.borderWidth = rect.borderWidth; if (rect.borderWidthLeft != UNDEFINED) this.borderWidthLeft = rect.borderWidthLeft; if (rect.borderWidthRight != UNDEFINED) this.borderWidthRight = rect.borderWidthRight; if (rect.borderWidthTop != UNDEFINED) this.borderWidthTop = rect.borderWidthTop; if (rect.borderWidthBottom != UNDEFINED) this.borderWidthBottom = rect.borderWidthBottom; if (rect.borderColor != null) this.borderColor = rect.borderColor; if (rect.borderColorLeft != null) this.borderColorLeft = rect.borderColorLeft; if (rect.borderColorRight != null) this.borderColorRight = rect.borderColorRight; if (rect.borderColorTop != null) this.borderColorTop = rect.borderColorTop; if (rect.borderColorBottom != null) this.borderColorBottom = rect.borderColorBottom; } /** * @return a String representation of the rectangle * @see java.lang.Object#toString() */ public String toString() { StringBuffer buf = new StringBuffer("Rectangle: "); buf.append(getWidth()); buf.append('x'); buf.append(getHeight()); buf.append(" (rot: "); buf.append(rotation); buf.append(" degrees)"); return buf.toString(); } }src/core/com/lowagie/text/RectangleReadOnly.java100644 0 0 22650 11154165267 17357 0ustar 0 0 /* * $Id: RectangleReadOnly.java 3746 2009-03-04 10:13:52Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.awt.Color; /** * A RectangleReadOnly is the representation of a geometric figure. * It's the same as a Rectangle but immutable. * Rectangles support constant width borders using * {@link #setBorderWidth(float)}and {@link #setBorder(int)}. * They also support borders that vary in width/color on each side using * methods like {@link #setBorderWidthLeft(float)}or * {@link #setBorderColorLeft(java.awt.Color)}. * * @see Element * @see Table * @see Cell * @see HeaderFooter * @since 2.1.2 */ public class RectangleReadOnly extends Rectangle { // CONSTRUCTORS /** * Constructs a RectangleReadOnly -object. * * @param llx lower left x * @param lly lower left y * @param urx upper right x * @param ury upper right y */ public RectangleReadOnly(float llx, float lly, float urx, float ury) { super(llx, lly, urx, ury); } /** * Constructs a RectangleReadOnly -object starting from the origin * (0, 0). * * @param urx upper right x * @param ury upper right y */ public RectangleReadOnly(float urx, float ury) { super(0, 0, urx, ury); } /** * Constructs a RectangleReadOnly -object. * * @param rect another Rectangle */ public RectangleReadOnly(Rectangle rect) { super(rect.llx, rect.lly, rect.urx, rect.ury); super.cloneNonPositionParameters(rect); } /** * Throws an error because of the read only nature of this object. */ private void throwReadOnlyError() { throw new UnsupportedOperationException("RectangleReadOnly: this Rectangle is read only."); } // OVERWRITE METHODS SETTING THE DIMENSIONS: /** * Sets the lower left x-coordinate. * * @param llx the new value */ public void setLeft(float llx) { throwReadOnlyError(); } /** * Sets the upper right x-coordinate. * * @param urx the new value */ public void setRight(float urx) { throwReadOnlyError(); } /** * Sets the upper right y-coordinate. * * @param ury the new value */ public void setTop(float ury) { throwReadOnlyError(); } /** * Sets the lower left y-coordinate. * * @param lly the new value */ public void setBottom(float lly) { throwReadOnlyError(); } /** * Normalizes the rectangle. * Switches lower left with upper right if necessary. */ public void normalize() { throwReadOnlyError(); } // OVERWRITE METHODS SETTING THE BACKGROUND COLOR: /** * Sets the backgroundcolor of the rectangle. * * @param value the new value */ public void setBackgroundColor(Color value) { throwReadOnlyError(); } /** * Sets the grayscale of the rectangle. * * @param value the new value */ public void setGrayFill(float value) { throwReadOnlyError(); } // OVERWRITE METHODS SETTING THE BORDER: /** * Enables/Disables the border on the specified sides. * The border is specified as an integer bitwise combination of * the constants: LEFT, RIGHT, TOP, BOTTOM. * * @see #enableBorderSide(int) * @see #disableBorderSide(int) * @param border the new value */ public void setBorder(int border) { throwReadOnlyError(); } /** * Sets a parameter indicating if the rectangle has variable borders * * @param useVariableBorders indication if the rectangle has variable borders */ public void setUseVariableBorders(boolean useVariableBorders) { throwReadOnlyError(); } /** * Enables the border on the specified side. * * @param side the side to enable. * One of LEFT, RIGHT, TOP, BOTTOM */ public void enableBorderSide(int side) { throwReadOnlyError(); } /** * Disables the border on the specified side. * * @param side the side to disable. * One of LEFT, RIGHT, TOP, BOTTOM */ public void disableBorderSide(int side) { throwReadOnlyError(); } // OVERWRITE METHODS SETTING THE BORDER WIDTH: /** * Sets the borderwidth of the table. * * @param borderWidth the new value */ public void setBorderWidth(float borderWidth) { throwReadOnlyError(); } /** * Sets the width of the left border * * @param borderWidthLeft a width */ public void setBorderWidthLeft(float borderWidthLeft) { throwReadOnlyError(); } /** * Sets the width of the right border * * @param borderWidthRight a width */ public void setBorderWidthRight(float borderWidthRight) { throwReadOnlyError(); } /** * Sets the width of the top border * * @param borderWidthTop a width */ public void setBorderWidthTop(float borderWidthTop) { throwReadOnlyError(); } /** * Sets the width of the bottom border * * @param borderWidthBottom a width */ public void setBorderWidthBottom(float borderWidthBottom) { throwReadOnlyError(); } // METHODS TO GET/SET THE BORDER COLOR: /** * Sets the color of the border. * * @param borderColor a Color */ public void setBorderColor(Color borderColor) { throwReadOnlyError(); } /** * Sets the color of the left border. * * @param borderColorLeft a Color */ public void setBorderColorLeft(Color borderColorLeft) { throwReadOnlyError(); } /** * Sets the color of the right border * * @param borderColorRight a Color */ public void setBorderColorRight(Color borderColorRight) { throwReadOnlyError(); } /** * Sets the color of the top border. * * @param borderColorTop a Color */ public void setBorderColorTop(Color borderColorTop) { throwReadOnlyError(); } /** * Sets the color of the bottom border. * * @param borderColorBottom a Color */ public void setBorderColorBottom(Color borderColorBottom) { throwReadOnlyError(); } // SPECIAL METHODS: /** * Copies each of the parameters, except the position, from a * Rectangle object * * @param rect Rectangle to copy from */ public void cloneNonPositionParameters(Rectangle rect) { throwReadOnlyError(); } /** * Copies each of the parameters, except the position, from a * Rectangle object if the value is set there. * * @param rect Rectangle to copy from */ public void softCloneNonPositionParameters(Rectangle rect) { throwReadOnlyError(); } /** * @return String version of the most important rectangle properties * @see java.lang.Object#toString() */ public String toString() { StringBuffer buf = new StringBuffer("RectangleReadOnly: "); buf.append(getWidth()); buf.append('x'); buf.append(getHeight()); buf.append(" (rot: "); buf.append(rotation); buf.append(" degrees)"); return buf.toString(); } }src/core/com/lowagie/text/RomanList.java100644 0 0 7667 11000354131 15674 0ustar 0 0 /* * Copyright 2003 by Michael Niedermair and 2007 Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import com.lowagie.text.factories.RomanNumberFactory; /** * * A special-version of LIST which use roman-letters. * * @see com.lowagie.text.List */ public class RomanList extends List { // constructors /** * Initialization */ public RomanList() { super(true); } /** * Initialization * * @param symbolIndent indent */ public RomanList(int symbolIndent) { super(true, symbolIndent); } /** * Initialization * @param lowercase roman-char in lowercase * @param symbolIndent indent */ public RomanList(boolean lowercase, int symbolIndent) { super(true, symbolIndent); this.lowercase = lowercase; } // overridden method /** * Adds an Object to the List. * * @param o the object to add. * @return true if adding the object succeeded */ public boolean add(Object o) { if (o instanceof ListItem) { ListItem item = (ListItem) o; Chunk chunk; chunk = new Chunk(preSymbol, symbol.getFont()); chunk.append(RomanNumberFactory.getString(first + list.size(), lowercase)); chunk.append(postSymbol); item.setListSymbol(chunk); item.setIndentationLeft(symbolIndent, autoindent); item.setIndentationRight(0); list.add(item); } else if (o instanceof List) { List nested = (List) o; nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent); first--; return list.add(nested); } else if (o instanceof String) { return this.add(new ListItem((String) o)); } return false; } } src/core/com/lowagie/text/Row.java100644 0 0 30621 11012562273 14550 0ustar 0 0 /* * $Id: Row.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; /** * A Row is part of a Table * and contains some Cells. *

* All Rows are constructed by a Table-object. * You don't have to construct any Row yourself. * In fact you can't construct a Row outside the package. *

* Since a Cell can span several rows and/or columns * a row can contain reserved space without any content. * * @see Element * @see Cell * @see Table */ public class Row implements Element { // constants /** id of a null element in a Row*/ public static final int NULL = 0; /** id of the Cell element in a Row*/ public static final int CELL = 1; /** id of the Table element in a Row*/ public static final int TABLE = 2; // member variables /** This is the number of columns in the Row. */ protected int columns; /** This is a valid position the Row. */ protected int currentColumn; /** This is the array that keeps track of reserved cells. */ protected boolean[] reserved; /** This is the array of Objects (Cell or Table). */ protected Object[] cells; /** This is the vertical alignment. */ protected int horizontalAlignment; // constructors /** * Constructs a Row with a certain number of columns. * * @param columns a number of columns */ protected Row(int columns) { this.columns = columns; reserved = new boolean[columns]; cells = new Object[columns]; currentColumn = 0; } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to a * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.ROW; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } // method to delete a column /** * Returns a Row that is a copy of this Row * in which a certain column has been deleted. * * @param column the number of the column to delete */ void deleteColumn(int column) { if ((column >= columns) || (column < 0)) { throw new IndexOutOfBoundsException("getCell at illegal index : " + column); } columns--; boolean newReserved[] = new boolean[columns]; Object newCells[] = new Cell[columns]; for (int i = 0; i < column; i++) { newReserved[i] = reserved[i]; newCells[i] = cells[i]; if (newCells[i] != null && (i + ((Cell) newCells[i]).getColspan() > column)) { ((Cell) newCells[i]).setColspan(((Cell) cells[i]).getColspan() - 1); } } for (int i = column; i < columns; i++) { newReserved[i] = reserved[i + 1]; newCells[i] = cells[i + 1]; } if (cells[column] != null && ((Cell) cells[column]).getColspan() > 1) { newCells[column] = cells[column]; ((Cell) newCells[column]).setColspan(((Cell) newCells[column]).getColspan() - 1); } reserved = newReserved; cells = newCells; } // methods /** * Adds a Cell to the Row. * * @param element the element to add (currently only Cells and Tables supported) * @return the column position the Cell was added, * or -1 if the element couldn't be added. */ int addElement(Object element) { return addElement(element, currentColumn); } /** * Adds an element to the Row at the position given. * * @param element the element to add. (currently only Cells and Tables supported * @param column the position where to add the cell. * @return the column position the Cell was added, * or -1 if the Cell couldn't be added. */ int addElement(Object element, int column) { if (element == null) throw new NullPointerException("addCell - null argument"); if ((column < 0) || (column > columns)) throw new IndexOutOfBoundsException("addCell - illegal column argument"); if ( !((getObjectID(element) == CELL) || (getObjectID(element) == TABLE)) ) throw new IllegalArgumentException("addCell - only Cells or Tables allowed"); int lColspan = ( (Cell.class.isInstance(element)) ? ((Cell) element).getColspan() : 1); if (!reserve(column, lColspan)) { return -1; } cells[column] = element; currentColumn += lColspan - 1; return column; } /** * Puts Cell to the Row at the position given, doesn't reserve colspan. * * @param aElement the cell to add. * @param column the position where to add the cell. */ void setElement(Object aElement, int column) { if (reserved[column]) throw new IllegalArgumentException("setElement - position already taken"); cells[column] = aElement; if (aElement != null) { reserved[column] = true; } } /** * Reserves a Cell in the Row. * * @param column the column that has to be reserved. * @return true if the column was reserved, false if not. */ boolean reserve(int column) { return reserve(column, 1); } /** * Reserves a Cell in the Row. * * @param column the column that has to be reserved. * @param size the number of columns * @return true if the column was reserved, false if not. */ boolean reserve(int column, int size) { if ((column < 0) || ((column + size) > columns)) throw new IndexOutOfBoundsException("reserve - incorrect column/size"); for(int i=column; i < column + size; i++) { if (reserved[i]) { // undo reserve for(int j=i; j >= column; j--) { reserved[j] = false; } return false; } reserved[i] = true; } return true; } // methods to retrieve information /** * Returns true/false when this position in the Row has been reserved, either filled or through a colspan of an Element. * * @param column the column. * @return true if the column was reserved, false if not. */ boolean isReserved(int column) { return reserved[column]; } /** * Returns the type-id of the element in a Row. * * @param column the column of which you'd like to know the type * @return the type-id of the element in the row */ int getElementID(int column) { if (cells[column] == null) return NULL; else if (Cell.class.isInstance(cells[column])) return CELL; else if (Table.class.isInstance(cells[column])) return TABLE; return -1; } /** * Returns the type-id of an Object. * * @param element the object of which you'd like to know the type-id, -1 if invalid * @return the type-id of an object */ int getObjectID(Object element) { if (element == null) return NULL; else if (Cell.class.isInstance(element)) return CELL; else if (Table.class.isInstance(element)) return TABLE; return -1; } /** * Gets a Cell or Table from a certain column. * * @param column the column the Cell/Table is in. * @return the Cell,Table or Object if the column was * reserved or null if empty. */ public Object getCell(int column) { if ((column < 0) || (column > columns)) { throw new IndexOutOfBoundsException("getCell at illegal index :" + column + " max is " + columns); } return cells[column]; } /** * Checks if the row is empty. * * @return true if none of the columns is reserved. */ public boolean isEmpty() { for (int i = 0; i < columns; i++) { if (cells[i] != null) { return false; } } return true; } /** * Gets the number of columns. * * @return a value */ public int getColumns() { return columns; } /** * Sets the horizontal alignment. * * @param value the new value */ public void setHorizontalAlignment(int value) { horizontalAlignment = value; } /** * Gets the horizontal alignment. * * @return a value */ public int getHorizontalAlignment() { return horizontalAlignment; } } src/core/com/lowagie/text/RtfElementInterface.java100644 0 0 5440 11012562273 17650 0ustar 0 0 /* * $Id: RtfElementInterface.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * The RTF jar depends on the iText jar, but the iText jar may not * depend on the RTF jar. This interface offers a temporary solution * until we find a more elegant way to solve this. * @since 2.1.0 */ public interface RtfElementInterface { } src/core/com/lowagie/text/Section.java100644 0 0 56723 11012562273 15420 0ustar 0 0 /* * $Id: Section.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * A Section is a part of a Document containing * other Sections, Paragraphs, List * and/or Tables. *

* Remark: you can not construct a Section yourself. * You will have to ask an instance of Section to the * Chapter or Section to which you want to * add the new Section. *

* Example: *

 * Paragraph title2 = new Paragraph("This is Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
 * Chapter chapter2 = new Chapter(title2, 2);
 * Paragraph someText = new Paragraph("This is some text");
 * chapter2.add(someText);
 * Paragraph title21 = new Paragraph("This is Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
 * Section section1 = chapter2.addSection(title21);
 * Paragraph someSectionText = new Paragraph("This is some silly paragraph in a chapter and/or section. It contains some text to test the functionality of Chapters and Section.");
 * section1.add(someSectionText);
 * Paragraph title211 = new Paragraph("This is SubSection 1 in Section 1 in Chapter 2", FontFactory.getFont(FontFactory.HELVETICA, 14, Font.BOLD, new Color(255, 0, 0)));
 * Section section11 = section1.addSection(40, title211, 2);
 * section11.add(someSectionText);
 * 
*/ public class Section extends ArrayList implements TextElementArray, LargeElement { // constant /** * A possible number style. The default number style: "1.2.3." * @since iText 2.0.8 */ public static final int NUMBERSTYLE_DOTTED = 0; /** * A possible number style. For instance: "1.2.3" * @since iText 2.0.8 */ public static final int NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT = 1; /** A serial version uid. */ private static final long serialVersionUID = 3324172577544748043L; // member variables /** The title of this section. */ protected Paragraph title; /** The bookmark title if different from the content title */ protected String bookmarkTitle; /** The number of sectionnumbers that has to be shown before the section title. */ protected int numberDepth; /** * The style for sectionnumbers. * @since iText 2.0.8 */ protected int numberStyle = NUMBERSTYLE_DOTTED; /** The indentation of this section on the left side. */ protected float indentationLeft; /** The indentation of this section on the right side. */ protected float indentationRight; /** The additional indentation of the content of this section. */ protected float indentation; /** false if the bookmark children are not visible */ protected boolean bookmarkOpen = true; /** true if the section has to trigger a new page */ protected boolean triggerNewPage = false; /** This is the number of subsections. */ protected int subsections = 0; /** This is the complete list of sectionnumbers of this section and the parents of this section. */ protected ArrayList numbers = null; /** * Indicates if the Section will be complete once added to the document. * @since iText 2.0.8 */ protected boolean complete = true; /** * Indicates if the Section was added completely to the document. * @since iText 2.0.8 */ protected boolean addedCompletely = false; /** * Indicates if this is the first time the section was added. * @since iText 2.0.8 */ protected boolean notAddedYet = true; // constructors /** * Constructs a new Section. */ protected Section() { title = new Paragraph(); numberDepth = 1; } /** * Constructs a new Section. * * @param title a Paragraph * @param numberDepth the numberDepth */ protected Section(Paragraph title, int numberDepth) { this.numberDepth = numberDepth; this.title = title; } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener the ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { Element element; for (Iterator i = iterator(); i.hasNext(); ) { element = (Element)i.next(); listener.add(element); } return true; } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.SECTION; } /** * Checks if this object is a Chapter. * * @return true if it is a Chapter, * false if it is a Section. */ public boolean isChapter() { return type() == Element.CHAPTER; } /** * Checks if this object is a Section. * * @return true if it is a Section, * false if it is a Chapter. */ public boolean isSection() { return type() == Element.SECTION; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { ArrayList tmp = new ArrayList(); for (Iterator i = iterator(); i.hasNext(); ) { tmp.addAll(((Element) i.next()).getChunks()); } return tmp; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } // overriding some of the ArrayList-methods /** * Adds a Paragraph, List or Table * to this Section. * * @param index index at which the specified element is to be inserted * @param o an object of type Paragraph, List or Table= * @throws ClassCastException if the object is not a Paragraph, List or Table */ public void add(int index, Object o) { if (isAddedCompletely()) { throw new IllegalStateException("This LargeElement has already been added to the Document."); } try { Element element = (Element) o; if (element.isNestable()) { super.add(index, element); } else { throw new ClassCastException("You can't add a " + element.getClass().getName() + " to a Section."); } } catch(ClassCastException cce) { throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage()); } } /** * Adds a Paragraph, List, Table or another Section * to this Section. * * @param o an object of type Paragraph, List, Table or another Section * @return a boolean * @throws ClassCastException if the object is not a Paragraph, List, Table or Section */ public boolean add(Object o) { if (isAddedCompletely()) { throw new IllegalStateException("This LargeElement has already been added to the Document."); } try { Element element = (Element) o; if (element.type() == Element.SECTION) { Section section = (Section) o; section.setNumbers(++subsections, numbers); return super.add(section); } else if (o instanceof MarkedSection && ((MarkedObject)o).element.type() == Element.SECTION) { MarkedSection mo = (MarkedSection)o; Section section = (Section)mo.element; section.setNumbers(++subsections, numbers); return super.add(mo); } else if (element.isNestable()) { return super.add(o); } else { throw new ClassCastException("You can't add a " + element.getClass().getName() + " to a Section."); } } catch(ClassCastException cce) { throw new ClassCastException("Insertion of illegal Element: " + cce.getMessage()); } } /** * Adds a collection of Elements * to this Section. * * @param collection a collection of Paragraphs, Lists and/or Tables * @return true if the action succeeded, false if not. * @throws ClassCastException if one of the objects isn't a Paragraph, List, Table */ public boolean addAll(Collection collection) { for (Iterator iterator = collection.iterator(); iterator.hasNext(); ) { this.add(iterator.next()); } return true; } // methods that return a Section /** * Creates a Section, adds it to this Section and returns it. * * @param indentation the indentation of the new section * @param title the title of the new section * @param numberDepth the numberDepth of the section * @return a new Section object */ public Section addSection(float indentation, Paragraph title, int numberDepth) { if (isAddedCompletely()) { throw new IllegalStateException("This LargeElement has already been added to the Document."); } Section section = new Section(title, numberDepth); section.setIndentation(indentation); add(section); return section; } /** * Creates a Section, adds it to this Section and returns it. * * @param indentation the indentation of the new section * @param title the title of the new section * @return a new Section object */ public Section addSection(float indentation, Paragraph title) { return addSection(indentation, title, numberDepth + 1); } /** * Creates a Section, add it to this Section and returns it. * * @param title the title of the new section * @param numberDepth the numberDepth of the section * @return a new Section object */ public Section addSection(Paragraph title, int numberDepth) { return addSection(0, title, numberDepth); } /** * Adds a marked section. For use in class MarkedSection only! */ public MarkedSection addMarkedSection() { MarkedSection section = new MarkedSection(new Section(null, numberDepth + 1)); add(section); return section; } /** * Creates a Section, adds it to this Section and returns it. * * @param title the title of the new section * @return a new Section object */ public Section addSection(Paragraph title) { return addSection(0, title, numberDepth + 1); } /** * Adds a Section to this Section and returns it. * * @param indentation the indentation of the new section * @param title the title of the new section * @param numberDepth the numberDepth of the section * @return a new Section object */ public Section addSection(float indentation, String title, int numberDepth) { return addSection(indentation, new Paragraph(title), numberDepth); } /** * Adds a Section to this Section and returns it. * * @param title the title of the new section * @param numberDepth the numberDepth of the section * @return a new Section object */ public Section addSection(String title, int numberDepth) { return addSection(new Paragraph(title), numberDepth); } /** * Adds a Section to this Section and returns it. * * @param indentation the indentation of the new section * @param title the title of the new section * @return a new Section object */ public Section addSection(float indentation, String title) { return addSection(indentation, new Paragraph(title)); } /** * Adds a Section to this Section and returns it. * * @param title the title of the new section * @return a new Section object */ public Section addSection(String title) { return addSection(new Paragraph(title)); } // public methods /** * Sets the title of this section. * * @param title the new title */ public void setTitle(Paragraph title) { this.title = title; } /** * Returns the title, preceded by a certain number of sectionnumbers. * * @return a Paragraph */ public Paragraph getTitle() { return constructTitle(title, numbers, numberDepth, numberStyle); } /** * Constructs a Paragraph that will be used as title for a Section or Chapter. * @param title the title of the section * @param numbers a list of sectionnumbers * @param numberDepth how many numbers have to be shown * @param numberStyle the numbering style * @return a Paragraph object * @since iText 2.0.8 */ public static Paragraph constructTitle(Paragraph title, ArrayList numbers, int numberDepth, int numberStyle) { if (title == null) { return null; } int depth = Math.min(numbers.size(), numberDepth); if (depth < 1) { return title; } StringBuffer buf = new StringBuffer(" "); for (int i = 0; i < depth; i++) { buf.insert(0, "."); buf.insert(0, ((Integer) numbers.get(i)).intValue()); } if (numberStyle == NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT) { buf.deleteCharAt(buf.length() - 2); } Paragraph result = new Paragraph(title); result.add(0, new Chunk(buf.toString(), title.getFont())); return result; } /** * Sets the depth of the sectionnumbers that will be shown preceding the title. *

* If the numberdepth is 0, the sections will not be numbered. If the numberdepth * is 1, the section will be numbered with their own number. If the numberdepth is * higher (for instance x > 1), the numbers of x - 1 parents will be shown. * * @param numberDepth the new numberDepth */ public void setNumberDepth(int numberDepth) { this.numberDepth = numberDepth; } /** * Returns the numberdepth of this Section. * * @return the numberdepth */ public int getNumberDepth() { return numberDepth; } /** * Sets the style for numbering sections. * Possible values are NUMBERSTYLE_DOTTED: 1.2.3. (the default) * or NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT: 1.2.3 * @since iText 2.0.8 */ public void setNumberStyle(int numberStyle) { this.numberStyle = numberStyle; } /** * Gets the style used for numbering sections. * @since iText 2.0.8 * @return a value corresponding with a numbering style */ public int getNumberStyle() { return numberStyle; } /** * Sets the indentation of this Section on the left side. * * @param indentation the indentation */ public void setIndentationLeft(float indentation) { indentationLeft = indentation; } /** * Returns the indentation of this Section on the left side. * * @return the indentation */ public float getIndentationLeft() { return indentationLeft; } /** * Sets the indentation of this Section on the right side. * * @param indentation the indentation */ public void setIndentationRight(float indentation) { indentationRight = indentation; } /** * Returns the indentation of this Section on the right side. * * @return the indentation */ public float getIndentationRight() { return indentationRight; } /** * Sets the indentation of the content of this Section. * * @param indentation the indentation */ public void setIndentation(float indentation) { this.indentation = indentation; } /** * Returns the indentation of the content of this Section. * * @return the indentation */ public float getIndentation() { return indentation; } /** Setter for property bookmarkOpen. * @param bookmarkOpen false if the bookmark children are not * visible. */ public void setBookmarkOpen(boolean bookmarkOpen) { this.bookmarkOpen = bookmarkOpen; } /** * Getter for property bookmarkOpen. * @return Value of property bookmarkOpen. */ public boolean isBookmarkOpen() { return bookmarkOpen; } /** * Setter for property triggerNewPage. * @param triggerNewPage true if a new page has to be triggered. */ public void setTriggerNewPage(boolean triggerNewPage) { this.triggerNewPage = triggerNewPage; } /** * Getter for property bookmarkOpen. * @return Value of property triggerNewPage. */ public boolean isTriggerNewPage() { return triggerNewPage && notAddedYet; } /** * Sets the bookmark title. The bookmark title is the same as the section title but * can be changed with this method. * @param bookmarkTitle the bookmark title */ public void setBookmarkTitle(String bookmarkTitle) { this.bookmarkTitle = bookmarkTitle; } /** * Gets the bookmark title. * @return the bookmark title */ public Paragraph getBookmarkTitle() { if (bookmarkTitle == null) return getTitle(); else return new Paragraph(bookmarkTitle); } /** * Changes the Chapter number. */ public void setChapterNumber(int number) { numbers.set(numbers.size() - 1, new Integer(number)); Object s; for (Iterator i = iterator(); i.hasNext(); ) { s = i.next(); if (s instanceof Section) { ((Section)s).setChapterNumber(number); } } } /** * Returns the depth of this section. * * @return the depth */ public int getDepth() { return numbers.size(); } // private methods /** * Sets the number of this section. * * @param number the number of this section * @param numbers an ArrayList, containing the numbers of the Parent */ private void setNumbers(int number, ArrayList numbers) { this.numbers = new ArrayList(); this.numbers.add(new Integer(number)); this.numbers.addAll(numbers); } /** * Indicates if this is the first time the section is added. * @since iText2.0.8 * @return true if the section wasn't added yet */ public boolean isNotAddedYet() { return notAddedYet; } /** * Sets the indication if the section was already added to * the document. * @since iText2.0.8 * @param notAddedYet */ public void setNotAddedYet(boolean notAddedYet) { this.notAddedYet = notAddedYet; } /** * @since iText 2.0.8 */ protected boolean isAddedCompletely() { return addedCompletely; } /** * @since iText 2.0.8 */ protected void setAddedCompletely(boolean addedCompletely) { this.addedCompletely = addedCompletely; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#flushContent() */ public void flushContent() { setNotAddedYet(false); title = null; Element element; for (Iterator i = iterator(); i.hasNext(); ) { element = (Element)i.next(); if (element instanceof Section) { Section s = (Section)element; if (!s.isComplete() && size() == 1) { s.flushContent(); return; } else { s.setAddedCompletely(true); } } i.remove(); } } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#isComplete() */ public boolean isComplete() { return complete; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#setComplete(boolean) */ public void setComplete(boolean complete) { this.complete = complete; } /** * Adds a new page to the section. * @since 2.1.1 */ public void newPage() { this.add(Chunk.NEXTPAGE); } }src/core/com/lowagie/text/SimpleCell.java100644 0 0 36734 11154165267 16056 0ustar 0 0 /* * $Id: SimpleCell.java 3752 2009-03-04 18:02:40Z blowagie $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPCellEvent; import com.lowagie.text.pdf.PdfPTable; /** * Rectangle that can be used for Cells. * This Rectangle is padded and knows how to draw itself in a PdfPTable or PdfPcellEvent. */ public class SimpleCell extends Rectangle implements PdfPCellEvent, TextElementArray { // constants /** the CellAttributes object represents a row. */ public static final boolean ROW = true; /** the CellAttributes object represents a cell. */ public static final boolean CELL = false; // member variables /** the content of the Cell. */ private ArrayList content = new ArrayList(); /** the width of the Cell. */ private float width = 0f; /** the widthpercentage of the Cell. */ private float widthpercentage = 0f; /** an extra spacing variable */ private float spacing_left = Float.NaN; /** an extra spacing variable */ private float spacing_right = Float.NaN; /** an extra spacing variable */ private float spacing_top = Float.NaN; /** an extra spacing variable */ private float spacing_bottom = Float.NaN; /** an extra padding variable */ private float padding_left = Float.NaN; /** an extra padding variable */ private float padding_right = Float.NaN; /** an extra padding variable */ private float padding_top = Float.NaN; /** an extra padding variable */ private float padding_bottom = Float.NaN; /** the colspan of a Cell */ private int colspan = 1; /** horizontal alignment inside the Cell. */ private int horizontalAlignment = Element.ALIGN_UNDEFINED; /** vertical alignment inside the Cell. */ private int verticalAlignment = Element.ALIGN_UNDEFINED; /** indicates if these are the attributes of a single Cell (false) or a group of Cells (true). */ private boolean cellgroup = false; /** Indicates that the largest ascender height should be used to determine the * height of the first line. Note that this only has an effect when rendered * to PDF. Setting this to true can help with vertical alignment problems. */ protected boolean useAscender = false; /** Indicates that the largest descender height should be added to the height of * the last line (so characters like y don't dip into the border). Note that * this only has an effect when rendered to PDF. */ protected boolean useDescender = false; /** * Adjusts the cell contents to compensate for border widths. Note that * this only has an effect when rendered to PDF. */ protected boolean useBorderPadding; /** * A CellAttributes object is always constructed without any dimensions. * Dimensions are defined after creation. * @param row only true if the CellAttributes object represents a row. */ public SimpleCell(boolean row) { super(0f, 0f, 0f, 0f); cellgroup = row; setBorder(BOX); } /** * Adds content to this object. * @param element * @throws BadElementException */ public void addElement(Element element) throws BadElementException { if (cellgroup) { if (element instanceof SimpleCell) { if(((SimpleCell)element).isCellgroup()) { throw new BadElementException("You can't add one row to another row."); } content.add(element); return; } else { throw new BadElementException("You can only add cells to rows, no objects of type " + element.getClass().getName()); } } if (element.type() == Element.PARAGRAPH || element.type() == Element.PHRASE || element.type() == Element.ANCHOR || element.type() == Element.CHUNK || element.type() == Element.LIST || element.type() == Element.MARKED || element.type() == Element.JPEG || element.type() == Element.JPEG2000 || element.type() == Element.JBIG2 || element.type() == Element.IMGRAW || element.type() == Element.IMGTEMPLATE) { content.add(element); } else { throw new BadElementException("You can't add an element of type " + element.getClass().getName() + " to a SimpleCell."); } } /** * Creates a Cell with these attributes. * @param rowAttributes * @return a cell based on these attributes. * @throws BadElementException */ public Cell createCell(SimpleCell rowAttributes) throws BadElementException { Cell cell = new Cell(); cell.cloneNonPositionParameters(rowAttributes); cell.softCloneNonPositionParameters(this); cell.setColspan(colspan); cell.setHorizontalAlignment(horizontalAlignment); cell.setVerticalAlignment(verticalAlignment); cell.setUseAscender(useAscender); cell.setUseBorderPadding(useBorderPadding); cell.setUseDescender(useDescender); Element element; for (Iterator i = content.iterator(); i.hasNext(); ) { element = (Element)i.next(); cell.addElement(element); } return cell; } /** * Creates a PdfPCell with these attributes. * @param rowAttributes * @return a PdfPCell based on these attributes. */ public PdfPCell createPdfPCell(SimpleCell rowAttributes) { PdfPCell cell = new PdfPCell(); cell.setBorder(NO_BORDER); SimpleCell tmp = new SimpleCell(CELL); tmp.setSpacing_left(spacing_left); tmp.setSpacing_right(spacing_right); tmp.setSpacing_top(spacing_top); tmp.setSpacing_bottom(spacing_bottom); tmp.cloneNonPositionParameters(rowAttributes); tmp.softCloneNonPositionParameters(this); cell.setCellEvent(tmp); cell.setHorizontalAlignment(rowAttributes.horizontalAlignment); cell.setVerticalAlignment(rowAttributes.verticalAlignment); cell.setUseAscender(rowAttributes.useAscender); cell.setUseBorderPadding(rowAttributes.useBorderPadding); cell.setUseDescender(rowAttributes.useDescender); cell.setColspan(colspan); if (horizontalAlignment != Element.ALIGN_UNDEFINED) cell.setHorizontalAlignment(horizontalAlignment); if (verticalAlignment != Element.ALIGN_UNDEFINED) cell.setVerticalAlignment(verticalAlignment); if (useAscender) cell.setUseAscender(useAscender); if (useBorderPadding) cell.setUseBorderPadding(useBorderPadding); if (useDescender) cell.setUseDescender(useDescender); float p; float sp_left = spacing_left; if (Float.isNaN(sp_left)) sp_left = 0f; float sp_right = spacing_right; if (Float.isNaN(sp_right)) sp_right = 0f; float sp_top = spacing_top; if (Float.isNaN(sp_top)) sp_top = 0f; float sp_bottom = spacing_bottom; if (Float.isNaN(sp_bottom)) sp_bottom = 0f; p = padding_left; if (Float.isNaN(p)) p = 0f; cell.setPaddingLeft(p + sp_left); p = padding_right; if (Float.isNaN(p)) p = 0f; cell.setPaddingRight(p + sp_right); p = padding_top; if (Float.isNaN(p)) p = 0f; cell.setPaddingTop(p + sp_top); p = padding_bottom; if (Float.isNaN(p)) p = 0f; cell.setPaddingBottom(p + sp_bottom); Element element; for (Iterator i = content.iterator(); i.hasNext(); ) { element = (Element)i.next(); cell.addElement(element); } return cell; } /** * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell, com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[]) */ public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { float sp_left = spacing_left; if (Float.isNaN(sp_left)) sp_left = 0f; float sp_right = spacing_right; if (Float.isNaN(sp_right)) sp_right = 0f; float sp_top = spacing_top; if (Float.isNaN(sp_top)) sp_top = 0f; float sp_bottom = spacing_bottom; if (Float.isNaN(sp_bottom)) sp_bottom = 0f; Rectangle rect = new Rectangle(position.getLeft(sp_left), position.getBottom(sp_bottom), position.getRight(sp_right), position.getTop(sp_top)); rect.cloneNonPositionParameters(this); canvases[PdfPTable.BACKGROUNDCANVAS].rectangle(rect); rect.setBackgroundColor(null); canvases[PdfPTable.LINECANVAS].rectangle(rect); } /** Sets the padding parameters if they are undefined. * @param padding */ public void setPadding(float padding) { if (Float.isNaN(padding_right)) { setPadding_right(padding); } if (Float.isNaN(padding_left)) { setPadding_left(padding); } if (Float.isNaN(padding_top)) { setPadding_top(padding); } if (Float.isNaN(padding_bottom)) { setPadding_bottom(padding); } } /** * @return Returns the colspan. */ public int getColspan() { return colspan; } /** * @param colspan The colspan to set. */ public void setColspan(int colspan) { if (colspan > 0) this.colspan = colspan; } /** * @return Returns the padding_bottom. */ public float getPadding_bottom() { return padding_bottom; } /** * @param padding_bottom The padding_bottom to set. */ public void setPadding_bottom(float padding_bottom) { this.padding_bottom = padding_bottom; } /** * @return Returns the padding_left. */ public float getPadding_left() { return padding_left; } /** * @param padding_left The padding_left to set. */ public void setPadding_left(float padding_left) { this.padding_left = padding_left; } /** * @return Returns the padding_right. */ public float getPadding_right() { return padding_right; } /** * @param padding_right The padding_right to set. */ public void setPadding_right(float padding_right) { this.padding_right = padding_right; } /** * @return Returns the padding_top. */ public float getPadding_top() { return padding_top; } /** * @param padding_top The padding_top to set. */ public void setPadding_top(float padding_top) { this.padding_top = padding_top; } /** * @return Returns the spacing. */ public float getSpacing_left() { return spacing_left; } /** * @return Returns the spacing. */ public float getSpacing_right() { return spacing_right; } /** * @return Returns the spacing. */ public float getSpacing_top() { return spacing_top; } /** * @return Returns the spacing. */ public float getSpacing_bottom() { return spacing_bottom; } /** * @param spacing The spacing to set. */ public void setSpacing(float spacing) { this.spacing_left = spacing; this.spacing_right = spacing; this.spacing_top = spacing; this.spacing_bottom = spacing; } /** * @param spacing The spacing to set. */ public void setSpacing_left(float spacing) { this.spacing_left = spacing; } /** * @param spacing The spacing to set. */ public void setSpacing_right(float spacing) { this.spacing_right = spacing; } /** * @param spacing The spacing to set. */ public void setSpacing_top(float spacing) { this.spacing_top = spacing; } /** * @param spacing The spacing to set. */ public void setSpacing_bottom(float spacing) { this.spacing_bottom = spacing; } /** * @return Returns the cellgroup. */ public boolean isCellgroup() { return cellgroup; } /** * @param cellgroup The cellgroup to set. */ public void setCellgroup(boolean cellgroup) { this.cellgroup = cellgroup; } /** * @return Returns the horizontal alignment. */ public int getHorizontalAlignment() { return horizontalAlignment; } /** * @param horizontalAlignment The horizontalAlignment to set. */ public void setHorizontalAlignment(int horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } /** * @return Returns the vertical alignment. */ public int getVerticalAlignment() { return verticalAlignment; } /** * @param verticalAlignment The verticalAligment to set. */ public void setVerticalAlignment(int verticalAlignment) { this.verticalAlignment = verticalAlignment; } /** * @return Returns the width. */ public float getWidth() { return width; } /** * @param width The width to set. */ public void setWidth(float width) { this.width = width; } /** * @return Returns the widthpercentage. */ public float getWidthpercentage() { return widthpercentage; } /** * @param widthpercentage The widthpercentage to set. */ public void setWidthpercentage(float widthpercentage) { this.widthpercentage = widthpercentage; } /** * @return Returns the useAscender. */ public boolean isUseAscender() { return useAscender; } /** * @param useAscender The useAscender to set. */ public void setUseAscender(boolean useAscender) { this.useAscender = useAscender; } /** * @return Returns the useBorderPadding. */ public boolean isUseBorderPadding() { return useBorderPadding; } /** * @param useBorderPadding The useBorderPadding to set. */ public void setUseBorderPadding(boolean useBorderPadding) { this.useBorderPadding = useBorderPadding; } /** * @return Returns the useDescender. */ public boolean isUseDescender() { return useDescender; } /** * @param useDescender The useDescender to set. */ public void setUseDescender(boolean useDescender) { this.useDescender = useDescender; } /** * @return Returns the content. */ ArrayList getContent() { return content; } /** * @see com.lowagie.text.TextElementArray#add(java.lang.Object) */ public boolean add(Object o) { try { addElement((Element)o); return true; } catch(ClassCastException e) { return false; } catch(BadElementException e) { throw new ExceptionConverter(e); } } /** * @see com.lowagie.text.Element#type() */ public int type() { return Element.CELL; } }src/core/com/lowagie/text/SimpleTable.java100644 0 0 24621 11154165267 16216 0ustar 0 0 /* * $Id: SimpleTable.java 3752 2009-03-04 18:02:40Z blowagie $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfPTableEvent; /** * Rectangle that can be used for Cells. * This Rectangle is padded and knows how to draw itself in a PdfPTable or PdfPcellEvent. */ public class SimpleTable extends Rectangle implements PdfPTableEvent, TextElementArray { /** the content of a Table. */ private ArrayList content = new ArrayList(); /** the width of the Table. */ private float width = 0f; /** the widthpercentage of the Table. */ private float widthpercentage = 0f; /** the spacing of the Cells. */ private float cellspacing; /** the padding of the Cells. */ private float cellpadding; /** the alignment of the table. */ private int alignment; /** * A RectangleCell is always constructed without any dimensions. * Dimensions are defined after creation. */ public SimpleTable() { super(0f, 0f, 0f, 0f); setBorder(BOX); setBorderWidth(2f); } /** * Adds content to this object. * @param element * @throws BadElementException */ public void addElement(SimpleCell element) throws BadElementException { if(!element.isCellgroup()) { throw new BadElementException("You can't add cells to a table directly, add them to a row first."); } content.add(element); } /** * Creates a Table object based on this TableAttributes object. * @return a com.lowagie.text.Table object * @throws BadElementException */ public Table createTable() throws BadElementException { if (content.isEmpty()) throw new BadElementException("Trying to create a table without rows."); SimpleCell row = (SimpleCell)content.get(0); SimpleCell cell; int columns = 0; for (Iterator i = row.getContent().iterator(); i.hasNext(); ) { cell = (SimpleCell)i.next(); columns += cell.getColspan(); } float[] widths = new float[columns]; float[] widthpercentages = new float[columns]; Table table = new Table(columns); table.setAlignment(alignment); table.setSpacing(cellspacing); table.setPadding(cellpadding); table.cloneNonPositionParameters(this); int pos; for (Iterator rows = content.iterator(); rows.hasNext(); ) { row = (SimpleCell)rows.next(); pos = 0; for (Iterator cells = row.getContent().iterator(); cells.hasNext(); ) { cell = (SimpleCell)cells.next(); table.addCell(cell.createCell(row)); if (cell.getColspan() == 1) { if (cell.getWidth() > 0) widths[pos] = cell.getWidth(); if (cell.getWidthpercentage() > 0) widthpercentages[pos] = cell.getWidthpercentage(); } pos += cell.getColspan(); } } float sumWidths = 0f; for(int i = 0; i < columns; i++) { if (widths[i] == 0) { sumWidths = 0; break; } sumWidths += widths[i]; } if (sumWidths > 0) { table.setWidth(sumWidths); table.setLocked(true); table.setWidths(widths); } else { for(int i = 0; i < columns; i++) { if (widthpercentages[i] == 0) { sumWidths = 0; break; } sumWidths += widthpercentages[i]; } if (sumWidths > 0) { table.setWidths(widthpercentages); } } if (width > 0) { table.setWidth(width); table.setLocked(true); } else if (widthpercentage > 0) { table.setWidth(widthpercentage); } return table; } /** * Creates a PdfPTable object based on this TableAttributes object. * @return a com.lowagie.text.pdf.PdfPTable object * @throws DocumentException */ public PdfPTable createPdfPTable() throws DocumentException { if (content.isEmpty()) throw new BadElementException("Trying to create a table without rows."); SimpleCell row = (SimpleCell)content.get(0); SimpleCell cell; int columns = 0; for (Iterator i = row.getContent().iterator(); i.hasNext(); ) { cell = (SimpleCell)i.next(); columns += cell.getColspan(); } float[] widths = new float[columns]; float[] widthpercentages = new float[columns]; PdfPTable table = new PdfPTable(columns); table.setTableEvent(this); table.setHorizontalAlignment(alignment); int pos; for (Iterator rows = content.iterator(); rows.hasNext(); ) { row = (SimpleCell)rows.next(); pos = 0; for (Iterator cells = row.getContent().iterator(); cells.hasNext(); ) { cell = (SimpleCell)cells.next(); if (Float.isNaN(cell.getSpacing_left())) { cell.setSpacing_left(cellspacing / 2f); } if (Float.isNaN(cell.getSpacing_right())) { cell.setSpacing_right(cellspacing / 2f); } if (Float.isNaN(cell.getSpacing_top())) { cell.setSpacing_top(cellspacing / 2f); } if (Float.isNaN(cell.getSpacing_bottom())) { cell.setSpacing_bottom(cellspacing / 2f); } cell.setPadding(cellpadding); table.addCell(cell.createPdfPCell(row)); if (cell.getColspan() == 1) { if (cell.getWidth() > 0) widths[pos] = cell.getWidth(); if (cell.getWidthpercentage() > 0) widthpercentages[pos] = cell.getWidthpercentage(); } pos += cell.getColspan(); } } float sumWidths = 0f; for(int i = 0; i < columns; i++) { if (widths[i] == 0) { sumWidths = 0; break; } sumWidths += widths[i]; } if (sumWidths > 0) { table.setTotalWidth(sumWidths); table.setWidths(widths); } else { for(int i = 0; i < columns; i++) { if (widthpercentages[i] == 0) { sumWidths = 0; break; } sumWidths += widthpercentages[i]; } if (sumWidths > 0) { table.setWidths(widthpercentages); } } if (width > 0) { table.setTotalWidth(width); } if (widthpercentage > 0) { table.setWidthPercentage(widthpercentage); } return table; } /** * @see com.lowagie.text.pdf.PdfPTableEvent#tableLayout(com.lowagie.text.pdf.PdfPTable, float[][], float[], int, int, com.lowagie.text.pdf.PdfContentByte[]) */ public void tableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) { float[] width = widths[0]; Rectangle rect = new Rectangle(width[0], heights[heights.length - 1], width[width.length - 1], heights[0]); rect.cloneNonPositionParameters(this); int bd = rect.getBorder(); rect.setBorder(Rectangle.NO_BORDER); canvases[PdfPTable.BACKGROUNDCANVAS].rectangle(rect); rect.setBorder(bd); rect.setBackgroundColor(null); canvases[PdfPTable.LINECANVAS].rectangle(rect); } /** * @return Returns the cellpadding. */ public float getCellpadding() { return cellpadding; } /** * @param cellpadding The cellpadding to set. */ public void setCellpadding(float cellpadding) { this.cellpadding = cellpadding; } /** * @return Returns the cellspacing. */ public float getCellspacing() { return cellspacing; } /** * @param cellspacing The cellspacing to set. */ public void setCellspacing(float cellspacing) { this.cellspacing = cellspacing; } /** * @return Returns the alignment. */ public int getAlignment() { return alignment; } /** * @param alignment The alignment to set. */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * @return Returns the width. */ public float getWidth() { return width; } /** * @param width The width to set. */ public void setWidth(float width) { this.width = width; } /** * @return Returns the widthpercentage. */ public float getWidthpercentage() { return widthpercentage; } /** * @param widthpercentage The widthpercentage to set. */ public void setWidthpercentage(float widthpercentage) { this.widthpercentage = widthpercentage; } /** * @see com.lowagie.text.Element#type() */ public int type() { return Element.TABLE; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } /** * @see com.lowagie.text.TextElementArray#add(java.lang.Object) */ public boolean add(Object o) { try { addElement((SimpleCell)o); return true; } catch(ClassCastException e) { return false; } catch(BadElementException e) { throw new ExceptionConverter(e); } } }src/core/com/lowagie/text/SpecialSymbol.java100644 0 0 16332 11215636056 16560 0ustar 0 0 /* * $Id: SpecialSymbol.java 3963 2009-06-11 11:45:49Z psoares33 $ * * Copyright 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * This class contains the symbols that correspond with special symbols. *

* When you construct a Phrase with Phrase.getInstance using a String, * this String can contain special Symbols. These are characters with an int value * between 913 and 937 (except 930) and between 945 and 969. With this class the value of the * corresponding character of the Font Symbol, can be retrieved. * * @see Phrase * * @author Bruno Lowagie * @author Evelyne De Cordier */ public class SpecialSymbol { /** * Returns the first occurrence of a special symbol in a String. * * @param string a String * @return an index of -1 if no special symbol was found */ public static int index(String string) { int length = string.length(); for (int i = 0; i < length; i++) { if (getCorrespondingSymbol(string.charAt(i)) != ' ') { return i; } } return -1; } /** * Gets a chunk with a symbol character. * @param c a character that has to be changed into a symbol * @param font Font if there is no SYMBOL character corresponding with c * @return a SYMBOL version of a character */ public static Chunk get(char c, Font font) { char greek = SpecialSymbol.getCorrespondingSymbol(c); if (greek == ' ') { return new Chunk(String.valueOf(c), font); } Font symbol = new Font(Font.SYMBOL, font.getSize(), font.getStyle(), font.getColor()); String s = String.valueOf(greek); return new Chunk(s, symbol); } /** * Looks for the corresponding symbol in the font Symbol. * * @param c the original ASCII-char * @return the corresponding symbol in font Symbol */ public static char getCorrespondingSymbol(char c) { switch(c) { case 913: return 'A'; // ALFA case 914: return 'B'; // BETA case 915: return 'G'; // GAMMA case 916: return 'D'; // DELTA case 917: return 'E'; // EPSILON case 918: return 'Z'; // ZETA case 919: return 'H'; // ETA case 920: return 'Q'; // THETA case 921: return 'I'; // IOTA case 922: return 'K'; // KAPPA case 923: return 'L'; // LAMBDA case 924: return 'M'; // MU case 925: return 'N'; // NU case 926: return 'X'; // XI case 927: return 'O'; // OMICRON case 928: return 'P'; // PI case 929: return 'R'; // RHO case 931: return 'S'; // SIGMA case 932: return 'T'; // TAU case 933: return 'U'; // UPSILON case 934: return 'F'; // PHI case 935: return 'C'; // CHI case 936: return 'Y'; // PSI case 937: return 'W'; // OMEGA case 945: return 'a'; // alfa case 946: return 'b'; // beta case 947: return 'g'; // gamma case 948: return 'd'; // delta case 949: return 'e'; // epsilon case 950: return 'z'; // zeta case 951: return 'h'; // eta case 952: return 'q'; // theta case 953: return 'i'; // iota case 954: return 'k'; // kappa case 955: return 'l'; // lambda case 956: return 'm'; // mu case 957: return 'n'; // nu case 958: return 'x'; // xi case 959: return 'o'; // omicron case 960: return 'p'; // pi case 961: return 'r'; // rho case 962: return 'V'; // sigma case 963: return 's'; // sigma case 964: return 't'; // tau case 965: return 'u'; // upsilon case 966: return 'f'; // phi case 967: return 'c'; // chi case 968: return 'y'; // psi case 969: return 'w'; // omega default: return ' '; } } }src/core/com/lowagie/text/SplitCharacter.java100644 0 0 10376 11012562273 16716 0ustar 0 0 /* * $Id: SplitCharacter.java 3374 2008-05-12 18:42:56Z xlv $ * * Copyright 2001, 2002 by Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import com.lowagie.text.pdf.PdfChunk; /** Interface for customizing the split character. * * @author Paulo Soares (psoares@consiste.pt) */ public interface SplitCharacter { /** * Returns true if the character can split a line. The splitting implementation * is free to look ahead or look behind characters to make a decision. *

* The default implementation is: *

*

     * public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) {
     *    char c;
     *    if (ck == null)
     *        c = cc[current];
     *    else
     *        c = (char) ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]);
     *    if (c <= ' ' || c == '-') {
     *        return true;
     *    }
     *    if (c < 0x2e80)
     *        return false;
     *    return ((c >= 0x2e80 && c < 0xd7a0)
     *    || (c >= 0xf900 && c < 0xfb00)
     *    || (c >= 0xfe30 && c < 0xfe50)
     *    || (c >= 0xff61 && c < 0xffa0));
     * }
     * 
* @param start the lower limit of cc inclusive * @param current the pointer to the character in cc * @param end the upper limit of cc exclusive * @param cc an array of characters at least end sized * @param ck an array of PdfChunk. The main use is to be able to call * {@link PdfChunk#getUnicodeEquivalent(int)}. It may be null * or shorter than end. If null no conversion takes place. * If shorter than end the last element is used * @return true if the character(s) can split a line */ public boolean isSplitCharacter(int start, int current, int end, char cc[], PdfChunk ck[]); } src/core/com/lowagie/text/Table.java100644 0 0 150137 11154165267 15066 0ustar 0 0 /* * $Id: Table.java 3754 2009-03-04 19:05:20Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * Some methods in this class were contributed by Geert Poels, Kris Jespers and * Steve Ogryzek. Check the CVS repository. */ package com.lowagie.text; import java.awt.Dimension; import java.awt.Point; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; /** * A Table is a Rectangle that contains Cells, * ordered in some kind of matrix. *

* Tables that span multiple pages are cut into different parts automatically. * If you want a table header to be repeated on every page, you may not forget to * mark the end of the header section by using the method endHeaders(). *

* The matrix of a table is not necessarily an m x n-matrix. It can contain holes * or cells that are bigger than the unit. Believe me or not, but it took some serious * thinking to make this as user friendly as possible. I hope you will find the result * quite simple (I love simple solutions, especially for complex problems). * I didn't want it to be something as complex as the Java GridBagLayout. *

* Example: *

 * // Remark: You MUST know the number of columns when constructing a Table.
 * //         The number of rows is not important.
 * Table table = new Table(3);
 * table.setBorderWidth(1);
 * table.setBorderColor(new Color(0, 0, 255));
 * table.setPadding(5);
 * table.setSpacing(5);
 * Cell cell = new Cell("header");
 * cell.setHeader(true);
 * cell.setColspan(3);
 * table.addCell(cell);
 * table.endHeaders();
 * cell = new Cell("example cell with colspan 1 and rowspan 2");
 * cell.setRowspan(2);
 * cell.setBorderColor(new Color(255, 0, 0));
 * table.addCell(cell);
 * table.addCell("1.1");
 * table.addCell("2.1");
 * table.addCell("1.2");
 * table.addCell("2.2");
 * table.addCell("cell test1");
 * cell = new Cell("big cell");
 * cell.setRowspan(2);
 * cell.setColspan(2);
 * table.addCell(cell);
 * table.addCell("cell test2");
 * 
* The result of this code is a table: * * * * * * * * * * * * * * * * * * * * *
* header *
* example cell with colspan 1 and rowspan 2 * * 1.1 * * 2.1 *
* 1.2 * * 2.2 *
* cell test1 * * big cell *
* cell test2 *
* * @see Rectangle * @see Element * @see Row * @see Cell */ public class Table extends Rectangle implements LargeElement { // membervariables /** This is the number of columns in the Table. */ private int columns; /** This is the list of Rows. */ private ArrayList rows = new ArrayList(); /** The current Position in the table. */ private Point curPosition = new Point(0, 0); /** This Empty Cell contains the DEFAULT layout of each Cell added with the method addCell(String content). */ private Cell defaultCell = new Cell(true); /** This is the number of the last row of the table headers. */ private int lastHeaderRow = -1; /** This is the horizontal alignment. */ private int alignment = Element.ALIGN_CENTER; /** This is cellpadding. */ private float cellpadding; /** This is cellspacing. */ private float cellspacing; /** This is the width of the table (in percent of the available space). */ private float width = 80; /** Is the width a percentage (false) or an absolute width (true)? */ private boolean locked = false; /** This is an array containing the widths (in percentages) of every column. */ private float[] widths; /** Boolean to track if a table was inserted (to avoid unnecessary computations afterwards) */ private boolean mTableInserted = false; /** * Boolean to automatically fill empty cells before a table is rendered * (takes CPU so may be set to false in case of certainty) */ protected boolean autoFillEmptyCells = false; /** If true this table may not be split over two pages. */ boolean tableFitsPage = false; /** If true cells may not be split over two pages. */ boolean cellsFitPage = false; /** This is the offset of the table. */ float offset = Float.NaN; /** if you want to generate tables the old way, set this value to false. */ protected boolean convert2pdfptable = false; /** * Indicates if this is the first time the section was added. * @since iText 2.0.8 */ protected boolean notAddedYet = true; /** * Indicates if the PdfPTable is complete once added to the document. * @since iText 2.0.8 */ protected boolean complete = true; // constructors /** * Constructs a Table with a certain number of columns. * * @param columns The number of columns in the table * @throws BadElementException if the creator was called with less than 1 column */ public Table(int columns) throws BadElementException { this(columns, 1); } /** * Constructs a Table with a certain number of columns * and a certain number of Rows. * * @param columns The number of columns in the table * @param rows The number of rows * @throws BadElementException if the creator was called with less than 1 column */ public Table(int columns, int rows) throws BadElementException { // a Rectangle is create with BY DEFAULT a border with a width of 1 super(0, 0, 0, 0); setBorder(BOX); setBorderWidth(1); defaultCell.setBorder(BOX); // a table should have at least 1 column if (columns <= 0) { throw new BadElementException("A table should have at least 1 column."); } this.columns = columns; // a certain number of rows are created for (int i = 0; i < rows; i++) { this.rows.add(new Row(columns)); } curPosition = new Point(0, 0); // the DEFAULT widths are calculated widths = new float[columns]; float width = 100f / columns; for (int i = 0; i < columns; i++) { widths[i] = width; } } /** * Copy constructor (shallow copy). */ public Table(Table t) { super(0, 0, 0, 0); this.cloneNonPositionParameters(t); this.columns = t.columns; this.rows = t.rows; this.curPosition = t.curPosition; this.defaultCell = t.defaultCell; this.lastHeaderRow = t.lastHeaderRow; this.alignment = t.alignment; this.cellpadding = t.cellpadding; this.cellspacing = t.cellspacing; this.width = t.width; this.widths = t.widths; this.autoFillEmptyCells = t.autoFillEmptyCells; this.tableFitsPage = t.tableFitsPage; this.cellsFitPage = t.cellsFitPage; this.offset = t.offset; this.convert2pdfptable = t.convert2pdfptable; } // implementation of the Element-methods /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch(DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.TABLE; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } // getters and setters /** * Gets the number of columns. * * @return a value */ public int getColumns() { return columns; } /** * Gets the number of rows in this Table. * * @return the number of rows in this Table */ public int size() { return rows.size(); } /** * Gets the dimension of this table * * @return dimension */ public Dimension getDimension() { return new Dimension(columns, size()); } /** * Gets the default layout of the Table. * @return a cell with all the defaults * @since 2.0.7 */ public Cell getDefaultCell() { return defaultCell; } /** * Sets the default layout of the Table to * the provided Cell * @param value a cell with all the defaults * @since 2.0.7 */ public void setDefaultCell(Cell value) { defaultCell = value; } /** * Gets the last number of the rows that contain headers. * * @return a rownumber */ public int getLastHeaderRow() { return this.lastHeaderRow; } /** * Sets the horizontal alignment. * * @param value the new value */ public void setLastHeaderRow(int value) { lastHeaderRow = value; } /** * Marks the last row of the table headers. * * @return the number of the last row of the table headers */ public int endHeaders() { lastHeaderRow = curPosition.x - 1; return lastHeaderRow; } /** * Gets the horizontal alignment. * * @return a value */ public int getAlignment() { return alignment; } /** * Sets the horizontal alignment. * * @param value the new value */ public void setAlignment(int value) { alignment = value; } /** * Sets the alignment of this paragraph. * * @param alignment the new alignment as a String */ public void setAlignment(String alignment) { if (ElementTags.ALIGN_LEFT.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_LEFT; return; } if (ElementTags.RIGHT.equalsIgnoreCase(alignment)) { this.alignment = Element.ALIGN_RIGHT; return; } this.alignment = Element.ALIGN_CENTER; } /** * Gets the cellpadding. * * @return a value */ public float getPadding() { return cellpadding; } /** * Sets the cellpadding. * * @param value the new value */ public void setPadding(float value) { cellpadding = value; } /** * Gets the cellspacing. * * @return a value */ public float getSpacing() { return cellspacing; } /** * Sets the cellspacing. * * @param value the new value */ public void setSpacing(float value) { cellspacing = value; } /** * Enables/disables automatic insertion of empty cells before table is rendered. (default = false) * As some people may want to create a table, fill only a couple of the cells and don't bother with * investigating which empty ones need to be added, this default behavior may be very welcome. * Disabling is recommended to increase speed. (empty cells should be added through extra code then) * * @param aDoAutoFill enable/disable autofill */ public void setAutoFillEmptyCells(boolean aDoAutoFill) { autoFillEmptyCells = aDoAutoFill; } /** * Gets the table width (a percentage). * * @return the table width */ public float getWidth() { return width; } /** * Sets the width of this table (in percentage of the available space). * * @param width the width */ public void setWidth(float width) { this.width = width; } /** * @return the locked */ public boolean isLocked() { return locked; } /** * @param locked the locked to set */ public void setLocked(boolean locked) { this.locked = locked; } /** * Gets the proportional widths of the columns in this Table. * * @return the proportional widths of the columns in this Table */ public float[] getProportionalWidths() { return widths; } /** * Sets the widths of the different columns (percentages). *

* You can give up relative values of borderwidths. * The sum of these values will be considered 100%. * The values will be recalculated as percentages of this sum. *

* example: *

     * float[] widths = {2, 1, 1};
     * table.setWidths(widths)
     * 
* The widths will be: a width of 50% for the first column, * 25% for the second and third column. * * @param widths an array with values * @throws BadElementException */ public void setWidths(float[] widths) throws BadElementException { if (widths.length != columns) { throw new BadElementException("Wrong number of columns."); } // The sum of all values is 100% float hundredPercent = 0; for (int i = 0; i < columns; i++) { hundredPercent += widths[i]; } // The different percentages are calculated float width; this.widths[columns - 1] = 100; for (int i = 0; i < columns - 1; i++) { width = (100.0f * widths[i]) / hundredPercent; this.widths[i] = width; this.widths[columns - 1] -= width; } } /** * Sets the widths of the different columns (percentages). *

* You can give up relative values of borderwidths. * The sum of these values will be considered 100%. * The values will be recalculated as percentages of this sum. * * @param widths an array with values * @throws DocumentException */ public void setWidths(int[] widths) throws DocumentException { float tb[] = new float[widths.length]; for (int k = 0; k < widths.length; ++k) tb[k] = widths[k]; setWidths(tb); } /** * Checks if this Table has to fit a page. * * @return true if the table may not be split */ public boolean isTableFitsPage() { return tableFitsPage; } /** * Allows you to control when a page break occurs. *

* When a table doesn't fit a page, it is split in two parts. * If you want to avoid this, you should set the tableFitsPage value to true. * * @param fitPage enter true if you don't want to split cells */ public void setTableFitsPage(boolean fitPage) { this.tableFitsPage = fitPage; if (fitPage) setCellsFitPage(true); } /** * Checks if the cells of this Table have to fit a page. * * @return true if the cells may not be split */ public boolean isCellsFitPage() { return cellsFitPage; } /** * Allows you to control when a page break occurs. *

* When a cell doesn't fit a page, it is split in two parts. * If you want to avoid this, you should set the cellsFitPage value to true. * * @param fitPage enter true if you don't want to split cells */ public void setCellsFitPage(boolean fitPage) { this.cellsFitPage = fitPage; } /** * Sets the offset of this table. * * Normally a newline is added before you add a Table object. * This newline uses the current leading. * If you want to control the space between the table and the previous * element yourself, you have to set the offset of this table. * * @param offset the space between this table and the previous object. */ public void setOffset(float offset) { this.offset = offset; } /** * Gets the offset of this table. * * @return the space between this table and the previous element. */ public float getOffset() { return offset; } /** * Method to check if the Table should be converted to a PdfPTable or not. * @return false if the table should be handled the old fashioned way. */ public boolean isConvert2pdfptable() { return convert2pdfptable; } /** * If set to true, iText will try to convert the Table to a PdfPTable. * @param convert2pdfptable true if you want iText to try to convert the Table to a PdfPTable */ public void setConvert2pdfptable(boolean convert2pdfptable) { this.convert2pdfptable = convert2pdfptable; } // methods to add content to the table /** * Adds a Cell to the Table at a certain row and column. * * @param aCell The Cell to add * @param row The row where the Cell will be added * @param column The column where the Cell will be added * @throws BadElementException */ public void addCell(Cell aCell, int row, int column) throws BadElementException { addCell(aCell, new Point(row,column)); } /** * Adds a Cell to the Table at a certain location. * * @param aCell The Cell to add * @param aLocation The location where the Cell will be added * @throws BadElementException */ public void addCell(Cell aCell, Point aLocation) throws BadElementException { if (aCell == null) throw new NullPointerException("addCell - cell has null-value"); if (aLocation == null) throw new NullPointerException("addCell - point has null-value"); if (aCell.isTable()) insertTable((Table)aCell.getElements().next(), aLocation); if (aLocation.x < 0) throw new BadElementException("row coordinate of location must be >= 0"); if ((aLocation.y <= 0) && (aLocation.y > columns)) throw new BadElementException("column coordinate of location must be >= 0 and < nr of columns"); if (!isValidLocation(aCell, aLocation)) throw new BadElementException("Adding a cell at the location (" + aLocation.x + "," + aLocation.y + ") with a colspan of " + aCell.getColspan() + " and a rowspan of " + aCell.getRowspan() + " is illegal (beyond boundaries/overlapping)."); if (aCell.getBorder() == UNDEFINED) aCell.setBorder(defaultCell.getBorder()); aCell.fill(); placeCell(rows, aCell, aLocation); setCurrentLocationToNextValidPosition(aLocation); } /** * Adds a Cell to the Table. * * @param cell a Cell */ public void addCell(Cell cell) { try { addCell(cell, curPosition); } catch(BadElementException bee) { // don't add the cell } } /** * Adds a Cell to the Table. *

* This is a shortcut for addCell(Cell cell). * The Phrase will be converted to a Cell. * * @param content a Phrase * @throws BadElementException this should never happen */ public void addCell(Phrase content) throws BadElementException { addCell(content, curPosition); } /** * Adds a Cell to the Table. *

* This is a shortcut for addCell(Cell cell, Point location). * The Phrase will be converted to a Cell. * * @param content a Phrase * @param location a Point * @throws BadElementException this should never happen */ public void addCell(Phrase content, Point location) throws BadElementException { Cell cell = new Cell(content); cell.setBorder(defaultCell.getBorder()); cell.setBorderWidth(defaultCell.getBorderWidth()); cell.setBorderColor(defaultCell.getBorderColor()); cell.setBackgroundColor(defaultCell.getBackgroundColor()); cell.setHorizontalAlignment(defaultCell.getHorizontalAlignment()); cell.setVerticalAlignment(defaultCell.getVerticalAlignment()); cell.setColspan(defaultCell.getColspan()); cell.setRowspan(defaultCell.getRowspan()); addCell(cell, location); } /** * Adds a Cell to the Table. *

* This is a shortcut for addCell(Cell cell). * The String will be converted to a Cell. * * @param content a String * @throws BadElementException this should never happen */ public void addCell(String content) throws BadElementException { addCell(new Phrase(content), curPosition); } /** * Adds a Cell to the Table. *

* This is a shortcut for addCell(Cell cell, Point location). * The String will be converted to a Cell. * * @param content a String * @param location a Point * @throws BadElementException this should never happen */ public void addCell(String content, Point location) throws BadElementException { addCell(new Phrase(content), location); } /** * To put a table within the existing table at the current position * generateTable will of course re-arrange the widths of the columns. * * @param aTable the table you want to insert */ public void insertTable(Table aTable) { if (aTable == null) throw new NullPointerException("insertTable - table has null-value"); insertTable(aTable, curPosition); } /** * To put a table within the existing table at the given position * generateTable will of course re-arrange the widths of the columns. * * @param aTable The Table to add * @param row The row where the Cell will be added * @param column The column where the Cell will be added */ public void insertTable(Table aTable, int row, int column) { if (aTable == null) throw new NullPointerException("insertTable - table has null-value"); insertTable(aTable, new Point(row, column)); } /** * To put a table within the existing table at the given position * generateTable will of course re-arrange the widths of the columns. * * @param aTable the table you want to insert * @param aLocation a Point */ public void insertTable(Table aTable, Point aLocation) { if (aTable == null) throw new NullPointerException("insertTable - table has null-value"); if (aLocation == null) throw new NullPointerException("insertTable - point has null-value"); mTableInserted = true; aTable.complete(); if (aLocation.y > columns) { throw new IllegalArgumentException("insertTable -- wrong columnposition("+ aLocation.y + ") of location; max =" + columns); } int rowCount = aLocation.x + 1 - rows.size(); int i = 0; if ( rowCount > 0 ) { //create new rows ? for (; i < rowCount; i++) { rows.add(new Row(columns)); } } ((Row) rows.get(aLocation.x)).setElement(aTable,aLocation.y); setCurrentLocationToNextValidPosition(aLocation); } /** * Gives you the possibility to add columns. * * @param aColumns the number of columns to add */ public void addColumns(int aColumns) { ArrayList newRows = new ArrayList(rows.size()); int newColumns = columns + aColumns; Row row; for (int i = 0; i < rows.size(); i++) { row = new Row(newColumns); for (int j = 0; j < columns; j++) { row.setElement(((Row) rows.get(i)).getCell(j) ,j); } for (int j = columns; j < newColumns && i < curPosition.x; j++) { row.setElement(null, j); } newRows.add(row); } // applied 1 column-fix; last column needs to have a width of 0 float [] newWidths = new float[newColumns]; System.arraycopy(widths, 0, newWidths, 0, columns); for (int j = columns; j < newColumns ; j++) { newWidths[j] = 0; } columns = newColumns; widths = newWidths; rows = newRows; } /** * Deletes a column in this table. * * @param column the number of the column that has to be deleted * @throws BadElementException */ public void deleteColumn(int column) throws BadElementException { float newWidths[] = new float[--columns]; System.arraycopy(widths, 0, newWidths, 0, column); System.arraycopy(widths, column + 1, newWidths, column, columns - column); setWidths(newWidths); System.arraycopy(widths, 0, newWidths, 0, columns); widths = newWidths; Row row; int size = rows.size(); for (int i = 0; i < size; i++) { row = (Row) rows.get(i); row.deleteColumn(column); rows.set(i, row); } if (column == columns) { curPosition.setLocation(curPosition.x+1, 0); } } /** * Deletes a row. * * @param row the number of the row to delete * @return boolean true if the row was deleted; false if not */ public boolean deleteRow(int row) { if (row < 0 || row >= rows.size()) { return false; } rows.remove(row); curPosition.setLocation(curPosition.x-1, curPosition.y); return true; } /** * Deletes all rows in this table. * (contributed by dperezcar@fcc.es) */ public void deleteAllRows() { rows.clear(); rows.add(new Row(columns)); curPosition.setLocation(0, 0); lastHeaderRow = -1; } /** * Deletes the last row in this table. * * @return boolean true if the row was deleted; false if not */ public boolean deleteLastRow() { return deleteRow(rows.size() - 1); } /** * Will fill empty cells with valid blank Cells */ public void complete() { if (mTableInserted) { mergeInsertedTables(); // integrate tables in the table mTableInserted = false; } if (autoFillEmptyCells) { fillEmptyMatrixCells(); } } // private helper classes /** * returns the element at the position row, column * (Cast to Cell or Table) * * @param row * @param column * @return dimension * @since 2.1.0 (was made private in 2.0.3) */ public Object getElement(int row, int column) { return ((Row) rows.get(row)).getCell(column); } /** * Integrates all added tables and recalculates column widths. */ private void mergeInsertedTables() { int i=0, j=0; float [] lNewWidths = null; int [] lDummyWidths = new int[columns]; // to keep track in how many new cols this one will be split float[][] lDummyColumnWidths = new float[columns][]; // bugfix Tony Copping int [] lDummyHeights = new int[rows.size()]; // to keep track in how many new rows this one will be split ArrayList newRows = null; boolean isTable=false; int lTotalRows = 0, lTotalColumns = 0; int lNewMaxRows = 0, lNewMaxColumns = 0; Table lDummyTable = null; // first we'll add new columns when needed // check one column at a time, find maximum needed nr of cols // Search internal tables and find one with max columns for (j=0; j < columns; j++) { lNewMaxColumns = 1; // value to hold in how many columns the current one will be split float [] tmpWidths = null; for (i=0; i < rows.size(); i++) { if ( Table.class.isInstance(((Row) rows.get(i)).getCell(j)) ) { isTable=true; lDummyTable = ((Table) ((Row) rows.get(i)).getCell(j)); if( tmpWidths == null) { tmpWidths = lDummyTable.widths; lNewMaxColumns=tmpWidths.length; } else { int cols = lDummyTable.getDimension().width; float [] tmpWidthsN = new float[ cols * tmpWidths.length]; float tpW=0, btW=0, totW=0; int tpI=0, btI=0, totI=0; tpW+=tmpWidths[0]; btW+=lDummyTable.widths[0]; while( tpItpW) { tmpWidthsN[totI] = tpW-totW; tpI++; if(tpI lNewMaxColumns ) { lNewMaxColumns = lDummyTable.getDimension().width; lDummyColumnWidths[j] = lDummyTable.widths; // bugfix Tony Copping }*/ } } lDummyColumnWidths[j] = tmpWidths; lTotalColumns += lNewMaxColumns; lDummyWidths [j] = lNewMaxColumns; } // next we'll add new rows when needed for (i=0; i < rows.size(); i++) { lNewMaxRows = 1; // holds value in how many rows the current one will be split for (j=0; j < columns; j++) { if ( Table.class.isInstance(((Row) rows.get(i)).getCell(j)) ) { isTable=true; lDummyTable = (Table) ((Row) rows.get(i)).getCell(j); if ( lDummyTable.getDimension().height > lNewMaxRows ) { lNewMaxRows = lDummyTable.getDimension().height; } } } lTotalRows += lNewMaxRows; lDummyHeights [i] = lNewMaxRows; } if ( (lTotalColumns != columns) || (lTotalRows != rows.size()) || isTable) // NO ADJUSTMENT { // ** WIDTH // set correct width for new columns // divide width over new nr of columns // Take new max columns of internal table and work out widths for each col lNewWidths = new float [lTotalColumns]; int lDummy = 0; for (int tel=0; tel < widths.length;tel++) { if ( lDummyWidths[tel] != 1) { // divide for (int tel2 = 0; tel2 < lDummyWidths[tel]; tel2++) { // lNewWidths[lDummy] = widths[tel] / lDummyWidths[tel]; lNewWidths[lDummy] = widths[tel] * lDummyColumnWidths[tel][tel2] / 100f; // bugfix Tony Copping lDummy++; } } else { lNewWidths[lDummy] = widths[tel]; lDummy++; } } // ** FILL OUR NEW TABLE // generate new table // set new widths // copy old values newRows = new ArrayList(lTotalRows); for (i = 0; i < lTotalRows; i++) { newRows.add(new Row(lTotalColumns)); } int lDummyRow = 0, lDummyColumn = 0; // to remember where we are in the new, larger table Object lDummyElement = null; for (i=0; i < rows.size(); i++) { lDummyColumn = 0; lNewMaxRows = 1; for (j=0; j < columns; j++) { if ( Table.class.isInstance(((Row) rows.get(i)).getCell(j)) ) // copy values from embedded table { lDummyTable = (Table) ((Row) rows.get(i)).getCell(j); // Work out where columns in table table correspond to columns in current table int colMap[] = new int[lDummyTable.widths.length+1]; int cb=0, ct=0; for( ; cbCell's to empty/null spaces. */ private void fillEmptyMatrixCells() { try { for (int i=0; i < rows.size(); i++) { for (int j=0; j < columns; j++) { if (!((Row) rows.get(i)).isReserved(j)) { addCell(defaultCell, new Point(i, j)); } } } } catch(BadElementException bee) { throw new ExceptionConverter(bee); } } /** * check if Cell 'fits' the table. *

*

  • rowspan/colspan not beyond borders *
  • spanned cell don't overlap existing cells
* * @param aCell the cell that has to be checked * @param aLocation the location where the cell has to be placed * @return true if the location was valid */ private boolean isValidLocation(Cell aCell, Point aLocation) { // rowspan not beyond last column if ( aLocation.x < rows.size() ) // if false : new location is already at new, not-yet-created area so no check { if ((aLocation.y + aCell.getColspan()) > columns) { return false; } int difx = ((rows.size() - aLocation.x) > aCell.getRowspan()) ? aCell.getRowspan() : rows.size() - aLocation.x; int dify = ((columns - aLocation.y) > aCell.getColspan()) ? aCell.getColspan() : columns - aLocation.y; // no other content at cells targeted by rowspan/colspan for (int i=aLocation.x; i < (aLocation.x + difx); i++) { for (int j=aLocation.y; j < (aLocation.y + dify); j++) { if (((Row) rows.get(i)).isReserved(j)) { return false; } } } } else { if ((aLocation.y + aCell.getColspan()) > columns) { return false; } } return true; } /** * Sets the unset cell properties to be the table defaults. * * @param aCell The cell to set to table defaults as necessary. */ private void assumeTableDefaults(Cell aCell) { if (aCell.getBorder() == Rectangle.UNDEFINED) { aCell.setBorder(defaultCell.getBorder()); } if (aCell.getBorderWidth() == Rectangle.UNDEFINED) { aCell.setBorderWidth(defaultCell.getBorderWidth()); } if (aCell.getBorderColor() == null) { aCell.setBorderColor(defaultCell.getBorderColor()); } if (aCell.getBackgroundColor() == null) { aCell.setBackgroundColor(defaultCell.getBackgroundColor()); } if (aCell.getHorizontalAlignment() == Element.ALIGN_UNDEFINED) { aCell.setHorizontalAlignment(defaultCell.getHorizontalAlignment()); } if (aCell.getVerticalAlignment() == Element.ALIGN_UNDEFINED) { aCell.setVerticalAlignment(defaultCell.getVerticalAlignment()); } } /** * Inserts a Cell in a cell-array and reserves cells defined by row-/colspan. * * @param someRows some rows * @param aCell the cell that has to be inserted * @param aPosition the position where the cell has to be placed */ private void placeCell(ArrayList someRows, Cell aCell, Point aPosition) { int i; Row row = null; int rowCount = aPosition.x + aCell.getRowspan() - someRows.size(); assumeTableDefaults(aCell); if ( (aPosition.x + aCell.getRowspan()) > someRows.size() ) { for (i = 0; i < rowCount; i++) { row = new Row(columns); someRows.add(row); } } // reserve cell in rows below for (i = aPosition.x + 1; i < (aPosition.x + aCell.getRowspan()); i++) { if ( !((Row) someRows.get(i)).reserve(aPosition.y, aCell.getColspan())) { // should be impossible to come here :-) throw new RuntimeException("addCell - error in reserve"); } } row = (Row) someRows.get(aPosition.x); row.addElement(aCell, aPosition.y); } /** * Sets current col/row to valid(empty) pos after addCell/Table * @param aLocation a location in the Table */ private void setCurrentLocationToNextValidPosition(Point aLocation) { // set latest location to next valid position int i, j; i = aLocation.x; j = aLocation.y; do { if ( (j + 1) == columns ) { // goto next row i++; j = 0; } else { j++; } } while ( (i < rows.size()) && (j < columns) && (((Row) rows.get(i)).isReserved(j)) ); curPosition = new Point(i, j); } // public helper methods /** * Gets an array with the positions of the borders between every column. *

* This method translates the widths expressed in percentages into the * x-coordinate of the borders of the columns on a real document. * * @param left this is the position of the first border at the left (cellpadding not included) * @param totalWidth this is the space between the first border at the left * and the last border at the right (cellpadding not included) * @return an array with border positions */ public float[] getWidths(float left, float totalWidth) { // for x columns, there are x+1 borders float[] w = new float[columns + 1]; float wPercentage; if (locked) { wPercentage = 100 * width / totalWidth; } else { wPercentage = width; } // the border at the left is calculated switch(alignment) { case Element.ALIGN_LEFT: w[0] = left; break; case Element.ALIGN_RIGHT: w[0] = left + (totalWidth * (100 - wPercentage)) / 100; break; case Element.ALIGN_CENTER: default: w[0] = left + (totalWidth * (100 - wPercentage)) / 200; } // the total available width is changed totalWidth = (totalWidth * wPercentage) / 100; // the inner borders are calculated for (int i = 1; i < columns; i++) { w[i] = w[i - 1] + (widths[i - 1] * totalWidth / 100); } // the border at the right is calculated w[columns] = w[0] + totalWidth; return w; } /** * Gets an Iterator of all the Rows. * * @return an Iterator */ public Iterator iterator() { return rows.iterator(); } /** * Create a PdfPTable based on this Table object. * @return a PdfPTable object * @throws BadElementException */ public PdfPTable createPdfPTable() throws BadElementException { if (!convert2pdfptable) { throw new BadElementException("No error, just an old style table"); } setAutoFillEmptyCells(true); complete(); PdfPTable pdfptable = new PdfPTable(widths); pdfptable.setComplete(complete); if (isNotAddedYet()) pdfptable.setSkipFirstHeader(true); SimpleTable t_evt = new SimpleTable(); t_evt.cloneNonPositionParameters(this); t_evt.setCellspacing(cellspacing); pdfptable.setTableEvent(t_evt); pdfptable.setHeaderRows(lastHeaderRow + 1); pdfptable.setSplitLate(cellsFitPage); pdfptable.setKeepTogether(tableFitsPage); if (!Float.isNaN(offset)) { pdfptable.setSpacingBefore(offset); } pdfptable.setHorizontalAlignment(alignment); if (locked) { pdfptable.setTotalWidth(width); pdfptable.setLockedWidth(true); } else { pdfptable.setWidthPercentage(width); } Row row; for (Iterator iterator = iterator(); iterator.hasNext(); ) { row = (Row) iterator.next(); Element cell; PdfPCell pcell; for (int i = 0; i < row.getColumns(); i++) { if ((cell = (Element)row.getCell(i)) != null) { if (cell instanceof Table) { pcell = new PdfPCell(((Table)cell).createPdfPTable()); } else if (cell instanceof Cell) { pcell = ((Cell)cell).createPdfPCell(); pcell.setPadding(cellpadding + cellspacing / 2f); SimpleCell c_evt = new SimpleCell(SimpleCell.CELL); c_evt.cloneNonPositionParameters((Cell)cell); c_evt.setSpacing(cellspacing * 2f); pcell.setCellEvent(c_evt); } else { pcell = new PdfPCell(); } pdfptable.addCell(pcell); } } } return pdfptable; } /** * Indicates if this is the first time the section is added. * @since iText2.0.8 * @return true if the section wasn't added yet */ public boolean isNotAddedYet() { return notAddedYet; } /** * Sets the indication if the section was already added to * the document. * @since iText2.0.8 * @param notAddedYet */ public void setNotAddedYet(boolean notAddedYet) { this.notAddedYet = notAddedYet; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#flushContent() */ public void flushContent() { this.setNotAddedYet(false); ArrayList headerrows = new ArrayList(); for (int i = 0; i < getLastHeaderRow() + 1; i++) { headerrows.add(rows.get(i)); } rows = headerrows; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#isComplete() */ public boolean isComplete() { return complete; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#setComplete(boolean) */ public void setComplete(boolean complete) { this.complete = complete; } /** * Gets the default layout of the Table. * @return a cell with all the defaults * @deprecated As of iText 2.0.7, replaced by {@link #getDefaultCell()}, * scheduled for removal at 2.2.0 */ public Cell getDefaultLayout() { return getDefaultCell(); } /** * Sets the default layout of the Table to * the provided Cell * @param value a cell with all the defaults * @deprecated As of iText 2.0.7, replaced by {@link #setDefaultCell(Cell)}, * scheduled for removal at 2.2.0 */ public void setDefaultLayout(Cell value) { defaultCell = value; } } src/core/com/lowagie/text/TextElementArray.java100644 0 0 5754 11012562273 17227 0ustar 0 0 /* * $Id: TextElementArray.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright (c) 1999, 2000, 2001, 2002 Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * Interface for a text element to which other objects can be added. * * @see Phrase * @see Paragraph * @see Section * @see ListItem * @see Chapter * @see Anchor * @see Cell */ public interface TextElementArray extends Element { /** * Adds an object to the TextElementArray. * * @param o an object that has to be added * @return true if the addition succeeded; false otherwise */ public boolean add(Object o); }src/core/com/lowagie/text/Utilities.java100644 0 0 26345 11036112746 15766 0ustar 0 0 /* * $Id: Utilities.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.Hashtable; import java.util.Properties; import java.util.Set; import com.lowagie.text.pdf.PRTokeniser; /** * A collection of convenience methods that were present in many different iText * classes. */ public class Utilities { /** * Gets the keys of a Hashtable * * @param table * a Hashtable * @return the keyset of a Hashtable (or an empty set if table is null) */ public static Set getKeySet(Hashtable table) { return (table == null) ? Collections.EMPTY_SET : table.keySet(); } /** * Utility method to extend an array. * * @param original * the original array or null * @param item * the item to be added to the array * @return a new array with the item appended */ public static Object[][] addToArray(Object original[][], Object item[]) { if (original == null) { original = new Object[1][]; original[0] = item; return original; } else { Object original2[][] = new Object[original.length + 1][]; System.arraycopy(original, 0, original2, 0, original.length); original2[original.length] = item; return original2; } } /** * Checks for a true/false value of a key in a Properties object. * @param attributes * @param key * @return a true/false value of a key in a Properties object */ public static boolean checkTrueOrFalse(Properties attributes, String key) { return "true".equalsIgnoreCase(attributes.getProperty(key)); } /** * Unescapes an URL. All the "%xx" are replaced by the 'xx' hex char value. * @param src the url to unescape * @return the unescaped value */ public static String unEscapeURL(String src) { StringBuffer bf = new StringBuffer(); char[] s = src.toCharArray(); for (int k = 0; k < s.length; ++k) { char c = s[k]; if (c == '%') { if (k + 2 >= s.length) { bf.append(c); continue; } int a0 = PRTokeniser.getHex(s[k + 1]); int a1 = PRTokeniser.getHex(s[k + 2]); if (a0 < 0 || a1 < 0) { bf.append(c); continue; } bf.append((char)(a0 * 16 + a1)); k += 2; } else bf.append(c); } return bf.toString(); } /** * This method makes a valid URL from a given filename. *

* This method makes the conversion of this library from the JAVA 2 platform * to a JDK1.1.x-version easier. * * @param filename * a given filename * @return a valid URL * @throws MalformedURLException */ public static URL toURL(String filename) throws MalformedURLException { try { return new URL(filename); } catch (Exception e) { return new File(filename).toURI().toURL(); } } /** * This method is an alternative for the InputStream.skip() * -method that doesn't seem to work properly for big values of size * . * * @param is * the InputStream * @param size * the number of bytes to skip * @throws IOException */ static public void skip(InputStream is, int size) throws IOException { long n; while (size > 0) { n = is.skip(size); if (n <= 0) break; size -= n; } } /** * Measurement conversion from millimeters to points. * @param value a value in millimeters * @return a value in points * @since 2.1.2 */ public static final float millimetersToPoints(float value) { return inchesToPoints(millimetersToInches(value)); } /** * Measurement conversion from millimeters to inches. * @param value a value in millimeters * @return a value in inches * @since 2.1.2 */ public static final float millimetersToInches(float value) { return value / 25.4f; } /** * Measurement conversion from points to millimeters. * @param value a value in points * @return a value in millimeters * @since 2.1.2 */ public static final float pointsToMillimeters(float value) { return inchesToMillimeters(pointsToInches(value)); } /** * Measurement conversion from points to inches. * @param value a value in points * @return a value in inches * @since 2.1.2 */ public static final float pointsToInches(float value) { return value / 72f; } /** * Measurement conversion from inches to millimeters. * @param value a value in inches * @return a value in millimeters * @since 2.1.2 */ public static final float inchesToMillimeters(float value) { return value * 25.4f; } /** * Measurement conversion from inches to points. * @param value a value in inches * @return a value in points * @since 2.1.2 */ public static final float inchesToPoints(float value) { return value * 72f; } /** * Check if the value of a character belongs to a certain interval * that indicates it's the higher part of a surrogate pair. * @param c the character * @return true if the character belongs to the interval * @since 2.1.2 */ public static boolean isSurrogateHigh(char c) { return c >= '\ud800' && c <= '\udbff'; } /** * Check if the value of a character belongs to a certain interval * that indicates it's the lower part of a surrogate pair. * @param c the character * @return true if the character belongs to the interval * @since 2.1.2 */ public static boolean isSurrogateLow(char c) { return c >= '\udc00' && c <= '\udfff'; } /** * Checks if two subsequent characters in a String are * are the higher and the lower character in a surrogate * pair (and therefore eligible for conversion to a UTF 32 character). * @param text the String with the high and low surrogate characters * @param idx the index of the 'high' character in the pair * @return true if the characters are surrogate pairs * @since 2.1.2 */ public static boolean isSurrogatePair(String text, int idx) { if (idx < 0 || idx > text.length() - 2) return false; return isSurrogateHigh(text.charAt(idx)) && isSurrogateLow(text.charAt(idx + 1)); } /** * Checks if two subsequent characters in a character array are * are the higher and the lower character in a surrogate * pair (and therefore eligible for conversion to a UTF 32 character). * @param text the character array with the high and low surrogate characters * @param idx the index of the 'high' character in the pair * @return true if the characters are surrogate pairs * @since 2.1.2 */ public static boolean isSurrogatePair(char[] text, int idx) { if (idx < 0 || idx > text.length - 2) return false; return isSurrogateHigh(text[idx]) && isSurrogateLow(text[idx + 1]); } /** * Returns the code point of a UTF32 character corresponding with * a high and a low surrogate value. * @param highSurrogate the high surrogate value * @param lowSurrogate the low surrogate value * @return a code point value * @since 2.1.2 */ public static int convertToUtf32(char highSurrogate, char lowSurrogate) { return (((highSurrogate - 0xd800) * 0x400) + (lowSurrogate - 0xdc00)) + 0x10000; } /** * Converts a unicode character in a character array to a UTF 32 code point value. * @param text a character array that has the unicode character(s) * @param idx the index of the 'high' character * @return the code point value * @since 2.1.2 */ public static int convertToUtf32(char[] text, int idx) { return (((text[idx] - 0xd800) * 0x400) + (text[idx + 1] - 0xdc00)) + 0x10000; } /** * Converts a unicode character in a String to a UTF32 code point value * @param text a String that has the unicode character(s) * @param idx the index of the 'high' character * @return the codepoint value * @since 2.1.2 */ public static int convertToUtf32(String text, int idx) { return (((text.charAt(idx) - 0xd800) * 0x400) + (text.charAt(idx + 1) - 0xdc00)) + 0x10000; } /** * Converts a UTF32 code point value to a String with the corresponding character(s). * @param codePoint a Unicode value * @return the corresponding characters in a String * @since 2.1.2 */ public static String convertFromUtf32(int codePoint) { if (codePoint < 0x10000) return Character.toString((char)codePoint); codePoint -= 0x10000; return new String(new char[]{(char)((codePoint / 0x400) + 0xd800), (char)((codePoint % 0x400) + 0xdc00)}); } } src/core/com/lowagie/text/ZapfDingbatsList.java100644 0 0 10522 11000354131 17174 0ustar 0 0 /* * Copyright 2003 by Michael Niedermair. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * * A special-version of LIST which use zapfdingbats-letters. * * @see com.lowagie.text.List * @author Michael Niedermair and Bruno Lowagie */ public class ZapfDingbatsList extends List { /** * char-number in zapfdingbats */ protected int zn; /** * Creates a ZapfDingbatsList * * @param zn a char-number */ public ZapfDingbatsList(int zn) { super(true); this.zn = zn; float fontsize = symbol.getFont().getSize(); symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL)); postSymbol = " "; } /** * Creates a ZapfDingbatsList * * @param zn a char-number * @param symbolIndent indent */ public ZapfDingbatsList(int zn, int symbolIndent) { super(true, symbolIndent); this.zn = zn; float fontsize = symbol.getFont().getSize(); symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL)); postSymbol = " "; } /** * set the char-number * @param zn a char-number */ public void setCharNumber(int zn) { this.zn = zn; } /** * get the char-number * * @return char-number */ public int getCharNumber() { return zn; } /** * Adds an Object to the List. * * @param o the object to add. * @return true if adding the object succeeded */ public boolean add(Object o) { if (o instanceof ListItem) { ListItem item = (ListItem) o; Chunk chunk = new Chunk(preSymbol, symbol.getFont()); chunk.append(String.valueOf((char)zn)); chunk.append(postSymbol); item.setListSymbol(chunk); item.setIndentationLeft(symbolIndent, autoindent); item.setIndentationRight(0); list.add(item); } else if (o instanceof List) { List nested = (List) o; nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent); first--; return list.add(nested); } else if (o instanceof String) { return this.add(new ListItem((String) o)); } return false; } } src/core/com/lowagie/text/ZapfDingbatsNumberList.java100644 0 0 11267 11000354131 20354 0ustar 0 0 /* * Copyright 2003 by Michael Niedermair. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text; /** * * A special-version of LIST which use zapfdingbats-numbers (1..10). * * @see com.lowagie.text.List * @author Michael Niedermair and Bruno Lowagie */ public class ZapfDingbatsNumberList extends List { /** * which type */ protected int type; /** * Creates a ZapdDingbatsNumberList * @param type the type of list */ public ZapfDingbatsNumberList(int type) { super(true); this.type = type; float fontsize = symbol.getFont().getSize(); symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL)); postSymbol = " "; } /** * Creates a ZapdDingbatsNumberList * @param type the type of list * @param symbolIndent indent */ public ZapfDingbatsNumberList(int type, int symbolIndent) { super(true, symbolIndent); this.type = type; float fontsize = symbol.getFont().getSize(); symbol.setFont(FontFactory.getFont(FontFactory.ZAPFDINGBATS, fontsize, Font.NORMAL)); postSymbol = " "; } /** * set the type * * @param type */ public void setType(int type) { this.type = type; } /** * get the type * * @return char-number */ public int getType() { return type; } /** * Adds an Object to the List. * * @param o the object to add. * @return true if adding the object succeeded */ public boolean add(Object o) { if (o instanceof ListItem) { ListItem item = (ListItem) o; Chunk chunk = new Chunk(preSymbol, symbol.getFont()); switch (type ) { case 0: chunk.append(String.valueOf((char)(first + list.size() + 171))); break; case 1: chunk.append(String.valueOf((char)(first + list.size() + 181))); break; case 2: chunk.append(String.valueOf((char)(first + list.size() + 191))); break; default: chunk.append(String.valueOf((char)(first + list.size() + 201))); } chunk.append(postSymbol); item.setListSymbol(chunk); item.setIndentationLeft(symbolIndent, autoindent); item.setIndentationRight(0); list.add(item); } else if (o instanceof List) { List nested = (List) o; nested.setIndentationLeft(nested.getIndentationLeft() + symbolIndent); first--; return list.add(nested); } else if (o instanceof String) { return this.add(new ListItem((String) o)); } return false; } } src/core/com/lowagie/text/apache_license.txt100644 0 0 26411 11000354131 16611 0ustar 0 0 Some files use code from different Apache projects. The source code of these files contains the appropriate copyright notices as described in the Appendix of http://www.apache.org/licenses/LICENSE-2.0 This is a copy of the text that can be found at that specific URL: Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: * You must give any other recipients of the Work or Derivative Works a copy of this License; and * You must cause any modified files to carry prominent notices stating that You changed the files; and * You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and * If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.src/core/com/lowagie/text/exceptions/BadPasswordException.java100644 0 0 6125 11154165264 22242 0ustar 0 0 /* * $Id: BadPasswordException.java 3665 2009-01-26 22:32:15Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.exceptions; import java.io.IOException; /** * Typed exception used when opening an existing PDF document. * Gets thrown when the document isn't a valid PDF document. * @since 2.1.5 It was written for iText 2.0.8, but moved to another package */ public class BadPasswordException extends IOException { /** Serial Version UID. */ private static final long serialVersionUID = -4333706268155063964L; /** * Creates an exception saying the user password was incorrect. */ public BadPasswordException(String message) { super(message); } } src/core/com/lowagie/text/exceptions/IllegalPdfSyntaxException.java100644 0 0 5776 11213370067 23251 0ustar 0 0 /* * $Id: IllegalPdfSyntaxException.java 3820 2009-03-25 10:30:01Z blowagie $ * * Copyright 2009 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.exceptions; /** * Typed exception used when creating PDF syntax that isn't valid. * @since 2.1.6 */ public class IllegalPdfSyntaxException extends IllegalArgumentException { /** Serial version ID */ private static final long serialVersionUID = -643024246596031671L; /** * Creates an exception saying the PDF syntax isn't correct. * @param message some extra info about the exception */ public IllegalPdfSyntaxException(String message) { super(message); } } src/core/com/lowagie/text/exceptions/InvalidPdfException.java100644 0 0 6103 11154165264 22045 0ustar 0 0 /* * $Id: InvalidPdfException.java 3665 2009-01-26 22:32:15Z xlv $ * * Copyright 2009 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.exceptions; import java.io.IOException; /** * Typed exception used when opening an existing PDF document. * Gets thrown when the document isn't a valid PDF document. * @since 2.1.5 */ public class InvalidPdfException extends IOException { /** a serial version UID */ private static final long serialVersionUID = -2319614911517026938L; /** * Creates an instance of a NoPdfException. * @param message the reason why the document isn't a PDF document according to iText. */ public InvalidPdfException(String message) { super(message); } } src/core/com/lowagie/text/exceptions/UnsupportedPdfException.java100644 0 0 6525 11154165264 23017 0ustar 0 0 /* * $Id: UnsupportedPdfException.java 3665 2009-01-26 22:32:15Z xlv $ * * Copyright 2009 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.exceptions; /** * Typed exception used when opening an existing PDF document. * Gets thrown when the document isn't a valid PDF document according to iText, * but it's different from the InvalidPdfException in the sense that it may * be an iText limitation (most of the times it isn't but you might have * bumped into something that has been added to the PDF specs, but that isn't * supported in iText yet). * @since 2.1.5 */ public class UnsupportedPdfException extends InvalidPdfException { /** a serial version UID */ private static final long serialVersionUID = 2180764250839096628L; /** * Creates an instance of an UnsupportedPdfException. * @param message the reason why the document isn't a PDF document according to iText. */ public UnsupportedPdfException(String message) { super(message); } } src/core/com/lowagie/text/factories/ElementFactory.java100644 0 0 46412 11036112743 20705 0ustar 0 0 /* * $Id: ElementFactory.java 3528 2008-07-07 14:46:09Z Howard_s $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.factories; import java.awt.Color; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Properties; import java.util.StringTokenizer; import com.lowagie.text.Anchor; import com.lowagie.text.Annotation; import com.lowagie.text.BadElementException; import com.lowagie.text.Cell; import com.lowagie.text.ChapterAutoNumber; import com.lowagie.text.Chunk; import com.lowagie.text.ElementTags; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.FontFactory; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.Section; import com.lowagie.text.Table; import com.lowagie.text.Utilities; import com.lowagie.text.html.Markup; /** * This class is able to create Element objects based on a list of properties. */ public class ElementFactory { /** * Creates a Chunk object based on a list of properties. * @param attributes * @return a Chunk */ public static Chunk getChunk(Properties attributes) { Chunk chunk = new Chunk(); chunk.setFont(FontFactory.getFont(attributes)); String value; value = attributes.getProperty(ElementTags.ITEXT); if (value != null) { chunk.append(value); } value = attributes.getProperty(ElementTags.LOCALGOTO); if (value != null) { chunk.setLocalGoto(value); } value = attributes.getProperty(ElementTags.REMOTEGOTO); if (value != null) { String page = attributes.getProperty(ElementTags.PAGE); if (page != null) { chunk.setRemoteGoto(value, Integer.parseInt(page)); } else { String destination = attributes .getProperty(ElementTags.DESTINATION); if (destination != null) { chunk.setRemoteGoto(value, destination); } } } value = attributes.getProperty(ElementTags.LOCALDESTINATION); if (value != null) { chunk.setLocalDestination(value); } value = attributes.getProperty(ElementTags.SUBSUPSCRIPT); if (value != null) { chunk.setTextRise(Float.parseFloat(value + "f")); } value = attributes.getProperty(Markup.CSS_KEY_VERTICALALIGN); if (value != null && value.endsWith("%")) { float p = Float.parseFloat(value.substring(0, value.length() - 1) + "f") / 100f; chunk.setTextRise(p * chunk.getFont().getSize()); } value = attributes.getProperty(ElementTags.GENERICTAG); if (value != null) { chunk.setGenericTag(value); } value = attributes.getProperty(ElementTags.BACKGROUNDCOLOR); if (value != null) { chunk.setBackground(Markup.decodeColor(value)); } return chunk; } /** * Creates a Phrase object based on a list of properties. * @param attributes * @return a Phrase */ public static Phrase getPhrase(Properties attributes) { Phrase phrase = new Phrase(); phrase.setFont(FontFactory.getFont(attributes)); String value; value = attributes.getProperty(ElementTags.LEADING); if (value != null) { phrase.setLeading(Float.parseFloat(value + "f")); } value = attributes.getProperty(Markup.CSS_KEY_LINEHEIGHT); if (value != null) { phrase.setLeading(Markup.parseLength(value, Markup.DEFAULT_FONT_SIZE)); } value = attributes.getProperty(ElementTags.ITEXT); if (value != null) { Chunk chunk = new Chunk(value); if ((value = attributes.getProperty(ElementTags.GENERICTAG)) != null) { chunk.setGenericTag(value); } phrase.add(chunk); } return phrase; } /** * Creates an Anchor object based on a list of properties. * @param attributes * @return an Anchor */ public static Anchor getAnchor(Properties attributes) { Anchor anchor = new Anchor(getPhrase(attributes)); String value; value = attributes.getProperty(ElementTags.NAME); if (value != null) { anchor.setName(value); } value = (String) attributes.remove(ElementTags.REFERENCE); if (value != null) { anchor.setReference(value); } return anchor; } /** * Creates a Paragraph object based on a list of properties. * @param attributes * @return a Paragraph */ public static Paragraph getParagraph(Properties attributes) { Paragraph paragraph = new Paragraph(getPhrase(attributes)); String value; value = attributes.getProperty(ElementTags.ALIGN); if (value != null) { paragraph.setAlignment(value); } value = attributes.getProperty(ElementTags.INDENTATIONLEFT); if (value != null) { paragraph.setIndentationLeft(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.INDENTATIONRIGHT); if (value != null) { paragraph.setIndentationRight(Float.parseFloat(value + "f")); } return paragraph; } /** * Creates a ListItem object based on a list of properties. * @param attributes * @return a ListItem */ public static ListItem getListItem(Properties attributes) { ListItem item = new ListItem(getParagraph(attributes)); return item; } /** * Creates a List object based on a list of properties. * @param attributes * @return the List */ public static List getList(Properties attributes) { List list = new List(); list.setNumbered(Utilities.checkTrueOrFalse(attributes, ElementTags.NUMBERED)); list.setLettered(Utilities.checkTrueOrFalse(attributes, ElementTags.LETTERED)); list.setLowercase(Utilities.checkTrueOrFalse(attributes, ElementTags.LOWERCASE)); list.setAutoindent(Utilities.checkTrueOrFalse(attributes, ElementTags.AUTO_INDENT_ITEMS)); list.setAlignindent(Utilities.checkTrueOrFalse(attributes, ElementTags.ALIGN_INDENTATION_ITEMS)); String value; value = attributes.getProperty(ElementTags.FIRST); if (value != null) { char character = value.charAt(0); if (Character.isLetter(character)) { list.setFirst(character); } else { list.setFirst(Integer.parseInt(value)); } } value = attributes.getProperty(ElementTags.LISTSYMBOL); if (value != null) { list .setListSymbol(new Chunk(value, FontFactory .getFont(attributes))); } value = attributes.getProperty(ElementTags.INDENTATIONLEFT); if (value != null) { list.setIndentationLeft(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.INDENTATIONRIGHT); if (value != null) { list.setIndentationRight(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.SYMBOLINDENT); if (value != null) { list.setSymbolIndent(Float.parseFloat(value)); } return list; } /** * Creates a Cell object based on a list of properties. * @param attributes * @return a Cell */ public static Cell getCell(Properties attributes) { Cell cell = new Cell(); String value; cell.setHorizontalAlignment(attributes .getProperty(ElementTags.HORIZONTALALIGN)); cell.setVerticalAlignment(attributes .getProperty(ElementTags.VERTICALALIGN)); value = attributes.getProperty(ElementTags.WIDTH); if (value != null) { cell.setWidth(value); } value = attributes.getProperty(ElementTags.COLSPAN); if (value != null) { cell.setColspan(Integer.parseInt(value)); } value = attributes.getProperty(ElementTags.ROWSPAN); if (value != null) { cell.setRowspan(Integer.parseInt(value)); } value = attributes.getProperty(ElementTags.LEADING); if (value != null) { cell.setLeading(Float.parseFloat(value + "f")); } cell.setHeader(Utilities.checkTrueOrFalse(attributes, ElementTags.HEADER)); if (Utilities.checkTrueOrFalse(attributes, ElementTags.NOWRAP)) { cell.setMaxLines(1); } setRectangleProperties(cell, attributes); return cell; } /** * Creates an Table object based on a list of properties. * @param attributes * @return a Table */ public static Table getTable(Properties attributes) { String value; Table table; try { value = attributes.getProperty(ElementTags.WIDTHS); if (value != null) { StringTokenizer widthTokens = new StringTokenizer(value, ";"); ArrayList values = new ArrayList(); while (widthTokens.hasMoreTokens()) { values.add(widthTokens.nextToken()); } table = new Table(values.size()); float[] widths = new float[table.getColumns()]; for (int i = 0; i < values.size(); i++) { value = (String) values.get(i); widths[i] = Float.parseFloat(value + "f"); } table.setWidths(widths); } else { value = attributes.getProperty(ElementTags.COLUMNS); try { table = new Table(Integer.parseInt(value)); } catch (Exception e) { table = new Table(1); } } table.setBorder(Table.BOX); table.setBorderWidth(1); table.getDefaultCell().setBorder(Table.BOX); value = attributes.getProperty(ElementTags.LASTHEADERROW); if (value != null) { table.setLastHeaderRow(Integer.parseInt(value)); } value = attributes.getProperty(ElementTags.ALIGN); if (value != null) { table.setAlignment(value); } value = attributes.getProperty(ElementTags.CELLSPACING); if (value != null) { table.setSpacing(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.CELLPADDING); if (value != null) { table.setPadding(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.OFFSET); if (value != null) { table.setOffset(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.WIDTH); if (value != null) { if (value.endsWith("%")) table.setWidth(Float.parseFloat(value.substring(0, value .length() - 1) + "f")); else { table.setWidth(Float.parseFloat(value + "f")); table.setLocked(true); } } table.setTableFitsPage(Utilities.checkTrueOrFalse(attributes, ElementTags.TABLEFITSPAGE)); table.setCellsFitPage(Utilities.checkTrueOrFalse(attributes, ElementTags.CELLSFITPAGE)); table.setConvert2pdfptable(Utilities.checkTrueOrFalse(attributes, ElementTags.CONVERT2PDFP)); setRectangleProperties(table, attributes); return table; } catch (BadElementException e) { throw new ExceptionConverter(e); } } /** * Sets some Rectangle properties (for a Cell, Table,...). */ private static void setRectangleProperties(Rectangle rect, Properties attributes) { String value; value = attributes.getProperty(ElementTags.BORDERWIDTH); if (value != null) { rect.setBorderWidth(Float.parseFloat(value + "f")); } int border = 0; if (Utilities.checkTrueOrFalse(attributes, ElementTags.LEFT)) { border |= Rectangle.LEFT; } if (Utilities.checkTrueOrFalse(attributes, ElementTags.RIGHT)) { border |= Rectangle.RIGHT; } if (Utilities.checkTrueOrFalse(attributes, ElementTags.TOP)) { border |= Rectangle.TOP; } if (Utilities.checkTrueOrFalse(attributes, ElementTags.BOTTOM)) { border |= Rectangle.BOTTOM; } rect.setBorder(border); String r = attributes.getProperty(ElementTags.RED); String g = attributes.getProperty(ElementTags.GREEN); String b = attributes.getProperty(ElementTags.BLUE); if (r != null || g != null || b != null) { int red = 0; int green = 0; int blue = 0; if (r != null) red = Integer.parseInt(r); if (g != null) green = Integer.parseInt(g); if (b != null) blue = Integer.parseInt(b); rect.setBorderColor(new Color(red, green, blue)); } else { rect.setBorderColor(Markup.decodeColor(attributes .getProperty(ElementTags.BORDERCOLOR))); } r = (String) attributes.remove(ElementTags.BGRED); g = (String) attributes.remove(ElementTags.BGGREEN); b = (String) attributes.remove(ElementTags.BGBLUE); value = attributes.getProperty(ElementTags.BACKGROUNDCOLOR); if (r != null || g != null || b != null) { int red = 0; int green = 0; int blue = 0; if (r != null) red = Integer.parseInt(r); if (g != null) green = Integer.parseInt(g); if (b != null) blue = Integer.parseInt(b); rect.setBackgroundColor(new Color(red, green, blue)); } else if (value != null) { rect.setBackgroundColor(Markup.decodeColor(value)); } else { value = attributes.getProperty(ElementTags.GRAYFILL); if (value != null) { rect.setGrayFill(Float.parseFloat(value + "f")); } } } /** * Creates a ChapterAutoNumber object based on a list of properties. * @param attributes * @return a Chapter */ public static ChapterAutoNumber getChapter(Properties attributes) { ChapterAutoNumber chapter = new ChapterAutoNumber(""); setSectionParameters(chapter, attributes); return chapter; } /** * Creates a Section object based on a list of properties. * @param attributes * @return a Section */ public static Section getSection(Section parent, Properties attributes) { Section section = parent.addSection(""); setSectionParameters(section, attributes); return section; } /** * Helper method to create a Chapter/Section object. * @param attributes */ private static void setSectionParameters(Section section, Properties attributes) { String value; value = attributes.getProperty(ElementTags.NUMBERDEPTH); if (value != null) { section.setNumberDepth(Integer.parseInt(value)); } value = attributes.getProperty(ElementTags.INDENT); if (value != null) { section.setIndentation(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.INDENTATIONLEFT); if (value != null) { section.setIndentationLeft(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.INDENTATIONRIGHT); if (value != null) { section.setIndentationRight(Float.parseFloat(value + "f")); } } /** * Creates an Image object based on a list of properties. * @param attributes * @return an Image */ public static Image getImage(Properties attributes) throws BadElementException, MalformedURLException, IOException { String value; value = attributes.getProperty(ElementTags.URL); if (value == null) throw new MalformedURLException("The URL of the image is missing."); Image image = Image.getInstance(value); value = attributes.getProperty(ElementTags.ALIGN); int align = 0; if (value != null) { if (ElementTags.ALIGN_LEFT.equalsIgnoreCase(value)) align |= Image.LEFT; else if (ElementTags.ALIGN_RIGHT.equalsIgnoreCase(value)) align |= Image.RIGHT; else if (ElementTags.ALIGN_MIDDLE.equalsIgnoreCase(value)) align |= Image.MIDDLE; } if ("true".equalsIgnoreCase(attributes .getProperty(ElementTags.UNDERLYING))) align |= Image.UNDERLYING; if ("true".equalsIgnoreCase(attributes .getProperty(ElementTags.TEXTWRAP))) align |= Image.TEXTWRAP; image.setAlignment(align); value = attributes.getProperty(ElementTags.ALT); if (value != null) { image.setAlt(value); } String x = attributes.getProperty(ElementTags.ABSOLUTEX); String y = attributes.getProperty(ElementTags.ABSOLUTEY); if ((x != null) && (y != null)) { image.setAbsolutePosition(Float.parseFloat(x + "f"), Float .parseFloat(y + "f")); } value = attributes.getProperty(ElementTags.PLAINWIDTH); if (value != null) { image.scaleAbsoluteWidth(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.PLAINHEIGHT); if (value != null) { image.scaleAbsoluteHeight(Float.parseFloat(value + "f")); } value = attributes.getProperty(ElementTags.ROTATION); if (value != null) { image.setRotation(Float.parseFloat(value + "f")); } return image; } /** * Creates an Annotation object based on a list of properties. * @param attributes * @return an Annotation */ public static Annotation getAnnotation(Properties attributes) { float llx = 0, lly = 0, urx = 0, ury = 0; String value; value = attributes.getProperty(ElementTags.LLX); if (value != null) { llx = Float.parseFloat(value + "f"); } value = attributes.getProperty(ElementTags.LLY); if (value != null) { lly = Float.parseFloat(value + "f"); } value = attributes.getProperty(ElementTags.URX); if (value != null) { urx = Float.parseFloat(value + "f"); } value = attributes.getProperty(ElementTags.URY); if (value != null) { ury = Float.parseFloat(value + "f"); } String title = attributes.getProperty(ElementTags.TITLE); String text = attributes.getProperty(ElementTags.CONTENT); if (title != null || text != null) { return new Annotation(title, text, llx, lly, urx, ury); } value = attributes.getProperty(ElementTags.URL); if (value != null) { return new Annotation(llx, lly, urx, ury, value); } value = attributes.getProperty(ElementTags.NAMED); if (value != null) { return new Annotation(llx, lly, urx, ury, Integer.parseInt(value)); } String file = attributes.getProperty(ElementTags.FILE); String destination = attributes.getProperty(ElementTags.DESTINATION); String page = (String) attributes.remove(ElementTags.PAGE); if (file != null) { if (destination != null) { return new Annotation(llx, lly, urx, ury, file, destination); } if (page != null) { return new Annotation(llx, lly, urx, ury, file, Integer .parseInt(page)); } } return new Annotation("", "", llx, lly, urx, ury); } }src/core/com/lowagie/text/factories/GreekAlphabetFactory.java100644 0 0 11616 11012562263 22010 0ustar 0 0 /* * $Id: GreekAlphabetFactory.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.factories; import com.lowagie.text.SpecialSymbol; /** * This class can produce String combinations representing a number built with * Greek letters (from alpha to omega, then alpha alpha, alpha beta, alpha gamma). * We are aware of the fact that the original Greek numbering is different; * See http://www.cogsci.indiana.edu/farg/harry/lan/grknum.htm#ancient * but this isn't implemented yet; the main reason being the fact that we * need a font that has the obsolete Greek characters qoppa and sampi. * * @since 2.0.7 (was called GreekNumberFactory in earlier versions) */ public class GreekAlphabetFactory { /** * Changes an int into a lower case Greek letter combination. * @param index the original number * @return the letter combination */ public static final String getString(int index) { return getString(index, true); } /** * Changes an int into a lower case Greek letter combination. * @param index the original number * @return the letter combination */ public static final String getLowerCaseString(int index) { return getString(index); } /** * Changes an int into a upper case Greek letter combination. * @param index the original number * @return the letter combination */ public static final String getUpperCaseString(int index) { return getString(index).toUpperCase(); } /** * Changes an int into a Greek letter combination. * @param index the original number * @return the letter combination */ public static final String getString(int index, boolean lowercase) { if (index < 1) return ""; index--; int bytes = 1; int start = 0; int symbols = 24; while(index >= symbols + start) { bytes++; start += symbols; symbols *= 24; } int c = index - start; char[] value = new char[bytes]; while(bytes > 0) { bytes--; value[bytes] = (char)(c % 24); if (value[bytes] > 16) value[bytes]++; value[bytes] += (lowercase ? 945 : 913); value[bytes] = SpecialSymbol.getCorrespondingSymbol(value[bytes]); c /= 24; } return String.valueOf(value); } /** * Test this class using this main method. */ public static void main(String[] args) { for (int i = 1; i < 1000; i++) { System.out.println(getString(i)); } } } src/core/com/lowagie/text/factories/RomanAlphabetFactory.java100644 0 0 10753 11012562263 22030 0ustar 0 0 /* * $Id: RomanAlphabetFactory.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.factories; /** * This class can produce String combinations representing a number. * "a" to "z" represent 1 to 26, "AA" represents 27, "AB" represents 28, * and so on; "ZZ" is followed by "AAA". */ public class RomanAlphabetFactory { /** * Translates a positive integer (not equal to zero) * into a String using the letters 'a' to 'z'; * 1 = a, 2 = b, ..., 26 = z, 27 = aa, 28 = ab,... */ public static final String getString(int index) { if (index < 1) throw new NumberFormatException( "You can't translate a negative number into an alphabetical value."); index--; int bytes = 1; int start = 0; int symbols = 26; while(index >= symbols + start) { bytes++; start += symbols; symbols *= 26; } int c = index - start; char[] value = new char[bytes]; while(bytes > 0) { value[--bytes] = (char)( 'a' + (c % 26)); c /= 26; } return new String(value); } /** * Translates a positive integer (not equal to zero) * into a String using the letters 'a' to 'z'; * 1 = a, 2 = b, ..., 26 = z, 27 = aa, 28 = ab,... */ public static final String getLowerCaseString(int index) { return getString(index); } /** * Translates a positive integer (not equal to zero) * into a String using the letters 'A' to 'Z'; * 1 = A, 2 = B, ..., 26 = Z, 27 = AA, 28 = AB,... */ public static final String getUpperCaseString(int index) { return getString(index).toUpperCase(); } /** * Translates a positive integer (not equal to zero) * into a String using the letters 'a' to 'z' * (a = 1, b = 2, ..., z = 26, aa = 27, ab = 28,...). */ public static final String getString(int index, boolean lowercase) { if (lowercase) { return getLowerCaseString(index); } else { return getUpperCaseString(index); } } /** * Test this class using this main method. */ public static void main(String[] args) { for (int i = 1; i < 32000; i++) { System.out.println(getString(i)); } } }src/core/com/lowagie/text/factories/RomanNumberFactory.java100644 0 0 13066 11012562263 21540 0ustar 0 0 /* * $Id: RomanNumberFactory.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.factories; /** * This class can produce String combinations representing a roman number. */ public class RomanNumberFactory { /** * Helper class for Roman Digits */ private static class RomanDigit { /** part of a roman number */ public char digit; /** value of the roman digit */ public int value; /** can the digit be used as a prefix */ public boolean pre; /** * Constructs a roman digit * @param digit the roman digit * @param value the value * @param pre can it be used as a prefix */ RomanDigit(char digit, int value, boolean pre) { this.digit = digit; this.value = value; this.pre = pre; } } /** * Array with Roman digits. */ private static final RomanDigit[] roman = { new RomanDigit('m', 1000, false), new RomanDigit('d', 500, false), new RomanDigit('c', 100, true), new RomanDigit('l', 50, false), new RomanDigit('x', 10, true), new RomanDigit('v', 5, false), new RomanDigit('i', 1, true) }; /** * Changes an int into a lower case roman number. * @param index the original number * @return the roman number (lower case) */ public static final String getString(int index) { StringBuffer buf = new StringBuffer(); // lower than 0 ? Add minus if (index < 0) { buf.append('-'); index = -index; } // greater than 3000 if (index > 3000) { buf.append('|'); buf.append(getString(index / 1000)); buf.append('|'); // remainder index = index - (index / 1000) * 1000; } // number between 1 and 3000 int pos = 0; while (true) { // loop over the array with values for m-d-c-l-x-v-i RomanDigit dig = roman[pos]; // adding as many digits as we can while (index >= dig.value) { buf.append(dig.digit); index -= dig.value; } // we have the complete number if (index <= 0) { break; } // look for the next digit that can be used in a special way int j = pos; while (!roman[++j].pre); // does the special notation apply? if (index + roman[j].value >= dig.value) { buf.append(roman[j].digit).append(dig.digit); index -= dig.value - roman[j].value; } pos++; } return buf.toString(); } /** * Changes an int into a lower case roman number. * @param index the original number * @return the roman number (lower case) */ public static final String getLowerCaseString(int index) { return getString(index); } /** * Changes an int into an upper case roman number. * @param index the original number * @return the roman number (lower case) */ public static final String getUpperCaseString(int index) { return getString(index).toUpperCase(); } /** * Changes an int into a roman number. * @param index the original number * @return the roman number (lower case) */ public static final String getString(int index, boolean lowercase) { if (lowercase) { return getLowerCaseString(index); } else { return getUpperCaseString(index); } } /** * Test this class using this main method. */ public static void main(String[] args) { for (int i = 1; i < 2000; i++) { System.out.println(getString(i)); } } }src/core/com/lowagie/text/html/HtmlEncoder.java100644 0 0 16400 11012562264 17150 0ustar 0 0 /* * $Id: HtmlEncoder.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.awt.Color; import com.lowagie.text.Element; /** * This class converts a String to the HTML-format of a String. *

* To convert the String, each character is examined: *

    *
  • ASCII-characters from 000 till 031 are represented as &#xxx;
    * (with xxx = the value of the character) *
  • ASCII-characters from 032 t/m 127 are represented by the character itself, except for: *
      *
    • '\n' becomes <BR>\n *
    • " becomes &quot; *
    • & becomes &amp; *
    • < becomes &lt; *
    • > becomes &gt; *
    *
  • ASCII-characters from 128 till 255 are represented as &#xxx;
    * (with xxx = the value of the character) *
*

* Example: *

 *    String htmlPresentation = HtmlEncoder.encode("Marie-Thérèse Sørensen");
 * 

* for more info: see O'Reilly; "HTML: The Definitive Guide" (page 164) * * @author mario.maccarini@ugent.be */ public final class HtmlEncoder { // membervariables /** List with the HTML translation of all the characters. */ private static final String[] htmlCode = new String[256]; static { for (int i = 0; i < 10; i++) { htmlCode[i] = "�" + i + ";"; } for (int i = 10; i < 32; i++) { htmlCode[i] = "�" + i + ";"; } for (int i = 32; i < 128; i++) { htmlCode[i] = String.valueOf((char)i); } // Special characters htmlCode['\t'] = "\t"; htmlCode['\n'] = "<" + HtmlTags.NEWLINE + " />\n"; htmlCode['\"'] = """; // double quote htmlCode['&'] = "&"; // ampersand htmlCode['<'] = "<"; // lower than htmlCode['>'] = ">"; // greater than for (int i = 128; i < 256; i++) { htmlCode[i] = "&#" + i + ";"; } } // constructors /** * This class will never be constructed. *

* HtmlEncoder only contains static methods. */ private HtmlEncoder () { } // methods /** * Converts a String to the HTML-format of this String. * * @param string The String to convert * @return a String */ public static String encode(String string) { int n = string.length(); char character; StringBuffer buffer = new StringBuffer(); // loop over all the characters of the String. for (int i = 0; i < n; i++) { character = string.charAt(i); // the Htmlcode of these characters are added to a StringBuffer one by one if (character < 256) { buffer.append(htmlCode[character]); } else { // Improvement posted by Joachim Eyrich buffer.append("&#").append((int)character).append(';'); } } return buffer.toString(); } /** * Converts a Color into a HTML representation of this Color. * * @param color the Color that has to be converted. * @return the HTML representation of this Color */ public static String encode(Color color) { StringBuffer buffer = new StringBuffer("#"); if (color.getRed() < 16) { buffer.append('0'); } buffer.append(Integer.toString(color.getRed(), 16)); if (color.getGreen() < 16) { buffer.append('0'); } buffer.append(Integer.toString(color.getGreen(), 16)); if (color.getBlue() < 16) { buffer.append('0'); } buffer.append(Integer.toString(color.getBlue(), 16)); return buffer.toString(); } /** * Translates the alignment value. * * @param alignment the alignment value * @return the translated value */ public static String getAlignment(int alignment) { switch(alignment) { case Element.ALIGN_LEFT: return HtmlTags.ALIGN_LEFT; case Element.ALIGN_CENTER: return HtmlTags.ALIGN_CENTER; case Element.ALIGN_RIGHT: return HtmlTags.ALIGN_RIGHT; case Element.ALIGN_JUSTIFIED: case Element.ALIGN_JUSTIFIED_ALL: return HtmlTags.ALIGN_JUSTIFIED; case Element.ALIGN_TOP: return HtmlTags.ALIGN_TOP; case Element.ALIGN_MIDDLE: return HtmlTags.ALIGN_MIDDLE; case Element.ALIGN_BOTTOM: return HtmlTags.ALIGN_BOTTOM; case Element.ALIGN_BASELINE: return HtmlTags.ALIGN_BASELINE; default: return ""; } } }src/core/com/lowagie/text/html/HtmlParser.java100644 0 0 14360 11012562264 17030 0ustar 0 0 /* * $Id: HtmlParser.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.lowagie.text.DocListener; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.xml.XmlParser; /** * This class can be used to parse some HTML files. */ public class HtmlParser extends XmlParser { /** * Constructs an HtmlParser. */ public HtmlParser() { super(); } /** * Parses a given file. * @param document the document the parser will write to * @param is the InputSource with the content */ public void go(DocListener document, InputSource is) { try { parser.parse(is, new SAXmyHtmlHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document the document the parser will write to * @param is the InputSource with the content */ public static void parse(DocListener document, InputSource is) { HtmlParser p = new HtmlParser(); p.go(document, is); } /** * Parses a given file. * @param document the document the parser will write to * @param file the file with the content */ public void go(DocListener document, String file) { try { parser.parse(file, new SAXmyHtmlHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document the document the parser will write to * @param file the file with the content */ public static void parse(DocListener document, String file) { HtmlParser p = new HtmlParser(); p.go(document, file); } /** * Parses a given file. * @param document the document the parser will write to * @param is the InputStream with the content */ public void go(DocListener document, InputStream is) { try { parser.parse(new InputSource(is), new SAXmyHtmlHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document the document the parser will write to * @param is the InputStream with the content */ public static void parse(DocListener document, InputStream is) { HtmlParser p = new HtmlParser(); p.go(document, new InputSource(is)); } /** * Parses a given file. * @param document the document the parser will write to * @param is the Reader with the content */ public void go(DocListener document, Reader is) { try { parser.parse(new InputSource(is), new SAXmyHtmlHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document the document the parser will write to * @param is the Reader with the content */ public static void parse(DocListener document, Reader is) { HtmlParser p = new HtmlParser(); p.go(document, new InputSource(is)); } }src/core/com/lowagie/text/html/HtmlPeer.java100644 0 0 7445 11012562264 16455 0ustar 0 0 /* * $Id: HtmlPeer.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.util.Properties; import org.xml.sax.Attributes; import com.lowagie.text.ElementTags; import com.lowagie.text.xml.XmlPeer; /** * This interface is implemented by the peer of all the iText objects. */ public class HtmlPeer extends XmlPeer { /** * Creates a XmlPeer. * * @param name * the iText name of the tag * @param alias * the Html name of the tag */ public HtmlPeer(String name, String alias) { super(name, alias.toLowerCase()); } /** * Sets an alias for an attribute. * * @param name * the iText tagname * @param alias * the custom tagname */ public void addAlias(String name, String alias) { attributeAliases.put(alias.toLowerCase(), name); } /** * @see com.lowagie.text.xml.XmlPeer#getAttributes(org.xml.sax.Attributes) */ public Properties getAttributes(Attributes attrs) { Properties attributes = new Properties(); attributes.putAll(attributeValues); if (defaultContent != null) { attributes.put(ElementTags.ITEXT, defaultContent); } if (attrs != null) { String attribute, value; for (int i = 0; i < attrs.getLength(); i++) { attribute = getName(attrs.getQName(i).toLowerCase()); value = attrs.getValue(i); attributes.setProperty(attribute, value); } } return attributes; } } src/core/com/lowagie/text/html/HtmlTagMap.java100644 0 0 24777 11036112743 16761 0ustar 0 0 /* * $Id: HtmlTagMap.java 3528 2008-07-07 14:46:09Z Howard_s $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.util.HashMap; import com.lowagie.text.ElementTags; import com.lowagie.text.FontFactory; /** * The Tags-class maps several XHTML-tags to iText-objects. */ public class HtmlTagMap extends HashMap { private static final long serialVersionUID = 5287430058473705350L; /** * Constructs an HtmlTagMap. */ public HtmlTagMap() { super(); HtmlPeer peer; peer = new HtmlPeer(ElementTags.ITEXT, HtmlTags.HTML); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.SPAN); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.CHUNK); peer.addAlias(ElementTags.FONT, HtmlTags.FONT); peer.addAlias(ElementTags.SIZE, HtmlTags.SIZE); peer.addAlias(ElementTags.COLOR, HtmlTags.COLOR); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.ANCHOR, HtmlTags.ANCHOR); peer.addAlias(ElementTags.NAME, HtmlTags.NAME); peer.addAlias(ElementTags.REFERENCE, HtmlTags.REFERENCE); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.PARAGRAPH); peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.DIV); peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[0]); peer.addValue(ElementTags.SIZE, "20"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[1]); peer.addValue(ElementTags.SIZE, "18"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[2]); peer.addValue(ElementTags.SIZE, "16"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[3]); peer.addValue(ElementTags.SIZE, "14"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[4]); peer.addValue(ElementTags.SIZE, "12"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PARAGRAPH, HtmlTags.H[5]); peer.addValue(ElementTags.SIZE, "10"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.LIST, HtmlTags.ORDEREDLIST); peer.addValue(ElementTags.NUMBERED, "true"); peer.addValue(ElementTags.SYMBOLINDENT, "20"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.LIST, HtmlTags.UNORDEREDLIST); peer.addValue(ElementTags.NUMBERED, "false"); peer.addValue(ElementTags.SYMBOLINDENT, "20"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.LISTITEM, HtmlTags.LISTITEM); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.I); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.EM); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.B); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.STRONG); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_BOLD); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.S); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_LINETHROUGH); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.CODE); peer.addValue(ElementTags.FONT, FontFactory.COURIER); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.VAR); peer.addValue(ElementTags.FONT, FontFactory.COURIER); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_ITALIC); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.PHRASE, HtmlTags.U); peer.addValue(ElementTags.STYLE, Markup.CSS_VALUE_UNDERLINE); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUP); peer.addValue(ElementTags.SUBSUPSCRIPT, "6.0"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.CHUNK, HtmlTags.SUB); peer.addValue(ElementTags.SUBSUPSCRIPT, "-6.0"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.HORIZONTALRULE, HtmlTags.HORIZONTALRULE); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.TABLE, HtmlTags.TABLE); peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); peer.addAlias(ElementTags.COLUMNS, HtmlTags.COLUMNS); peer.addAlias(ElementTags.CELLPADDING, HtmlTags.CELLPADDING); peer.addAlias(ElementTags.CELLSPACING, HtmlTags.CELLSPACING); peer.addAlias(ElementTags.BORDERWIDTH, HtmlTags.BORDERWIDTH); peer.addAlias(ElementTags.ALIGN, HtmlTags.ALIGN); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.ROW, HtmlTags.ROW); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.CELL, HtmlTags.CELL); peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN); peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN); peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP); peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN); peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN); peer.addValue(ElementTags.HEADER, "false"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.CELL, HtmlTags.HEADERCELL); peer.addAlias(ElementTags.WIDTH, HtmlTags.WIDTH); peer.addAlias(ElementTags.BACKGROUNDCOLOR, HtmlTags.BACKGROUNDCOLOR); peer.addAlias(ElementTags.BORDERCOLOR, HtmlTags.BORDERCOLOR); peer.addAlias(ElementTags.COLSPAN, HtmlTags.COLSPAN); peer.addAlias(ElementTags.ROWSPAN, HtmlTags.ROWSPAN); peer.addAlias(ElementTags.NOWRAP, HtmlTags.NOWRAP); peer.addAlias(ElementTags.HORIZONTALALIGN, HtmlTags.HORIZONTALALIGN); peer.addAlias(ElementTags.VERTICALALIGN, HtmlTags.VERTICALALIGN); peer.addValue(ElementTags.HEADER, "true"); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.IMAGE, HtmlTags.IMAGE); // peer.addAlias(ElementTags.URL, HtmlTags.URL); peer.addAlias(ElementTags.URL, ElementTags.SRC); // contributed by Lubos Strapko peer.addAlias(ElementTags.ALT, HtmlTags.ALT); peer.addAlias(ElementTags.PLAINWIDTH, HtmlTags.PLAINWIDTH); peer.addAlias(ElementTags.PLAINHEIGHT, HtmlTags.PLAINHEIGHT); put(peer.getAlias(), peer); peer = new HtmlPeer(ElementTags.NEWLINE, HtmlTags.NEWLINE); put(peer.getAlias(), peer); } /** * Checks if this is the root tag. * @param tag a tagvalue * @return true if tag is HTML or html */ public static boolean isHtml(String tag) { return HtmlTags.HTML.equalsIgnoreCase(tag); } /** * Checks if this is the head tag. * @param tag a tagvalue * @return true if tag is HEAD or head */ public static boolean isHead(String tag) { return HtmlTags.HEAD.equalsIgnoreCase(tag); } /** * Checks if this is the meta tag. * @param tag a tagvalue * @return true if tag is META or meta */ public static boolean isMeta(String tag) { return HtmlTags.META.equalsIgnoreCase(tag); } /** * Checks if this is the link tag. * @param tag a tagvalue * @return true if tag is LINK or link */ public static boolean isLink(String tag) { return HtmlTags.LINK.equalsIgnoreCase(tag); } /** * Checks if this is the title tag. * @param tag a tagvalue * @return true if tag is TITLE or title */ public static boolean isTitle(String tag) { return HtmlTags.TITLE.equalsIgnoreCase(tag); } /** * Checks if this is the root tag. * @param tag a tagvalue * @return true if tag is BODY or body */ public static boolean isBody(String tag) { return HtmlTags.BODY.equalsIgnoreCase(tag); } /** * Checks if this is a special tag. * @param tag a tagvalue * @return true if tag is a HTML, HEAD, META, LINK or BODY tag (case insensitive) */ public static boolean isSpecialTag(String tag) { return isHtml(tag) || isHead(tag) || isMeta(tag) || isLink(tag) || isBody(tag); } }src/core/com/lowagie/text/html/HtmlTags.java100644 0 0 24227 11036112743 16474 0ustar 0 0 /* * $Id: HtmlTags.java 3533 2008-07-07 21:27:13Z Howard_s $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; /** * A class that contains all the possible tagnames and their attributes. */ public class HtmlTags { /** the root tag. */ public static final String HTML = "html"; /** the head tag */ public static final String HEAD = "head"; /** This is a possible HTML attribute for the HEAD tag. */ public static final String CONTENT = "content"; /** the meta tag */ public static final String META = "meta"; /** attribute of the root tag */ public static final String SUBJECT = "subject"; /** attribute of the root tag */ public static final String KEYWORDS = "keywords"; /** attribute of the root tag */ public static final String AUTHOR = "author"; /** the title tag. */ public static final String TITLE = "title"; /** the script tag. */ public static final String SCRIPT = "script"; /** This is a possible HTML attribute for the SCRIPT tag. */ public static final String LANGUAGE = "language"; /** This is a possible value for the LANGUAGE attribute. */ public static final String JAVASCRIPT = "JavaScript"; /** the body tag. */ public static final String BODY = "body"; /** This is a possible HTML attribute for the BODY tag */ public static final String JAVASCRIPT_ONLOAD = "onLoad"; /** This is a possible HTML attribute for the BODY tag */ public static final String JAVASCRIPT_ONUNLOAD = "onUnLoad"; /** This is a possible HTML attribute for the BODY tag. */ public static final String TOPMARGIN = "topmargin"; /** This is a possible HTML attribute for the BODY tag. */ public static final String BOTTOMMARGIN = "bottommargin"; /** This is a possible HTML attribute for the BODY tag. */ public static final String LEFTMARGIN = "leftmargin"; /** This is a possible HTML attribute for the BODY tag. */ public static final String RIGHTMARGIN = "rightmargin"; // Phrases, Anchors, Lists and Paragraphs /** the chunk tag */ public static final String CHUNK = "font"; /** the phrase tag */ public static final String CODE = "code"; /** the phrase tag */ public static final String VAR = "var"; /** the anchor tag */ public static final String ANCHOR = "a"; /** the list tag */ public static final String ORDEREDLIST = "ol"; /** the list tag */ public static final String UNORDEREDLIST = "ul"; /** the listitem tag */ public static final String LISTITEM = "li"; /** the paragraph tag */ public static final String PARAGRAPH = "p"; /** attribute of anchor tag */ public static final String NAME = "name"; /** attribute of anchor tag */ public static final String REFERENCE = "href"; /** attribute of anchor tag */ public static final String[] H = new String[6]; static { H[0] = "h1"; H[1] = "h2"; H[2] = "h3"; H[3] = "h4"; H[4] = "h5"; H[5] = "h6"; } // Chunks /** attribute of the chunk tag */ public static final String FONT = "face"; /** attribute of the chunk tag */ public static final String SIZE = "point-size"; /** attribute of the chunk/table/cell tag */ public static final String COLOR = "color"; /** some phrase tag */ public static final String EM = "em"; /** some phrase tag */ public static final String I = "i"; /** some phrase tag */ public static final String STRONG = "strong"; /** some phrase tag */ public static final String B = "b"; /** some phrase tag */ public static final String S = "s"; /** some phrase tag */ public static final String U = "u"; /** some phrase tag */ public static final String SUB = "sub"; /** some phrase tag */ public static final String SUP = "sup"; /** the possible value of a tag */ public static final String HORIZONTALRULE = "hr"; // tables/cells /** the table tag */ public static final String TABLE = "table"; /** the cell tag */ public static final String ROW = "tr"; /** the cell tag */ public static final String CELL = "td"; /** attribute of the cell tag */ public static final String HEADERCELL = "th"; /** attribute of the table tag */ public static final String COLUMNS = "cols"; /** attribute of the table tag */ public static final String CELLPADDING = "cellpadding"; /** attribute of the table tag */ public static final String CELLSPACING = "cellspacing"; /** attribute of the cell tag */ public static final String COLSPAN = "colspan"; /** attribute of the cell tag */ public static final String ROWSPAN = "rowspan"; /** attribute of the cell tag */ public static final String NOWRAP = "nowrap"; /** attribute of the table/cell tag */ public static final String BORDERWIDTH = "border"; /** attribute of the table/cell tag */ public static final String WIDTH = "width"; /** attribute of the table/cell tag */ public static final String BACKGROUNDCOLOR = "bgcolor"; /** attribute of the table/cell tag */ public static final String BORDERCOLOR = "bordercolor"; /** attribute of paragraph/image/table tag */ public static final String ALIGN = "align"; /** attribute of chapter/section/paragraph/table/cell tag */ public static final String LEFT = "left"; /** attribute of chapter/section/paragraph/table/cell tag */ public static final String RIGHT = "right"; /** attribute of the cell tag */ public static final String HORIZONTALALIGN = "align"; /** attribute of the cell tag */ public static final String VERTICALALIGN = "valign"; /** attribute of the table/cell tag */ public static final String TOP = "top"; /** attribute of the table/cell tag */ public static final String BOTTOM = "bottom"; // Misc /** the image tag */ public static final String IMAGE = "img"; /** attribute of the image tag * @see com.lowagie.text.ElementTags#SRC */ public static final String URL = "src"; /** attribute of the image tag */ public static final String ALT = "alt"; /** attribute of the image tag */ public static final String PLAINWIDTH = "width"; /** attribute of the image tag */ public static final String PLAINHEIGHT = "height"; /** the newpage tag */ public static final String NEWLINE = "br"; // alignment attribute values /** the possible value of an alignment attribute */ public static final String ALIGN_LEFT = "Left"; /** the possible value of an alignment attribute */ public static final String ALIGN_CENTER = "Center"; /** the possible value of an alignment attribute */ public static final String ALIGN_RIGHT = "Right"; /** the possible value of an alignment attribute */ public static final String ALIGN_JUSTIFIED = "Justify"; /** the possible value of an alignment attribute */ public static final String ALIGN_TOP = "Top"; /** the possible value of an alignment attribute */ public static final String ALIGN_MIDDLE = "Middle"; /** the possible value of an alignment attribute */ public static final String ALIGN_BOTTOM = "Bottom"; /** the possible value of an alignment attribute */ public static final String ALIGN_BASELINE = "Baseline"; /** the possible value of an alignment attribute */ public static final String DEFAULT = "Default"; /** The DIV tag. */ public static final String DIV = "div"; /** The SPAN tag. */ public static final String SPAN = "span"; /** The LINK tag. */ public static final String LINK = "link"; /** This is a possible HTML attribute for the LINK tag. */ public static final String TEXT_CSS = "text/css"; /** This is a possible HTML attribute for the LINK tag. */ public static final String REL = "rel"; /** This is used for inline css style information */ public static final String STYLE = "style"; /** This is a possible HTML attribute for the LINK tag. */ public static final String TYPE = "type"; /** This is a possible HTML attribute. */ public static final String STYLESHEET = "stylesheet"; /** This is a possible HTML attribute for auto-formated * @since 2.1.3 */ public static final String PRE = "pre"; }src/core/com/lowagie/text/html/HtmlWriter.java100644 0 0 116576 11106243444 17104 0ustar 0 0 /* * $Id: HtmlWriter.java 3583 2008-08-12 00:00:09Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import java.util.EmptyStackException; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import java.util.Stack; import com.lowagie.text.Anchor; import com.lowagie.text.Annotation; import com.lowagie.text.BadElementException; import com.lowagie.text.Cell; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Font; import com.lowagie.text.Header; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.MarkedObject; import com.lowagie.text.MarkedSection; import com.lowagie.text.Meta; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.Row; import com.lowagie.text.Section; import com.lowagie.text.SimpleTable; import com.lowagie.text.Table; import com.lowagie.text.pdf.BaseFont; /** * A DocWriter class for HTML. *

* An HtmlWriter can be added as a DocListener * to a certain Document by getting an instance. * Every Element added to the original Document * will be written to the OutputStream of this HtmlWriter. *

* Example: *

 * // creation of the document with a certain size and certain margins
 * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
 * try {
 *    // this will write HTML to the Standard OutputStream
 *    HtmlWriter.getInstance(document, System.out);
 *    // this will write HTML to a file called text.html
 *    HtmlWriter.getInstance(document, new FileOutputStream("text.html"));
 *    // this will write HTML to for instance the OutputStream of a HttpServletResponse-object
 *    HtmlWriter.getInstance(document, response.getOutputStream());
 * }
 * catch(DocumentException de) {
 *    System.err.println(de.getMessage());
 * }
 * // this will close the document and all the OutputStreams listening to it
 * document.close();
 * 
*/ public class HtmlWriter extends DocWriter { // static membervariables (tags) /** This is a possible HTML-tag. */ public static final byte[] BEGINCOMMENT = getISOBytes(""); /** This is a possible HTML-tag. */ public static final String NBSP = " "; // membervariables /** This is the current font of the HTML. */ protected Stack currentfont = new Stack(); /** This is the standard font of the HTML. */ protected Font standardfont = new Font(); /** This is a path for images. */ protected String imagepath = null; /** Stores the page number. */ protected int pageN = 0; /** This is the textual part of a header */ protected HeaderFooter header = null; /** This is the textual part of the footer */ protected HeaderFooter footer = null; /** Store the markup properties of a MarkedObject. */ protected Properties markup = new Properties(); // constructor /** * Constructs a HtmlWriter. * * @param doc The Document that has to be written as HTML * @param os The OutputStream the writer has to write to. */ protected HtmlWriter(Document doc, OutputStream os) { super(doc, os); document.addDocListener(this); this.pageN = document.getPageNumber(); try { os.write(LT); os.write(getISOBytes(HtmlTags.HTML)); os.write(GT); os.write(NEWLINE); os.write(TAB); os.write(LT); os.write(getISOBytes(HtmlTags.HEAD)); os.write(GT); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } // get an instance of the HtmlWriter /** * Gets an instance of the HtmlWriter. * * @param document The Document that has to be written * @param os The OutputStream the writer has to write to. * @return a new HtmlWriter */ public static HtmlWriter getInstance(Document document, OutputStream os) { return new HtmlWriter(document, os); } // implementation of the DocListener methods /** * Signals that an new page has to be started. * * @return true if this action succeeded, false if not. */ public boolean newPage() { try { writeStart(HtmlTags.DIV); write(" "); write(HtmlTags.STYLE); write("=\""); writeCssProperty(Markup.CSS_KEY_PAGE_BREAK_BEFORE, Markup.CSS_VALUE_ALWAYS); write("\" /"); os.write(GT); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } return true; } /** * Signals that an Element was added to the Document. * * @param element a high level object that has to be translated to HTML * @return true if the element was added, false if not. * @throws DocumentException when a document isn't open yet, or has been closed */ public boolean add(Element element) throws DocumentException { if (pause) { return false; } if (open && !element.isContent()) { throw new DocumentException( "The document is open; you can only add Elements with content."); } try { switch(element.type()) { case Element.HEADER: try { Header h = (Header) element; if (HtmlTags.STYLESHEET.equals(h.getName())) { writeLink(h); } else if (HtmlTags.JAVASCRIPT.equals(h.getName())) { writeJavaScript(h); } else { writeHeader(h); } } catch(ClassCastException cce) { } return true; case Element.SUBJECT: case Element.KEYWORDS: case Element.AUTHOR: Meta meta = (Meta) element; writeHeader(meta); return true; case Element.TITLE: addTabs(2); writeStart(HtmlTags.TITLE); os.write(GT); addTabs(3); write(HtmlEncoder.encode(((Meta)element).getContent())); addTabs(2); writeEnd(HtmlTags.TITLE); return true; case Element.CREATOR: writeComment("Creator: " + HtmlEncoder.encode(((Meta)element).getContent())); return true; case Element.PRODUCER: writeComment("Producer: " + HtmlEncoder.encode(((Meta)element).getContent())); return true; case Element.CREATIONDATE: writeComment("Creationdate: " + HtmlEncoder.encode(((Meta)element).getContent())); return true; case Element.MARKED: if (element instanceof MarkedSection) { MarkedSection ms = (MarkedSection)element; addTabs(1); writeStart(HtmlTags.DIV); writeMarkupAttributes(ms.getMarkupAttributes()); os.write(GT); MarkedObject mo = ((MarkedSection)element).getTitle(); if (mo != null) { markup = mo.getMarkupAttributes(); mo.process(this); } ms.process(this); writeEnd(HtmlTags.DIV); return true; } else { MarkedObject mo = (MarkedObject) element; markup = mo.getMarkupAttributes(); return mo.process(this); } default: write(element, 2); return true; } } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Signals that the Document has been opened and that * Elements can be added. *

* The HEAD-section of the HTML-document is written. */ public void open() { super.open(); try { writeComment(Document.getVersion()); writeComment("CreationDate: " + new Date().toString()); addTabs(1); writeEnd(HtmlTags.HEAD); addTabs(1); writeStart(HtmlTags.BODY); if (document.leftMargin() > 0) { write(HtmlTags.LEFTMARGIN, String.valueOf(document.leftMargin())); } if (document.rightMargin() > 0) { write(HtmlTags.RIGHTMARGIN, String.valueOf(document.rightMargin())); } if (document.topMargin() > 0) { write(HtmlTags.TOPMARGIN, String.valueOf(document.topMargin())); } if (document.bottomMargin() > 0) { write(HtmlTags.BOTTOMMARGIN, String.valueOf(document.bottomMargin())); } if (pageSize.getBackgroundColor() != null) { write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(pageSize.getBackgroundColor())); } if (document.getJavaScript_onLoad() != null) { write(HtmlTags.JAVASCRIPT_ONLOAD, HtmlEncoder.encode(document.getJavaScript_onLoad())); } if (document.getJavaScript_onUnLoad() != null) { write(HtmlTags.JAVASCRIPT_ONUNLOAD, HtmlEncoder.encode(document.getJavaScript_onUnLoad())); } if (document.getHtmlStyleClass() != null) { write(Markup.HTML_ATTR_CSS_CLASS, document.getHtmlStyleClass()); } os.write(GT); initHeader(); // line added by David Freels } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Signals that the Document was closed and that no other * Elements will be added. */ public void close() { try { initFooter(); // line added by David Freels addTabs(1); writeEnd(HtmlTags.BODY); os.write(NEWLINE); writeEnd(HtmlTags.HTML); super.close(); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } // some protected methods /** * Adds the header to the top of the Document */ protected void initHeader() { if (header != null) { try { add(header.paragraph()); } catch(Exception e) { throw new ExceptionConverter(e); } } } /** * Adds the header to the top of the Document */ protected void initFooter() { if (footer != null) { try { // Set the page number. HTML has no notion of a page, so it should always // add up to 1 footer.setPageNumber(pageN + 1); add(footer.paragraph()); } catch(Exception e) { throw new ExceptionConverter(e); } } } /** * Writes a Metatag in the header. * * @param meta the element that has to be written * @throws IOException */ protected void writeHeader(Meta meta) throws IOException { addTabs(2); writeStart(HtmlTags.META); switch(meta.type()) { case Element.HEADER: write(HtmlTags.NAME, ((Header) meta).getName()); break; case Element.SUBJECT: write(HtmlTags.NAME, HtmlTags.SUBJECT); break; case Element.KEYWORDS: write(HtmlTags.NAME, HtmlTags.KEYWORDS); break; case Element.AUTHOR: write(HtmlTags.NAME, HtmlTags.AUTHOR); break; } write(HtmlTags.CONTENT, HtmlEncoder.encode(meta.getContent())); writeEnd(); } /** * Writes a link in the header. * * @param header the element that has to be written * @throws IOException */ protected void writeLink(Header header) throws IOException { addTabs(2); writeStart(HtmlTags.LINK); write(HtmlTags.REL, header.getName()); write(HtmlTags.TYPE, HtmlTags.TEXT_CSS); write(HtmlTags.REFERENCE, header.getContent()); writeEnd(); } /** * Writes a JavaScript section or, if the markup attribute HtmlTags.URL is set, a JavaScript reference in the header. * * @param header the element that has to be written * @throws IOException */ protected void writeJavaScript(Header header) throws IOException { addTabs(2); writeStart(HtmlTags.SCRIPT); write(HtmlTags.LANGUAGE, HtmlTags.JAVASCRIPT); if (markup.size() > 0) { /* JavaScript reference example: * * */ write(HtmlTags.TYPE, Markup.HTML_VALUE_JAVASCRIPT); os.write(GT); addTabs(2); write(new String(BEGINCOMMENT) + "\n"); write(header.getContent()); addTabs(2); write("//" + new String(ENDCOMMENT)); addTabs(2); writeEnd(HtmlTags.SCRIPT); } } /** * Writes some comment. *

* This method writes some comment. * * @param comment the comment that has to be written * @throws IOException */ protected void writeComment(String comment) throws IOException { addTabs(2); os.write(BEGINCOMMENT); write(comment); os.write(ENDCOMMENT); } // public methods /** * Changes the standardfont. * * @param standardfont The font */ public void setStandardFont(Font standardfont) { this.standardfont = standardfont; } /** * Checks if a given font is the same as the font that was last used. * * @param font the font of an object * @return true if the font differs */ public boolean isOtherFont(Font font) { try { Font cFont = (Font) currentfont.peek(); if (cFont.compareTo(font) == 0) return false; return true; } catch(EmptyStackException ese) { if (standardfont.compareTo(font) == 0) return false; return true; } } /** * Sets the basepath for images. *

* This is especially useful if you add images using a file, * rather than an URL. In PDF there is no problem, since * the images are added inline, but in HTML it is sometimes * necessary to use a relative path or a special path to some * images directory. * * @param imagepath the new imagepath */ public void setImagepath(String imagepath) { this.imagepath = imagepath; } /** * Resets the imagepath. */ public void resetImagepath() { imagepath = null; } /** * Changes the header of this document. * * @param header the new header */ public void setHeader(HeaderFooter header) { this.header = header; } /** * Changes the footer of this document. * * @param footer the new footer */ public void setFooter(HeaderFooter footer) { this.footer = footer; } /** * Signals that a String was added to the Document. * * @param string a String to add to the HTML * @return true if the string was added, false if not. */ public boolean add(String string) { if (pause) { return false; } try { write(string); return true; } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Writes the HTML representation of an element. * * @param element the element * @param indent the indentation * @throws IOException */ protected void write(Element element, int indent) throws IOException { Properties styleAttributes = null; switch(element.type()) { case Element.MARKED: { try { add(element); } catch (DocumentException e) { e.printStackTrace(); } return; } case Element.CHUNK: { Chunk chunk = (Chunk) element; // if the chunk contains an image, return the image representation Image image = chunk.getImage(); if (image != null) { write(image, indent); return; } if (chunk.isEmpty()) return; HashMap attributes = chunk.getAttributes(); if (attributes != null && attributes.get(Chunk.NEWPAGE) != null) { return; } boolean tag = isOtherFont(chunk.getFont()) || markup.size() > 0; if (tag) { // start span tag addTabs(indent); writeStart(HtmlTags.SPAN); if (isOtherFont(chunk.getFont())) { write(chunk.getFont(), null); } writeMarkupAttributes(markup); os.write(GT); } if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) { // start sup or sub tag if (((Float)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) { writeStart(HtmlTags.SUP); } else { writeStart(HtmlTags.SUB); } os.write(GT); } // contents write(HtmlEncoder.encode(chunk.getContent())); if (attributes != null && attributes.get(Chunk.SUBSUPSCRIPT) != null) { // end sup or sub tag os.write(LT); os.write(FORWARD); if (((Float)attributes.get(Chunk.SUBSUPSCRIPT)).floatValue() > 0) { write(HtmlTags.SUP); } else { write(HtmlTags.SUB); } os.write(GT); } if (tag) { // end tag writeEnd(Markup.HTML_TAG_SPAN); } return; } case Element.PHRASE: { Phrase phrase = (Phrase) element; styleAttributes = new Properties(); if (phrase.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, phrase.getLeading() + "pt"); // start tag addTabs(indent); writeStart(Markup.HTML_TAG_SPAN); writeMarkupAttributes(markup); write(phrase.getFont(), styleAttributes); os.write(GT); currentfont.push(phrase.getFont()); // contents for (Iterator i = phrase.iterator(); i.hasNext(); ) { write((Element) i.next(), indent + 1); } // end tag addTabs(indent); writeEnd(Markup.HTML_TAG_SPAN); currentfont.pop(); return; } case Element.ANCHOR: { Anchor anchor = (Anchor) element; styleAttributes = new Properties(); if (anchor.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, anchor.getLeading() + "pt"); // start tag addTabs(indent); writeStart(HtmlTags.ANCHOR); if (anchor.getName() != null) { write(HtmlTags.NAME, anchor.getName()); } if (anchor.getReference() != null) { write(HtmlTags.REFERENCE, anchor.getReference()); } writeMarkupAttributes(markup); write(anchor.getFont(), styleAttributes); os.write(GT); currentfont.push(anchor.getFont()); // contents for (Iterator i = anchor.iterator(); i.hasNext(); ) { write((Element) i.next(), indent + 1); } // end tag addTabs(indent); writeEnd(HtmlTags.ANCHOR); currentfont.pop(); return; } case Element.PARAGRAPH: { Paragraph paragraph = (Paragraph) element; styleAttributes = new Properties(); if (paragraph.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, paragraph.getTotalLeading() + "pt"); // start tag addTabs(indent); writeStart(HtmlTags.DIV); writeMarkupAttributes(markup); String alignment = HtmlEncoder.getAlignment(paragraph.getAlignment()); if (!"".equals(alignment)) { write(HtmlTags.ALIGN, alignment); } write(paragraph.getFont(), styleAttributes); os.write(GT); currentfont.push(paragraph.getFont()); // contents for (Iterator i = paragraph.iterator(); i.hasNext(); ) { write((Element)i.next(), indent + 1); } // end tag addTabs(indent); writeEnd(HtmlTags.DIV); currentfont.pop(); return; } case Element.SECTION: case Element.CHAPTER: { // part of the start tag + contents writeSection((Section) element, indent); return; } case Element.LIST: { List list = (List) element; // start tag addTabs(indent); if (list.isNumbered()) { writeStart(HtmlTags.ORDEREDLIST); } else { writeStart(HtmlTags.UNORDEREDLIST); } writeMarkupAttributes(markup); os.write(GT); // contents for (Iterator i = list.getItems().iterator(); i.hasNext(); ) { write((Element) i.next(), indent + 1); } // end tag addTabs(indent); if (list.isNumbered()) { writeEnd(HtmlTags.ORDEREDLIST); } else { writeEnd(HtmlTags.UNORDEREDLIST); } return; } case Element.LISTITEM: { ListItem listItem = (ListItem) element; styleAttributes = new Properties(); if (listItem.hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, listItem.getTotalLeading() + "pt"); // start tag addTabs(indent); writeStart(HtmlTags.LISTITEM); writeMarkupAttributes(markup); write(listItem.getFont(), styleAttributes); os.write(GT); currentfont.push(listItem.getFont()); // contents for (Iterator i = listItem.iterator(); i.hasNext(); ) { write((Element) i.next(), indent + 1); } // end tag addTabs(indent); writeEnd(HtmlTags.LISTITEM); currentfont.pop(); return; } case Element.CELL: { Cell cell = (Cell) element; // start tag addTabs(indent); if (cell.isHeader()) { writeStart(HtmlTags.HEADERCELL); } else { writeStart(HtmlTags.CELL); } writeMarkupAttributes(markup); if (cell.getBorderWidth() != Rectangle.UNDEFINED) { write(HtmlTags.BORDERWIDTH, String.valueOf(cell.getBorderWidth())); } if (cell.getBorderColor() != null) { write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(cell.getBorderColor())); } if (cell.getBackgroundColor() != null) { write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(cell.getBackgroundColor())); } String alignment = HtmlEncoder.getAlignment(cell.getHorizontalAlignment()); if (!"".equals(alignment)) { write(HtmlTags.HORIZONTALALIGN, alignment); } alignment = HtmlEncoder.getAlignment(cell.getVerticalAlignment()); if (!"".equals(alignment)) { write(HtmlTags.VERTICALALIGN, alignment); } if (cell.getWidthAsString() != null) { write(HtmlTags.WIDTH, cell.getWidthAsString()); } if (cell.getColspan() != 1) { write(HtmlTags.COLSPAN, String.valueOf(cell.getColspan())); } if (cell.getRowspan() != 1) { write(HtmlTags.ROWSPAN, String.valueOf(cell.getRowspan())); } if (cell.getMaxLines() == 1) { write(HtmlTags.STYLE, "white-space: nowrap;"); } os.write(GT); // contents if (cell.isEmpty()) { write(NBSP); } else { for (Iterator i = cell.getElements(); i.hasNext(); ) { write((Element) i.next(), indent + 1); } } // end tag addTabs(indent); if (cell.isHeader()) { writeEnd(HtmlTags.HEADERCELL); } else { writeEnd(HtmlTags.CELL); } return; } case Element.ROW: { Row row = (Row) element; // start tag addTabs(indent); writeStart(HtmlTags.ROW); writeMarkupAttributes(markup); os.write(GT); // contents Element cell; for (int i = 0; i < row.getColumns(); i++) { if ((cell = (Element)row.getCell(i)) != null) { write(cell, indent + 1); } } // end tag addTabs(indent); writeEnd(HtmlTags.ROW); return; } case Element.TABLE: { Table table; try { table = (Table) element; } catch(ClassCastException cce) { try { table = ((SimpleTable)element).createTable(); } catch (BadElementException e) { throw new ExceptionConverter(e); } } table.complete(); // start tag addTabs(indent); writeStart(HtmlTags.TABLE); writeMarkupAttributes(markup); os.write(SPACE); write(HtmlTags.WIDTH); os.write(EQUALS); os.write(QUOTE); write(String.valueOf(table.getWidth())); if (!table.isLocked()){ write("%"); } os.write(QUOTE); String alignment = HtmlEncoder.getAlignment(table.getAlignment()); if (!"".equals(alignment)) { write(HtmlTags.ALIGN, alignment); } write(HtmlTags.CELLPADDING, String.valueOf(table.getPadding())); write(HtmlTags.CELLSPACING, String.valueOf(table.getSpacing())); if (table.getBorderWidth() != Rectangle.UNDEFINED) { write(HtmlTags.BORDERWIDTH, String.valueOf(table.getBorderWidth())); } if (table.getBorderColor() != null) { write(HtmlTags.BORDERCOLOR, HtmlEncoder.encode(table.getBorderColor())); } if (table.getBackgroundColor() != null) { write(HtmlTags.BACKGROUNDCOLOR, HtmlEncoder.encode(table.getBackgroundColor())); } os.write(GT); // contents Row row; for (Iterator iterator = table.iterator(); iterator.hasNext(); ) { row = (Row) iterator.next(); write(row, indent + 1); } // end tag addTabs(indent); writeEnd(HtmlTags.TABLE); return; } case Element.ANNOTATION: { Annotation annotation = (Annotation) element; writeComment(annotation.title() + ": " + annotation.content()); return; } case Element.IMGRAW: case Element.JPEG: case Element.JPEG2000: case Element.IMGTEMPLATE: { Image image = (Image) element; if (image.getUrl() == null) { return; } // start tag addTabs(indent); writeStart(HtmlTags.IMAGE); String path = image.getUrl().toString(); if (imagepath != null) { if (path.indexOf('/') > 0) { path = imagepath + path.substring(path.lastIndexOf('/') + 1); } else { path = imagepath + path; } } write(HtmlTags.URL, path); if ((image.getAlignment() & Image.RIGHT) > 0) { write(HtmlTags.ALIGN, HtmlTags.ALIGN_RIGHT); } else if ((image.getAlignment() & Image.MIDDLE) > 0) { write(HtmlTags.ALIGN, HtmlTags.ALIGN_MIDDLE); } else { write(HtmlTags.ALIGN, HtmlTags.ALIGN_LEFT); } if (image.getAlt() != null) { write(HtmlTags.ALT, image.getAlt()); } write(HtmlTags.PLAINWIDTH, String.valueOf(image.getScaledWidth())); write(HtmlTags.PLAINHEIGHT, String.valueOf(image.getScaledHeight())); writeMarkupAttributes(markup); writeEnd(); return; } default: return; } } /** * Writes the HTML representation of a section. * * @param section the section to write * @param indent the indentation * @throws IOException */ protected void writeSection(Section section, int indent) throws IOException { if (section.getTitle() != null) { int depth = section.getDepth() - 1; if (depth > 5) { depth = 5; } Properties styleAttributes = new Properties(); if (section.getTitle().hasLeading()) styleAttributes.setProperty(Markup.CSS_KEY_LINEHEIGHT, section.getTitle().getTotalLeading() + "pt"); // start tag addTabs(indent); writeStart(HtmlTags.H[depth]); write(section.getTitle().getFont(), styleAttributes); String alignment = HtmlEncoder.getAlignment(section.getTitle().getAlignment()); if (!"".equals(alignment)) { write(HtmlTags.ALIGN, alignment); } writeMarkupAttributes(markup); os.write(GT); currentfont.push(section.getTitle().getFont()); // contents for (Iterator i = section.getTitle().iterator(); i.hasNext(); ) { write((Element)i.next(), indent + 1); } // end tag addTabs(indent); writeEnd(HtmlTags.H[depth]); currentfont.pop(); } for (Iterator i = section.iterator(); i.hasNext(); ) { write((Element) i.next(), indent); } } /** * Writes the representation of a Font. * * @param font a Font * @param styleAttributes the style of the font * @throws IOException */ protected void write(Font font, Properties styleAttributes) throws IOException { if (font == null || !isOtherFont(font) /* || styleAttributes == null*/) return; write(" "); write(HtmlTags.STYLE); write("=\""); if (styleAttributes != null) { String key; for (Enumeration e = styleAttributes.propertyNames(); e.hasMoreElements(); ) { key = (String)e.nextElement(); writeCssProperty(key, styleAttributes.getProperty(key)); } } if (isOtherFont(font)) { writeCssProperty(Markup.CSS_KEY_FONTFAMILY, font.getFamilyname()); if (font.getSize() != Font.UNDEFINED) { writeCssProperty(Markup.CSS_KEY_FONTSIZE, font.getSize() + "pt"); } if (font.getColor() != null) { writeCssProperty(Markup.CSS_KEY_COLOR, HtmlEncoder.encode(font.getColor())); } int fontstyle = font.getStyle(); BaseFont bf = font.getBaseFont(); if (bf != null) { String ps = bf.getPostscriptFontName().toLowerCase(); if (ps.indexOf("bold") >= 0) { if (fontstyle == Font.UNDEFINED) fontstyle = 0; fontstyle |= Font.BOLD; } if (ps.indexOf("italic") >= 0 || ps.indexOf("oblique") >= 0) { if (fontstyle == Font.UNDEFINED) fontstyle = 0; fontstyle |= Font.ITALIC; } } if (fontstyle != Font.UNDEFINED && fontstyle != Font.NORMAL) { switch (fontstyle & Font.BOLDITALIC) { case Font.BOLD: writeCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD); break; case Font.ITALIC: writeCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC); break; case Font.BOLDITALIC: writeCssProperty(Markup.CSS_KEY_FONTWEIGHT, Markup.CSS_VALUE_BOLD); writeCssProperty(Markup.CSS_KEY_FONTSTYLE, Markup.CSS_VALUE_ITALIC); break; } // CSS only supports one decoration tag so if both are specified // only one of the two will display if ((fontstyle & Font.UNDERLINE) > 0) { writeCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_UNDERLINE); } if ((fontstyle & Font.STRIKETHRU) > 0) { writeCssProperty(Markup.CSS_KEY_TEXTDECORATION, Markup.CSS_VALUE_LINETHROUGH); } } } write("\""); } /** * Writes out a CSS property. * @param prop a CSS property * @param value the value of the CSS property * @throws IOException */ protected void writeCssProperty(String prop, String value) throws IOException { write(new StringBuffer(prop).append(": ").append(value).append("; ").toString()); } }src/core/com/lowagie/text/html/Markup.java100644 0 0 35516 11154165264 16222 0ustar 0 0 /* * $Id: Markup.java 3654 2009-01-21 16:11:00Z blowagie $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.awt.Color; import java.util.Properties; import java.util.StringTokenizer; /** * A class that contains all the possible tagnames and their attributes. */ public class Markup { // iText specific /** the key for any tag */ public static final String ITEXT_TAG = "tag"; // HTML tags /** the markup for the body part of a file */ public static final String HTML_TAG_BODY = "body"; /** The DIV tag. */ public static final String HTML_TAG_DIV = "div"; /** This is a possible HTML-tag. */ public static final String HTML_TAG_LINK = "link"; /** The SPAN tag. */ public static final String HTML_TAG_SPAN = "span"; // HTML attributes /** the height attribute. */ public static final String HTML_ATTR_HEIGHT = "height"; /** the hyperlink reference attribute. */ public static final String HTML_ATTR_HREF = "href"; /** This is a possible HTML attribute for the LINK tag. */ public static final String HTML_ATTR_REL = "rel"; /** This is used for inline css style information */ public static final String HTML_ATTR_STYLE = "style"; /** This is a possible HTML attribute for the LINK tag. */ public static final String HTML_ATTR_TYPE = "type"; /** This is a possible HTML attribute. */ public static final String HTML_ATTR_STYLESHEET = "stylesheet"; /** the width attribute. */ public static final String HTML_ATTR_WIDTH = "width"; /** attribute for specifying externally defined CSS class */ public static final String HTML_ATTR_CSS_CLASS = "class"; /** The ID attribute. */ public static final String HTML_ATTR_CSS_ID = "id"; // HTML values /** This is a possible value for the language attribute (SCRIPT tag). */ public static final String HTML_VALUE_JAVASCRIPT = "text/javascript"; /** This is a possible HTML attribute for the LINK tag. */ public static final String HTML_VALUE_CSS = "text/css"; // CSS keys /** the CSS tag for background color */ public static final String CSS_KEY_BGCOLOR = "background-color"; /** the CSS tag for text color */ public static final String CSS_KEY_COLOR = "color"; /** CSS key that indicate the way something has to be displayed */ public static final String CSS_KEY_DISPLAY = "display"; /** the CSS tag for the font family */ public static final String CSS_KEY_FONTFAMILY = "font-family"; /** the CSS tag for the font size */ public static final String CSS_KEY_FONTSIZE = "font-size"; /** the CSS tag for the font style */ public static final String CSS_KEY_FONTSTYLE = "font-style"; /** the CSS tag for the font weight */ public static final String CSS_KEY_FONTWEIGHT = "font-weight"; /** the CSS tag for text decorations */ public static final String CSS_KEY_LINEHEIGHT = "line-height"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_MARGIN = "margin"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_MARGINLEFT = "margin-left"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_MARGINRIGHT = "margin-right"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_MARGINTOP = "margin-top"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_MARGINBOTTOM = "margin-bottom"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_PADDING = "padding"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_PADDINGLEFT = "padding-left"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_PADDINGRIGHT = "padding-right"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_PADDINGTOP = "padding-top"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_PADDINGBOTTOM = "padding-bottom"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERCOLOR = "border-color"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERWIDTH = "border-width"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERWIDTHLEFT = "border-left-width"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERWIDTHRIGHT = "border-right-width"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERWIDTHTOP = "border-top-width"; /** the CSS tag for the margin of an object */ public static final String CSS_KEY_BORDERWIDTHBOTTOM = "border-bottom-width"; /** the CSS tag for adding a page break when the document is printed */ public static final String CSS_KEY_PAGE_BREAK_AFTER = "page-break-after"; /** the CSS tag for adding a page break when the document is printed */ public static final String CSS_KEY_PAGE_BREAK_BEFORE = "page-break-before"; /** the CSS tag for the horizontal alignment of an object */ public static final String CSS_KEY_TEXTALIGN = "text-align"; /** the CSS tag for text decorations */ public static final String CSS_KEY_TEXTDECORATION = "text-decoration"; /** the CSS tag for text decorations */ public static final String CSS_KEY_VERTICALALIGN = "vertical-align"; /** the CSS tag for the visibility of objects */ public static final String CSS_KEY_VISIBILITY = "visibility"; // CSS values /** * value for the CSS tag for adding a page break when the document is * printed */ public static final String CSS_VALUE_ALWAYS = "always"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_BLOCK = "block"; /** a CSS value for text font weight */ public static final String CSS_VALUE_BOLD = "bold"; /** the value if you want to hide objects. */ public static final String CSS_VALUE_HIDDEN = "hidden"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_INLINE = "inline"; /** a CSS value for text font style */ public static final String CSS_VALUE_ITALIC = "italic"; /** a CSS value for text decoration */ public static final String CSS_VALUE_LINETHROUGH = "line-through"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_LISTITEM = "list-item"; /** a CSS value */ public static final String CSS_VALUE_NONE = "none"; /** a CSS value */ public static final String CSS_VALUE_NORMAL = "normal"; /** a CSS value for text font style */ public static final String CSS_VALUE_OBLIQUE = "oblique"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_TABLE = "table"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_TABLEROW = "table-row"; /** A possible value for the DISPLAY key */ public static final String CSS_VALUE_TABLECELL = "table-cell"; /** the CSS value for a horizontal alignment of an object */ public static final String CSS_VALUE_TEXTALIGNLEFT = "left"; /** the CSS value for a horizontal alignment of an object */ public static final String CSS_VALUE_TEXTALIGNRIGHT = "right"; /** the CSS value for a horizontal alignment of an object */ public static final String CSS_VALUE_TEXTALIGNCENTER = "center"; /** the CSS value for a horizontal alignment of an object */ public static final String CSS_VALUE_TEXTALIGNJUSTIFY = "justify"; /** a CSS value for text decoration */ public static final String CSS_VALUE_UNDERLINE = "underline"; /** a default value for font-size * @since 2.1.3 */ public static final float DEFAULT_FONT_SIZE = 12f; /** * Parses a length. * * @param string * a length in the form of an optional + or -, followed by a * number and a unit. * @return a float */ public static float parseLength(String string) { // TODO: Evaluate the effect of this. // It may change the default behavour of the methd if this is changed. // return parseLength(string, Markup.DEFAULT_FONT_SIZE); int pos = 0; int length = string.length(); boolean ok = true; while (ok && pos < length) { switch (string.charAt(pos)) { case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': pos++; break; default: ok = false; } } if (pos == 0) return 0f; if (pos == length) return Float.parseFloat(string + "f"); float f = Float.parseFloat(string.substring(0, pos) + "f"); string = string.substring(pos); // inches if (string.startsWith("in")) { return f * 72f; } // centimeters if (string.startsWith("cm")) { return (f / 2.54f) * 72f; } // millimeters if (string.startsWith("mm")) { return (f / 25.4f) * 72f; } // picas if (string.startsWith("pc")) { return f * 12f; } // default: we assume the length was measured in points return f; } /** * New method contributed by: Lubos Strapko * * @since 2.1.3 */ public static float parseLength(String string, float actualFontSize) { if (string == null) return 0f; int pos = 0; int length = string.length(); boolean ok = true; while (ok && pos < length) { switch (string.charAt(pos)) { case '+': case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': pos++; break; default: ok = false; } } if (pos == 0) return 0f; if (pos == length) return Float.parseFloat(string + "f"); float f = Float.parseFloat(string.substring(0, pos) + "f"); string = string.substring(pos); // inches if (string.startsWith("in")) { return f * 72f; } // centimeters if (string.startsWith("cm")) { return (f / 2.54f) * 72f; } // millimeters if (string.startsWith("mm")) { return (f / 25.4f) * 72f; } // picas if (string.startsWith("pc")) { return f * 12f; } // 1em is equal to the current font size if (string.startsWith("em")) { return f * actualFontSize; } // one ex is the x-height of a font (x-height is usually about half the // font-size) if (string.startsWith("ex")) { return f * actualFontSize / 2; } // default: we assume the length was measured in points return f; } /** * Converts a Color into a HTML representation of this * Color. * * @param s * the Color that has to be converted. * @return the HTML representation of this Color */ public static Color decodeColor(String s) { if (s == null) return null; s = s.toLowerCase().trim(); try { return WebColors.getRGBColor(s); } catch(IllegalArgumentException iae) { return null; } } /** * This method parses a String with attributes and returns a Properties * object. * * @param string * a String of this form: 'key1="value1"; key2="value2";... * keyN="valueN" ' * @return a Properties object */ public static Properties parseAttributes(String string) { Properties result = new Properties(); if (string == null) return result; StringTokenizer keyValuePairs = new StringTokenizer(string, ";"); StringTokenizer keyValuePair; String key; String value; while (keyValuePairs.hasMoreTokens()) { keyValuePair = new StringTokenizer(keyValuePairs.nextToken(), ":"); if (keyValuePair.hasMoreTokens()) key = keyValuePair.nextToken().trim(); else continue; if (keyValuePair.hasMoreTokens()) value = keyValuePair.nextToken().trim(); else continue; if (value.startsWith("\"")) value = value.substring(1); if (value.endsWith("\"")) value = value.substring(0, value.length() - 1); result.setProperty(key.toLowerCase(), value); } return result; } /** * Removes the comments sections of a String. * * @param string * the original String * @param startComment * the String that marks the start of a Comment section * @param endComment * the String that marks the end of a Comment section. * @return the String stripped of its comment section */ public static String removeComment(String string, String startComment, String endComment) { StringBuffer result = new StringBuffer(); int pos = 0; int end = endComment.length(); int start = string.indexOf(startComment, pos); while (start > -1) { result.append(string.substring(pos, start)); pos = string.indexOf(endComment, start) + end; start = string.indexOf(startComment, pos); } result.append(string.substring(pos)); return result.toString(); } }src/core/com/lowagie/text/html/SAXmyHtmlHandler.java100644 0 0 24372 11012562264 20077 0ustar 0 0 /* * $Id: SAXmyHtmlHandler.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.util.HashMap; import java.util.Properties; import org.xml.sax.Attributes; import com.lowagie.text.DocListener; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementTags; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.xml.SAXiTextHandler; import com.lowagie.text.xml.XmlPeer; /** * The Tags-class maps several XHTML-tags to iText-objects. */ public class SAXmyHtmlHandler extends SAXiTextHandler // SAXmyHandler { /** These are the properties of the body section. */ private Properties bodyAttributes = new Properties(); /** This is the status of the table border. */ private boolean tableBorder = false; /** * Constructs a new SAXiTextHandler that will translate all the events * triggered by the parser to actions on the Document-object. * * @param document * this is the document on which events must be triggered */ public SAXmyHtmlHandler(DocListener document) { super(document, new HtmlTagMap()); } /** * Constructs a new SAXiTextHandler that will translate all the events * triggered by the parser to actions on the Document-object. * * @param document * this is the document on which events must be triggered * @param bf */ public SAXmyHtmlHandler(DocListener document, BaseFont bf) { super(document, new HtmlTagMap(), bf); } /** * Constructs a new SAXiTextHandler that will translate all the events * triggered by the parser to actions on the Document-object. * * @param document * this is the document on which events must be triggered * @param htmlTags * a tagmap translating HTML tags to iText tags */ public SAXmyHtmlHandler(DocListener document, HashMap htmlTags) { super(document, htmlTags); } /** * This method gets called when a start tag is encountered. * * @param uri * the Uniform Resource Identifier * @param lname * the local name (without prefix), or the empty string if * Namespace processing is not being performed. * @param name * the name of the tag that is encountered * @param attrs * the list of attributes */ public void startElement(String uri, String lname, String name, Attributes attrs) { // System.err.println("Start: " + name); // super.handleStartingTags is replaced with handleStartingTags // suggestion by Vu Ngoc Tan/Hop name = name.toLowerCase(); if (HtmlTagMap.isHtml(name)) { // we do nothing return; } if (HtmlTagMap.isHead(name)) { // we do nothing return; } if (HtmlTagMap.isTitle(name)) { // we do nothing return; } if (HtmlTagMap.isMeta(name)) { // we look if we can change the body attributes String meta = null; String content = null; if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String attribute = attrs.getQName(i); if (attribute.equalsIgnoreCase(HtmlTags.CONTENT)) content = attrs.getValue(i); else if (attribute.equalsIgnoreCase(HtmlTags.NAME)) meta = attrs.getValue(i); } } if (meta != null && content != null) { bodyAttributes.put(meta, content); } return; } if (HtmlTagMap.isLink(name)) { // we do nothing for the moment, in a later version we could extract // the style sheet return; } if (HtmlTagMap.isBody(name)) { // maybe we could extract some info about the document: color, // margins,... // but that's for a later version... XmlPeer peer = new XmlPeer(ElementTags.ITEXT, name); peer.addAlias(ElementTags.TOP, HtmlTags.TOPMARGIN); peer.addAlias(ElementTags.BOTTOM, HtmlTags.BOTTOMMARGIN); peer.addAlias(ElementTags.RIGHT, HtmlTags.RIGHTMARGIN); peer.addAlias(ElementTags.LEFT, HtmlTags.LEFTMARGIN); bodyAttributes.putAll(peer.getAttributes(attrs)); handleStartingTags(peer.getTag(), bodyAttributes); return; } if (myTags.containsKey(name)) { XmlPeer peer = (XmlPeer) myTags.get(name); if (ElementTags.TABLE.equals(peer.getTag()) || ElementTags.CELL.equals(peer.getTag())) { Properties p = peer.getAttributes(attrs); String value; if (ElementTags.TABLE.equals(peer.getTag()) && (value = p.getProperty(ElementTags.BORDERWIDTH)) != null) { if (Float.parseFloat(value + "f") > 0) { tableBorder = true; } } if (tableBorder) { p.put(ElementTags.LEFT, String.valueOf(true)); p.put(ElementTags.RIGHT, String.valueOf(true)); p.put(ElementTags.TOP, String.valueOf(true)); p.put(ElementTags.BOTTOM, String.valueOf(true)); } handleStartingTags(peer.getTag(), p); return; } handleStartingTags(peer.getTag(), peer.getAttributes(attrs)); return; } Properties attributes = new Properties(); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String attribute = attrs.getQName(i).toLowerCase(); attributes.setProperty(attribute, attrs.getValue(i).toLowerCase()); } } handleStartingTags(name, attributes); } /** * This method gets called when an end tag is encountered. * * @param uri * the Uniform Resource Identifier * @param lname * the local name (without prefix), or the empty string if * Namespace processing is not being performed. * @param name * the name of the tag that ends */ public void endElement(String uri, String lname, String name) { // System.err.println("End: " + name); name = name.toLowerCase(); if (ElementTags.PARAGRAPH.equals(name)) { try { document.add((Element) stack.pop()); return; } catch (DocumentException e) { throw new ExceptionConverter(e); } } if (HtmlTagMap.isHead(name)) { // we do nothing return; } if (HtmlTagMap.isTitle(name)) { if (currentChunk != null) { bodyAttributes.put(ElementTags.TITLE, currentChunk.getContent()); } return; } if (HtmlTagMap.isMeta(name)) { // we do nothing return; } if (HtmlTagMap.isLink(name)) { // we do nothing return; } if (HtmlTagMap.isBody(name)) { // we do nothing return; } if (myTags.containsKey(name)) { XmlPeer peer = (XmlPeer) myTags.get(name); if (ElementTags.TABLE.equals(peer.getTag())) { tableBorder = false; } super.handleEndingTags(peer.getTag()); return; } // super.handleEndingTags is replaced with handleEndingTags // suggestion by Ken Auer handleEndingTags(name); } }src/core/com/lowagie/text/html/WebColors.java100644 0 0 33255 11012562264 16652 0ustar 0 0 /* * $Id: WebColors.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html; import java.awt.Color; import java.util.HashMap; import java.util.StringTokenizer; /** * This class is a HashMap that contains the names of colors as a key and the * corresponding Color as value. (Source: Wikipedia * http://en.wikipedia.org/wiki/Web_colors ) * * @author blowagie */ public class WebColors extends HashMap { private static final long serialVersionUID = 3542523100813372896L; /** HashMap containing all the names and corresponding color values. */ public static final WebColors NAMES = new WebColors(); static { NAMES.put("aliceblue", new int[] { 0xf0, 0xf8, 0xff, 0x00 }); NAMES.put("antiquewhite", new int[] { 0xfa, 0xeb, 0xd7, 0x00 }); NAMES.put("aqua", new int[] { 0x00, 0xff, 0xff, 0x00 }); NAMES.put("aquamarine", new int[] { 0x7f, 0xff, 0xd4, 0x00 }); NAMES.put("azure", new int[] { 0xf0, 0xff, 0xff, 0x00 }); NAMES.put("beige", new int[] { 0xf5, 0xf5, 0xdc, 0x00 }); NAMES.put("bisque", new int[] { 0xff, 0xe4, 0xc4, 0x00 }); NAMES.put("black", new int[] { 0x00, 0x00, 0x00, 0x00 }); NAMES.put("blanchedalmond", new int[] { 0xff, 0xeb, 0xcd, 0x00 }); NAMES.put("blue", new int[] { 0x00, 0x00, 0xff, 0x00 }); NAMES.put("blueviolet", new int[] { 0x8a, 0x2b, 0xe2, 0x00 }); NAMES.put("brown", new int[] { 0xa5, 0x2a, 0x2a, 0x00 }); NAMES.put("burlywood", new int[] { 0xde, 0xb8, 0x87, 0x00 }); NAMES.put("cadetblue", new int[] { 0x5f, 0x9e, 0xa0, 0x00 }); NAMES.put("chartreuse", new int[] { 0x7f, 0xff, 0x00, 0x00 }); NAMES.put("chocolate", new int[] { 0xd2, 0x69, 0x1e, 0x00 }); NAMES.put("coral", new int[] { 0xff, 0x7f, 0x50, 0x00 }); NAMES.put("cornflowerblue", new int[] { 0x64, 0x95, 0xed, 0x00 }); NAMES.put("cornsilk", new int[] { 0xff, 0xf8, 0xdc, 0x00 }); NAMES.put("crimson", new int[] { 0xdc, 0x14, 0x3c, 0x00 }); NAMES.put("cyan", new int[] { 0x00, 0xff, 0xff, 0x00 }); NAMES.put("darkblue", new int[] { 0x00, 0x00, 0x8b, 0x00 }); NAMES.put("darkcyan", new int[] { 0x00, 0x8b, 0x8b, 0x00 }); NAMES.put("darkgoldenrod", new int[] { 0xb8, 0x86, 0x0b, 0x00 }); NAMES.put("darkgray", new int[] { 0xa9, 0xa9, 0xa9, 0x00 }); NAMES.put("darkgreen", new int[] { 0x00, 0x64, 0x00, 0x00 }); NAMES.put("darkkhaki", new int[] { 0xbd, 0xb7, 0x6b, 0x00 }); NAMES.put("darkmagenta", new int[] { 0x8b, 0x00, 0x8b, 0x00 }); NAMES.put("darkolivegreen", new int[] { 0x55, 0x6b, 0x2f, 0x00 }); NAMES.put("darkorange", new int[] { 0xff, 0x8c, 0x00, 0x00 }); NAMES.put("darkorchid", new int[] { 0x99, 0x32, 0xcc, 0x00 }); NAMES.put("darkred", new int[] { 0x8b, 0x00, 0x00, 0x00 }); NAMES.put("darksalmon", new int[] { 0xe9, 0x96, 0x7a, 0x00 }); NAMES.put("darkseagreen", new int[] { 0x8f, 0xbc, 0x8f, 0x00 }); NAMES.put("darkslateblue", new int[] { 0x48, 0x3d, 0x8b, 0x00 }); NAMES.put("darkslategray", new int[] { 0x2f, 0x4f, 0x4f, 0x00 }); NAMES.put("darkturquoise", new int[] { 0x00, 0xce, 0xd1, 0x00 }); NAMES.put("darkviolet", new int[] { 0x94, 0x00, 0xd3, 0x00 }); NAMES.put("deeppink", new int[] { 0xff, 0x14, 0x93, 0x00 }); NAMES.put("deepskyblue", new int[] { 0x00, 0xbf, 0xff, 0x00 }); NAMES.put("dimgray", new int[] { 0x69, 0x69, 0x69, 0x00 }); NAMES.put("dodgerblue", new int[] { 0x1e, 0x90, 0xff, 0x00 }); NAMES.put("firebrick", new int[] { 0xb2, 0x22, 0x22, 0x00 }); NAMES.put("floralwhite", new int[] { 0xff, 0xfa, 0xf0, 0x00 }); NAMES.put("forestgreen", new int[] { 0x22, 0x8b, 0x22, 0x00 }); NAMES.put("fuchsia", new int[] { 0xff, 0x00, 0xff, 0x00 }); NAMES.put("gainsboro", new int[] { 0xdc, 0xdc, 0xdc, 0x00 }); NAMES.put("ghostwhite", new int[] { 0xf8, 0xf8, 0xff, 0x00 }); NAMES.put("gold", new int[] { 0xff, 0xd7, 0x00, 0x00 }); NAMES.put("goldenrod", new int[] { 0xda, 0xa5, 0x20, 0x00 }); NAMES.put("gray", new int[] { 0x80, 0x80, 0x80, 0x00 }); NAMES.put("green", new int[] { 0x00, 0x80, 0x00, 0x00 }); NAMES.put("greenyellow", new int[] { 0xad, 0xff, 0x2f, 0x00 }); NAMES.put("honeydew", new int[] { 0xf0, 0xff, 0xf0, 0x00 }); NAMES.put("hotpink", new int[] { 0xff, 0x69, 0xb4, 0x00 }); NAMES.put("indianred", new int[] { 0xcd, 0x5c, 0x5c, 0x00 }); NAMES.put("indigo", new int[] { 0x4b, 0x00, 0x82, 0x00 }); NAMES.put("ivory", new int[] { 0xff, 0xff, 0xf0, 0x00 }); NAMES.put("khaki", new int[] { 0xf0, 0xe6, 0x8c, 0x00 }); NAMES.put("lavender", new int[] { 0xe6, 0xe6, 0xfa, 0x00 }); NAMES.put("lavenderblush", new int[] { 0xff, 0xf0, 0xf5, 0x00 }); NAMES.put("lawngreen", new int[] { 0x7c, 0xfc, 0x00, 0x00 }); NAMES.put("lemonchiffon", new int[] { 0xff, 0xfa, 0xcd, 0x00 }); NAMES.put("lightblue", new int[] { 0xad, 0xd8, 0xe6, 0x00 }); NAMES.put("lightcoral", new int[] { 0xf0, 0x80, 0x80, 0x00 }); NAMES.put("lightcyan", new int[] { 0xe0, 0xff, 0xff, 0x00 }); NAMES.put("lightgoldenrodyellow", new int[] { 0xfa, 0xfa, 0xd2, 0x00 }); NAMES.put("lightgreen", new int[] { 0x90, 0xee, 0x90, 0x00 }); NAMES.put("lightgrey", new int[] { 0xd3, 0xd3, 0xd3, 0x00 }); NAMES.put("lightpink", new int[] { 0xff, 0xb6, 0xc1, 0x00 }); NAMES.put("lightsalmon", new int[] { 0xff, 0xa0, 0x7a, 0x00 }); NAMES.put("lightseagreen", new int[] { 0x20, 0xb2, 0xaa, 0x00 }); NAMES.put("lightskyblue", new int[] { 0x87, 0xce, 0xfa, 0x00 }); NAMES.put("lightslategray", new int[] { 0x77, 0x88, 0x99, 0x00 }); NAMES.put("lightsteelblue", new int[] { 0xb0, 0xc4, 0xde, 0x00 }); NAMES.put("lightyellow", new int[] { 0xff, 0xff, 0xe0, 0x00 }); NAMES.put("lime", new int[] { 0x00, 0xff, 0x00, 0x00 }); NAMES.put("limegreen", new int[] { 0x32, 0xcd, 0x32, 0x00 }); NAMES.put("linen", new int[] { 0xfa, 0xf0, 0xe6, 0x00 }); NAMES.put("magenta", new int[] { 0xff, 0x00, 0xff, 0x00 }); NAMES.put("maroon", new int[] { 0x80, 0x00, 0x00, 0x00 }); NAMES.put("mediumaquamarine", new int[] { 0x66, 0xcd, 0xaa, 0x00 }); NAMES.put("mediumblue", new int[] { 0x00, 0x00, 0xcd, 0x00 }); NAMES.put("mediumorchid", new int[] { 0xba, 0x55, 0xd3, 0x00 }); NAMES.put("mediumpurple", new int[] { 0x93, 0x70, 0xdb, 0x00 }); NAMES.put("mediumseagreen", new int[] { 0x3c, 0xb3, 0x71, 0x00 }); NAMES.put("mediumslateblue", new int[] { 0x7b, 0x68, 0xee, 0x00 }); NAMES.put("mediumspringgreen", new int[] { 0x00, 0xfa, 0x9a, 0x00 }); NAMES.put("mediumturquoise", new int[] { 0x48, 0xd1, 0xcc, 0x00 }); NAMES.put("mediumvioletred", new int[] { 0xc7, 0x15, 0x85, 0x00 }); NAMES.put("midnightblue", new int[] { 0x19, 0x19, 0x70, 0x00 }); NAMES.put("mintcream", new int[] { 0xf5, 0xff, 0xfa, 0x00 }); NAMES.put("mistyrose", new int[] { 0xff, 0xe4, 0xe1, 0x00 }); NAMES.put("moccasin", new int[] { 0xff, 0xe4, 0xb5, 0x00 }); NAMES.put("navajowhite", new int[] { 0xff, 0xde, 0xad, 0x00 }); NAMES.put("navy", new int[] { 0x00, 0x00, 0x80, 0x00 }); NAMES.put("oldlace", new int[] { 0xfd, 0xf5, 0xe6, 0x00 }); NAMES.put("olive", new int[] { 0x80, 0x80, 0x00, 0x00 }); NAMES.put("olivedrab", new int[] { 0x6b, 0x8e, 0x23, 0x00 }); NAMES.put("orange", new int[] { 0xff, 0xa5, 0x00, 0x00 }); NAMES.put("orangered", new int[] { 0xff, 0x45, 0x00, 0x00 }); NAMES.put("orchid", new int[] { 0xda, 0x70, 0xd6, 0x00 }); NAMES.put("palegoldenrod", new int[] { 0xee, 0xe8, 0xaa, 0x00 }); NAMES.put("palegreen", new int[] { 0x98, 0xfb, 0x98, 0x00 }); NAMES.put("paleturquoise", new int[] { 0xaf, 0xee, 0xee, 0x00 }); NAMES.put("palevioletred", new int[] { 0xdb, 0x70, 0x93, 0x00 }); NAMES.put("papayawhip", new int[] { 0xff, 0xef, 0xd5, 0x00 }); NAMES.put("peachpuff", new int[] { 0xff, 0xda, 0xb9, 0x00 }); NAMES.put("peru", new int[] { 0xcd, 0x85, 0x3f, 0x00 }); NAMES.put("pink", new int[] { 0xff, 0xc0, 0xcb, 0x00 }); NAMES.put("plum", new int[] { 0xdd, 0xa0, 0xdd, 0x00 }); NAMES.put("powderblue", new int[] { 0xb0, 0xe0, 0xe6, 0x00 }); NAMES.put("purple", new int[] { 0x80, 0x00, 0x80, 0x00 }); NAMES.put("red", new int[] { 0xff, 0x00, 0x00, 0x00 }); NAMES.put("rosybrown", new int[] { 0xbc, 0x8f, 0x8f, 0x00 }); NAMES.put("royalblue", new int[] { 0x41, 0x69, 0xe1, 0x00 }); NAMES.put("saddlebrown", new int[] { 0x8b, 0x45, 0x13, 0x00 }); NAMES.put("salmon", new int[] { 0xfa, 0x80, 0x72, 0x00 }); NAMES.put("sandybrown", new int[] { 0xf4, 0xa4, 0x60, 0x00 }); NAMES.put("seagreen", new int[] { 0x2e, 0x8b, 0x57, 0x00 }); NAMES.put("seashell", new int[] { 0xff, 0xf5, 0xee, 0x00 }); NAMES.put("sienna", new int[] { 0xa0, 0x52, 0x2d, 0x00 }); NAMES.put("silver", new int[] { 0xc0, 0xc0, 0xc0, 0x00 }); NAMES.put("skyblue", new int[] { 0x87, 0xce, 0xeb, 0x00 }); NAMES.put("slateblue", new int[] { 0x6a, 0x5a, 0xcd, 0x00 }); NAMES.put("slategray", new int[] { 0x70, 0x80, 0x90, 0x00 }); NAMES.put("snow", new int[] { 0xff, 0xfa, 0xfa, 0x00 }); NAMES.put("springgreen", new int[] { 0x00, 0xff, 0x7f, 0x00 }); NAMES.put("steelblue", new int[] { 0x46, 0x82, 0xb4, 0x00 }); NAMES.put("tan", new int[] { 0xd2, 0xb4, 0x8c, 0x00 }); NAMES.put("transparent", new int[] { 0x00, 0x00, 0x00, 0xff }); NAMES.put("teal", new int[] { 0x00, 0x80, 0x80, 0x00 }); NAMES.put("thistle", new int[] { 0xd8, 0xbf, 0xd8, 0x00 }); NAMES.put("tomato", new int[] { 0xff, 0x63, 0x47, 0x00 }); NAMES.put("turquoise", new int[] { 0x40, 0xe0, 0xd0, 0x00 }); NAMES.put("violet", new int[] { 0xee, 0x82, 0xee, 0x00 }); NAMES.put("wheat", new int[] { 0xf5, 0xde, 0xb3, 0x00 }); NAMES.put("white", new int[] { 0xff, 0xff, 0xff, 0x00 }); NAMES.put("whitesmoke", new int[] { 0xf5, 0xf5, 0xf5, 0x00 }); NAMES.put("yellow", new int[] { 0xff, 0xff, 0x00, 0x00 }); NAMES.put("yellowgreen", new int[] { 0x9, 0xacd, 0x32, 0x00 }); } /** * Gives you a Color based on a name. * * @param name * a name such as black, violet, cornflowerblue or #RGB or #RRGGBB * or rgb(R,G,B) * @return the corresponding Color object * @throws IllegalArgumentException * if the String isn't a know representation of a color. */ public static Color getRGBColor(String name) throws IllegalArgumentException { int[] c = { 0, 0, 0, 0 }; if (name.startsWith("#")) { if (name.length() == 4) { c[0] = Integer.parseInt(name.substring(1, 2), 16) * 16; c[1] = Integer.parseInt(name.substring(2, 3), 16) * 16; c[2] = Integer.parseInt(name.substring(3), 16) * 16; return new Color(c[0], c[1], c[2], c[3]); } if (name.length() == 7) { c[0] = Integer.parseInt(name.substring(1, 3), 16); c[1] = Integer.parseInt(name.substring(3, 5), 16); c[2] = Integer.parseInt(name.substring(5), 16); return new Color(c[0], c[1], c[2], c[3]); } throw new IllegalArgumentException( "Unknown color format. Must be #RGB or #RRGGBB"); } else if (name.startsWith("rgb(")) { StringTokenizer tok = new StringTokenizer(name, "rgb(), \t\r\n\f"); for (int k = 0; k < 3; ++k) { String v = tok.nextToken(); if (v.endsWith("%")) c[k] = Integer.parseInt(v.substring(0, v.length() - 1)) * 255 / 100; else c[k] = Integer.parseInt(v); if (c[k] < 0) c[k] = 0; else if (c[k] > 255) c[k] = 255; } return new Color(c[0], c[1], c[2], c[3]); } name = name.toLowerCase(); if (!NAMES.containsKey(name)) throw new IllegalArgumentException("Color '" + name + "' not found."); c = (int[]) NAMES.get(name); return new Color(c[0], c[1], c[2], c[3]); } }src/core/com/lowagie/text/html/simpleparser/ALink.java100644 0 0 5121 11000354011 20410 0ustar 0 0 /* * Copyright 2005 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import com.lowagie.text.Paragraph; /** * * @author psoares */ public interface ALink { boolean process(Paragraph current, ChainedProperties cprops); } src/core/com/lowagie/text/html/simpleparser/ChainedProperties.java100644 0 0 11014 11213370067 23057 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import com.lowagie.text.ElementTags; import java.util.ArrayList; import java.util.HashMap; public class ChainedProperties { public final static int fontSizes[] = { 8, 10, 12, 14, 18, 24, 36 }; public ArrayList chain = new ArrayList(); /** Creates a new instance of ChainedProperties */ public ChainedProperties() { } public String getProperty(String key) { for (int k = chain.size() - 1; k >= 0; --k) { Object obj[] = (Object[]) chain.get(k); HashMap prop = (HashMap) obj[1]; String ret = (String) prop.get(key); if (ret != null) return ret; } return null; } public boolean hasProperty(String key) { for (int k = chain.size() - 1; k >= 0; --k) { Object obj[] = (Object[]) chain.get(k); HashMap prop = (HashMap) obj[1]; if (prop.containsKey(key)) return true; } return false; } public void addToChain(String key, HashMap prop) { // adjust the font size String value = (String) prop.get(ElementTags.SIZE); if (value != null) { if (value.endsWith("pt")) { prop.put(ElementTags.SIZE, value.substring(0, value.length() - 2)); } else { int s = 0; if (value.startsWith("+") || value.startsWith("-")) { String old = getProperty("basefontsize"); if (old == null) old = "12"; float f = Float.parseFloat(old); int c = (int) f; for (int k = fontSizes.length - 1; k >= 0; --k) { if (c >= fontSizes[k]) { s = k; break; } } int inc = Integer.parseInt(value.startsWith("+") ? value .substring(1) : value); s += inc; } else { try { s = Integer.parseInt(value) - 1; } catch (NumberFormatException nfe) { s = 0; } } if (s < 0) s = 0; else if (s >= fontSizes.length) s = fontSizes.length - 1; prop.put(ElementTags.SIZE, Integer.toString(fontSizes[s])); } } chain.add(new Object[] { key, prop }); } public void removeChain(String key) { for (int k = chain.size() - 1; k >= 0; --k) { if (key.equals(((Object[]) chain.get(k))[0])) { chain.remove(k); return; } } } } src/core/com/lowagie/text/html/simpleparser/FactoryProperties.java100644 0 0 32636 11215636056 23155 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import java.awt.Color; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import java.util.StringTokenizer; import com.lowagie.text.Chunk; import com.lowagie.text.Element; import com.lowagie.text.ElementTags; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.FontFactoryImp; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.html.Markup; import com.lowagie.text.html.HtmlTags; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.HyphenationAuto; import com.lowagie.text.pdf.HyphenationEvent; /** * * @author psoares */ public class FactoryProperties { private FontFactoryImp fontImp = FontFactory.getFontImp(); /** Creates a new instance of FactoryProperties */ public FactoryProperties() { } public Chunk createChunk(String text, ChainedProperties props) { Font font = getFont(props); float size = font.getSize(); size /= 2; Chunk ck = new Chunk(text, font); if (props.hasProperty("sub")) ck.setTextRise(-size); else if (props.hasProperty("sup")) ck.setTextRise(size); ck.setHyphenation(getHyphenation(props)); return ck; } private static void setParagraphLeading(Paragraph p, String leading) { if (leading == null) { p.setLeading(0, 1.5f); return; } try { StringTokenizer tk = new StringTokenizer(leading, " ,"); String v = tk.nextToken(); float v1 = Float.parseFloat(v); if (!tk.hasMoreTokens()) { p.setLeading(v1, 0); return; } v = tk.nextToken(); float v2 = Float.parseFloat(v); p.setLeading(v1, v2); } catch (Exception e) { p.setLeading(0, 1.5f); } } public static void createParagraph(Paragraph p, ChainedProperties props) { String value = props.getProperty("align"); if (value != null) { if (value.equalsIgnoreCase("center")) p.setAlignment(Element.ALIGN_CENTER); else if (value.equalsIgnoreCase("right")) p.setAlignment(Element.ALIGN_RIGHT); else if (value.equalsIgnoreCase("justify")) p.setAlignment(Element.ALIGN_JUSTIFIED); } p.setHyphenation(getHyphenation(props)); setParagraphLeading(p, props.getProperty("leading")); value = props.getProperty("before"); if (value != null) { try { p.setSpacingBefore(Float.parseFloat(value)); } catch (Exception e) { } } value = props.getProperty("after"); if (value != null) { try { p.setSpacingAfter(Float.parseFloat(value)); } catch (Exception e) { } } value = props.getProperty("extraparaspace"); if (value != null) { try { p.setExtraParagraphSpace(Float.parseFloat(value)); } catch (Exception e) { } } } public static Paragraph createParagraph(ChainedProperties props) { Paragraph p = new Paragraph(); createParagraph(p, props); return p; } public static ListItem createListItem(ChainedProperties props) { ListItem p = new ListItem(); createParagraph(p, props); return p; } public Font getFont(ChainedProperties props) { String face = props.getProperty(ElementTags.FACE); if (face != null) { StringTokenizer tok = new StringTokenizer(face, ","); while (tok.hasMoreTokens()) { face = tok.nextToken().trim(); if (face.startsWith("\"")) face = face.substring(1); if (face.endsWith("\"")) face = face.substring(0, face.length() - 1); if (fontImp.isRegistered(face)) break; } } int style = 0; if (props.hasProperty(HtmlTags.I)) style |= Font.ITALIC; if (props.hasProperty(HtmlTags.B)) style |= Font.BOLD; if (props.hasProperty(HtmlTags.U)) style |= Font.UNDERLINE; if (props.hasProperty(HtmlTags.S)) style |= Font.STRIKETHRU; String value = props.getProperty(ElementTags.SIZE); float size = 12; if (value != null) size = Float.parseFloat(value); Color color = Markup.decodeColor(props.getProperty("color")); String encoding = props.getProperty("encoding"); if (encoding == null) encoding = BaseFont.WINANSI; return fontImp.getFont(face, encoding, true, size, style, color); } /** * Gets a HyphenationEvent based on the hyphenation entry in ChainedProperties. * @param props ChainedProperties * @return a HyphenationEvent * @since 2.1.2 */ public static HyphenationEvent getHyphenation(ChainedProperties props) { return getHyphenation(props.getProperty("hyphenation")); } /** * Gets a HyphenationEvent based on the hyphenation entry in a HashMap. * @param props a HashMap with properties * @return a HyphenationEvent * @since 2.1.2 */ public static HyphenationEvent getHyphenation(HashMap props) { return getHyphenation((String) props.get("hyphenation")); } /** * Gets a HyphenationEvent based on a String. * For instance "en_UK,3,2" returns new HyphenationAuto("en", "UK", 3, 2); * @param s a String, for instance "en_UK,2,2" * @return a HyphenationEvent * @since 2.1.2 */ public static HyphenationEvent getHyphenation(String s) { if (s == null || s.length() == 0) { return null; } String lang = s; String country = null; int leftMin = 2; int rightMin = 2; int pos = s.indexOf('_'); if (pos == -1) { return new HyphenationAuto(lang, country, leftMin, rightMin); } lang = s.substring(0, pos); country = s.substring(pos + 1); pos = country.indexOf(','); if (pos == -1) { return new HyphenationAuto(lang, country, leftMin, rightMin); } s = country.substring(pos + 1); country = country.substring(0, pos); pos = s.indexOf(','); if (pos == -1) { leftMin = Integer.parseInt(s); } else { leftMin = Integer.parseInt(s.substring(0, pos)); rightMin = Integer.parseInt(s.substring(pos + 1)); } return new HyphenationAuto(lang, country, leftMin, rightMin); } /** * This method isn't used by iText, but you can use it to analyze * the value of a style attribute inside a HashMap. * The different elements of the style attribute are added to the * HashMap as key-value pairs. * @param h a HashMap that should have at least a key named * style. After this method is invoked, more keys could be added. */ public static void insertStyle(HashMap h) { String style = (String) h.get("style"); if (style == null) return; Properties prop = Markup.parseAttributes(style); for (Iterator it = prop.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); if (key.equals(Markup.CSS_KEY_FONTFAMILY)) { h.put("face", prop.getProperty(key)); } else if (key.equals(Markup.CSS_KEY_FONTSIZE)) { h.put("size", Float.toString(Markup.parseLength(prop .getProperty(key))) + "pt"); } else if (key.equals(Markup.CSS_KEY_FONTSTYLE)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals("italic") || ss.equals("oblique")) h.put("i", null); } else if (key.equals(Markup.CSS_KEY_FONTWEIGHT)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals("bold") || ss.equals("700") || ss.equals("800") || ss.equals("900")) h.put("b", null); } else if (key.equals(Markup.CSS_KEY_TEXTDECORATION)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals(Markup.CSS_VALUE_UNDERLINE)) h.put("u", null); } else if (key.equals(Markup.CSS_KEY_COLOR)) { Color c = Markup.decodeColor(prop.getProperty(key)); if (c != null) { int hh = c.getRGB(); String hs = Integer.toHexString(hh); hs = "000000" + hs; hs = "#" + hs.substring(hs.length() - 6); h.put("color", hs); } } else if (key.equals(Markup.CSS_KEY_LINEHEIGHT)) { String ss = prop.getProperty(key).trim(); float v = Markup.parseLength(prop.getProperty(key)); if (ss.endsWith("%")) { h.put("leading", "0," + (v / 100)); } else if ("normal".equalsIgnoreCase(ss)) { h.put("leading", "0,1.5"); } else { h.put("leading", v + ",0"); } } else if (key.equals(Markup.CSS_KEY_TEXTALIGN)) { String ss = prop.getProperty(key).trim().toLowerCase(); h.put("align", ss); } } } /** * New method contributed by Lubos Strapko * @param h * @param cprops * @since 2.1.3 */ public static void insertStyle(HashMap h, ChainedProperties cprops) { String style = (String) h.get("style"); if (style == null) return; Properties prop = Markup.parseAttributes(style); for (Iterator it = prop.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); if (key.equals(Markup.CSS_KEY_FONTFAMILY)) { h.put(ElementTags.FACE, prop.getProperty(key)); } else if (key.equals(Markup.CSS_KEY_FONTSIZE)) { float actualFontSize = Markup.parseLength(cprops .getProperty(ElementTags.SIZE), Markup.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) actualFontSize = Markup.DEFAULT_FONT_SIZE; h.put(ElementTags.SIZE, Float.toString(Markup.parseLength(prop .getProperty(key), actualFontSize)) + "pt"); } else if (key.equals(Markup.CSS_KEY_FONTSTYLE)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals("italic") || ss.equals("oblique")) h.put("i", null); } else if (key.equals(Markup.CSS_KEY_FONTWEIGHT)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals("bold") || ss.equals("700") || ss.equals("800") || ss.equals("900")) h.put("b", null); } else if (key.equals(Markup.CSS_KEY_TEXTDECORATION)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals(Markup.CSS_VALUE_UNDERLINE)) h.put("u", null); } else if (key.equals(Markup.CSS_KEY_COLOR)) { Color c = Markup.decodeColor(prop.getProperty(key)); if (c != null) { int hh = c.getRGB(); String hs = Integer.toHexString(hh); hs = "000000" + hs; hs = "#" + hs.substring(hs.length() - 6); h.put("color", hs); } } else if (key.equals(Markup.CSS_KEY_LINEHEIGHT)) { String ss = prop.getProperty(key).trim(); float actualFontSize = Markup.parseLength(cprops .getProperty(ElementTags.SIZE), Markup.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) actualFontSize = Markup.DEFAULT_FONT_SIZE; float v = Markup.parseLength(prop.getProperty(key), actualFontSize); if (ss.endsWith("%")) { h.put("leading", "0," + (v / 100)); return; } if ("normal".equalsIgnoreCase(ss)) { h.put("leading", "0,1.5"); return; } h.put("leading", v + ",0"); } else if (key.equals(Markup.CSS_KEY_TEXTALIGN)) { String ss = prop.getProperty(key).trim().toLowerCase(); h.put("align", ss); } else if (key.equals(Markup.CSS_KEY_PADDINGLEFT)) { String ss = prop.getProperty(key).trim().toLowerCase(); h.put("indent", Float.toString(Markup.parseLength(ss))); } } } public FontFactoryImp getFontImp() { return fontImp; } public void setFontImp(FontFactoryImp fontImp) { this.fontImp = fontImp; } public static HashMap followTags = new HashMap(); static { followTags.put("i", "i"); followTags.put("b", "b"); followTags.put("u", "u"); followTags.put("sub", "sub"); followTags.put("sup", "sup"); followTags.put("em", "i"); followTags.put("strong", "b"); followTags.put("s", "s"); followTags.put("strike", "s"); } } src/core/com/lowagie/text/html/simpleparser/HTMLWorker.java100644 0 0 51156 11215636056 21425 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import java.io.File; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.Stack; import java.util.StringTokenizer; import com.lowagie.text.html.HtmlTags; import com.lowagie.text.html.Markup; import com.lowagie.text.Chunk; import com.lowagie.text.DocListener; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementTags; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.FontFactoryImp; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Image; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.TextElementArray; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.draw.LineSeparator; import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; import com.lowagie.text.xml.simpleparser.SimpleXMLParser; public class HTMLWorker implements SimpleXMLDocHandler, DocListener { protected ArrayList objectList; protected DocListener document; private Paragraph currentParagraph; private ChainedProperties cprops = new ChainedProperties(); private Stack stack = new Stack(); private boolean pendingTR = false; private boolean pendingTD = false; private boolean pendingLI = false; private StyleSheet style = new StyleSheet(); private boolean isPRE = false; private Stack tableState = new Stack(); private boolean skipText = false; private HashMap interfaceProps; private FactoryProperties factoryProperties = new FactoryProperties(); /** Creates a new instance of HTMLWorker * @param document A class that implements DocListener * */ public HTMLWorker(DocListener document) { this.document = document; } public void setStyleSheet(StyleSheet style) { this.style = style; } public StyleSheet getStyleSheet() { return style; } public void setInterfaceProps(HashMap interfaceProps) { this.interfaceProps = interfaceProps; FontFactoryImp ff = null; if (interfaceProps != null) ff = (FontFactoryImp) interfaceProps.get("font_factory"); if (ff != null) factoryProperties.setFontImp(ff); } public HashMap getInterfaceProps() { return interfaceProps; } public void parse(Reader reader) throws IOException { SimpleXMLParser.parse(this, null, reader, true); } public static ArrayList parseToList(Reader reader, StyleSheet style) throws IOException { return parseToList(reader, style, null); } public static ArrayList parseToList(Reader reader, StyleSheet style, HashMap interfaceProps) throws IOException { HTMLWorker worker = new HTMLWorker(null); if (style != null) worker.style = style; worker.document = worker; worker.setInterfaceProps(interfaceProps); worker.objectList = new ArrayList(); worker.parse(reader); return worker.objectList; } public void endDocument() { try { for (int k = 0; k < stack.size(); ++k) document.add((Element) stack.elementAt(k)); if (currentParagraph != null) document.add(currentParagraph); currentParagraph = null; } catch (Exception e) { throw new ExceptionConverter(e); } } public void startDocument() { HashMap h = new HashMap(); style.applyStyle("body", h); cprops.addToChain("body", h); } public void startElement(String tag, HashMap h) { if (!tagsSupported.containsKey(tag)) return; try { style.applyStyle(tag, h); String follow = (String) FactoryProperties.followTags.get(tag); if (follow != null) { HashMap prop = new HashMap(); prop.put(follow, null); cprops.addToChain(follow, prop); return; } FactoryProperties.insertStyle(h, cprops); if (tag.equals(HtmlTags.ANCHOR)) { cprops.addToChain(tag, h); if (currentParagraph == null) { currentParagraph = new Paragraph(); } stack.push(currentParagraph); currentParagraph = new Paragraph(); return; } if (tag.equals(HtmlTags.NEWLINE)) { if (currentParagraph == null) { currentParagraph = new Paragraph(); } currentParagraph.add(factoryProperties .createChunk("\n", cprops)); return; } if (tag.equals(HtmlTags.HORIZONTALRULE)) { // Attempting to duplicate the behavior seen on Firefox with // http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_hr_test // where an initial break is only inserted when the preceding element doesn't // end with a break, but a trailing break is always inserted. boolean addLeadingBreak = true; if (currentParagraph == null) { currentParagraph = new Paragraph(); addLeadingBreak = false; } if (addLeadingBreak) { // Not a new paragraph int numChunks = currentParagraph.getChunks().size(); if (numChunks == 0 || ((Chunk)(currentParagraph.getChunks().get(numChunks - 1))).getContent().endsWith("\n")) addLeadingBreak = false; } String align = (String) h.get("align"); int hrAlign = Element.ALIGN_CENTER; if (align != null) { if (align.equalsIgnoreCase("left")) hrAlign = Element.ALIGN_LEFT; if (align.equalsIgnoreCase("right")) hrAlign = Element.ALIGN_RIGHT; } String width = (String) h.get("width"); float hrWidth = 1; if (width != null) { float tmpWidth = Markup.parseLength(width, Markup.DEFAULT_FONT_SIZE); if (tmpWidth > 0) hrWidth = tmpWidth; if (!width.endsWith("%")) hrWidth = 100; // Treat a pixel width as 100% for now. } String size = (String) h.get("size"); float hrSize = 1; if (size != null) { float tmpSize = Markup.parseLength(size, Markup.DEFAULT_FONT_SIZE); if (tmpSize > 0) hrSize = tmpSize; } if (addLeadingBreak) currentParagraph.add(Chunk.NEWLINE); currentParagraph.add(new LineSeparator(hrSize, hrWidth, null, hrAlign, currentParagraph.getLeading()/2)); currentParagraph.add(Chunk.NEWLINE); return; } if (tag.equals(HtmlTags.CHUNK) || tag.equals(HtmlTags.SPAN)) { cprops.addToChain(tag, h); return; } if (tag.equals(HtmlTags.IMAGE)) { String src = (String) h.get(ElementTags.SRC); if (src == null) return; cprops.addToChain(tag, h); Image img = null; if (interfaceProps != null) { ImageProvider ip = (ImageProvider) interfaceProps .get("img_provider"); if (ip != null) img = ip.getImage(src, h, cprops, document); if (img == null) { HashMap images = (HashMap) interfaceProps .get("img_static"); if (images != null) { Image tim = (Image) images.get(src); if (tim != null) img = Image.getInstance(tim); } else { if (!src.startsWith("http")) { // relative src references only String baseurl = (String) interfaceProps .get("img_baseurl"); if (baseurl != null) { src = baseurl + src; img = Image.getInstance(src); } } } } } if (img == null) { if (!src.startsWith("http")) { String path = cprops.getProperty("image_path"); if (path == null) path = ""; src = new File(path, src).getPath(); } img = Image.getInstance(src); } String align = (String) h.get("align"); String width = (String) h.get("width"); String height = (String) h.get("height"); String before = cprops.getProperty("before"); String after = cprops.getProperty("after"); if (before != null) img.setSpacingBefore(Float.parseFloat(before)); if (after != null) img.setSpacingAfter(Float.parseFloat(after)); float actualFontSize = Markup.parseLength(cprops .getProperty(ElementTags.SIZE), Markup.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) actualFontSize = Markup.DEFAULT_FONT_SIZE; float widthInPoints = Markup.parseLength(width, actualFontSize); float heightInPoints = Markup.parseLength(height, actualFontSize); if (widthInPoints > 0 && heightInPoints > 0) { img.scaleAbsolute(widthInPoints, heightInPoints); } else if (widthInPoints > 0) { heightInPoints = img.getHeight() * widthInPoints / img.getWidth(); img.scaleAbsolute(widthInPoints, heightInPoints); } else if (heightInPoints > 0) { widthInPoints = img.getWidth() * heightInPoints / img.getHeight(); img.scaleAbsolute(widthInPoints, heightInPoints); } img.setWidthPercentage(0); if (align != null) { endElement("p"); int ralign = Image.MIDDLE; if (align.equalsIgnoreCase("left")) ralign = Image.LEFT; else if (align.equalsIgnoreCase("right")) ralign = Image.RIGHT; img.setAlignment(ralign); Img i = null; boolean skip = false; if (interfaceProps != null) { i = (Img) interfaceProps.get("img_interface"); if (i != null) skip = i.process(img, h, cprops, document); } if (!skip) document.add(img); cprops.removeChain(tag); } else { cprops.removeChain(tag); if (currentParagraph == null) { currentParagraph = FactoryProperties .createParagraph(cprops); } currentParagraph.add(new Chunk(img, 0, 0)); } return; } endElement("p"); if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) { if (!h.containsKey(ElementTags.SIZE)) { int v = 7 - Integer.parseInt(tag.substring(1)); h.put(ElementTags.SIZE, Integer.toString(v)); } cprops.addToChain(tag, h); return; } if (tag.equals(HtmlTags.UNORDEREDLIST)) { if (pendingLI) endElement(HtmlTags.LISTITEM); skipText = true; cprops.addToChain(tag, h); com.lowagie.text.List list = new com.lowagie.text.List(false); try{ list.setIndentationLeft(new Float(cprops.getProperty("indent")).floatValue()); }catch (Exception e) { list.setAutoindent(true); } list.setListSymbol("\u2022"); stack.push(list); return; } if (tag.equals(HtmlTags.ORDEREDLIST)) { if (pendingLI) endElement(HtmlTags.LISTITEM); skipText = true; cprops.addToChain(tag, h); com.lowagie.text.List list = new com.lowagie.text.List(true); try{ list.setIndentationLeft(new Float(cprops.getProperty("indent")).floatValue()); }catch (Exception e) { list.setAutoindent(true); } stack.push(list); return; } if (tag.equals(HtmlTags.LISTITEM)) { if (pendingLI) endElement(HtmlTags.LISTITEM); skipText = false; pendingLI = true; cprops.addToChain(tag, h); ListItem item = FactoryProperties.createListItem(cprops); stack.push(item); return; } if (tag.equals(HtmlTags.DIV) || tag.equals(HtmlTags.BODY) || tag.equals("p")) { cprops.addToChain(tag, h); return; } if (tag.equals(HtmlTags.PRE)) { if (!h.containsKey(ElementTags.FACE)) { h.put(ElementTags.FACE, "Courier"); } cprops.addToChain(tag, h); isPRE = true; return; } if (tag.equals("tr")) { if (pendingTR) endElement("tr"); skipText = true; pendingTR = true; cprops.addToChain("tr", h); return; } if (tag.equals("td") || tag.equals("th")) { if (pendingTD) endElement(tag); skipText = false; pendingTD = true; cprops.addToChain("td", h); stack.push(new IncCell(tag, cprops)); return; } if (tag.equals("table")) { cprops.addToChain("table", h); IncTable table = new IncTable(h); stack.push(table); tableState.push(new boolean[] { pendingTR, pendingTD }); pendingTR = pendingTD = false; skipText = true; return; } } catch (Exception e) { throw new ExceptionConverter(e); } } public void endElement(String tag) { if (!tagsSupported.containsKey(tag)) return; try { String follow = (String) FactoryProperties.followTags.get(tag); if (follow != null) { cprops.removeChain(follow); return; } if (tag.equals("font") || tag.equals("span")) { cprops.removeChain(tag); return; } if (tag.equals("a")) { if (currentParagraph == null) { currentParagraph = new Paragraph(); } boolean skip = false; if (interfaceProps != null) { ALink i = (ALink) interfaceProps.get("alink_interface"); if (i != null) skip = i.process(currentParagraph, cprops); } if (!skip) { String href = cprops.getProperty("href"); if (href != null) { ArrayList chunks = currentParagraph.getChunks(); int size = chunks.size(); for (int k = 0; k < size; ++k) { Chunk ck = (Chunk) chunks.get(k); ck.setAnchor(href); } } } Paragraph tmp = (Paragraph) stack.pop(); Phrase tmp2 = new Phrase(); tmp2.add(currentParagraph); tmp.add(tmp2); currentParagraph = tmp; cprops.removeChain("a"); return; } if (tag.equals("br")) { return; } if (currentParagraph != null) { if (stack.empty()) document.add(currentParagraph); else { Object obj = stack.pop(); if (obj instanceof TextElementArray) { TextElementArray current = (TextElementArray) obj; current.add(currentParagraph); } stack.push(obj); } } currentParagraph = null; if (tag.equals(HtmlTags.UNORDEREDLIST) || tag.equals(HtmlTags.ORDEREDLIST)) { if (pendingLI) endElement(HtmlTags.LISTITEM); skipText = false; cprops.removeChain(tag); if (stack.empty()) return; Object obj = stack.pop(); if (!(obj instanceof com.lowagie.text.List)) { stack.push(obj); return; } if (stack.empty()) document.add((Element) obj); else ((TextElementArray) stack.peek()).add(obj); return; } if (tag.equals(HtmlTags.LISTITEM)) { pendingLI = false; skipText = true; cprops.removeChain(tag); if (stack.empty()) return; Object obj = stack.pop(); if (!(obj instanceof ListItem)) { stack.push(obj); return; } if (stack.empty()) { document.add((Element) obj); return; } Object list = stack.pop(); if (!(list instanceof com.lowagie.text.List)) { stack.push(list); return; } ListItem item = (ListItem) obj; ((com.lowagie.text.List) list).add(item); ArrayList cks = item.getChunks(); if (!cks.isEmpty()) item.getListSymbol() .setFont(((Chunk) cks.get(0)).getFont()); stack.push(list); return; } if (tag.equals("div") || tag.equals("body")) { cprops.removeChain(tag); return; } if (tag.equals(HtmlTags.PRE)) { cprops.removeChain(tag); isPRE = false; return; } if (tag.equals("p")) { cprops.removeChain(tag); return; } if (tag.equals("h1") || tag.equals("h2") || tag.equals("h3") || tag.equals("h4") || tag.equals("h5") || tag.equals("h6")) { cprops.removeChain(tag); return; } if (tag.equals("table")) { if (pendingTR) endElement("tr"); cprops.removeChain("table"); IncTable table = (IncTable) stack.pop(); PdfPTable tb = table.buildTable(); tb.setSplitRows(true); if (stack.empty()) document.add(tb); else ((TextElementArray) stack.peek()).add(tb); boolean state[] = (boolean[]) tableState.pop(); pendingTR = state[0]; pendingTD = state[1]; skipText = false; return; } if (tag.equals("tr")) { if (pendingTD) endElement("td"); pendingTR = false; cprops.removeChain("tr"); ArrayList cells = new ArrayList(); IncTable table = null; while (true) { Object obj = stack.pop(); if (obj instanceof IncCell) { cells.add(((IncCell) obj).getCell()); } if (obj instanceof IncTable) { table = (IncTable) obj; break; } } table.addCols(cells); table.endRow(); stack.push(table); skipText = true; return; } if (tag.equals("td") || tag.equals("th")) { pendingTD = false; cprops.removeChain("td"); skipText = true; return; } } catch (Exception e) { throw new ExceptionConverter(e); } } public void text(String str) { if (skipText) return; String content = str; if (isPRE) { if (currentParagraph == null) { currentParagraph = FactoryProperties.createParagraph(cprops); } Chunk chunk = factoryProperties.createChunk(content, cprops); currentParagraph.add(chunk); return; } if (content.trim().length() == 0 && content.indexOf(' ') < 0) { return; } StringBuffer buf = new StringBuffer(); int len = content.length(); char character; boolean newline = false; for (int i = 0; i < len; i++) { switch (character = content.charAt(i)) { case ' ': if (!newline) { buf.append(character); } break; case '\n': if (i > 0) { newline = true; buf.append(' '); } break; case '\r': break; case '\t': break; default: newline = false; buf.append(character); } } if (currentParagraph == null) { currentParagraph = FactoryProperties.createParagraph(cprops); } Chunk chunk = factoryProperties.createChunk(buf.toString(), cprops); currentParagraph.add(chunk); } public boolean add(Element element) throws DocumentException { objectList.add(element); return true; } public void clearTextWrap() throws DocumentException { } public void close() { } public boolean newPage() { return true; } public void open() { } public void resetFooter() { } public void resetHeader() { } public void resetPageCount() { } public void setFooter(HeaderFooter footer) { } public void setHeader(HeaderFooter header) { } public boolean setMarginMirroring(boolean marginMirroring) { return false; } /** * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) * @since 2.1.6 */ public boolean setMarginMirroringTopBottom(boolean marginMirroring) { return false; } public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { return true; } public void setPageCount(int pageN) { } public boolean setPageSize(Rectangle pageSize) { return true; } public static final String tagsSupportedString = "ol ul li a pre font span br p div body table td th tr i b u sub sup em strong s strike" + " h1 h2 h3 h4 h5 h6 img hr"; public static final HashMap tagsSupported = new HashMap(); static { StringTokenizer tok = new StringTokenizer(tagsSupportedString); while (tok.hasMoreTokens()) tagsSupported.put(tok.nextToken(), null); } } src/core/com/lowagie/text/html/simpleparser/ImageProvider.java100644 0 0 5304 11000354011 22152 0ustar 0 0 /* * Copyright 2007 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import com.lowagie.text.DocListener; import com.lowagie.text.Image; import java.util.HashMap; public interface ImageProvider { Image getImage(String src, HashMap h, ChainedProperties cprops, DocListener doc); } src/core/com/lowagie/text/html/simpleparser/Img.java100644 0 0 5240 11000354011 20130 0ustar 0 0 /* * Copyright 2005 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import java.util.HashMap; import com.lowagie.text.DocListener; import com.lowagie.text.Image; /** * * @author psoares */ public interface Img { boolean process(Image img, HashMap h, ChainedProperties cprops, DocListener doc); } src/core/com/lowagie/text/html/simpleparser/IncCell.java100644 0 0 12417 11000354011 20751 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import java.util.ArrayList; import com.lowagie.text.Element; import com.lowagie.text.ElementListener; import com.lowagie.text.Phrase; import com.lowagie.text.TextElementArray; import com.lowagie.text.html.Markup; import com.lowagie.text.pdf.PdfPCell; /** * * @author psoares */ public class IncCell implements TextElementArray { private ArrayList chunks = new ArrayList(); private PdfPCell cell; /** Creates a new instance of IncCell */ public IncCell(String tag, ChainedProperties props) { cell = new PdfPCell((Phrase)null); String value = props.getProperty("colspan"); if (value != null) cell.setColspan(Integer.parseInt(value)); value = props.getProperty("align"); if (tag.equals("th")) cell.setHorizontalAlignment(Element.ALIGN_CENTER); if (value != null) { if ("center".equalsIgnoreCase(value)) cell.setHorizontalAlignment(Element.ALIGN_CENTER); else if ("right".equalsIgnoreCase(value)) cell.setHorizontalAlignment(Element.ALIGN_RIGHT); else if ("left".equalsIgnoreCase(value)) cell.setHorizontalAlignment(Element.ALIGN_LEFT); else if ("justify".equalsIgnoreCase(value)) cell.setHorizontalAlignment(Element.ALIGN_JUSTIFIED); } value = props.getProperty("valign"); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); if (value != null) { if ("top".equalsIgnoreCase(value)) cell.setVerticalAlignment(Element.ALIGN_TOP); else if ("bottom".equalsIgnoreCase(value)) cell.setVerticalAlignment(Element.ALIGN_BOTTOM); } value = props.getProperty("border"); float border = 0; if (value != null) border = Float.parseFloat(value); cell.setBorderWidth(border); value = props.getProperty("cellpadding"); if (value != null) cell.setPadding(Float.parseFloat(value)); cell.setUseDescender(true); value = props.getProperty("bgcolor"); cell.setBackgroundColor(Markup.decodeColor(value)); } public boolean add(Object o) { if (!(o instanceof Element)) return false; cell.addElement((Element)o); return true; } public ArrayList getChunks() { return chunks; } public boolean process(ElementListener listener) { return true; } public int type() { return Element.RECTANGLE; } public PdfPCell getCell() { return cell; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } }src/core/com/lowagie/text/html/simpleparser/IncTable.java100644 0 0 10622 11000354011 21115 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; /** * * @author psoares */ public class IncTable { private HashMap props = new HashMap(); private ArrayList rows = new ArrayList(); private ArrayList cols; /** Creates a new instance of IncTable */ public IncTable(HashMap props) { this.props.putAll(props); } public void addCol(PdfPCell cell) { if (cols == null) cols = new ArrayList(); cols.add(cell); } public void addCols(ArrayList ncols) { if (cols == null) cols = new ArrayList(ncols); else cols.addAll(ncols); } public void endRow() { if (cols != null) { Collections.reverse(cols); rows.add(cols); cols = null; } } public ArrayList getRows() { return rows; } public PdfPTable buildTable() { if (rows.isEmpty()) return new PdfPTable(1); int ncol = 0; ArrayList c0 = (ArrayList)rows.get(0); for (int k = 0; k < c0.size(); ++k) { ncol += ((PdfPCell)c0.get(k)).getColspan(); } PdfPTable table = new PdfPTable(ncol); String width = (String)props.get("width"); if (width == null) table.setWidthPercentage(100); else { if (width.endsWith("%")) table.setWidthPercentage(Float.parseFloat(width.substring(0, width.length() - 1))); else { table.setTotalWidth(Float.parseFloat(width)); table.setLockedWidth(true); } } for (int row = 0; row < rows.size(); ++row) { ArrayList col = (ArrayList)rows.get(row); for (int k = 0; k < col.size(); ++k) { table.addCell((PdfPCell)col.get(k)); } } return table; } } src/core/com/lowagie/text/html/simpleparser/StyleSheet.java100644 0 0 7631 11036112743 21530 0ustar 0 0 /* * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.html.simpleparser; import com.lowagie.text.html.Markup; import java.util.HashMap; public class StyleSheet { public HashMap classMap = new HashMap(); public HashMap tagMap = new HashMap(); /** Creates a new instance of StyleSheet */ public StyleSheet() { } public void applyStyle(String tag, HashMap props) { HashMap map = (HashMap) tagMap.get(tag.toLowerCase()); if (map != null) { HashMap temp = new HashMap(map); temp.putAll(props); props.putAll(temp); } String cm = (String) props.get(Markup.HTML_ATTR_CSS_CLASS); if (cm == null) return; map = (HashMap) classMap.get(cm.toLowerCase()); if (map == null) return; props.remove(Markup.HTML_ATTR_CSS_CLASS); HashMap temp = new HashMap(map); temp.putAll(props); props.putAll(temp); } public void loadStyle(String style, HashMap props) { classMap.put(style.toLowerCase(), props); } public void loadStyle(String style, String key, String value) { style = style.toLowerCase(); HashMap props = (HashMap) classMap.get(style); if (props == null) { props = new HashMap(); classMap.put(style, props); } props.put(key, value); } public void loadTagStyle(String tag, HashMap props) { tagMap.put(tag.toLowerCase(), props); } public void loadTagStyle(String tag, String key, String value) { tag = tag.toLowerCase(); HashMap props = (HashMap) tagMap.get(tag); if (props == null) { props = new HashMap(); tagMap.put(tag, props); } props.put(key, value); } }src/core/com/lowagie/text/lgpl.txt100644 0 0 55314 11000354131 14630 0ustar 0 0 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. . Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. . GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. . 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. . Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. . 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. . 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. . 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. . 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS src/core/com/lowagie/text/misc_licenses.txt100644 0 0 21714 11000354131 16507 0ustar 0 0 (1) ExceptionConverter: The original version of this class was published in an article by Heinz Kabutz. Read http://www.javaspecialists.co.za/archive/newsletter.do?issue=033&print=yes&locale=en_US "This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information. (2) SimpleXMLParser: The original version of this class was published in a JavaWorld article by Steven Brandt: http://www.javaworld.com/javaworld/javatips/jw-javatip128.html Jennifer Orr (JavaWorld) wrote: "You have permission to use the code appearing in Steven Brandt's JavaWorld article, 'Java Tip 128: Create a quick-and-dirty XML parser.' We ask that you reference the author as the creator and JavaWorld as the original publisher of the code." Steven Brandt also agreed with the use of this class. (3) The following files contain material that was copyrighted by SUN: com/lowagie/text/pdf/LZWDecoder.java (first appearance in iText: 2002-02-08) com/lowagie/text/pdf/codec/BmpImage.java (first appearance in iText: 2003-06-20) com/lowagie/text/pdf/codec/PngImage.java (first appearance in iText: 2003-04-25) com/lowagie/text/pdf/codec/TIFFDirectory.java (first appearance in iText: 2003-04-09) com/lowagie/text/pdf/codec/TIFFFaxDecoder.java (first appearance in iText: 2003-04-09) com/lowagie/text/pdf/codec/TIFFField.java (first appearance in iText: 2003-04-09) com/lowagie/text/pdf/codec/TIFFLZWDecoder.java (first appearance in iText: 2003-04-09) The original code was released under the BSD license, and contained the following extra restriction: "You acknowledge that Software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility." In a mail sent to Bruno Lowagie on January 23, 2008, Brian Burkhalter (@sun.com) writes: "This code is under a BSD license and supersedes the older codec packages on which your code is based. It also includes numerous fixes among them being the ability to handle a lot of 'broken' TIFFs." Note that numerous fixes were applied to the code used in iText by Paulo Soares, but apart from the fixes there were no essential changes between the code that was originally adapted and the code that is now available under the following license: Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistribution of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. You acknowledge that this software is not designed or intended for use in the design, construction, operation or maintenance of any nuclear facility. The main difference can be found in the final paragraph: the restriction that the source code is not "licensed" in this particular situation has been removed. FYI: Brian also added: "A bit of history might be in order. The codec classes that you used originally were based on some classes included with JAI but not strictly part of JAI. As of Java SE 1.4 an official Image I/O framework was added in javax.imageio.... This frameork supports these formats: Java 1.4: GIF (read only), JPEG, PNG Java 1.5: Added support for BMP and WBMP Java 1.6: Added support for writing GIF The JAI Image I/O Tools packages (jai-imageio-core) were created to support formats handled by JAI but not included in Java SE as well as some new things like JPEG2000." (4) the file com/lowagie/text/pdf/codec/TIFFConstants and some other TIFF related code is derived from LIBTIFF: Copyright (c) 1988-1997 Sam Leffler Copyright (c) 1991-1997 Silicon Graphics, Inc. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that (i) the above copyright notices and this permission notice appear in all copies of the software and related documentation, and (ii) the names of Sam Leffler and Silicon Graphics may not be used in any advertising or publicity relating to the software without the specific, prior written permission of Sam Leffler and Silicon Graphics. THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (5) BidiOrder: As stated in the Javadoc comments, materials from Unicode.org are used in the class com/lowagie/text/pdf/BidiOrder.java The following license applies to these materials: http://www.unicode.org/copyright.html#Exhibit1 EXHIBIT 1 UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/ . Unicode Software includes any source code published in the Unicode Standard or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. COPYRIGHT AND PERMISSION NOTICE Copyright (C) 1991-2007 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html. Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified. THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.src/core/com/lowagie/text/pdf/AcroFields.java100644 0 0 312417 11215636056 16621 0ustar 0 0 /* * Copyright 2003-2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.w3c.dom.Node; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.codec.Base64; /** * Query and change fields in existing documents either by method * calls or by FDF merging. * * @author Paulo Soares (psoares@consiste.pt) */ public class AcroFields { PdfReader reader; PdfWriter writer; HashMap fields; private int topFirst; private HashMap sigNames; private boolean append; public static final int DA_FONT = 0; public static final int DA_SIZE = 1; public static final int DA_COLOR = 2; private HashMap extensionFonts = new HashMap(); private XfaForm xfa; /** * A field type invalid or not found. */ public static final int FIELD_TYPE_NONE = 0; /** * A field type. */ public static final int FIELD_TYPE_PUSHBUTTON = 1; /** * A field type. */ public static final int FIELD_TYPE_CHECKBOX = 2; /** * A field type. */ public static final int FIELD_TYPE_RADIOBUTTON = 3; /** * A field type. */ public static final int FIELD_TYPE_TEXT = 4; /** * A field type. */ public static final int FIELD_TYPE_LIST = 5; /** * A field type. */ public static final int FIELD_TYPE_COMBO = 6; /** * A field type. */ public static final int FIELD_TYPE_SIGNATURE = 7; private boolean lastWasString; /** Holds value of property generateAppearances. */ private boolean generateAppearances = true; private HashMap localFonts = new HashMap(); private float extraMarginLeft; private float extraMarginTop; private ArrayList substitutionFonts; AcroFields(PdfReader reader, PdfWriter writer) { this.reader = reader; this.writer = writer; try { xfa = new XfaForm(reader); } catch (Exception e) { throw new ExceptionConverter(e); } if (writer instanceof PdfStamperImp) { append = ((PdfStamperImp)writer).isAppend(); } fill(); } void fill() { fields = new HashMap(); PdfDictionary top = (PdfDictionary)PdfReader.getPdfObjectRelease(reader.getCatalog().get(PdfName.ACROFORM)); if (top == null) return; PdfArray arrfds = (PdfArray)PdfReader.getPdfObjectRelease(top.get(PdfName.FIELDS)); if (arrfds == null || arrfds.size() == 0) return; for (int k = 1; k <= reader.getNumberOfPages(); ++k) { PdfDictionary page = reader.getPageNRelease(k); PdfArray annots = (PdfArray)PdfReader.getPdfObjectRelease(page.get(PdfName.ANNOTS), page); if (annots == null) continue; for (int j = 0; j < annots.size(); ++j) { PdfDictionary annot = annots.getAsDict(j); if (annot == null) { PdfReader.releaseLastXrefPartial(annots.getAsIndirectObject(j)); continue; } if (!PdfName.WIDGET.equals(annot.getAsName(PdfName.SUBTYPE))) { PdfReader.releaseLastXrefPartial(annots.getAsIndirectObject(j)); continue; } PdfDictionary widget = annot; PdfDictionary dic = new PdfDictionary(); dic.putAll(annot); String name = ""; PdfDictionary value = null; PdfObject lastV = null; while (annot != null) { dic.mergeDifferent(annot); PdfString t = annot.getAsString(PdfName.T); if (t != null) name = t.toUnicodeString() + "." + name; if (lastV == null && annot.get(PdfName.V) != null) lastV = PdfReader.getPdfObjectRelease(annot.get(PdfName.V)); if (value == null && t != null) { value = annot; if (annot.get(PdfName.V) == null && lastV != null) value.put(PdfName.V, lastV); } annot = annot.getAsDict(PdfName.PARENT); } if (name.length() > 0) name = name.substring(0, name.length() - 1); Item item = (Item)fields.get(name); if (item == null) { item = new Item(); fields.put(name, item); } if (value == null) item.addValue(widget); else item.addValue(value); item.addWidget(widget); item.addWidgetRef(annots.getAsIndirectObject(j)); // must be a reference if (top != null) dic.mergeDifferent(top); item.addMerged(dic); item.addPage(k); item.addTabOrder(j); } } // some tools produce invisible signatures without an entry in the page annotation array // look for a single level annotation PdfNumber sigFlags = top.getAsNumber(PdfName.SIGFLAGS); if (sigFlags == null || (sigFlags.intValue() & 1) != 1) return; for (int j = 0; j < arrfds.size(); ++j) { PdfDictionary annot = arrfds.getAsDict(j); if (annot == null) { PdfReader.releaseLastXrefPartial(arrfds.getAsIndirectObject(j)); continue; } if (!PdfName.WIDGET.equals(annot.getAsName(PdfName.SUBTYPE))) { PdfReader.releaseLastXrefPartial(arrfds.getAsIndirectObject(j)); continue; } PdfArray kids = (PdfArray)PdfReader.getPdfObjectRelease(annot.get(PdfName.KIDS)); if (kids != null) continue; PdfDictionary dic = new PdfDictionary(); dic.putAll(annot); PdfString t = annot.getAsString(PdfName.T); if (t == null) continue; String name = t.toUnicodeString(); if (fields.containsKey(name)) continue; Item item = new Item(); fields.put(name, item); item.addValue(dic); item.addWidget(dic); item.addWidgetRef(arrfds.getAsIndirectObject(j)); // must be a reference item.addMerged(dic); item.addPage(-1); item.addTabOrder(-1); } } /** * Gets the list of appearance names. Use it to get the names allowed * with radio and checkbox fields. If the /Opt key exists the values will * also be included. The name 'Off' may also be valid * even if not returned in the list. * * @param fieldName the fully qualified field name * @return the list of names or null if the field does not exist */ public String[] getAppearanceStates(String fieldName) { Item fd = (Item)fields.get(fieldName); if (fd == null) return null; HashMap names = new HashMap(); PdfDictionary vals = fd.getValue(0); PdfString stringOpt = vals.getAsString( PdfName.OPT ); if (stringOpt != null) { names.put(stringOpt.toUnicodeString(), null); } else { PdfArray arrayOpt = vals.getAsArray(PdfName.OPT); if (arrayOpt != null) { for (int k = 0; k < arrayOpt.size(); ++k) { PdfString valStr = arrayOpt.getAsString( k ); if (valStr != null) names.put(valStr.toUnicodeString(), null); } } } for (int k = 0; k < fd.size(); ++k) { PdfDictionary dic = fd.getWidget( k ); dic = dic.getAsDict(PdfName.AP); if (dic == null) continue; dic = dic.getAsDict(PdfName.N); if (dic == null) continue; for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { String name = PdfName.decodeName(((PdfName)it.next()).toString()); names.put(name, null); } } String out[] = new String[names.size()]; return (String[])names.keySet().toArray(out); } private String[] getListOption(String fieldName, int idx) { Item fd = getFieldItem(fieldName); if (fd == null) return null; PdfArray ar = fd.getMerged(0).getAsArray(PdfName.OPT); if (ar == null) return null; String[] ret = new String[ar.size()]; for (int k = 0; k < ar.size(); ++k) { PdfObject obj = ar.getDirectObject( k ); try { if (obj.isArray()) { obj = ((PdfArray)obj).getDirectObject(idx); } if (obj.isString()) ret[k] = ((PdfString)obj).toUnicodeString(); else ret[k] = obj.toString(); } catch (Exception e) { ret[k] = ""; } } return ret; } /** * Gets the list of export option values from fields of type list or combo. * If the field doesn't exist or the field type is not list or combo it will return * null. * * @param fieldName the field name * @return the list of export option values from fields of type list or combo */ public String[] getListOptionExport(String fieldName) { return getListOption(fieldName, 0); } /** * Gets the list of display option values from fields of type list or combo. * If the field doesn't exist or the field type is not list or combo it will return * null. * * @param fieldName the field name * @return the list of export option values from fields of type list or combo */ public String[] getListOptionDisplay(String fieldName) { return getListOption(fieldName, 1); } /** * Sets the option list for fields of type list or combo. One of exportValues * or displayValues may be null but not both. This method will only * set the list but will not set the value or appearance. For that, calling setField() * is required. *

* An example: *

*

     * PdfReader pdf = new PdfReader("input.pdf");
     * PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("output.pdf"));
     * AcroFields af = stp.getAcroFields();
     * af.setListOption("ComboBox", new String[]{"a", "b", "c"}, new String[]{"first", "second", "third"});
     * af.setField("ComboBox", "b");
     * stp.close();
     * 
* * @param fieldName the field name * @param exportValues the export values * @param displayValues the display values * @return true if the operation succeeded, false otherwise */ public boolean setListOption(String fieldName, String[] exportValues, String[] displayValues) { if (exportValues == null && displayValues == null) return false; if (exportValues != null && displayValues != null && exportValues.length != displayValues.length) throw new IllegalArgumentException("The export and the display array must have the same size."); int ftype = getFieldType(fieldName); if (ftype != FIELD_TYPE_COMBO && ftype != FIELD_TYPE_LIST) return false; Item fd = (Item)fields.get(fieldName); String[] sing = null; if (exportValues == null && displayValues != null) sing = displayValues; else if (exportValues != null && displayValues == null) sing = exportValues; PdfArray opt = new PdfArray(); if (sing != null) { for (int k = 0; k < sing.length; ++k) opt.add(new PdfString(sing[k], PdfObject.TEXT_UNICODE)); } else { for (int k = 0; k < exportValues.length; ++k) { PdfArray a = new PdfArray(); a.add(new PdfString(exportValues[k], PdfObject.TEXT_UNICODE)); a.add(new PdfString(displayValues[k], PdfObject.TEXT_UNICODE)); opt.add(a); } } fd.writeToAll( PdfName.OPT, opt, Item.WRITE_VALUE | Item.WRITE_MERGED ); return true; } /** * Gets the field type. The type can be one of: FIELD_TYPE_PUSHBUTTON, * FIELD_TYPE_CHECKBOX, FIELD_TYPE_RADIOBUTTON, * FIELD_TYPE_TEXT, FIELD_TYPE_LIST, * FIELD_TYPE_COMBO or FIELD_TYPE_SIGNATURE. *

* If the field does not exist or is invalid it returns * FIELD_TYPE_NONE. * * @param fieldName the field name * @return the field type */ public int getFieldType(String fieldName) { Item fd = getFieldItem(fieldName); if (fd == null) return FIELD_TYPE_NONE; PdfDictionary merged = fd.getMerged( 0 ); PdfName type = merged.getAsName(PdfName.FT); if (type == null) return FIELD_TYPE_NONE; int ff = 0; PdfNumber ffo = merged.getAsNumber(PdfName.FF); if (ffo != null) { ff = ffo.intValue(); } if (PdfName.BTN.equals(type)) { if ((ff & PdfFormField.FF_PUSHBUTTON) != 0) return FIELD_TYPE_PUSHBUTTON; if ((ff & PdfFormField.FF_RADIO) != 0) return FIELD_TYPE_RADIOBUTTON; else return FIELD_TYPE_CHECKBOX; } else if (PdfName.TX.equals(type)) { return FIELD_TYPE_TEXT; } else if (PdfName.CH.equals(type)) { if ((ff & PdfFormField.FF_COMBO) != 0) return FIELD_TYPE_COMBO; else return FIELD_TYPE_LIST; } else if (PdfName.SIG.equals(type)) { return FIELD_TYPE_SIGNATURE; } return FIELD_TYPE_NONE; } /** * Export the fields as a FDF. * * @param writer the FDF writer */ public void exportAsFdf(FdfWriter writer) { for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); Item item = (Item)entry.getValue(); String name = (String)entry.getKey(); PdfObject v = item.getMerged(0).get(PdfName.V); if (v == null) continue; String value = getField(name); if (lastWasString) writer.setFieldAsString(name, value); else writer.setFieldAsName(name, value); } } /** * Renames a field. Only the last part of the name can be renamed. For example, * if the original field is "ab.cd.ef" only the "ef" part can be renamed. * * @param oldName the old field name * @param newName the new field name * @return true if the renaming was successful, false * otherwise */ public boolean renameField(String oldName, String newName) { int idx1 = oldName.lastIndexOf('.') + 1; int idx2 = newName.lastIndexOf('.') + 1; if (idx1 != idx2) return false; if (!oldName.substring(0, idx1).equals(newName.substring(0, idx2))) return false; if (fields.containsKey(newName)) return false; Item item = (Item)fields.get(oldName); if (item == null) return false; newName = newName.substring(idx2); PdfString ss = new PdfString(newName, PdfObject.TEXT_UNICODE); item.writeToAll( PdfName.T, ss, Item.WRITE_VALUE | Item.WRITE_MERGED); item.markUsed( this, Item.WRITE_VALUE ); fields.remove(oldName); fields.put(newName, item); return true; } public static Object[] splitDAelements(String da) { try { PRTokeniser tk = new PRTokeniser(PdfEncodings.convertToBytes(da, null)); ArrayList stack = new ArrayList(); Object ret[] = new Object[3]; while (tk.nextToken()) { if (tk.getTokenType() == PRTokeniser.TK_COMMENT) continue; if (tk.getTokenType() == PRTokeniser.TK_OTHER) { String operator = tk.getStringValue(); if (operator.equals("Tf")) { if (stack.size() >= 2) { ret[DA_FONT] = stack.get(stack.size() - 2); ret[DA_SIZE] = new Float((String)stack.get(stack.size() - 1)); } } else if (operator.equals("g")) { if (stack.size() >= 1) { float gray = new Float((String)stack.get(stack.size() - 1)).floatValue(); if (gray != 0) ret[DA_COLOR] = new GrayColor(gray); } } else if (operator.equals("rg")) { if (stack.size() >= 3) { float red = new Float((String)stack.get(stack.size() - 3)).floatValue(); float green = new Float((String)stack.get(stack.size() - 2)).floatValue(); float blue = new Float((String)stack.get(stack.size() - 1)).floatValue(); ret[DA_COLOR] = new Color(red, green, blue); } } else if (operator.equals("k")) { if (stack.size() >= 4) { float cyan = new Float((String)stack.get(stack.size() - 4)).floatValue(); float magenta = new Float((String)stack.get(stack.size() - 3)).floatValue(); float yellow = new Float((String)stack.get(stack.size() - 2)).floatValue(); float black = new Float((String)stack.get(stack.size() - 1)).floatValue(); ret[DA_COLOR] = new CMYKColor(cyan, magenta, yellow, black); } } stack.clear(); } else stack.add(tk.getStringValue()); } return ret; } catch (IOException ioe) { throw new ExceptionConverter(ioe); } } public void decodeGenericDictionary(PdfDictionary merged, BaseField tx) throws IOException, DocumentException { int flags = 0; // the text size and color PdfString da = merged.getAsString(PdfName.DA); if (da != null) { Object dab[] = splitDAelements(da.toUnicodeString()); if (dab[DA_SIZE] != null) tx.setFontSize(((Float)dab[DA_SIZE]).floatValue()); if (dab[DA_COLOR] != null) tx.setTextColor((Color)dab[DA_COLOR]); if (dab[DA_FONT] != null) { PdfDictionary font = merged.getAsDict(PdfName.DR); if (font != null) { font = font.getAsDict(PdfName.FONT); if (font != null) { PdfObject po = font.get(new PdfName((String)dab[DA_FONT])); if (po != null && po.type() == PdfObject.INDIRECT) { PRIndirectReference por = (PRIndirectReference)po; BaseFont bp = new DocumentFont((PRIndirectReference)po); tx.setFont(bp); Integer porkey = new Integer(por.getNumber()); BaseFont porf = (BaseFont)extensionFonts.get(porkey); if (porf == null) { if (!extensionFonts.containsKey(porkey)) { PdfDictionary fo = (PdfDictionary)PdfReader.getPdfObject(po); PdfDictionary fd = fo.getAsDict(PdfName.FONTDESCRIPTOR); if (fd != null) { PRStream prs = (PRStream)PdfReader.getPdfObject(fd.get(PdfName.FONTFILE2)); if (prs == null) prs = (PRStream)PdfReader.getPdfObject(fd.get(PdfName.FONTFILE3)); if (prs == null) { extensionFonts.put(porkey, null); } else { try { porf = BaseFont.createFont("font.ttf", BaseFont.IDENTITY_H, true, false, PdfReader.getStreamBytes(prs), null); } catch (Exception e) { } extensionFonts.put(porkey, porf); } } } } if (tx instanceof TextField) ((TextField)tx).setExtensionFont(porf); } else { BaseFont bf = (BaseFont)localFonts.get(dab[DA_FONT]); if (bf == null) { String fn[] = (String[])stdFieldFontNames.get(dab[DA_FONT]); if (fn != null) { try { String enc = "winansi"; if (fn.length > 1) enc = fn[1]; bf = BaseFont.createFont(fn[0], enc, false); tx.setFont(bf); } catch (Exception e) { // empty } } } else tx.setFont(bf); } } } } } //rotation, border and background color PdfDictionary mk = merged.getAsDict(PdfName.MK); if (mk != null) { PdfArray ar = mk.getAsArray(PdfName.BC); Color border = getMKColor(ar); tx.setBorderColor(border); if (border != null) tx.setBorderWidth(1); ar = mk.getAsArray(PdfName.BG); tx.setBackgroundColor(getMKColor(ar)); PdfNumber rotation = mk.getAsNumber(PdfName.R); if (rotation != null) tx.setRotation(rotation.intValue()); } //flags PdfNumber nfl = merged.getAsNumber(PdfName.F); flags = 0; tx.setVisibility(BaseField.VISIBLE_BUT_DOES_NOT_PRINT); if (nfl != null) { flags = nfl.intValue(); if ((flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) != 0) tx.setVisibility(BaseField.HIDDEN); else if ((flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_NOVIEW) != 0) tx.setVisibility(BaseField.HIDDEN_BUT_PRINTABLE); else if ((flags & PdfFormField.FLAGS_PRINT) != 0) tx.setVisibility(BaseField.VISIBLE); } //multiline nfl = merged.getAsNumber(PdfName.FF); flags = 0; if (nfl != null) flags = nfl.intValue(); tx.setOptions(flags); if ((flags & PdfFormField.FF_COMB) != 0) { PdfNumber maxLen = merged.getAsNumber(PdfName.MAXLEN); int len = 0; if (maxLen != null) len = maxLen.intValue(); tx.setMaxCharacterLength(len); } //alignment nfl = merged.getAsNumber(PdfName.Q); if (nfl != null) { if (nfl.intValue() == PdfFormField.Q_CENTER) tx.setAlignment(Element.ALIGN_CENTER); else if (nfl.intValue() == PdfFormField.Q_RIGHT) tx.setAlignment(Element.ALIGN_RIGHT); } //border styles PdfDictionary bs = merged.getAsDict(PdfName.BS); if (bs != null) { PdfNumber w = bs.getAsNumber(PdfName.W); if (w != null) tx.setBorderWidth(w.floatValue()); PdfName s = bs.getAsName(PdfName.S); if (PdfName.D.equals(s)) tx.setBorderStyle(PdfBorderDictionary.STYLE_DASHED); else if (PdfName.B.equals(s)) tx.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED); else if (PdfName.I.equals(s)) tx.setBorderStyle(PdfBorderDictionary.STYLE_INSET); else if (PdfName.U.equals(s)) tx.setBorderStyle(PdfBorderDictionary.STYLE_UNDERLINE); } else { PdfArray bd = merged.getAsArray(PdfName.BORDER); if (bd != null) { if (bd.size() >= 3) tx.setBorderWidth(bd.getAsNumber(2).floatValue()); if (bd.size() >= 4) tx.setBorderStyle(PdfBorderDictionary.STYLE_DASHED); } } } PdfAppearance getAppearance(PdfDictionary merged, String text, String fieldName) throws IOException, DocumentException { topFirst = 0; TextField tx = null; if (fieldCache == null || !fieldCache.containsKey(fieldName)) { tx = new TextField(writer, null, null); tx.setExtraMargin(extraMarginLeft, extraMarginTop); tx.setBorderWidth(0); tx.setSubstitutionFonts(substitutionFonts); decodeGenericDictionary(merged, tx); //rect PdfArray rect = merged.getAsArray(PdfName.RECT); Rectangle box = PdfReader.getNormalizedRectangle(rect); if (tx.getRotation() == 90 || tx.getRotation() == 270) box = box.rotate(); tx.setBox(box); if (fieldCache != null) fieldCache.put(fieldName, tx); } else { tx = (TextField)fieldCache.get(fieldName); tx.setWriter(writer); } PdfName fieldType = merged.getAsName(PdfName.FT); if (PdfName.TX.equals(fieldType)) { tx.setText(text); return tx.getAppearance(); } if (!PdfName.CH.equals(fieldType)) throw new DocumentException("An appearance was requested without a variable text field."); PdfArray opt = merged.getAsArray(PdfName.OPT); int flags = 0; PdfNumber nfl = merged.getAsNumber(PdfName.FF); if (nfl != null) flags = nfl.intValue(); if ((flags & PdfFormField.FF_COMBO) != 0 && opt == null) { tx.setText(text); return tx.getAppearance(); } if (opt != null) { String choices[] = new String[opt.size()]; String choicesExp[] = new String[opt.size()]; for (int k = 0; k < opt.size(); ++k) { PdfObject obj = opt.getPdfObject(k); if (obj.isString()) { choices[k] = choicesExp[k] = ((PdfString)obj).toUnicodeString(); } else { PdfArray a = (PdfArray) obj; choicesExp[k] = a.getAsString(0).toUnicodeString(); choices[k] = a.getAsString(1).toUnicodeString(); } } if ((flags & PdfFormField.FF_COMBO) != 0) { for (int k = 0; k < choices.length; ++k) { if (text.equals(choicesExp[k])) { text = choices[k]; break; } } tx.setText(text); return tx.getAppearance(); } int idx = 0; for (int k = 0; k < choicesExp.length; ++k) { if (text.equals(choicesExp[k])) { idx = k; break; } } tx.setChoices(choices); tx.setChoiceExports(choicesExp); tx.setChoiceSelection(idx); } PdfAppearance app = tx.getListAppearance(); topFirst = tx.getTopFirst(); return app; } Color getMKColor(PdfArray ar) { if (ar == null) return null; switch (ar.size()) { case 1: return new GrayColor(ar.getAsNumber(0).floatValue()); case 3: return new Color(ExtendedColor.normalize(ar.getAsNumber(0).floatValue()), ExtendedColor.normalize(ar.getAsNumber(1).floatValue()), ExtendedColor.normalize(ar.getAsNumber(2).floatValue())); case 4: return new CMYKColor(ar.getAsNumber(0).floatValue(), ar.getAsNumber(1).floatValue(), ar.getAsNumber(2).floatValue(), ar.getAsNumber(3).floatValue()); default: return null; } } /** * Gets the field value. * * @param name the fully qualified field name * @return the field value */ public String getField(String name) { if (xfa.isXfaPresent()) { name = xfa.findFieldName(name, this); if (name == null) return null; name = XfaForm.Xml2Som.getShortName(name); return XfaForm.getNodeText(xfa.findDatasetsNode(name)); } Item item = (Item)fields.get(name); if (item == null) return null; lastWasString = false; PdfDictionary mergedDict = item.getMerged( 0 ); // Jose A. Rodriguez posted a fix to the mailing list (May 11, 2009) // explaining that the value can also be a stream value // the fix was made against an old iText version. Bruno adapted it. PdfObject v = PdfReader.getPdfObject(mergedDict.get(PdfName.V)); if (v == null) return ""; if (v instanceof PRStream) { byte[] valBytes; try { valBytes = PdfReader.getStreamBytes((PRStream)v); return new String(valBytes); } catch (IOException e) { throw new ExceptionConverter(e); } } PdfName type = mergedDict.getAsName(PdfName.FT); if (PdfName.BTN.equals(type)) { PdfNumber ff = mergedDict.getAsNumber(PdfName.FF); int flags = 0; if (ff != null) flags = ff.intValue(); if ((flags & PdfFormField.FF_PUSHBUTTON) != 0) return ""; String value = ""; if (v instanceof PdfName) value = PdfName.decodeName(v.toString()); else if (v instanceof PdfString) value = ((PdfString)v).toUnicodeString(); PdfArray opts = item.getValue(0).getAsArray(PdfName.OPT); if (opts != null) { int idx = 0; try { idx = Integer.parseInt(value); PdfString ps = opts.getAsString(idx); value = ps.toUnicodeString(); lastWasString = true; } catch (Exception e) { } } return value; } if (v instanceof PdfString) { lastWasString = true; return ((PdfString)v).toUnicodeString(); } else if (v instanceof PdfName) { return PdfName.decodeName(v.toString()); } else return ""; } /** * Gets the field values of a Choice field. * * @param name the fully qualified field name * @return the field value * @since 2.1.3 */ public String[] getListSelection(String name) { String[] ret; String s = getField(name); if (s == null) { ret = new String[]{}; } else { ret = new String[]{ s }; } Item item = (Item)fields.get(name); if (item == null) return ret; //PdfName type = (PdfName)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.FT)); //if (!PdfName.CH.equals(type)) { // return ret; //} PdfArray values = item.getMerged(0).getAsArray(PdfName.I); if (values == null) return ret; ret = new String[values.size()]; String[] options = getListOptionExport(name); PdfNumber n; int idx = 0; for (Iterator i = values.listIterator(); i.hasNext(); ) { n = (PdfNumber)i.next(); ret[idx++] = options[n.intValue()]; } return ret; } /** * Sets a field property. Valid property names are: *

*

    *
  • textfont - sets the text font. The value for this entry is a BaseFont.
    *
  • textcolor - sets the text color. The value for this entry is a java.awt.Color.
    *
  • textsize - sets the text size. The value for this entry is a Float. *
  • bgcolor - sets the background color. The value for this entry is a java.awt.Color. * If null removes the background.
    *
  • bordercolor - sets the border color. The value for this entry is a java.awt.Color. * If null removes the border.
    *
* * @param field the field name * @param name the property name * @param value the property value * @param inst an array of int indexing into AcroField.Item.merged elements to process. * Set to null to process all * @return true if the property exists, false otherwise */ public boolean setFieldProperty(String field, String name, Object value, int inst[]) { if (writer == null) throw new RuntimeException("This AcroFields instance is read-only."); try { Item item = (Item)fields.get(field); if (item == null) return false; InstHit hit = new InstHit(inst); PdfDictionary merged; PdfString da; if (name.equalsIgnoreCase("textfont")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { merged = item.getMerged( k ); da = merged.getAsString(PdfName.DA); PdfDictionary dr = merged.getAsDict(PdfName.DR); if (da != null && dr != null) { Object dao[] = splitDAelements(da.toUnicodeString()); PdfAppearance cb = new PdfAppearance(); if (dao[DA_FONT] != null) { BaseFont bf = (BaseFont)value; PdfName psn = (PdfName)PdfAppearance.stdFieldFontNames.get(bf.getPostscriptFontName()); if (psn == null) { psn = new PdfName(bf.getPostscriptFontName()); } PdfDictionary fonts = dr.getAsDict(PdfName.FONT); if (fonts == null) { fonts = new PdfDictionary(); dr.put(PdfName.FONT, fonts); } PdfIndirectReference fref = (PdfIndirectReference)fonts.get(psn); PdfDictionary top = reader.getCatalog().getAsDict(PdfName.ACROFORM); markUsed(top); dr = top.getAsDict(PdfName.DR); if (dr == null) { dr = new PdfDictionary(); top.put(PdfName.DR, dr); } markUsed(dr); PdfDictionary fontsTop = dr.getAsDict(PdfName.FONT); if (fontsTop == null) { fontsTop = new PdfDictionary(); dr.put(PdfName.FONT, fontsTop); } markUsed(fontsTop); PdfIndirectReference frefTop = (PdfIndirectReference)fontsTop.get(psn); if (frefTop != null) { if (fref == null) fonts.put(psn, frefTop); } else if (fref == null) { FontDetails fd; if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { fd = new FontDetails(null, ((DocumentFont)bf).getIndirectReference(), bf); } else { bf.setSubset(false); fd = writer.addSimple(bf); localFonts.put(psn.toString().substring(1), bf); } fontsTop.put(psn, fd.getIndirectReference()); fonts.put(psn, fd.getIndirectReference()); } ByteBuffer buf = cb.getInternalBuffer(); buf.append(psn.getBytes()).append(' ').append(((Float)dao[DA_SIZE]).floatValue()).append(" Tf "); if (dao[DA_COLOR] != null) cb.setColorFill((Color)dao[DA_COLOR]); PdfString s = new PdfString(cb.toString()); item.getMerged(k).put(PdfName.DA, s); item.getWidget(k).put(PdfName.DA, s); markUsed(item.getWidget(k)); } } } } } else if (name.equalsIgnoreCase("textcolor")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { merged = item.getMerged( k ); da = merged.getAsString(PdfName.DA); if (da != null) { Object dao[] = splitDAelements(da.toUnicodeString()); PdfAppearance cb = new PdfAppearance(); if (dao[DA_FONT] != null) { ByteBuffer buf = cb.getInternalBuffer(); buf.append(new PdfName((String)dao[DA_FONT]).getBytes()).append(' ').append(((Float)dao[DA_SIZE]).floatValue()).append(" Tf "); cb.setColorFill((Color)value); PdfString s = new PdfString(cb.toString()); item.getMerged(k).put(PdfName.DA, s); item.getWidget(k).put(PdfName.DA, s); markUsed(item.getWidget(k)); } } } } } else if (name.equalsIgnoreCase("textsize")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { merged = item.getMerged( k ); da = merged.getAsString(PdfName.DA); if (da != null) { Object dao[] = splitDAelements(da.toUnicodeString()); PdfAppearance cb = new PdfAppearance(); if (dao[DA_FONT] != null) { ByteBuffer buf = cb.getInternalBuffer(); buf.append(new PdfName((String)dao[DA_FONT]).getBytes()).append(' ').append(((Float)value).floatValue()).append(" Tf "); if (dao[DA_COLOR] != null) cb.setColorFill((Color)dao[DA_COLOR]); PdfString s = new PdfString(cb.toString()); item.getMerged(k).put(PdfName.DA, s); item.getWidget(k).put(PdfName.DA, s); markUsed(item.getWidget(k)); } } } } } else if (name.equalsIgnoreCase("bgcolor") || name.equalsIgnoreCase("bordercolor")) { PdfName dname = (name.equalsIgnoreCase("bgcolor") ? PdfName.BG : PdfName.BC); for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { merged = item.getMerged( k ); PdfDictionary mk = merged.getAsDict(PdfName.MK); if (mk == null) { if (value == null) return true; mk = new PdfDictionary(); item.getMerged(k).put(PdfName.MK, mk); item.getWidget(k).put(PdfName.MK, mk); markUsed(item.getWidget(k)); } else { markUsed( mk ); } if (value == null) mk.remove(dname); else mk.put(dname, PdfFormField.getMKColor((Color)value)); } } } else return false; return true; } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Sets a field property. Valid property names are: *

*

    *
  • flags - a set of flags specifying various characteristics of the field's widget annotation. * The value of this entry replaces that of the F entry in the form's corresponding annotation dictionary.
    *
  • setflags - a set of flags to be set (turned on) in the F entry of the form's corresponding * widget annotation dictionary. Bits equal to 1 cause the corresponding bits in F to be set to 1.
    *
  • clrflags - a set of flags to be cleared (turned off) in the F entry of the form's corresponding * widget annotation dictionary. Bits equal to 1 cause the corresponding * bits in F to be set to 0.
    *
  • fflags - a set of flags specifying various characteristics of the field. The value * of this entry replaces that of the Ff entry in the form's corresponding field dictionary.
    *
  • setfflags - a set of flags to be set (turned on) in the Ff entry of the form's corresponding * field dictionary. Bits equal to 1 cause the corresponding bits in Ff to be set to 1.
    *
  • clrfflags - a set of flags to be cleared (turned off) in the Ff entry of the form's corresponding * field dictionary. Bits equal to 1 cause the corresponding bits in Ff * to be set to 0.
    *
* * @param field the field name * @param name the property name * @param value the property value * @param inst an array of int indexing into AcroField.Item.merged elements to process. * Set to null to process all * @return true if the property exists, false otherwise */ public boolean setFieldProperty(String field, String name, int value, int inst[]) { if (writer == null) throw new RuntimeException("This AcroFields instance is read-only."); Item item = (Item)fields.get(field); if (item == null) return false; InstHit hit = new InstHit(inst); if (name.equalsIgnoreCase("flags")) { PdfNumber num = new PdfNumber(value); for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { item.getMerged(k).put(PdfName.F, num); item.getWidget(k).put(PdfName.F, num); markUsed(item.getWidget(k)); } } } else if (name.equalsIgnoreCase("setflags")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { PdfNumber num = item.getWidget(k).getAsNumber(PdfName.F); int val = 0; if (num != null) val = num.intValue(); num = new PdfNumber(val | value); item.getMerged(k).put(PdfName.F, num); item.getWidget(k).put(PdfName.F, num); markUsed(item.getWidget(k)); } } } else if (name.equalsIgnoreCase("clrflags")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { PdfDictionary widget = item.getWidget( k ); PdfNumber num = widget.getAsNumber(PdfName.F); int val = 0; if (num != null) val = num.intValue(); num = new PdfNumber(val & (~value)); item.getMerged(k).put(PdfName.F, num); widget.put(PdfName.F, num); markUsed(widget); } } } else if (name.equalsIgnoreCase("fflags")) { PdfNumber num = new PdfNumber(value); for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { item.getMerged(k).put(PdfName.FF, num); item.getValue(k).put(PdfName.FF, num); markUsed(item.getValue(k)); } } } else if (name.equalsIgnoreCase("setfflags")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { PdfDictionary valDict = item.getValue( k ); PdfNumber num = valDict.getAsNumber( PdfName.FF ); int val = 0; if (num != null) val = num.intValue(); num = new PdfNumber(val | value); item.getMerged(k).put(PdfName.FF, num); valDict.put(PdfName.FF, num); markUsed(valDict); } } } else if (name.equalsIgnoreCase("clrfflags")) { for (int k = 0; k < item.size(); ++k) { if (hit.isHit(k)) { PdfDictionary valDict = item.getValue( k ); PdfNumber num = valDict.getAsNumber(PdfName.FF); int val = 0; if (num != null) val = num.intValue(); num = new PdfNumber(val & (~value)); item.getMerged(k).put(PdfName.FF, num); valDict.put(PdfName.FF, num); markUsed(valDict); } } } else return false; return true; } /** * Merges an XML data structure into this form. * * @param n the top node of the data structure * @throws java.io.IOException on error * @throws com.lowagie.text.DocumentException o error */ public void mergeXfaData(Node n) throws IOException, DocumentException { XfaForm.Xml2SomDatasets data = new XfaForm.Xml2SomDatasets(n); for (Iterator it = data.getOrder().iterator(); it.hasNext();) { String name = (String)it.next(); String text = XfaForm.getNodeText((Node)data.getName2Node().get(name)); setField(name, text); } } /** * Sets the fields by FDF merging. * * @param fdf the FDF form * @throws IOException on error * @throws DocumentException on error */ public void setFields(FdfReader fdf) throws IOException, DocumentException { HashMap fd = fdf.getFields(); for (Iterator i = fd.keySet().iterator(); i.hasNext();) { String f = (String)i.next(); String v = fdf.getFieldValue(f); if (v != null) setField(f, v); } } /** * Sets the fields by XFDF merging. * * @param xfdf the XFDF form * @throws IOException on error * @throws DocumentException on error */ public void setFields(XfdfReader xfdf) throws IOException, DocumentException { HashMap fd = xfdf.getFields(); for (Iterator i = fd.keySet().iterator(); i.hasNext();) { String f = (String)i.next(); String v = xfdf.getFieldValue(f); if (v != null) setField(f, v); List l = xfdf.getListValues(f); if (l != null) setListSelection(v, (String[])l.toArray(new String[l.size()])); } } /** * Regenerates the field appearance. * This is useful when you change a field property, but not its value, * for instance form.setFieldProperty("f", "bgcolor", Color.BLUE, null); * This won't have any effect, unless you use regenerateField("f") after changing * the property. * * @param name the fully qualified field name or the partial name in the case of XFA forms * @throws IOException on error * @throws DocumentException on error * @return true if the field was found and changed, * false otherwise */ public boolean regenerateField(String name) throws IOException, DocumentException { String value = getField(name); return setField(name, value, value); } /** * Sets the field value. * * @param name the fully qualified field name or the partial name in the case of XFA forms * @param value the field value * @throws IOException on error * @throws DocumentException on error * @return true if the field was found and changed, * false otherwise */ public boolean setField(String name, String value) throws IOException, DocumentException { return setField(name, value, null); } /** * Sets the field value and the display string. The display string * is used to build the appearance in the cases where the value * is modified by Acrobat with JavaScript and the algorithm is * known. * * @param name the fully qualified field name or the partial name in the case of XFA forms * @param value the field value * @param display the string that is used for the appearance. If null * the value parameter will be used * @return true if the field was found and changed, * false otherwise * @throws IOException on error * @throws DocumentException on error */ public boolean setField(String name, String value, String display) throws IOException, DocumentException { if (writer == null) throw new DocumentException("This AcroFields instance is read-only."); if (xfa.isXfaPresent()) { name = xfa.findFieldName(name, this); if (name == null) return false; String shortName = XfaForm.Xml2Som.getShortName(name); Node xn = xfa.findDatasetsNode(shortName); if (xn == null) { xn = xfa.getDatasetsSom().insertNode(xfa.getDatasetsNode(), shortName); } xfa.setNodeText(xn, value); } Item item = (Item)fields.get(name); if (item == null) return false; PdfDictionary merged = item.getMerged( 0 ); PdfName type = merged.getAsName(PdfName.FT); if (PdfName.TX.equals(type)) { PdfNumber maxLen = merged.getAsNumber(PdfName.MAXLEN); int len = 0; if (maxLen != null) len = maxLen.intValue(); if (len > 0) value = value.substring(0, Math.min(len, value.length())); } if (display == null) display = value; if (PdfName.TX.equals(type) || PdfName.CH.equals(type)) { PdfString v = new PdfString(value, PdfObject.TEXT_UNICODE); for (int idx = 0; idx < item.size(); ++idx) { PdfDictionary valueDic = item.getValue(idx); valueDic.put(PdfName.V, v); valueDic.remove(PdfName.I); markUsed(valueDic); merged = item.getMerged(idx); merged.remove(PdfName.I); merged.put(PdfName.V, v); PdfDictionary widget = item.getWidget(idx); if (generateAppearances) { PdfAppearance app = getAppearance(merged, display, name); if (PdfName.CH.equals(type)) { PdfNumber n = new PdfNumber(topFirst); widget.put(PdfName.TI, n); merged.put(PdfName.TI, n); } PdfDictionary appDic = widget.getAsDict(PdfName.AP); if (appDic == null) { appDic = new PdfDictionary(); widget.put(PdfName.AP, appDic); merged.put(PdfName.AP, appDic); } appDic.put(PdfName.N, app.getIndirectReference()); writer.releaseTemplate(app); } else { widget.remove(PdfName.AP); merged.remove(PdfName.AP); } markUsed(widget); } return true; } else if (PdfName.BTN.equals(type)) { PdfNumber ff = item.getMerged(0).getAsNumber(PdfName.FF); int flags = 0; if (ff != null) flags = ff.intValue(); if ((flags & PdfFormField.FF_PUSHBUTTON) != 0) { //we'll assume that the value is an image in base64 Image img; try { img = Image.getInstance(Base64.decode(value)); } catch (Exception e) { return false; } PushbuttonField pb = getNewPushbuttonFromField(name); pb.setImage(img); replacePushbuttonField(name, pb.getField()); return true; } PdfName v = new PdfName(value); ArrayList lopt = new ArrayList(); PdfArray opts = item.getValue(0).getAsArray(PdfName.OPT); if (opts != null) { for (int k = 0; k < opts.size(); ++k) { PdfString valStr = opts.getAsString(k); if (valStr != null) lopt.add(valStr.toUnicodeString()); else lopt.add(null); } } int vidx = lopt.indexOf(value); PdfName valt = null; PdfName vt; if (vidx >= 0) { vt = valt = new PdfName(String.valueOf(vidx)); } else vt = v; for (int idx = 0; idx < item.size(); ++idx) { merged = item.getMerged(idx); PdfDictionary widget = item.getWidget(idx); PdfDictionary valDict = item.getValue(idx); markUsed(item.getValue(idx)); if (valt != null) { PdfString ps = new PdfString(value, PdfObject.TEXT_UNICODE); valDict.put(PdfName.V, ps); merged.put(PdfName.V, ps); } else { valDict.put(PdfName.V, v); merged.put(PdfName.V, v); } markUsed(widget); if (isInAP(widget, vt)) { merged.put(PdfName.AS, vt); widget.put(PdfName.AS, vt); } else { merged.put(PdfName.AS, PdfName.Off); widget.put(PdfName.AS, PdfName.Off); } } return true; } return false; } /** * Sets different values in a list selection. * No appearance is generated yet; nor does the code check if multiple select is allowed. * * @param name the name of the field * @param value an array with values that need to be selected * @return true only if the field value was changed * @since 2.1.4 */ public boolean setListSelection(String name, String[] value) throws IOException, DocumentException { Item item = getFieldItem(name); if (item == null) return false; PdfName type = item.getMerged(0).getAsName(PdfName.FT); if (!PdfName.CH.equals(type)) { return false; } String[] options = getListOptionExport(name); PdfArray array = new PdfArray(); for (int i = 0; i < value.length; i++) { for (int j = 0; j < options.length; j++) { if (options[j].equals(value[i])) { array.add(new PdfNumber(j)); } } } item.writeToAll(PdfName.I, array, Item.WRITE_MERGED | Item.WRITE_VALUE); item.writeToAll(PdfName.V, null, Item.WRITE_MERGED | Item.WRITE_VALUE); item.writeToAll(PdfName.AP, null, Item.WRITE_MERGED | Item.WRITE_WIDGET); item.markUsed( this, Item.WRITE_VALUE | Item.WRITE_WIDGET ); return true; } boolean isInAP(PdfDictionary dic, PdfName check) { PdfDictionary appDic = dic.getAsDict(PdfName.AP); if (appDic == null) return false; PdfDictionary NDic = appDic.getAsDict(PdfName.N); return (NDic != null && NDic.get(check) != null); } /** * Gets all the fields. The fields are keyed by the fully qualified field name and * the value is an instance of AcroFields.Item. * * @return all the fields */ public HashMap getFields() { return fields; } /** * Gets the field structure. * * @param name the name of the field * @return the field structure or null if the field * does not exist */ public Item getFieldItem(String name) { if (xfa.isXfaPresent()) { name = xfa.findFieldName(name, this); if (name == null) return null; } return (Item)fields.get(name); } /** * Gets the long XFA translated name. * * @param name the name of the field * @return the long field name */ public String getTranslatedFieldName(String name) { if (xfa.isXfaPresent()) { String namex = xfa.findFieldName(name, this); if (namex != null) name = namex; } return name; } /** * Gets the field box positions in the document. The return is an array of float * multiple of 5. For each of this groups the values are: [page, llx, lly, urx, * ury]. The coordinates have the page rotation in consideration. * * @param name the field name * @return the positions or null if field does not exist */ public float[] getFieldPositions(String name) { Item item = getFieldItem(name); if (item == null) return null; float ret[] = new float[item.size() * 5]; int ptr = 0; for (int k = 0; k < item.size(); ++k) { try { PdfDictionary wd = item.getWidget(k); PdfArray rect = wd.getAsArray(PdfName.RECT); if (rect == null) continue; Rectangle r = PdfReader.getNormalizedRectangle(rect); int page = item.getPage(k).intValue(); int rotation = reader.getPageRotation(page); ret[ptr++] = page; if (rotation != 0) { Rectangle pageSize = reader.getPageSize(page); switch (rotation) { case 270: r = new Rectangle( pageSize.getTop() - r.getBottom(), r.getLeft(), pageSize.getTop() - r.getTop(), r.getRight()); break; case 180: r = new Rectangle( pageSize.getRight() - r.getLeft(), pageSize.getTop() - r.getBottom(), pageSize.getRight() - r.getRight(), pageSize.getTop() - r.getTop()); break; case 90: r = new Rectangle( r.getBottom(), pageSize.getRight() - r.getLeft(), r.getTop(), pageSize.getRight() - r.getRight()); break; } r.normalize(); } ret[ptr++] = r.getLeft(); ret[ptr++] = r.getBottom(); ret[ptr++] = r.getRight(); ret[ptr++] = r.getTop(); } catch (Exception e) { // empty on purpose } } if (ptr < ret.length) { float ret2[] = new float[ptr]; System.arraycopy(ret, 0, ret2, 0, ptr); return ret2; } return ret; } private int removeRefFromArray(PdfArray array, PdfObject refo) { if (refo == null || !refo.isIndirect()) return array.size(); PdfIndirectReference ref = (PdfIndirectReference)refo; for (int j = 0; j < array.size(); ++j) { PdfObject obj = array.getPdfObject(j); if (!obj.isIndirect()) continue; if (((PdfIndirectReference)obj).getNumber() == ref.getNumber()) array.remove(j--); } return array.size(); } /** * Removes all the fields from page. * * @param page the page to remove the fields from * @return true if any field was removed, false otherwise */ public boolean removeFieldsFromPage(int page) { if (page < 1) return false; String names[] = new String[fields.size()]; fields.keySet().toArray(names); boolean found = false; for (int k = 0; k < names.length; ++k) { boolean fr = removeField(names[k], page); found = (found || fr); } return found; } /** * Removes a field from the document. If page equals -1 all the fields with this * name are removed from the document otherwise only the fields in * that particular page are removed. * * @param name the field name * @param page the page to remove the field from or -1 to remove it from all the pages * @return true if the field exists, false otherwise */ public boolean removeField(String name, int page) { Item item = getFieldItem(name); if (item == null) return false; PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM), reader.getCatalog()); if (acroForm == null) return false; PdfArray arrayf = acroForm.getAsArray(PdfName.FIELDS); if (arrayf == null) return false; for (int k = 0; k < item.size(); ++k) { int pageV = item.getPage(k).intValue(); if (page != -1 && page != pageV) continue; PdfIndirectReference ref = item.getWidgetRef(k); PdfDictionary wd = item.getWidget( k ); PdfDictionary pageDic = reader.getPageN(pageV); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots != null) { if (removeRefFromArray(annots, ref) == 0) { pageDic.remove(PdfName.ANNOTS); markUsed(pageDic); } else markUsed(annots); } PdfReader.killIndirect(ref); PdfIndirectReference kid = ref; while ((ref = wd.getAsIndirectObject(PdfName.PARENT)) != null) { wd = wd.getAsDict( PdfName.PARENT ); PdfArray kids = wd.getAsArray(PdfName.KIDS); if (removeRefFromArray(kids, kid) != 0) break; kid = ref; PdfReader.killIndirect(ref); } if (ref == null) { removeRefFromArray(arrayf, kid); markUsed(arrayf); } if (page != -1) { item.remove( k ); --k; } } if (page == -1 || item.size() == 0) fields.remove(name); return true; } /** * Removes a field from the document. * * @param name the field name * @return true if the field exists, false otherwise */ public boolean removeField(String name) { return removeField(name, -1); } /** * Gets the property generateAppearances. * * @return the property generateAppearances */ public boolean isGenerateAppearances() { return generateAppearances; } /** * Sets the option to generate appearances. Not generating appearances * will speed-up form filling but the results can be * unexpected in Acrobat. Don't use it unless your environment is well * controlled. The default is true. * * @param generateAppearances the option to generate appearances */ public void setGenerateAppearances(boolean generateAppearances) { this.generateAppearances = generateAppearances; PdfDictionary top = reader.getCatalog().getAsDict(PdfName.ACROFORM); if (generateAppearances) top.remove(PdfName.NEEDAPPEARANCES); else top.put(PdfName.NEEDAPPEARANCES, PdfBoolean.PDFTRUE); } /** The field representations for retrieval and modification. */ public static class Item { /** * writeToAll constant. * * @since 2.1.5 */ public static final int WRITE_MERGED = 1; /** * writeToAll and markUsed constant. * * @since 2.1.5 */ public static final int WRITE_WIDGET = 2; /** * writeToAll and markUsed constant. * * @since 2.1.5 */ public static final int WRITE_VALUE = 4; /** * This function writes the given key/value pair to all the instances * of merged, widget, and/or value, depending on the writeFlags setting * * @since 2.1.5 * * @param key you'll never guess what this is for. * @param value if value is null, the key will be removed * @param writeFlags ORed together WRITE_* flags */ public void writeToAll(PdfName key, PdfObject value, int writeFlags) { int i; PdfDictionary curDict = null; if ((writeFlags & WRITE_MERGED) != 0) { for (i = 0; i < merged.size(); ++i) { curDict = getMerged(i); curDict.put(key, value); } } if ((writeFlags & WRITE_WIDGET) != 0) { for (i = 0; i < widgets.size(); ++i) { curDict = getWidget(i); curDict.put(key, value); } } if ((writeFlags & WRITE_VALUE) != 0) { for (i = 0; i < values.size(); ++i) { curDict = getValue(i); curDict.put(key, value); } } } /** * Mark all the item dictionaries used matching the given flags * * @since 2.1.5 * @param writeFlags WRITE_MERGED is ignored */ public void markUsed( AcroFields parentFields, int writeFlags ) { if ((writeFlags & WRITE_VALUE) != 0) { for (int i = 0; i < size(); ++i) { parentFields.markUsed( getValue( i ) ); } } if ((writeFlags & WRITE_WIDGET) != 0) { for (int i = 0; i < size(); ++i) { parentFields.markUsed(getWidget(i)); } } } /** * An array of PdfDictionary where the value tag /V * is present. * * @deprecated (will remove 'public' in the future) */ public ArrayList values = new ArrayList(); /** * An array of PdfDictionary with the widgets. * * @deprecated (will remove 'public' in the future) */ public ArrayList widgets = new ArrayList(); /** * An array of PdfDictionary with the widget references. * * @deprecated (will remove 'public' in the future) */ public ArrayList widget_refs = new ArrayList(); /** * An array of PdfDictionary with all the field * and widget tags merged. * * @deprecated (will remove 'public' in the future) */ public ArrayList merged = new ArrayList(); /** * An array of Integer with the page numbers where * the widgets are displayed. * * @deprecated (will remove 'public' in the future) */ public ArrayList page = new ArrayList(); /** * An array of Integer with the tab order of the field in the page. * * @deprecated (will remove 'public' in the future) */ public ArrayList tabOrder = new ArrayList(); /** * Preferred method of determining the number of instances * of a given field. * * @since 2.1.5 * @return number of instances */ public int size() { return values.size(); } /** * Remove the given instance from this item. It is possible to * remove all instances using this function. * * @since 2.1.5 * @param killIdx */ void remove(int killIdx) { values.remove(killIdx); widgets.remove(killIdx); widget_refs.remove(killIdx); merged.remove(killIdx); page.remove(killIdx); tabOrder.remove(killIdx); } /** * Retrieve the value dictionary of the given instance * * @since 2.1.5 * @param idx instance index * @return dictionary storing this instance's value. It may be shared across instances. */ public PdfDictionary getValue(int idx) { return (PdfDictionary) values.get(idx); } /** * Add a value dict to this Item * * @since 2.1.5 * @param value new value dictionary */ void addValue(PdfDictionary value) { values.add(value); } /** * Retrieve the widget dictionary of the given instance * * @since 2.1.5 * @param idx instance index * @return The dictionary found in the appropriate page's Annot array. */ public PdfDictionary getWidget(int idx) { return (PdfDictionary) widgets.get(idx); } /** * Add a widget dict to this Item * * @since 2.1.5 * @param widget */ void addWidget(PdfDictionary widget) { widgets.add(widget); } /** * Retrieve the reference to the given instance * * @since 2.1.5 * @param idx instance index * @return reference to the given field instance */ public PdfIndirectReference getWidgetRef(int idx) { return (PdfIndirectReference) widget_refs.get(idx); } /** * Add a widget ref to this Item * * @since 2.1.5 * @param widgRef */ void addWidgetRef(PdfIndirectReference widgRef) { widget_refs.add(widgRef); } /** * Retrieve the merged dictionary for the given instance. The merged * dictionary contains all the keys present in parent fields, though they * may have been overwritten (or modified?) by children. * Example: a merged radio field dict will contain /V * * @since 2.1.5 * @param idx instance index * @return the merged dictionary for the given instance */ public PdfDictionary getMerged(int idx) { return (PdfDictionary) merged.get(idx); } /** * Adds a merged dictionary to this Item. * * @since 2.1.5 * @param mergeDict */ void addMerged(PdfDictionary mergeDict) { merged.add(mergeDict); } /** * Retrieve the page number of the given instance * * @since 2.1.5 * @param idx * @return remember, pages are "1-indexed", not "0-indexed" like field instances. */ public Integer getPage(int idx) { return (Integer) page.get(idx); } /** * Adds a page to the current Item. * * @since 2.1.5 * @param pg */ void addPage(int pg) { page.add(new Integer(pg)); } /** * forces a page value into the Item. * * @since 2.1.5 * @param idx */ void forcePage(int idx, int pg) { page.set(idx, new Integer( pg )); } /** * Gets the tabOrder. * * @since 2.1.5 * @param idx * @return tab index of the given field instance */ public Integer getTabOrder(int idx) { return (Integer) tabOrder.get(idx); } /** * Adds a tab order value to this Item. * * @since 2.1.5 * @param order */ void addTabOrder(int order) { tabOrder.add(new Integer(order)); } } private static class InstHit { IntHashtable hits; public InstHit(int inst[]) { if (inst == null) return; hits = new IntHashtable(); for (int k = 0; k < inst.length; ++k) hits.put(inst[k], 1); } public boolean isHit(int n) { if (hits == null) return true; return hits.containsKey(n); } } /** * Gets the field names that have signatures and are signed. * * @return the field names that have signatures and are signed */ public ArrayList getSignatureNames() { if (sigNames != null) return new ArrayList(sigNames.keySet()); sigNames = new HashMap(); ArrayList sorter = new ArrayList(); for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); Item item = (Item)entry.getValue(); PdfDictionary merged = item.getMerged(0); if (!PdfName.SIG.equals(merged.get(PdfName.FT))) continue; PdfDictionary v = merged.getAsDict(PdfName.V); if (v == null) continue; PdfString contents = v.getAsString(PdfName.CONTENTS); if (contents == null) continue; PdfArray ro = v.getAsArray(PdfName.BYTERANGE); if (ro == null) continue; int rangeSize = ro.size(); if (rangeSize < 2) continue; int length = ro.getAsNumber(rangeSize - 1).intValue() + ro.getAsNumber(rangeSize - 2).intValue(); sorter.add(new Object[]{entry.getKey(), new int[]{length, 0}}); } Collections.sort(sorter, new AcroFields.SorterComparator()); if (!sorter.isEmpty()) { if (((int[])((Object[])sorter.get(sorter.size() - 1))[1])[0] == reader.getFileLength()) totalRevisions = sorter.size(); else totalRevisions = sorter.size() + 1; for (int k = 0; k < sorter.size(); ++k) { Object objs[] = (Object[])sorter.get(k); String name = (String)objs[0]; int p[] = (int[])objs[1]; p[1] = k + 1; sigNames.put(name, p); } } return new ArrayList(sigNames.keySet()); } /** * Gets the field names that have blank signatures. * * @return the field names that have blank signatures */ public ArrayList getBlankSignatureNames() { getSignatureNames(); ArrayList sigs = new ArrayList(); for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); Item item = (Item)entry.getValue(); PdfDictionary merged = item.getMerged(0); if (!PdfName.SIG.equals(merged.getAsName(PdfName.FT))) continue; if (sigNames.containsKey(entry.getKey())) continue; sigs.add(entry.getKey()); } return sigs; } /** * Gets the signature dictionary, the one keyed by /V. * * @param name the field name * @return the signature dictionary keyed by /V or null if the field is not * a signature */ public PdfDictionary getSignatureDictionary(String name) { getSignatureNames(); name = getTranslatedFieldName(name); if (!sigNames.containsKey(name)) return null; Item item = (Item)fields.get(name); PdfDictionary merged = item.getMerged(0); return merged.getAsDict(PdfName.V); } /** * Checks is the signature covers the entire document or just part of it. * * @param name the signature field name * @return true if the signature covers the entire document, * false otherwise */ public boolean signatureCoversWholeDocument(String name) { getSignatureNames(); name = getTranslatedFieldName(name); if (!sigNames.containsKey(name)) return false; return ((int[])sigNames.get(name))[0] == reader.getFileLength(); } /** * Verifies a signature. An example usage is: *

*

     * KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
     * PdfReader reader = new PdfReader("my_signed_doc.pdf");
     * AcroFields af = reader.getAcroFields();
     * ArrayList names = af.getSignatureNames();
     * for (int k = 0; k < names.size(); ++k) {
     *    String name = (String)names.get(k);
     *    System.out.println("Signature name: " + name);
     *    System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
     *    PdfPKCS7 pk = af.verifySignature(name);
     *    Calendar cal = pk.getSignDate();
     *    Certificate pkc[] = pk.getCertificates();
     *    System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
     *    System.out.println("Document modified: " + !pk.verify());
     *    Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
     *    if (fails == null)
     *        System.out.println("Certificates verified against the KeyStore");
     *    else
     *        System.out.println("Certificate failed: " + fails[1]);
     * }
     * 
* * @param name the signature field name * @return a PdfPKCS7 class to continue the verification */ public PdfPKCS7 verifySignature(String name) { return verifySignature(name, null); } /** * Verifies a signature. An example usage is: *

*

     * KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
     * PdfReader reader = new PdfReader("my_signed_doc.pdf");
     * AcroFields af = reader.getAcroFields();
     * ArrayList names = af.getSignatureNames();
     * for (int k = 0; k < names.size(); ++k) {
     *    String name = (String)names.get(k);
     *    System.out.println("Signature name: " + name);
     *    System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
     *    PdfPKCS7 pk = af.verifySignature(name);
     *    Calendar cal = pk.getSignDate();
     *    Certificate pkc[] = pk.getCertificates();
     *    System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
     *    System.out.println("Document modified: " + !pk.verify());
     *    Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
     *    if (fails == null)
     *        System.out.println("Certificates verified against the KeyStore");
     *    else
     *        System.out.println("Certificate failed: " + fails[1]);
     * }
     * 
* * @param name the signature field name * @param provider the provider or null for the default provider * @return a PdfPKCS7 class to continue the verification */ public PdfPKCS7 verifySignature(String name, String provider) { PdfDictionary v = getSignatureDictionary(name); if (v == null) return null; try { PdfName sub = v.getAsName(PdfName.SUBFILTER); PdfString contents = v.getAsString(PdfName.CONTENTS); PdfPKCS7 pk = null; if (sub.equals(PdfName.ADBE_X509_RSA_SHA1)) { PdfString cert = v.getAsString(PdfName.CERT); pk = new PdfPKCS7(contents.getOriginalBytes(), cert.getBytes(), provider); } else pk = new PdfPKCS7(contents.getOriginalBytes(), provider); updateByteRange(pk, v); PdfString str = v.getAsString(PdfName.M); if (str != null) pk.setSignDate(PdfDate.decode(str.toString())); PdfObject obj = PdfReader.getPdfObject(v.get(PdfName.NAME)); if (obj != null) { if (obj.isString()) pk.setSignName(((PdfString)obj).toUnicodeString()); else if(obj.isName()) pk.setSignName(PdfName.decodeName(obj.toString())); } str = v.getAsString(PdfName.REASON); if (str != null) pk.setReason(str.toUnicodeString()); str = v.getAsString(PdfName.LOCATION); if (str != null) pk.setLocation(str.toUnicodeString()); return pk; } catch (Exception e) { throw new ExceptionConverter(e); } } private void updateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) { PdfArray b = v.getAsArray(PdfName.BYTERANGE); RandomAccessFileOrArray rf = reader.getSafeFile(); try { rf.reOpen(); byte buf[] = new byte[8192]; for (int k = 0; k < b.size(); ++k) { int start = b.getAsNumber(k).intValue(); int length = b.getAsNumber(++k).intValue(); rf.seek(start); while (length > 0) { int rd = rf.read(buf, 0, Math.min(length, buf.length)); if (rd <= 0) break; length -= rd; pkcs7.update(buf, 0, rd); } } } catch (Exception e) { throw new ExceptionConverter(e); } finally { try{rf.close();}catch(Exception e){} } } private void markUsed(PdfObject obj) { if (!append) return; ((PdfStamperImp)writer).markUsed(obj); } /** * Gets the total number of revisions this document has. * * @return the total number of revisions */ public int getTotalRevisions() { getSignatureNames(); return this.totalRevisions; } /** * Gets this field revision. * * @param field the signature field name * @return the revision or zero if it's not a signature field */ public int getRevision(String field) { getSignatureNames(); field = getTranslatedFieldName(field); if (!sigNames.containsKey(field)) return 0; return ((int[])sigNames.get(field))[1]; } /** * Extracts a revision from the document. * * @param field the signature field name * @return an InputStream covering the revision. Returns null if * it's not a signature field * @throws IOException on error */ public InputStream extractRevision(String field) throws IOException { getSignatureNames(); field = getTranslatedFieldName(field); if (!sigNames.containsKey(field)) return null; int length = ((int[])sigNames.get(field))[0]; RandomAccessFileOrArray raf = reader.getSafeFile(); raf.reOpen(); raf.seek(0); return new RevisionStream(raf, length); } /** * Gets the appearances cache. * * @return the appearances cache * @since 2.1.5 this method used to return a HashMap */ public Map getFieldCache() { return this.fieldCache; } /** * Sets a cache for field appearances. Parsing the existing PDF to * create a new TextField is time expensive. For those tasks that repeatedly * fill the same PDF with different field values the use of the cache has dramatic * speed advantages. An example usage: *

*

     * String pdfFile = ...;// the pdf file used as template
     * ArrayList xfdfFiles = ...;// the xfdf file names
     * ArrayList pdfOutFiles = ...;// the output file names, one for each element in xpdfFiles
     * HashMap cache = new HashMap();// the appearances cache
     * PdfReader originalReader = new PdfReader(pdfFile);
     * for (int k = 0; k < xfdfFiles.size(); ++k) {
     *    PdfReader reader = new PdfReader(originalReader);
     *    XfdfReader xfdf = new XfdfReader((String)xfdfFiles.get(k));
     *    PdfStamper stp = new PdfStamper(reader, new FileOutputStream((String)pdfOutFiles.get(k)));
     *    AcroFields af = stp.getAcroFields();
     *    af.setFieldCache(cache);
     *    af.setFields(xfdf);
     *    stp.close();
     * }
     * 
* * @param fieldCache a Map that will carry the cached appearances * @since 2.1.5 this method used to take a HashMap as parameter */ public void setFieldCache(Map fieldCache) { this.fieldCache = fieldCache; } /** * Sets extra margins in text fields to better mimic the Acrobat layout. * * @param extraMarginLeft the extra margin left * @param extraMarginTop the extra margin top */ public void setExtraMargin(float extraMarginLeft, float extraMarginTop) { this.extraMarginLeft = extraMarginLeft; this.extraMarginTop = extraMarginTop; } /** * Adds a substitution font to the list. The fonts in this list will be used if the original * font doesn't contain the needed glyphs. * * @param font the font */ public void addSubstitutionFont(BaseFont font) { if (substitutionFonts == null) substitutionFonts = new ArrayList(); substitutionFonts.add(font); } private static final HashMap stdFieldFontNames = new HashMap(); /** * Holds value of property totalRevisions. */ private int totalRevisions; /** * Holds value of property fieldCache. * * @since 2.1.5 this used to be a HashMap */ private Map fieldCache; static { stdFieldFontNames.put("CoBO", new String[]{"Courier-BoldOblique"}); stdFieldFontNames.put("CoBo", new String[]{"Courier-Bold"}); stdFieldFontNames.put("CoOb", new String[]{"Courier-Oblique"}); stdFieldFontNames.put("Cour", new String[]{"Courier"}); stdFieldFontNames.put("HeBO", new String[]{"Helvetica-BoldOblique"}); stdFieldFontNames.put("HeBo", new String[]{"Helvetica-Bold"}); stdFieldFontNames.put("HeOb", new String[]{"Helvetica-Oblique"}); stdFieldFontNames.put("Helv", new String[]{"Helvetica"}); stdFieldFontNames.put("Symb", new String[]{"Symbol"}); stdFieldFontNames.put("TiBI", new String[]{"Times-BoldItalic"}); stdFieldFontNames.put("TiBo", new String[]{"Times-Bold"}); stdFieldFontNames.put("TiIt", new String[]{"Times-Italic"}); stdFieldFontNames.put("TiRo", new String[]{"Times-Roman"}); stdFieldFontNames.put("ZaDb", new String[]{"ZapfDingbats"}); stdFieldFontNames.put("HySm", new String[]{"HYSMyeongJo-Medium", "UniKS-UCS2-H"}); stdFieldFontNames.put("HyGo", new String[]{"HYGoThic-Medium", "UniKS-UCS2-H"}); stdFieldFontNames.put("KaGo", new String[]{"HeiseiKakuGo-W5", "UniKS-UCS2-H"}); stdFieldFontNames.put("KaMi", new String[]{"HeiseiMin-W3", "UniJIS-UCS2-H"}); stdFieldFontNames.put("MHei", new String[]{"MHei-Medium", "UniCNS-UCS2-H"}); stdFieldFontNames.put("MSun", new String[]{"MSung-Light", "UniCNS-UCS2-H"}); stdFieldFontNames.put("STSo", new String[]{"STSong-Light", "UniGB-UCS2-H"}); } private static class RevisionStream extends InputStream { private byte b[] = new byte[1]; private RandomAccessFileOrArray raf; private int length; private int rangePosition = 0; private boolean closed; private RevisionStream(RandomAccessFileOrArray raf, int length) { this.raf = raf; this.length = length; } public int read() throws IOException { int n = read(b); if (n != 1) return -1; return b[0] & 0xff; } public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } if (rangePosition >= length) { close(); return -1; } int elen = Math.min(len, length - rangePosition); raf.readFully(b, off, elen); rangePosition += elen; return elen; } public void close() throws IOException { if (!closed) { raf.close(); closed = true; } } } private static class SorterComparator implements Comparator { public int compare(Object o1, Object o2) { int n1 = ((int[])((Object[])o1)[1])[0]; int n2 = ((int[])((Object[])o2)[1])[0]; return n1 - n2; } } /** * Gets the list of substitution fonts. The list is composed of BaseFont and can be null. The fonts in this list will be used if the original * font doesn't contain the needed glyphs. * * @return the list */ public ArrayList getSubstitutionFonts() { return substitutionFonts; } /** * Sets a list of substitution fonts. The list is composed of BaseFont and can also be null. The fonts in this list will be used if the original * font doesn't contain the needed glyphs. * * @param substitutionFonts the list */ public void setSubstitutionFonts(ArrayList substitutionFonts) { this.substitutionFonts = substitutionFonts; } /** * Gets the XFA form processor. * * @return the XFA form processor */ public XfaForm getXfa() { return xfa; } private static final PdfName[] buttonRemove = {PdfName.MK, PdfName.F , PdfName.FF , PdfName.Q , PdfName.BS , PdfName.BORDER}; /** * Creates a new pushbutton from an existing field. If there are several pushbuttons with the same name * only the first one is used. This pushbutton can be changed and be used to replace * an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton * call {@link #replacePushbuttonField(String,PdfFormField)}. * * @param field the field name that should be a pushbutton * @return a new pushbutton or null if the field is not a pushbutton */ public PushbuttonField getNewPushbuttonFromField(String field) { return getNewPushbuttonFromField(field, 0); } /** * Creates a new pushbutton from an existing field. This pushbutton can be changed and be used to replace * an existing one, with the same name or other name, as long is it is in the same document. To replace an existing pushbutton * call {@link #replacePushbuttonField(String,PdfFormField,int)}. * * @param field the field name that should be a pushbutton * @param order the field order in fields with same name * @return a new pushbutton or null if the field is not a pushbutton * * @since 2.0.7 */ public PushbuttonField getNewPushbuttonFromField(String field, int order) { try { if (getFieldType(field) != FIELD_TYPE_PUSHBUTTON) return null; Item item = getFieldItem(field); if (order >= item.size()) return null; int posi = order * 5; float[] pos = getFieldPositions(field); Rectangle box = new Rectangle(pos[posi + 1], pos[posi + 2], pos[posi + 3], pos[posi + 4]); PushbuttonField newButton = new PushbuttonField(writer, box, null); PdfDictionary dic = item.getMerged(order); decodeGenericDictionary(dic, newButton); PdfDictionary mk = dic.getAsDict(PdfName.MK); if (mk != null) { PdfString text = mk.getAsString(PdfName.CA); if (text != null) newButton.setText(text.toUnicodeString()); PdfNumber tp = mk.getAsNumber(PdfName.TP); if (tp != null) newButton.setLayout(tp.intValue() + 1); PdfDictionary ifit = mk.getAsDict(PdfName.IF); if (ifit != null) { PdfName sw = ifit.getAsName(PdfName.SW); if (sw != null) { int scale = PushbuttonField.SCALE_ICON_ALWAYS; if (sw.equals(PdfName.B)) scale = PushbuttonField.SCALE_ICON_IS_TOO_BIG; else if (sw.equals(PdfName.S)) scale = PushbuttonField.SCALE_ICON_IS_TOO_SMALL; else if (sw.equals(PdfName.N)) scale = PushbuttonField.SCALE_ICON_NEVER; newButton.setScaleIcon(scale); } sw = ifit.getAsName(PdfName.S); if (sw != null) { if (sw.equals(PdfName.A)) newButton.setProportionalIcon(false); } PdfArray aj = ifit.getAsArray(PdfName.A); if (aj != null && aj.size() == 2) { float left = aj.getAsNumber(0).floatValue(); float bottom = aj.getAsNumber(1).floatValue(); newButton.setIconHorizontalAdjustment(left); newButton.setIconVerticalAdjustment(bottom); } PdfBoolean fb = ifit.getAsBoolean(PdfName.FB); if (fb != null && fb.booleanValue()) newButton.setIconFitToBounds(true); } PdfObject i = mk.get(PdfName.I); if (i != null && i.isIndirect()) newButton.setIconReference((PRIndirectReference)i); } return newButton; } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Replaces the first field with a new pushbutton. The pushbutton can be created with * {@link #getNewPushbuttonFromField(String)} from the same document or it can be a * generic PdfFormField of the type pushbutton. * * @param field the field name * @param button the PdfFormField representing the pushbutton * @return true if the field was replaced, false if the field * was not a pushbutton */ public boolean replacePushbuttonField(String field, PdfFormField button) { return replacePushbuttonField(field, button, 0); } /** * Replaces the designated field with a new pushbutton. The pushbutton can be created with * {@link #getNewPushbuttonFromField(String,int)} from the same document or it can be a * generic PdfFormField of the type pushbutton. * * @param field the field name * @param button the PdfFormField representing the pushbutton * @param order the field order in fields with same name * @return true if the field was replaced, false if the field * was not a pushbutton * * @since 2.0.7 */ public boolean replacePushbuttonField(String field, PdfFormField button, int order) { if (getFieldType(field) != FIELD_TYPE_PUSHBUTTON) return false; Item item = getFieldItem(field); if (order >= item.size()) return false; PdfDictionary merged = item.getMerged(order); PdfDictionary values = item.getValue(order); PdfDictionary widgets = item.getWidget(order); for (int k = 0; k < buttonRemove.length; ++k) { merged.remove(buttonRemove[k]); values.remove(buttonRemove[k]); widgets.remove(buttonRemove[k]); } for (Iterator it = button.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); if (key.equals(PdfName.T) || key.equals(PdfName.RECT)) continue; if (key.equals(PdfName.FF)) values.put(key, button.get(key)); else widgets.put(key, button.get(key)); merged.put(key, button.get(key)); } return true; } } src/core/com/lowagie/text/pdf/ArabicLigaturizer.java100644 0 0 75061 11000354131 20151 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Shape arabic characters. This code was inspired by an LGPL'ed C library: * Pango ( see http://www.pango.com/ ). Note that the code of this is the * original work of Paulo Soares. Hence it is perfectly justifiable to distribute * it under the MPL. * * @author Paulo Soares (psoares@consiste.pt) */ public class ArabicLigaturizer { static boolean isVowel(char s) { return ((s >= 0x064B) && (s <= 0x0655)) || (s == 0x0670); } static char charshape(char s, int which) /* which 0=isolated 1=final 2=initial 3=medial */ { int l, r, m; if ((s >= 0x0621) && (s <= 0x06D3)) { l = 0; r = chartable.length - 1; while (l <= r) { m = (l + r) / 2; if (s == chartable[m][0]) { return chartable[m][which + 1]; } else if (s < chartable[m][0]) { r = m - 1; } else { l = m + 1; } } } else if (s >= 0xfef5 && s <= 0xfefb) return (char)(s + which); return s; } static int shapecount(char s) { int l, r, m; if ((s >= 0x0621) && (s <= 0x06D3) && !isVowel(s)) { l = 0; r = chartable.length - 1; while (l <= r) { m = (l + r) / 2; if (s == chartable[m][0]) { return chartable[m].length - 1; } else if (s < chartable[m][0]) { r = m - 1; } else { l = m + 1; } } } else if (s == ZWJ) { return 4; } return 1; } static int ligature(char newchar, charstruct oldchar) { /* 0 == no ligature possible; 1 == vowel; 2 == two chars; 3 == Lam+Alef */ int retval = 0; if (oldchar.basechar == 0) return 0; if (isVowel(newchar)) { retval = 1; if ((oldchar.vowel != 0) && (newchar != SHADDA)) { retval = 2; /* we eliminate the old vowel .. */ } switch (newchar) { case SHADDA: if (oldchar.mark1 == 0) { oldchar.mark1 = SHADDA; } else { return 0; /* no ligature possible */ } break; case HAMZABELOW: switch (oldchar.basechar) { case ALEF: oldchar.basechar = ALEFHAMZABELOW; retval = 2; break; case LAM_ALEF: oldchar.basechar = LAM_ALEFHAMZABELOW; retval = 2; break; default: oldchar.mark1 = HAMZABELOW; break; } break; case HAMZAABOVE: switch (oldchar.basechar) { case ALEF: oldchar.basechar = ALEFHAMZA; retval = 2; break; case LAM_ALEF: oldchar.basechar = LAM_ALEFHAMZA; retval = 2; break; case WAW: oldchar.basechar = WAWHAMZA; retval = 2; break; case YEH: case ALEFMAKSURA: case FARSIYEH: oldchar.basechar = YEHHAMZA; retval = 2; break; default: /* whatever sense this may make .. */ oldchar.mark1 = HAMZAABOVE; break; } break; case MADDA: switch (oldchar.basechar) { case ALEF: oldchar.basechar = ALEFMADDA; retval = 2; break; } break; default: oldchar.vowel = newchar; break; } if (retval == 1) { oldchar.lignum++; } return retval; } if (oldchar.vowel != 0) { /* if we already joined a vowel, we can't join a Hamza */ return 0; } switch (oldchar.basechar) { case LAM: switch (newchar) { case ALEF: oldchar.basechar = LAM_ALEF; oldchar.numshapes = 2; retval = 3; break; case ALEFHAMZA: oldchar.basechar = LAM_ALEFHAMZA; oldchar.numshapes = 2; retval = 3; break; case ALEFHAMZABELOW: oldchar.basechar = LAM_ALEFHAMZABELOW; oldchar.numshapes = 2; retval = 3; break; case ALEFMADDA: oldchar.basechar = LAM_ALEFMADDA; oldchar.numshapes = 2; retval = 3; break; } break; case 0: oldchar.basechar = newchar; oldchar.numshapes = shapecount(newchar); retval = 1; break; } return retval; } static void copycstostring(StringBuffer string, charstruct s, int level) { /* s is a shaped charstruct; i is the index into the string */ if (s.basechar == 0) return; string.append(s.basechar); s.lignum--; if (s.mark1 != 0) { if ((level & ar_novowel) == 0) { string.append(s.mark1); s.lignum--; } else { s.lignum--; } } if (s.vowel != 0) { if ((level & ar_novowel) == 0) { string.append(s.vowel); s.lignum--; } else { /* vowel elimination */ s.lignum--; } } // while (s.lignum > 0) { /* NULL-insertion for Langbox-font */ // string[i] = 0; // i++; // (s.lignum)--; // } // return i; } // return len static void doublelig(StringBuffer string, int level) /* Ok. We have presentation ligatures in our font. */ { int len; int olen = len = string.length(); int j = 0, si = 1; char lapresult; while (si < olen) { lapresult = 0; if ((level & ar_composedtashkeel) != 0) { switch (string.charAt(j)) { case SHADDA: switch (string.charAt(si)) { case KASRA: lapresult = 0xFC62; break; case FATHA: lapresult = 0xFC60; break; case DAMMA: lapresult = 0xFC61; break; case 0x064C: lapresult = 0xFC5E; break; case 0x064D: lapresult = 0xFC5F; break; } break; case KASRA: if (string.charAt(si) == SHADDA) lapresult = 0xFC62; break; case FATHA: if (string.charAt(si) == SHADDA) lapresult = 0xFC60; break; case DAMMA: if (string.charAt(si) == SHADDA) lapresult = 0xFC61; break; } } if ((level & ar_lig) != 0) { switch (string.charAt(j)) { case 0xFEDF: /* LAM initial */ switch (string.charAt(si)) { case 0xFE9E: lapresult = 0xFC3F; break; /* JEEM final */ case 0xFEA0: lapresult = 0xFCC9; break; /* JEEM medial */ case 0xFEA2: lapresult = 0xFC40; break; /* HAH final */ case 0xFEA4: lapresult = 0xFCCA; break; /* HAH medial */ case 0xFEA6: lapresult = 0xFC41; break; /* KHAH final */ case 0xFEA8: lapresult = 0xFCCB; break; /* KHAH medial */ case 0xFEE2: lapresult = 0xFC42; break; /* MEEM final */ case 0xFEE4: lapresult = 0xFCCC; break; /* MEEM medial */ } break; case 0xFE97: /* TEH inital */ switch (string.charAt(si)) { case 0xFEA0: lapresult = 0xFCA1; break; /* JEEM medial */ case 0xFEA4: lapresult = 0xFCA2; break; /* HAH medial */ case 0xFEA8: lapresult = 0xFCA3; break; /* KHAH medial */ } break; case 0xFE91: /* BEH inital */ switch (string.charAt(si)) { case 0xFEA0: lapresult = 0xFC9C; break; /* JEEM medial */ case 0xFEA4: lapresult = 0xFC9D; break; /* HAH medial */ case 0xFEA8: lapresult = 0xFC9E; break; /* KHAH medial */ } break; case 0xFEE7: /* NOON inital */ switch (string.charAt(si)) { case 0xFEA0: lapresult = 0xFCD2; break; /* JEEM initial */ case 0xFEA4: lapresult = 0xFCD3; break; /* HAH medial */ case 0xFEA8: lapresult = 0xFCD4; break; /* KHAH medial */ } break; case 0xFEE8: /* NOON medial */ switch (string.charAt(si)) { case 0xFEAE: lapresult = 0xFC8A; break; /* REH final */ case 0xFEB0: lapresult = 0xFC8B; break; /* ZAIN final */ } break; case 0xFEE3: /* MEEM initial */ switch (string.charAt(si)) { case 0xFEA0: lapresult = 0xFCCE; break; /* JEEM medial */ case 0xFEA4: lapresult = 0xFCCF; break; /* HAH medial */ case 0xFEA8: lapresult = 0xFCD0; break; /* KHAH medial */ case 0xFEE4: lapresult = 0xFCD1; break; /* MEEM medial */ } break; case 0xFED3: /* FEH initial */ switch (string.charAt(si)) { case 0xFEF2: lapresult = 0xFC32; break; /* YEH final */ } break; default: break; } /* end switch string[si] */ } if (lapresult != 0) { string.setCharAt(j, lapresult); len--; si++; /* jump over one character */ /* we'll have to change this, too. */ } else { j++; string.setCharAt(j, string.charAt(si)); si++; } } string.setLength(len); } static boolean connects_to_left(charstruct a) { return a.numshapes > 2; } static void shape(char text[], StringBuffer string, int level) { /* string is assumed to be empty and big enough. * text is the original text. * This routine does the basic arabic reshaping. * *len the number of non-null characters. * * Note: We have to unshape each character first! */ int join; int which; char nextletter; int p = 0; /* initialize for output */ charstruct oldchar = new charstruct(); charstruct curchar = new charstruct(); while (p < text.length) { nextletter = text[p++]; //nextletter = unshape (nextletter); join = ligature(nextletter, curchar); if (join == 0) { /* shape curchar */ int nc = shapecount(nextletter); //(*len)++; if (nc == 1) { which = 0; /* final or isolated */ } else { which = 2; /* medial or initial */ } if (connects_to_left(oldchar)) { which++; } which = which % (curchar.numshapes); curchar.basechar = charshape(curchar.basechar, which); /* get rid of oldchar */ copycstostring(string, oldchar, level); oldchar = curchar; /* new values in oldchar */ /* init new curchar */ curchar = new charstruct(); curchar.basechar = nextletter; curchar.numshapes = nc; curchar.lignum++; // (*len) += unligature (&curchar, level); } else if (join == 1) { } // else // { // (*len) += unligature (&curchar, level); // } // p = g_utf8_next_char (p); } /* Handle last char */ if (connects_to_left(oldchar)) which = 1; else which = 0; which = which % (curchar.numshapes); curchar.basechar = charshape(curchar.basechar, which); /* get rid of oldchar */ copycstostring(string, oldchar, level); copycstostring(string, curchar, level); } static int arabic_shape(char src[], int srcoffset, int srclength, char dest[], int destoffset, int destlength, int level) { char str[] = new char[srclength]; for (int k = srclength + srcoffset - 1; k >= srcoffset; --k) str[k - srcoffset] = src[k]; StringBuffer string = new StringBuffer(srclength); shape(str, string, level); if ((level & (ar_composedtashkeel | ar_lig)) != 0) doublelig(string, level); // string.reverse(); System.arraycopy(string.toString().toCharArray(), 0, dest, destoffset, string.length()); return string.length(); } static void processNumbers(char text[], int offset, int length, int options) { int limit = offset + length; if ((options & DIGITS_MASK) != 0) { char digitBase = '\u0030'; // European digits switch (options & DIGIT_TYPE_MASK) { case DIGIT_TYPE_AN: digitBase = '\u0660'; // Arabic-Indic digits break; case DIGIT_TYPE_AN_EXTENDED: digitBase = '\u06f0'; // Eastern Arabic-Indic digits (Persian and Urdu) break; default: break; } switch (options & DIGITS_MASK) { case DIGITS_EN2AN: { int digitDelta = digitBase - '\u0030'; for (int i = offset; i < limit; ++i) { char ch = text[i]; if (ch <= '\u0039' && ch >= '\u0030') { text[i] += digitDelta; } } } break; case DIGITS_AN2EN: { char digitTop = (char)(digitBase + 9); int digitDelta = '\u0030' - digitBase; for (int i = offset; i < limit; ++i) { char ch = text[i]; if (ch <= digitTop && ch >= digitBase) { text[i] += digitDelta; } } } break; case DIGITS_EN2AN_INIT_LR: shapeToArabicDigitsWithContext(text, 0, length, digitBase, false); break; case DIGITS_EN2AN_INIT_AL: shapeToArabicDigitsWithContext(text, 0, length, digitBase, true); break; default: break; } } } static void shapeToArabicDigitsWithContext(char[] dest, int start, int length, char digitBase, boolean lastStrongWasAL) { digitBase -= '0'; // move common adjustment out of loop int limit = start + length; for(int i = start; i < limit; ++i) { char ch = dest[i]; switch (BidiOrder.getDirection(ch)) { case BidiOrder.L: case BidiOrder.R: lastStrongWasAL = false; break; case BidiOrder.AL: lastStrongWasAL = true; break; case BidiOrder.EN: if (lastStrongWasAL && ch <= '\u0039') { dest[i] = (char)(ch + digitBase); } break; default: break; } } } private static final char ALEF = 0x0627; private static final char ALEFHAMZA = 0x0623; private static final char ALEFHAMZABELOW = 0x0625; private static final char ALEFMADDA = 0x0622; private static final char LAM = 0x0644; private static final char HAMZA = 0x0621; private static final char TATWEEL = 0x0640; private static final char ZWJ = 0x200D; private static final char HAMZAABOVE = 0x0654; private static final char HAMZABELOW = 0x0655; private static final char WAWHAMZA = 0x0624; private static final char YEHHAMZA = 0x0626; private static final char WAW = 0x0648; private static final char ALEFMAKSURA = 0x0649; private static final char YEH = 0x064A; private static final char FARSIYEH = 0x06CC; private static final char SHADDA = 0x0651; private static final char KASRA = 0x0650; private static final char FATHA = 0x064E; private static final char DAMMA = 0x064F; private static final char MADDA = 0x0653; private static final char LAM_ALEF = 0xFEFB; private static final char LAM_ALEFHAMZA = 0xFEF7; private static final char LAM_ALEFHAMZABELOW = 0xFEF9; private static final char LAM_ALEFMADDA = 0xFEF5; private static final char chartable[][] = { {0x0621, 0xFE80}, /* HAMZA */ {0x0622, 0xFE81, 0xFE82}, /* ALEF WITH MADDA ABOVE */ {0x0623, 0xFE83, 0xFE84}, /* ALEF WITH HAMZA ABOVE */ {0x0624, 0xFE85, 0xFE86}, /* WAW WITH HAMZA ABOVE */ {0x0625, 0xFE87, 0xFE88}, /* ALEF WITH HAMZA BELOW */ {0x0626, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C}, /* YEH WITH HAMZA ABOVE */ {0x0627, 0xFE8D, 0xFE8E}, /* ALEF */ {0x0628, 0xFE8F, 0xFE90, 0xFE91, 0xFE92}, /* BEH */ {0x0629, 0xFE93, 0xFE94}, /* TEH MARBUTA */ {0x062A, 0xFE95, 0xFE96, 0xFE97, 0xFE98}, /* TEH */ {0x062B, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C}, /* THEH */ {0x062C, 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0}, /* JEEM */ {0x062D, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4}, /* HAH */ {0x062E, 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8}, /* KHAH */ {0x062F, 0xFEA9, 0xFEAA}, /* DAL */ {0x0630, 0xFEAB, 0xFEAC}, /* THAL */ {0x0631, 0xFEAD, 0xFEAE}, /* REH */ {0x0632, 0xFEAF, 0xFEB0}, /* ZAIN */ {0x0633, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4}, /* SEEN */ {0x0634, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8}, /* SHEEN */ {0x0635, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC}, /* SAD */ {0x0636, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0}, /* DAD */ {0x0637, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4}, /* TAH */ {0x0638, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8}, /* ZAH */ {0x0639, 0xFEC9, 0xFECA, 0xFECB, 0xFECC}, /* AIN */ {0x063A, 0xFECD, 0xFECE, 0xFECF, 0xFED0}, /* GHAIN */ {0x0640, 0x0640, 0x0640, 0x0640, 0x0640}, /* TATWEEL */ {0x0641, 0xFED1, 0xFED2, 0xFED3, 0xFED4}, /* FEH */ {0x0642, 0xFED5, 0xFED6, 0xFED7, 0xFED8}, /* QAF */ {0x0643, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC}, /* KAF */ {0x0644, 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0}, /* LAM */ {0x0645, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4}, /* MEEM */ {0x0646, 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8}, /* NOON */ {0x0647, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC}, /* HEH */ {0x0648, 0xFEED, 0xFEEE}, /* WAW */ {0x0649, 0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9}, /* ALEF MAKSURA */ {0x064A, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4}, /* YEH */ {0x0671, 0xFB50, 0xFB51}, /* ALEF WASLA */ {0x0679, 0xFB66, 0xFB67, 0xFB68, 0xFB69}, /* TTEH */ {0x067A, 0xFB5E, 0xFB5F, 0xFB60, 0xFB61}, /* TTEHEH */ {0x067B, 0xFB52, 0xFB53, 0xFB54, 0xFB55}, /* BEEH */ {0x067E, 0xFB56, 0xFB57, 0xFB58, 0xFB59}, /* PEH */ {0x067F, 0xFB62, 0xFB63, 0xFB64, 0xFB65}, /* TEHEH */ {0x0680, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D}, /* BEHEH */ {0x0683, 0xFB76, 0xFB77, 0xFB78, 0xFB79}, /* NYEH */ {0x0684, 0xFB72, 0xFB73, 0xFB74, 0xFB75}, /* DYEH */ {0x0686, 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D}, /* TCHEH */ {0x0687, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81}, /* TCHEHEH */ {0x0688, 0xFB88, 0xFB89}, /* DDAL */ {0x068C, 0xFB84, 0xFB85}, /* DAHAL */ {0x068D, 0xFB82, 0xFB83}, /* DDAHAL */ {0x068E, 0xFB86, 0xFB87}, /* DUL */ {0x0691, 0xFB8C, 0xFB8D}, /* RREH */ {0x0698, 0xFB8A, 0xFB8B}, /* JEH */ {0x06A4, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D}, /* VEH */ {0x06A6, 0xFB6E, 0xFB6F, 0xFB70, 0xFB71}, /* PEHEH */ {0x06A9, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91}, /* KEHEH */ {0x06AD, 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6}, /* NG */ {0x06AF, 0xFB92, 0xFB93, 0xFB94, 0xFB95}, /* GAF */ {0x06B1, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D}, /* NGOEH */ {0x06B3, 0xFB96, 0xFB97, 0xFB98, 0xFB99}, /* GUEH */ {0x06BA, 0xFB9E, 0xFB9F}, /* NOON GHUNNA */ {0x06BB, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3}, /* RNOON */ {0x06BE, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD}, /* HEH DOACHASHMEE */ {0x06C0, 0xFBA4, 0xFBA5}, /* HEH WITH YEH ABOVE */ {0x06C1, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9}, /* HEH GOAL */ {0x06C5, 0xFBE0, 0xFBE1}, /* KIRGHIZ OE */ {0x06C6, 0xFBD9, 0xFBDA}, /* OE */ {0x06C7, 0xFBD7, 0xFBD8}, /* U */ {0x06C8, 0xFBDB, 0xFBDC}, /* YU */ {0x06C9, 0xFBE2, 0xFBE3}, /* KIRGHIZ YU */ {0x06CB, 0xFBDE, 0xFBDF}, /* VE */ {0x06CC, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF}, /* FARSI YEH */ {0x06D0, 0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7}, /* E */ {0x06D2, 0xFBAE, 0xFBAF}, /* YEH BARREE */ {0x06D3, 0xFBB0, 0xFBB1} /* YEH BARREE WITH HAMZA ABOVE */ }; public static final int ar_nothing = 0x0; public static final int ar_novowel = 0x1; public static final int ar_composedtashkeel = 0x4; public static final int ar_lig = 0x8; /** * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits. */ public static final int DIGITS_EN2AN = 0x20; /** * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039). */ public static final int DIGITS_AN2EN = 0x40; /** * Digit shaping option: * Replace European digits (U+0030...U+0039) by Arabic-Indic digits * if the most recent strongly directional character * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). * The initial state at the start of the text is assumed to be not an Arabic, * letter, so European digits at the start of the text will not change. * Compare to DIGITS_ALEN2AN_INIT_AL. */ public static final int DIGITS_EN2AN_INIT_LR = 0x60; /** * Digit shaping option: * Replace European digits (U+0030...U+0039) by Arabic-Indic digits * if the most recent strongly directional character * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). * The initial state at the start of the text is assumed to be an Arabic, * letter, so European digits at the start of the text will change. * Compare to DIGITS_ALEN2AN_INT_LR. */ public static final int DIGITS_EN2AN_INIT_AL = 0x80; /** Not a valid option value. */ private static final int DIGITS_RESERVED = 0xa0; /** * Bit mask for digit shaping options. */ public static final int DIGITS_MASK = 0xe0; /** * Digit type option: Use Arabic-Indic digits (U+0660...U+0669). */ public static final int DIGIT_TYPE_AN = 0; /** * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9). */ public static final int DIGIT_TYPE_AN_EXTENDED = 0x100; /** * Bit mask for digit type options. */ public static final int DIGIT_TYPE_MASK = 0x0100; // 0x3f00? static class charstruct { char basechar; char mark1; /* has to be initialized to zero */ char vowel; int lignum; /* is a ligature with lignum aditional characters */ int numshapes = 1; }; } src/core/com/lowagie/text/pdf/AsianFontMapper.java100644 0 0 10343 11000354131 17565 0ustar 0 0 /* * Copyright 2004 by Takenori. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Font; public class AsianFontMapper extends DefaultFontMapper { public static final String ChineseSimplifiedFont = "STSong-Light"; public static final String ChineseSimplifiedEncoding_H = "UniGB-UCS2-H"; public static final String ChineseSimplifiedEncoding_V = "UniGB-UCS2-V"; public static final String ChineseTraditionalFont_MHei = "MHei-Medium"; public static final String ChineseTraditionalFont_MSung = "MSung-Light"; public static final String ChineseTraditionalEncoding_H = "UniCNS-UCS2-H"; public static final String ChineseTraditionalEncoding_V = "UniCNS-UCS2-V"; public static final String JapaneseFont_Go = "HeiseiKakuGo-W5"; public static final String JapaneseFont_Min = "HeiseiMin-W3"; public static final String JapaneseEncoding_H = "UniJIS-UCS2-H"; public static final String JapaneseEncoding_V = "UniJIS-UCS2-V"; public static final String JapaneseEncoding_HW_H = "UniJIS-UCS2-HW-H"; public static final String JapaneseEncoding_HW_V = "UniJIS-UCS2-HW-V"; public static final String KoreanFont_GoThic = "HYGoThic-Medium"; public static final String KoreanFont_SMyeongJo = "HYSMyeongJo-Medium"; public static final String KoreanEncoding_H = "UniKS-UCS2-H"; public static final String KoreanEncoding_V = "UniKS-UCS2-V"; private final String defaultFont; private final String encoding; public AsianFontMapper(String font, String encoding) { super(); this.defaultFont = font; this.encoding = encoding; } public BaseFont awtToPdf(Font font) { try { BaseFontParameters p = getBaseFontParameters(font.getFontName()); if (p != null){ return BaseFont.createFont(p.fontName, p.encoding, p.embedded, p.cached, p.ttfAfm, p.pfb); }else{ return BaseFont.createFont(defaultFont, encoding, true); } } catch (Exception e) { e.printStackTrace(); } return null; } } src/core/com/lowagie/text/pdf/BadPdfFormatException.java100644 0 0 6332 11012562273 20704 0ustar 0 0 /* * $Id: BadPdfFormatException.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Signals that a bad PDF format has been used to construct a PdfObject. * * @see PdfException * @see PdfBoolean * @see PdfNumber * @see PdfString * @see PdfName * @see PdfDictionary */ public class BadPdfFormatException extends PdfException { // constructors private static final long serialVersionUID = 1802317735708833538L; /** * Constructs a BadPdfFormatException without a message. */ BadPdfFormatException() { super(); } /** * Constructs a BadPdfFormatException with a message. * * @param message a message describing the exception */ BadPdfFormatException(String message) { super(message); } }src/core/com/lowagie/text/pdf/Barcode.java100644 0 0 36232 11000354131 16102 0ustar 0 0 /* * $Id: Barcode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2002-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; /** Base class containing properties and methods common to all * barcode types. * * @author Paulo Soares (psoares@consiste.pt) */ public abstract class Barcode { /** A type of barcode */ public static final int EAN13 = 1; /** A type of barcode */ public static final int EAN8 = 2; /** A type of barcode */ public static final int UPCA = 3; /** A type of barcode */ public static final int UPCE = 4; /** A type of barcode */ public static final int SUPP2 = 5; /** A type of barcode */ public static final int SUPP5 = 6; /** A type of barcode */ public static final int POSTNET = 7; /** A type of barcode */ public static final int PLANET = 8; /** A type of barcode */ public static final int CODE128 = 9; /** A type of barcode */ public static final int CODE128_UCC = 10; /** A type of barcode */ public static final int CODE128_RAW = 11; /** A type of barcode */ public static final int CODABAR = 12; /** The minimum bar width. */ protected float x; /** The bar multiplier for wide bars or the distance between * bars for Postnet and Planet. */ protected float n; /** The text font. null if no text. */ protected BaseFont font; /** The size of the text or the height of the shorter bar * in Postnet. */ protected float size; /** If positive, the text distance under the bars. If zero or negative, * the text distance above the bars. */ protected float baseline; /** The height of the bars. */ protected float barHeight; /** The text alignment. Can be Element.ALIGN_LEFT, * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. */ protected int textAlignment; /** The optional checksum generation. */ protected boolean generateChecksum; /** Shows the generated checksum in the the text. */ protected boolean checksumText; /** Show the start and stop character '*' in the text for * the barcode 39 or 'ABCD' for codabar. */ protected boolean startStopText; /** Generates extended barcode 39. */ protected boolean extended; /** The code to generate. */ protected String code = ""; /** Show the guard bars for barcode EAN. */ protected boolean guardBars; /** The code type. */ protected int codeType; /** The ink spreading. */ protected float inkSpreading = 0; /** Gets the minimum bar width. * @return the minimum bar width */ public float getX() { return x; } /** Sets the minimum bar width. * @param x the minimum bar width */ public void setX(float x) { this.x = x; } /** Gets the bar multiplier for wide bars. * @return the bar multiplier for wide bars */ public float getN() { return n; } /** Sets the bar multiplier for wide bars. * @param n the bar multiplier for wide bars */ public void setN(float n) { this.n = n; } /** Gets the text font. null if no text. * @return the text font. null if no text */ public BaseFont getFont() { return font; } /** Sets the text font. * @param font the text font. Set to null to suppress any text */ public void setFont(BaseFont font) { this.font = font; } /** Gets the size of the text. * @return the size of the text */ public float getSize() { return size; } /** Sets the size of the text. * @param size the size of the text */ public void setSize(float size) { this.size = size; } /** Gets the text baseline. * If positive, the text distance under the bars. If zero or negative, * the text distance above the bars. * @return the baseline. */ public float getBaseline() { return baseline; } /** Sets the text baseline. * If positive, the text distance under the bars. If zero or negative, * the text distance above the bars. * @param baseline the baseline. */ public void setBaseline(float baseline) { this.baseline = baseline; } /** Gets the height of the bars. * @return the height of the bars */ public float getBarHeight() { return barHeight; } /** Sets the height of the bars. * @param barHeight the height of the bars */ public void setBarHeight(float barHeight) { this.barHeight = barHeight; } /** Gets the text alignment. Can be Element.ALIGN_LEFT, * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. * @return the text alignment */ public int getTextAlignment() { return textAlignment; } /** Sets the text alignment. Can be Element.ALIGN_LEFT, * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. * @param textAlignment the text alignment */ public void setTextAlignment(int textAlignment) { this.textAlignment = textAlignment; } /** Gets the optional checksum generation. * @return the optional checksum generation */ public boolean isGenerateChecksum() { return generateChecksum; } /** Setter for property generateChecksum. * @param generateChecksum New value of property generateChecksum. */ public void setGenerateChecksum(boolean generateChecksum) { this.generateChecksum = generateChecksum; } /** Gets the property to show the generated checksum in the the text. * @return value of property checksumText */ public boolean isChecksumText() { return checksumText; } /** Sets the property to show the generated checksum in the the text. * @param checksumText new value of property checksumText */ public void setChecksumText(boolean checksumText) { this.checksumText = checksumText; } /** Sets the property to show the start and stop character '*' in the text for * the barcode 39. * @return value of property startStopText */ public boolean isStartStopText() { return startStopText; } /** Gets the property to show the start and stop character '*' in the text for * the barcode 39. * @param startStopText new value of property startStopText */ public void setStartStopText(boolean startStopText) { this.startStopText = startStopText; } /** Gets the property to generate extended barcode 39. * @return value of property extended. */ public boolean isExtended() { return extended; } /** Sets the property to generate extended barcode 39. * @param extended new value of property extended */ public void setExtended(boolean extended) { this.extended = extended; } /** Gets the code to generate. * @return the code to generate */ public String getCode() { return code; } /** Sets the code to generate. * @param code the code to generate */ public void setCode(String code) { this.code = code; } /** Gets the property to show the guard bars for barcode EAN. * @return value of property guardBars */ public boolean isGuardBars() { return guardBars; } /** Sets the property to show the guard bars for barcode EAN. * @param guardBars new value of property guardBars */ public void setGuardBars(boolean guardBars) { this.guardBars = guardBars; } /** Gets the code type. * @return the code type */ public int getCodeType() { return codeType; } /** Sets the code type. * @param codeType the code type */ public void setCodeType(int codeType) { this.codeType = codeType; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public abstract Rectangle getBarcodeSize(); /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public abstract Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor); /** Creates a template with the barcode. * @param cb the PdfContentByte to create the template. It * serves no other use * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the template * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor) */ public PdfTemplate createTemplateWithBarcode(PdfContentByte cb, Color barColor, Color textColor) { PdfTemplate tp = cb.createTemplate(0, 0); Rectangle rect = placeBarcode(tp, barColor, textColor); tp.setBoundingBox(rect); return tp; } /** Creates an Image with the barcode. * @param cb the PdfContentByte to create the Image. It * serves no other use * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the Image * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor) */ public Image createImageWithBarcode(PdfContentByte cb, Color barColor, Color textColor) { try { return Image.getInstance(createTemplateWithBarcode(cb, barColor, textColor)); } catch (Exception e) { throw new ExceptionConverter(e); } } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public abstract java.awt.Image createAwtImage(Color foreground, Color background); /** Gets the amount of ink spreading. * @return the ink spreading * */ public float getInkSpreading() { return this.inkSpreading; } /** Sets the amount of ink spreading. This value will be subtracted * to the width of each bar. The actual value will depend on the ink * and the printing medium. * @param inkSpreading the ink spreading * */ public void setInkSpreading(float inkSpreading) { this.inkSpreading = inkSpreading; } /** * The alternate text to be used, if present. */ protected String altText; /** * Gets the alternate text. * @return the alternate text */ public String getAltText() { return this.altText; } /** * Sets the alternate text. If present, this text will be used instead of the * text derived from the supplied code. * @param altText the alternate text */ public void setAltText(String altText) { this.altText = altText; } } src/core/com/lowagie/text/pdf/Barcode128.java100644 0 0 70310 11036112746 16345 0ustar 0 0 /* * $Id: Barcode128.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2002-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.Image; import java.awt.image.MemoryImageSource; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** * Implements the code 128 and UCC/EAN-128. Other symbologies are allowed in raw mode.

* The code types allowed are:
*

    *
  • CODE128 - plain barcode 128. *
  • CODE128_UCC - support for UCC/EAN-128 with a full list of AI. *
  • CODE128_RAW - raw mode. The code attribute has the actual codes from 0 * to 105 followed by '\uffff' and the human readable text. *
* The default parameters are: *
 * x = 0.8f;
 * font = BaseFont.createFont("Helvetica", "winansi", false);
 * size = 8;
 * baseline = size;
 * barHeight = size * 3;
 * textAlignment = Element.ALIGN_CENTER;
 * codeType = CODE128;
 * 
* @author Paulo Soares (psoares@consiste.pt) */ public class Barcode128 extends Barcode{ /** The bars to generate the code. */ private static final byte BARS[][] = { {2, 1, 2, 2, 2, 2}, {2, 2, 2, 1, 2, 2}, {2, 2, 2, 2, 2, 1}, {1, 2, 1, 2, 2, 3}, {1, 2, 1, 3, 2, 2}, {1, 3, 1, 2, 2, 2}, {1, 2, 2, 2, 1, 3}, {1, 2, 2, 3, 1, 2}, {1, 3, 2, 2, 1, 2}, {2, 2, 1, 2, 1, 3}, {2, 2, 1, 3, 1, 2}, {2, 3, 1, 2, 1, 2}, {1, 1, 2, 2, 3, 2}, {1, 2, 2, 1, 3, 2}, {1, 2, 2, 2, 3, 1}, {1, 1, 3, 2, 2, 2}, {1, 2, 3, 1, 2, 2}, {1, 2, 3, 2, 2, 1}, {2, 2, 3, 2, 1, 1}, {2, 2, 1, 1, 3, 2}, {2, 2, 1, 2, 3, 1}, {2, 1, 3, 2, 1, 2}, {2, 2, 3, 1, 1, 2}, {3, 1, 2, 1, 3, 1}, {3, 1, 1, 2, 2, 2}, {3, 2, 1, 1, 2, 2}, {3, 2, 1, 2, 2, 1}, {3, 1, 2, 2, 1, 2}, {3, 2, 2, 1, 1, 2}, {3, 2, 2, 2, 1, 1}, {2, 1, 2, 1, 2, 3}, {2, 1, 2, 3, 2, 1}, {2, 3, 2, 1, 2, 1}, {1, 1, 1, 3, 2, 3}, {1, 3, 1, 1, 2, 3}, {1, 3, 1, 3, 2, 1}, {1, 1, 2, 3, 1, 3}, {1, 3, 2, 1, 1, 3}, {1, 3, 2, 3, 1, 1}, {2, 1, 1, 3, 1, 3}, {2, 3, 1, 1, 1, 3}, {2, 3, 1, 3, 1, 1}, {1, 1, 2, 1, 3, 3}, {1, 1, 2, 3, 3, 1}, {1, 3, 2, 1, 3, 1}, {1, 1, 3, 1, 2, 3}, {1, 1, 3, 3, 2, 1}, {1, 3, 3, 1, 2, 1}, {3, 1, 3, 1, 2, 1}, {2, 1, 1, 3, 3, 1}, {2, 3, 1, 1, 3, 1}, {2, 1, 3, 1, 1, 3}, {2, 1, 3, 3, 1, 1}, {2, 1, 3, 1, 3, 1}, {3, 1, 1, 1, 2, 3}, {3, 1, 1, 3, 2, 1}, {3, 3, 1, 1, 2, 1}, {3, 1, 2, 1, 1, 3}, {3, 1, 2, 3, 1, 1}, {3, 3, 2, 1, 1, 1}, {3, 1, 4, 1, 1, 1}, {2, 2, 1, 4, 1, 1}, {4, 3, 1, 1, 1, 1}, {1, 1, 1, 2, 2, 4}, {1, 1, 1, 4, 2, 2}, {1, 2, 1, 1, 2, 4}, {1, 2, 1, 4, 2, 1}, {1, 4, 1, 1, 2, 2}, {1, 4, 1, 2, 2, 1}, {1, 1, 2, 2, 1, 4}, {1, 1, 2, 4, 1, 2}, {1, 2, 2, 1, 1, 4}, {1, 2, 2, 4, 1, 1}, {1, 4, 2, 1, 1, 2}, {1, 4, 2, 2, 1, 1}, {2, 4, 1, 2, 1, 1}, {2, 2, 1, 1, 1, 4}, {4, 1, 3, 1, 1, 1}, {2, 4, 1, 1, 1, 2}, {1, 3, 4, 1, 1, 1}, {1, 1, 1, 2, 4, 2}, {1, 2, 1, 1, 4, 2}, {1, 2, 1, 2, 4, 1}, {1, 1, 4, 2, 1, 2}, {1, 2, 4, 1, 1, 2}, {1, 2, 4, 2, 1, 1}, {4, 1, 1, 2, 1, 2}, {4, 2, 1, 1, 1, 2}, {4, 2, 1, 2, 1, 1}, {2, 1, 2, 1, 4, 1}, {2, 1, 4, 1, 2, 1}, {4, 1, 2, 1, 2, 1}, {1, 1, 1, 1, 4, 3}, {1, 1, 1, 3, 4, 1}, {1, 3, 1, 1, 4, 1}, {1, 1, 4, 1, 1, 3}, {1, 1, 4, 3, 1, 1}, {4, 1, 1, 1, 1, 3}, {4, 1, 1, 3, 1, 1}, {1, 1, 3, 1, 4, 1}, {1, 1, 4, 1, 3, 1}, {3, 1, 1, 1, 4, 1}, {4, 1, 1, 1, 3, 1}, {2, 1, 1, 4, 1, 2}, {2, 1, 1, 2, 1, 4}, {2, 1, 1, 2, 3, 2} }; /** The stop bars. */ private static final byte BARS_STOP[] = {2, 3, 3, 1, 1, 1, 2}; /** The charset code change. */ public static final char CODE_AB_TO_C = 99; /** The charset code change. */ public static final char CODE_AC_TO_B = 100; /** The charset code change. */ public static final char CODE_BC_TO_A = 101; /** The code for UCC/EAN-128. */ public static final char FNC1_INDEX = 102; /** The start code. */ public static final char START_A = 103; /** The start code. */ public static final char START_B = 104; /** The start code. */ public static final char START_C = 105; public static final char FNC1 = '\u00ca'; public static final char DEL = '\u00c3'; public static final char FNC3 = '\u00c4'; public static final char FNC2 = '\u00c5'; public static final char SHIFT = '\u00c6'; public static final char CODE_C = '\u00c7'; public static final char CODE_A = '\u00c8'; public static final char FNC4 = '\u00c8'; public static final char STARTA = '\u00cb'; public static final char STARTB = '\u00cc'; public static final char STARTC = '\u00cd'; private static final IntHashtable ais = new IntHashtable(); /** Creates new Barcode128 */ public Barcode128() { try { x = 0.8f; font = BaseFont.createFont("Helvetica", "winansi", false); size = 8; baseline = size; barHeight = size * 3; textAlignment = Element.ALIGN_CENTER; codeType = CODE128; } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Removes the FNC1 codes in the text. * @param code the text to clean * @return the cleaned text */ public static String removeFNC1(String code) { int len = code.length(); StringBuffer buf = new StringBuffer(len); for (int k = 0; k < len; ++k) { char c = code.charAt(k); if (c >= 32 && c <= 126) buf.append(c); } return buf.toString(); } /** * Gets the human readable text of a sequence of AI. * @param code the text * @return the human readable text */ public static String getHumanReadableUCCEAN(String code) { StringBuffer buf = new StringBuffer(); String fnc1 = String.valueOf(FNC1); try { while (true) { if (code.startsWith(fnc1)) { code = code.substring(1); continue; } int n = 0; int idlen = 0; for (int k = 2; k < 5; ++k) { if (code.length() < k) break; if ((n = ais.get(Integer.parseInt(code.substring(0, k)))) != 0) { idlen = k; break; } } if (idlen == 0) break; buf.append('(').append(code.substring(0, idlen)).append(')'); code = code.substring(idlen); if (n > 0) { n -= idlen; if (code.length() <= n) break; buf.append(removeFNC1(code.substring(0, n))); code = code.substring(n); } else { int idx = code.indexOf(FNC1); if (idx < 0) break; buf.append(code.substring(0,idx)); code = code.substring(idx + 1); } } } catch (Exception e) { //empty } buf.append(removeFNC1(code)); return buf.toString(); } /** Returns true if the next numDigits * starting from index textIndex are numeric skipping any FNC1. * @param text the text to check * @param textIndex where to check from * @param numDigits the number of digits to check * @return the check result */ static boolean isNextDigits(String text, int textIndex, int numDigits) { int len = text.length(); while (textIndex < len && numDigits > 0) { if (text.charAt(textIndex) == FNC1) { ++textIndex; continue; } int n = Math.min(2, numDigits); if (textIndex + n > len) return false; while (n-- > 0) { char c = text.charAt(textIndex++); if (c < '0' || c > '9') return false; --numDigits; } } return numDigits == 0; } /** Packs the digits for charset C also considering FNC1. It assumes that all the parameters * are valid. * @param text the text to pack * @param textIndex where to pack from * @param numDigits the number of digits to pack. It is always an even number * @return the packed digits, two digits per character */ static String getPackedRawDigits(String text, int textIndex, int numDigits) { String out = ""; int start = textIndex; while (numDigits > 0) { if (text.charAt(textIndex) == FNC1) { out += FNC1_INDEX; ++textIndex; continue; } numDigits -= 2; int c1 = text.charAt(textIndex++) - '0'; int c2 = text.charAt(textIndex++) - '0'; out += (char)(c1 * 10 + c2); } return (char)(textIndex - start) + out; } /** Converts the human readable text to the characters needed to * create a barcode. Some optimization is done to get the shortest code. * @param text the text to convert * @param ucc true if it is an UCC/EAN-128. In this case * the character FNC1 is added * @return the code ready to be fed to getBarsCode128Raw() */ public static String getRawText(String text, boolean ucc) { String out = ""; int tLen = text.length(); if (tLen == 0) { out += START_B; if (ucc) out += FNC1_INDEX; return out; } int c = 0; for (int k = 0; k < tLen; ++k) { c = text.charAt(k); if (c > 127 && c != FNC1) throw new RuntimeException("There are illegal characters for barcode 128 in '" + text + "'."); } c = text.charAt(0); char currentCode = START_B; int index = 0; if (isNextDigits(text, index, 2)) { currentCode = START_C; out += currentCode; if (ucc) out += FNC1_INDEX; String out2 = getPackedRawDigits(text, index, 2); index += out2.charAt(0); out += out2.substring(1); } else if (c < ' ') { currentCode = START_A; out += currentCode; if (ucc) out += FNC1_INDEX; out += (char)(c + 64); ++index; } else { out += currentCode; if (ucc) out += FNC1_INDEX; if (c == FNC1) out += FNC1_INDEX; else out += (char)(c - ' '); ++index; } while (index < tLen) { switch (currentCode) { case START_A: { if (isNextDigits(text, index, 4)) { currentCode = START_C; out += CODE_AB_TO_C; String out2 = getPackedRawDigits(text, index, 4); index += out2.charAt(0); out += out2.substring(1); } else { c = text.charAt(index++); if (c == FNC1) out += FNC1_INDEX; else if (c > '_') { currentCode = START_B; out += CODE_AC_TO_B; out += (char)(c - ' '); } else if (c < ' ') out += (char)(c + 64); else out += (char)(c - ' '); } } break; case START_B: { if (isNextDigits(text, index, 4)) { currentCode = START_C; out += CODE_AB_TO_C; String out2 = getPackedRawDigits(text, index, 4); index += out2.charAt(0); out += out2.substring(1); } else { c = text.charAt(index++); if (c == FNC1) out += FNC1_INDEX; else if (c < ' ') { currentCode = START_A; out += CODE_BC_TO_A; out += (char)(c + 64); } else { out += (char)(c - ' '); } } } break; case START_C: { if (isNextDigits(text, index, 2)) { String out2 = getPackedRawDigits(text, index, 2); index += out2.charAt(0); out += out2.substring(1); } else { c = text.charAt(index++); if (c == FNC1) out += FNC1_INDEX; else if (c < ' ') { currentCode = START_A; out += CODE_BC_TO_A; out += (char)(c + 64); } else { currentCode = START_B; out += CODE_AC_TO_B; out += (char)(c - ' '); } } } break; } } return out; } /** Generates the bars. The input has the actual barcodes, not * the human readable text. * @param text the barcode * @return the bars */ public static byte[] getBarsCode128Raw(String text) { int idx = text.indexOf('\uffff'); if (idx >= 0) text = text.substring(0, idx); int chk = text.charAt(0); for (int k = 1; k < text.length(); ++k) chk += k * text.charAt(k); chk = chk % 103; text += (char)chk; byte bars[] = new byte[(text.length() + 1) * 6 + 7]; int k; for (k = 0; k < text.length(); ++k) System.arraycopy(BARS[text.charAt(k)], 0, bars, k * 6, 6); System.arraycopy(BARS_STOP, 0, bars, k * 6, 7); return bars; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float fontX = 0; float fontY = 0; String fullCode; if (font != null) { if (baseline > 0) fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); else fontY = -baseline + size; if (codeType == CODE128_RAW) { int idx = code.indexOf('\uffff'); if (idx < 0) fullCode = ""; else fullCode = code.substring(idx + 1); } else if (codeType == CODE128_UCC) fullCode = getHumanReadableUCCEAN(code); else fullCode = removeFNC1(code); fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); } if (codeType == CODE128_RAW) { int idx = code.indexOf('\uffff'); if (idx >= 0) fullCode = code.substring(0, idx); else fullCode = code; } else { fullCode = getRawText(code, codeType == CODE128_UCC); } int len = fullCode.length(); float fullWidth = (len + 2) * 11 * x + 2 * x; fullWidth = Math.max(fullWidth, fontX); float fullHeight = barHeight + fontY; return new Rectangle(fullWidth, fullHeight); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { String fullCode; if (codeType == CODE128_RAW) { int idx = code.indexOf('\uffff'); if (idx < 0) fullCode = ""; else fullCode = code.substring(idx + 1); } else if (codeType == CODE128_UCC) fullCode = getHumanReadableUCCEAN(code); else fullCode = removeFNC1(code); float fontX = 0; if (font != null) { fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); } String bCode; if (codeType == CODE128_RAW) { int idx = code.indexOf('\uffff'); if (idx >= 0) bCode = code.substring(0, idx); else bCode = code; } else { bCode = getRawText(code, codeType == CODE128_UCC); } int len = bCode.length(); float fullWidth = (len + 2) * 11 * x + 2 * x; float barStartX = 0; float textStartX = 0; switch (textAlignment) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: if (fontX > fullWidth) barStartX = fontX - fullWidth; else textStartX = fullWidth - fontX; break; default: if (fontX > fullWidth) barStartX = (fontX - fullWidth) / 2; else textStartX = (fullWidth - fontX) / 2; break; } float barStartY = 0; float textStartY = 0; if (font != null) { if (baseline <= 0) textStartY = barHeight - baseline; else { textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); barStartY = textStartY + baseline; } } byte bars[] = getBarsCode128Raw(bCode); boolean print = true; if (barColor != null) cb.setColorFill(barColor); for (int k = 0; k < bars.length; ++k) { float w = bars[k] * x; if (print) cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); print = !print; barStartX += w; } cb.fill(); if (font != null) { if (textColor != null) cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(font, size); cb.setTextMatrix(textStartX, textStartY); cb.showText(fullCode); cb.endText(); } return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); String bCode; if (codeType == CODE128_RAW) { int idx = code.indexOf('\uffff'); if (idx >= 0) bCode = code.substring(0, idx); else bCode = code; } else { bCode = getRawText(code, codeType == CODE128_UCC); } int len = bCode.length(); int fullWidth = (len + 2) * 11 + 2; byte bars[] = getBarsCode128Raw(bCode); boolean print = true; int ptr = 0; int height = (int)barHeight; int pix[] = new int[fullWidth * height]; for (int k = 0; k < bars.length; ++k) { int w = bars[k]; int c = g; if (print) c = f; print = !print; for (int j = 0; j < w; ++j) pix[ptr++] = c; } for (int k = fullWidth; k < pix.length; k += fullWidth) { System.arraycopy(pix, 0, pix, k, fullWidth); } Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); return img; } /** * Sets the code to generate. If it's an UCC code and starts with '(' it will * be split by the AI. This code in UCC mode is valid: *

* (01)00000090311314(10)ABC123(15)060916 * @param code the code to generate */ public void setCode(String code) { if (getCodeType() == Barcode128.CODE128_UCC && code.startsWith("(")) { int idx = 0; String ret = ""; while (idx >= 0) { int end = code.indexOf(')', idx); if (end < 0) throw new IllegalArgumentException("Badly formed UCC string: " + code); String sai = code.substring(idx + 1, end); if (sai.length() < 2) throw new IllegalArgumentException("AI too short: (" + sai + ")"); int ai = Integer.parseInt(sai); int len = ais.get(ai); if (len == 0) throw new IllegalArgumentException("AI not found: (" + sai + ")"); sai = String.valueOf(ai); if (sai.length() == 1) sai = "0" + sai; idx = code.indexOf('(', end); int next = (idx < 0 ? code.length() : idx); ret += sai + code.substring(end + 1, next); if (len < 0) { if (idx >= 0) ret += FNC1; } else if (next - end - 1 + sai.length() != len) throw new IllegalArgumentException("Invalid AI length: (" + sai + ")"); } super.setCode(ret); } else super.setCode(code); } static { ais.put(0, 20); ais.put(1, 16); ais.put(2, 16); ais.put(10, -1); ais.put(11, 9); ais.put(12, 8); ais.put(13, 8); ais.put(15, 8); ais.put(17, 8); ais.put(20, 4); ais.put(21, -1); ais.put(22, -1); ais.put(23, -1); ais.put(240, -1); ais.put(241, -1); ais.put(250, -1); ais.put(251, -1); ais.put(252, -1); ais.put(30, -1); for (int k = 3100; k < 3700; ++k) ais.put(k, 10); ais.put(37, -1); for (int k = 3900; k < 3940; ++k) ais.put(k, -1); ais.put(400, -1); ais.put(401, -1); ais.put(402, 20); ais.put(403, -1); for (int k = 410; k < 416; ++k) ais.put(k, 16); ais.put(420, -1); ais.put(421, -1); ais.put(422, 6); ais.put(423, -1); ais.put(424, 6); ais.put(425, 6); ais.put(426, 6); ais.put(7001, 17); ais.put(7002, -1); for (int k = 7030; k < 7040; ++k) ais.put(k, -1); ais.put(8001, 18); ais.put(8002, -1); ais.put(8003, -1); ais.put(8004, -1); ais.put(8005, 10); ais.put(8006, 22); ais.put(8007, -1); ais.put(8008, -1); ais.put(8018, 22); ais.put(8020, -1); ais.put(8100, 10); ais.put(8101, 14); ais.put(8102, 6); for (int k = 90; k < 100; ++k) ais.put(k, -1); } } src/core/com/lowagie/text/pdf/Barcode39.java100644 0 0 33664 11000354131 16264 0ustar 0 0 /* * $Id: Barcode39.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2002-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.Image; import java.awt.image.MemoryImageSource; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** Implements the code 39 and code 39 extended. The default parameters are: *

 *x = 0.8f;
 *n = 2;
 *font = BaseFont.createFont("Helvetica", "winansi", false);
 *size = 8;
 *baseline = size;
 *barHeight = size * 3;
 *textAlignment = Element.ALIGN_CENTER;
 *generateChecksum = false;
 *checksumText = false;
 *startStopText = true;
 *extended = false;
 * 
* * @author Paulo Soares (psoares@consiste.pt) */ public class Barcode39 extends Barcode{ /** The bars to generate the code. */ private static final byte BARS[][] = { {0,0,0,1,1,0,1,0,0}, {1,0,0,1,0,0,0,0,1}, {0,0,1,1,0,0,0,0,1}, {1,0,1,1,0,0,0,0,0}, {0,0,0,1,1,0,0,0,1}, {1,0,0,1,1,0,0,0,0}, {0,0,1,1,1,0,0,0,0}, {0,0,0,1,0,0,1,0,1}, {1,0,0,1,0,0,1,0,0}, {0,0,1,1,0,0,1,0,0}, {1,0,0,0,0,1,0,0,1}, {0,0,1,0,0,1,0,0,1}, {1,0,1,0,0,1,0,0,0}, {0,0,0,0,1,1,0,0,1}, {1,0,0,0,1,1,0,0,0}, {0,0,1,0,1,1,0,0,0}, {0,0,0,0,0,1,1,0,1}, {1,0,0,0,0,1,1,0,0}, {0,0,1,0,0,1,1,0,0}, {0,0,0,0,1,1,1,0,0}, {1,0,0,0,0,0,0,1,1}, {0,0,1,0,0,0,0,1,1}, {1,0,1,0,0,0,0,1,0}, {0,0,0,0,1,0,0,1,1}, {1,0,0,0,1,0,0,1,0}, {0,0,1,0,1,0,0,1,0}, {0,0,0,0,0,0,1,1,1}, {1,0,0,0,0,0,1,1,0}, {0,0,1,0,0,0,1,1,0}, {0,0,0,0,1,0,1,1,0}, {1,1,0,0,0,0,0,0,1}, {0,1,1,0,0,0,0,0,1}, {1,1,1,0,0,0,0,0,0}, {0,1,0,0,1,0,0,0,1}, {1,1,0,0,1,0,0,0,0}, {0,1,1,0,1,0,0,0,0}, {0,1,0,0,0,0,1,0,1}, {1,1,0,0,0,0,1,0,0}, {0,1,1,0,0,0,1,0,0}, {0,1,0,1,0,1,0,0,0}, {0,1,0,1,0,0,0,1,0}, {0,1,0,0,0,1,0,1,0}, {0,0,0,1,0,1,0,1,0}, {0,1,0,0,1,0,1,0,0} }; /** The index chars to BARS. */ private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*"; /** The character combinations to make the code 39 extended. */ private static final String EXTENDED = "%U" + "$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z" + "%A%B%C%D%E /A/B/C/D/E/F/G/H/I/J/K/L - ./O" + " 0 1 2 3 4 5 6 7 8 9/Z%F%G%H%I%J%V" + " A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" + "%K%L%M%N%O%W" + "+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z" + "%P%Q%R%S%T"; /** Creates a new Barcode39. */ public Barcode39() { try { x = 0.8f; n = 2; font = BaseFont.createFont("Helvetica", "winansi", false); size = 8; baseline = size; barHeight = size * 3; textAlignment = Element.ALIGN_CENTER; generateChecksum = false; checksumText = false; startStopText = true; extended = false; } catch (Exception e) { throw new ExceptionConverter(e); } } /** Creates the bars. * @param text the text to create the bars. This text does not include the start and * stop characters * @return the bars */ public static byte[] getBarsCode39(String text) { text = "*" + text + "*"; byte bars[] = new byte[text.length() * 10 - 1]; for (int k = 0; k < text.length(); ++k) { int idx = CHARS.indexOf(text.charAt(k)); if (idx < 0) throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in code 39."); System.arraycopy(BARS[idx], 0, bars, k * 10, 9); } return bars; } /** Converts the extended text into a normal, escaped text, * ready to generate bars. * @param text the extended text * @return the escaped text */ public static String getCode39Ex(String text) { String out = ""; for (int k = 0; k < text.length(); ++k) { char c = text.charAt(k); if (c > 127) throw new IllegalArgumentException("The character '" + c + "' is illegal in code 39 extended."); char c1 = EXTENDED.charAt(c * 2); char c2 = EXTENDED.charAt(c * 2 + 1); if (c1 != ' ') out += c1; out += c2; } return out; } /** Calculates the checksum. * @param text the text * @return the checksum */ static char getChecksum(String text) { int chk = 0; for (int k = 0; k < text.length(); ++k) { int idx = CHARS.indexOf(text.charAt(k)); if (idx < 0) throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in code 39."); chk += idx; } return CHARS.charAt(chk % 43); } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float fontX = 0; float fontY = 0; String fCode = code; if (extended) fCode = getCode39Ex(code); if (font != null) { if (baseline > 0) fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); else fontY = -baseline + size; String fullCode = code; if (generateChecksum && checksumText) fullCode += getChecksum(fCode); if (startStopText) fullCode = "*" + fullCode + "*"; fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); } int len = fCode.length() + 2; if (generateChecksum) ++len; float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x; fullWidth = Math.max(fullWidth, fontX); float fullHeight = barHeight + fontY; return new Rectangle(fullWidth, fullHeight); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { String fullCode = code; float fontX = 0; String bCode = code; if (extended) bCode = getCode39Ex(code); if (font != null) { if (generateChecksum && checksumText) fullCode += getChecksum(bCode); if (startStopText) fullCode = "*" + fullCode + "*"; fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); } if (generateChecksum) bCode += getChecksum(bCode); int len = bCode.length() + 2; float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x; float barStartX = 0; float textStartX = 0; switch (textAlignment) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: if (fontX > fullWidth) barStartX = fontX - fullWidth; else textStartX = fullWidth - fontX; break; default: if (fontX > fullWidth) barStartX = (fontX - fullWidth) / 2; else textStartX = (fullWidth - fontX) / 2; break; } float barStartY = 0; float textStartY = 0; if (font != null) { if (baseline <= 0) textStartY = barHeight - baseline; else { textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); barStartY = textStartY + baseline; } } byte bars[] = getBarsCode39(bCode); boolean print = true; if (barColor != null) cb.setColorFill(barColor); for (int k = 0; k < bars.length; ++k) { float w = (bars[k] == 0 ? x : x * n); if (print) cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); print = !print; barStartX += w; } cb.fill(); if (font != null) { if (textColor != null) cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(font, size); cb.setTextMatrix(textStartX, textStartY); cb.showText(fullCode); cb.endText(); } return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); String bCode = code; if (extended) bCode = getCode39Ex(code); if (generateChecksum) bCode += getChecksum(bCode); int len = bCode.length() + 2; int nn = (int)n; int fullWidth = len * (6 + 3 * nn) + (len - 1); byte bars[] = getBarsCode39(bCode); boolean print = true; int ptr = 0; int height = (int)barHeight; int pix[] = new int[fullWidth * height]; for (int k = 0; k < bars.length; ++k) { int w = (bars[k] == 0 ? 1 : nn); int c = g; if (print) c = f; print = !print; for (int j = 0; j < w; ++j) pix[ptr++] = c; } for (int k = fullWidth; k < pix.length; k += fullWidth) { System.arraycopy(pix, 0, pix, k, fullWidth); } Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); return img; } } src/core/com/lowagie/text/pdf/BarcodeCodabar.java100644 0 0 31477 11036112746 17401 0ustar 0 0 /* * $Id: BarcodeCodabar.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2002-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.Image; import java.awt.image.MemoryImageSource; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** Implements the code codabar. The default parameters are: *

 *x = 0.8f;
 *n = 2;
 *font = BaseFont.createFont("Helvetica", "winansi", false);
 *size = 8;
 *baseline = size;
 *barHeight = size * 3;
 *textAlignment = Element.ALIGN_CENTER;
 *generateChecksum = false;
 *checksumText = false;
 *startStopText = false;
 * 
* * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodeCodabar extends Barcode{ /** The bars to generate the code. */ private static final byte BARS[][] = { {0,0,0,0,0,1,1}, // 0 {0,0,0,0,1,1,0}, // 1 {0,0,0,1,0,0,1}, // 2 {1,1,0,0,0,0,0}, // 3 {0,0,1,0,0,1,0}, // 4 {1,0,0,0,0,1,0}, // 5 {0,1,0,0,0,0,1}, // 6 {0,1,0,0,1,0,0}, // 7 {0,1,1,0,0,0,0}, // 8 {1,0,0,1,0,0,0}, // 9 {0,0,0,1,1,0,0}, // - {0,0,1,1,0,0,0}, // $ {1,0,0,0,1,0,1}, // : {1,0,1,0,0,0,1}, // / {1,0,1,0,1,0,0}, // . {0,0,1,0,1,0,1}, // + {0,0,1,1,0,1,0}, // a {0,1,0,1,0,0,1}, // b {0,0,0,1,0,1,1}, // c {0,0,0,1,1,1,0} // d }; /** The index chars to BARS. */ private static final String CHARS = "0123456789-$:/.+ABCD"; private static final int START_STOP_IDX = 16; /** Creates a new BarcodeCodabar. */ public BarcodeCodabar() { try { x = 0.8f; n = 2; font = BaseFont.createFont("Helvetica", "winansi", false); size = 8; baseline = size; barHeight = size * 3; textAlignment = Element.ALIGN_CENTER; generateChecksum = false; checksumText = false; startStopText = false; codeType = CODABAR; } catch (Exception e) { throw new ExceptionConverter(e); } } /** Creates the bars. * @param text the text to create the bars * @return the bars */ public static byte[] getBarsCodabar(String text) { text = text.toUpperCase(); int len = text.length(); if (len < 2) throw new IllegalArgumentException("Codabar must have at least a start and stop character."); if (CHARS.indexOf(text.charAt(0)) < START_STOP_IDX || CHARS.indexOf(text.charAt(len - 1)) < START_STOP_IDX) throw new IllegalArgumentException("Codabar must have one of 'ABCD' as start/stop character."); byte bars[] = new byte[text.length() * 8 - 1]; for (int k = 0; k < len; ++k) { int idx = CHARS.indexOf(text.charAt(k)); if (idx >= START_STOP_IDX && k > 0 && k < len - 1) throw new IllegalArgumentException("In codabar, start/stop characters are only allowed at the extremes."); if (idx < 0) throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in codabar."); System.arraycopy(BARS[idx], 0, bars, k * 8, 7); } return bars; } public static String calculateChecksum(String code) { if (code.length() < 2) return code; String text = code.toUpperCase(); int sum = 0; int len = text.length(); for (int k = 0; k < len; ++k) sum += CHARS.indexOf(text.charAt(k)); sum = (sum + 15) / 16 * 16 - sum; return code.substring(0, len - 1) + CHARS.charAt(sum) + code.substring(len - 1); } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float fontX = 0; float fontY = 0; String text = code; if (generateChecksum && checksumText) text = calculateChecksum(code); if (!startStopText) text = text.substring(1, text.length() - 1); if (font != null) { if (baseline > 0) fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); else fontY = -baseline + size; fontX = font.getWidthPoint(altText != null ? altText : text, size); } text = code; if (generateChecksum) text = calculateChecksum(code); byte bars[] = getBarsCodabar(text); int wide = 0; for (int k = 0; k < bars.length; ++k) { wide += bars[k]; } int narrow = bars.length - wide; float fullWidth = x * (narrow + wide * n); fullWidth = Math.max(fullWidth, fontX); float fullHeight = barHeight + fontY; return new Rectangle(fullWidth, fullHeight); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { String fullCode = code; if (generateChecksum && checksumText) fullCode = calculateChecksum(code); if (!startStopText) fullCode = fullCode.substring(1, fullCode.length() - 1); float fontX = 0; if (font != null) { fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); } byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code); int wide = 0; for (int k = 0; k < bars.length; ++k) { wide += bars[k]; } int narrow = bars.length - wide; float fullWidth = x * (narrow + wide * n); float barStartX = 0; float textStartX = 0; switch (textAlignment) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: if (fontX > fullWidth) barStartX = fontX - fullWidth; else textStartX = fullWidth - fontX; break; default: if (fontX > fullWidth) barStartX = (fontX - fullWidth) / 2; else textStartX = (fullWidth - fontX) / 2; break; } float barStartY = 0; float textStartY = 0; if (font != null) { if (baseline <= 0) textStartY = barHeight - baseline; else { textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); barStartY = textStartY + baseline; } } boolean print = true; if (barColor != null) cb.setColorFill(barColor); for (int k = 0; k < bars.length; ++k) { float w = (bars[k] == 0 ? x : x * n); if (print) cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); print = !print; barStartX += w; } cb.fill(); if (font != null) { if (textColor != null) cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(font, size); cb.setTextMatrix(textStartX, textStartY); cb.showText(fullCode); cb.endText(); } return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); String fullCode = code; if (generateChecksum && checksumText) fullCode = calculateChecksum(code); if (!startStopText) fullCode = fullCode.substring(1, fullCode.length() - 1); byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code); int wide = 0; for (int k = 0; k < bars.length; ++k) { wide += bars[k]; } int narrow = bars.length - wide; int fullWidth = narrow + wide * (int)n; boolean print = true; int ptr = 0; int height = (int)barHeight; int pix[] = new int[fullWidth * height]; for (int k = 0; k < bars.length; ++k) { int w = (bars[k] == 0 ? 1 : (int)n); int c = g; if (print) c = f; print = !print; for (int j = 0; j < w; ++j) pix[ptr++] = c; } for (int k = fullWidth; k < pix.length; k += fullWidth) { System.arraycopy(pix, 0, pix, k, fullWidth); } Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); return img; } } src/core/com/lowagie/text/pdf/BarcodeDatamatrix.java100644 0 0 137551 11000354131 20147 0ustar 0 0 /* * $Id: BarcodeDatamatrix.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.BadElementException; import com.lowagie.text.Image; import com.lowagie.text.pdf.codec.CCITTG4Encoder; import java.awt.Canvas; import java.awt.Color; import java.awt.image.MemoryImageSource; import java.util.Arrays; import java.io.UnsupportedEncodingException; import java.util.Hashtable; /** * A DataMatrix 2D barcode generator. */ public class BarcodeDatamatrix { /** * No error. */ public static final int DM_NO_ERROR = 0; /** * The text is too big for the symbology capabilities. */ public static final int DM_ERROR_TEXT_TOO_BIG = 1; /** * The dimensions given for the symbol are illegal. */ public static final int DM_ERROR_INVALID_SQUARE = 3; /** * An error while parsing an extension. */ public static final int DM_ERROR_EXTENSION = 5; /** * The best encodation will be used. */ public static final int DM_AUTO = 0; /** * ASCII encodation. */ public static final int DM_ASCII = 1; /** * C40 encodation. */ public static final int DM_C40 = 2; /** * TEXT encodation. */ public static final int DM_TEXT = 3; /** * Binary encodation. */ public static final int DM_B256 = 4; /** * X21 encodation. */ public static final int DM_X21 = 5; /** * EDIFACT encodation. */ public static final int DM_EDIFACT = 6; /** * No encodation needed. The bytes provided are already encoded. */ public static final int DM_RAW = 7; /** * Allows extensions to be embedded at the start of the text. */ public static final int DM_EXTENSION = 32; /** * Doesn't generate the image but returns all the other information. */ public static final int DM_TEST = 64; private final static DmParams[] dmSizes = { new DmParams(10, 10, 10, 10, 3, 3, 5), new DmParams(12, 12, 12, 12, 5, 5, 7), new DmParams(8, 18, 8, 18, 5, 5, 7), new DmParams(14, 14, 14, 14, 8, 8, 10), new DmParams(8, 32, 8, 16, 10, 10, 11), new DmParams(16, 16, 16, 16, 12, 12, 12), new DmParams(12, 26, 12, 26, 16, 16, 14), new DmParams(18, 18, 18, 18, 18, 18, 14), new DmParams(20, 20, 20, 20, 22, 22, 18), new DmParams(12, 36, 12, 18, 22, 22, 18), new DmParams(22, 22, 22, 22, 30, 30, 20), new DmParams(16, 36, 16, 18, 32, 32, 24), new DmParams(24, 24, 24, 24, 36, 36, 24), new DmParams(26, 26, 26, 26, 44, 44, 28), new DmParams(16, 48, 16, 24, 49, 49, 28), new DmParams(32, 32, 16, 16, 62, 62, 36), new DmParams(36, 36, 18, 18, 86, 86, 42), new DmParams(40, 40, 20, 20, 114, 114, 48), new DmParams(44, 44, 22, 22, 144, 144, 56), new DmParams(48, 48, 24, 24, 174, 174, 68), new DmParams(52, 52, 26, 26, 204, 102, 42), new DmParams(64, 64, 16, 16, 280, 140, 56), new DmParams(72, 72, 18, 18, 368, 92, 36), new DmParams(80, 80, 20, 20, 456, 114, 48), new DmParams(88, 88, 22, 22, 576, 144, 56), new DmParams(96, 96, 24, 24, 696, 174, 68), new DmParams(104, 104, 26, 26, 816, 136, 56), new DmParams(120, 120, 20, 20, 1050, 175, 68), new DmParams(132, 132, 22, 22, 1304, 163, 62), new DmParams(144, 144, 24, 24, 1558, 156, 62)}; private static final String x12 = "\r*> 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private int extOut; private short[] place; private byte[] image; private int height; private int width; private int ws; private int options; /** * Creates an instance of this class. */ public BarcodeDatamatrix() { } private void setBit(int x, int y, int xByte) { image[y * xByte + x / 8] |= (byte)(128 >> (x & 7)); } private void draw(byte[] data, int dataSize, DmParams dm) { int i, j, p, x, y, xs, ys, z; int xByte = (dm.width + ws * 2 + 7) / 8; Arrays.fill(image, (byte)0); //alignment patterns //dotted horizontal line for (i = ws; i < dm.height + ws; i += dm.heightSection) { for (j = ws; j < dm.width + ws; j += 2) { setBit(j, i, xByte); } } //solid horizontal line for (i = dm.heightSection - 1 + ws; i < dm.height + ws; i += dm.heightSection) { for (j = ws; j < dm.width + ws; ++j) { setBit(j, i, xByte); } } //solid vertical line for (i = ws; i < dm.width + ws; i += dm.widthSection) { for (j = ws; j < dm.height + ws; ++j) { setBit(i, j, xByte); } } //dotted vertical line for (i = dm.widthSection - 1 + ws; i < dm.width + ws; i += dm.widthSection) { for (j = 1 + ws; j < dm.height + ws; j += 2) { setBit(i, j, xByte); } } p = 0; for (ys = 0; ys < dm.height; ys += dm.heightSection) { for (y = 1; y < dm.heightSection - 1; ++y) { for (xs = 0; xs < dm.width; xs += dm.widthSection) { for (x = 1; x < dm.widthSection - 1; ++x) { z = place[p++]; if (z == 1 || (z > 1 && ((data[z/8-1] & 0xff) & (128 >> (z%8))) != 0)) setBit(x + xs + ws, y + ys + ws, xByte); } } } } } private static void makePadding(byte[] data, int position, int count) { //already in ascii mode if (count <= 0) return; data[position++] = (byte)129; while (--count > 0) { int t = 129 + (((position + 1) * 149) % 253) + 1; if (t > 254) t -= 254; data[position++] = (byte)t; } } private static boolean isDigit(int c) { return c >= '0' && c <= '9'; } private static int asciiEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) { int ptrIn, ptrOut, c; ptrIn = textOffset; ptrOut = dataOffset; textLength += textOffset; dataLength += dataOffset; while (ptrIn < textLength) { if (ptrOut >= dataLength) return -1; c = text[ptrIn++] & 0xff; if (isDigit(c) && ptrIn < textLength && isDigit(text[ptrIn] & 0xff)) { data[ptrOut++] = (byte)((c - '0') * 10 + (text[ptrIn++] & 0xff) - '0' + 130); } else if (c > 127) { if (ptrOut + 1 >= dataLength) return -1; data[ptrOut++] = (byte)235; data[ptrOut++] = (byte)(c - 128 + 1); } else { data[ptrOut++] = (byte)(c + 1); } } return ptrOut - dataOffset; } private static int b256Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) { int k, j, prn, tv, c; if (textLength == 0) return 0; if (textLength < 250 && textLength + 2 > dataLength) return -1; if (textLength >= 250 && textLength + 3 > dataLength) return -1; data[dataOffset] = (byte)231; if (textLength < 250) { data[dataOffset + 1] = (byte)textLength; k = 2; } else { data[dataOffset + 1] = (byte)(textLength / 250 + 249); data[dataOffset + 2] = (byte)(textLength % 250); k = 3; } System.arraycopy(text, textOffset, data, k + dataOffset, textLength); k += textLength + dataOffset; for (j = dataOffset + 1; j < k; ++j) { c = data[j] & 0xff; prn = ((149 * (j + 1)) % 255) + 1; tv = c + prn; if (tv > 255) tv -= 256; data[j] = (byte)tv; } return k - dataOffset; } private static int X12Encodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) { int ptrIn, ptrOut, count, k, n, ci; byte c; if (textLength == 0) return 0; ptrIn = 0; ptrOut = 0; byte[] x = new byte[textLength]; count = 0; for (; ptrIn < textLength; ++ptrIn) { int i = x12.indexOf((char)text[ptrIn + textOffset]); if (i >= 0) { x[ptrIn] = (byte)i; ++count; } else { x[ptrIn] = 100; if (count >= 6) count -= (count / 3) * 3; for (k = 0; k < count; ++k) x[ptrIn - k - 1] = 100; count = 0; } } if (count >= 6) count -= (count / 3) * 3; for (k = 0; k < count; ++k) x[ptrIn - k - 1] = 100; ptrIn = 0; c = 0; for (; ptrIn < textLength; ++ptrIn) { c = x[ptrIn]; if (ptrOut >= dataLength) break; if (c < 40) { if (ptrIn == 0 || (ptrIn > 0 && x[ptrIn - 1] > 40)) data[dataOffset + ptrOut++] = (byte)238; if (ptrOut + 2 > dataLength) break; n = 1600 * x[ptrIn] + 40 * x[ptrIn + 1] + x[ptrIn + 2] + 1; data[dataOffset + ptrOut++] = (byte)(n / 256); data[dataOffset + ptrOut++] = (byte)n; ptrIn += 2; } else { if (ptrIn > 0 && x[ptrIn - 1] < 40) data[dataOffset + ptrOut++] = (byte)254; ci = text[ptrIn + textOffset] & 0xff; if (ci > 127) { data[dataOffset + ptrOut++] = (byte)235; ci -= 128; } if (ptrOut >= dataLength) break; data[dataOffset + ptrOut++] = (byte)(ci + 1); } } c = 100; if (textLength > 0) c = x[textLength - 1]; if (ptrIn != textLength || (c < 40 && ptrOut >= dataLength)) return -1; if (c < 40) data[dataOffset + ptrOut++] = (byte)(254); return ptrOut; } private static int EdifactEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength) { int ptrIn, ptrOut, edi, pedi, c; if (textLength == 0) return 0; ptrIn = 0; ptrOut = 0; edi = 0; pedi = 18; boolean ascii = true; for (; ptrIn < textLength; ++ptrIn) { c = text[ptrIn + textOffset] & 0xff; if (((c & 0xe0) == 0x40 || (c & 0xe0) == 0x20) && c != '_') { if (ascii) { if (ptrOut + 1 > dataLength) break; data[dataOffset + ptrOut++] = (byte)240; ascii = false; } c &= 0x3f; edi |= c << pedi; if (pedi == 0) { if (ptrOut + 3 > dataLength) break; data[dataOffset + ptrOut++] = (byte)(edi >> 16); data[dataOffset + ptrOut++] = (byte)(edi >> 8); data[dataOffset + ptrOut++] = (byte)edi; edi = 0; pedi = 18; } else pedi -= 6; } else { if (!ascii) { edi |= ('_' & 0x3f) << pedi; if (ptrOut + (3 - pedi / 8) > dataLength) break; data[dataOffset + ptrOut++] = (byte)(edi >> 16); if (pedi <= 12) data[dataOffset + ptrOut++] = (byte)(edi >> 8); if (pedi <= 6) data[dataOffset + ptrOut++] = (byte)edi; ascii = true; pedi = 18; edi = 0; } if (c > 127) { if (ptrOut >= dataLength) break; data[dataOffset + ptrOut++] = (byte)235; c -= 128; } if (ptrOut >= dataLength) break; data[dataOffset + ptrOut++] = (byte)(c + 1); } } if (ptrIn != textLength) return -1; if (!ascii) { edi |= ('_' & 0x3f) << pedi; if (ptrOut + (3 - pedi / 8) > dataLength) return -1; data[dataOffset + ptrOut++] = (byte)(edi >> 16); if (pedi <= 12) data[dataOffset + ptrOut++] = (byte)(edi >> 8); if (pedi <= 6) data[dataOffset + ptrOut++] = (byte)edi; } return ptrOut; } private static int C40OrTextEncodation(byte[] text, int textOffset, int textLength, byte[] data, int dataOffset, int dataLength, boolean c40) { int ptrIn, ptrOut, encPtr, last0, last1, i, a, c; String basic, shift2, shift3; if (textLength == 0) return 0; ptrIn = 0; ptrOut = 0; if (c40) data[dataOffset + ptrOut++] = (byte)230; else data[dataOffset + ptrOut++] = (byte)239; shift2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_"; if (c40) { basic = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; shift3 = "`abcdefghijklmnopqrstuvwxyz{|}~\177"; } else { basic = " 0123456789abcdefghijklmnopqrstuvwxyz"; shift3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\177"; } int[] enc = new int[textLength * 4 + 10]; encPtr = 0; last0 = 0; last1 = 0; while (ptrIn < textLength) { if ((encPtr % 3) == 0) { last0 = ptrIn; last1 = encPtr; } c = text[textOffset + ptrIn++] & 0xff; if (c > 127) { c -= 128; enc[encPtr++] = 1; enc[encPtr++] = 30; } int idx = basic.indexOf((char)c); if (idx >= 0) { enc[encPtr++] = idx + 3; } else if (c < 32) { enc[encPtr++] = 0; enc[encPtr++] = c; } else if ((idx = shift2.indexOf((char)c)) >= 0) { enc[encPtr++] = 1; enc[encPtr++] = idx; } else if ((idx = shift3.indexOf((char)c)) >= 0) { enc[encPtr++] = 2; enc[encPtr++] = idx; } } if ((encPtr % 3) != 0) { ptrIn = last0; encPtr = last1; } if (encPtr / 3 * 2 > dataLength - 2) { return -1; } i = 0; for (; i < encPtr; i += 3) { a = 1600 * enc[i] + 40 * enc[i + 1] + enc[i + 2] + 1; data[dataOffset + ptrOut++] = (byte)(a / 256); data[dataOffset + ptrOut++] = (byte)a; } data[ptrOut++] = (byte)254; i = asciiEncodation(text, ptrIn, textLength - ptrIn, data, ptrOut, dataLength - ptrOut); if (i < 0) return i; return ptrOut + i; } private static int getEncodation(byte[] text, int textOffset, int textSize, byte[] data, int dataOffset, int dataSize, int options, boolean firstMatch) { int e, j, k; int[] e1 = new int[6]; if (dataSize < 0) return -1; e = -1; options &= 7; if (options == 0) { e1[0] = asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize); if (firstMatch && e1[0] >= 0) return e1[0]; e1[1] = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false); if (firstMatch && e1[1] >= 0) return e1[1]; e1[2] = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true); if (firstMatch && e1[2] >= 0) return e1[2]; e1[3] = b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize); if (firstMatch && e1[3] >= 0) return e1[3]; e1[4] = X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize); if (firstMatch && e1[4] >= 0) return e1[4]; e1[5] = EdifactEncodation(text, textOffset, textSize, data, dataOffset, dataSize); if (firstMatch && e1[5] >= 0) return e1[5]; if (e1[0] < 0 && e1[1] < 0 && e1[2] < 0 && e1[3] < 0 && e1[4] < 0 && e1[5] < 0) { return -1; } j = 0; e = 99999; for (k = 0; k < 6; ++k) { if (e1[k] >= 0 && e1[k] < e) { e = e1[k]; j = k; } } if (j == 0) e = asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize); else if (j == 1) e = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false); else if (j == 2) e = C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true); else if (j == 3) e = b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize); else if (j == 4) e = X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize); return e; } switch (options) { case DM_ASCII: return asciiEncodation(text, textOffset, textSize, data, dataOffset, dataSize); case DM_C40: return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, true); case DM_TEXT: return C40OrTextEncodation(text, textOffset, textSize, data, dataOffset, dataSize, false); case DM_B256: return b256Encodation(text, textOffset, textSize, data, dataOffset, dataSize); case DM_X21: return X12Encodation(text, textOffset, textSize, data, dataOffset, dataSize); case DM_EDIFACT: return EdifactEncodation(text, textOffset, textSize, data, dataOffset, dataSize); case DM_RAW: if (textSize > dataSize) return -1; System.arraycopy(text, textOffset, data, dataOffset, textSize); return textSize; } return -1; } private static int getNumber(byte[] text, int ptrIn, int n) { int v, j, c; v = 0; for (j = 0; j < n; ++j) { c = text[ptrIn++] &0xff; if (c < '0' || c > '9') return -1; v = v * 10 + c - '0'; } return v; } private int processExtensions(byte[] text, int textOffset, int textSize, byte[] data) { int order, ptrIn, ptrOut, eci, fn, ft, fi, c; if ((options & DM_EXTENSION) == 0) return 0; order = 0; ptrIn = 0; ptrOut = 0; while (ptrIn < textSize) { if (order > 20) return -1; c = text[textOffset + ptrIn++] &0xff; ++order; switch (c) { case '.': extOut = ptrIn; return ptrOut; case 'e': if (ptrIn + 6 > textSize) return -1; eci = getNumber(text, textOffset + ptrIn, 6); if (eci < 0) return -1; ptrIn += 6; data[ptrOut++] = (byte)241; if (eci < 127) data[ptrOut++] = (byte)(eci + 1); else if (eci < 16383) { data[ptrOut++] = (byte)((eci - 127) / 254 + 128); data[ptrOut++] = (byte)(((eci - 127) % 254) + 1); } else { data[ptrOut++] = (byte)((eci - 16383) / 64516 + 192); data[ptrOut++] = (byte)((((eci - 16383) / 254) % 254) + 1); data[ptrOut++] = (byte)(((eci - 16383) % 254) + 1); } break; case 's': if (order != 1) return -1; if (ptrIn + 9 > textSize) return -1; fn = getNumber(text, textOffset + ptrIn, 2); if (fn <= 0 || fn > 16) return -1; ptrIn += 2; ft = getNumber(text, textOffset + ptrIn, 2); if (ft <= 1 || ft > 16) return -1; ptrIn += 2; fi = getNumber(text, textOffset + ptrIn, 5); if (fi < 0 || fn >= 64516) return -1; ptrIn += 5; data[ptrOut++] = (byte)(233); data[ptrOut++] = (byte)(((fn - 1) << 4) | (17 - ft)); data[ptrOut++] = (byte)(fi / 254 + 1); data[ptrOut++] = (byte)((fi % 254) + 1); break; case 'p': if (order != 1) return -1; data[ptrOut++] = (byte)(234); break; case 'm': if (order != 1) return -1; if (ptrIn + 1 > textSize) return -1; c = text[textOffset + ptrIn++] &0xff; if (c != '5' && c != '5') return -1; data[ptrOut++] = (byte)(234); data[ptrOut++] = (byte)(c == '5' ? 236 : 237); break; case 'f': if (order != 1 && (order != 2 || (text[textOffset] != 's' && text[textOffset] != 'm'))) return -1; data[ptrOut++] = (byte)(232); } } return -1; } /** * Creates a barcode. The String is interpreted with the ISO-8859-1 encoding * @param text the text * @return the status of the generation. It can be one of this values: *

* DM_NO_ERROR - no error.
* DM_ERROR_TEXT_TOO_BIG - the text is too big for the symbology capabilities.
* DM_ERROR_INVALID_SQUARE - the dimensions given for the symbol are illegal.
* DM_ERROR_EXTENSION - an error was while parsing an extension. * @throws java.io.UnsupportedEncodingException on error */ public int generate(String text) throws UnsupportedEncodingException { byte[] t = text.getBytes("iso-8859-1"); return generate(t, 0, t.length); } /** * Creates a barcode. * @param text the text * @param textOffset the offset to the start of the text * @param textSize the text size * @return the status of the generation. It can be one of this values: *

* DM_NO_ERROR - no error.
* DM_ERROR_TEXT_TOO_BIG - the text is too big for the symbology capabilities.
* DM_ERROR_INVALID_SQUARE - the dimensions given for the symbol are illegal.
* DM_ERROR_EXTENSION - an error was while parsing an extension. */ public int generate(byte[] text, int textOffset, int textSize) { int extCount, e, k, full; DmParams dm, last; byte[] data = new byte[2500]; extOut = 0; extCount = processExtensions(text, textOffset, textSize, data); if (extCount < 0) { return DM_ERROR_EXTENSION; } e = -1; if (height == 0 || width == 0) { last = dmSizes[dmSizes.length - 1]; e = getEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, last.dataSize - extCount, options, false); if (e < 0) { return DM_ERROR_TEXT_TOO_BIG; } e += extCount; for (k = 0; k < dmSizes.length; ++k) { if (dmSizes[k].dataSize >= e) break; } dm = dmSizes[k]; height = dm.height; width = dm.width; } else { for (k = 0; k < dmSizes.length; ++k) { if (height == dmSizes[k].height && width == dmSizes[k].width) break; } if (k == dmSizes.length) { return DM_ERROR_INVALID_SQUARE; } dm = dmSizes[k]; e = getEncodation(text, textOffset + extOut, textSize - extOut, data, extCount, dm.dataSize - extCount, options, true); if (e < 0) { return DM_ERROR_TEXT_TOO_BIG; } e += extCount; } if ((options & DM_TEST) != 0) { return DM_NO_ERROR; } image = new byte[(((dm.width + 2 * ws) + 7) / 8) * (dm.height + 2 * ws)]; makePadding(data, e, dm.dataSize - e); place = Placement.doPlacement(dm.height - (dm.height / dm.heightSection * 2), dm.width - (dm.width / dm.widthSection * 2)); full = dm.dataSize + ((dm.dataSize + 2) / dm.dataBlock) * dm.errorBlock; ReedSolomon.generateECC(data, dm.dataSize, dm.dataBlock, dm.errorBlock); draw(data, full, dm); return DM_NO_ERROR; } /** Gets an Image with the barcode. A successful call to the method generate() * before calling this method is required. * @return the barcode Image * @throws BadElementException on error */ public Image createImage() throws BadElementException { if (image == null) return null; byte g4[] = CCITTG4Encoder.compress(image, width + 2 * ws, height + 2 * ws); return Image.getInstance(width + 2 * ws, height + 2 * ws, false, Image.CCITTG4, 0, g4, null); } /** * Creates a java.awt.Image. A successful call to the method generate() * before calling this method is required. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { if (image == null) return null; int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); int w = width + 2 * ws; int h = height + 2 * ws; int pix[] = new int[w * h]; int stride = (w + 7) / 8; int ptr = 0; for (int k = 0; k < h; ++k) { int p = k * stride; for (int j = 0; j < w; ++j) { int b = image[p + (j / 8)] & 0xff; b <<= j % 8; pix[ptr++] = (b & 0x80) == 0 ? g : f; } } java.awt.Image img = canvas.createImage(new MemoryImageSource(w, h, pix, 0, w)); return img; } private static class DmParams { DmParams(int height, int width, int heightSection, int widthSection, int dataSize, int dataBlock, int errorBlock) { this.height = height; this.width = width; this.heightSection = heightSection; this.widthSection = widthSection; this.dataSize = dataSize; this.dataBlock = dataBlock; this.errorBlock = errorBlock; } int height; int width; int heightSection; int widthSection; int dataSize; int dataBlock; int errorBlock; }; /** * Gets the generated image. The image is represented as a stream of bytes, each byte representing * 8 pixels, 0 for white and 1 for black, with the high-order bit of each byte first. Each row * is aligned at byte boundaries. The dimensions of the image are defined by height and width * plus 2 * ws. * @return the generated image */ public byte[] getImage() { return image; } /** * Gets the height of the barcode. Will contain the real height used after a successful call * to generate(). This height doesn't include the whitespace border, if any. * @return the height of the barcode */ public int getHeight() { return height; } /** * Sets the height of the barcode. If the height is zero it will be calculated. This height doesn't include the whitespace border, if any. *

* The allowed dimensions are (height, width):

* 10, 10
* 12, 12
* 8, 18
* 14, 14
* 8, 32
* 16, 16
* 12, 26
* 18, 18
* 20, 20
* 12, 36
* 22, 22
* 16, 36
* 24, 24
* 26, 26
* 16, 48
* 32, 32
* 36, 36
* 40, 40
* 44, 44
* 48, 48
* 52, 52
* 64, 64
* 72, 72
* 80, 80
* 88, 88
* 96, 96
* 104, 104
* 120, 120
* 132, 132
* 144, 144
* @param height the height of the barcode */ public void setHeight(int height) { this.height = height; } /** * Gets the width of the barcode. Will contain the real width used after a successful call * to generate(). This width doesn't include the whitespace border, if any. * @return the width of the barcode */ public int getWidth() { return width; } /** * Sets the width of the barcode. If the width is zero it will be calculated. This width doesn't include the whitespace border, if any. *

* The allowed dimensions are (height, width):

* 10, 10
* 12, 12
* 8, 18
* 14, 14
* 8, 32
* 16, 16
* 12, 26
* 18, 18
* 20, 20
* 12, 36
* 22, 22
* 16, 36
* 24, 24
* 26, 26
* 16, 48
* 32, 32
* 36, 36
* 40, 40
* 44, 44
* 48, 48
* 52, 52
* 64, 64
* 72, 72
* 80, 80
* 88, 88
* 96, 96
* 104, 104
* 120, 120
* 132, 132
* 144, 144
* @param width the width of the barcode */ public void setWidth(int width) { this.width = width; } /** * Gets the whitespace border around the barcode. * @return the whitespace border around the barcode */ public int getWs() { return ws; } /** * Sets the whitespace border around the barcode. * @param ws the whitespace border around the barcode */ public void setWs(int ws) { this.ws = ws; } /** * Gets the barcode options. * @return the barcode options */ public int getOptions() { return options; } /** * Sets the options for the barcode generation. The options can be:

* One of:
* DM_AUTO - the best encodation will be used
* DM_ASCII - ASCII encodation
* DM_C40 - C40 encodation
* DM_TEXT - TEXT encodation
* DM_B256 - binary encodation
* DM_X21 - X21 encodation
* DM_EDIFACT - EDIFACT encodation
* DM_RAW - no encodation. The bytes provided are already encoded and will be added directly to the barcode, using padding if needed. It assumes that the encodation state is left at ASCII after the last byte.
*

* One of:
* DM_EXTENSION - allows extensions to be embedded at the start of the text:

* exxxxxx - ECI number xxxxxx
* m5 - macro 5
* m6 - macro 6
* f - FNC1
* saabbccccc - Structured Append, aa symbol position (1-16), bb total number of symbols (2-16), ccccc file identification (0-64515)
* p - Reader programming
* . - extension terminator

* Example for a structured append, symbol 2 of 6, with FNC1 and ECI 000005. The actual text is "Hello".

* s020600075fe000005.Hello

* One of:
* DM_TEST - doesn't generate the image but returns all the other information. * @param options the barcode options */ public void setOptions(int options) { this.options = options; } static class Placement { private int nrow; private int ncol; private short[] array; private static final Hashtable cache = new Hashtable(); private Placement() { } static short[] doPlacement(int nrow, int ncol) { Integer key = new Integer(nrow * 1000 + ncol); short[] pc = (short[])cache.get(key); if (pc != null) return pc; Placement p = new Placement(); p.nrow = nrow; p.ncol = ncol; p.array = new short[nrow * ncol]; p.ecc200(); cache.put(key, p.array); return p.array; } /* "module" places "chr+bit" with appropriate wrapping within array[] */ private void module(int row, int col, int chr, int bit) { if (row < 0) { row += nrow; col += 4 - ((nrow+4)%8); } if (col < 0) { col += ncol; row += 4 - ((ncol+4)%8); } array[row*ncol+col] = (short)(8*chr + bit); } /* "utah" places the 8 bits of a utah-shaped symbol character in ECC200 */ private void utah(int row, int col, int chr) { module(row-2,col-2,chr,0); module(row-2,col-1,chr,1); module(row-1,col-2,chr,2); module(row-1,col-1,chr,3); module(row-1,col,chr,4); module(row,col-2,chr,5); module(row,col-1,chr,6); module(row,col,chr,7); } /* "cornerN" places 8 bits of the four special corner cases in ECC200 */ private void corner1(int chr) { module(nrow-1,0,chr,0); module(nrow-1,1,chr,1); module(nrow-1,2,chr,2); module(0,ncol-2,chr,3); module(0,ncol-1,chr,4); module(1,ncol-1,chr,5); module(2,ncol-1,chr,6); module(3,ncol-1,chr,7); } private void corner2(int chr){ module(nrow-3,0,chr,0); module(nrow-2,0,chr,1); module(nrow-1,0,chr,2); module(0,ncol-4,chr,3); module(0,ncol-3,chr,4); module(0,ncol-2,chr,5); module(0,ncol-1,chr,6); module(1,ncol-1,chr,7); } private void corner3(int chr){ module(nrow-3,0,chr,0); module(nrow-2,0,chr,1); module(nrow-1,0,chr,2); module(0,ncol-2,chr,3); module(0,ncol-1,chr,4); module(1,ncol-1,chr,5); module(2,ncol-1,chr,6); module(3,ncol-1,chr,7); } private void corner4(int chr){ module(nrow-1,0,chr,0); module(nrow-1,ncol-1,chr,1); module(0,ncol-3,chr,2); module(0,ncol-2,chr,3); module(0,ncol-1,chr,4); module(1,ncol-3,chr,5); module(1,ncol-2,chr,6); module(1,ncol-1,chr,7); } /* "ECC200" fills an nrow x ncol array with appropriate values for ECC200 */ private void ecc200(){ int row, col, chr; /* First, fill the array[] with invalid entries */ Arrays.fill(array, (short)0); /* Starting in the correct location for character #1, bit 8,... */ chr = 1; row = 4; col = 0; do { /* repeatedly first check for one of the special corner cases, then... */ if ((row == nrow) && (col == 0)) corner1(chr++); if ((row == nrow-2) && (col == 0) && (ncol%4 != 0)) corner2(chr++); if ((row == nrow-2) && (col == 0) && (ncol%8 == 4)) corner3(chr++); if ((row == nrow+4) && (col == 2) && (ncol%8 == 0)) corner4(chr++); /* sweep upward diagonally, inserting successive characters,... */ do { if ((row < nrow) && (col >= 0) && array[row*ncol+col] == 0) utah(row,col,chr++); row -= 2; col += 2; } while ((row >= 0) && (col < ncol)); row += 1; col += 3; /* & then sweep downward diagonally, inserting successive characters,... */ do { if ((row >= 0) && (col < ncol) && array[row*ncol+col] == 0) utah(row,col,chr++); row += 2; col -= 2; } while ((row < nrow) && (col >= 0)); row += 3; col += 1; /* ... until the entire array is scanned */ } while ((row < nrow) || (col < ncol)); /* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */ if (array[nrow*ncol-1] == 0) { array[nrow*ncol-1] = array[nrow*ncol-ncol-2] = 1; } } } static class ReedSolomon { private static final int log[] = { 0, 255, 1, 240, 2, 225, 241, 53, 3, 38, 226, 133, 242, 43, 54, 210, 4, 195, 39, 114, 227, 106, 134, 28, 243, 140, 44, 23, 55, 118, 211, 234, 5, 219, 196, 96, 40, 222, 115, 103, 228, 78, 107, 125, 135, 8, 29, 162, 244, 186, 141, 180, 45, 99, 24, 49, 56, 13, 119, 153, 212, 199, 235, 91, 6, 76, 220, 217, 197, 11, 97, 184, 41, 36, 223, 253, 116, 138, 104, 193, 229, 86, 79, 171, 108, 165, 126, 145, 136, 34, 9, 74, 30, 32, 163, 84, 245, 173, 187, 204, 142, 81, 181, 190, 46, 88, 100, 159, 25, 231, 50, 207, 57, 147, 14, 67, 120, 128, 154, 248, 213, 167, 200, 63, 236, 110, 92, 176, 7, 161, 77, 124, 221, 102, 218, 95, 198, 90, 12, 152, 98, 48, 185, 179, 42, 209, 37, 132, 224, 52, 254, 239, 117, 233, 139, 22, 105, 27, 194, 113, 230, 206, 87, 158, 80, 189, 172, 203, 109, 175, 166, 62, 127, 247, 146, 66, 137, 192, 35, 252, 10, 183, 75, 216, 31, 83, 33, 73, 164, 144, 85, 170, 246, 65, 174, 61, 188, 202, 205, 157, 143, 169, 82, 72, 182, 215, 191, 251, 47, 178, 89, 151, 101, 94, 160, 123, 26, 112, 232, 21, 51, 238, 208, 131, 58, 69, 148, 18, 15, 16, 68, 17, 121, 149, 129, 19, 155, 59, 249, 70, 214, 250, 168, 71, 201, 156, 64, 60, 237, 130, 111, 20, 93, 122, 177, 150 }; private static final int alog[] = { 1, 2, 4, 8, 16, 32, 64, 128, 45, 90, 180, 69, 138, 57, 114, 228, 229, 231, 227, 235, 251, 219, 155, 27, 54, 108, 216, 157, 23, 46, 92, 184, 93, 186, 89, 178, 73, 146, 9, 18, 36, 72, 144, 13, 26, 52, 104, 208, 141, 55, 110, 220, 149, 7, 14, 28, 56, 112, 224, 237, 247, 195, 171, 123, 246, 193, 175, 115, 230, 225, 239, 243, 203, 187, 91, 182, 65, 130, 41, 82, 164, 101, 202, 185, 95, 190, 81, 162, 105, 210, 137, 63, 126, 252, 213, 135, 35, 70, 140, 53, 106, 212, 133, 39, 78, 156, 21, 42, 84, 168, 125, 250, 217, 159, 19, 38, 76, 152, 29, 58, 116, 232, 253, 215, 131, 43, 86, 172, 117, 234, 249, 223, 147, 11, 22, 44, 88, 176, 77, 154, 25, 50, 100, 200, 189, 87, 174, 113, 226, 233, 255, 211, 139, 59, 118, 236, 245, 199, 163, 107, 214, 129, 47, 94, 188, 85, 170, 121, 242, 201, 191, 83, 166, 97, 194, 169, 127, 254, 209, 143, 51, 102, 204, 181, 71, 142, 49, 98, 196, 165, 103, 206, 177, 79, 158, 17, 34, 68, 136, 61, 122, 244, 197, 167, 99, 198, 161, 111, 222, 145, 15, 30, 60, 120, 240, 205, 183, 67, 134, 33, 66, 132, 37, 74, 148, 5, 10, 20, 40, 80, 160, 109, 218, 153, 31, 62, 124, 248, 221, 151, 3, 6, 12, 24, 48, 96, 192, 173, 119, 238, 241, 207, 179, 75, 150, 1 }; private static final int poly5[] = { 228, 48, 15, 111, 62 }; private static final int poly7[] = { 23, 68, 144, 134, 240, 92, 254 }; private static final int poly10[] = { 28, 24, 185, 166, 223, 248, 116, 255, 110, 61 }; private static final int poly11[] = { 175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120 }; private static final int poly12[] = { 41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242 }; private static final int poly14[] = { 156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185 }; private static final int poly18[] = { 83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188 }; private static final int poly20[] = { 15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172 }; private static final int poly24[] = { 52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172, 254, 124, 12, 181, 184, 96, 50, 193 }; private static final int poly28[] = { 211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121, 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255 }; private static final int poly36[] = { 245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182, 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25, 225, 98, 81, 112 }; private static final int poly42[] = { 77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8, 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101, 248, 202, 69, 50, 150, 177, 226, 5, 9, 5 }; private static final int poly48[] = { 245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87, 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138, 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19 }; private static final int poly56[] = { 175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235, 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232, 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28, 155, 43, 203, 107, 233, 53, 143, 46 }; private static final int poly62[] = { 242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37, 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71, 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31, 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204 }; private static final int poly68[] = { 220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127, 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236, 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239, 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63, 96, 103, 82, 186 }; private static int[] getPoly(int nc) { switch (nc) { case 5: return poly5; case 7: return poly7; case 10: return poly10; case 11: return poly11; case 12: return poly12; case 14: return poly14; case 18: return poly18; case 20: return poly20; case 24: return poly24; case 28: return poly28; case 36: return poly36; case 42: return poly42; case 48: return poly48; case 56: return poly56; case 62: return poly62; case 68: return poly68; } return null; } private static void reedSolomonBlock(byte[] wd, int nd, byte[] ncout, int nc, int[] c) { int i, j, k; for (i=0; i<=nc; i++) ncout[i] = 0; for (i=0; i *x = 0.8f; *font = BaseFont.createFont("Helvetica", "winansi", false); *size = 8; *baseline = size; *barHeight = size * 3; *guardBars = true; *codeType = EAN13; *code = ""; * * * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodeEAN extends Barcode{ /** The bar positions that are guard bars.*/ private static final int GUARD_EMPTY[] = {}; /** The bar positions that are guard bars.*/ private static final int GUARD_UPCA[] = {0, 2, 4, 6, 28, 30, 52, 54, 56, 58}; /** The bar positions that are guard bars.*/ private static final int GUARD_EAN13[] = {0, 2, 28, 30, 56, 58}; /** The bar positions that are guard bars.*/ private static final int GUARD_EAN8[] = {0, 2, 20, 22, 40, 42}; /** The bar positions that are guard bars.*/ private static final int GUARD_UPCE[] = {0, 2, 28, 30, 32}; /** The x coordinates to place the text.*/ private static final float TEXTPOS_EAN13[] = {6.5f, 13.5f, 20.5f, 27.5f, 34.5f, 41.5f, 53.5f, 60.5f, 67.5f, 74.5f, 81.5f, 88.5f}; /** The x coordinates to place the text.*/ private static final float TEXTPOS_EAN8[] = {6.5f, 13.5f, 20.5f, 27.5f, 39.5f, 46.5f, 53.5f, 60.5f}; /** The basic bar widths.*/ private static final byte BARS[][] = { {3, 2, 1, 1}, // 0 {2, 2, 2, 1}, // 1 {2, 1, 2, 2}, // 2 {1, 4, 1, 1}, // 3 {1, 1, 3, 2}, // 4 {1, 2, 3, 1}, // 5 {1, 1, 1, 4}, // 6 {1, 3, 1, 2}, // 7 {1, 2, 1, 3}, // 8 {3, 1, 1, 2} // 9 }; /** The total number of bars for EAN13.*/ private static final int TOTALBARS_EAN13 = 11 + 12 * 4; /** The total number of bars for EAN8.*/ private static final int TOTALBARS_EAN8 = 11 + 8 * 4; /** The total number of bars for UPCE.*/ private static final int TOTALBARS_UPCE = 9 + 6 * 4; /** The total number of bars for supplemental 2.*/ private static final int TOTALBARS_SUPP2 = 13; /** The total number of bars for supplemental 5.*/ private static final int TOTALBARS_SUPP5 = 31; /** Marker for odd parity.*/ private static final int ODD = 0; /** Marker for even parity.*/ private static final int EVEN = 1; /** Sequence of parities to be used with EAN13.*/ private static final byte PARITY13[][] = { {ODD, ODD, ODD, ODD, ODD, ODD}, // 0 {ODD, ODD, EVEN, ODD, EVEN, EVEN}, // 1 {ODD, ODD, EVEN, EVEN, ODD, EVEN}, // 2 {ODD, ODD, EVEN, EVEN, EVEN, ODD}, // 3 {ODD, EVEN, ODD, ODD, EVEN, EVEN}, // 4 {ODD, EVEN, EVEN, ODD, ODD, EVEN}, // 5 {ODD, EVEN, EVEN, EVEN, ODD, ODD}, // 6 {ODD, EVEN, ODD, EVEN, ODD, EVEN}, // 7 {ODD, EVEN, ODD, EVEN, EVEN, ODD}, // 8 {ODD, EVEN, EVEN, ODD, EVEN, ODD} // 9 }; /** Sequence of parities to be used with supplemental 2.*/ private static final byte PARITY2[][] = { {ODD, ODD}, // 0 {ODD, EVEN}, // 1 {EVEN, ODD}, // 2 {EVEN, EVEN} // 3 }; /** Sequence of parities to be used with supplemental 2.*/ private static final byte PARITY5[][] = { {EVEN, EVEN, ODD, ODD, ODD}, // 0 {EVEN, ODD, EVEN, ODD, ODD}, // 1 {EVEN, ODD, ODD, EVEN, ODD}, // 2 {EVEN, ODD, ODD, ODD, EVEN}, // 3 {ODD, EVEN, EVEN, ODD, ODD}, // 4 {ODD, ODD, EVEN, EVEN, ODD}, // 5 {ODD, ODD, ODD, EVEN, EVEN}, // 6 {ODD, EVEN, ODD, EVEN, ODD}, // 7 {ODD, EVEN, ODD, ODD, EVEN}, // 8 {ODD, ODD, EVEN, ODD, EVEN} // 9 }; /** Sequence of parities to be used with UPCE.*/ private static final byte PARITYE[][] = { {EVEN, EVEN, EVEN, ODD, ODD, ODD}, // 0 {EVEN, EVEN, ODD, EVEN, ODD, ODD}, // 1 {EVEN, EVEN, ODD, ODD, EVEN, ODD}, // 2 {EVEN, EVEN, ODD, ODD, ODD, EVEN}, // 3 {EVEN, ODD, EVEN, EVEN, ODD, ODD}, // 4 {EVEN, ODD, ODD, EVEN, EVEN, ODD}, // 5 {EVEN, ODD, ODD, ODD, EVEN, EVEN}, // 6 {EVEN, ODD, EVEN, ODD, EVEN, ODD}, // 7 {EVEN, ODD, EVEN, ODD, ODD, EVEN}, // 8 {EVEN, ODD, ODD, EVEN, ODD, EVEN} // 9 }; /** Creates new BarcodeEAN */ public BarcodeEAN() { try { x = 0.8f; font = BaseFont.createFont("Helvetica", "winansi", false); size = 8; baseline = size; barHeight = size * 3; guardBars = true; codeType = EAN13; code = ""; } catch (Exception e) { throw new ExceptionConverter(e); } } /** Calculates the EAN parity character. * @param code the code * @return the parity character */ public static int calculateEANParity(String code) { int mul = 3; int total = 0; for (int k = code.length() - 1; k >= 0; --k) { int n = code.charAt(k) - '0'; total += mul * n; mul ^= 2; } return (10 - (total % 10)) % 10; } /** Converts an UPCA code into an UPCE code. If the code can not * be converted a null is returned. * @param text the code to convert. It must have 12 numeric characters * @return the 8 converted digits or null if the * code could not be converted */ static public String convertUPCAtoUPCE(String text) { if (text.length() != 12 || !(text.startsWith("0") || text.startsWith("1"))) return null; if (text.substring(3, 6).equals("000") || text.substring(3, 6).equals("100") || text.substring(3, 6).equals("200")) { if (text.substring(6, 8).equals("00")) return text.substring(0, 1) + text.substring(1, 3) + text.substring(8, 11) + text.substring(3, 4) + text.substring(11); } else if (text.substring(4, 6).equals("00")) { if (text.substring(6, 9).equals("000")) return text.substring(0, 1) + text.substring(1, 4) + text.substring(9, 11) + "3" + text.substring(11); } else if (text.substring(5, 6).equals("0")) { if (text.substring(6, 10).equals("0000")) return text.substring(0, 1) + text.substring(1, 5) + text.substring(10, 11) + "4" + text.substring(11); } else if (text.charAt(10) >= '5') { if (text.substring(6, 10).equals("0000")) return text.substring(0, 1) + text.substring(1, 6) + text.substring(10, 11) + text.substring(11); } return null; } /** Creates the bars for the barcode EAN13 and UPCA. * @param _code the text with 13 digits * @return the barcode */ public static byte[] getBarsEAN13(String _code) { int code[] = new int[_code.length()]; for (int k = 0; k < code.length; ++k) code[k] = _code.charAt(k) - '0'; byte bars[] = new byte[TOTALBARS_EAN13]; int pb = 0; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; byte sequence[] = PARITY13[code[0]]; for (int k = 0; k < sequence.length; ++k) { int c = code[k + 1]; byte stripes[] = BARS[c]; if (sequence[k] == ODD) { bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } else { bars[pb++] = stripes[3]; bars[pb++] = stripes[2]; bars[pb++] = stripes[1]; bars[pb++] = stripes[0]; } } bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; for (int k = 7; k < 13; ++k) { int c = code[k]; byte stripes[] = BARS[c]; bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; return bars; } /** Creates the bars for the barcode EAN8. * @param _code the text with 8 digits * @return the barcode */ public static byte[] getBarsEAN8(String _code) { int code[] = new int[_code.length()]; for (int k = 0; k < code.length; ++k) code[k] = _code.charAt(k) - '0'; byte bars[] = new byte[TOTALBARS_EAN8]; int pb = 0; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; for (int k = 0; k < 4; ++k) { int c = code[k]; byte stripes[] = BARS[c]; bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; for (int k = 4; k < 8; ++k) { int c = code[k]; byte stripes[] = BARS[c]; bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; return bars; } /** Creates the bars for the barcode UPCE. * @param _code the text with 8 digits * @return the barcode */ public static byte[] getBarsUPCE(String _code) { int code[] = new int[_code.length()]; for (int k = 0; k < code.length; ++k) code[k] = _code.charAt(k) - '0'; byte bars[] = new byte[TOTALBARS_UPCE]; boolean flip = (code[0] != 0); int pb = 0; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; byte sequence[] = PARITYE[code[code.length - 1]]; for (int k = 1; k < code.length - 1; ++k) { int c = code[k]; byte stripes[] = BARS[c]; if (sequence[k - 1] == (flip ? EVEN : ODD)) { bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } else { bars[pb++] = stripes[3]; bars[pb++] = stripes[2]; bars[pb++] = stripes[1]; bars[pb++] = stripes[0]; } } bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 1; return bars; } /** Creates the bars for the barcode supplemental 2. * @param _code the text with 2 digits * @return the barcode */ public static byte[] getBarsSupplemental2(String _code) { int code[] = new int[2]; for (int k = 0; k < code.length; ++k) code[k] = _code.charAt(k) - '0'; byte bars[] = new byte[TOTALBARS_SUPP2]; int pb = 0; int parity = (code[0] * 10 + code[1]) % 4; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 2; byte sequence[] = PARITY2[parity]; for (int k = 0; k < sequence.length; ++k) { if (k == 1) { bars[pb++] = 1; bars[pb++] = 1; } int c = code[k]; byte stripes[] = BARS[c]; if (sequence[k] == ODD) { bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } else { bars[pb++] = stripes[3]; bars[pb++] = stripes[2]; bars[pb++] = stripes[1]; bars[pb++] = stripes[0]; } } return bars; } /** Creates the bars for the barcode supplemental 5. * @param _code the text with 5 digits * @return the barcode */ public static byte[] getBarsSupplemental5(String _code) { int code[] = new int[5]; for (int k = 0; k < code.length; ++k) code[k] = _code.charAt(k) - '0'; byte bars[] = new byte[TOTALBARS_SUPP5]; int pb = 0; int parity = (((code[0] + code[2] + code[4]) * 3) + ((code[1] + code[3]) * 9)) % 10; bars[pb++] = 1; bars[pb++] = 1; bars[pb++] = 2; byte sequence[] = PARITY5[parity]; for (int k = 0; k < sequence.length; ++k) { if (k != 0) { bars[pb++] = 1; bars[pb++] = 1; } int c = code[k]; byte stripes[] = BARS[c]; if (sequence[k] == ODD) { bars[pb++] = stripes[0]; bars[pb++] = stripes[1]; bars[pb++] = stripes[2]; bars[pb++] = stripes[3]; } else { bars[pb++] = stripes[3]; bars[pb++] = stripes[2]; bars[pb++] = stripes[1]; bars[pb++] = stripes[0]; } } return bars; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float width = 0; float height = barHeight; if (font != null) { if (baseline <= 0) height += -baseline + size; else height += baseline - font.getFontDescriptor(BaseFont.DESCENT, size); } switch (codeType) { case EAN13: width = x * (11 + 12 * 7); if (font != null) { width += font.getWidthPoint(code.charAt(0), size); } break; case EAN8: width = x * (11 + 8 * 7); break; case UPCA: width = x * (11 + 12 * 7); if (font != null) { width += font.getWidthPoint(code.charAt(0), size) + font.getWidthPoint(code.charAt(11), size); } break; case UPCE: width = x * (9 + 6 * 7); if (font != null) { width += font.getWidthPoint(code.charAt(0), size) + font.getWidthPoint(code.charAt(7), size); } break; case SUPP2: width = x * (6 + 2 * 7); break; case SUPP5: width = x * (4 + 5 * 7 + 4 * 2); break; default: throw new RuntimeException("Invalid code type."); } return new Rectangle(width, height); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { Rectangle rect = getBarcodeSize(); float barStartX = 0; float barStartY = 0; float textStartY = 0; if (font != null) { if (baseline <= 0) textStartY = barHeight - baseline; else { textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); barStartY = textStartY + baseline; } } switch (codeType) { case EAN13: case UPCA: case UPCE: if (font != null) barStartX += font.getWidthPoint(code.charAt(0), size); break; } byte bars[] = null; int guard[] = GUARD_EMPTY; switch (codeType) { case EAN13: bars = getBarsEAN13(code); guard = GUARD_EAN13; break; case EAN8: bars = getBarsEAN8(code); guard = GUARD_EAN8; break; case UPCA: bars = getBarsEAN13("0" + code); guard = GUARD_UPCA; break; case UPCE: bars = getBarsUPCE(code); guard = GUARD_UPCE; break; case SUPP2: bars = getBarsSupplemental2(code); break; case SUPP5: bars = getBarsSupplemental5(code); break; } float keepBarX = barStartX; boolean print = true; float gd = 0; if (font != null && baseline > 0 && guardBars) { gd = baseline / 2; } if (barColor != null) cb.setColorFill(barColor); for (int k = 0; k < bars.length; ++k) { float w = bars[k] * x; if (print) { if (Arrays.binarySearch(guard, k) >= 0) cb.rectangle(barStartX, barStartY - gd, w - inkSpreading, barHeight + gd); else cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); } print = !print; barStartX += w; } cb.fill(); if (font != null) { if (textColor != null) cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(font, size); switch (codeType) { case EAN13: cb.setTextMatrix(0, textStartY); cb.showText(code.substring(0, 1)); for (int k = 1; k < 13; ++k) { String c = code.substring(k, k + 1); float len = font.getWidthPoint(c, size); float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2; cb.setTextMatrix(pX, textStartY); cb.showText(c); } break; case EAN8: for (int k = 0; k < 8; ++k) { String c = code.substring(k, k + 1); float len = font.getWidthPoint(c, size); float pX = TEXTPOS_EAN8[k] * x - len / 2; cb.setTextMatrix(pX, textStartY); cb.showText(c); } break; case UPCA: cb.setTextMatrix(0, textStartY); cb.showText(code.substring(0, 1)); for (int k = 1; k < 11; ++k) { String c = code.substring(k, k + 1); float len = font.getWidthPoint(c, size); float pX = keepBarX + TEXTPOS_EAN13[k] * x - len / 2; cb.setTextMatrix(pX, textStartY); cb.showText(c); } cb.setTextMatrix(keepBarX + x * (11 + 12 * 7), textStartY); cb.showText(code.substring(11, 12)); break; case UPCE: cb.setTextMatrix(0, textStartY); cb.showText(code.substring(0, 1)); for (int k = 1; k < 7; ++k) { String c = code.substring(k, k + 1); float len = font.getWidthPoint(c, size); float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2; cb.setTextMatrix(pX, textStartY); cb.showText(c); } cb.setTextMatrix(keepBarX + x * (9 + 6 * 7), textStartY); cb.showText(code.substring(7, 8)); break; case SUPP2: case SUPP5: for (int k = 0; k < code.length(); ++k) { String c = code.substring(k, k + 1); float len = font.getWidthPoint(c, size); float pX = (7.5f + (9 * k)) * x - len / 2; cb.setTextMatrix(pX, textStartY); cb.showText(c); } break; } cb.endText(); } return rect; } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); int width = 0; byte bars[] = null; switch (codeType) { case EAN13: bars = getBarsEAN13(code); width = 11 + 12 * 7; break; case EAN8: bars = getBarsEAN8(code); width = 11 + 8 * 7; break; case UPCA: bars = getBarsEAN13("0" + code); width = 11 + 12 * 7; break; case UPCE: bars = getBarsUPCE(code); width = 9 + 6 * 7; break; case SUPP2: bars = getBarsSupplemental2(code); width = 6 + 2 * 7; break; case SUPP5: bars = getBarsSupplemental5(code); width = 4 + 5 * 7 + 4 * 2; break; default: throw new RuntimeException("Invalid code type."); } boolean print = true; int ptr = 0; int height = (int)barHeight; int pix[] = new int[width * height]; for (int k = 0; k < bars.length; ++k) { int w = bars[k]; int c = g; if (print) c = f; print = !print; for (int j = 0; j < w; ++j) pix[ptr++] = c; } for (int k = width; k < pix.length; k += width) { System.arraycopy(pix, 0, pix, k, width); } Image img = canvas.createImage(new MemoryImageSource(width, height, pix, 0, width)); return img; } } src/core/com/lowagie/text/pdf/BarcodeEANSUPP.java100644 0 0 14612 11000354131 17134 0ustar 0 0 /* * Copyright 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import com.lowagie.text.Rectangle; /** This class takes 2 barcodes, an EAN/UPC and a supplemental * and creates a single barcode with both combined in the * expected layout. The UPC/EAN should have a positive text * baseline and the supplemental a negative one (in the supplemental * the text is on the top of the barcode.

* The default parameters are: *

 *n = 8; // horizontal distance between the two barcodes
 * 
* * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodeEANSUPP extends Barcode{ /** The barcode with the EAN/UPC. */ protected Barcode ean; /** The barcode with the supplemental. */ protected Barcode supp; /** Creates new combined barcode. * @param ean the EAN/UPC barcode * @param supp the supplemental barcode */ public BarcodeEANSUPP(Barcode ean, Barcode supp) { n = 8; // horizontal distance between the two barcodes this.ean = ean; this.supp = supp; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { Rectangle rect = ean.getBarcodeSize(); rect.setRight(rect.getWidth() + supp.getBarcodeSize().getWidth() + n); return rect; } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { if (supp.getFont() != null) supp.setBarHeight(ean.getBarHeight() + supp.getBaseline() - supp.getFont().getFontDescriptor(BaseFont.CAPHEIGHT, supp.getSize())); else supp.setBarHeight(ean.getBarHeight()); Rectangle eanR = ean.getBarcodeSize(); cb.saveState(); ean.placeBarcode(cb, barColor, textColor); cb.restoreState(); cb.saveState(); cb.concatCTM(1, 0, 0, 1, eanR.getWidth() + n, eanR.getHeight() - ean.getBarHeight()); supp.placeBarcode(cb, barColor, textColor); cb.restoreState(); return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { throw new UnsupportedOperationException("The two barcodes must be composed externally."); } } src/core/com/lowagie/text/pdf/BarcodeInter25.java100644 0 0 30024 11000354131 17244 0ustar 0 0 /* * $Id: BarcodeInter25.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2002-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.Image; import java.awt.image.MemoryImageSource; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** Implements the code interleaved 2 of 5. The text can include * non numeric characters that are printed but do not generate bars. * The default parameters are: *

 *x = 0.8f;
 *n = 2;
 *font = BaseFont.createFont("Helvetica", "winansi", false);
 *size = 8;
 *baseline = size;
 *barHeight = size * 3;
 *textAlignment = Element.ALIGN_CENTER;
 *generateChecksum = false;
 *checksumText = false;
 * 
* * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodeInter25 extends Barcode{ /** The bars to generate the code. */ private static final byte BARS[][] = { {0,0,1,1,0}, {1,0,0,0,1}, {0,1,0,0,1}, {1,1,0,0,0}, {0,0,1,0,1}, {1,0,1,0,0}, {0,1,1,0,0}, {0,0,0,1,1}, {1,0,0,1,0}, {0,1,0,1,0} }; /** Creates new BarcodeInter25 */ public BarcodeInter25() { try { x = 0.8f; n = 2; font = BaseFont.createFont("Helvetica", "winansi", false); size = 8; baseline = size; barHeight = size * 3; textAlignment = Element.ALIGN_CENTER; generateChecksum = false; checksumText = false; } catch (Exception e) { throw new ExceptionConverter(e); } } /** Deletes all the non numeric characters from text. * @param text the text * @return a String with only numeric characters */ public static String keepNumbers(String text) { StringBuffer sb = new StringBuffer(); for (int k = 0; k < text.length(); ++k) { char c = text.charAt(k); if (c >= '0' && c <= '9') sb.append(c); } return sb.toString(); } /** Calculates the checksum. * @param text the numeric text * @return the checksum */ public static char getChecksum(String text) { int mul = 3; int total = 0; for (int k = text.length() - 1; k >= 0; --k) { int n = text.charAt(k) - '0'; total += mul * n; mul ^= 2; } return (char)(((10 - (total % 10)) % 10) + '0'); } /** Creates the bars for the barcode. * @param text the text. It can contain non numeric characters * @return the barcode */ public static byte[] getBarsInter25(String text) { text = keepNumbers(text); if ((text.length() & 1) != 0) throw new IllegalArgumentException("The text length must be even."); byte bars[] = new byte[text.length() * 5 + 7]; int pb = 0; bars[pb++] = 0; bars[pb++] = 0; bars[pb++] = 0; bars[pb++] = 0; int len = text.length() / 2; for (int k = 0; k < len; ++k) { int c1 = text.charAt(k * 2) - '0'; int c2 = text.charAt(k * 2 + 1) - '0'; byte b1[] = BARS[c1]; byte b2[] = BARS[c2]; for (int j = 0; j < 5; ++j) { bars[pb++] = b1[j]; bars[pb++] = b2[j]; } } bars[pb++] = 1; bars[pb++] = 0; bars[pb++] = 0; return bars; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float fontX = 0; float fontY = 0; if (font != null) { if (baseline > 0) fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); else fontY = -baseline + size; String fullCode = code; if (generateChecksum && checksumText) fullCode += getChecksum(fullCode); fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); } String fullCode = keepNumbers(code); int len = fullCode.length(); if (generateChecksum) ++len; float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x; fullWidth = Math.max(fullWidth, fontX); float fullHeight = barHeight + fontY; return new Rectangle(fullWidth, fullHeight); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { String fullCode = code; float fontX = 0; if (font != null) { if (generateChecksum && checksumText) fullCode += getChecksum(fullCode); fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); } String bCode = keepNumbers(code); if (generateChecksum) bCode += getChecksum(bCode); int len = bCode.length(); float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x; float barStartX = 0; float textStartX = 0; switch (textAlignment) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: if (fontX > fullWidth) barStartX = fontX - fullWidth; else textStartX = fullWidth - fontX; break; default: if (fontX > fullWidth) barStartX = (fontX - fullWidth) / 2; else textStartX = (fullWidth - fontX) / 2; break; } float barStartY = 0; float textStartY = 0; if (font != null) { if (baseline <= 0) textStartY = barHeight - baseline; else { textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); barStartY = textStartY + baseline; } } byte bars[] = getBarsInter25(bCode); boolean print = true; if (barColor != null) cb.setColorFill(barColor); for (int k = 0; k < bars.length; ++k) { float w = (bars[k] == 0 ? x : x * n); if (print) cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); print = !print; barStartX += w; } cb.fill(); if (font != null) { if (textColor != null) cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(font, size); cb.setTextMatrix(textStartX, textStartY); cb.showText(fullCode); cb.endText(); } return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); String bCode = keepNumbers(code); if (generateChecksum) bCode += getChecksum(bCode); int len = bCode.length(); int nn = (int)n; int fullWidth = len * (3 + 2 * nn) + (6 + nn ); byte bars[] = getBarsInter25(bCode); boolean print = true; int ptr = 0; int height = (int)barHeight; int pix[] = new int[fullWidth * height]; for (int k = 0; k < bars.length; ++k) { int w = (bars[k] == 0 ? 1 : nn); int c = g; if (print) c = f; print = !print; for (int j = 0; j < w; ++j) pix[ptr++] = c; } for (int k = fullWidth; k < pix.length; k += fullWidth) { System.arraycopy(pix, 0, pix, k, fullWidth); } Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); return img; } }src/core/com/lowagie/text/pdf/BarcodePDF417.java100644 0 0 221515 11036112746 16725 0ustar 0 0 /* * * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.image.MemoryImageSource; import java.util.ArrayList; import com.lowagie.text.BadElementException; import com.lowagie.text.Image; import com.lowagie.text.pdf.codec.CCITTG4Encoder; /** Generates the 2D barcode PDF417. Supports dimensioning auto-sizing, fixed * and variable sizes, automatic and manual error levels, raw codeword input, * codeword size optimization and bitmap inversion. The output can * be a CCITT G4 Image or a raw bitmap. * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodePDF417 { /** Auto-size is made based on aspectRatio and yHeight. */ public static final int PDF417_USE_ASPECT_RATIO = 0; /** The size of the barcode will be at least codeColumns*codeRows. */ public static final int PDF417_FIXED_RECTANGLE = 1; /** The size will be at least codeColumns * with a variable number of codeRows. */ public static final int PDF417_FIXED_COLUMNS = 2; /** The size will be at least codeRows * with a variable number of codeColumns. */ public static final int PDF417_FIXED_ROWS = 4; /** The error level correction is set automatically according * to ISO 15438 recommendations. */ public static final int PDF417_AUTO_ERROR_LEVEL = 0; /** The error level correction is set by the user. It can be 0 to 8. */ public static final int PDF417_USE_ERROR_LEVEL = 16; /** * One single binary segment is used */ public static final int PDF417_FORCE_BINARY = 32; /** No text interpretation is done and the content of codewords * is used directly. */ public static final int PDF417_USE_RAW_CODEWORDS = 64; /** Inverts the output bits of the raw bitmap that is normally * bit one for black. It has only effect for the raw bitmap. */ public static final int PDF417_INVERT_BITMAP = 128; /** Use Macro PDF417 Encoding * @see #setMacroFileId(String) * @see #setMacroSegmentId(int) * @see #setMacroSegmentCount(int) */ public static final int PDF417_USE_MACRO = 256; private int macroSegmentCount=0; private int macroSegmentId=-1; private String macroFileId; private int macroIndex; protected int bitPtr; protected int cwPtr; protected SegmentList segmentList; /** Creates a new BarcodePDF417 with the default settings. */ public BarcodePDF417() { setDefaultParameters(); } /** * Sets the segment id for macro PDF417 encoding * @param id the id (starting at 0) * @see #setMacroSegmentCount(int) */ public void setMacroSegmentId(int id) { this.macroSegmentId = id; } /** * Sets the segment count for macro PDF417 encoding * @param cnt the number of macro segments * @see #setMacroSegmentId(int) */ public void setMacroSegmentCount(int cnt) { this.macroSegmentCount = cnt; } /** * Sets the File ID for macro PDF417 encoding * @param id the file id */ public void setMacroFileId(String id) { this.macroFileId = id; } protected boolean checkSegmentType(Segment segment, char type) { if (segment == null) return false; return segment.type == type; } protected int getSegmentLength(Segment segment) { if (segment == null) return 0; return segment.end - segment.start; } /** Set the default settings that correspond to PDF417_USE_ASPECT_RATIO * and PDF417_AUTO_ERROR_LEVEL. */ public void setDefaultParameters() { options = 0; outBits = null; text = new byte[0]; yHeight = 3; aspectRatio = 0.5f; } protected void outCodeword17(int codeword) { int bytePtr = bitPtr / 8; int bit = bitPtr - bytePtr * 8; outBits[bytePtr++] |= codeword >> (9 + bit); outBits[bytePtr++] |= codeword >> (1 + bit); codeword <<= 8; outBits[bytePtr] |= codeword >> (1 + bit); bitPtr += 17; } protected void outCodeword18(int codeword) { int bytePtr = bitPtr / 8; int bit = bitPtr - bytePtr * 8; outBits[bytePtr++] |= codeword >> (10 + bit); outBits[bytePtr++] |= codeword >> (2 + bit); codeword <<= 8; outBits[bytePtr] |= codeword >> (2 + bit); if (bit == 7) outBits[++bytePtr] |= 0x80; bitPtr += 18; } protected void outCodeword(int codeword) { outCodeword17(codeword); } protected void outStopPattern() { outCodeword18(STOP_PATTERN); } protected void outStartPattern() { outCodeword17(START_PATTERN); } protected void outPaintCode() { int codePtr = 0; bitColumns = START_CODE_SIZE * (codeColumns + 3) + STOP_SIZE; int lenBits = ((bitColumns - 1) / 8 + 1) * codeRows; outBits = new byte[lenBits]; for (int row = 0; row < codeRows; ++row) { bitPtr = ((bitColumns - 1) / 8 + 1) * 8 * row; int rowMod = row % 3; int cluster[] = CLUSTERS[rowMod]; outStartPattern(); int edge = 0; switch (rowMod) { case 0: edge = 30 * (row / 3) + ((codeRows - 1) / 3); break; case 1: edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); break; default: edge = 30 * (row / 3) + codeColumns - 1; break; } outCodeword(cluster[edge]); for (int column = 0; column < codeColumns; ++column) { outCodeword(cluster[codewords[codePtr++]]); } switch (rowMod) { case 0: edge = 30 * (row / 3) + codeColumns - 1; break; case 1: edge = 30 * (row / 3) + ((codeRows - 1) / 3); break; default: edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); break; } outCodeword(cluster[edge]); outStopPattern(); } if ((options & PDF417_INVERT_BITMAP) != 0) { for (int k = 0; k < outBits.length; ++k) outBits[k] ^= 0xff; } } protected void calculateErrorCorrection(int dest) { if (errorLevel < 0 || errorLevel > 8) errorLevel = 0; int A[] = ERROR_LEVEL[errorLevel]; int Alength = 2 << errorLevel; for (int k = 0; k < Alength; ++k) codewords[dest + k] = 0; int lastE = Alength - 1; for (int k = 0; k < lenCodewords; ++k) { int t1 = codewords[k] + codewords[dest]; for (int e = 0; e <= lastE; ++e) { int t2 = (t1 * A[lastE - e]) % MOD; int t3 = MOD - t2; codewords[dest + e] = ((e == lastE ? 0 : codewords[dest + e + 1]) + t3) % MOD; } } for (int k = 0; k < Alength; ++k) codewords[dest + k] = (MOD - codewords[dest + k]) % MOD; } private static int getTextTypeAndValue(byte[] input, int maxLength, int idx) { if (idx >= maxLength) return 0; char c = (char)(input[idx] & 0xff); if (c >= 'A' && c <= 'Z') return (ALPHA + c - 'A'); if (c >= 'a' && c <= 'z') return (LOWER + c - 'a'); if (c == ' ') return (ALPHA + LOWER + MIXED + SPACE); int ms = MIXED_SET.indexOf(c); int ps = PUNCTUATION_SET.indexOf(c); if (ms < 0 && ps < 0) return (ISBYTE + c); if (ms == ps) return (MIXED + PUNCTUATION + ms); if (ms >= 0) return (MIXED + ms); return (PUNCTUATION + ps); } protected int getTextTypeAndValue(int maxLength, int idx) { return getTextTypeAndValue(text, maxLength,idx); } private void textCompaction(byte[] input, int start, int length) { int dest[] = new int[ABSOLUTE_MAX_TEXT_SIZE * 2]; int mode = ALPHA; int ptr = 0; int fullBytes = 0; int v = 0; int k; int size; length += start; for (k = start; k < length; ++k) { v = getTextTypeAndValue(input, length, k); if ((v & mode) != 0) { dest[ptr++] = v & 0xff; continue; } if ((v & ISBYTE) != 0) { if ((ptr & 1) != 0) { //add a padding word dest[ptr++] = PAL; mode = (mode & PUNCTUATION) != 0 ? ALPHA : mode; } dest[ptr++] = BYTESHIFT; dest[ptr++] = v & 0xff; fullBytes += 2; continue; } switch (mode) { case ALPHA: if ((v & LOWER) != 0) { dest[ptr++] = LL; dest[ptr++] = v & 0xff; mode = LOWER; } else if ((v & MIXED) != 0) { dest[ptr++] = ML; dest[ptr++] = v & 0xff; mode = MIXED; } else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = ML; dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case LOWER: if ((v & ALPHA) != 0) { if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & ALPHA) != 0) { dest[ptr++] = ML; dest[ptr++] = AL; mode = ALPHA; } else { dest[ptr++] = AS; } dest[ptr++] = v & 0xff; } else if ((v & MIXED) != 0) { dest[ptr++] = ML; dest[ptr++] = v & 0xff; mode = MIXED; } else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = ML; dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case MIXED: if ((v & LOWER) != 0) { dest[ptr++] = LL; dest[ptr++] = v & 0xff; mode = LOWER; } else if ((v & ALPHA) != 0) { dest[ptr++] = AL; dest[ptr++] = v & 0xff; mode = ALPHA; } else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { dest[ptr++] = PL; dest[ptr++] = v & 0xff; mode = PUNCTUATION; } else { dest[ptr++] = PS; dest[ptr++] = v & 0xff; } break; case PUNCTUATION: dest[ptr++] = PAL; mode = ALPHA; --k; break; } } if ((ptr & 1) != 0) dest[ptr++] = PS; size = (ptr + fullBytes) / 2; if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length = ptr; ptr = 0; while (ptr < length) { v = dest[ptr++]; if (v >= 30) { codewords[cwPtr++] = v; codewords[cwPtr++] = dest[ptr++]; } else codewords[cwPtr++] = v * 30 + dest[ptr++]; } } protected void textCompaction(int start, int length) { textCompaction(text, start, length); } protected void basicNumberCompaction(int start, int length) { basicNumberCompaction(text, start, length); } private void basicNumberCompaction(byte[] input, int start, int length) { int ret = cwPtr; int retLast = length / 3; int ni, k; cwPtr += retLast + 1; for (k = 0; k <= retLast; ++k) codewords[ret + k] = 0; codewords[ret + retLast] = 1; length += start; for (ni = start; ni < length; ++ni) { // multiply by 10 for (k = retLast; k >= 0; --k) codewords[ret + k] *= 10; // add the digit codewords[ret + retLast] += input[ni] - '0'; // propagate carry for (k = retLast; k > 0; --k) { codewords[ret + k - 1] += codewords[ret + k] / 900; codewords[ret + k] %= 900; } } } private void numberCompaction(byte[] input, int start, int length) { int full = (length / 44) * 15; int size = length % 44; int k; if (size == 0) size = full; else size = full + size / 3 + 1; if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length += start; for (k = start; k < length; k += 44) { size = length - k < 44 ? length - k : 44; basicNumberCompaction(input, k, size); } } protected void numberCompaction(int start, int length) { numberCompaction(text, start, length); } protected void byteCompaction6(int start) { int length = 6; int ret = cwPtr; int retLast = 4; int ni, k; cwPtr += retLast + 1; for (k = 0; k <= retLast ; ++k) codewords[ret + k] = 0; length += start; for (ni = start; ni < length; ++ni) { // multiply by 256 for (k = retLast; k >= 0; --k) codewords[ret + k] *= 256; // add the digit codewords[ret + retLast] += text[ni] & 0xff; // propagate carry for (k = retLast; k > 0; --k) { codewords[ret + k - 1] += codewords[ret + k] / 900; codewords[ret + k] %= 900; } } } void byteCompaction(int start, int length) { int k, j; int size = (length / 6) * 5 + (length % 6); if (size + cwPtr > MAX_DATA_CODEWORDS) { throw new IndexOutOfBoundsException("The text is too big."); } length += start; for (k = start; k < length; k += 6) { size = length - k < 44 ? length - k : 6; if (size < 6) { for (j = 0; j < size; ++j) codewords[cwPtr++] = text[k + j] & 0xff; } else { byteCompaction6(k); } } } void breakString() { int textLength = text.length; int lastP = 0; int startN = 0; int nd = 0; char c = 0; int k, j; boolean lastTxt, txt; Segment v; Segment vp; Segment vn; if ((options & PDF417_FORCE_BINARY) != 0) { segmentList.add('B', 0, textLength); return; } for (k = 0; k < textLength; ++k) { c = (char)(text[k] & 0xff); if (c >= '0' && c <= '9') { if (nd == 0) startN = k; ++nd; continue; } if (nd >= 13) { if (lastP != startN) { c = (char)(text[lastP] & 0xff); lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; for (j = lastP; j < startN; ++j) { c = (char)(text[j] & 0xff); txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; if (txt != lastTxt) { segmentList.add(lastTxt ? 'T' : 'B', lastP, j); lastP = j; lastTxt = txt; } } segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); } segmentList.add('N', startN, k); lastP = k; } nd = 0; } if (nd < 13) startN = textLength; if (lastP != startN) { c = (char)(text[lastP] & 0xff); lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; for (j = lastP; j < startN; ++j) { c = (char)(text[j] & 0xff); txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; if (txt != lastTxt) { segmentList.add(lastTxt ? 'T' : 'B', lastP, j); lastP = j; lastTxt = txt; } } segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); } if (nd >= 13) segmentList.add('N', startN, textLength); //optimize //merge short binary for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1); if (checkSegmentType(v, 'B') && getSegmentLength(v) == 1) { if (checkSegmentType(vp, 'T') && checkSegmentType(vn, 'T') && getSegmentLength(vp) + getSegmentLength(vn) >= 3) { vp.end = vn.end; segmentList.remove(k); segmentList.remove(k); k = -1; continue; } } } //merge text sections for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1); if (checkSegmentType(v, 'T') && getSegmentLength(v) >= 5) { boolean redo = false; if ((checkSegmentType(vp, 'B') && getSegmentLength(vp) == 1) || checkSegmentType(vp, 'T')) { redo = true; v.start = vp.start; segmentList.remove(k - 1); --k; } if ((checkSegmentType(vn, 'B') && getSegmentLength(vn) == 1) || checkSegmentType(vn, 'T')) { redo = true; v.end = vn.end; segmentList.remove(k + 1); } if (redo) { k = -1; continue; } } } //merge binary sections for (k = 0; k < segmentList.size(); ++k) { v = segmentList.get(k); vp = segmentList.get(k - 1); vn = segmentList.get(k + 1); if (checkSegmentType(v, 'B')) { boolean redo = false; if ((checkSegmentType(vp, 'T') && getSegmentLength(vp) < 5) || checkSegmentType(vp, 'B')) { redo = true; v.start = vp.start; segmentList.remove(k - 1); --k; } if ((checkSegmentType(vn, 'T') && getSegmentLength(vn) < 5) || checkSegmentType(vn, 'B')) { redo = true; v.end = vn.end; segmentList.remove(k + 1); } if (redo) { k = -1; continue; } } } // check if all numbers if (segmentList.size() == 1 && (v = segmentList.get(0)).type == 'T' && getSegmentLength(v) >= 8) { for (k = v.start; k < v.end; ++k) { c = (char)(text[k] & 0xff); if (c < '0' || c > '9') break; } if (k == v.end) v.type = 'N'; } } protected void assemble() { int k; if (segmentList.size() == 0) return; cwPtr = 1; for (k = 0; k < segmentList.size(); ++k) { Segment v = segmentList.get(k); switch (v.type) { case 'T': if (k != 0) codewords[cwPtr++] = TEXT_MODE; textCompaction(v.start, getSegmentLength(v)); break; case 'N': codewords[cwPtr++] = NUMERIC_MODE; numberCompaction(v.start, getSegmentLength(v)); break; case 'B': codewords[cwPtr++] = (getSegmentLength(v) % 6) != 0 ? BYTE_MODE : BYTE_MODE_6; byteCompaction(v.start, getSegmentLength(v)); break; } } if ((options & PDF417_USE_MACRO) != 0) { macroCodes(); } } private void macroCodes() { if (macroSegmentId < 0) { throw new IllegalStateException("macroSegmentId must be >=0"); } if (macroSegmentId >= macroSegmentCount) { throw new IllegalStateException("macroSegmentId must be < macroSemgentCount"); } if (macroSegmentCount < 1) { throw new IllegalStateException("macroSemgentCount must be > 0"); } macroIndex = cwPtr; codewords[cwPtr++] = MACRO_SEGMENT_ID; append(macroSegmentId, 5); if (macroFileId != null) { append(macroFileId); } if (macroSegmentId >= macroSegmentCount-1) { codewords[cwPtr++] = MACRO_LAST_SEGMENT; } } private void append(int in, int len) { StringBuffer sb = new StringBuffer(len+1); sb.append(Integer.toString(in)); for(int i = sb.length(); i < len; i++) { sb.insert(0, "0"); } byte[] bytes = PdfEncodings.convertToBytes(sb.toString(), "cp437"); numberCompaction(bytes, 0, bytes.length); } private void append(String s) { byte[] bytes = PdfEncodings.convertToBytes(s, "cp437"); textCompaction(bytes, 0, bytes.length); } protected static int maxPossibleErrorLevel(int remain) { int level = 8; int size = 512; while (level > 0) { if (remain >= size) return level; --level; size >>= 1; } return 0; } protected void dumpList() { if (segmentList.size() == 0) return; for (int k = 0; k < segmentList.size(); ++k) { Segment v = segmentList.get(k); int len = getSegmentLength(v); char c[] = new char[len]; for (int j = 0; j < len; ++j) { c[j] = (char)(text[v.start + j] & 0xff); if (c[j] == '\r') c[j] = '\n'; } StringBuffer sb = new StringBuffer(); sb.append(v.type); sb.append(c); System.out.println(sb.toString()); } } protected int getMaxSquare() { if (codeColumns > 21) { codeColumns = 29; codeRows = 32; } else { codeColumns = 16; codeRows = 58; } return MAX_DATA_CODEWORDS + 2; } /** Paints the barcode. If no exception was thrown a valid barcode is available. */ public void paintCode() { int maxErr, lenErr, tot, pad; if ((options & PDF417_USE_RAW_CODEWORDS) != 0) { if (lenCodewords > MAX_DATA_CODEWORDS || lenCodewords < 1 || lenCodewords != codewords[0]) { throw new IllegalArgumentException("Invalid codeword size."); } } else { if (text == null) throw new NullPointerException("Text cannot be null."); if (text.length > ABSOLUTE_MAX_TEXT_SIZE) { throw new IndexOutOfBoundsException("The text is too big."); } segmentList = new SegmentList(); breakString(); //dumpList(); assemble(); segmentList = null; codewords[0] = lenCodewords = cwPtr; } maxErr = maxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - lenCodewords); if ((options & PDF417_USE_ERROR_LEVEL) == 0) { if (lenCodewords < 41) errorLevel = 2; else if (lenCodewords < 161) errorLevel = 3; else if (lenCodewords < 321) errorLevel = 4; else errorLevel = 5; } if (errorLevel < 0) errorLevel = 0; else if (errorLevel > maxErr) errorLevel = maxErr; if (codeColumns < 1) codeColumns = 1; else if (codeColumns > 30) codeColumns = 30; if (codeRows < 3) codeRows = 3; else if (codeRows > 90) codeRows = 90; lenErr = 2 << errorLevel; boolean fixedColumn = (options & PDF417_FIXED_ROWS) == 0; boolean skipRowColAdjust = false; tot = lenCodewords + lenErr; if ((options & PDF417_FIXED_RECTANGLE) != 0) { tot = codeColumns * codeRows; if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(); } if (tot < lenCodewords + lenErr) tot = lenCodewords + lenErr; else skipRowColAdjust = true; } else if ((options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS)) == 0) { double c, b; fixedColumn = true; if (aspectRatio < 0.001) aspectRatio = 0.001f; else if (aspectRatio > 1000) aspectRatio = 1000; b = 73 * aspectRatio - 4; c = (-b + Math.sqrt(b * b + 4 * 17 * aspectRatio * (lenCodewords + lenErr) * yHeight)) / (2 * 17 * aspectRatio); codeColumns = (int)(c + 0.5); if (codeColumns < 1) codeColumns = 1; else if (codeColumns > 30) codeColumns = 30; } if (!skipRowColAdjust) { if (fixedColumn) { codeRows = (tot - 1) / codeColumns + 1; if (codeRows < 3) codeRows = 3; else if (codeRows > 90) { codeRows = 90; codeColumns = (tot - 1) / 90 + 1; } } else { codeColumns = (tot - 1) / codeRows + 1; if (codeColumns > 30) { codeColumns = 30; codeRows = (tot - 1) / 30 + 1; } } tot = codeRows * codeColumns; } if (tot > MAX_DATA_CODEWORDS + 2) { tot = getMaxSquare(); } errorLevel = maxPossibleErrorLevel(tot - lenCodewords); lenErr = 2 << errorLevel; pad = tot - lenErr - lenCodewords; if ((options & PDF417_USE_MACRO) != 0) { // the padding comes before the control block System.arraycopy(codewords, macroIndex, codewords, macroIndex + pad, pad); cwPtr = lenCodewords + pad; while (pad-- != 0) codewords[macroIndex++] = TEXT_MODE; } else { cwPtr = lenCodewords; while (pad-- != 0) codewords[cwPtr++] = TEXT_MODE; } codewords[0] = lenCodewords = cwPtr; calculateErrorCorrection(lenCodewords); lenCodewords = tot; outPaintCode(); } /** Gets an Image with the barcode. The image will have to be * scaled in the Y direction by yHeightfor the barcode * to have the right printing aspect. * @return the barcode Image * @throws BadElementException on error */ public Image getImage() throws BadElementException { paintCode(); byte g4[] = CCITTG4Encoder.compress(outBits, bitColumns, codeRows); return Image.getInstance(bitColumns, codeRows, false, Image.CCITTG4, (options & PDF417_INVERT_BITMAP) == 0 ? 0 : Image.CCITT_BLACKIS1, g4, null); } /** Creates a java.awt.Image. * @param foreground the color of the bars * @param background the color of the background * @return the image */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); paintCode(); int h = (int)yHeight; int pix[] = new int[bitColumns * codeRows * h]; int stride = (bitColumns + 7) / 8; int ptr = 0; for (int k = 0; k < codeRows; ++k) { int p = k * stride; for (int j = 0; j < bitColumns; ++j) { int b = outBits[p + (j / 8)] & 0xff; b <<= j % 8; pix[ptr++] = (b & 0x80) == 0 ? g : f; } for (int j = 1; j < h; ++j) { System.arraycopy(pix, ptr - bitColumns, pix, ptr + bitColumns * (j - 1), bitColumns); } ptr += bitColumns * (h - 1); } java.awt.Image img = canvas.createImage(new MemoryImageSource(bitColumns, codeRows * h, pix, 0, bitColumns)); return img; } /** Gets the raw image bits of the barcode. The image will have to * be scaled in the Y direction by yHeight. * @return The raw barcode image */ public byte[] getOutBits() { return this.outBits; } /** Gets the number of X pixels of outBits. * @return the number of X pixels of outBits */ public int getBitColumns() { return this.bitColumns; } /** Gets the number of Y pixels of outBits. * It is also the number of rows in the barcode. * @return the number of Y pixels of outBits */ public int getCodeRows() { return this.codeRows; } /** Sets the number of barcode rows. This number may be changed * to keep the barcode valid. * @param codeRows the number of barcode rows */ public void setCodeRows(int codeRows) { this.codeRows = codeRows; } /** Gets the number of barcode data columns. * @return he number of barcode data columns */ public int getCodeColumns() { return this.codeColumns; } /** Sets the number of barcode data columns. * This number may be changed to keep the barcode valid. * @param codeColumns the number of barcode data columns */ public void setCodeColumns(int codeColumns) { this.codeColumns = codeColumns; } /** Gets the codeword array. This array is always 928 elements long. * It can be written to if the option PDF417_USE_RAW_CODEWORDS * is set. * @return the codeword array */ public int[] getCodewords() { return this.codewords; } /** Gets the length of the codewords. * @return the length of the codewords */ public int getLenCodewords() { return this.lenCodewords; } /** Sets the length of the codewords. * @param lenCodewords the length of the codewords */ public void setLenCodewords(int lenCodewords) { this.lenCodewords = lenCodewords; } /** Gets the error level correction used for the barcode. It may different * from the previously set value. * @return the error level correction used for the barcode */ public int getErrorLevel() { return this.errorLevel; } /** Sets the error level correction for the barcode. * @param errorLevel the error level correction for the barcode */ public void setErrorLevel(int errorLevel) { this.errorLevel = errorLevel; } /** Gets the bytes that form the barcode. This bytes should * be interpreted in the codepage Cp437. * @return the bytes that form the barcode */ public byte[] getText() { return this.text; } /** Sets the bytes that form the barcode. This bytes should * be interpreted in the codepage Cp437. * @param text the bytes that form the barcode */ public void setText(byte[] text) { this.text = text; } /** Sets the text that will form the barcode. This text is converted * to bytes using the encoding Cp437. * @param s the text that will form the barcode */ public void setText(String s) { this.text = PdfEncodings.convertToBytes(s, "cp437"); } /** Gets the options to generate the barcode. * @return the options to generate the barcode */ public int getOptions() { return this.options; } /** Sets the options to generate the barcode. This can be all * the PDF417_* constants. * @param options the options to generate the barcode */ public void setOptions(int options) { this.options = options; } /** Gets the barcode aspect ratio. * @return the barcode aspect ratio */ public float getAspectRatio() { return this.aspectRatio; } /** Sets the barcode aspect ratio. A ratio or 0.5 will make the * barcode width twice as large as the height. * @param aspectRatio the barcode aspect ratio */ public void setAspectRatio(float aspectRatio) { this.aspectRatio = aspectRatio; } /** Gets the Y pixel height relative to X. * @return the Y pixel height relative to X */ public float getYHeight() { return this.yHeight; } /** Sets the Y pixel height relative to X. It is usually 3. * @param yHeight the Y pixel height relative to X */ public void setYHeight(float yHeight) { this.yHeight = yHeight; } protected static final int START_PATTERN = 0x1fea8; protected static final int STOP_PATTERN = 0x3fa29; protected static final int START_CODE_SIZE = 17; protected static final int STOP_SIZE = 18; protected static final int MOD = 929; protected static final int ALPHA = 0x10000; protected static final int LOWER = 0x20000; protected static final int MIXED = 0x40000; protected static final int PUNCTUATION = 0x80000; protected static final int ISBYTE = 0x100000; protected static final int BYTESHIFT = 913; protected static final int PL = 25; protected static final int LL = 27; protected static final int AS = 27; protected static final int ML = 28; protected static final int AL = 28; protected static final int PS = 29; protected static final int PAL = 29; protected static final int SPACE = 26; protected static final int TEXT_MODE = 900; protected static final int BYTE_MODE_6 = 924; protected static final int BYTE_MODE = 901; protected static final int NUMERIC_MODE = 902; protected static final int ABSOLUTE_MAX_TEXT_SIZE = 5420; protected static final int MAX_DATA_CODEWORDS = 926; protected static final int MACRO_SEGMENT_ID=928; protected static final int MACRO_LAST_SEGMENT=922; private static final String MIXED_SET = "0123456789&\r\t,:#-.$/+%*=^"; private static final String PUNCTUATION_SET = ";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'"; private static final int CLUSTERS[][] = {{ 0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e, 0x1a8c0, 0x1d470, 0x1a860, 0x15040, 0x1a830, 0x15020, 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, 0x1d678, 0x1eb3e, 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c, 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0, 0x1af7c, 0x15e78, 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0, 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, 0x1e93c, 0x1a460, 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418, 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670, 0x1d33c, 0x14c60, 0x1a638, 0x1d31e, 0x14c30, 0x1a61c, 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, 0x1a73c, 0x14e38, 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0, 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440, 0x1a230, 0x1d11c, 0x14420, 0x1a218, 0x14410, 0x14408, 0x146c0, 0x1a370, 0x1d1bc, 0x14660, 0x1a338, 0x1d19e, 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc, 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8, 0x1e85e, 0x14240, 0x1a130, 0x1d09c, 0x14220, 0x1a118, 0x1d08e, 0x14210, 0x1a10c, 0x14208, 0x1a106, 0x14360, 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e, 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0, 0x1d05c, 0x14120, 0x1a098, 0x1d04e, 0x14110, 0x1a08c, 0x14108, 0x1a086, 0x14104, 0x141b0, 0x14198, 0x1418c, 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0, 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460, 0x1ca38, 0x1e51e, 0x12840, 0x19430, 0x12820, 0x196e0, 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, 0x1cb3c, 0x12c60, 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe, 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be, 0x12f3c, 0x12fbe, 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60, 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, 0x1ed1c, 0x1b420, 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970, 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660, 0x1db38, 0x1ed9e, 0x16c40, 0x12420, 0x19218, 0x1c90e, 0x16c20, 0x1b618, 0x16c10, 0x126c0, 0x19370, 0x1c9bc, 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738, 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc, 0x16f70, 0x12738, 0x1939e, 0x16f38, 0x1b79e, 0x16f1c, 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, 0x1d960, 0x1ecb8, 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918, 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160, 0x1c8b8, 0x1e45e, 0x1b360, 0x19130, 0x1c89c, 0x16640, 0x12220, 0x1d99c, 0x1c88e, 0x16620, 0x12210, 0x1910c, 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8, 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c, 0x1918e, 0x16718, 0x1230c, 0x12306, 0x123b8, 0x191de, 0x167b8, 0x1239c, 0x1679c, 0x1238e, 0x1678e, 0x167de, 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e, 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102, 0x12140, 0x190b0, 0x1c85c, 0x16340, 0x12120, 0x19098, 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, 0x16310, 0x12108, 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc, 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c, 0x12186, 0x16386, 0x163dc, 0x163ce, 0x1b0a0, 0x1d858, 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, 0x1d846, 0x1b084, 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090, 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084, 0x16184, 0x12082, 0x120d8, 0x161d8, 0x161cc, 0x161c6, 0x1d82c, 0x1d826, 0x1b042, 0x1902c, 0x12048, 0x160c8, 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60, 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18, 0x11410, 0x11408, 0x116c0, 0x18b70, 0x1c5bc, 0x11660, 0x18b38, 0x1c59e, 0x11630, 0x18b1c, 0x11618, 0x1160c, 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc, 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30, 0x1e69c, 0x19a20, 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c, 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, 0x1e25e, 0x19b60, 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e, 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608, 0x11360, 0x189b8, 0x1c4de, 0x13760, 0x11330, 0x1cdde, 0x13730, 0x19b9c, 0x1898e, 0x13718, 0x1130c, 0x1370c, 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e, 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20, 0x1ee98, 0x1f74e, 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86, 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, 0x1bb40, 0x19920, 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10, 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140, 0x188b0, 0x1c45c, 0x13340, 0x11120, 0x18898, 0x1c44e, 0x17740, 0x13320, 0x19998, 0x1ccce, 0x17720, 0x1bb98, 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708, 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce, 0x177b0, 0x13398, 0x199ce, 0x17798, 0x1bbce, 0x11186, 0x13386, 0x111dc, 0x133dc, 0x111ce, 0x177dc, 0x133ce, 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88, 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e, 0x1b9a0, 0x19890, 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46, 0x1b988, 0x19884, 0x1b984, 0x19882, 0x1b982, 0x110a0, 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0, 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084, 0x17388, 0x13184, 0x11082, 0x13182, 0x110d8, 0x1886e, 0x131d8, 0x110cc, 0x173d8, 0x131cc, 0x110c6, 0x173cc, 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48, 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0, 0x19848, 0x1cc26, 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842, 0x1b8c2, 0x11050, 0x1882c, 0x130d0, 0x11048, 0x18826, 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042, 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6, 0x1ee16, 0x1dc22, 0x1cc16, 0x19824, 0x19822, 0x11028, 0x13068, 0x170e8, 0x11022, 0x13062, 0x18560, 0x10a40, 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c, 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30, 0x1859c, 0x10b18, 0x1858e, 0x10b0c, 0x10b06, 0x10bb8, 0x185de, 0x10b9c, 0x10b8e, 0x10bde, 0x18d40, 0x1c6b0, 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08, 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40, 0x10920, 0x1c6dc, 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce, 0x11b10, 0x10908, 0x18486, 0x11b08, 0x18d86, 0x10902, 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98, 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce, 0x11bce, 0x1cea0, 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c, 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, 0x18ca0, 0x1c658, 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646, 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0, 0x18458, 0x119a0, 0x10890, 0x1c66e, 0x13ba0, 0x11990, 0x18ccc, 0x18446, 0x13b90, 0x19dcc, 0x10884, 0x13b88, 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8, 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6, 0x108ee, 0x119ee, 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48, 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, 0x1e72c, 0x1ded0, 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42, 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626, 0x1bdd0, 0x19cc8, 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42, 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, 0x1842c, 0x118d0, 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0, 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2, 0x17bc4, 0x1086c, 0x118ec, 0x10866, 0x139ec, 0x118e6, 0x17bec, 0x139e6, 0x17be6, 0x1ef28, 0x1f796, 0x1ef24, 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64, 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24, 0x1bce8, 0x19c64, 0x18c22, 0x1bce4, 0x19c62, 0x1bce2, 0x10828, 0x18416, 0x11868, 0x18c36, 0x138e8, 0x11864, 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2, 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32, 0x19c34, 0x1bc74, 0x1bc72, 0x11834, 0x13874, 0x178f4, 0x178f2, 0x10540, 0x10520, 0x18298, 0x10510, 0x10508, 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc, 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346, 0x18684, 0x18682, 0x104a0, 0x18258, 0x10da0, 0x186d8, 0x1824c, 0x10d90, 0x186cc, 0x10d88, 0x186c6, 0x10d84, 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee, 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750, 0x1c748, 0x1c744, 0x1c742, 0x18650, 0x18ed0, 0x1c76c, 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, 0x18642, 0x18ec2, 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8, 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2, 0x1046c, 0x10cec, 0x10466, 0x11dec, 0x10ce6, 0x11de6, 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, 0x1cf68, 0x1e7b6, 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68, 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62, 0x19ee2, 0x10428, 0x18216, 0x10c68, 0x18636, 0x11ce8, 0x10c64, 0x10422, 0x13de8, 0x11ce4, 0x10c62, 0x13de4, 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4, 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714, 0x1cf34, 0x1c712, 0x1df74, 0x1cf32, 0x1df72, 0x18614, 0x18e34, 0x18612, 0x19e74, 0x18e32, 0x1bef4 }, { 0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20, 0x1f518, 0x1fa8e, 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506, 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, 0x1d640, 0x1eb30, 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c, 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de, 0x1ae40, 0x1d730, 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e, 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, 0x1ae04, 0x1af60, 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20, 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06, 0x15f60, 0x1afb8, 0x1d7de, 0x15f30, 0x1af9c, 0x15f18, 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, 0x15f9c, 0x15f8e, 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e, 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902, 0x1d340, 0x1e9b0, 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce, 0x1d310, 0x1e98c, 0x1d308, 0x1e986, 0x1d304, 0x1d302, 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce, 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702, 0x14f40, 0x1a7b0, 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce, 0x14f10, 0x1a78c, 0x14f08, 0x1a786, 0x14f04, 0x14fb0, 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc, 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c, 0x1e888, 0x1f446, 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8, 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, 0x1e8c6, 0x1d184, 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc, 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8, 0x1d1ee, 0x14790, 0x1a3cc, 0x14788, 0x1a3c6, 0x14784, 0x14782, 0x147d8, 0x1a3ee, 0x147cc, 0x147c6, 0x147ee, 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842, 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2, 0x1a1d0, 0x1d0ec, 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2, 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, 0x143c4, 0x143c2, 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822, 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076, 0x1a0e4, 0x1a0e2, 0x141e8, 0x1a0f6, 0x141e4, 0x141e2, 0x1e814, 0x1e812, 0x1d034, 0x1d032, 0x1a074, 0x1a072, 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e, 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502, 0x1cb40, 0x1e5b0, 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce, 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, 0x1cb04, 0x1cb02, 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce, 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702, 0x12f40, 0x197b0, 0x1cbdc, 0x12f20, 0x19798, 0x1cbce, 0x12f10, 0x1978c, 0x12f08, 0x19786, 0x12f04, 0x12fb0, 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc, 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c, 0x169f8, 0x1f688, 0x1fb46, 0x168fc, 0x1f684, 0x1f682, 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, 0x1e490, 0x1fb6e, 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84, 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0, 0x1c990, 0x1e4cc, 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88, 0x1c984, 0x1db84, 0x1c982, 0x1db82, 0x193a0, 0x1c9d8, 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc, 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782, 0x127a0, 0x193d8, 0x1c9ee, 0x16fa0, 0x12790, 0x193cc, 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, 0x12784, 0x16f84, 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc, 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8, 0x1f648, 0x1fb26, 0x164fc, 0x1f644, 0x1647e, 0x1f642, 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, 0x1f226, 0x1ecc8, 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c, 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4, 0x1c8c2, 0x1d9c2, 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8, 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, 0x191c2, 0x1b3c2, 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8, 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec, 0x123e6, 0x167e6, 0x1f628, 0x1fb16, 0x162fc, 0x1f624, 0x1627e, 0x1f622, 0x1e428, 0x1f216, 0x1ec68, 0x1f636, 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8, 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876, 0x1b1e8, 0x1d8f6, 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8, 0x190f6, 0x163e8, 0x121e4, 0x163e4, 0x121e2, 0x163e2, 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414, 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832, 0x1d872, 0x19074, 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4, 0x161f4, 0x120f2, 0x161f2, 0x1f60a, 0x1e40a, 0x1ec1a, 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158, 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284, 0x1e282, 0x1c5a0, 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc, 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, 0x18ba0, 0x1c5d8, 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84, 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc, 0x11788, 0x18bc6, 0x11784, 0x11782, 0x117d8, 0x18bee, 0x117cc, 0x117c6, 0x117ee, 0x1f350, 0x1f9ac, 0x135f8, 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342, 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8, 0x1f366, 0x1e6c4, 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c, 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, 0x1e6e6, 0x1cdc4, 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8, 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2, 0x113d0, 0x189ec, 0x137d0, 0x113c8, 0x189e6, 0x137c8, 0x19be6, 0x137c4, 0x113c2, 0x137c2, 0x113ec, 0x137ec, 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4, 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328, 0x1f996, 0x132fc, 0x1f768, 0x1fbb6, 0x176fc, 0x1327e, 0x1f764, 0x1f322, 0x1767e, 0x1f762, 0x1e228, 0x1f116, 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4, 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464, 0x1dde8, 0x1cce4, 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2, 0x188e8, 0x1c476, 0x199e8, 0x188e4, 0x1bbe8, 0x199e4, 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6, 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4, 0x133e2, 0x177e2, 0x111f6, 0x133f6, 0x1fb94, 0x172f8, 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, 0x1f314, 0x1317e, 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634, 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74, 0x1c432, 0x1dcf4, 0x1cc72, 0x1dcf2, 0x18874, 0x198f4, 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, 0x110f4, 0x131f4, 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c, 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a, 0x1c41a, 0x1cc3a, 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa, 0x1107a, 0x130fa, 0x171fa, 0x170be, 0x1e150, 0x1f0ac, 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c, 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec, 0x185c8, 0x1c2e6, 0x185c4, 0x185c2, 0x10bd0, 0x185ec, 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, 0x10bec, 0x10be6, 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2, 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122, 0x1e362, 0x1c268, 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4, 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, 0x18de8, 0x184e4, 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8, 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6, 0x1f9d4, 0x13af8, 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e, 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, 0x13b7e, 0x1f3b2, 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772, 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2, 0x18474, 0x18cf4, 0x18472, 0x19df4, 0x18cf2, 0x19df2, 0x108f4, 0x119f4, 0x108f2, 0x13bf4, 0x119f2, 0x13bf2, 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e, 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e, 0x1f18a, 0x1f39a, 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a, 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, 0x1defa, 0x1843a, 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa, 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be, 0x178bc, 0x1789e, 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2, 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, 0x182e8, 0x1c176, 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2, 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4, 0x1e092, 0x1e1b2, 0x1c134, 0x1c374, 0x1c132, 0x1c372, 0x18274, 0x186f4, 0x18272, 0x186f2, 0x104f4, 0x10df4, 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca, 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a, 0x1c77a, 0x1823a, 0x1867a, 0x18efa, 0x1047a, 0x10cfa, 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, 0x13d1e, 0x11cbe, 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c, 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8, 0x1be5e, 0x17c9c, 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c, 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, 0x18174, 0x18172, 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a, 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e, 0x13eb8, 0x19f5e, 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede, 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, 0x17e8c, 0x17e86, 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e, 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26, 0x10f5e, 0x11f5c, 0x11f4e, 0x13f58, 0x19fae, 0x13f4c, 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, 0x13f26 }, { 0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0, 0x1a8f8, 0x1d47e, 0x150f0, 0x1a87c, 0x15078, 0x1fad0, 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, 0x1acfc, 0x1fac4, 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec, 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e, 0x1f5c2, 0x1ebd0, 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4, 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, 0x1ebe6, 0x1d7c4, 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4, 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e, 0x148f0, 0x1a47c, 0x14878, 0x1a43e, 0x1483c, 0x1fa68, 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, 0x1a67e, 0x1fa62, 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4, 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2, 0x1d3e8, 0x1e9f6, 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6, 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, 0x1d17e, 0x144f0, 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34, 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474, 0x1477e, 0x1f472, 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2, 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, 0x14278, 0x1a13e, 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a, 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e, 0x141be, 0x140bc, 0x1409e, 0x12bc0, 0x195f0, 0x1cafc, 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, 0x1947c, 0x12878, 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964, 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8, 0x1f976, 0x12efc, 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8, 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, 0x1e5f6, 0x1cbe4, 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0, 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0, 0x1b478, 0x1da3e, 0x16870, 0x1b43c, 0x16838, 0x1b41e, 0x1681c, 0x125e0, 0x192f8, 0x1c97e, 0x16de0, 0x124f0, 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c, 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e, 0x1fb74, 0x1f932, 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c, 0x1263e, 0x16e3e, 0x1f274, 0x1277e, 0x1f6f4, 0x1f272, 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2, 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2, 0x165c0, 0x1b2f0, 0x1d97c, 0x164e0, 0x1b278, 0x1d93e, 0x16470, 0x1b23c, 0x16438, 0x1b21e, 0x1641c, 0x1640e, 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678, 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c, 0x1fb3a, 0x1677c, 0x1233e, 0x1673e, 0x1f23a, 0x1f67a, 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, 0x191fa, 0x162e0, 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e, 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c, 0x1633c, 0x1211e, 0x1631e, 0x121be, 0x163be, 0x16170, 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, 0x1610e, 0x120bc, 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c, 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0, 0x18af8, 0x1c57e, 0x114f0, 0x18a7c, 0x11478, 0x18a3e, 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, 0x18b7e, 0x1f8b2, 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4, 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0, 0x19af0, 0x1cd7c, 0x134e0, 0x19a78, 0x1cd3e, 0x13470, 0x19a3c, 0x13438, 0x19a1e, 0x1341c, 0x1340e, 0x112f0, 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e, 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba, 0x1377c, 0x1133e, 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a, 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, 0x1bae0, 0x1dd78, 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38, 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c, 0x132e0, 0x19978, 0x1ccbe, 0x176e0, 0x13270, 0x1993c, 0x17670, 0x1bb3c, 0x1991e, 0x17638, 0x1321c, 0x1761c, 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c, 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e, 0x111be, 0x133be, 0x177be, 0x172c0, 0x1b970, 0x1dcbc, 0x17260, 0x1b938, 0x1dc9e, 0x17230, 0x1b91c, 0x17218, 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370, 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e, 0x1730e, 0x110bc, 0x131bc, 0x1109e, 0x173bc, 0x1319e, 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, 0x17130, 0x1b89c, 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e, 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e, 0x130de, 0x171de, 0x170b0, 0x1b85c, 0x17098, 0x1b84e, 0x1708c, 0x17086, 0x1305c, 0x170dc, 0x1304e, 0x170ce, 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e, 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e, 0x10a3c, 0x10a1e, 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a, 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, 0x1c6be, 0x11a70, 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978, 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e, 0x109be, 0x11bbe, 0x13ac0, 0x19d70, 0x1cebc, 0x13a60, 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, 0x13a18, 0x19d0e, 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938, 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e, 0x108bc, 0x119bc, 0x1089e, 0x13bbc, 0x1199e, 0x13b9e, 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, 0x1bd30, 0x1de9c, 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08, 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60, 0x13930, 0x19c9c, 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18, 0x1390c, 0x17b0c, 0x13906, 0x17b06, 0x118b8, 0x18c5e, 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c, 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde, 0x17940, 0x1bcb0, 0x1de5c, 0x17920, 0x1bc98, 0x1de4e, 0x17910, 0x1bc8c, 0x17908, 0x1bc86, 0x17904, 0x17902, 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998, 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc, 0x1184e, 0x179dc, 0x138ce, 0x179ce, 0x178a0, 0x1bc58, 0x1de2e, 0x17890, 0x1bc4c, 0x17888, 0x1bc46, 0x17884, 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc, 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850, 0x1bc2c, 0x17848, 0x1bc26, 0x17844, 0x17842, 0x1382c, 0x1786c, 0x13826, 0x17866, 0x17828, 0x1bc16, 0x17824, 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c, 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e, 0x10d1c, 0x10d0e, 0x104bc, 0x10dbc, 0x1049e, 0x10d9e, 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, 0x18e9c, 0x11d18, 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8, 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde, 0x11dde, 0x13d40, 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98, 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, 0x19e86, 0x13d04, 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e, 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c, 0x11cdc, 0x10c4e, 0x13ddc, 0x11cce, 0x13dce, 0x1bea0, 0x1df58, 0x1efae, 0x1be90, 0x1df4c, 0x1be88, 0x1df46, 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0, 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88, 0x13c84, 0x17d84, 0x13c82, 0x17d82, 0x11c58, 0x18e2e, 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, 0x11c46, 0x17dcc, 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee, 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42, 0x13c50, 0x19e2c, 0x17cd0, 0x13c48, 0x19e26, 0x17cc8, 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, 0x11c2c, 0x13c6c, 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16, 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24, 0x17c64, 0x13c22, 0x17c62, 0x11c16, 0x13c36, 0x17c76, 0x1be14, 0x1be12, 0x13c14, 0x17c34, 0x13c12, 0x17c32, 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e, 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e, 0x10e8c, 0x10e86, 0x1065c, 0x10edc, 0x1064e, 0x10ece, 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, 0x18f4c, 0x11e88, 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8, 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e, 0x11eee, 0x19f50, 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44, 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, 0x19f6c, 0x18f26, 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c, 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8, 0x1efd6, 0x1dfa4, 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68, 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, 0x11e28, 0x18f16, 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4, 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6, 0x1df94, 0x1df92, 0x19f14, 0x1bf34, 0x19f12, 0x1bf32, 0x11e14, 0x13e34, 0x11e12, 0x17e74, 0x13e32, 0x17e72, 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a, 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746, 0x1032e, 0x1076e, 0x10f50, 0x187ac, 0x10f48, 0x187a6, 0x10f44, 0x10f42, 0x1072c, 0x10f6c, 0x10726, 0x10f66, 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796, 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716, 0x10f36, 0x11f76, 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4, 0x18f92, 0x19fb2, 0x10f14, 0x11f34, 0x10f12, 0x13f74, 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a, 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6, 0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2, 0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea }}; private static final int ERROR_LEVEL[][] = {{ 27, 917 }, { 522, 568, 723, 809 }, { 237, 308, 436, 284, 646, 653, 428, 379 }, { 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65 }, { 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410 }, { 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543 }, { 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539 }, { 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10 }, { 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 }}; /** Holds value of property outBits. */ private byte[] outBits; /** Holds value of property bitColumns. */ private int bitColumns; /** Holds value of property codeRows. */ private int codeRows; /** Holds value of property codeColumns. */ private int codeColumns; /** Holds value of property codewords. */ private int[] codewords = new int[MAX_DATA_CODEWORDS + 2]; /** Holds value of property lenCodewords. */ private int lenCodewords; /** Holds value of property errorLevel. */ private int errorLevel; /** Holds value of property text. */ private byte[] text; /** Holds value of property options. */ private int options; /** Holds value of property aspectRatio. */ private float aspectRatio; /** Holds value of property yHeight. */ private float yHeight; protected static class Segment { public char type; public int start; public int end; public Segment(char type, int start, int end) { this.type = type; this.start = start; this.end = end; } } protected static class SegmentList { protected ArrayList list = new ArrayList(); public void add(char type, int start, int end) { list.add(new Segment(type, start, end)); } public Segment get(int idx) { if (idx < 0 || idx >= list.size()) return null; return (Segment)list.get(idx); } public void remove(int idx) { if (idx < 0 || idx >= list.size()) return; list.remove(idx); } public int size() { return list.size(); } } } src/core/com/lowagie/text/pdf/BarcodePostnet.java100644 0 0 21303 11000354131 17450 0ustar 0 0 /* * Copyright 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Canvas; import java.awt.Color; import java.awt.Image; import java.awt.image.MemoryImageSource; import com.lowagie.text.Rectangle; /** Implements the Postnet and Planet barcodes. The default parameters are: *

 *n = 72f / 22f; // distance between bars
 *x = 0.02f * 72f; // bar width
 *barHeight = 0.125f * 72f; // height of the tall bars
 *size = 0.05f * 72f; // height of the short bars
 *codeType = POSTNET; // type of code
 * 
* * @author Paulo Soares (psoares@consiste.pt) */ public class BarcodePostnet extends Barcode{ /** The bars for each character. */ private static final byte BARS[][] = { {1,1,0,0,0}, {0,0,0,1,1}, {0,0,1,0,1}, {0,0,1,1,0}, {0,1,0,0,1}, {0,1,0,1,0}, {0,1,1,0,0}, {1,0,0,0,1}, {1,0,0,1,0}, {1,0,1,0,0} }; /** Creates new BarcodePostnet */ public BarcodePostnet() { n = 72f / 22f; // distance between bars x = 0.02f * 72f; // bar width barHeight = 0.125f * 72f; // height of the tall bars size = 0.05f * 72f; // height of the short bars codeType = POSTNET; // type of code } /** Creates the bars for Postnet. * @param text the code to be created without checksum * @return the bars */ public static byte[] getBarsPostnet(String text) { int total = 0; for (int k = text.length() - 1; k >= 0; --k) { int n = text.charAt(k) - '0'; total += n; } text += (char)(((10 - (total % 10)) % 10) + '0'); byte bars[] = new byte[text.length() * 5 + 2]; bars[0] = 1; bars[bars.length - 1] = 1; for (int k = 0; k < text.length(); ++k) { int c = text.charAt(k) - '0'; System.arraycopy(BARS[c], 0, bars, k * 5 + 1, 5); } return bars; } /** Gets the maximum area that the barcode and the text, if * any, will occupy. The lower left corner is always (0, 0). * @return the size the barcode occupies. */ public Rectangle getBarcodeSize() { float width = ((code.length() + 1) * 5 + 1) * n + x; return new Rectangle(width, barHeight); } /** Places the barcode in a PdfContentByte. The * barcode is always placed at coordinates (0, 0). Use the * translation matrix to move it elsewhere.

* The bars and text are written in the following colors:

*

* * * * * * * * * * * * * * * * * * * * * * * * * *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

* @param cb the PdfContentByte where the barcode will be placed * @param barColor the color of the bars. It can be null * @param textColor the color of the text. It can be null * @return the dimensions the barcode occupies */ public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { if (barColor != null) cb.setColorFill(barColor); byte bars[] = getBarsPostnet(code); byte flip = 1; if (codeType == PLANET) { flip = 0; bars[0] = 0; bars[bars.length - 1] = 0; } float startX = 0; for (int k = 0; k < bars.length; ++k) { cb.rectangle(startX, 0, x - inkSpreading, bars[k] == flip ? barHeight : size); startX += n; } cb.fill(); return getBarcodeSize(); } /** Creates a java.awt.Image. This image only * contains the bars without any text. * @param foreground the color of the bars * @param background the color of the background * @return the image * */ public java.awt.Image createAwtImage(Color foreground, Color background) { int f = foreground.getRGB(); int g = background.getRGB(); Canvas canvas = new Canvas(); int barWidth = (int)x; if (barWidth <= 0) barWidth = 1; int barDistance = (int)n; if (barDistance <= barWidth) barDistance = barWidth + 1; int barShort = (int)size; if (barShort <= 0) barShort = 1; int barTall = (int)barHeight; if (barTall <= barShort) barTall = barShort + 1; int width = ((code.length() + 1) * 5 + 1) * barDistance + barWidth; int pix[] = new int[width * barTall]; byte bars[] = getBarsPostnet(code); byte flip = 1; if (codeType == PLANET) { flip = 0; bars[0] = 0; bars[bars.length - 1] = 0; } int idx = 0; for (int k = 0; k < bars.length; ++k) { boolean dot = (bars[k] == flip); for (int j = 0; j < barDistance; ++j) { pix[idx + j] = ((dot && j < barWidth) ? f : g); } idx += barDistance; } int limit = width * (barTall - barShort); for (int k = width; k < limit; k += width) System.arraycopy(pix, 0, pix, k, width); idx = limit; for (int k = 0; k < bars.length; ++k) { for (int j = 0; j < barDistance; ++j) { pix[idx + j] = ((j < barWidth) ? f : g); } idx += barDistance; } for (int k = limit + width; k < pix.length; k += width) System.arraycopy(pix, limit, pix, k, width); Image img = canvas.createImage(new MemoryImageSource(width, barTall, pix, 0, width)); return img; } }src/core/com/lowagie/text/pdf/BaseField.java100644 0 0 56761 11000354131 16372 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Rectangle; /** Common field variables. * @author Paulo Soares (psoares@consiste.pt) */ public abstract class BaseField { /** A thin border with 1 point width. */ public static final float BORDER_WIDTH_THIN = 1; /** A medium border with 2 point width. */ public static final float BORDER_WIDTH_MEDIUM = 2; /** A thick border with 3 point width. */ public static final float BORDER_WIDTH_THICK = 3; /** The field is visible. */ public static final int VISIBLE = 0; /** The field is hidden. */ public static final int HIDDEN = 1; /** The field is visible but does not print. */ public static final int VISIBLE_BUT_DOES_NOT_PRINT = 2; /** The field is hidden but is printable. */ public static final int HIDDEN_BUT_PRINTABLE = 3; /** The user may not change the value of the field. */ public static final int READ_ONLY = PdfFormField.FF_READ_ONLY; /** The field must have a value at the time it is exported by a submit-form * action. */ public static final int REQUIRED = PdfFormField.FF_REQUIRED; /** The field may contain multiple lines of text. * This flag is only meaningful with text fields. */ public static final int MULTILINE = PdfFormField.FF_MULTILINE; /** The field will not scroll (horizontally for single-line * fields, vertically for multiple-line fields) to accommodate more text * than will fit within its annotation rectangle. Once the field is full, no * further text will be accepted. */ public static final int DO_NOT_SCROLL = PdfFormField.FF_DONOTSCROLL; /** The field is intended for entering a secure password that should * not be echoed visibly to the screen. */ public static final int PASSWORD = PdfFormField.FF_PASSWORD; /** The text entered in the field represents the pathname of * a file whose contents are to be submitted as the value of the field. */ public static final int FILE_SELECTION = PdfFormField.FF_FILESELECT; /** The text entered in the field will not be spell-checked. * This flag is meaningful only in text fields and in combo * fields with the EDIT flag set. */ public static final int DO_NOT_SPELL_CHECK = PdfFormField.FF_DONOTSPELLCHECK; /** If set the combo box includes an editable text box as well as a drop list; if * clear, it includes only a drop list. * This flag is only meaningful with combo fields. */ public static final int EDIT = PdfFormField.FF_EDIT; /** * combo box flag. */ public static final int COMB = PdfFormField.FF_COMB; protected float borderWidth = BORDER_WIDTH_THIN; protected int borderStyle = PdfBorderDictionary.STYLE_SOLID; protected Color borderColor; protected Color backgroundColor; protected Color textColor; protected BaseFont font; protected float fontSize = 0; protected int alignment = Element.ALIGN_LEFT; protected PdfWriter writer; protected String text; protected Rectangle box; /** Holds value of property rotation. */ protected int rotation = 0; /** Holds value of property visibility. */ protected int visibility; /** Holds value of property fieldName. */ protected String fieldName; /** Holds value of property options. */ protected int options; /** Holds value of property maxCharacterLength. */ protected int maxCharacterLength; private final static HashMap fieldKeys = new HashMap(); static { fieldKeys.putAll(PdfCopyFieldsImp.fieldKeys); fieldKeys.put(PdfName.T, new Integer(1)); } /** Creates a new TextField. * @param writer the document PdfWriter * @param box the field location and dimensions * @param fieldName the field name. If null only the widget keys * will be included in the field allowing it to be used as a kid field. */ public BaseField(PdfWriter writer, Rectangle box, String fieldName) { this.writer = writer; setBox(box); this.fieldName = fieldName; } protected BaseFont getRealFont() throws IOException, DocumentException { if (font == null) return BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, false); else return font; } protected PdfAppearance getBorderAppearance() { PdfAppearance app = PdfAppearance.createAppearance(writer, box.getWidth(), box.getHeight()); switch (rotation) { case 90: app.setMatrix(0, 1, -1, 0, box.getHeight(), 0); break; case 180: app.setMatrix(-1, 0, 0, -1, box.getWidth(), box.getHeight()); break; case 270: app.setMatrix(0, -1, 1, 0, 0, box.getWidth()); break; } app.saveState(); // background if (backgroundColor != null) { app.setColorFill(backgroundColor); app.rectangle(0, 0, box.getWidth(), box.getHeight()); app.fill(); } // border if (borderStyle == PdfBorderDictionary.STYLE_UNDERLINE) { if (borderWidth != 0 && borderColor != null) { app.setColorStroke(borderColor); app.setLineWidth(borderWidth); app.moveTo(0, borderWidth / 2); app.lineTo(box.getWidth(), borderWidth / 2); app.stroke(); } } else if (borderStyle == PdfBorderDictionary.STYLE_BEVELED) { if (borderWidth != 0 && borderColor != null) { app.setColorStroke(borderColor); app.setLineWidth(borderWidth); app.rectangle(borderWidth / 2, borderWidth / 2, box.getWidth() - borderWidth, box.getHeight() - borderWidth); app.stroke(); } // beveled Color actual = backgroundColor; if (actual == null) actual = Color.white; app.setGrayFill(1); drawTopFrame(app); app.setColorFill(actual.darker()); drawBottomFrame(app); } else if (borderStyle == PdfBorderDictionary.STYLE_INSET) { if (borderWidth != 0 && borderColor != null) { app.setColorStroke(borderColor); app.setLineWidth(borderWidth); app.rectangle(borderWidth / 2, borderWidth / 2, box.getWidth() - borderWidth, box.getHeight() - borderWidth); app.stroke(); } // inset app.setGrayFill(0.5f); drawTopFrame(app); app.setGrayFill(0.75f); drawBottomFrame(app); } else { if (borderWidth != 0 && borderColor != null) { if (borderStyle == PdfBorderDictionary.STYLE_DASHED) app.setLineDash(3, 0); app.setColorStroke(borderColor); app.setLineWidth(borderWidth); app.rectangle(borderWidth / 2, borderWidth / 2, box.getWidth() - borderWidth, box.getHeight() - borderWidth); app.stroke(); if ((options & COMB) != 0 && maxCharacterLength > 1) { float step = box.getWidth() / maxCharacterLength; float yb = borderWidth / 2; float yt = box.getHeight() - borderWidth / 2; for (int k = 1; k < maxCharacterLength; ++k) { float x = step * k; app.moveTo(x, yb); app.lineTo(x, yt); } app.stroke(); } } } app.restoreState(); return app; } protected static ArrayList getHardBreaks(String text) { ArrayList arr = new ArrayList(); char cs[] = text.toCharArray(); int len = cs.length; StringBuffer buf = new StringBuffer(); for (int k = 0; k < len; ++k) { char c = cs[k]; if (c == '\r') { if (k + 1 < len && cs[k + 1] == '\n') ++k; arr.add(buf.toString()); buf = new StringBuffer(); } else if (c == '\n') { arr.add(buf.toString()); buf = new StringBuffer(); } else buf.append(c); } arr.add(buf.toString()); return arr; } protected static void trimRight(StringBuffer buf) { int len = buf.length(); while (true) { if (len == 0) return; if (buf.charAt(--len) != ' ') return; buf.setLength(len); } } protected static ArrayList breakLines(ArrayList breaks, BaseFont font, float fontSize, float width) { ArrayList lines = new ArrayList(); StringBuffer buf = new StringBuffer(); for (int ck = 0; ck < breaks.size(); ++ck) { buf.setLength(0); float w = 0; char cs[] = ((String)breaks.get(ck)).toCharArray(); int len = cs.length; // 0 inline first, 1 inline, 2 spaces int state = 0; int lastspace = -1; char c = 0; int refk = 0; for (int k = 0; k < len; ++k) { c = cs[k]; switch (state) { case 0: w += font.getWidthPoint(c, fontSize); buf.append(c); if (w > width) { w = 0; if (buf.length() > 1) { --k; buf.setLength(buf.length() - 1); } lines.add(buf.toString()); buf.setLength(0); refk = k; if (c == ' ') state = 2; else state = 1; } else { if (c != ' ') state = 1; } break; case 1: w += font.getWidthPoint(c, fontSize); buf.append(c); if (c == ' ') lastspace = k; if (w > width) { w = 0; if (lastspace >= 0) { k = lastspace; buf.setLength(lastspace - refk); trimRight(buf); lines.add(buf.toString()); buf.setLength(0); refk = k; lastspace = -1; state = 2; } else { if (buf.length() > 1) { --k; buf.setLength(buf.length() - 1); } lines.add(buf.toString()); buf.setLength(0); refk = k; if (c == ' ') state = 2; } } break; case 2: if (c != ' ') { w = 0; --k; state = 1; } break; } } trimRight(buf); lines.add(buf.toString()); } return lines; } private void drawTopFrame(PdfAppearance app) { app.moveTo(borderWidth, borderWidth); app.lineTo(borderWidth, box.getHeight() - borderWidth); app.lineTo(box.getWidth() - borderWidth, box.getHeight() - borderWidth); app.lineTo(box.getWidth() - 2 * borderWidth, box.getHeight() - 2 * borderWidth); app.lineTo(2 * borderWidth, box.getHeight() - 2 * borderWidth); app.lineTo(2 * borderWidth, 2 * borderWidth); app.lineTo(borderWidth, borderWidth); app.fill(); } private void drawBottomFrame(PdfAppearance app) { app.moveTo(borderWidth, borderWidth); app.lineTo(box.getWidth() - borderWidth, borderWidth); app.lineTo(box.getWidth() - borderWidth, box.getHeight() - borderWidth); app.lineTo(box.getWidth() - 2 * borderWidth, box.getHeight() - 2 * borderWidth); app.lineTo(box.getWidth() - 2 * borderWidth, 2 * borderWidth); app.lineTo(2 * borderWidth, 2 * borderWidth); app.lineTo(borderWidth, borderWidth); app.fill(); } /** Gets the border width in points. * @return the border width in points */ public float getBorderWidth() { return this.borderWidth; } /** Sets the border width in points. To eliminate the border * set the border color to null. * @param borderWidth the border width in points */ public void setBorderWidth(float borderWidth) { this.borderWidth = borderWidth; } /** Gets the border style. * @return the border style */ public int getBorderStyle() { return this.borderStyle; } /** Sets the border style. The styles are found in PdfBorderDictionary * and can be STYLE_SOLID, STYLE_DASHED, * STYLE_BEVELED, STYLE_INSET and * STYLE_UNDERLINE. * @param borderStyle the border style */ public void setBorderStyle(int borderStyle) { this.borderStyle = borderStyle; } /** Gets the border color. * @return the border color */ public Color getBorderColor() { return this.borderColor; } /** Sets the border color. Set to null to remove * the border. * @param borderColor the border color */ public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } /** Gets the background color. * @return the background color */ public Color getBackgroundColor() { return this.backgroundColor; } /** Sets the background color. Set to null for * transparent background. * @param backgroundColor the background color */ public void setBackgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; } /** Gets the text color. * @return the text color */ public Color getTextColor() { return this.textColor; } /** Sets the text color. If null the color used * will be black. * @param textColor the text color */ public void setTextColor(Color textColor) { this.textColor = textColor; } /** Gets the text font. * @return the text font */ public BaseFont getFont() { return this.font; } /** Sets the text font. If null then Helvetica * will be used. * @param font the text font */ public void setFont(BaseFont font) { this.font = font; } /** Gets the font size. * @return the font size */ public float getFontSize() { return this.fontSize; } /** Sets the font size. If 0 then auto-sizing will be used but * only for text fields. * @param fontSize the font size */ public void setFontSize(float fontSize) { this.fontSize = fontSize; } /** Gets the text horizontal alignment. * @return the text horizontal alignment */ public int getAlignment() { return this.alignment; } /** Sets the text horizontal alignment. It can be Element.ALIGN_LEFT, * Element.ALIGN_CENTER and Element.ALIGN_RIGHT. * @param alignment the text horizontal alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } /** Gets the text. * @return the text */ public String getText() { return this.text; } /** Sets the text for text fields. * @param text the text */ public void setText(String text) { this.text = text; } /** Gets the field dimension and position. * @return the field dimension and position */ public Rectangle getBox() { return this.box; } /** Sets the field dimension and position. * @param box the field dimension and position */ public void setBox(Rectangle box) { if (box == null) { this.box = null; } else { this.box = new Rectangle(box); this.box.normalize(); } } /** Gets the field rotation. * @return the field rotation */ public int getRotation() { return this.rotation; } /** Sets the field rotation. This value should be the same as * the page rotation where the field will be shown. * @param rotation the field rotation */ public void setRotation(int rotation) { if (rotation % 90 != 0) throw new IllegalArgumentException("Rotation must be a multiple of 90."); rotation %= 360; if (rotation < 0) rotation += 360; this.rotation = rotation; } /** Convenience method to set the field rotation the same as the * page rotation. * @param page the page */ public void setRotationFromPage(Rectangle page) { setRotation(page.getRotation()); } /** Gets the field visibility flag. * @return the field visibility flag */ public int getVisibility() { return this.visibility; } /** Sets the field visibility flag. This flags can be one of * VISIBLE, HIDDEN, VISIBLE_BUT_DOES_NOT_PRINT * and HIDDEN_BUT_PRINTABLE. * @param visibility field visibility flag */ public void setVisibility(int visibility) { this.visibility = visibility; } /** Gets the field name. * @return the field name */ public String getFieldName() { return this.fieldName; } /** Sets the field name. * @param fieldName the field name. If null only the widget keys * will be included in the field allowing it to be used as a kid field. */ public void setFieldName(String fieldName) { this.fieldName = fieldName; } /** Gets the option flags. * @return the option flags */ public int getOptions() { return this.options; } /** Sets the option flags. The option flags can be a combination by oring of * READ_ONLY, REQUIRED, * MULTILINE, DO_NOT_SCROLL, * PASSWORD, FILE_SELECTION, * DO_NOT_SPELL_CHECK and EDIT. * @param options the option flags */ public void setOptions(int options) { this.options = options; } /** Gets the maximum length of the field's text, in characters. * @return the maximum length of the field's text, in characters. */ public int getMaxCharacterLength() { return this.maxCharacterLength; } /** Sets the maximum length of the field's text, in characters. * It is only meaningful for text fields. * @param maxCharacterLength the maximum length of the field's text, in characters */ public void setMaxCharacterLength(int maxCharacterLength) { this.maxCharacterLength = maxCharacterLength; } /** * Getter for property writer. * @return Value of property writer. */ public PdfWriter getWriter() { return writer; } /** * Setter for property writer. * @param writer New value of property writer. */ public void setWriter(PdfWriter writer) { this.writer = writer; } /** * Moves the field keys from from to to. The moved keys * are removed from from. * @param from the source * @param to the destination. It may be null */ public static void moveFields(PdfDictionary from, PdfDictionary to) { for (Iterator i = from.getKeys().iterator(); i.hasNext();) { PdfName key = (PdfName)i.next(); if (fieldKeys.containsKey(key)) { if (to != null) to.put(key, from.get(key)); i.remove(); } } } } src/core/com/lowagie/text/pdf/BaseFont.java100644 0 0 204116 11213370070 16270 0ustar 0 0 /* * $Id: BaseFont.java 3869 2009-04-17 18:03:45Z blowagie $ * * Copyright 2000-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.StringTokenizer; import com.lowagie.text.DocumentException; /** * Base class for the several font types supported * * @author Paulo Soares (psoares@consiste.pt) */ public abstract class BaseFont { /** This is a possible value of a base 14 type 1 font */ public static final String COURIER = "Courier"; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_BOLD = "Courier-Bold"; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_OBLIQUE = "Courier-Oblique"; /** This is a possible value of a base 14 type 1 font */ public static final String COURIER_BOLDOBLIQUE = "Courier-BoldOblique"; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA = "Helvetica"; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_BOLD = "Helvetica-Bold"; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_OBLIQUE = "Helvetica-Oblique"; /** This is a possible value of a base 14 type 1 font */ public static final String HELVETICA_BOLDOBLIQUE = "Helvetica-BoldOblique"; /** This is a possible value of a base 14 type 1 font */ public static final String SYMBOL = "Symbol"; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_ROMAN = "Times-Roman"; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_BOLD = "Times-Bold"; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_ITALIC = "Times-Italic"; /** This is a possible value of a base 14 type 1 font */ public static final String TIMES_BOLDITALIC = "Times-BoldItalic"; /** This is a possible value of a base 14 type 1 font */ public static final String ZAPFDINGBATS = "ZapfDingbats"; /** The maximum height above the baseline reached by glyphs in this * font, excluding the height of glyphs for accented characters. */ public static final int ASCENT = 1; /** The y coordinate of the top of flat capital letters, measured from * the baseline. */ public static final int CAPHEIGHT = 2; /** The maximum depth below the baseline reached by glyphs in this * font. The value is a negative number. */ public static final int DESCENT = 3; /** The angle, expressed in degrees counterclockwise from the vertical, * of the dominant vertical strokes of the font. The value is * negative for fonts that slope to the right, as almost all italic fonts do. */ public static final int ITALICANGLE = 4; /** The lower left x glyph coordinate. */ public static final int BBOXLLX = 5; /** The lower left y glyph coordinate. */ public static final int BBOXLLY = 6; /** The upper right x glyph coordinate. */ public static final int BBOXURX = 7; /** The upper right y glyph coordinate. */ public static final int BBOXURY = 8; /** java.awt.Font property */ public static final int AWT_ASCENT = 9; /** java.awt.Font property */ public static final int AWT_DESCENT = 10; /** java.awt.Font property */ public static final int AWT_LEADING = 11; /** java.awt.Font property */ public static final int AWT_MAXADVANCE = 12; /** * The underline position. Usually a negative value. */ public static final int UNDERLINE_POSITION = 13; /** * The underline thickness. */ public static final int UNDERLINE_THICKNESS = 14; /** * The strikethrough position. */ public static final int STRIKETHROUGH_POSITION = 15; /** * The strikethrough thickness. */ public static final int STRIKETHROUGH_THICKNESS = 16; /** * The recommended vertical size for subscripts for this font. */ public static final int SUBSCRIPT_SIZE = 17; /** * The recommended vertical offset from the baseline for subscripts for this font. Usually a negative value. */ public static final int SUBSCRIPT_OFFSET = 18; /** * The recommended vertical size for superscripts for this font. */ public static final int SUPERSCRIPT_SIZE = 19; /** * The recommended vertical offset from the baseline for superscripts for this font. */ public static final int SUPERSCRIPT_OFFSET = 20; /** The font is Type 1. */ public static final int FONT_TYPE_T1 = 0; /** The font is True Type with a standard encoding. */ public static final int FONT_TYPE_TT = 1; /** The font is CJK. */ public static final int FONT_TYPE_CJK = 2; /** The font is True Type with a Unicode encoding. */ public static final int FONT_TYPE_TTUNI = 3; /** A font already inside the document. */ public static final int FONT_TYPE_DOCUMENT = 4; /** A Type3 font. */ public static final int FONT_TYPE_T3 = 5; /** The Unicode encoding with horizontal writing. */ public static final String IDENTITY_H = "Identity-H"; /** The Unicode encoding with vertical writing. */ public static final String IDENTITY_V = "Identity-V"; /** A possible encoding. */ public static final String CP1250 = "Cp1250"; /** A possible encoding. */ public static final String CP1252 = "Cp1252"; /** A possible encoding. */ public static final String CP1257 = "Cp1257"; /** A possible encoding. */ public static final String WINANSI = "Cp1252"; /** A possible encoding. */ public static final String MACROMAN = "MacRoman"; public static final int[] CHAR_RANGE_LATIN = {0, 0x17f, 0x2000, 0x206f, 0x20a0, 0x20cf, 0xfb00, 0xfb06}; public static final int[] CHAR_RANGE_ARABIC = {0, 0x7f, 0x0600, 0x067f, 0x20a0, 0x20cf, 0xfb50, 0xfbff, 0xfe70, 0xfeff}; public static final int[] CHAR_RANGE_HEBREW = {0, 0x7f, 0x0590, 0x05ff, 0x20a0, 0x20cf, 0xfb1d, 0xfb4f}; public static final int[] CHAR_RANGE_CYRILLIC = {0, 0x7f, 0x0400, 0x052f, 0x2000, 0x206f, 0x20a0, 0x20cf}; /** if the font has to be embedded */ public static final boolean EMBEDDED = true; /** if the font doesn't have to be embedded */ public static final boolean NOT_EMBEDDED = false; /** if the font has to be cached */ public static final boolean CACHED = true; /** if the font doesn't have to be cached */ public static final boolean NOT_CACHED = false; /** The path to the font resources. */ public static final String RESOURCE_PATH = "com/lowagie/text/pdf/fonts/"; /** The fake CID code that represents a newline. */ public static final char CID_NEWLINE = '\u7fff'; protected ArrayList subsetRanges; /** The font type. */ int fontType; /** a not defined character in a custom PDF encoding */ public static final String notdef = ".notdef"; /** table of characters widths for this encoding */ protected int widths[] = new int[256]; /** encoding names */ protected String differences[] = new String[256]; /** same as differences but with the unicode codes */ protected char unicodeDifferences[] = new char[256]; protected int charBBoxes[][] = new int[256][]; /** encoding used with this font */ protected String encoding; /** true if the font is to be embedded in the PDF */ protected boolean embedded; /** * The compression level for the font stream. * @since 2.1.3 */ protected int compressionLevel = PdfStream.DEFAULT_COMPRESSION; /** * true if the font must use its built in encoding. In that case the * encoding is only used to map a char to the position inside * the font, not to the expected char name. */ protected boolean fontSpecific = true; /** cache for the fonts already used. */ protected static HashMap fontCache = new HashMap(); /** list of the 14 built in fonts. */ protected static final HashMap BuiltinFonts14 = new HashMap(); /** Forces the output of the width array. Only matters for the 14 * built-in fonts. */ protected boolean forceWidthsOutput = false; /** Converts char directly to byte * by casting. */ protected boolean directTextToByte = false; /** Indicates if all the glyphs and widths for that particular * encoding should be included in the document. */ protected boolean subset = true; protected boolean fastWinansi = false; /** * Custom encodings use this map to key the Unicode character * to the single byte code. */ protected IntHashtable specialMap; static { BuiltinFonts14.put(COURIER, PdfName.COURIER); BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD); BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE); BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE); BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA); BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD); BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE); BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE); BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL); BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN); BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD); BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC); BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC); BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS); } /** Generates the PDF stream with the Type1 and Truetype fonts returning * a PdfStream. */ static class StreamFont extends PdfStream { /** Generates the PDF stream with the Type1 and Truetype fonts returning * a PdfStream. * @param contents the content of the stream * @param lengths an array of int that describes the several lengths of each part of the font * @param compressionLevel the compression level of the Stream * @throws DocumentException error in the stream compression * @since 2.1.3 (replaces the constructor without param compressionLevel) */ public StreamFont(byte contents[], int lengths[], int compressionLevel) throws DocumentException { try { bytes = contents; put(PdfName.LENGTH, new PdfNumber(bytes.length)); for (int k = 0; k < lengths.length; ++k) { put(new PdfName("Length" + (k + 1)), new PdfNumber(lengths[k])); } flateCompress(compressionLevel); } catch (Exception e) { throw new DocumentException(e); } } /** * Generates the PDF stream for a font. * @param contents the content of a stream * @param subType the subtype of the font. * @param compressionLevel the compression level of the Stream * @throws DocumentException error in the stream compression * @since 2.1.3 (replaces the constructor without param compressionLevel) */ public StreamFont(byte contents[], String subType, int compressionLevel) throws DocumentException { try { bytes = contents; put(PdfName.LENGTH, new PdfNumber(bytes.length)); if (subType != null) put(PdfName.SUBTYPE, new PdfName(subType)); flateCompress(compressionLevel); } catch (Exception e) { throw new DocumentException(e); } } } /** *Creates new BaseFont */ protected BaseFont() { } /** * Creates a new font. This will always be the default Helvetica font (not embedded). * This method is introduced because Helvetica is used in many examples. * @return a BaseFont object (Helvetica, Winansi, not embedded) * @throws IOException This shouldn't occur ever * @throws DocumentException This shouldn't occur ever * @since 2.1.1 */ public static BaseFont createFont() throws DocumentException, IOException { return createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); } /** * Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An * example would be "STSong-Light,Bold". Note that this modifiers do not work if * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". * This would get the second font (indexes start at 0), in this case "MS PGothic". *

* The fonts are cached and if they already exist they are extracted from the cache, * not parsed again. *

* Besides the common encodings described by name, custom encodings * can also be made. These encodings will only work for the single byte fonts * Type1 and TrueType. The encoding string starts with a '#' * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list * of hex values representing the Unicode codes that compose that encoding.
* The "simple" encoding is recommended for TrueType fonts * as the "full" encoding risks not matching the character with the right glyph * if not done with care.
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be * described by non standard names like the Tex math fonts. Each group of three elements * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character * used to access the glyph. The space must be assigned to character position 32 otherwise * text justification will not work. *

* Example for a "simple" encoding that includes the Unicode * character space, A, B and ecyrillic: *

     * "# simple 32 0020 0041 0042 0454"
     * 
*

* Example for a "full" encoding for a Type1 Tex font: *

     * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
     * 
*

* This method calls:
*

     * createFont(name, encoding, embedded, true, null, null);
     * 
* @param name the name of the font or its location on file * @param encoding the encoding to be applied to this font * @param embedded true if the font is to be embedded in the PDF * @return returns a new font. This font may come from the cache * @throws DocumentException the font is invalid * @throws IOException the font file could not be read */ public static BaseFont createFont(String name, String encoding, boolean embedded) throws DocumentException, IOException { return createFont(name, encoding, embedded, true, null, null, false); } /** * Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An * example would be "STSong-Light,Bold". Note that this modifiers do not work if * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". * This would get the second font (indexes start at 0), in this case "MS PGothic". *

* The fonts are cached and if they already exist they are extracted from the cache, * not parsed again. *

* Besides the common encodings described by name, custom encodings * can also be made. These encodings will only work for the single byte fonts * Type1 and TrueType. The encoding string starts with a '#' * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list * of hex values representing the Unicode codes that compose that encoding.
* The "simple" encoding is recommended for TrueType fonts * as the "full" encoding risks not matching the character with the right glyph * if not done with care.
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be * described by non standard names like the Tex math fonts. Each group of three elements * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character * used to access the glyph. The space must be assigned to character position 32 otherwise * text justification will not work. *

* Example for a "simple" encoding that includes the Unicode * character space, A, B and ecyrillic: *

     * "# simple 32 0020 0041 0042 0454"
     * 
*

* Example for a "full" encoding for a Type1 Tex font: *

     * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
     * 
*

* This method calls:
*

     * createFont(name, encoding, embedded, true, null, null);
     * 
* @param name the name of the font or its location on file * @param encoding the encoding to be applied to this font * @param embedded true if the font is to be embedded in the PDF * @param forceRead in some cases (TrueTypeFont, Type1Font), the full font file will be read and kept in memory if forceRead is true * @return returns a new font. This font may come from the cache * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since 2.1.5 */ public static BaseFont createFont(String name, String encoding, boolean embedded, boolean forceRead) throws DocumentException, IOException { return createFont(name, encoding, embedded, true, null, null, forceRead); } /** Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An * example would be "STSong-Light,Bold". Note that this modifiers do not work if * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". * This would get the second font (indexes start at 0), in this case "MS PGothic". *

* The fonts may or may not be cached depending on the flag cached. * If the byte arrays are present the font will be * read from them instead of the name. A name is still required to identify * the font type. *

* Besides the common encodings described by name, custom encodings * can also be made. These encodings will only work for the single byte fonts * Type1 and TrueType. The encoding string starts with a '#' * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list * of hex values representing the Unicode codes that compose that encoding.
* The "simple" encoding is recommended for TrueType fonts * as the "full" encoding risks not matching the character with the right glyph * if not done with care.
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be * described by non standard names like the Tex math fonts. Each group of three elements * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character * used to access the glyph. The space must be assigned to character position 32 otherwise * text justification will not work. *

* Example for a "simple" encoding that includes the Unicode * character space, A, B and ecyrillic: *

     * "# simple 32 0020 0041 0042 0454"
     * 
*

* Example for a "full" encoding for a Type1 Tex font: *

     * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
     * 
* @param name the name of the font or its location on file * @param encoding the encoding to be applied to this font * @param embedded true if the font is to be embedded in the PDF * @param cached true if the font comes from the cache or is added to * the cache if new, false if the font is always created new * @param ttfAfm the true type font or the afm in a byte array * @param pfb the pfb in a byte array * @return returns a new font. This font may come from the cache but only if cached * is true, otherwise it will always be created new * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since iText 0.80 */ public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException { return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false); } /** Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An * example would be "STSong-Light,Bold". Note that this modifiers do not work if * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". * This would get the second font (indexes start at 0), in this case "MS PGothic". *

* The fonts may or may not be cached depending on the flag cached. * If the byte arrays are present the font will be * read from them instead of the name. A name is still required to identify * the font type. *

* Besides the common encodings described by name, custom encodings * can also be made. These encodings will only work for the single byte fonts * Type1 and TrueType. The encoding string starts with a '#' * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list * of hex values representing the Unicode codes that compose that encoding.
* The "simple" encoding is recommended for TrueType fonts * as the "full" encoding risks not matching the character with the right glyph * if not done with care.
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be * described by non standard names like the Tex math fonts. Each group of three elements * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character * used to access the glyph. The space must be assigned to character position 32 otherwise * text justification will not work. *

* Example for a "simple" encoding that includes the Unicode * character space, A, B and ecyrillic: *

     * "# simple 32 0020 0041 0042 0454"
     * 
*

* Example for a "full" encoding for a Type1 Tex font: *

     * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
     * 
* @param name the name of the font or its location on file * @param encoding the encoding to be applied to this font * @param embedded true if the font is to be embedded in the PDF * @param cached true if the font comes from the cache or is added to * the cache if new, false if the font is always created new * @param ttfAfm the true type font or the afm in a byte array * @param pfb the pfb in a byte array * @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw * an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances. * This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one * @return returns a new font. This font may come from the cache but only if cached * is true, otherwise it will always be created new * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since 2.0.3 */ public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow) throws DocumentException, IOException { return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false, false); } /** Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An * example would be "STSong-Light,Bold". Note that this modifiers do not work if * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". * This would get the second font (indexes start at 0), in this case "MS PGothic". *

* The fonts may or may not be cached depending on the flag cached. * If the byte arrays are present the font will be * read from them instead of the name. A name is still required to identify * the font type. *

* Besides the common encodings described by name, custom encodings * can also be made. These encodings will only work for the single byte fonts * Type1 and TrueType. The encoding string starts with a '#' * followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list * of hex values representing the Unicode codes that compose that encoding.
* The "simple" encoding is recommended for TrueType fonts * as the "full" encoding risks not matching the character with the right glyph * if not done with care.
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be * described by non standard names like the Tex math fonts. Each group of three elements * compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character * used to access the glyph. The space must be assigned to character position 32 otherwise * text justification will not work. *

* Example for a "simple" encoding that includes the Unicode * character space, A, B and ecyrillic: *

     * "# simple 32 0020 0041 0042 0454"
     * 
*

* Example for a "full" encoding for a Type1 Tex font: *

     * "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
     * 
* @param name the name of the font or its location on file * @param encoding the encoding to be applied to this font * @param embedded true if the font is to be embedded in the PDF * @param cached true if the font comes from the cache or is added to * the cache if new, false if the font is always created new * @param ttfAfm the true type font or the afm in a byte array * @param pfb the pfb in a byte array * @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw * an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances. * This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one * @param forceRead in some cases (TrueTypeFont, Type1Font), the full font file will be read and kept in memory if forceRead is true * @return returns a new font. This font may come from the cache but only if cached * is true, otherwise it will always be created new * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since 2.1.5 */ public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow, boolean forceRead) throws DocumentException, IOException { String nameBase = getBaseName(name); encoding = normalizeEncoding(encoding); boolean isBuiltinFonts14 = BuiltinFonts14.containsKey(name); boolean isCJKFont = isBuiltinFonts14 ? false : CJKFont.isCJKFont(nameBase, encoding); if (isBuiltinFonts14 || isCJKFont) embedded = false; else if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) embedded = true; BaseFont fontFound = null; BaseFont fontBuilt = null; String key = name + "\n" + encoding + "\n" + embedded; if (cached) { synchronized (fontCache) { fontFound = (BaseFont)fontCache.get(key); } if (fontFound != null) return fontFound; } if (isBuiltinFonts14 || name.toLowerCase().endsWith(".afm") || name.toLowerCase().endsWith(".pfm")) { fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb, forceRead); fontBuilt.fastWinansi = encoding.equals(CP1252); } else if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) { if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm, forceRead); else { fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm, false, forceRead); fontBuilt.fastWinansi = encoding.equals(CP1252); } } else if (isCJKFont) fontBuilt = new CJKFont(name, encoding, embedded); else if (noThrow) return null; else throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized."); if (cached) { synchronized (fontCache) { fontFound = (BaseFont)fontCache.get(key); if (fontFound != null) return fontFound; fontCache.put(key, fontBuilt); } } return fontBuilt; } /** * Creates a font based on an existing document font. The created font font may not * behave as expected, depending on the encoding or subset. * @param fontRef the reference to the document font * @return the font */ public static BaseFont createFont(PRIndirectReference fontRef) { return new DocumentFont(fontRef); } /** * Gets the name without the modifiers Bold, Italic or BoldItalic. * @param name the full name of the font * @return the name without the modifiers Bold, Italic or BoldItalic */ protected static String getBaseName(String name) { if (name.endsWith(",Bold")) return name.substring(0, name.length() - 5); else if (name.endsWith(",Italic")) return name.substring(0, name.length() - 7); else if (name.endsWith(",BoldItalic")) return name.substring(0, name.length() - 11); else return name; } /** * Normalize the encoding names. "winansi" is changed to "Cp1252" and * "macroman" is changed to "MacRoman". * @param enc the encoding to be normalized * @return the normalized encoding */ protected static String normalizeEncoding(String enc) { if (enc.equals("winansi") || enc.equals("")) return CP1252; else if (enc.equals("macroman")) return MACROMAN; else return enc; } /** * Creates the widths and the differences arrays */ protected void createEncoding() { if (encoding.startsWith("#")) { specialMap = new IntHashtable(); StringTokenizer tok = new StringTokenizer(encoding.substring(1), " ,\t\n\r\f"); if (tok.nextToken().equals("full")) { while (tok.hasMoreTokens()) { String order = tok.nextToken(); String name = tok.nextToken(); char uni = (char)Integer.parseInt(tok.nextToken(), 16); int orderK; if (order.startsWith("'")) orderK = order.charAt(1); else orderK = Integer.parseInt(order); orderK %= 256; specialMap.put(uni, orderK); differences[orderK] = name; unicodeDifferences[orderK] = uni; widths[orderK] = getRawWidth(uni, name); charBBoxes[orderK] = getRawCharBBox(uni, name); } } else { int k = 0; if (tok.hasMoreTokens()) k = Integer.parseInt(tok.nextToken()); while (tok.hasMoreTokens() && k < 256) { String hex = tok.nextToken(); int uni = Integer.parseInt(hex, 16) % 0x10000; String name = GlyphList.unicodeToName(uni); if (name != null) { specialMap.put(uni, k); differences[k] = name; unicodeDifferences[k] = (char)uni; widths[k] = getRawWidth(uni, name); charBBoxes[k] = getRawCharBBox(uni, name); ++k; } } } for (int k = 0; k < 256; ++k) { if (differences[k] == null) { differences[k] = notdef; } } } else if (fontSpecific) { for (int k = 0; k < 256; ++k) { widths[k] = getRawWidth(k, null); charBBoxes[k] = getRawCharBBox(k, null); } } else { String s; String name; char c; byte b[] = new byte[1]; for (int k = 0; k < 256; ++k) { b[0] = (byte)k; s = PdfEncodings.convertToString(b, encoding); if (s.length() > 0) { c = s.charAt(0); } else { c = '?'; } name = GlyphList.unicodeToName(c); if (name == null) name = notdef; differences[k] = name; unicodeDifferences[k] = c; widths[k] = getRawWidth(c, name); charBBoxes[k] = getRawCharBBox(c, name); } } } /** * Gets the width from the font according to the Unicode char c * or the name. If the name is null it's a symbolic font. * @param c the unicode char * @param name the glyph name * @return the width of the char */ abstract int getRawWidth(int c, String name); /** * Gets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @return the kerning to be applied in normalized 1000 units */ public abstract int getKerning(int char1, int char2); /** * Sets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @param kern the kerning to apply in normalized 1000 units * @return true if the kerning was applied, false otherwise */ public abstract boolean setKerning(int char1, int char2, int kern); /** * Gets the width of a char in normalized 1000 units. * @param char1 the unicode char to get the width of * @return the width in normalized 1000 units */ public int getWidth(int char1) { if (fastWinansi) { if (char1 < 128 || (char1 >= 160 && char1 <= 255)) return widths[char1]; else return widths[PdfEncodings.winansi.get(char1)]; } else { int total = 0; byte mbytes[] = convertToBytes((char)char1); for (int k = 0; k < mbytes.length; ++k) total += widths[0xff & mbytes[k]]; return total; } } /** * Gets the width of a String in normalized 1000 units. * @param text the String to get the width of * @return the width in normalized 1000 units */ public int getWidth(String text) { int total = 0; if (fastWinansi) { int len = text.length(); for (int k = 0; k < len; ++k) { char char1 = text.charAt(k); if (char1 < 128 || (char1 >= 160 && char1 <= 255)) total += widths[char1]; else total += widths[PdfEncodings.winansi.get(char1)]; } return total; } else { byte mbytes[] = convertToBytes(text); for (int k = 0; k < mbytes.length; ++k) total += widths[0xff & mbytes[k]]; } return total; } /** * Gets the descent of a String in normalized 1000 units. The descent will always be * less than or equal to zero even if all the characters have an higher descent. * @param text the String to get the descent of * @return the descent in normalized 1000 units */ public int getDescent(String text) { int min = 0; char chars[] = text.toCharArray(); for (int k = 0; k < chars.length; ++k) { int bbox[] = getCharBBox(chars[k]); if (bbox != null && bbox[1] < min) min = bbox[1]; } return min; } /** * Gets the ascent of a String in normalized 1000 units. The ascent will always be * greater than or equal to zero even if all the characters have a lower ascent. * @param text the String to get the ascent of * @return the ascent in normalized 1000 units */ public int getAscent(String text) { int max = 0; char chars[] = text.toCharArray(); for (int k = 0; k < chars.length; ++k) { int bbox[] = getCharBBox(chars[k]); if (bbox != null && bbox[3] > max) max = bbox[3]; } return max; } /** * Gets the descent of a String in points. The descent will always be * less than or equal to zero even if all the characters have an higher descent. * @param text the String to get the descent of * @param fontSize the size of the font * @return the descent in points */ public float getDescentPoint(String text, float fontSize) { return getDescent(text) * 0.001f * fontSize; } /** * Gets the ascent of a String in points. The ascent will always be * greater than or equal to zero even if all the characters have a lower ascent. * @param text the String to get the ascent of * @param fontSize the size of the font * @return the ascent in points */ public float getAscentPoint(String text, float fontSize) { return getAscent(text) * 0.001f * fontSize; } // ia> /** * Gets the width of a String in points taking kerning * into account. * @param text the String to get the width of * @param fontSize the font size * @return the width in points */ public float getWidthPointKerned(String text, float fontSize) { float size = getWidth(text) * 0.001f * fontSize; if (!hasKernPairs()) return size; int len = text.length() - 1; int kern = 0; char c[] = text.toCharArray(); for (int k = 0; k < len; ++k) { kern += getKerning(c[k], c[k + 1]); } return size + kern * 0.001f * fontSize; } /** * Gets the width of a String in points. * @param text the String to get the width of * @param fontSize the font size * @return the width in points */ public float getWidthPoint(String text, float fontSize) { return getWidth(text) * 0.001f * fontSize; } /** * Gets the width of a char in points. * @param char1 the char to get the width of * @param fontSize the font size * @return the width in points */ public float getWidthPoint(int char1, float fontSize) { return getWidth(char1) * 0.001f * fontSize; } /** * Converts a String to a byte array according * to the font's encoding. * @param text the String to be converted * @return an array of byte representing the conversion according to the font's encoding */ byte[] convertToBytes(String text) { if (directTextToByte) return PdfEncodings.convertToBytes(text, null); if (specialMap != null) { byte[] b = new byte[text.length()]; int ptr = 0; int length = text.length(); for (int k = 0; k < length; ++k) { char c = text.charAt(k); if (specialMap.containsKey(c)) b[ptr++] = (byte)specialMap.get(c); } if (ptr < length) { byte[] b2 = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } else return b; } return PdfEncodings.convertToBytes(text, encoding); } /** * Converts a char to a byte array according * to the font's encoding. * @param char1 the char to be converted * @return an array of byte representing the conversion according to the font's encoding */ byte[] convertToBytes(int char1) { if (directTextToByte) return PdfEncodings.convertToBytes((char)char1, null); if (specialMap != null) { if (specialMap.containsKey(char1)) return new byte[]{(byte)specialMap.get(char1)}; else return new byte[0]; } return PdfEncodings.convertToBytes((char)char1, encoding); } /** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param params several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ abstract void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException; /** * Returns a PdfStream object with the full font program (if possible). * This method will return null for some types of fonts (CJKFont, Type3Font) * or if there is no font program available (standard Type 1 fonts). * @return a PdfStream with the font program * @since 2.1.3 */ abstract PdfStream getFullFontStream() throws IOException, DocumentException; /** Gets the encoding used to convert String into byte[]. * @return the encoding name */ public String getEncoding() { return encoding; } /** Gets the font parameter identified by key. Valid values * for key are ASCENT, AWT_ASCENT, CAPHEIGHT, * DESCENT, AWT_DESCENT, * ITALICANGLE, BBOXLLX, BBOXLLY, BBOXURX * and BBOXURY. * @param key the parameter to be extracted * @param fontSize the font size in points * @return the parameter in points */ public abstract float getFontDescriptor(int key, float fontSize); /** Gets the font type. The font types can be: FONT_TYPE_T1, * FONT_TYPE_TT, FONT_TYPE_CJK and FONT_TYPE_TTUNI. * @return the font type */ public int getFontType() { return fontType; } /** Gets the embedded flag. * @return true if the font is embedded. */ public boolean isEmbedded() { return embedded; } /** Gets the symbolic flag of the font. * @return true if the font is symbolic */ public boolean isFontSpecific() { return fontSpecific; } /** Creates a unique subset prefix to be added to the font name when the font is embedded and subset. * @return the subset prefix */ public static String createSubsetPrefix() { String s = ""; for (int k = 0; k < 6; ++k) s += (char)(Math.random() * 26 + 'A'); return s + "+"; } /** Gets the Unicode character corresponding to the byte output to the pdf stream. * @param index the byte index * @return the Unicode character */ char getUnicodeDifferences(int index) { return unicodeDifferences[index]; } /** Gets the postscript font name. * @return the postscript font name */ public abstract String getPostscriptFontName(); /** * Sets the font name that will appear in the pdf font dictionary. * Use with care as it can easily make a font unreadable if not embedded. * @param name the new font name */ public abstract void setPostscriptFontName(String name); /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font */ public abstract String[][] getFullFontName(); /** Gets all the entries of the names-table. If it is a True Type font * each array element will have {Name ID, Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"4", "", "", "", * font name}. * @return the full name of the font * @since 2.0.8 */ public abstract String[][] getAllNameEntries(); /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @param name the name of the font * @param encoding the encoding of the font * @param ttfAfm the true type font or the afm in a byte array * @throws DocumentException on error * @throws IOException on error * @return the full name of the font */ public static String[][] getFullFontName(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { String nameBase = getBaseName(name); BaseFont fontBuilt = null; if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); else fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); return fontBuilt.getFullFontName(); } /** Gets all the names from the font. Only the required tables are read. * @param name the name of the font * @param encoding the encoding of the font * @param ttfAfm the true type font or the afm in a byte array * @throws DocumentException on error * @throws IOException on error * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()} */ public static Object[] getAllFontNames(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { String nameBase = getBaseName(name); BaseFont fontBuilt = null; if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); else fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); return new Object[]{fontBuilt.getPostscriptFontName(), fontBuilt.getFamilyFontName(), fontBuilt.getFullFontName()}; } /** Gets all the entries of the namestable from the font. Only the required tables are read. * @param name the name of the font * @param encoding the encoding of the font * @param ttfAfm the true type font or the afm in a byte array * @throws DocumentException on error * @throws IOException on error * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()} * @since 2.0.8 */ public static String[][] getAllNameEntries(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { String nameBase = getBaseName(name); BaseFont fontBuilt = null; if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true, false); else fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); return fontBuilt.getAllNameEntries(); } /** Gets the family name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the family name of the font */ public abstract String[][] getFamilyFontName(); /** Gets the code pages supported by the font. This has only meaning * with True Type fonts. * @return the code pages supported by the font */ public String[] getCodePagesSupported() { return new String[0]; } /** Enumerates the postscript font names present inside a * True Type Collection. * @param ttcFile the file name of the font * @throws DocumentException on error * @throws IOException on error * @return the postscript font names */ public static String[] enumerateTTCNames(String ttcFile) throws DocumentException, IOException { return new EnumerateTTC(ttcFile).getNames(); } /** Enumerates the postscript font names present inside a * True Type Collection. * @param ttcArray the font as a byte array * @throws DocumentException on error * @throws IOException on error * @return the postscript font names */ public static String[] enumerateTTCNames(byte ttcArray[]) throws DocumentException, IOException { return new EnumerateTTC(ttcArray).getNames(); } /** Gets the font width array. * @return the font width array */ public int[] getWidths() { return widths; } /** Gets the array with the names of the characters. * @return the array with the names of the characters */ public String[] getDifferences() { return differences; } /** Gets the array with the unicode characters. * @return the array with the unicode characters */ public char[] getUnicodeDifferences() { return unicodeDifferences; } /** Gets the state of the property. * @return value of property forceWidthsOutput */ public boolean isForceWidthsOutput() { return forceWidthsOutput; } /** Set to true to force the generation of the * widths array. * @param forceWidthsOutput true to force the generation of the * widths array */ public void setForceWidthsOutput(boolean forceWidthsOutput) { this.forceWidthsOutput = forceWidthsOutput; } /** Gets the direct conversion of char to byte. * @return value of property directTextToByte. * @see #setDirectTextToByte(boolean directTextToByte) */ public boolean isDirectTextToByte() { return directTextToByte; } /** Sets the conversion of char directly to byte * by casting. This is a low level feature to put the bytes directly in * the content stream without passing through String.getBytes(). * @param directTextToByte New value of property directTextToByte. */ public void setDirectTextToByte(boolean directTextToByte) { this.directTextToByte = directTextToByte; } /** Indicates if all the glyphs and widths for that particular * encoding should be included in the document. * @return false to include all the glyphs and widths. */ public boolean isSubset() { return subset; } /** Indicates if all the glyphs and widths for that particular * encoding should be included in the document. When set to true * only the glyphs used will be included in the font. When set to false * and {@link #addSubsetRange(int[])} was not called the full font will be included * otherwise just the characters ranges will be included. * @param subset new value of property subset */ public void setSubset(boolean subset) { this.subset = subset; } /** Gets the font resources. * @param key the full name of the resource * @return the InputStream to get the resource or * null if not found */ public static InputStream getResourceStream(String key) { return getResourceStream(key, null); } /** Gets the font resources. * @param key the full name of the resource * @param loader the ClassLoader to load the resource or null to try the ones available * @return the InputStream to get the resource or * null if not found */ public static InputStream getResourceStream(String key, ClassLoader loader) { if (key.startsWith("/")) key = key.substring(1); InputStream is = null; if (loader != null) { is = loader.getResourceAsStream(key); if (is != null) return is; } // Try to use Context Class Loader to load the properties file. try { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (contextClassLoader != null) { is = contextClassLoader.getResourceAsStream(key); } } catch (Throwable e) {} if (is == null) { is = BaseFont.class.getResourceAsStream("/" + key); } if (is == null) { is = ClassLoader.getSystemResourceAsStream(key); } return is; } /** Gets the Unicode equivalent to a CID. * The (inexistent) CID is translated as '\n'. * It has only meaning with CJK fonts with Identity encoding. * @param c the CID code * @return the Unicode equivalent */ public int getUnicodeEquivalent(int c) { return c; } /** Gets the CID code given an Unicode. * It has only meaning with CJK fonts. * @param c the Unicode * @return the CID equivalent */ public int getCidCode(int c) { return c; } /** Checks if the font has any kerning pairs. * @return true if the font has any kerning pairs */ public abstract boolean hasKernPairs(); /** * Checks if a character exists in this font. * @param c the character to check * @return true if the character has a glyph, * false otherwise */ public boolean charExists(int c) { byte b[] = convertToBytes(c); return b.length > 0; } /** * Sets the character advance. * @param c the character * @param advance the character advance normalized to 1000 units * @return true if the advance was set, * false otherwise */ public boolean setCharAdvance(int c, int advance) { byte b[] = convertToBytes(c); if (b.length == 0) return false; widths[0xff & b[0]] = advance; return true; } private static void addFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts) { PdfObject obj = PdfReader.getPdfObject(fontRef); if (obj == null || !obj.isDictionary()) return; PdfDictionary font = (PdfDictionary)obj; PdfName subtype = font.getAsName(PdfName.SUBTYPE); if (!PdfName.TYPE1.equals(subtype) && !PdfName.TRUETYPE.equals(subtype)) return; PdfName name = font.getAsName(PdfName.BASEFONT); fonts.add(new Object[]{PdfName.decodeName(name.toString()), fontRef}); hits.put(fontRef.getNumber(), 1); } private static void recourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level) { ++level; if (level > 50) // in case we have an endless loop return; PdfDictionary resources = page.getAsDict(PdfName.RESOURCES); if (resources == null) return; PdfDictionary font = resources.getAsDict(PdfName.FONT); if (font != null) { for (Iterator it = font.getKeys().iterator(); it.hasNext();) { PdfObject ft = font.get((PdfName)it.next()); if (ft == null || !ft.isIndirect()) continue; int hit = ((PRIndirectReference)ft).getNumber(); if (hits.containsKey(hit)) continue; addFont((PRIndirectReference)ft, hits, fonts); } } PdfDictionary xobj = resources.getAsDict(PdfName.XOBJECT); if (xobj != null) { for (Iterator it = xobj.getKeys().iterator(); it.hasNext();) { recourseFonts(xobj.getAsDict((PdfName)it.next()), hits, fonts, level); } } } /** * Gets a list of all document fonts. Each element of the ArrayList * contains a Object[]{String,PRIndirectReference} with the font name * and the indirect reference to it. * @param reader the document where the fonts are to be listed from * @return the list of fonts and references */ public static ArrayList getDocumentFonts(PdfReader reader) { IntHashtable hits = new IntHashtable(); ArrayList fonts = new ArrayList(); int npages = reader.getNumberOfPages(); for (int k = 1; k <= npages; ++k) recourseFonts(reader.getPageN(k), hits, fonts, 1); return fonts; } /** * Gets a list of the document fonts in a particular page. Each element of the ArrayList * contains a Object[]{String,PRIndirectReference} with the font name * and the indirect reference to it. * @param reader the document where the fonts are to be listed from * @param page the page to list the fonts from * @return the list of fonts and references */ public static ArrayList getDocumentFonts(PdfReader reader, int page) { IntHashtable hits = new IntHashtable(); ArrayList fonts = new ArrayList(); recourseFonts(reader.getPageN(page), hits, fonts, 1); return fonts; } /** * Gets the smallest box enclosing the character contours. It will return * null if the font has not the information or the character has no * contours, as in the case of the space, for example. Characters with no contours may * also return [0,0,0,0]. * @param c the character to get the contour bounding box from * @return an array of four floats with the bounding box in the format [llx,lly,urx,ury] or * null */ public int[] getCharBBox(int c) { byte b[] = convertToBytes(c); if (b.length == 0) return null; else return charBBoxes[b[0] & 0xff]; } protected abstract int[] getRawCharBBox(int c, String name); /** * iText expects Arabic Diactrics (tashkeel) to have zero advance but some fonts, * most notably those that come with Windows, like times.ttf, have non-zero * advance for those characters. This method makes those character to have zero * width advance and work correctly in the iText Arabic shaping and reordering * context. */ public void correctArabicAdvance() { for (char c = '\u064b'; c <= '\u0658'; ++c) setCharAdvance(c, 0); setCharAdvance('\u0670', 0); for (char c = '\u06d6'; c <= '\u06dc'; ++c) setCharAdvance(c, 0); for (char c = '\u06df'; c <= '\u06e4'; ++c) setCharAdvance(c, 0); for (char c = '\u06e7'; c <= '\u06e8'; ++c) setCharAdvance(c, 0); for (char c = '\u06ea'; c <= '\u06ed'; ++c) setCharAdvance(c, 0); } /** * Adds a character range when subsetting. The range is an int array * where the first element is the start range inclusive and the second element is the * end range inclusive. Several ranges are allowed in the same array. * @param range the character range */ public void addSubsetRange(int[] range) { if (subsetRanges == null) subsetRanges = new ArrayList(); subsetRanges.add(range); } /** * Returns the compression level used for the font streams. * @return the compression level (0 = best speed, 9 = best compression, -1 is default) * @since 2.1.3 */ public int getCompressionLevel() { return compressionLevel; } /** * Sets the compression level to be used for the font streams. * @param compressionLevel a value between 0 (best speed) and 9 (best compression) * @since 2.1.3 */ public void setCompressionLevel(int compressionLevel) { if (compressionLevel < PdfStream.NO_COMPRESSION || compressionLevel > PdfStream.BEST_COMPRESSION) this.compressionLevel = PdfStream.DEFAULT_COMPRESSION; else this.compressionLevel = compressionLevel; } } src/core/com/lowagie/text/pdf/BidiLine.java100644 0 0 136135 11012562273 16260 0ustar 0 0 /* * * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.Utilities; /** Does all the line bidirectional processing with PdfChunk assembly. * * @author Paulo Soares (psoares@consiste.pt) */ public class BidiLine { protected int runDirection; protected int pieceSize = 256; protected char text[] = new char[pieceSize]; protected PdfChunk detailChunks[] = new PdfChunk[pieceSize]; protected int totalTextLength = 0; protected byte orderLevels[] = new byte[pieceSize]; protected int indexChars[] = new int[pieceSize]; protected ArrayList chunks = new ArrayList(); protected int indexChunk = 0; protected int indexChunkChar = 0; protected int currentChar = 0; protected int storedRunDirection; protected char storedText[] = new char[0]; protected PdfChunk storedDetailChunks[] = new PdfChunk[0]; protected int storedTotalTextLength = 0; protected byte storedOrderLevels[] = new byte[0]; protected int storedIndexChars[] = new int[0]; protected int storedIndexChunk = 0; protected int storedIndexChunkChar = 0; protected int storedCurrentChar = 0; protected boolean shortStore; // protected ArabicShaping arabic = new ArabicShaping(ArabicShaping.LETTERS_SHAPE | ArabicShaping.LENGTH_GROW_SHRINK | ArabicShaping.TEXT_DIRECTION_LOGICAL); protected static final IntHashtable mirrorChars = new IntHashtable(); protected int arabicOptions; /** Creates new BidiLine */ public BidiLine() { } public BidiLine(BidiLine org) { runDirection = org.runDirection; pieceSize = org.pieceSize; text = (char[])org.text.clone(); detailChunks = (PdfChunk[])org.detailChunks.clone(); totalTextLength = org.totalTextLength; orderLevels = (byte[])org.orderLevels.clone(); indexChars = (int[])org.indexChars.clone(); chunks = new ArrayList(org.chunks); indexChunk = org.indexChunk; indexChunkChar = org.indexChunkChar; currentChar = org.currentChar; storedRunDirection = org.storedRunDirection; storedText = (char[])org.storedText.clone(); storedDetailChunks = (PdfChunk[])org.storedDetailChunks.clone(); storedTotalTextLength = org.storedTotalTextLength; storedOrderLevels = (byte[])org.storedOrderLevels.clone(); storedIndexChars = (int[])org.storedIndexChars.clone(); storedIndexChunk = org.storedIndexChunk; storedIndexChunkChar = org.storedIndexChunkChar; storedCurrentChar = org.storedCurrentChar; shortStore = org.shortStore; arabicOptions = org.arabicOptions; } public boolean isEmpty() { return (currentChar >= totalTextLength && indexChunk >= chunks.size()); } public void clearChunks() { chunks.clear(); totalTextLength = 0; currentChar = 0; } public boolean getParagraph(int runDirection) { this.runDirection = runDirection; currentChar = 0; totalTextLength = 0; boolean hasText = false; char c; char uniC; BaseFont bf; for (; indexChunk < chunks.size(); ++indexChunk) { PdfChunk ck = (PdfChunk)chunks.get(indexChunk); bf = ck.font().getFont(); String s = ck.toString(); int len = s.length(); for (; indexChunkChar < len; ++indexChunkChar) { c = s.charAt(indexChunkChar); uniC = (char)bf.getUnicodeEquivalent(c); if (uniC == '\r' || uniC == '\n') { // next condition is never true for CID if (uniC == '\r' && indexChunkChar + 1 < len && s.charAt(indexChunkChar + 1) == '\n') ++indexChunkChar; ++indexChunkChar; if (indexChunkChar >= len) { indexChunkChar = 0; ++indexChunk; } hasText = true; if (totalTextLength == 0) detailChunks[0] = ck; break; } addPiece(c, ck); } if (hasText) break; indexChunkChar = 0; } if (totalTextLength == 0) return hasText; // remove trailing WS totalTextLength = trimRight(0, totalTextLength - 1) + 1; if (totalTextLength == 0) { return true; } if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { if (orderLevels.length < totalTextLength) { orderLevels = new byte[pieceSize]; indexChars = new int[pieceSize]; } ArabicLigaturizer.processNumbers(text, 0, totalTextLength, arabicOptions); BidiOrder order = new BidiOrder(text, 0, totalTextLength, (byte)(runDirection == PdfWriter.RUN_DIRECTION_RTL ? 1 : 0)); byte od[] = order.getLevels(); for (int k = 0; k < totalTextLength; ++k) { orderLevels[k] = od[k]; indexChars[k] = k; } doArabicShapping(); mirrorGlyphs(); } totalTextLength = trimRightEx(0, totalTextLength - 1) + 1; return true; } public void addChunk(PdfChunk chunk) { chunks.add(chunk); } public void addChunks(ArrayList chunks) { this.chunks.addAll(chunks); } public void addPiece(char c, PdfChunk chunk) { if (totalTextLength >= pieceSize) { char tempText[] = text; PdfChunk tempDetailChunks[] = detailChunks; pieceSize *= 2; text = new char[pieceSize]; detailChunks = new PdfChunk[pieceSize]; System.arraycopy(tempText, 0, text, 0, totalTextLength); System.arraycopy(tempDetailChunks, 0, detailChunks, 0, totalTextLength); } text[totalTextLength] = c; detailChunks[totalTextLength++] = chunk; } public void save() { if (indexChunk > 0) { if (indexChunk >= chunks.size()) chunks.clear(); else { for (--indexChunk; indexChunk >= 0; --indexChunk) chunks.remove(indexChunk); } indexChunk = 0; } storedRunDirection = runDirection; storedTotalTextLength = totalTextLength; storedIndexChunk = indexChunk; storedIndexChunkChar = indexChunkChar; storedCurrentChar = currentChar; shortStore = (currentChar < totalTextLength); if (!shortStore) { // long save if (storedText.length < totalTextLength) { storedText = new char[totalTextLength]; storedDetailChunks = new PdfChunk[totalTextLength]; } System.arraycopy(text, 0, storedText, 0, totalTextLength); System.arraycopy(detailChunks, 0, storedDetailChunks, 0, totalTextLength); } if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { if (storedOrderLevels.length < totalTextLength) { storedOrderLevels = new byte[totalTextLength]; storedIndexChars = new int[totalTextLength]; } System.arraycopy(orderLevels, currentChar, storedOrderLevels, currentChar, totalTextLength - currentChar); System.arraycopy(indexChars, currentChar, storedIndexChars, currentChar, totalTextLength - currentChar); } } public void restore() { runDirection = storedRunDirection; totalTextLength = storedTotalTextLength; indexChunk = storedIndexChunk; indexChunkChar = storedIndexChunkChar; currentChar = storedCurrentChar; if (!shortStore) { // long restore System.arraycopy(storedText, 0, text, 0, totalTextLength); System.arraycopy(storedDetailChunks, 0, detailChunks, 0, totalTextLength); } if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { System.arraycopy(storedOrderLevels, currentChar, orderLevels, currentChar, totalTextLength - currentChar); System.arraycopy(storedIndexChars, currentChar, indexChars, currentChar, totalTextLength - currentChar); } } public void mirrorGlyphs() { for (int k = 0; k < totalTextLength; ++k) { if ((orderLevels[k] & 1) == 1) { int mirror = mirrorChars.get(text[k]); if (mirror != 0) text[k] = (char)mirror; } } } public void doArabicShapping() { int src = 0; int dest = 0; for (;;) { while (src < totalTextLength) { char c = text[src]; if (c >= 0x0600 && c <= 0x06ff) break; if (src != dest) { text[dest] = text[src]; detailChunks[dest] = detailChunks[src]; orderLevels[dest] = orderLevels[src]; } ++src; ++dest; } if (src >= totalTextLength) { totalTextLength = dest; return; } int startArabicIdx = src; ++src; while (src < totalTextLength) { char c = text[src]; if (c < 0x0600 || c > 0x06ff) break; ++src; } int arabicWordSize = src - startArabicIdx; int size = ArabicLigaturizer.arabic_shape(text, startArabicIdx, arabicWordSize, text, dest, arabicWordSize, arabicOptions); if (startArabicIdx != dest) { for (int k = 0; k < size; ++k) { detailChunks[dest] = detailChunks[startArabicIdx]; orderLevels[dest++] = orderLevels[startArabicIdx++]; } } else dest += size; } } public PdfLine processLine(float leftX, float width, int alignment, int runDirection, int arabicOptions) { this.arabicOptions = arabicOptions; save(); boolean isRTL = (runDirection == PdfWriter.RUN_DIRECTION_RTL); if (currentChar >= totalTextLength) { boolean hasText = getParagraph(runDirection); if (!hasText) return null; if (totalTextLength == 0) { ArrayList ar = new ArrayList(); PdfChunk ck = new PdfChunk("", detailChunks[0]); ar.add(ck); return new PdfLine(0, 0, 0, alignment, true, ar, isRTL); } } float originalWidth = width; int lastSplit = -1; if (currentChar != 0) currentChar = trimLeftEx(currentChar, totalTextLength - 1); int oldCurrentChar = currentChar; int uniC = 0; PdfChunk ck = null; float charWidth = 0; PdfChunk lastValidChunk = null; boolean splitChar = false; boolean surrogate = false; for (; currentChar < totalTextLength; ++currentChar) { ck = detailChunks[currentChar]; surrogate = Utilities.isSurrogatePair(text, currentChar); if (surrogate) uniC = ck.getUnicodeEquivalent(Utilities.convertToUtf32(text, currentChar)); else uniC = ck.getUnicodeEquivalent(text[currentChar]); if (PdfChunk.noPrint(uniC)) continue; if (surrogate) charWidth = ck.getCharWidth(uniC); else charWidth = ck.getCharWidth(text[currentChar]); splitChar = ck.isExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks); if (splitChar && Character.isWhitespace((char)uniC)) lastSplit = currentChar; if (width - charWidth < 0) break; if (splitChar) lastSplit = currentChar; width -= charWidth; lastValidChunk = ck; if (ck.isTab()) { Object[] tab = (Object[])ck.getAttribute(Chunk.TAB); float tabPosition = ((Float)tab[1]).floatValue(); boolean newLine = ((Boolean)tab[2]).booleanValue(); if (newLine && tabPosition < originalWidth - width) { return new PdfLine(0, originalWidth, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL); } detailChunks[currentChar].adjustLeft(leftX); width = originalWidth - tabPosition; } if (surrogate) ++currentChar; } if (lastValidChunk == null) { // not even a single char fit; must output the first char ++currentChar; if (surrogate) ++currentChar; return new PdfLine(0, originalWidth, 0, alignment, false, createArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL); } if (currentChar >= totalTextLength) { // there was more line than text return new PdfLine(0, originalWidth, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL); } int newCurrentChar = trimRightEx(oldCurrentChar, currentChar - 1); if (newCurrentChar < oldCurrentChar) { // only WS return new PdfLine(0, originalWidth, width, alignment, false, createArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL); } if (newCurrentChar == currentChar - 1) { // middle of word HyphenationEvent he = (HyphenationEvent)lastValidChunk.getAttribute(Chunk.HYPHENATION); if (he != null) { int word[] = getWord(oldCurrentChar, newCurrentChar); if (word != null) { float testWidth = width + getWidth(word[0], currentChar - 1); String pre = he.getHyphenatedWordPre(new String(text, word[0], word[1] - word[0]), lastValidChunk.font().getFont(), lastValidChunk.font().size(), testWidth); String post = he.getHyphenatedWordPost(); if (pre.length() > 0) { PdfChunk extra = new PdfChunk(pre, lastValidChunk); currentChar = word[1] - post.length(); return new PdfLine(0, originalWidth, testWidth - lastValidChunk.font().width(pre), alignment, false, createArrayOfPdfChunks(oldCurrentChar, word[0] - 1, extra), isRTL); } } } } if (lastSplit == -1 || lastSplit >= newCurrentChar) { // no split point or split point ahead of end return new PdfLine(0, originalWidth, width + getWidth(newCurrentChar + 1, currentChar - 1), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); } // standard split currentChar = lastSplit + 1; newCurrentChar = trimRightEx(oldCurrentChar, lastSplit); if (newCurrentChar < oldCurrentChar) { // only WS again newCurrentChar = currentChar - 1; } return new PdfLine(0, originalWidth, originalWidth - getWidth(oldCurrentChar, newCurrentChar), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); } /** Gets the width of a range of characters. * @param startIdx the first index to calculate * @param lastIdx the last inclusive index to calculate * @return the sum of all widths */ public float getWidth(int startIdx, int lastIdx) { char c = 0; char uniC; PdfChunk ck = null; float width = 0; for (; startIdx <= lastIdx; ++startIdx) { boolean surrogate = Utilities.isSurrogatePair(text, startIdx); if (surrogate) { width += detailChunks[startIdx].getCharWidth(Utilities.convertToUtf32(text, startIdx)); ++startIdx; } else { c = text[startIdx]; ck = detailChunks[startIdx]; if (PdfChunk.noPrint(ck.getUnicodeEquivalent(c))) continue; width += detailChunks[startIdx].getCharWidth(c); } } return width; } public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx) { return createArrayOfPdfChunks(startIdx, endIdx, null); } public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx, PdfChunk extraPdfChunk) { boolean bidi = (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL); if (bidi) reorder(startIdx, endIdx); ArrayList ar = new ArrayList(); PdfChunk refCk = detailChunks[startIdx]; PdfChunk ck = null; StringBuffer buf = new StringBuffer(); char c; int idx = 0; for (; startIdx <= endIdx; ++startIdx) { idx = bidi ? indexChars[startIdx] : startIdx; c = text[idx]; ck = detailChunks[idx]; if (PdfChunk.noPrint(ck.getUnicodeEquivalent(c))) continue; if (ck.isImage() || ck.isSeparator() || ck.isTab()) { if (buf.length() > 0) { ar.add(new PdfChunk(buf.toString(), refCk)); buf = new StringBuffer(); } ar.add(ck); } else if (ck == refCk) { buf.append(c); } else { if (buf.length() > 0) { ar.add(new PdfChunk(buf.toString(), refCk)); buf = new StringBuffer(); } if (!ck.isImage() && !ck.isSeparator() && !ck.isTab()) buf.append(c); refCk = ck; } } if (buf.length() > 0) { ar.add(new PdfChunk(buf.toString(), refCk)); } if (extraPdfChunk != null) ar.add(extraPdfChunk); return ar; } public int[] getWord(int startIdx, int idx) { int last = idx; int first = idx; // forward for (; last < totalTextLength; ++last) { if (!Character.isLetter(text[last])) break; } if (last == idx) return null; // backward for (; first >= startIdx; --first) { if (!Character.isLetter(text[first])) break; } ++first; return new int[]{first, last}; } public int trimRight(int startIdx, int endIdx) { int idx = endIdx; char c; for (; idx >= startIdx; --idx) { c = (char)detailChunks[idx].getUnicodeEquivalent(text[idx]); if (!isWS(c)) break; } return idx; } public int trimLeft(int startIdx, int endIdx) { int idx = startIdx; char c; for (; idx <= endIdx; ++idx) { c = (char)detailChunks[idx].getUnicodeEquivalent(text[idx]); if (!isWS(c)) break; } return idx; } public int trimRightEx(int startIdx, int endIdx) { int idx = endIdx; char c = 0; for (; idx >= startIdx; --idx) { c = (char)detailChunks[idx].getUnicodeEquivalent(text[idx]); if (!isWS(c) && !PdfChunk.noPrint(c)) break; } return idx; } public int trimLeftEx(int startIdx, int endIdx) { int idx = startIdx; char c = 0; for (; idx <= endIdx; ++idx) { c = (char)detailChunks[idx].getUnicodeEquivalent(text[idx]); if (!isWS(c) && !PdfChunk.noPrint(c)) break; } return idx; } public void reorder(int start, int end) { byte maxLevel = orderLevels[start]; byte minLevel = maxLevel; byte onlyOddLevels = maxLevel; byte onlyEvenLevels = maxLevel; for (int k = start + 1; k <= end; ++k) { byte b = orderLevels[k]; if (b > maxLevel) maxLevel = b; else if (b < minLevel) minLevel = b; onlyOddLevels &= b; onlyEvenLevels |= b; } if ((onlyEvenLevels & 1) == 0) // nothing to do return; if ((onlyOddLevels & 1) == 1) { // single inversion flip(start, end + 1); return; } minLevel |= 1; for (; maxLevel >= minLevel; --maxLevel) { int pstart = start; for (;;) { for (;pstart <= end; ++pstart) { if (orderLevels[pstart] >= maxLevel) break; } if (pstart > end) break; int pend = pstart + 1; for (; pend <= end; ++pend) { if (orderLevels[pend] < maxLevel) break; } flip(pstart, pend); pstart = pend + 1; } } } public void flip(int start, int end) { int mid = (start + end) / 2; --end; for (; start < mid; ++start, --end) { int temp = indexChars[start]; indexChars[start] = indexChars[end]; indexChars[end] = temp; } } public static boolean isWS(char c) { return (c <= ' '); } static { mirrorChars.put(0x0028, 0x0029); // LEFT PARENTHESIS mirrorChars.put(0x0029, 0x0028); // RIGHT PARENTHESIS mirrorChars.put(0x003C, 0x003E); // LESS-THAN SIGN mirrorChars.put(0x003E, 0x003C); // GREATER-THAN SIGN mirrorChars.put(0x005B, 0x005D); // LEFT SQUARE BRACKET mirrorChars.put(0x005D, 0x005B); // RIGHT SQUARE BRACKET mirrorChars.put(0x007B, 0x007D); // LEFT CURLY BRACKET mirrorChars.put(0x007D, 0x007B); // RIGHT CURLY BRACKET mirrorChars.put(0x00AB, 0x00BB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK mirrorChars.put(0x00BB, 0x00AB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK mirrorChars.put(0x2039, 0x203A); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK mirrorChars.put(0x203A, 0x2039); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK mirrorChars.put(0x2045, 0x2046); // LEFT SQUARE BRACKET WITH QUILL mirrorChars.put(0x2046, 0x2045); // RIGHT SQUARE BRACKET WITH QUILL mirrorChars.put(0x207D, 0x207E); // SUPERSCRIPT LEFT PARENTHESIS mirrorChars.put(0x207E, 0x207D); // SUPERSCRIPT RIGHT PARENTHESIS mirrorChars.put(0x208D, 0x208E); // SUBSCRIPT LEFT PARENTHESIS mirrorChars.put(0x208E, 0x208D); // SUBSCRIPT RIGHT PARENTHESIS mirrorChars.put(0x2208, 0x220B); // ELEMENT OF mirrorChars.put(0x2209, 0x220C); // NOT AN ELEMENT OF mirrorChars.put(0x220A, 0x220D); // SMALL ELEMENT OF mirrorChars.put(0x220B, 0x2208); // CONTAINS AS MEMBER mirrorChars.put(0x220C, 0x2209); // DOES NOT CONTAIN AS MEMBER mirrorChars.put(0x220D, 0x220A); // SMALL CONTAINS AS MEMBER mirrorChars.put(0x2215, 0x29F5); // DIVISION SLASH mirrorChars.put(0x223C, 0x223D); // TILDE OPERATOR mirrorChars.put(0x223D, 0x223C); // REVERSED TILDE mirrorChars.put(0x2243, 0x22CD); // ASYMPTOTICALLY EQUAL TO mirrorChars.put(0x2252, 0x2253); // APPROXIMATELY EQUAL TO OR THE IMAGE OF mirrorChars.put(0x2253, 0x2252); // IMAGE OF OR APPROXIMATELY EQUAL TO mirrorChars.put(0x2254, 0x2255); // COLON EQUALS mirrorChars.put(0x2255, 0x2254); // EQUALS COLON mirrorChars.put(0x2264, 0x2265); // LESS-THAN OR EQUAL TO mirrorChars.put(0x2265, 0x2264); // GREATER-THAN OR EQUAL TO mirrorChars.put(0x2266, 0x2267); // LESS-THAN OVER EQUAL TO mirrorChars.put(0x2267, 0x2266); // GREATER-THAN OVER EQUAL TO mirrorChars.put(0x2268, 0x2269); // [BEST FIT] LESS-THAN BUT NOT EQUAL TO mirrorChars.put(0x2269, 0x2268); // [BEST FIT] GREATER-THAN BUT NOT EQUAL TO mirrorChars.put(0x226A, 0x226B); // MUCH LESS-THAN mirrorChars.put(0x226B, 0x226A); // MUCH GREATER-THAN mirrorChars.put(0x226E, 0x226F); // [BEST FIT] NOT LESS-THAN mirrorChars.put(0x226F, 0x226E); // [BEST FIT] NOT GREATER-THAN mirrorChars.put(0x2270, 0x2271); // [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO mirrorChars.put(0x2271, 0x2270); // [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO mirrorChars.put(0x2272, 0x2273); // [BEST FIT] LESS-THAN OR EQUIVALENT TO mirrorChars.put(0x2273, 0x2272); // [BEST FIT] GREATER-THAN OR EQUIVALENT TO mirrorChars.put(0x2274, 0x2275); // [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO mirrorChars.put(0x2275, 0x2274); // [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO mirrorChars.put(0x2276, 0x2277); // LESS-THAN OR GREATER-THAN mirrorChars.put(0x2277, 0x2276); // GREATER-THAN OR LESS-THAN mirrorChars.put(0x2278, 0x2279); // NEITHER LESS-THAN NOR GREATER-THAN mirrorChars.put(0x2279, 0x2278); // NEITHER GREATER-THAN NOR LESS-THAN mirrorChars.put(0x227A, 0x227B); // PRECEDES mirrorChars.put(0x227B, 0x227A); // SUCCEEDS mirrorChars.put(0x227C, 0x227D); // PRECEDES OR EQUAL TO mirrorChars.put(0x227D, 0x227C); // SUCCEEDS OR EQUAL TO mirrorChars.put(0x227E, 0x227F); // [BEST FIT] PRECEDES OR EQUIVALENT TO mirrorChars.put(0x227F, 0x227E); // [BEST FIT] SUCCEEDS OR EQUIVALENT TO mirrorChars.put(0x2280, 0x2281); // [BEST FIT] DOES NOT PRECEDE mirrorChars.put(0x2281, 0x2280); // [BEST FIT] DOES NOT SUCCEED mirrorChars.put(0x2282, 0x2283); // SUBSET OF mirrorChars.put(0x2283, 0x2282); // SUPERSET OF mirrorChars.put(0x2284, 0x2285); // [BEST FIT] NOT A SUBSET OF mirrorChars.put(0x2285, 0x2284); // [BEST FIT] NOT A SUPERSET OF mirrorChars.put(0x2286, 0x2287); // SUBSET OF OR EQUAL TO mirrorChars.put(0x2287, 0x2286); // SUPERSET OF OR EQUAL TO mirrorChars.put(0x2288, 0x2289); // [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO mirrorChars.put(0x2289, 0x2288); // [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO mirrorChars.put(0x228A, 0x228B); // [BEST FIT] SUBSET OF WITH NOT EQUAL TO mirrorChars.put(0x228B, 0x228A); // [BEST FIT] SUPERSET OF WITH NOT EQUAL TO mirrorChars.put(0x228F, 0x2290); // SQUARE IMAGE OF mirrorChars.put(0x2290, 0x228F); // SQUARE ORIGINAL OF mirrorChars.put(0x2291, 0x2292); // SQUARE IMAGE OF OR EQUAL TO mirrorChars.put(0x2292, 0x2291); // SQUARE ORIGINAL OF OR EQUAL TO mirrorChars.put(0x2298, 0x29B8); // CIRCLED DIVISION SLASH mirrorChars.put(0x22A2, 0x22A3); // RIGHT TACK mirrorChars.put(0x22A3, 0x22A2); // LEFT TACK mirrorChars.put(0x22A6, 0x2ADE); // ASSERTION mirrorChars.put(0x22A8, 0x2AE4); // TRUE mirrorChars.put(0x22A9, 0x2AE3); // FORCES mirrorChars.put(0x22AB, 0x2AE5); // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE mirrorChars.put(0x22B0, 0x22B1); // PRECEDES UNDER RELATION mirrorChars.put(0x22B1, 0x22B0); // SUCCEEDS UNDER RELATION mirrorChars.put(0x22B2, 0x22B3); // NORMAL SUBGROUP OF mirrorChars.put(0x22B3, 0x22B2); // CONTAINS AS NORMAL SUBGROUP mirrorChars.put(0x22B4, 0x22B5); // NORMAL SUBGROUP OF OR EQUAL TO mirrorChars.put(0x22B5, 0x22B4); // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO mirrorChars.put(0x22B6, 0x22B7); // ORIGINAL OF mirrorChars.put(0x22B7, 0x22B6); // IMAGE OF mirrorChars.put(0x22C9, 0x22CA); // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT mirrorChars.put(0x22CA, 0x22C9); // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT mirrorChars.put(0x22CB, 0x22CC); // LEFT SEMIDIRECT PRODUCT mirrorChars.put(0x22CC, 0x22CB); // RIGHT SEMIDIRECT PRODUCT mirrorChars.put(0x22CD, 0x2243); // REVERSED TILDE EQUALS mirrorChars.put(0x22D0, 0x22D1); // DOUBLE SUBSET mirrorChars.put(0x22D1, 0x22D0); // DOUBLE SUPERSET mirrorChars.put(0x22D6, 0x22D7); // LESS-THAN WITH DOT mirrorChars.put(0x22D7, 0x22D6); // GREATER-THAN WITH DOT mirrorChars.put(0x22D8, 0x22D9); // VERY MUCH LESS-THAN mirrorChars.put(0x22D9, 0x22D8); // VERY MUCH GREATER-THAN mirrorChars.put(0x22DA, 0x22DB); // LESS-THAN EQUAL TO OR GREATER-THAN mirrorChars.put(0x22DB, 0x22DA); // GREATER-THAN EQUAL TO OR LESS-THAN mirrorChars.put(0x22DC, 0x22DD); // EQUAL TO OR LESS-THAN mirrorChars.put(0x22DD, 0x22DC); // EQUAL TO OR GREATER-THAN mirrorChars.put(0x22DE, 0x22DF); // EQUAL TO OR PRECEDES mirrorChars.put(0x22DF, 0x22DE); // EQUAL TO OR SUCCEEDS mirrorChars.put(0x22E0, 0x22E1); // [BEST FIT] DOES NOT PRECEDE OR EQUAL mirrorChars.put(0x22E1, 0x22E0); // [BEST FIT] DOES NOT SUCCEED OR EQUAL mirrorChars.put(0x22E2, 0x22E3); // [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO mirrorChars.put(0x22E3, 0x22E2); // [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO mirrorChars.put(0x22E4, 0x22E5); // [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO mirrorChars.put(0x22E5, 0x22E4); // [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO mirrorChars.put(0x22E6, 0x22E7); // [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO mirrorChars.put(0x22E7, 0x22E6); // [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO mirrorChars.put(0x22E8, 0x22E9); // [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO mirrorChars.put(0x22E9, 0x22E8); // [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO mirrorChars.put(0x22EA, 0x22EB); // [BEST FIT] NOT NORMAL SUBGROUP OF mirrorChars.put(0x22EB, 0x22EA); // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP mirrorChars.put(0x22EC, 0x22ED); // [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO mirrorChars.put(0x22ED, 0x22EC); // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL mirrorChars.put(0x22F0, 0x22F1); // UP RIGHT DIAGONAL ELLIPSIS mirrorChars.put(0x22F1, 0x22F0); // DOWN RIGHT DIAGONAL ELLIPSIS mirrorChars.put(0x22F2, 0x22FA); // ELEMENT OF WITH LONG HORIZONTAL STROKE mirrorChars.put(0x22F3, 0x22FB); // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE mirrorChars.put(0x22F4, 0x22FC); // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE mirrorChars.put(0x22F6, 0x22FD); // ELEMENT OF WITH OVERBAR mirrorChars.put(0x22F7, 0x22FE); // SMALL ELEMENT OF WITH OVERBAR mirrorChars.put(0x22FA, 0x22F2); // CONTAINS WITH LONG HORIZONTAL STROKE mirrorChars.put(0x22FB, 0x22F3); // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE mirrorChars.put(0x22FC, 0x22F4); // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE mirrorChars.put(0x22FD, 0x22F6); // CONTAINS WITH OVERBAR mirrorChars.put(0x22FE, 0x22F7); // SMALL CONTAINS WITH OVERBAR mirrorChars.put(0x2308, 0x2309); // LEFT CEILING mirrorChars.put(0x2309, 0x2308); // RIGHT CEILING mirrorChars.put(0x230A, 0x230B); // LEFT FLOOR mirrorChars.put(0x230B, 0x230A); // RIGHT FLOOR mirrorChars.put(0x2329, 0x232A); // LEFT-POINTING ANGLE BRACKET mirrorChars.put(0x232A, 0x2329); // RIGHT-POINTING ANGLE BRACKET mirrorChars.put(0x2768, 0x2769); // MEDIUM LEFT PARENTHESIS ORNAMENT mirrorChars.put(0x2769, 0x2768); // MEDIUM RIGHT PARENTHESIS ORNAMENT mirrorChars.put(0x276A, 0x276B); // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT mirrorChars.put(0x276B, 0x276A); // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT mirrorChars.put(0x276C, 0x276D); // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT mirrorChars.put(0x276D, 0x276C); // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT mirrorChars.put(0x276E, 0x276F); // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT mirrorChars.put(0x276F, 0x276E); // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT mirrorChars.put(0x2770, 0x2771); // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT mirrorChars.put(0x2771, 0x2770); // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT mirrorChars.put(0x2772, 0x2773); // LIGHT LEFT TORTOISE SHELL BRACKET mirrorChars.put(0x2773, 0x2772); // LIGHT RIGHT TORTOISE SHELL BRACKET mirrorChars.put(0x2774, 0x2775); // MEDIUM LEFT CURLY BRACKET ORNAMENT mirrorChars.put(0x2775, 0x2774); // MEDIUM RIGHT CURLY BRACKET ORNAMENT mirrorChars.put(0x27D5, 0x27D6); // LEFT OUTER JOIN mirrorChars.put(0x27D6, 0x27D5); // RIGHT OUTER JOIN mirrorChars.put(0x27DD, 0x27DE); // LONG RIGHT TACK mirrorChars.put(0x27DE, 0x27DD); // LONG LEFT TACK mirrorChars.put(0x27E2, 0x27E3); // WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK mirrorChars.put(0x27E3, 0x27E2); // WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK mirrorChars.put(0x27E4, 0x27E5); // WHITE SQUARE WITH LEFTWARDS TICK mirrorChars.put(0x27E5, 0x27E4); // WHITE SQUARE WITH RIGHTWARDS TICK mirrorChars.put(0x27E6, 0x27E7); // MATHEMATICAL LEFT WHITE SQUARE BRACKET mirrorChars.put(0x27E7, 0x27E6); // MATHEMATICAL RIGHT WHITE SQUARE BRACKET mirrorChars.put(0x27E8, 0x27E9); // MATHEMATICAL LEFT ANGLE BRACKET mirrorChars.put(0x27E9, 0x27E8); // MATHEMATICAL RIGHT ANGLE BRACKET mirrorChars.put(0x27EA, 0x27EB); // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET mirrorChars.put(0x27EB, 0x27EA); // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET mirrorChars.put(0x2983, 0x2984); // LEFT WHITE CURLY BRACKET mirrorChars.put(0x2984, 0x2983); // RIGHT WHITE CURLY BRACKET mirrorChars.put(0x2985, 0x2986); // LEFT WHITE PARENTHESIS mirrorChars.put(0x2986, 0x2985); // RIGHT WHITE PARENTHESIS mirrorChars.put(0x2987, 0x2988); // Z NOTATION LEFT IMAGE BRACKET mirrorChars.put(0x2988, 0x2987); // Z NOTATION RIGHT IMAGE BRACKET mirrorChars.put(0x2989, 0x298A); // Z NOTATION LEFT BINDING BRACKET mirrorChars.put(0x298A, 0x2989); // Z NOTATION RIGHT BINDING BRACKET mirrorChars.put(0x298B, 0x298C); // LEFT SQUARE BRACKET WITH UNDERBAR mirrorChars.put(0x298C, 0x298B); // RIGHT SQUARE BRACKET WITH UNDERBAR mirrorChars.put(0x298D, 0x2990); // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER mirrorChars.put(0x298E, 0x298F); // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER mirrorChars.put(0x298F, 0x298E); // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER mirrorChars.put(0x2990, 0x298D); // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER mirrorChars.put(0x2991, 0x2992); // LEFT ANGLE BRACKET WITH DOT mirrorChars.put(0x2992, 0x2991); // RIGHT ANGLE BRACKET WITH DOT mirrorChars.put(0x2993, 0x2994); // LEFT ARC LESS-THAN BRACKET mirrorChars.put(0x2994, 0x2993); // RIGHT ARC GREATER-THAN BRACKET mirrorChars.put(0x2995, 0x2996); // DOUBLE LEFT ARC GREATER-THAN BRACKET mirrorChars.put(0x2996, 0x2995); // DOUBLE RIGHT ARC LESS-THAN BRACKET mirrorChars.put(0x2997, 0x2998); // LEFT BLACK TORTOISE SHELL BRACKET mirrorChars.put(0x2998, 0x2997); // RIGHT BLACK TORTOISE SHELL BRACKET mirrorChars.put(0x29B8, 0x2298); // CIRCLED REVERSE SOLIDUS mirrorChars.put(0x29C0, 0x29C1); // CIRCLED LESS-THAN mirrorChars.put(0x29C1, 0x29C0); // CIRCLED GREATER-THAN mirrorChars.put(0x29C4, 0x29C5); // SQUARED RISING DIAGONAL SLASH mirrorChars.put(0x29C5, 0x29C4); // SQUARED FALLING DIAGONAL SLASH mirrorChars.put(0x29CF, 0x29D0); // LEFT TRIANGLE BESIDE VERTICAL BAR mirrorChars.put(0x29D0, 0x29CF); // VERTICAL BAR BESIDE RIGHT TRIANGLE mirrorChars.put(0x29D1, 0x29D2); // BOWTIE WITH LEFT HALF BLACK mirrorChars.put(0x29D2, 0x29D1); // BOWTIE WITH RIGHT HALF BLACK mirrorChars.put(0x29D4, 0x29D5); // TIMES WITH LEFT HALF BLACK mirrorChars.put(0x29D5, 0x29D4); // TIMES WITH RIGHT HALF BLACK mirrorChars.put(0x29D8, 0x29D9); // LEFT WIGGLY FENCE mirrorChars.put(0x29D9, 0x29D8); // RIGHT WIGGLY FENCE mirrorChars.put(0x29DA, 0x29DB); // LEFT DOUBLE WIGGLY FENCE mirrorChars.put(0x29DB, 0x29DA); // RIGHT DOUBLE WIGGLY FENCE mirrorChars.put(0x29F5, 0x2215); // REVERSE SOLIDUS OPERATOR mirrorChars.put(0x29F8, 0x29F9); // BIG SOLIDUS mirrorChars.put(0x29F9, 0x29F8); // BIG REVERSE SOLIDUS mirrorChars.put(0x29FC, 0x29FD); // LEFT-POINTING CURVED ANGLE BRACKET mirrorChars.put(0x29FD, 0x29FC); // RIGHT-POINTING CURVED ANGLE BRACKET mirrorChars.put(0x2A2B, 0x2A2C); // MINUS SIGN WITH FALLING DOTS mirrorChars.put(0x2A2C, 0x2A2B); // MINUS SIGN WITH RISING DOTS mirrorChars.put(0x2A2D, 0x2A2C); // PLUS SIGN IN LEFT HALF CIRCLE mirrorChars.put(0x2A2E, 0x2A2D); // PLUS SIGN IN RIGHT HALF CIRCLE mirrorChars.put(0x2A34, 0x2A35); // MULTIPLICATION SIGN IN LEFT HALF CIRCLE mirrorChars.put(0x2A35, 0x2A34); // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE mirrorChars.put(0x2A3C, 0x2A3D); // INTERIOR PRODUCT mirrorChars.put(0x2A3D, 0x2A3C); // RIGHTHAND INTERIOR PRODUCT mirrorChars.put(0x2A64, 0x2A65); // Z NOTATION DOMAIN ANTIRESTRICTION mirrorChars.put(0x2A65, 0x2A64); // Z NOTATION RANGE ANTIRESTRICTION mirrorChars.put(0x2A79, 0x2A7A); // LESS-THAN WITH CIRCLE INSIDE mirrorChars.put(0x2A7A, 0x2A79); // GREATER-THAN WITH CIRCLE INSIDE mirrorChars.put(0x2A7D, 0x2A7E); // LESS-THAN OR SLANTED EQUAL TO mirrorChars.put(0x2A7E, 0x2A7D); // GREATER-THAN OR SLANTED EQUAL TO mirrorChars.put(0x2A7F, 0x2A80); // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE mirrorChars.put(0x2A80, 0x2A7F); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE mirrorChars.put(0x2A81, 0x2A82); // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE mirrorChars.put(0x2A82, 0x2A81); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE mirrorChars.put(0x2A83, 0x2A84); // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT mirrorChars.put(0x2A84, 0x2A83); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT mirrorChars.put(0x2A8B, 0x2A8C); // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN mirrorChars.put(0x2A8C, 0x2A8B); // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN mirrorChars.put(0x2A91, 0x2A92); // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL mirrorChars.put(0x2A92, 0x2A91); // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL mirrorChars.put(0x2A93, 0x2A94); // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL mirrorChars.put(0x2A94, 0x2A93); // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL mirrorChars.put(0x2A95, 0x2A96); // SLANTED EQUAL TO OR LESS-THAN mirrorChars.put(0x2A96, 0x2A95); // SLANTED EQUAL TO OR GREATER-THAN mirrorChars.put(0x2A97, 0x2A98); // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE mirrorChars.put(0x2A98, 0x2A97); // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE mirrorChars.put(0x2A99, 0x2A9A); // DOUBLE-LINE EQUAL TO OR LESS-THAN mirrorChars.put(0x2A9A, 0x2A99); // DOUBLE-LINE EQUAL TO OR GREATER-THAN mirrorChars.put(0x2A9B, 0x2A9C); // DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN mirrorChars.put(0x2A9C, 0x2A9B); // DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN mirrorChars.put(0x2AA1, 0x2AA2); // DOUBLE NESTED LESS-THAN mirrorChars.put(0x2AA2, 0x2AA1); // DOUBLE NESTED GREATER-THAN mirrorChars.put(0x2AA6, 0x2AA7); // LESS-THAN CLOSED BY CURVE mirrorChars.put(0x2AA7, 0x2AA6); // GREATER-THAN CLOSED BY CURVE mirrorChars.put(0x2AA8, 0x2AA9); // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL mirrorChars.put(0x2AA9, 0x2AA8); // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL mirrorChars.put(0x2AAA, 0x2AAB); // SMALLER THAN mirrorChars.put(0x2AAB, 0x2AAA); // LARGER THAN mirrorChars.put(0x2AAC, 0x2AAD); // SMALLER THAN OR EQUAL TO mirrorChars.put(0x2AAD, 0x2AAC); // LARGER THAN OR EQUAL TO mirrorChars.put(0x2AAF, 0x2AB0); // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN mirrorChars.put(0x2AB0, 0x2AAF); // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN mirrorChars.put(0x2AB3, 0x2AB4); // PRECEDES ABOVE EQUALS SIGN mirrorChars.put(0x2AB4, 0x2AB3); // SUCCEEDS ABOVE EQUALS SIGN mirrorChars.put(0x2ABB, 0x2ABC); // DOUBLE PRECEDES mirrorChars.put(0x2ABC, 0x2ABB); // DOUBLE SUCCEEDS mirrorChars.put(0x2ABD, 0x2ABE); // SUBSET WITH DOT mirrorChars.put(0x2ABE, 0x2ABD); // SUPERSET WITH DOT mirrorChars.put(0x2ABF, 0x2AC0); // SUBSET WITH PLUS SIGN BELOW mirrorChars.put(0x2AC0, 0x2ABF); // SUPERSET WITH PLUS SIGN BELOW mirrorChars.put(0x2AC1, 0x2AC2); // SUBSET WITH MULTIPLICATION SIGN BELOW mirrorChars.put(0x2AC2, 0x2AC1); // SUPERSET WITH MULTIPLICATION SIGN BELOW mirrorChars.put(0x2AC3, 0x2AC4); // SUBSET OF OR EQUAL TO WITH DOT ABOVE mirrorChars.put(0x2AC4, 0x2AC3); // SUPERSET OF OR EQUAL TO WITH DOT ABOVE mirrorChars.put(0x2AC5, 0x2AC6); // SUBSET OF ABOVE EQUALS SIGN mirrorChars.put(0x2AC6, 0x2AC5); // SUPERSET OF ABOVE EQUALS SIGN mirrorChars.put(0x2ACD, 0x2ACE); // SQUARE LEFT OPEN BOX OPERATOR mirrorChars.put(0x2ACE, 0x2ACD); // SQUARE RIGHT OPEN BOX OPERATOR mirrorChars.put(0x2ACF, 0x2AD0); // CLOSED SUBSET mirrorChars.put(0x2AD0, 0x2ACF); // CLOSED SUPERSET mirrorChars.put(0x2AD1, 0x2AD2); // CLOSED SUBSET OR EQUAL TO mirrorChars.put(0x2AD2, 0x2AD1); // CLOSED SUPERSET OR EQUAL TO mirrorChars.put(0x2AD3, 0x2AD4); // SUBSET ABOVE SUPERSET mirrorChars.put(0x2AD4, 0x2AD3); // SUPERSET ABOVE SUBSET mirrorChars.put(0x2AD5, 0x2AD6); // SUBSET ABOVE SUBSET mirrorChars.put(0x2AD6, 0x2AD5); // SUPERSET ABOVE SUPERSET mirrorChars.put(0x2ADE, 0x22A6); // SHORT LEFT TACK mirrorChars.put(0x2AE3, 0x22A9); // DOUBLE VERTICAL BAR LEFT TURNSTILE mirrorChars.put(0x2AE4, 0x22A8); // VERTICAL BAR DOUBLE LEFT TURNSTILE mirrorChars.put(0x2AE5, 0x22AB); // DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE mirrorChars.put(0x2AEC, 0x2AED); // DOUBLE STROKE NOT SIGN mirrorChars.put(0x2AED, 0x2AEC); // REVERSED DOUBLE STROKE NOT SIGN mirrorChars.put(0x2AF7, 0x2AF8); // TRIPLE NESTED LESS-THAN mirrorChars.put(0x2AF8, 0x2AF7); // TRIPLE NESTED GREATER-THAN mirrorChars.put(0x2AF9, 0x2AFA); // DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO mirrorChars.put(0x2AFA, 0x2AF9); // DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO mirrorChars.put(0x3008, 0x3009); // LEFT ANGLE BRACKET mirrorChars.put(0x3009, 0x3008); // RIGHT ANGLE BRACKET mirrorChars.put(0x300A, 0x300B); // LEFT DOUBLE ANGLE BRACKET mirrorChars.put(0x300B, 0x300A); // RIGHT DOUBLE ANGLE BRACKET mirrorChars.put(0x300C, 0x300D); // [BEST FIT] LEFT CORNER BRACKET mirrorChars.put(0x300D, 0x300C); // [BEST FIT] RIGHT CORNER BRACKET mirrorChars.put(0x300E, 0x300F); // [BEST FIT] LEFT WHITE CORNER BRACKET mirrorChars.put(0x300F, 0x300E); // [BEST FIT] RIGHT WHITE CORNER BRACKET mirrorChars.put(0x3010, 0x3011); // LEFT BLACK LENTICULAR BRACKET mirrorChars.put(0x3011, 0x3010); // RIGHT BLACK LENTICULAR BRACKET mirrorChars.put(0x3014, 0x3015); // LEFT TORTOISE SHELL BRACKET mirrorChars.put(0x3015, 0x3014); // RIGHT TORTOISE SHELL BRACKET mirrorChars.put(0x3016, 0x3017); // LEFT WHITE LENTICULAR BRACKET mirrorChars.put(0x3017, 0x3016); // RIGHT WHITE LENTICULAR BRACKET mirrorChars.put(0x3018, 0x3019); // LEFT WHITE TORTOISE SHELL BRACKET mirrorChars.put(0x3019, 0x3018); // RIGHT WHITE TORTOISE SHELL BRACKET mirrorChars.put(0x301A, 0x301B); // LEFT WHITE SQUARE BRACKET mirrorChars.put(0x301B, 0x301A); // RIGHT WHITE SQUARE BRACKET mirrorChars.put(0xFF08, 0xFF09); // FULLWIDTH LEFT PARENTHESIS mirrorChars.put(0xFF09, 0xFF08); // FULLWIDTH RIGHT PARENTHESIS mirrorChars.put(0xFF1C, 0xFF1E); // FULLWIDTH LESS-THAN SIGN mirrorChars.put(0xFF1E, 0xFF1C); // FULLWIDTH GREATER-THAN SIGN mirrorChars.put(0xFF3B, 0xFF3D); // FULLWIDTH LEFT SQUARE BRACKET mirrorChars.put(0xFF3D, 0xFF3B); // FULLWIDTH RIGHT SQUARE BRACKET mirrorChars.put(0xFF5B, 0xFF5D); // FULLWIDTH LEFT CURLY BRACKET mirrorChars.put(0xFF5D, 0xFF5B); // FULLWIDTH RIGHT CURLY BRACKET mirrorChars.put(0xFF5F, 0xFF60); // FULLWIDTH LEFT WHITE PARENTHESIS mirrorChars.put(0xFF60, 0xFF5F); // FULLWIDTH RIGHT WHITE PARENTHESIS mirrorChars.put(0xFF62, 0xFF63); // [BEST FIT] HALFWIDTH LEFT CORNER BRACKET mirrorChars.put(0xFF63, 0xFF62); // [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET } }src/core/com/lowagie/text/pdf/BidiOrder.java100644 0 0 161177 11000354131 16435 0ustar 0 0 package com.lowagie.text.pdf; /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ /* * (C) Copyright IBM Corp. 1999, All Rights Reserved * * version 1.1 */ /* * As stated in the Javadoc comments below, materials from Unicode.org * are used in this class. The following license applies to these materials: * http://www.unicode.org/copyright.html#Exhibit1 * * EXHIBIT 1 * UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE * * Unicode Data Files include all data files under the directories * http://www.unicode.org/Public/, http://www.unicode.org/reports/, * and http://www.unicode.org/cldr/data/ . * Unicode Software includes any source code published in the Unicode Standard * or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, * and http://www.unicode.org/cldr/data/. * * NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, * INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), * AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT * DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. * * COPYRIGHT AND PERMISSION NOTICE * Copyright (C) 1991-2007 Unicode, Inc. All rights reserved. Distributed under * the Terms of Use in http://www.unicode.org/copyright.html. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of the Unicode data files and any associated documentation (the "Data Files") * or Unicode software and any associated documentation (the "Software") to deal * in the Data Files or Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, and/or sell copies * of the Data Files or Software, and to permit persons to whom the Data Files * or Software are furnished to do so, provided that (a) the above copyright * notice(s) and this permission notice appear with all copies of the Data Files * or Software, (b) both the above copyright notice(s) and this permission notice * appear in associated documentation, and (c) there is clear notice in each * modified Data File or in the Software as well as in the documentation associated * with the Data File(s) or Software that the data or software has been modified. * * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE. * * Except as contained in this notice, the name of a copyright holder shall not * be used in advertising or otherwise to promote the sale, use or other dealings * in these Data Files or Software without prior written authorization of the * copyright holder. */ /** * Reference implementation of the Unicode 3.0 Bidi algorithm. * *

* This implementation is not optimized for performance. It is intended * as a reference implementation that closely follows the specification * of the Bidirectional Algorithm in The Unicode Standard version 3.0. *

* Input:
* There are two levels of input to the algorithm, since clients may prefer * to supply some information from out-of-band sources rather than relying on * the default behavior. *

    *
  1. unicode type array *
  2. unicode type array, with externally supplied base line direction *
*

Output:
* Output is separated into several stages as well, to better enable clients * to evaluate various aspects of implementation conformance. *

    *
  1. levels array over entire paragraph *
  2. reordering array over entire paragraph *
  3. levels array over line *
  4. reordering array over line *
* Note that for conformance, algorithms are only required to generate correct * reordering and character directionality (odd or even levels) over a line. * Generating identical level arrays over a line is not required. Bidi * explicit format codes (LRE, RLE, LRO, RLO, PDF) and BN can be assigned * arbitrary levels and positions as long as the other text matches. *

* As the algorithm is defined to operate on a single paragraph at a time, * this implementation is written to handle single paragraphs. Thus * rule P1 is presumed by this implementation-- the data provided to the * implementation is assumed to be a single paragraph, and either contains no * 'B' codes, or a single 'B' code at the end of the input. 'B' is allowed * as input to illustrate how the algorithm assigns it a level. *

* Also note that rules L3 and L4 depend on the rendering engine that uses * the result of the bidi algorithm. This implementation assumes that the * rendering engine expects combining marks in visual order (e.g. to the * left of their base character in RTL runs) and that it adjust the glyphs * used to render mirrored characters that are in RTL runs so that they * render appropriately. * * @author Doug Felt */ public final class BidiOrder { private byte[] initialTypes; private byte[] embeddings; // generated from processing format codes private byte paragraphEmbeddingLevel = -1; // undefined private int textLength; // for convenience private byte[] resultTypes; // for paragraph, not lines private byte[] resultLevels; // for paragraph, not lines // The bidi types /** Left-to-right*/ public static final byte L = 0; /** Left-to-Right Embedding */ public static final byte LRE = 1; /** Left-to-Right Override */ public static final byte LRO = 2; /** Right-to-Left */ public static final byte R = 3; /** Right-to-Left Arabic */ public static final byte AL = 4; /** Right-to-Left Embedding */ public static final byte RLE = 5; /** Right-to-Left Override */ public static final byte RLO = 6; /** Pop Directional Format */ public static final byte PDF = 7; /** European Number */ public static final byte EN = 8; /** European Number Separator */ public static final byte ES = 9; /** European Number Terminator */ public static final byte ET = 10; /** Arabic Number */ public static final byte AN = 11; /** Common Number Separator */ public static final byte CS = 12; /** Non-Spacing Mark */ public static final byte NSM = 13; /** Boundary Neutral */ public static final byte BN = 14; /** Paragraph Separator */ public static final byte B = 15; /** Segment Separator */ public static final byte S = 16; /** Whitespace */ public static final byte WS = 17; /** Other Neutrals */ public static final byte ON = 18; /** Minimum bidi type value. */ public static final byte TYPE_MIN = 0; /** Maximum bidi type value. */ public static final byte TYPE_MAX = 18; // // Input // /** * Initialize using an array of direction types. Types range from TYPE_MIN to TYPE_MAX inclusive * and represent the direction codes of the characters in the text. * * @param types the types array */ public BidiOrder(byte[] types) { validateTypes(types); this.initialTypes = (byte[])types.clone(); // client type array remains unchanged runAlgorithm(); } /** * Initialize using an array of direction types and an externally supplied paragraph embedding level. * The embedding level may be -1, 0, or 1. -1 means to apply the default algorithm (rules P2 and P3), * 0 is for LTR paragraphs, and 1 is for RTL paragraphs. * * @param types the types array * @param paragraphEmbeddingLevel the externally supplied paragraph embedding level. */ public BidiOrder(byte[] types, byte paragraphEmbeddingLevel) { validateTypes(types); validateParagraphEmbeddingLevel(paragraphEmbeddingLevel); this.initialTypes = (byte[])types.clone(); // client type array remains unchanged this.paragraphEmbeddingLevel = paragraphEmbeddingLevel; runAlgorithm(); } public BidiOrder(char text[], int offset, int length, byte paragraphEmbeddingLevel) { initialTypes = new byte[length]; for (int k = 0; k < length; ++k) { initialTypes[k] = rtypes[text[offset + k]]; } validateParagraphEmbeddingLevel(paragraphEmbeddingLevel); this.paragraphEmbeddingLevel = paragraphEmbeddingLevel; runAlgorithm(); } public final static byte getDirection(char c) { return rtypes[c]; } /** * The algorithm. * Does not include line-based processing (Rules L1, L2). * These are applied later in the line-based phase of the algorithm. */ private void runAlgorithm() { textLength = initialTypes.length; // Initialize output types. // Result types initialized to input types. resultTypes = (byte[])initialTypes.clone(); // 1) determining the paragraph level // Rule P1 is the requirement for entering this algorithm. // Rules P2, P3. // If no externally supplied paragraph embedding level, use default. if (paragraphEmbeddingLevel == -1) { determineParagraphEmbeddingLevel(); } // Initialize result levels to paragraph embedding level. resultLevels = new byte[textLength]; setLevels(0, textLength, paragraphEmbeddingLevel); // 2) Explicit levels and directions // Rules X1-X8. determineExplicitEmbeddingLevels(); // Rule X9. textLength = removeExplicitCodes(); // Rule X10. // Run remainder of algorithm one level run at a time byte prevLevel = paragraphEmbeddingLevel; int start = 0; while (start < textLength) { byte level = resultLevels[start]; byte prevType = typeForLevel(Math.max(prevLevel, level)); int limit = start + 1; while (limit < textLength && resultLevels[limit] == level) { ++limit; } byte succLevel = limit < textLength ? resultLevels[limit] : paragraphEmbeddingLevel; byte succType = typeForLevel(Math.max(succLevel, level)); // 3) resolving weak types // Rules W1-W7. resolveWeakTypes(start, limit, level, prevType, succType); // 4) resolving neutral types // Rules N1-N3. resolveNeutralTypes(start, limit, level, prevType, succType); // 5) resolving implicit embedding levels // Rules I1, I2. resolveImplicitLevels(start, limit, level, prevType, succType); prevLevel = level; start = limit; } // Reinsert explicit codes and assign appropriate levels to 'hide' them. // This is for convenience, so the resulting level array maps 1-1 // with the initial array. // See the implementation suggestions section of TR#9 for guidelines on // how to implement the algorithm without removing and reinserting the codes. textLength = reinsertExplicitCodes(textLength); } /** * 1) determining the paragraph level. *

* Rules P2, P3. *

* At the end of this function, the member variable paragraphEmbeddingLevel is set to either 0 or 1. */ private void determineParagraphEmbeddingLevel() { byte strongType = -1; // unknown // Rule P2. for (int i = 0; i < textLength; ++i) { byte t = resultTypes[i]; if (t == L || t == AL || t == R) { strongType = t; break; } } // Rule P3. if (strongType == -1) { // none found // default embedding level when no strong types found is 0. paragraphEmbeddingLevel = 0; } else if (strongType == L) { paragraphEmbeddingLevel = 0; } else { // AL, R paragraphEmbeddingLevel = 1; } } /** * Process embedding format codes. *

* Calls processEmbeddings to generate an embedding array from the explicit format codes. The * embedding overrides in the array are then applied to the result types, and the result levels are * initialized. * @see #processEmbeddings */ private void determineExplicitEmbeddingLevels() { embeddings = processEmbeddings(resultTypes, paragraphEmbeddingLevel); for (int i = 0; i < textLength; ++i) { byte level = embeddings[i]; if ((level & 0x80) != 0) { level &= 0x7f; resultTypes[i] = typeForLevel(level); } resultLevels[i] = level; } } /** * Rules X9. * Remove explicit codes so that they may be ignored during the remainder * of the main portion of the algorithm. The length of the resulting text * is returned. * @return the length of the data excluding explicit codes and BN. */ private int removeExplicitCodes() { int w = 0; for (int i = 0; i < textLength; ++i) { byte t = initialTypes[i]; if (!(t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN)) { embeddings[w] = embeddings[i]; resultTypes[w] = resultTypes[i]; resultLevels[w] = resultLevels[i]; w++; } } return w; // new textLength while explicit levels are removed } /** * Reinsert levels information for explicit codes. * This is for ease of relating the level information * to the original input data. Note that the levels * assigned to these codes are arbitrary, they're * chosen so as to avoid breaking level runs. * @param textLength the length of the data after compression * @return the length of the data (original length of * types array supplied to constructor) */ private int reinsertExplicitCodes(int textLength) { for (int i = initialTypes.length; --i >= 0;) { byte t = initialTypes[i]; if (t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN) { embeddings[i] = 0; resultTypes[i] = t; resultLevels[i] = -1; } else { --textLength; embeddings[i] = embeddings[textLength]; resultTypes[i] = resultTypes[textLength]; resultLevels[i] = resultLevels[textLength]; } } // now propagate forward the levels information (could have // propagated backward, the main thing is not to introduce a level // break where one doesn't already exist). if (resultLevels[0] == -1) { resultLevels[0] = paragraphEmbeddingLevel; } for (int i = 1; i < initialTypes.length; ++i) { if (resultLevels[i] == -1) { resultLevels[i] = resultLevels[i-1]; } } // Embedding information is for informational purposes only // so need not be adjusted. return initialTypes.length; } /** * 2) determining explicit levels * Rules X1 - X8 * * The interaction of these rules makes handling them a bit complex. * This examines resultTypes but does not modify it. It returns embedding and * override information in the result array. The low 7 bits are the level, the high * bit is set if the level is an override, and clear if it is an embedding. */ private static byte[] processEmbeddings(byte[] resultTypes, byte paragraphEmbeddingLevel) { final int EXPLICIT_LEVEL_LIMIT = 62; int textLength = resultTypes.length; byte[] embeddings = new byte[textLength]; // This stack will store the embedding levels and override status in a single byte // as described above. byte[] embeddingValueStack = new byte[EXPLICIT_LEVEL_LIMIT]; int stackCounter = 0; // An LRE or LRO at level 60 is invalid, since the new level 62 is invalid. But // an RLE at level 60 is valid, since the new level 61 is valid. The current wording // of the rules requires that the RLE remain valid even if a previous LRE is invalid. // This keeps track of ignored LRE or LRO codes at level 60, so that the matching PDFs // will not try to pop the stack. int overflowAlmostCounter = 0; // This keeps track of ignored pushes at level 61 or higher, so that matching PDFs will // not try to pop the stack. int overflowCounter = 0; // Rule X1. // Keep the level separate from the value (level | override status flag) for ease of access. byte currentEmbeddingLevel = paragraphEmbeddingLevel; byte currentEmbeddingValue = paragraphEmbeddingLevel; // Loop through types, handling all remaining rules for (int i = 0; i < textLength; ++i) { embeddings[i] = currentEmbeddingValue; byte t = resultTypes[i]; // Rules X2, X3, X4, X5 switch (t) { case RLE: case LRE: case RLO: case LRO: // Only need to compute new level if current level is valid if (overflowCounter == 0) { byte newLevel; if (t == RLE || t == RLO) { newLevel = (byte)((currentEmbeddingLevel + 1) | 1); // least greater odd } else { // t == LRE || t == LRO newLevel = (byte)((currentEmbeddingLevel + 2) & ~1); // least greater even } // If the new level is valid, push old embedding level and override status // No check for valid stack counter, since the level check suffices. if (newLevel < EXPLICIT_LEVEL_LIMIT) { embeddingValueStack[stackCounter] = currentEmbeddingValue; stackCounter++; currentEmbeddingLevel = newLevel; if (t == LRO || t == RLO) { // override currentEmbeddingValue = (byte)(newLevel | 0x80); } else { currentEmbeddingValue = newLevel; } // Adjust level of format mark (for expositional purposes only, this gets // removed later). embeddings[i] = currentEmbeddingValue; break; } // Otherwise new level is invalid, but a valid level can still be achieved if this // level is 60 and we encounter an RLE or RLO further on. So record that we // 'almost' overflowed. if (currentEmbeddingLevel == 60) { overflowAlmostCounter++; break; } } // Otherwise old or new level is invalid. overflowCounter++; break; case PDF: // The only case where this did not actually overflow but may have almost overflowed // is when there was an RLE or RLO on level 60, which would result in level 61. So we // only test the almost overflow condition in that case. // // Also note that there may be a PDF without any pushes at all. if (overflowCounter > 0) { --overflowCounter; } else if (overflowAlmostCounter > 0 && currentEmbeddingLevel != 61) { --overflowAlmostCounter; } else if (stackCounter > 0) { --stackCounter; currentEmbeddingValue = embeddingValueStack[stackCounter]; currentEmbeddingLevel = (byte)(currentEmbeddingValue & 0x7f); } break; case B: // Rule X8. // These values are reset for clarity, in this implementation B can only // occur as the last code in the array. stackCounter = 0; overflowCounter = 0; overflowAlmostCounter = 0; currentEmbeddingLevel = paragraphEmbeddingLevel; currentEmbeddingValue = paragraphEmbeddingLevel; embeddings[i] = paragraphEmbeddingLevel; break; default: break; } } return embeddings; } /** * 3) resolving weak types * Rules W1-W7. * * Note that some weak types (EN, AN) remain after this processing is complete. */ private void resolveWeakTypes(int start, int limit, byte level, byte sor, byte eor) { // Rule W1. // Changes all NSMs. byte preceedingCharacterType = sor; for (int i = start; i < limit; ++i) { byte t = resultTypes[i]; if (t == NSM) { resultTypes[i] = preceedingCharacterType; } else { preceedingCharacterType = t; } } // Rule W2. // EN does not change at the start of the run, because sor != AL. for (int i = start; i < limit; ++i) { if (resultTypes[i] == EN) { for (int j = i - 1; j >= start; --j) { byte t = resultTypes[j]; if (t == L || t == R || t == AL) { if (t == AL) { resultTypes[i] = AN; } break; } } } } // Rule W3. for (int i = start; i < limit; ++i) { if (resultTypes[i] == AL) { resultTypes[i] = R; } } // Rule W4. // Since there must be values on both sides for this rule to have an // effect, the scan skips the first and last value. // // Although the scan proceeds left to right, and changes the type values // in a way that would appear to affect the computations later in the scan, // there is actually no problem. A change in the current value can only // affect the value to its immediate right, and only affect it if it is // ES or CS. But the current value can only change if the value to its // right is not ES or CS. Thus either the current value will not change, // or its change will have no effect on the remainder of the analysis. for (int i = start + 1; i < limit - 1; ++i) { if (resultTypes[i] == ES || resultTypes[i] == CS) { byte prevSepType = resultTypes[i-1]; byte succSepType = resultTypes[i+1]; if (prevSepType == EN && succSepType == EN) { resultTypes[i] = EN; } else if (resultTypes[i] == CS && prevSepType == AN && succSepType == AN) { resultTypes[i] = AN; } } } // Rule W5. for (int i = start; i < limit; ++i) { if (resultTypes[i] == ET) { // locate end of sequence int runstart = i; int runlimit = findRunLimit(runstart, limit, new byte[] { ET }); // check values at ends of sequence byte t = runstart == start ? sor : resultTypes[runstart - 1]; if (t != EN) { t = runlimit == limit ? eor : resultTypes[runlimit]; } if (t == EN) { setTypes(runstart, runlimit, EN); } // continue at end of sequence i = runlimit; } } // Rule W6. for (int i = start; i < limit; ++i) { byte t = resultTypes[i]; if (t == ES || t == ET || t == CS) { resultTypes[i] = ON; } } // Rule W7. for (int i = start; i < limit; ++i) { if (resultTypes[i] == EN) { // set default if we reach start of run byte prevStrongType = sor; for (int j = i - 1; j >= start; --j) { byte t = resultTypes[j]; if (t == L || t == R) { // AL's have been removed prevStrongType = t; break; } } if (prevStrongType == L) { resultTypes[i] = L; } } } } /** * 6) resolving neutral types * Rules N1-N2. */ private void resolveNeutralTypes(int start, int limit, byte level, byte sor, byte eor) { for (int i = start; i < limit; ++i) { byte t = resultTypes[i]; if (t == WS || t == ON || t == B || t == S) { // find bounds of run of neutrals int runstart = i; int runlimit = findRunLimit(runstart, limit, new byte[] {B, S, WS, ON}); // determine effective types at ends of run byte leadingType; byte trailingType; if (runstart == start) { leadingType = sor; } else { leadingType = resultTypes[runstart - 1]; if (leadingType == L || leadingType == R) { // found the strong type } else if (leadingType == AN) { leadingType = R; } else if (leadingType == EN) { // Since EN's with previous strong L types have been changed // to L in W7, the leadingType must be R. leadingType = R; } } if (runlimit == limit) { trailingType = eor; } else { trailingType = resultTypes[runlimit]; if (trailingType == L || trailingType == R) { // found the strong type } else if (trailingType == AN) { trailingType = R; } else if (trailingType == EN) { trailingType = R; } } byte resolvedType; if (leadingType == trailingType) { // Rule N1. resolvedType = leadingType; } else { // Rule N2. // Notice the embedding level of the run is used, not // the paragraph embedding level. resolvedType = typeForLevel(level); } setTypes(runstart, runlimit, resolvedType); // skip over run of (former) neutrals i = runlimit; } } } /** * 7) resolving implicit embedding levels * Rules I1, I2. */ private void resolveImplicitLevels(int start, int limit, byte level, byte sor, byte eor) { if ((level & 1) == 0) { // even level for (int i = start; i < limit; ++i) { byte t = resultTypes[i]; // Rule I1. if (t == L ) { // no change } else if (t == R) { resultLevels[i] += 1; } else { // t == AN || t == EN resultLevels[i] += 2; } } } else { // odd level for (int i = start; i < limit; ++i) { byte t = resultTypes[i]; // Rule I2. if (t == R) { // no change } else { // t == L || t == AN || t == EN resultLevels[i] += 1; } } } } // // Output // public byte[] getLevels() { return getLevels(new int[]{textLength}); } /** * Return levels array breaking lines at offsets in linebreaks.
* Rule L1. *

* The returned levels array contains the resolved level for each * bidi code passed to the constructor. *

* The linebreaks array must include at least one value. * The values must be in strictly increasing order (no duplicates) * between 1 and the length of the text, inclusive. The last value * must be the length of the text. * * @param linebreaks the offsets at which to break the paragraph * @return the resolved levels of the text */ public byte[] getLevels(int[] linebreaks) { // Note that since the previous processing has removed all // P, S, and WS values from resultTypes, the values referred to // in these rules are the initial types, before any processing // has been applied (including processing of overrides). // // This example implementation has reinserted explicit format codes // and BN, in order that the levels array correspond to the // initial text. Their final placement is not normative. // These codes are treated like WS in this implementation, // so they don't interrupt sequences of WS. validateLineBreaks(linebreaks, textLength); byte[] result = (byte[])resultLevels.clone(); // will be returned to caller // don't worry about linebreaks since if there is a break within // a series of WS values preceding S, the linebreak itself // causes the reset. for (int i = 0; i < result.length; ++i) { byte t = initialTypes[i]; if (t == B || t == S) { // Rule L1, clauses one and two. result[i] = paragraphEmbeddingLevel; // Rule L1, clause three. for (int j = i - 1; j >= 0; --j) { if (isWhitespace(initialTypes[j])) { // including format codes result[j] = paragraphEmbeddingLevel; } else { break; } } } } // Rule L1, clause four. int start = 0; for (int i = 0; i < linebreaks.length; ++i) { int limit = linebreaks[i]; for (int j = limit - 1; j >= start; --j) { if (isWhitespace(initialTypes[j])) { // including format codes result[j] = paragraphEmbeddingLevel; } else { break; } } start = limit; } return result; } /** * Return reordering array breaking lines at offsets in linebreaks. *

* The reordering array maps from a visual index to a logical index. * Lines are concatenated from left to right. So for example, the * fifth character from the left on the third line is *

 getReordering(linebreaks)[linebreaks[1] + 4]
* (linebreaks[1] is the position after the last character of the * second line, which is also the index of the first character on the * third line, and adding four gets the fifth character from the left). *

* The linebreaks array must include at least one value. * The values must be in strictly increasing order (no duplicates) * between 1 and the length of the text, inclusive. The last value * must be the length of the text. * * @param linebreaks the offsets at which to break the paragraph. */ public int[] getReordering(int[] linebreaks) { validateLineBreaks(linebreaks, textLength); byte[] levels = getLevels(linebreaks); return computeMultilineReordering(levels, linebreaks); } /** * Return multiline reordering array for a given level array. * Reordering does not occur across a line break. */ private static int[] computeMultilineReordering(byte[] levels, int[] linebreaks) { int[] result = new int[levels.length]; int start = 0; for (int i = 0; i < linebreaks.length; ++i) { int limit = linebreaks[i]; byte[] templevels = new byte[limit - start]; System.arraycopy(levels, start, templevels, 0, templevels.length); int[] temporder = computeReordering(templevels); for (int j = 0; j < temporder.length; ++j) { result[start + j] = temporder[j] + start; } start = limit; } return result; } /** * Return reordering array for a given level array. This reorders a single line. * The reordering is a visual to logical map. For example, * the leftmost char is string.charAt(order[0]). * Rule L2. */ private static int[] computeReordering(byte[] levels) { int lineLength = levels.length; int[] result = new int[lineLength]; // initialize order for (int i = 0; i < lineLength; ++i) { result[i] = i; } // locate highest level found on line. // Note the rules say text, but no reordering across line bounds is performed, // so this is sufficient. byte highestLevel = 0; byte lowestOddLevel = 63; for (int i = 0; i < lineLength; ++i) { byte level = levels[i]; if (level > highestLevel) { highestLevel = level; } if (((level & 1) != 0) && level < lowestOddLevel) { lowestOddLevel = level; } } for (int level = highestLevel; level >= lowestOddLevel; --level) { for (int i = 0; i < lineLength; ++i) { if (levels[i] >= level) { // find range of text at or above this level int start = i; int limit = i + 1; while (limit < lineLength && levels[limit] >= level) { ++limit; } // reverse run for (int j = start, k = limit - 1; j < k; ++j, --k) { int temp = result[j]; result[j] = result[k]; result[k] = temp; } // skip to end of level run i = limit; } } } return result; } /** * Return the base level of the paragraph. */ public byte getBaseLevel() { return paragraphEmbeddingLevel; } // --- internal utilities ------------------------------------------------- /** * Return true if the type is considered a whitespace type for the line break rules. */ private static boolean isWhitespace(byte biditype) { switch (biditype) { case LRE: case RLE: case LRO: case RLO: case PDF: case BN: case WS: return true; default: return false; } } /** * Return the strong type (L or R) corresponding to the level. */ private static byte typeForLevel(int level) { return ((level & 0x1) == 0) ? L : R; } /** * Return the limit of the run starting at index that includes only resultTypes in validSet. * This checks the value at index, and will return index if that value is not in validSet. */ private int findRunLimit(int index, int limit, byte[] validSet) { --index; loop: while (++index < limit) { byte t = resultTypes[index]; for (int i = 0; i < validSet.length; ++i) { if (t == validSet[i]) { continue loop; } } // didn't find a match in validSet return index; } return limit; } /** * Return the start of the run including index that includes only resultTypes in validSet. * This assumes the value at index is valid, and does not check it. */ private int findRunStart(int index, byte[] validSet) { loop: while (--index >= 0) { byte t = resultTypes[index]; for (int i = 0; i < validSet.length; ++i) { if (t == validSet[i]) { continue loop; } } return index + 1; } return 0; } /** * Set resultTypes from start up to (but not including) limit to newType. */ private void setTypes(int start, int limit, byte newType) { for (int i = start; i < limit; ++i) { resultTypes[i] = newType; } } /** * Set resultLevels from start up to (but not including) limit to newLevel. */ private void setLevels(int start, int limit, byte newLevel) { for (int i = start; i < limit; ++i) { resultLevels[i] = newLevel; } } // --- input validation --------------------------------------------------- /** * Throw exception if type array is invalid. */ private static void validateTypes(byte[] types) { if (types == null) { throw new IllegalArgumentException("types is null"); } for (int i = 0; i < types.length; ++i) { if (types[i] < TYPE_MIN || types[i] > TYPE_MAX) { throw new IllegalArgumentException("illegal type value at " + i + ": " + types[i]); } } for (int i = 0; i < types.length - 1; ++i) { if (types[i] == B) { throw new IllegalArgumentException("B type before end of paragraph at index: " + i); } } } /** * Throw exception if paragraph embedding level is invalid. Special allowance for -1 so that * default processing can still be performed when using this API. */ private static void validateParagraphEmbeddingLevel(byte paragraphEmbeddingLevel) { if (paragraphEmbeddingLevel != -1 && paragraphEmbeddingLevel != 0 && paragraphEmbeddingLevel != 1) { throw new IllegalArgumentException("illegal paragraph embedding level: " + paragraphEmbeddingLevel); } } /** * Throw exception if line breaks array is invalid. */ private static void validateLineBreaks(int[] linebreaks, int textLength) { int prev = 0; for (int i = 0; i < linebreaks.length; ++i) { int next = linebreaks[i]; if (next <= prev) { throw new IllegalArgumentException("bad linebreak: " + next + " at index: " + i); } prev = next; } if (prev != textLength) { throw new IllegalArgumentException("last linebreak must be at " + textLength); } } private static final byte rtypes[] = new byte[0x10000]; private static char baseTypes[] = { 0, 8, (char)BN, 9, 9, (char)S, 10, 10, (char)B, 11, 11, (char)S, 12, 12, (char)WS, 13, 13, (char)B, 14, 27, (char)BN, 28, 30, (char)B, 31, 31, (char)S, 32, 32, (char)WS, 33, 34, (char)ON, 35, 37, (char)ET, 38, 42, (char)ON, 43, 43, (char)ET, 44, 44, (char)CS, 45, 45, (char)ET, 46, 46, (char)CS, 47, 47, (char)ES, 48, 57, (char)EN, 58, 58, (char)CS, 59, 64, (char)ON, 65, 90, (char)L, 91, 96, (char)ON, 97, 122, (char)L, 123, 126, (char)ON, 127, 132, (char)BN, 133, 133, (char)B, 134, 159, (char)BN, 160, 160, (char)CS, 161, 161, (char)ON, 162, 165, (char)ET, 166, 169, (char)ON, 170, 170, (char)L, 171, 175, (char)ON, 176, 177, (char)ET, 178, 179, (char)EN, 180, 180, (char)ON, 181, 181, (char)L, 182, 184, (char)ON, 185, 185, (char)EN, 186, 186, (char)L, 187, 191, (char)ON, 192, 214, (char)L, 215, 215, (char)ON, 216, 246, (char)L, 247, 247, (char)ON, 248, 696, (char)L, 697, 698, (char)ON, 699, 705, (char)L, 706, 719, (char)ON, 720, 721, (char)L, 722, 735, (char)ON, 736, 740, (char)L, 741, 749, (char)ON, 750, 750, (char)L, 751, 767, (char)ON, 768, 855, (char)NSM, 856, 860, (char)L, 861, 879, (char)NSM, 880, 883, (char)L, 884, 885, (char)ON, 886, 893, (char)L, 894, 894, (char)ON, 895, 899, (char)L, 900, 901, (char)ON, 902, 902, (char)L, 903, 903, (char)ON, 904, 1013, (char)L, 1014, 1014, (char)ON, 1015, 1154, (char)L, 1155, 1158, (char)NSM, 1159, 1159, (char)L, 1160, 1161, (char)NSM, 1162, 1417, (char)L, 1418, 1418, (char)ON, 1419, 1424, (char)L, 1425, 1441, (char)NSM, 1442, 1442, (char)L, 1443, 1465, (char)NSM, 1466, 1466, (char)L, 1467, 1469, (char)NSM, 1470, 1470, (char)R, 1471, 1471, (char)NSM, 1472, 1472, (char)R, 1473, 1474, (char)NSM, 1475, 1475, (char)R, 1476, 1476, (char)NSM, 1477, 1487, (char)L, 1488, 1514, (char)R, 1515, 1519, (char)L, 1520, 1524, (char)R, 1525, 1535, (char)L, 1536, 1539, (char)AL, 1540, 1547, (char)L, 1548, 1548, (char)CS, 1549, 1549, (char)AL, 1550, 1551, (char)ON, 1552, 1557, (char)NSM, 1558, 1562, (char)L, 1563, 1563, (char)AL, 1564, 1566, (char)L, 1567, 1567, (char)AL, 1568, 1568, (char)L, 1569, 1594, (char)AL, 1595, 1599, (char)L, 1600, 1610, (char)AL, 1611, 1624, (char)NSM, 1625, 1631, (char)L, 1632, 1641, (char)AN, 1642, 1642, (char)ET, 1643, 1644, (char)AN, 1645, 1647, (char)AL, 1648, 1648, (char)NSM, 1649, 1749, (char)AL, 1750, 1756, (char)NSM, 1757, 1757, (char)AL, 1758, 1764, (char)NSM, 1765, 1766, (char)AL, 1767, 1768, (char)NSM, 1769, 1769, (char)ON, 1770, 1773, (char)NSM, 1774, 1775, (char)AL, 1776, 1785, (char)EN, 1786, 1805, (char)AL, 1806, 1806, (char)L, 1807, 1807, (char)BN, 1808, 1808, (char)AL, 1809, 1809, (char)NSM, 1810, 1839, (char)AL, 1840, 1866, (char)NSM, 1867, 1868, (char)L, 1869, 1871, (char)AL, 1872, 1919, (char)L, 1920, 1957, (char)AL, 1958, 1968, (char)NSM, 1969, 1969, (char)AL, 1970, 2304, (char)L, 2305, 2306, (char)NSM, 2307, 2363, (char)L, 2364, 2364, (char)NSM, 2365, 2368, (char)L, 2369, 2376, (char)NSM, 2377, 2380, (char)L, 2381, 2381, (char)NSM, 2382, 2384, (char)L, 2385, 2388, (char)NSM, 2389, 2401, (char)L, 2402, 2403, (char)NSM, 2404, 2432, (char)L, 2433, 2433, (char)NSM, 2434, 2491, (char)L, 2492, 2492, (char)NSM, 2493, 2496, (char)L, 2497, 2500, (char)NSM, 2501, 2508, (char)L, 2509, 2509, (char)NSM, 2510, 2529, (char)L, 2530, 2531, (char)NSM, 2532, 2545, (char)L, 2546, 2547, (char)ET, 2548, 2560, (char)L, 2561, 2562, (char)NSM, 2563, 2619, (char)L, 2620, 2620, (char)NSM, 2621, 2624, (char)L, 2625, 2626, (char)NSM, 2627, 2630, (char)L, 2631, 2632, (char)NSM, 2633, 2634, (char)L, 2635, 2637, (char)NSM, 2638, 2671, (char)L, 2672, 2673, (char)NSM, 2674, 2688, (char)L, 2689, 2690, (char)NSM, 2691, 2747, (char)L, 2748, 2748, (char)NSM, 2749, 2752, (char)L, 2753, 2757, (char)NSM, 2758, 2758, (char)L, 2759, 2760, (char)NSM, 2761, 2764, (char)L, 2765, 2765, (char)NSM, 2766, 2785, (char)L, 2786, 2787, (char)NSM, 2788, 2800, (char)L, 2801, 2801, (char)ET, 2802, 2816, (char)L, 2817, 2817, (char)NSM, 2818, 2875, (char)L, 2876, 2876, (char)NSM, 2877, 2878, (char)L, 2879, 2879, (char)NSM, 2880, 2880, (char)L, 2881, 2883, (char)NSM, 2884, 2892, (char)L, 2893, 2893, (char)NSM, 2894, 2901, (char)L, 2902, 2902, (char)NSM, 2903, 2945, (char)L, 2946, 2946, (char)NSM, 2947, 3007, (char)L, 3008, 3008, (char)NSM, 3009, 3020, (char)L, 3021, 3021, (char)NSM, 3022, 3058, (char)L, 3059, 3064, (char)ON, 3065, 3065, (char)ET, 3066, 3066, (char)ON, 3067, 3133, (char)L, 3134, 3136, (char)NSM, 3137, 3141, (char)L, 3142, 3144, (char)NSM, 3145, 3145, (char)L, 3146, 3149, (char)NSM, 3150, 3156, (char)L, 3157, 3158, (char)NSM, 3159, 3259, (char)L, 3260, 3260, (char)NSM, 3261, 3275, (char)L, 3276, 3277, (char)NSM, 3278, 3392, (char)L, 3393, 3395, (char)NSM, 3396, 3404, (char)L, 3405, 3405, (char)NSM, 3406, 3529, (char)L, 3530, 3530, (char)NSM, 3531, 3537, (char)L, 3538, 3540, (char)NSM, 3541, 3541, (char)L, 3542, 3542, (char)NSM, 3543, 3632, (char)L, 3633, 3633, (char)NSM, 3634, 3635, (char)L, 3636, 3642, (char)NSM, 3643, 3646, (char)L, 3647, 3647, (char)ET, 3648, 3654, (char)L, 3655, 3662, (char)NSM, 3663, 3760, (char)L, 3761, 3761, (char)NSM, 3762, 3763, (char)L, 3764, 3769, (char)NSM, 3770, 3770, (char)L, 3771, 3772, (char)NSM, 3773, 3783, (char)L, 3784, 3789, (char)NSM, 3790, 3863, (char)L, 3864, 3865, (char)NSM, 3866, 3892, (char)L, 3893, 3893, (char)NSM, 3894, 3894, (char)L, 3895, 3895, (char)NSM, 3896, 3896, (char)L, 3897, 3897, (char)NSM, 3898, 3901, (char)ON, 3902, 3952, (char)L, 3953, 3966, (char)NSM, 3967, 3967, (char)L, 3968, 3972, (char)NSM, 3973, 3973, (char)L, 3974, 3975, (char)NSM, 3976, 3983, (char)L, 3984, 3991, (char)NSM, 3992, 3992, (char)L, 3993, 4028, (char)NSM, 4029, 4037, (char)L, 4038, 4038, (char)NSM, 4039, 4140, (char)L, 4141, 4144, (char)NSM, 4145, 4145, (char)L, 4146, 4146, (char)NSM, 4147, 4149, (char)L, 4150, 4151, (char)NSM, 4152, 4152, (char)L, 4153, 4153, (char)NSM, 4154, 4183, (char)L, 4184, 4185, (char)NSM, 4186, 5759, (char)L, 5760, 5760, (char)WS, 5761, 5786, (char)L, 5787, 5788, (char)ON, 5789, 5905, (char)L, 5906, 5908, (char)NSM, 5909, 5937, (char)L, 5938, 5940, (char)NSM, 5941, 5969, (char)L, 5970, 5971, (char)NSM, 5972, 6001, (char)L, 6002, 6003, (char)NSM, 6004, 6070, (char)L, 6071, 6077, (char)NSM, 6078, 6085, (char)L, 6086, 6086, (char)NSM, 6087, 6088, (char)L, 6089, 6099, (char)NSM, 6100, 6106, (char)L, 6107, 6107, (char)ET, 6108, 6108, (char)L, 6109, 6109, (char)NSM, 6110, 6127, (char)L, 6128, 6137, (char)ON, 6138, 6143, (char)L, 6144, 6154, (char)ON, 6155, 6157, (char)NSM, 6158, 6158, (char)WS, 6159, 6312, (char)L, 6313, 6313, (char)NSM, 6314, 6431, (char)L, 6432, 6434, (char)NSM, 6435, 6438, (char)L, 6439, 6443, (char)NSM, 6444, 6449, (char)L, 6450, 6450, (char)NSM, 6451, 6456, (char)L, 6457, 6459, (char)NSM, 6460, 6463, (char)L, 6464, 6464, (char)ON, 6465, 6467, (char)L, 6468, 6469, (char)ON, 6470, 6623, (char)L, 6624, 6655, (char)ON, 6656, 8124, (char)L, 8125, 8125, (char)ON, 8126, 8126, (char)L, 8127, 8129, (char)ON, 8130, 8140, (char)L, 8141, 8143, (char)ON, 8144, 8156, (char)L, 8157, 8159, (char)ON, 8160, 8172, (char)L, 8173, 8175, (char)ON, 8176, 8188, (char)L, 8189, 8190, (char)ON, 8191, 8191, (char)L, 8192, 8202, (char)WS, 8203, 8205, (char)BN, 8206, 8206, (char)L, 8207, 8207, (char)R, 8208, 8231, (char)ON, 8232, 8232, (char)WS, 8233, 8233, (char)B, 8234, 8234, (char)LRE, 8235, 8235, (char)RLE, 8236, 8236, (char)PDF, 8237, 8237, (char)LRO, 8238, 8238, (char)RLO, 8239, 8239, (char)WS, 8240, 8244, (char)ET, 8245, 8276, (char)ON, 8277, 8278, (char)L, 8279, 8279, (char)ON, 8280, 8286, (char)L, 8287, 8287, (char)WS, 8288, 8291, (char)BN, 8292, 8297, (char)L, 8298, 8303, (char)BN, 8304, 8304, (char)EN, 8305, 8307, (char)L, 8308, 8313, (char)EN, 8314, 8315, (char)ET, 8316, 8318, (char)ON, 8319, 8319, (char)L, 8320, 8329, (char)EN, 8330, 8331, (char)ET, 8332, 8334, (char)ON, 8335, 8351, (char)L, 8352, 8369, (char)ET, 8370, 8399, (char)L, 8400, 8426, (char)NSM, 8427, 8447, (char)L, 8448, 8449, (char)ON, 8450, 8450, (char)L, 8451, 8454, (char)ON, 8455, 8455, (char)L, 8456, 8457, (char)ON, 8458, 8467, (char)L, 8468, 8468, (char)ON, 8469, 8469, (char)L, 8470, 8472, (char)ON, 8473, 8477, (char)L, 8478, 8483, (char)ON, 8484, 8484, (char)L, 8485, 8485, (char)ON, 8486, 8486, (char)L, 8487, 8487, (char)ON, 8488, 8488, (char)L, 8489, 8489, (char)ON, 8490, 8493, (char)L, 8494, 8494, (char)ET, 8495, 8497, (char)L, 8498, 8498, (char)ON, 8499, 8505, (char)L, 8506, 8507, (char)ON, 8508, 8511, (char)L, 8512, 8516, (char)ON, 8517, 8521, (char)L, 8522, 8523, (char)ON, 8524, 8530, (char)L, 8531, 8543, (char)ON, 8544, 8591, (char)L, 8592, 8721, (char)ON, 8722, 8723, (char)ET, 8724, 9013, (char)ON, 9014, 9082, (char)L, 9083, 9108, (char)ON, 9109, 9109, (char)L, 9110, 9168, (char)ON, 9169, 9215, (char)L, 9216, 9254, (char)ON, 9255, 9279, (char)L, 9280, 9290, (char)ON, 9291, 9311, (char)L, 9312, 9371, (char)EN, 9372, 9449, (char)L, 9450, 9450, (char)EN, 9451, 9751, (char)ON, 9752, 9752, (char)L, 9753, 9853, (char)ON, 9854, 9855, (char)L, 9856, 9873, (char)ON, 9874, 9887, (char)L, 9888, 9889, (char)ON, 9890, 9984, (char)L, 9985, 9988, (char)ON, 9989, 9989, (char)L, 9990, 9993, (char)ON, 9994, 9995, (char)L, 9996, 10023, (char)ON, 10024, 10024, (char)L, 10025, 10059, (char)ON, 10060, 10060, (char)L, 10061, 10061, (char)ON, 10062, 10062, (char)L, 10063, 10066, (char)ON, 10067, 10069, (char)L, 10070, 10070, (char)ON, 10071, 10071, (char)L, 10072, 10078, (char)ON, 10079, 10080, (char)L, 10081, 10132, (char)ON, 10133, 10135, (char)L, 10136, 10159, (char)ON, 10160, 10160, (char)L, 10161, 10174, (char)ON, 10175, 10191, (char)L, 10192, 10219, (char)ON, 10220, 10223, (char)L, 10224, 11021, (char)ON, 11022, 11903, (char)L, 11904, 11929, (char)ON, 11930, 11930, (char)L, 11931, 12019, (char)ON, 12020, 12031, (char)L, 12032, 12245, (char)ON, 12246, 12271, (char)L, 12272, 12283, (char)ON, 12284, 12287, (char)L, 12288, 12288, (char)WS, 12289, 12292, (char)ON, 12293, 12295, (char)L, 12296, 12320, (char)ON, 12321, 12329, (char)L, 12330, 12335, (char)NSM, 12336, 12336, (char)ON, 12337, 12341, (char)L, 12342, 12343, (char)ON, 12344, 12348, (char)L, 12349, 12351, (char)ON, 12352, 12440, (char)L, 12441, 12442, (char)NSM, 12443, 12444, (char)ON, 12445, 12447, (char)L, 12448, 12448, (char)ON, 12449, 12538, (char)L, 12539, 12539, (char)ON, 12540, 12828, (char)L, 12829, 12830, (char)ON, 12831, 12879, (char)L, 12880, 12895, (char)ON, 12896, 12923, (char)L, 12924, 12925, (char)ON, 12926, 12976, (char)L, 12977, 12991, (char)ON, 12992, 13003, (char)L, 13004, 13007, (char)ON, 13008, 13174, (char)L, 13175, 13178, (char)ON, 13179, 13277, (char)L, 13278, 13279, (char)ON, 13280, 13310, (char)L, 13311, 13311, (char)ON, 13312, 19903, (char)L, 19904, 19967, (char)ON, 19968, 42127, (char)L, 42128, 42182, (char)ON, 42183, 64284, (char)L, 64285, 64285, (char)R, 64286, 64286, (char)NSM, 64287, 64296, (char)R, 64297, 64297, (char)ET, 64298, 64310, (char)R, 64311, 64311, (char)L, 64312, 64316, (char)R, 64317, 64317, (char)L, 64318, 64318, (char)R, 64319, 64319, (char)L, 64320, 64321, (char)R, 64322, 64322, (char)L, 64323, 64324, (char)R, 64325, 64325, (char)L, 64326, 64335, (char)R, 64336, 64433, (char)AL, 64434, 64466, (char)L, 64467, 64829, (char)AL, 64830, 64831, (char)ON, 64832, 64847, (char)L, 64848, 64911, (char)AL, 64912, 64913, (char)L, 64914, 64967, (char)AL, 64968, 65007, (char)L, 65008, 65020, (char)AL, 65021, 65021, (char)ON, 65022, 65023, (char)L, 65024, 65039, (char)NSM, 65040, 65055, (char)L, 65056, 65059, (char)NSM, 65060, 65071, (char)L, 65072, 65103, (char)ON, 65104, 65104, (char)CS, 65105, 65105, (char)ON, 65106, 65106, (char)CS, 65107, 65107, (char)L, 65108, 65108, (char)ON, 65109, 65109, (char)CS, 65110, 65118, (char)ON, 65119, 65119, (char)ET, 65120, 65121, (char)ON, 65122, 65123, (char)ET, 65124, 65126, (char)ON, 65127, 65127, (char)L, 65128, 65128, (char)ON, 65129, 65130, (char)ET, 65131, 65131, (char)ON, 65132, 65135, (char)L, 65136, 65140, (char)AL, 65141, 65141, (char)L, 65142, 65276, (char)AL, 65277, 65278, (char)L, 65279, 65279, (char)BN, 65280, 65280, (char)L, 65281, 65282, (char)ON, 65283, 65285, (char)ET, 65286, 65290, (char)ON, 65291, 65291, (char)ET, 65292, 65292, (char)CS, 65293, 65293, (char)ET, 65294, 65294, (char)CS, 65295, 65295, (char)ES, 65296, 65305, (char)EN, 65306, 65306, (char)CS, 65307, 65312, (char)ON, 65313, 65338, (char)L, 65339, 65344, (char)ON, 65345, 65370, (char)L, 65371, 65381, (char)ON, 65382, 65503, (char)L, 65504, 65505, (char)ET, 65506, 65508, (char)ON, 65509, 65510, (char)ET, 65511, 65511, (char)L, 65512, 65518, (char)ON, 65519, 65528, (char)L, 65529, 65531, (char)BN, 65532, 65533, (char)ON, 65534, 65535, (char)L}; static { for (int k = 0; k < baseTypes.length; ++k) { int start = baseTypes[k]; int end = baseTypes[++k]; byte b = (byte)baseTypes[++k]; while (start <= end) rtypes[start++] = b; } } }src/core/com/lowagie/text/pdf/ByteBuffer.java100644 0 0 52205 11012562273 16611 0ustar 0 0 /* * $Id: ByteBuffer.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; import com.lowagie.text.DocWriter; /** * Acts like a StringBuffer but works with byte arrays. * Floating point is converted to a format suitable to the PDF. * @author Paulo Soares (psoares@consiste.pt) */ public class ByteBuffer extends OutputStream { /** The count of bytes in the buffer. */ protected int count; /** The buffer where the bytes are stored. */ protected byte buf[]; private static int byteCacheSize = 0; private static byte[][] byteCache = new byte[byteCacheSize][]; public static final byte ZERO = (byte)'0'; private static final char[] chars = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; private static final byte[] bytes = new byte[] {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102}; /** * If true always output floating point numbers with 6 decimal digits. * If false uses the faster, although less precise, representation. */ public static boolean HIGH_PRECISION = false; private static final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); /** Creates new ByteBuffer with capacity 128 */ public ByteBuffer() { this(128); } /** * Creates a byte buffer with a certain capacity. * @param size the initial capacity */ public ByteBuffer(int size) { if (size < 1) size = 128; buf = new byte[size]; } /** * Sets the cache size. *

* This can only be used to increment the size. * If the size that is passed through is smaller than the current size, nothing happens. * * @param size the size of the cache */ public static void setCacheSize(int size) { if (size > 3276700) size = 3276700; if (size <= byteCacheSize) return; byte[][] tmpCache = new byte[size][]; System.arraycopy(byteCache, 0, tmpCache, 0, byteCacheSize); byteCache = tmpCache; byteCacheSize = size; } /** * You can fill the cache in advance if you want to. * * @param decimals */ public static void fillCache(int decimals) { int step = 1; switch(decimals) { case 0: step = 100; break; case 1: step = 10; break; } for (int i = 1; i < byteCacheSize; i += step) { if (byteCache[i] != null) continue; byteCache[i] = convertToBytes(i); } } /** * Converts an double (multiplied by 100 and cast to an int) into an array of bytes. * * @param i the int * @return a byte array */ private static byte[] convertToBytes(int i) { int size = (int)Math.floor(Math.log(i) / Math.log(10)); if (i % 100 != 0) { size += 2; } if (i % 10 != 0) { size++; } if (i < 100) { size++; if (i < 10) { size++; } } size--; byte[] cache = new byte[size]; size --; if (i < 100) { cache[0] = (byte)'0'; } if (i % 10 != 0) { cache[size--] = bytes[i % 10]; } if (i % 100 != 0) { cache[size--] = bytes[(i / 10) % 10]; cache[size--] = (byte)'.'; } size = (int)Math.floor(Math.log(i) / Math.log(10)) - 1; int add = 0; while (add < size) { cache[add] = bytes[(i / (int)Math.pow(10, size - add + 1)) % 10]; add++; } return cache; } /** * Appends an int. The size of the array will grow by one. * @param b the int to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append_i(int b) { int newcount = count + 1; if (newcount > buf.length) { byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count); buf = newbuf; } buf[count] = (byte)b; count = newcount; return this; } /** * Appends the subarray of the byte array. The buffer will grow by * len bytes. * @param b the array to be appended * @param off the offset to the start of the array * @param len the length of bytes to append * @return a reference to this ByteBuffer object */ public ByteBuffer append(byte b[], int off, int len) { if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || len == 0) return this; int newcount = count + len; if (newcount > buf.length) { byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; System.arraycopy(buf, 0, newbuf, 0, count); buf = newbuf; } System.arraycopy(b, off, buf, count, len); count = newcount; return this; } /** * Appends an array of bytes. * @param b the array to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(byte b[]) { return append(b, 0, b.length); } /** * Appends a String to the buffer. The String is * converted according to the encoding ISO-8859-1. * @param str the String to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(String str) { if (str != null) return append(DocWriter.getISOBytes(str)); return this; } /** * Appends a char to the buffer. The char is * converted according to the encoding ISO-8859-1. * @param c the char to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(char c) { return append_i(c); } /** * Appends another ByteBuffer to this buffer. * @param buf the ByteBuffer to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(ByteBuffer buf) { return append(buf.buf, 0, buf.count); } /** * Appends the string representation of an int. * @param i the int to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(int i) { return append((double)i); } public ByteBuffer append(byte b) { return append_i(b); } public ByteBuffer appendHex(byte b) { append(bytes[(b >> 4) & 0x0f]); return append(bytes[b & 0x0f]); } /** * Appends a string representation of a float according * to the Pdf conventions. * @param i the float to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(float i) { return append((double)i); } /** * Appends a string representation of a double according * to the Pdf conventions. * @param d the double to be appended * @return a reference to this ByteBuffer object */ public ByteBuffer append(double d) { append(formatDouble(d, this)); return this; } /** * Outputs a double into a format suitable for the PDF. * @param d a double * @return the String representation of the double */ public static String formatDouble(double d) { return formatDouble(d, null); } /** * Outputs a double into a format suitable for the PDF. * @param d a double * @param buf a ByteBuffer * @return the String representation of the double if * buf is null. If buf is not null, * then the double is appended directly to the buffer and this methods returns null. */ public static String formatDouble(double d, ByteBuffer buf) { if (HIGH_PRECISION) { DecimalFormat dn = new DecimalFormat("0.######", dfs); String sform = dn.format(d); if (buf == null) return sform; else { buf.append(sform); return null; } } boolean negative = false; if (Math.abs(d) < 0.000015) { if (buf != null) { buf.append(ZERO); return null; } else { return "0"; } } if (d < 0) { negative = true; d = -d; } if (d < 1.0) { d += 0.000005; if (d >= 1) { if (negative) { if (buf != null) { buf.append((byte)'-'); buf.append((byte)'1'); return null; } else { return "-1"; } } else { if (buf != null) { buf.append((byte)'1'); return null; } else { return "1"; } } } if (buf != null) { int v = (int) (d * 100000); if (negative) buf.append((byte)'-'); buf.append((byte)'0'); buf.append((byte)'.'); buf.append( (byte)(v / 10000 + ZERO) ); if (v % 10000 != 0) { buf.append( (byte)((v / 1000) % 10 + ZERO) ); if (v % 1000 != 0) { buf.append( (byte)((v / 100) % 10 + ZERO) ); if (v % 100 != 0) { buf.append((byte)((v / 10) % 10 + ZERO) ); if (v % 10 != 0) { buf.append((byte)((v) % 10 + ZERO) ); } } } } return null; } else { int x = 100000; int v = (int) (d * x); StringBuffer res = new StringBuffer(); if (negative) res.append('-'); res.append("0."); while( v < x/10 ) { res.append('0'); x /= 10; } res.append(v); int cut = res.length() - 1; while (res.charAt(cut) == '0') { --cut; } res.setLength(cut + 1); return res.toString(); } } else if (d <= 32767) { d += 0.005; int v = (int) (d * 100); if (v < byteCacheSize && byteCache[v] != null) { if (buf != null) { if (negative) buf.append((byte)'-'); buf.append(byteCache[v]); return null; } else { String tmp = PdfEncodings.convertToString(byteCache[v], null); if (negative) tmp = "-" + tmp; return tmp; } } if (buf != null) { if (v < byteCacheSize) { //create the cachebyte[] byte[] cache; int size = 0; if (v >= 1000000) { //the original number is >=10000, we need 5 more bytes size += 5; } else if (v >= 100000) { //the original number is >=1000, we need 4 more bytes size += 4; } else if (v >= 10000) { //the original number is >=100, we need 3 more bytes size += 3; } else if (v >= 1000) { //the original number is >=10, we need 2 more bytes size += 2; } else if (v >= 100) { //the original number is >=1, we need 1 more bytes size += 1; } //now we must check if we have a decimal number if (v % 100 != 0) { //yes, do not forget the "." size += 2; } if (v % 10 != 0) { size++; } cache = new byte[size]; int add = 0; if (v >= 1000000) { cache[add++] = bytes[(v / 1000000)]; } if (v >= 100000) { cache[add++] = bytes[(v / 100000) % 10]; } if (v >= 10000) { cache[add++] = bytes[(v / 10000) % 10]; } if (v >= 1000) { cache[add++] = bytes[(v / 1000) % 10]; } if (v >= 100) { cache[add++] = bytes[(v / 100) % 10]; } if (v % 100 != 0) { cache[add++] = (byte)'.'; cache[add++] = bytes[(v / 10) % 10]; if (v % 10 != 0) { cache[add++] = bytes[v % 10]; } } byteCache[v] = cache; } if (negative) buf.append((byte)'-'); if (v >= 1000000) { buf.append( bytes[(v / 1000000)] ); } if (v >= 100000) { buf.append( bytes[(v / 100000) % 10] ); } if (v >= 10000) { buf.append( bytes[(v / 10000) % 10] ); } if (v >= 1000) { buf.append( bytes[(v / 1000) % 10] ); } if (v >= 100) { buf.append( bytes[(v / 100) % 10] ); } if (v % 100 != 0) { buf.append((byte)'.'); buf.append( bytes[(v / 10) % 10] ); if (v % 10 != 0) { buf.append( bytes[v % 10] ); } } return null; } else { StringBuffer res = new StringBuffer(); if (negative) res.append('-'); if (v >= 1000000) { res.append( chars[(v / 1000000)] ); } if (v >= 100000) { res.append( chars[(v / 100000) % 10] ); } if (v >= 10000) { res.append( chars[(v / 10000) % 10] ); } if (v >= 1000) { res.append( chars[(v / 1000) % 10] ); } if (v >= 100) { res.append( chars[(v / 100) % 10] ); } if (v % 100 != 0) { res.append('.'); res.append( chars[(v / 10) % 10] ); if (v % 10 != 0) { res.append( chars[v % 10] ); } } return res.toString(); } } else { StringBuffer res = new StringBuffer(); if (negative) res.append('-'); d += 0.5; long v = (long) d; return res.append(v).toString(); } } /** * Sets the size to zero. */ public void reset() { count = 0; } /** * Creates a newly allocated byte array. Its size is the current * size of this output stream and the valid contents of the buffer * have been copied into it. * * @return the current contents of this output stream, as a byte array. */ public byte[] toByteArray() { byte newbuf[] = new byte[count]; System.arraycopy(buf, 0, newbuf, 0, count); return newbuf; } /** * Returns the current size of the buffer. * * @return the value of the count field, which is the number of valid bytes in this byte buffer. */ public int size() { return count; } public void setSize(int size) { if (size > count || size < 0) throw new IndexOutOfBoundsException("The new size must be positive and <= of the current size"); count = size; } /** * Converts the buffer's contents into a string, translating bytes into * characters according to the platform's default character encoding. * * @return String translated from the buffer's contents. */ public String toString() { return new String(buf, 0, count); } /** * Converts the buffer's contents into a string, translating bytes into * characters according to the specified character encoding. * * @param enc a character-encoding name. * @return String translated from the buffer's contents. * @throws UnsupportedEncodingException * If the named encoding is not supported. */ public String toString(String enc) throws UnsupportedEncodingException { return new String(buf, 0, count, enc); } /** * Writes the complete contents of this byte buffer output to * the specified output stream argument, as if by calling the output * stream's write method using out.write(buf, 0, count). * * @param out the output stream to which to write the data. * @exception IOException if an I/O error occurs. */ public void writeTo(OutputStream out) throws IOException { out.write(buf, 0, count); } public void write(int b) throws IOException { append((byte)b); } public void write(byte[] b, int off, int len) { append(b, off, len); } public byte[] getBuffer() { return buf; } }src/core/com/lowagie/text/pdf/CFFFont.java100644 0 0 133141 11036112746 16022 0ustar 0 0 /* * * Copyright 2003 Sivan Toledo * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * */ /* * Comments by Sivan Toledo: * I created this class in order to add to iText the ability to utilize * OpenType fonts with CFF glyphs (these usually have an .otf extension). * The CFF font within the CFF table of the OT font might be either a CID * or a Type1 font. (CFF fonts may also contain multiple fonts; I do not * know if this is allowed in an OT table). The PDF spec, however, only * allow a CID font with an Identity-H or Identity-V encoding. Otherwise, * you are limited to an 8-bit encoding. * Adobe fonts come in both flavors. That is, the OTFs sometimes have * a CID CFF inside (for Japanese fonts), and sometimes a Type1 CFF * (virtually all the others, Latin/Greek/Cyrillic). So to easily use * all the glyphs in the latter, without creating multiple 8-bit encoding, * I wrote this class, whose main purpose is to convert a Type1 font inside * a CFF container (which might include other fonts) into a CID CFF font * that can be directly embeded in the PDF. * * Limitations of the current version: * 1. It does not extract a single CID font from a CFF that contains that * particular CID along with other fonts. The Adobe Japanese OTF's that * I have only have one font in the CFF table, so these can be * embeded in the PDF as is. * 2. It does not yet subset fonts. * 3. It may or may not work on CFF fonts that are not within OTF's. * I didn't try that. In any case, that would probably only be * useful for subsetting CID fonts, not for CFF Type1 fonts (I don't * think there are any available. * I plan to extend the class to support these three features at some * future time. */ package com.lowagie.text.pdf; import java.util.Iterator; import java.util.LinkedList; import com.lowagie.text.ExceptionConverter; public class CFFFont { static final String operatorNames[] = { "version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "UNKNOWN_12", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23", "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27", "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31", "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15", "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27", "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName" }; static final String standardStrings[] = { // Automatically generated from Appendix A of the CFF specification; do // not edit. Size should be 391. ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader", "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", "threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior", "centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" }; //private String[] strings; public String getString(char sid) { if (sid < standardStrings.length) return standardStrings[sid]; if (sid >= standardStrings.length+(stringOffsets.length-1)) return null; int j = sid - standardStrings.length; //java.lang.System.err.println("going for "+j); int p = getPosition(); seek(stringOffsets[j]); StringBuffer s = new StringBuffer(); for (int k=stringOffsets[j]; k count in the index header. 1->offset size in index header + 2+1 //offset array size * offset size + (count+1)*indexOffSize //???zero <-> one base - 1 // read object offset relative to object array base + getOffset(indexOffSize); } //nextIndexOffset = offsets[count]; return offsets; } protected String key; protected Object[] args = new Object[48]; protected int arg_count = 0; protected void getDictItem() { for (int i=0; i= 32 && b0 <= 246) { byte item = (byte) (b0-139); args[arg_count] = new Integer(item); arg_count++; //System.err.println(item+" "); continue; } if (b0 >= 247 && b0 <= 250) { char b1 = getCard8(); short item = (short) ((b0-247)*256+b1+108); args[arg_count] = new Integer(item); arg_count++; //System.err.println(item+" "); continue; } if (b0 >= 251 && b0 <= 254) { char b1 = getCard8(); short item = (short) (-(b0-251)*256-b1-108); args[arg_count] = new Integer(item); arg_count++; //System.err.println(item+" "); continue; } if (b0 == 30) { String item = ""; boolean done = false; char buffer = 0; byte avail = 0; int nibble = 0; while (!done) { // get a nibble if (avail==0) { buffer = getCard8(); avail=2; } if (avail==1) { nibble = (buffer / 16); avail--; } if (avail==2) { nibble = (buffer % 16); avail--; } switch (nibble) { case 0xa: item += "." ; break; case 0xb: item += "E" ; break; case 0xc: item += "E-"; break; case 0xe: item += "-" ; break; case 0xf: done=true ; break; default: if (nibble >= 0 && nibble <= 9) item += String.valueOf(nibble); else { item += "'; done = true; } break; } } args[arg_count] = item; arg_count++; //System.err.println(" real=["+item+"]"); continue; } if (b0 <= 21) { gotKey=true; if (b0 != 12) key = operatorNames[b0]; else key = operatorNames[32 + getCard8()]; //for (int i=0; i>> 24) & 0xff); i++; case 3: buffer[myOffset+i] = (byte) ((value >>> 16) & 0xff); i++; case 2: buffer[myOffset+i] = (byte) ((value >>> 8) & 0xff); i++; case 1: buffer[myOffset+i] = (byte) ((value >>> 0) & 0xff); i++; } /* int mask = 0xff; for (int i=size-1; i>=0; i--) { buffer[myOffset+i] = (byte) (value & mask); mask <<= 8; } */ } } static protected final class IndexBaseItem extends Item { public IndexBaseItem() {} } static protected final class IndexMarkerItem extends Item { private OffsetItem offItem; private IndexBaseItem indexBase; public IndexMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { this.offItem = offItem; this.indexBase = indexBase; } public void xref() { //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset); offItem.set(this.myOffset-indexBase.myOffset+1); } } /** * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Generation - Code and Comments */ static protected final class SubrMarkerItem extends Item { private OffsetItem offItem; private IndexBaseItem indexBase; public SubrMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { this.offItem = offItem; this.indexBase = indexBase; } public void xref() { //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset); offItem.set(this.myOffset-indexBase.myOffset); } } /** an unknown offset in a dictionary for the list. * We will fix up the offset later; for now, assume it's large. */ static protected final class DictOffsetItem extends OffsetItem { public final int size; public DictOffsetItem() {this.size=5; } public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += size; } // this is incomplete! public void emit(byte[] buffer) { if (size==5) { buffer[myOffset] = 29; buffer[myOffset+1] = (byte) ((value >>> 24) & 0xff); buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); } } } /** Card24 item. */ static protected final class UInt24Item extends Item { public int value; public UInt24Item(int value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += 3; } // this is incomplete! public void emit(byte[] buffer) { buffer[myOffset+0] = (byte) ((value >>> 16) & 0xff); buffer[myOffset+1] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+2] = (byte) ((value >>> 0) & 0xff); } } /** Card32 item. */ static protected final class UInt32Item extends Item { public int value; public UInt32Item(int value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += 4; } // this is incomplete! public void emit(byte[] buffer) { buffer[myOffset+0] = (byte) ((value >>> 24) & 0xff); buffer[myOffset+1] = (byte) ((value >>> 16) & 0xff); buffer[myOffset+2] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+3] = (byte) ((value >>> 0) & 0xff); } } /** A SID or Card16 item. */ static protected final class UInt16Item extends Item { public char value; public UInt16Item(char value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += 2; } // this is incomplete! public void emit(byte[] buffer) { buffer[myOffset+0] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+1] = (byte) ((value >>> 0) & 0xff); } } /** A Card8 item. */ static protected final class UInt8Item extends Item { public char value; public UInt8Item(char value) {this.value=value;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += 1; } // this is incomplete! public void emit(byte[] buffer) { buffer[myOffset+0] = (byte) ((value >>> 0) & 0xff); } } static protected final class StringItem extends Item { public String s; public StringItem(String s) {this.s=s;} public void increment(int[] currentOffset) { super.increment(currentOffset); currentOffset[0] += s.length(); } public void emit(byte[] buffer) { for (int i=0; i>> 24) & 0xff); buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); } } } /** An offset-marker item for the list. * It is used to mark an offset and to set the offset list item. */ static protected final class MarkerItem extends Item { OffsetItem p; public MarkerItem(OffsetItem pointerToMarker) {p=pointerToMarker;} public void xref() { p.set(this.myOffset); } } /** a utility that creates a range item for an entire index * * @param indexOffset where the index is * @return a range item representing the entire index */ protected RangeItem getEntireIndexRange(int indexOffset) { seek(indexOffset); int count = getCard16(); if (count==0) { return new RangeItem(buf,indexOffset,2); } else { int indexOffSize = getCard8(); seek(indexOffset+2+1+count*indexOffSize); int size = getOffset(indexOffSize)-1; return new RangeItem(buf,indexOffset, 2+1+(count+1)*indexOffSize+size); } } /** get a single CID font. The PDF architecture (1.4) * supports 16-bit strings only with CID CFF fonts, not * in Type-1 CFF fonts, so we convert the font to CID if * it is in the Type-1 format. * Two other tasks that we need to do are to select * only a single font from the CFF package (this again is * a PDF restriction) and to subset the CharStrings glyph * description. */ public byte[] getCID(String fontName) //throws java.io.FileNotFoundException { int j; for (j=0; j 127) fdFontName = fdFontName.substring(0,127); String extraStrings = "Adobe"+"Identity"+fdFontName; int origStringsLen = stringOffsets[stringOffsets.length-1] - stringOffsets[0]; int stringsBaseOffset = stringOffsets[0]-1; byte stringsIndexOffSize; if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; else stringsIndexOffSize = 4; l.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count l.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize for (int i=0; i= 0) { //System.err.println("has subrs="+fonts[j].privateSubrs+" ,len="+fonts[j].privateLength); l.addLast(getEntireIndexRange(fonts[j].privateSubrs)); } } // copy the charstring index l.addLast(new MarkerItem(charstringsRef)); l.addLast(getEntireIndexRange(fonts[j].charstringsOffset)); // now create the new CFF font int[] currentOffset = new int[1]; currentOffset[0] = 0; Iterator listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.increment(currentOffset); } listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.xref(); } int size = currentOffset[0]; byte[] b = new byte[size]; listIter = l.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.emit(b); } return b; } public boolean isCID(String fontName) { int j; for (j=0; j"); } // string index //strings = new String[stringOffsets.length-1]; /* System.err.println("std strings = "+standardStrings.length); System.err.println("fnt strings = "+(stringOffsets.length-1)); for (char j=0; j"); } */ // top dict for (int j=0; j= 0) { //System.err.println("PRIVATE::"); seek(fonts[j].privateOffset); while (getPosition() < fonts[j].privateOffset+fonts[j].privateLength) { getDictItem(); if (key=="Subrs") //Add the private offset to the lsubrs since the offset is // relative to the beginning of the PrivateDict fonts[j].privateSubrs = ((Integer)args[0]).intValue()+fonts[j].privateOffset; } } // fdarray index if (fonts[j].fdarrayOffset >= 0) { int[] fdarrayOffsets = getIndex(fonts[j].fdarrayOffset); fonts[j].fdprivateOffsets = new int[fdarrayOffsets.length-1]; fonts[j].fdprivateLengths = new int[fdarrayOffsets.length-1]; //System.err.println("FD Font::"); for (int k=0; k=0) { // Process the FDSelect readFDSelect(i); // Build the FDArrayUsed hashmap BuildFDArrayUsed(i); } if (fonts[i].isCID) // Build the FD Array used Hash Map ReadFDArray(i); // compute the charset length fonts[i].CharsetLength = CountCharset(fonts[i].charsetOffset,fonts[i].nglyphs); } } /** * Calculates the length of the charset according to its format * @param Offset The Charset Offset * @param NumofGlyphs Number of glyphs in the font * @return the length of the Charset */ int CountCharset(int Offset,int NumofGlyphs){ int format; int Length=0; seek(Offset); // Read the format format = getCard8(); // Calc according to format switch (format){ case 0: Length = 1+2*NumofGlyphs; break; case 1: Length = 1+3*CountRange(NumofGlyphs,1); break; case 2: Length = 1+4*CountRange(NumofGlyphs,2); break; default: break; } return Length; } /** * Function calculates the number of ranges in the Charset * @param NumofGlyphs The number of glyphs in the font * @param Type The format of the Charset * @return The number of ranges in the Charset data structure */ int CountRange(int NumofGlyphs,int Type){ int num=0; char Sid; int i=1,nLeft; while (i= 0) GBias = CalcBias(gsubrIndexOffset,j); // Prepare the new CharStrings Index BuildNewCharString(j); // Prepare the new Global and Local Subrs Indices BuildNewLGSubrs(j); // Build the new file byte[] Ret = BuildNewFile(j); return Ret; } finally { try { buf.close(); } catch (Exception e) { // empty on purpose } } } /** * Function calcs bias according to the CharString type and the count * of the subrs * @param Offset The offset to the relevant subrs index * @param Font the font * @return The calculated Bias */ protected int CalcBias(int Offset,int Font) { seek(Offset); int nSubrs = getCard16(); // If type==1 -> bias=0 if (fonts[Font].CharstringType == 1) return 0; // else calc according to the count else if (nSubrs < 1240) return 107; else if (nSubrs < 33900) return 1131; else return 32768; } /** *Function uses BuildNewIndex to create the new index of the subset charstrings * @param FontIndex the font * @throws IOException */ protected void BuildNewCharString(int FontIndex) throws IOException { NewCharStringsIndex = BuildNewIndex(fonts[FontIndex].charstringsOffsets,GlyphsUsed,ENDCHAR_OP); } /** * Function builds the new local & global subsrs indices. IF CID then All of * the FD Array lsubrs will be subsetted. * @param Font the font * @throws IOException */ protected void BuildNewLGSubrs(int Font)throws IOException { // If the font is CID then the lsubrs are divided into FontDicts. // for each FD array the lsubrs will be subsetted. if(fonts[Font].isCID) { // Init the hashmap-array and the arraylist-array to hold the subrs used // in each private dict. hSubrsUsed = new HashMap[fonts[Font].fdprivateOffsets.length]; lSubrsUsed = new ArrayList[fonts[Font].fdprivateOffsets.length]; // A [][] which will store the byte array for each new FD Array lsubs index NewLSubrsIndex = new byte[fonts[Font].fdprivateOffsets.length][]; // An array to hold the offset for each Lsubr index fonts[Font].PrivateSubrsOffset = new int[fonts[Font].fdprivateOffsets.length]; // A [][] which will store the offset array for each lsubr index fonts[Font].PrivateSubrsOffsetsArray = new int[fonts[Font].fdprivateOffsets.length][]; // Put the FDarrayUsed into a list ArrayList FDInList = new ArrayList(FDArrayUsed.keySet()); // For each FD array which is used subset the lsubr for (int j=0;j=0) { //Scans the Charstring data storing the used Local and Global subroutines // by the glyphs. Scans the Subrs recursively. BuildSubrUsed(Font,FD,fonts[Font].PrivateSubrsOffset[FD],fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],lSubrsUsed[FD]); // Builds the New Local Subrs index NewLSubrsIndex[FD] = BuildNewIndex(fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],RETURN_OP); } } } // If the font is not CID && the Private Subr exists then subset: else if (fonts[Font].privateSubrs>=0) { // Build the subrs offsets; fonts[Font].SubrsOffsets = getIndex(fonts[Font].privateSubrs); //Scans the Charstring data storing the used Local and Global subroutines // by the glyphs. Scans the Subrs recursively. BuildSubrUsed(Font,-1,fonts[Font].privateSubrs,fonts[Font].SubrsOffsets,hSubrsUsedNonCID,lSubrsUsedNonCID); } // For all fonts subset the Global Subroutines // Scan the Global Subr Hashmap recursively on the Gsubrs BuildGSubrsUsed(Font); if (fonts[Font].privateSubrs>=0) // Builds the New Local Subrs index NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID,RETURN_OP); //Builds the New Global Subrs index NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed,RETURN_OP); } /** * The function finds for the FD array processed the local subr offset and its * offset array. * @param Font the font * @param FD The FDARRAY processed */ protected void BuildFDSubrsOffsets(int Font,int FD) { // Initiate to -1 to indicate lsubr operator present fonts[Font].PrivateSubrsOffset[FD] = -1; // Goto beginning of objects seek(fonts[Font].fdprivateOffsets[FD]); // While in the same object: while (getPosition() < fonts[Font].fdprivateOffsets[FD]+fonts[Font].fdprivateLengths[FD]) { getDictItem(); // If the dictItem is the "Subrs" then find and store offset, if (key=="Subrs") fonts[Font].PrivateSubrsOffset[FD] = ((Integer)args[0]).intValue()+fonts[Font].fdprivateOffsets[FD]; } //Read the lsubr index if the lsubr was found if (fonts[Font].PrivateSubrsOffset[FD] >= 0) fonts[Font].PrivateSubrsOffsetsArray[FD] = getIndex(fonts[Font].PrivateSubrsOffset[FD]); } /** * Function uses ReadAsubr on the glyph used to build the LSubr & Gsubr HashMap. * The HashMap (of the lsubr only) is then scanned recursively for Lsubr & Gsubrs * calls. * @param Font the font * @param FD FD array processed. 0 indicates function was called by non CID font * @param SubrOffset the offset to the subr index to calc the bias * @param SubrsOffsets the offset array of the subr index * @param hSubr HashMap of the subrs used * @param lSubr ArrayList of the subrs used */ protected void BuildSubrUsed(int Font,int FD,int SubrOffset,int[] SubrsOffsets,HashMap hSubr,ArrayList lSubr) { // Calc the Bias for the subr index int LBias = CalcBias(SubrOffset,Font); // For each glyph used find its GID, start & end pos for (int i=0;i= 0) { EmptyStack(); NumOfHints=0; // Using FDSELECT find the FD Array the glyph belongs to. int GlyphFD = fonts[Font].FDSelect[glyph]; // If the Glyph is part of the FD being processed if (GlyphFD == FD) // Find the Subrs called by the glyph and insert to hash: ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); } else // If the font is not CID //Find the Subrs called by the glyph and insert to hash: ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); } // For all Lsubrs used, check recursively for Lsubr & Gsubr used for (int i=0;i=0) { // Read and process the subr int Start = SubrsOffsets[Subr]; int End = SubrsOffsets[Subr+1]; ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); } } } /** * Function scans the Glsubr used ArrayList to find recursive calls * to Gsubrs and adds to Hashmap & ArrayList * @param Font the font */ protected void BuildGSubrsUsed(int Font) { int LBias = 0; int SizeOfNonCIDSubrsUsed = 0; if (fonts[Font].privateSubrs>=0) { LBias = CalcBias(fonts[Font].privateSubrs,Font); SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); } // For each global subr used for (int i=0;i=0) { // Read the subr and process int Start = gsubrOffsets[Subr]; int End = gsubrOffsets[Subr+1]; if (fonts[Font].isCID) ReadASubr(Start,End,GBias,0,hGSubrsUsed,lGSubrsUsed,null); else { ReadASubr(Start,End,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); if (SizeOfNonCIDSubrsUsed < lSubrsUsedNonCID.size()) { for (int j=SizeOfNonCIDSubrsUsed;j=0) { // Read the subr and process int LStart = fonts[Font].SubrsOffsets[LSubr]; int LEnd = fonts[Font].SubrsOffsets[LSubr+1]; ReadASubr(LStart,LEnd,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); } } SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); } } } } } /** * The function reads a subrs (glyph info) between begin and end. * Adds calls to a Lsubr to the hSubr and lSubrs. * Adds calls to a Gsubr to the hGSubr and lGSubrs. * @param begin the start point of the subr * @param end the end point of the subr * @param GBias the bias of the Global Subrs * @param LBias the bias of the Local Subrs * @param hSubr the HashMap for the lSubrs * @param lSubr the ArrayList for the lSubrs */ protected void ReadASubr(int begin,int end,int GBias,int LBias,HashMap hSubr,ArrayList lSubr,int[] LSubrsOffsets) { // Clear the stack for the subrs EmptyStack(); NumOfHints = 0; // Goto beginning of the subr seek(begin); while (getPosition() < end) { // Read the next command ReadCommand(); int pos = getPosition(); Object TopElement=null; if (arg_count > 0) TopElement = args[arg_count-1]; int NumOfArgs = arg_count; // Check the modification needed on the Argument Stack according to key; HandelStack(); // a call to a Lsubr if (key=="callsubr") { // Verify that arguments are passed if (NumOfArgs > 0) { // Calc the index of the Subrs int Subr = ((Integer)TopElement).intValue() + LBias; // If the subr isn't in the HashMap -> Put in if (!hSubr.containsKey(new Integer (Subr))) { hSubr.put(new Integer(Subr),null); lSubr.add(new Integer(Subr)); } CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); seek(pos); } } // a call to a Gsubr else if (key=="callgsubr") { // Verify that arguments are passed if (NumOfArgs > 0) { // Calc the index of the Subrs int Subr = ((Integer)TopElement).intValue() + GBias; // If the subr isn't in the HashMap -> Put in if (!hGSubrsUsed.containsKey(new Integer (Subr))) { hGSubrsUsed.put(new Integer(Subr),null); lGSubrsUsed.add(new Integer(Subr)); } CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); seek(pos); } } // A call to "stem" else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") // Increment the NumOfHints by the number couples of of arguments NumOfHints += NumOfArgs/2; // A call to "mask" else if (key == "hintmask" || key == "cntrmask") { // Compute the size of the mask int SizeOfMask = NumOfHints/8; if (NumOfHints%8 != 0 || SizeOfMask == 0) SizeOfMask++; // Continue the pointer in SizeOfMask steps for (int i=0;i flush the stack */ protected int StackOpp() { if (key == "ifelse") return -3; if (key == "roll" || key == "put") return -2; if (key == "callsubr" || key == "callgsubr" || key == "add" || key == "sub" || key == "div" || key == "mul" || key == "drop" || key == "and" || key == "or" || key == "eq") return -1; if (key == "abs" || key == "neg" || key == "sqrt" || key == "exch" || key == "index" || key == "get" || key == "not" || key == "return") return 0; if (key == "random" || key == "dup") return 1; return 2; } /** * Empty the Type2 Stack * */ protected void EmptyStack() { // Null the arguments for (int i=0; i0) { args[arg_count-1]=null; arg_count--; } } /** * Add an item to the stack * */ protected void PushStack() { arg_count++; } /** * The function reads the next command after the file pointer is set */ protected void ReadCommand() { key = null; boolean gotKey = false; // Until a key is found while (!gotKey) { // Read the first Char char b0 = getCard8(); // decode according to the type1/type2 format if (b0 == 28) // the two next bytes represent a short int; { int first = getCard8(); int second = getCard8(); args[arg_count] = new Integer(first<<8 | second); arg_count++; continue; } if (b0 >= 32 && b0 <= 246) // The byte read is the byte; { args[arg_count] = new Integer(b0 - 139); arg_count++; continue; } if (b0 >= 247 && b0 <= 250) // The byte read and the next byte constitute a short int { int w = getCard8(); args[arg_count] = new Integer((b0-247)*256 + w + 108); arg_count++; continue; } if (b0 >= 251 && b0 <= 254)// Same as above except negative { int w = getCard8(); args[arg_count] = new Integer(-(b0-251)*256 - w - 108); arg_count++; continue; } if (b0 == 255)// The next for bytes represent a double. { int first = getCard8(); int second = getCard8(); int third = getCard8(); int fourth = getCard8(); args[arg_count] = new Integer(first<<24 | second<<16 | third<<8 | fourth); arg_count++; continue; } if (b0<=31 && b0 != 28) // An operator was found.. Set Key. { gotKey=true; // 12 is an escape command therefore the next byte is a part // of this command if (b0 == 12) { int b1 = getCard8(); if (b1>SubrsEscapeFuncs.length-1) b1 = SubrsEscapeFuncs.length-1; key = SubrsEscapeFuncs[b1]; } else key = SubrsFunctions[b0]; continue; } } } /** * The function reads the subroutine and returns the number of the hint in it. * If a call to another subroutine is found the function calls recursively. * @param begin the start point of the subr * @param end the end point of the subr * @param LBias the bias of the Local Subrs * @param GBias the bias of the Global Subrs * @param LSubrsOffsets The Offsets array of the subroutines * @return The number of hints in the subroutine read. */ protected int CalcHints(int begin,int end,int LBias,int GBias,int[] LSubrsOffsets) { // Goto beginning of the subr seek(begin); while (getPosition() < end) { // Read the next command ReadCommand(); int pos = getPosition(); Object TopElement = null; if (arg_count>0) TopElement = args[arg_count-1]; int NumOfArgs = arg_count; //Check the modification needed on the Argument Stack according to key; HandelStack(); // a call to a Lsubr if (key=="callsubr") { if (NumOfArgs>0) { int Subr = ((Integer)TopElement).intValue() + LBias; CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); seek(pos); } } // a call to a Gsubr else if (key=="callgsubr") { if (NumOfArgs>0) { int Subr = ((Integer)TopElement).intValue() + GBias; CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); seek(pos); } } // A call to "stem" else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") // Increment the NumOfHints by the number couples of of arguments NumOfHints += NumOfArgs/2; // A call to "mask" else if (key == "hintmask" || key == "cntrmask") { // Compute the size of the mask int SizeOfMask = NumOfHints/8; if (NumOfHints%8 != 0 || SizeOfMask == 0) SizeOfMask++; // Continue the pointer in SizeOfMask steps for (int i=0;i>> 8) & 0xff); NewIndex[Place++] = (byte) ((Count >>> 0) & 0xff); // Write the offsize field NewIndex[Place++] = Offsize; // Write the offset array according to the offsize for (int i=0;i>> 24) & 0xff); case 3: NewIndex[Place++] = (byte) ((Num >>> 16) & 0xff); case 2: NewIndex[Place++] = (byte) ((Num >>> 8) & 0xff); case 1: NewIndex[Place++] = (byte) ((Num >>> 0) & 0xff); } } // Write the new object array one by one for (int i=0;i=0) OutputList.addLast(new RangeItem(buf,fonts[Font].fdselectOffset,fonts[Font].FDSelectLength)); // Else create a new one else CreateFDSelect(fdselectRef,fonts[Font].nglyphs); // Copy the Charset // Mark the beginning and copy entirely OutputList.addLast(new MarkerItem(charsetRef)); OutputList.addLast(new RangeItem(buf,fonts[Font].charsetOffset,fonts[Font].CharsetLength)); // Copy the FDArray // If an FDArray exists if (fonts[Font].fdarrayOffset>=0) { // Mark the beginning OutputList.addLast(new MarkerItem(fdarrayRef)); // Build a new FDArray with its private dicts and their LSubrs Reconstruct(Font); } else // Else create a new one CreateFDArray(fdarrayRef,privateRef,Font); } // If the font is not CID else { // create FDSelect CreateFDSelect(fdselectRef,fonts[Font].nglyphs); // recreate a new charset CreateCharset(charsetRef,fonts[Font].nglyphs); // create a font dict index (fdarray) CreateFDArray(fdarrayRef,privateRef,Font); } // if a private dict exists insert its subsetted version if (fonts[Font].privateOffset>=0) { // Mark the beginning of the private dict IndexBaseItem PrivateBase = new IndexBaseItem(); OutputList.addLast(PrivateBase); OutputList.addLast(new MarkerItem(privateRef)); OffsetItem Subr = new DictOffsetItem(); // Build and copy the new private dict CreateNonCIDPrivate(Font,Subr); // Copy the new LSubrs index CreateNonCIDSubrs(Font,PrivateBase,Subr); } // copy the charstring index OutputList.addLast(new MarkerItem(charstringsRef)); // Add the subsetted charstring OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewCharStringsIndex),0,NewCharStringsIndex.length)); // now create the new CFF font int[] currentOffset = new int[1]; currentOffset[0] = 0; // Count and save the offset for each item Iterator listIter = OutputList.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.increment(currentOffset); } // Compute the Xref for each of the offset items listIter = OutputList.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.xref(); } int size = currentOffset[0]; byte[] b = new byte[size]; // Emit all the items into the new byte array listIter = OutputList.iterator(); while ( listIter.hasNext() ) { Item item = (Item) listIter.next(); item.emit(b); } // Return the new stream return b; } /** * Function Copies the header from the original fileto the output list */ protected void CopyHeader() { seek(0); int major = getCard8(); int minor = getCard8(); int hdrSize = getCard8(); int offSize = getCard8(); nextIndexOffset = hdrSize; OutputList.addLast(new RangeItem(buf,0,hdrSize)); } /** * Function Build the header of an index * @param Count the count field of the index * @param Offsize the offsize field of the index * @param First the first offset of the index */ protected void BuildIndexHeader(int Count,int Offsize,int First) { // Add the count field OutputList.addLast(new UInt16Item((char)Count)); // count // Add the offsize field OutputList.addLast(new UInt8Item((char)Offsize)); // offSize // Add the first offset according to the offsize switch(Offsize){ case 1: OutputList.addLast(new UInt8Item((char)First)); // first offset break; case 2: OutputList.addLast(new UInt16Item((char)First)); // first offset break; case 3: OutputList.addLast(new UInt24Item((char)First)); // first offset break; case 4: OutputList.addLast(new UInt32Item((char)First)); // first offset break; default: break; } } /** * Function adds the keys into the TopDict * @param fdarrayRef OffsetItem for the FDArray * @param fdselectRef OffsetItem for the FDSelect * @param charsetRef OffsetItem for the CharSet * @param charstringsRef OffsetItem for the CharString */ protected void CreateKeys(OffsetItem fdarrayRef,OffsetItem fdselectRef,OffsetItem charsetRef,OffsetItem charstringsRef) { // create an FDArray key OutputList.addLast(fdarrayRef); OutputList.addLast(new UInt8Item((char)12)); OutputList.addLast(new UInt8Item((char)36)); // create an FDSelect key OutputList.addLast(fdselectRef); OutputList.addLast(new UInt8Item((char)12)); OutputList.addLast(new UInt8Item((char)37)); // create an charset key OutputList.addLast(charsetRef); OutputList.addLast(new UInt8Item((char)15)); // create a CharStrings key OutputList.addLast(charstringsRef); OutputList.addLast(new UInt8Item((char)17)); } /** * Function takes the original string item and adds the new strings * to accommodate the CID rules * @param Font the font */ protected void CreateNewStringIndex(int Font) { String fdFontName = fonts[Font].name+"-OneRange"; if (fdFontName.length() > 127) fdFontName = fdFontName.substring(0,127); String extraStrings = "Adobe"+"Identity"+fdFontName; int origStringsLen = stringOffsets[stringOffsets.length-1] - stringOffsets[0]; int stringsBaseOffset = stringOffsets[0]-1; byte stringsIndexOffSize; if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; else stringsIndexOffSize = 4; OutputList.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count OutputList.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize for (int i=0; i= 0) { OutputList.addLast(new SubrMarkerItem(fdSubrs[i],fdPrivateBase[i])); OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewLSubrsIndex[i]),0,NewLSubrsIndex[i].length)); } } } /** * Calculates how many byte it took to write the offset for the subrs in a specific * private dict. * @param Offset The Offset for the private dict * @param Size The size of the private dict * @return The size of the offset of the subrs in the private dict */ int CalcSubrOffsetSize(int Offset,int Size) { // Set the size to 0 int OffsetSize = 0; // Go to the beginning of the private dict seek(Offset); // Go until the end of the private dict while (getPosition() < Offset+Size) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // When reached to the subrs offset if (key=="Subrs") { // The Offsize (minus the subrs key) OffsetSize = p2-p1-1; } // All other keys are ignored } // return the size return OffsetSize; } /** * Function computes the size of an index * @param indexOffset The offset for the computed index * @return The size of the index */ protected int countEntireIndexRange(int indexOffset) { // Go to the beginning of the index seek(indexOffset); // Read the count field int count = getCard16(); // If count==0 -> size=2 if (count==0) return 2; else { // Read the offsize field int indexOffSize = getCard8(); // Go to the last element of the offset array seek(indexOffset+2+1+count*indexOffSize); // The size of the object array is the value of the last element-1 int size = getOffset(indexOffSize)-1; // Return the size of the entire index return 2+1+(count+1)*indexOffSize+size; } } /** * The function creates a private dict for a font that was not CID * All the keys are copied as is except for the subrs key * @param Font the font * @param Subr The OffsetItem for the subrs of the private */ void CreateNonCIDPrivate(int Font,OffsetItem Subr) { // Go to the beginning of the private dict and read until the end seek(fonts[Font].privateOffset); while (getPosition() < fonts[Font].privateOffset+fonts[Font].privateLength) { int p1 = getPosition(); getDictItem(); int p2 = getPosition(); // If the dictItem is the "Subrs" then, // use marker for offset and write operator number if (key=="Subrs") { OutputList.addLast(Subr); OutputList.addLast(new UInt8Item((char)19)); // Subrs } // Else copy the entire range else OutputList.addLast(new RangeItem(buf,p1,p2-p1)); } } /** * the function marks the beginning of the subrs index and adds the subsetted subrs * index to the output list. * @param Font the font * @param PrivateBase IndexBaseItem for the private that's referencing to the subrs * @param Subrs OffsetItem for the subrs */ void CreateNonCIDSubrs(int Font,IndexBaseItem PrivateBase,OffsetItem Subrs) { // Mark the beginning of the Subrs index OutputList.addLast(new SubrMarkerItem(Subrs,PrivateBase)); // Put the subsetted new subrs index OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewSubrsIndexNonCID),0,NewSubrsIndexNonCID.length)); } } src/core/com/lowagie/text/pdf/CJKFont.java100644 0 0 57752 11106243445 16027 0ustar 0 0 /* * $Id: CJKFont.java 3595 2008-10-08 13:46:32Z psoares33 $ * * Copyright 2000, 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; import com.lowagie.text.DocumentException; /** * Creates a CJK font compatible with the fonts in the Adobe Asian font Pack. * * @author Paulo Soares (psoares@consiste.pt) */ class CJKFont extends BaseFont { /** The encoding used in the PDF document for CJK fonts */ static final String CJK_ENCODING = "UnicodeBigUnmarked"; private static final int FIRST = 0; private static final int BRACKET = 1; private static final int SERIAL = 2; private static final int V1Y = 880; static Properties cjkFonts = new Properties(); static Properties cjkEncodings = new Properties(); static Hashtable allCMaps = new Hashtable(); static Hashtable allFonts = new Hashtable(); private static boolean propertiesLoaded = false; /** The font name */ private String fontName; /** The style modifier */ private String style = ""; /** The CMap name associated with this font */ private String CMap; private boolean cidDirect = false; private char[] translationMap; private IntHashtable vMetrics; private IntHashtable hMetrics; private HashMap fontDesc; private boolean vertical = false; private static void loadProperties() { if (propertiesLoaded) return; synchronized (allFonts) { if (propertiesLoaded) return; try { InputStream is = getResourceStream(RESOURCE_PATH + "cjkfonts.properties"); cjkFonts.load(is); is.close(); is = getResourceStream(RESOURCE_PATH + "cjkencodings.properties"); cjkEncodings.load(is); is.close(); } catch (Exception e) { cjkFonts = new Properties(); cjkEncodings = new Properties(); } propertiesLoaded = true; } } /** Creates a CJK font. * @param fontName the name of the font * @param enc the encoding of the font * @param emb always false. CJK font and not embedded * @throws DocumentException on error */ CJKFont(String fontName, String enc, boolean emb) throws DocumentException { loadProperties(); fontType = FONT_TYPE_CJK; String nameBase = getBaseName(fontName); if (!isCJKFont(nameBase, enc)) throw new DocumentException("Font '" + fontName + "' with '" + enc + "' encoding is not a CJK font."); if (nameBase.length() < fontName.length()) { style = fontName.substring(nameBase.length()); fontName = nameBase; } this.fontName = fontName; encoding = CJK_ENCODING; vertical = enc.endsWith("V"); CMap = enc; if (enc.startsWith("Identity-")) { cidDirect = true; String s = cjkFonts.getProperty(fontName); s = s.substring(0, s.indexOf('_')); char c[] = (char[])allCMaps.get(s); if (c == null) { c = readCMap(s); if (c == null) throw new DocumentException("The cmap " + s + " does not exist as a resource."); c[CID_NEWLINE] = '\n'; allCMaps.put(s, c); } translationMap = c; } else { char c[] = (char[])allCMaps.get(enc); if (c == null) { String s = cjkEncodings.getProperty(enc); if (s == null) throw new DocumentException("The resource cjkencodings.properties does not contain the encoding " + enc); StringTokenizer tk = new StringTokenizer(s); String nt = tk.nextToken(); c = (char[])allCMaps.get(nt); if (c == null) { c = readCMap(nt); allCMaps.put(nt, c); } if (tk.hasMoreTokens()) { String nt2 = tk.nextToken(); char m2[] = readCMap(nt2); for (int k = 0; k < 0x10000; ++k) { if (m2[k] == 0) m2[k] = c[k]; } allCMaps.put(enc, m2); c = m2; } } translationMap = c; } fontDesc = (HashMap)allFonts.get(fontName); if (fontDesc == null) { fontDesc = readFontProperties(fontName); allFonts.put(fontName, fontDesc); } hMetrics = (IntHashtable)fontDesc.get("W"); vMetrics = (IntHashtable)fontDesc.get("W2"); } /** Checks if its a valid CJK font. * @param fontName the font name * @param enc the encoding * @return true if it is CJK font */ public static boolean isCJKFont(String fontName, String enc) { loadProperties(); String encodings = cjkFonts.getProperty(fontName); return (encodings != null && (enc.equals("Identity-H") || enc.equals("Identity-V") || encodings.indexOf("_" + enc + "_") >= 0)); } /** * Gets the width of a char in normalized 1000 units. * @param char1 the unicode char to get the width of * @return the width in normalized 1000 units */ public int getWidth(int char1) { int c = char1; if (!cidDirect) c = translationMap[c]; int v; if (vertical) v = vMetrics.get(c); else v = hMetrics.get(c); if (v > 0) return v; else return 1000; } public int getWidth(String text) { int total = 0; for (int k = 0; k < text.length(); ++k) { int c = text.charAt(k); if (!cidDirect) c = translationMap[c]; int v; if (vertical) v = vMetrics.get(c); else v = hMetrics.get(c); if (v > 0) total += v; else total += 1000; } return total; } int getRawWidth(int c, String name) { return 0; } public int getKerning(int char1, int char2) { return 0; } private PdfDictionary getFontDescriptor() { PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR); dic.put(PdfName.ASCENT, new PdfLiteral((String)fontDesc.get("Ascent"))); dic.put(PdfName.CAPHEIGHT, new PdfLiteral((String)fontDesc.get("CapHeight"))); dic.put(PdfName.DESCENT, new PdfLiteral((String)fontDesc.get("Descent"))); dic.put(PdfName.FLAGS, new PdfLiteral((String)fontDesc.get("Flags"))); dic.put(PdfName.FONTBBOX, new PdfLiteral((String)fontDesc.get("FontBBox"))); dic.put(PdfName.FONTNAME, new PdfName(fontName + style)); dic.put(PdfName.ITALICANGLE, new PdfLiteral((String)fontDesc.get("ItalicAngle"))); dic.put(PdfName.STEMV, new PdfLiteral((String)fontDesc.get("StemV"))); PdfDictionary pdic = new PdfDictionary(); pdic.put(PdfName.PANOSE, new PdfString((String)fontDesc.get("Panose"), null)); dic.put(PdfName.STYLE, pdic); return dic; } private PdfDictionary getCIDFont(PdfIndirectReference fontDescriptor, IntHashtable cjkTag) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0); dic.put(PdfName.BASEFONT, new PdfName(fontName + style)); dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); int keys[] = cjkTag.toOrderedKeys(); String w = convertToHCIDMetrics(keys, hMetrics); if (w != null) dic.put(PdfName.W, new PdfLiteral(w)); if (vertical) { w = convertToVCIDMetrics(keys, vMetrics, hMetrics); if (w != null) dic.put(PdfName.W2, new PdfLiteral(w)); } else dic.put(PdfName.DW, new PdfNumber(1000)); PdfDictionary cdic = new PdfDictionary(); cdic.put(PdfName.REGISTRY, new PdfString((String)fontDesc.get("Registry"), null)); cdic.put(PdfName.ORDERING, new PdfString((String)fontDesc.get("Ordering"), null)); cdic.put(PdfName.SUPPLEMENT, new PdfLiteral((String)fontDesc.get("Supplement"))); dic.put(PdfName.CIDSYSTEMINFO, cdic); return dic; } private PdfDictionary getFontBaseType(PdfIndirectReference CIDFont) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.TYPE0); String name = fontName; if (style.length() > 0) name += "-" + style.substring(1); name += "-" + CMap; dic.put(PdfName.BASEFONT, new PdfName(name)); dic.put(PdfName.ENCODING, new PdfName(CMap)); dic.put(PdfName.DESCENDANTFONTS, new PdfArray(CIDFont)); return dic; } void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException { IntHashtable cjkTag = (IntHashtable)params[0]; PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; pobj = getFontDescriptor(); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getCIDFont(ind_font, cjkTag); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font); writer.addToBody(pobj, ref); } /** * You can't get the FontStream of a CJK font (CJK fonts are never embedded), * so this method always returns null. * @return null * @since 2.1.3 */ public PdfStream getFullFontStream() { return null; } private float getDescNumber(String name) { return Integer.parseInt((String)fontDesc.get(name)); } private float getBBox(int idx) { String s = (String)fontDesc.get("FontBBox"); StringTokenizer tk = new StringTokenizer(s, " []\r\n\t\f"); String ret = tk.nextToken(); for (int k = 0; k < idx; ++k) ret = tk.nextToken(); return Integer.parseInt(ret); } /** Gets the font parameter identified by key. Valid values * for key are ASCENT, CAPHEIGHT, DESCENT * and ITALICANGLE. * @param key the parameter to be extracted * @param fontSize the font size in points * @return the parameter in points */ public float getFontDescriptor(int key, float fontSize) { switch (key) { case AWT_ASCENT: case ASCENT: return getDescNumber("Ascent") * fontSize / 1000; case CAPHEIGHT: return getDescNumber("CapHeight") * fontSize / 1000; case AWT_DESCENT: case DESCENT: return getDescNumber("Descent") * fontSize / 1000; case ITALICANGLE: return getDescNumber("ItalicAngle"); case BBOXLLX: return fontSize * getBBox(0) / 1000; case BBOXLLY: return fontSize * getBBox(1) / 1000; case BBOXURX: return fontSize * getBBox(2) / 1000; case BBOXURY: return fontSize * getBBox(3) / 1000; case AWT_LEADING: return 0; case AWT_MAXADVANCE: return fontSize * (getBBox(2) - getBBox(0)) / 1000; } return 0; } public String getPostscriptFontName() { return fontName; } /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font */ public String[][] getFullFontName() { return new String[][]{{"", "", "", fontName}}; } /** Gets all the entries of the names-table. If it is a True Type font * each array element will have {Name ID, Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"4", "", "", "", * font name}. * @return the full name of the font */ public String[][] getAllNameEntries() { return new String[][]{{"4", "", "", "", fontName}}; } /** Gets the family name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the family name of the font */ public String[][] getFamilyFontName() { return getFullFontName(); } static char[] readCMap(String name) { try { name = name + ".cmap"; InputStream is = getResourceStream(RESOURCE_PATH + name); char c[] = new char[0x10000]; for (int k = 0; k < 0x10000; ++k) c[k] = (char)((is.read() << 8) + is.read()); is.close(); return c; } catch (Exception e) { // empty on purpose } return null; } static IntHashtable createMetric(String s) { IntHashtable h = new IntHashtable(); StringTokenizer tk = new StringTokenizer(s); while (tk.hasMoreTokens()) { int n1 = Integer.parseInt(tk.nextToken()); h.put(n1, Integer.parseInt(tk.nextToken())); } return h; } static String convertToHCIDMetrics(int keys[], IntHashtable h) { if (keys.length == 0) return null; int lastCid = 0; int lastValue = 0; int start; for (start = 0; start < keys.length; ++start) { lastCid = keys[start]; lastValue = h.get(lastCid); if (lastValue != 0) { ++start; break; } } if (lastValue == 0) return null; StringBuffer buf = new StringBuffer(); buf.append('['); buf.append(lastCid); int state = FIRST; for (int k = start; k < keys.length; ++k) { int cid = keys[k]; int value = h.get(cid); if (value == 0) continue; switch (state) { case FIRST: { if (cid == lastCid + 1 && value == lastValue) { state = SERIAL; } else if (cid == lastCid + 1) { state = BRACKET; buf.append('[').append(lastValue); } else { buf.append('[').append(lastValue).append(']').append(cid); } break; } case BRACKET: { if (cid == lastCid + 1 && value == lastValue) { state = SERIAL; buf.append(']').append(lastCid); } else if (cid == lastCid + 1) { buf.append(' ').append(lastValue); } else { state = FIRST; buf.append(' ').append(lastValue).append(']').append(cid); } break; } case SERIAL: { if (cid != lastCid + 1 || value != lastValue) { buf.append(' ').append(lastCid).append(' ').append(lastValue).append(' ').append(cid); state = FIRST; } break; } } lastValue = value; lastCid = cid; } switch (state) { case FIRST: { buf.append('[').append(lastValue).append("]]"); break; } case BRACKET: { buf.append(' ').append(lastValue).append("]]"); break; } case SERIAL: { buf.append(' ').append(lastCid).append(' ').append(lastValue).append(']'); break; } } return buf.toString(); } static String convertToVCIDMetrics(int keys[], IntHashtable v, IntHashtable h) { if (keys.length == 0) return null; int lastCid = 0; int lastValue = 0; int lastHValue = 0; int start; for (start = 0; start < keys.length; ++start) { lastCid = keys[start]; lastValue = v.get(lastCid); if (lastValue != 0) { ++start; break; } else lastHValue = h.get(lastCid); } if (lastValue == 0) return null; if (lastHValue == 0) lastHValue = 1000; StringBuffer buf = new StringBuffer(); buf.append('['); buf.append(lastCid); int state = FIRST; for (int k = start; k < keys.length; ++k) { int cid = keys[k]; int value = v.get(cid); if (value == 0) continue; int hValue = h.get(lastCid); if (hValue == 0) hValue = 1000; switch (state) { case FIRST: { if (cid == lastCid + 1 && value == lastValue && hValue == lastHValue) { state = SERIAL; } else { buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(' ').append(cid); } break; } case SERIAL: { if (cid != lastCid + 1 || value != lastValue || hValue != lastHValue) { buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(' ').append(cid); state = FIRST; } break; } } lastValue = value; lastCid = cid; lastHValue = hValue; } buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(" ]"); return buf.toString(); } static HashMap readFontProperties(String name) { try { name += ".properties"; InputStream is = getResourceStream(RESOURCE_PATH + name); Properties p = new Properties(); p.load(is); is.close(); IntHashtable W = createMetric(p.getProperty("W")); p.remove("W"); IntHashtable W2 = createMetric(p.getProperty("W2")); p.remove("W2"); HashMap map = new HashMap(); for (Enumeration e = p.keys(); e.hasMoreElements();) { Object obj = e.nextElement(); map.put(obj, p.getProperty((String)obj)); } map.put("W", W); map.put("W2", W2); return map; } catch (Exception e) { // empty on purpose } return null; } public int getUnicodeEquivalent(int c) { if (cidDirect) return translationMap[c]; return c; } public int getCidCode(int c) { if (cidDirect) return c; return translationMap[c]; } /** Checks if the font has any kerning pairs. * @return always false */ public boolean hasKernPairs() { return false; } /** * Checks if a character exists in this font. * @param c the character to check * @return true if the character has a glyph, * false otherwise */ public boolean charExists(int c) { return translationMap[c] != 0; } /** * Sets the character advance. * @param c the character * @param advance the character advance normalized to 1000 units * @return true if the advance was set, * false otherwise. Will always return false */ public boolean setCharAdvance(int c, int advance) { return false; } /** * Sets the font name that will appear in the pdf font dictionary. * Use with care as it can easily make a font unreadable if not embedded. * @param name the new font name */ public void setPostscriptFontName(String name) { fontName = name; } public boolean setKerning(int char1, int char2, int kern) { return false; } public int[] getCharBBox(int c) { return null; } protected int[] getRawCharBBox(int c, String name) { return null; } }src/core/com/lowagie/text/pdf/CMYKColor.java100644 0 0 10716 11036112746 16321 0ustar 0 0 /* * $Id: CMYKColor.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * * @author Paulo Soares (psoares@consiste.pt) */ public class CMYKColor extends ExtendedColor { private static final long serialVersionUID = 5940378778276468452L; float cyan; float magenta; float yellow; float black; /** * Constructs a CMYK Color based on 4 color values (values are integers from 0 to 255). * @param intCyan * @param intMagenta * @param intYellow * @param intBlack */ public CMYKColor(int intCyan, int intMagenta, int intYellow, int intBlack) { this(intCyan / 255f, intMagenta / 255f, intYellow / 255f, intBlack / 255f); } /** * Construct a CMYK Color. * @param floatCyan * @param floatMagenta * @param floatYellow * @param floatBlack */ public CMYKColor(float floatCyan, float floatMagenta, float floatYellow, float floatBlack) { super(TYPE_CMYK, 1f - floatCyan - floatBlack, 1f - floatMagenta - floatBlack, 1f - floatYellow - floatBlack); cyan = normalize(floatCyan); magenta = normalize(floatMagenta); yellow = normalize(floatYellow); black = normalize(floatBlack); } /** * @return the cyan value */ public float getCyan() { return cyan; } /** * @return the magenta value */ public float getMagenta() { return magenta; } /** * @return the yellow value */ public float getYellow() { return yellow; } /** * @return the black value */ public float getBlack() { return black; } public boolean equals(Object obj) { if (!(obj instanceof CMYKColor)) return false; CMYKColor c2 = (CMYKColor)obj; return (cyan == c2.cyan && magenta == c2.magenta && yellow == c2.yellow && black == c2.black); } public int hashCode() { return Float.floatToIntBits(cyan) ^ Float.floatToIntBits(magenta) ^ Float.floatToIntBits(yellow) ^ Float.floatToIntBits(black); } } src/core/com/lowagie/text/pdf/CMapAwareDocumentFont.java100644 0 0 21444 11224570760 20710 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayInputStream; import java.io.IOException; import com.lowagie.text.pdf.fonts.cmaps.CMap; import com.lowagie.text.pdf.fonts.cmaps.CMapParser; /** * Implementation of DocumentFont used while parsing PDF streams. * @since 2.1.4 */ public class CMapAwareDocumentFont extends DocumentFont { /** The font dictionary. */ private PdfDictionary fontDic; /** the width of a space for this font, in normalized 1000 point units */ private int spaceWidth; /** The CMap constructed from the ToUnicode map from the font's dictionary, if present. * This CMap transforms CID values into unicode equivalent */ private CMap toUnicodeCmap; /** * Mapping between CID code (single byte only for now) and unicode equivalent * as derived by the font's encoding. Only needed if the ToUnicode CMap is not provided. */ private char[] cidbyte2uni; /** * Creates an instance of a CMapAwareFont based on an indirect reference to a font. * @param refFont the indirect reference to a font */ public CMapAwareDocumentFont(PRIndirectReference refFont) { super(refFont); fontDic = (PdfDictionary)PdfReader.getPdfObjectRelease(refFont); processToUnicode(); if (toUnicodeCmap == null) processUni2Byte(); spaceWidth = super.getWidth(' '); if (spaceWidth == 0){ spaceWidth = computeAverageWidth(); } } /** * Parses the ToUnicode entry, if present, and constructs a CMap for it * @since 2.1.7 */ private void processToUnicode(){ PdfObject toUni = fontDic.get(PdfName.TOUNICODE); if (toUni != null){ try { byte[] touni = PdfReader.getStreamBytes((PRStream)PdfReader.getPdfObjectRelease(toUni)); CMapParser cmapParser = new CMapParser(); toUnicodeCmap = cmapParser.parse(new ByteArrayInputStream(touni)); } catch (IOException e) { throw new Error("Unable to process ToUnicode map - " + e.getMessage(), e); } } } /** * Inverts DocumentFont's uni2byte mapping to obtain a cid-to-unicode mapping based * on the font's encoding * @since 2.1.7 */ private void processUni2Byte(){ IntHashtable uni2byte = getUni2Byte(); int e[] = uni2byte.toOrderedKeys(); cidbyte2uni = new char[256]; for (int k = 0; k < e.length; ++k) { int n = uni2byte.get(e[k]); // this is messy, messy - an encoding can have multiple unicode values mapping to the same cid - we are going to arbitrarily choose the first one // what we really need to do is to parse the encoding, and handle the differences info ourselves. This is a huge duplication of code of what is already // being done in DocumentFont, so I really hate to go down that path without seriously thinking about a change in the organization of the Font class hierarchy if (cidbyte2uni[n] == 0) cidbyte2uni[n] = (char)e[k]; } } /** * For all widths of all glyphs, compute the average width in normalized 1000 point units. * This is used to give some meaningful width in cases where we need an average font width * (such as if the width of a space isn't specified by a given font) * @return the average width of all non-zero width glyphs in the font */ private int computeAverageWidth(){ int count = 0; int total = 0; for(int i = 0; i < super.widths.length; i++){ if(super.widths[i] != 0){ total += super.widths[i]; count++; } } return count != 0 ? total/count : 0; } /** * @since 2.1.5 * Override to allow special handling for fonts that don't specify width of space character * @see com.lowagie.text.pdf.DocumentFont#getWidth(int) */ public int getWidth(int char1) { if (char1 == ' ') return spaceWidth; return super.getWidth(char1); } /** * Decodes a single CID (represented by one or two bytes) to a unicode String. * @param bytes the bytes making up the character code to convert * @param offset an offset * @param len a length * @return a String containing the encoded form of the input bytes using the font's encoding. */ private String decodeSingleCID(byte[] bytes, int offset, int len){ if (toUnicodeCmap != null){ if (offset + len > bytes.length) throw new ArrayIndexOutOfBoundsException("Invalid index: " + offset + len); return toUnicodeCmap.lookup(bytes, offset, len); } if (len == 1){ return new String(cidbyte2uni, 0xff & bytes[offset], 1); } throw new Error("Multi-byte glyphs not implemented yet"); } /** * Decodes a string of bytes (encoded in the font's encoding) into a unicode string * This will use the ToUnicode map of the font, if available, otherwise it uses * the font's encoding * @param cidbytes the bytes that need to be decoded * @return the unicode String that results from decoding * @since 2.1.7 */ public String decode(byte[] cidbytes, final int offset, final int len){ StringBuffer sb = new StringBuffer(); // it's a shame we can't make this StringBuilder for(int i = offset; i < offset + len; i++){ String rslt = decodeSingleCID(cidbytes, i, 1); if (rslt == null){ rslt = decodeSingleCID(cidbytes, i, 2); i++; } sb.append(rslt); } return sb.toString(); } /** * Encodes bytes to a String. * @param bytes the bytes from a stream * @param offset an offset * @param len a length * @return a String encoded taking into account if the bytes are in unicode or not. * @deprecated method name is not indicative of what it does. Use decode instead. */ public String encode(byte[] bytes, int offset, int len){ return decode(bytes, offset, len); } } src/core/com/lowagie/text/pdf/ColorDetails.java100644 0 0 7575 11036112746 17134 0ustar 0 0 /* * $Id: ColorDetails.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** Each spotcolor in the document will have an instance of this class * * @author Phillip Pan (phillip@formstar.com) */ class ColorDetails { /** The indirect reference to this color */ PdfIndirectReference indirectReference; /** The color name that appears in the document body stream */ PdfName colorName; /** The color */ PdfSpotColor spotcolor; /** Each spot color used in a document has an instance of this class. * @param colorName the color name * @param indirectReference the indirect reference to the font * @param scolor the PDfSpotColor */ ColorDetails(PdfName colorName, PdfIndirectReference indirectReference, PdfSpotColor scolor) { this.colorName = colorName; this.indirectReference = indirectReference; this.spotcolor = scolor; } /** Gets the indirect reference to this color. * @return the indirect reference to this color */ PdfIndirectReference getIndirectReference() { return indirectReference; } /** Gets the color name as it appears in the document body. * @return the color name */ PdfName getColorName() { return colorName; } /** Gets the SpotColor object. * @return the PdfSpotColor */ PdfObject getSpotColor(PdfWriter writer) { return spotcolor.getSpotObject(writer); } } src/core/com/lowagie/text/pdf/ColumnText.java100644 0 0 166167 11213370070 16706 0ustar 0 0 /* * $Id: ColumnText.java 3904 2009-04-24 10:09:01Z blowagie $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.Stack; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.SimpleTable; import com.lowagie.text.pdf.draw.DrawInterface; /** * Formats text in a columnwise form. The text is bound * on the left and on the right by a sequence of lines. This allows the column * to have any shape, not only rectangular. *

* Several parameters can be set like the first paragraph line indent and * extra space between paragraphs. *

* A call to the method go will return one of the following * situations: the column ended or the text ended. *

* I the column ended, a new column definition can be loaded with the method * setColumns and the method go can be called again. *

* If the text ended, more text can be loaded with addText * and the method go can be called again.
* The only limitation is that one or more complete paragraphs must be loaded * each time. *

* Full bidirectional reordering is supported. If the run direction is * PdfWriter.RUN_DIRECTION_RTL the meaning of the horizontal * alignments and margins is mirrored. * @author Paulo Soares (psoares@consiste.pt) */ public class ColumnText { /** Eliminate the arabic vowels */ public static final int AR_NOVOWEL = ArabicLigaturizer.ar_novowel; /** Compose the tashkeel in the ligatures. */ public static final int AR_COMPOSEDTASHKEEL = ArabicLigaturizer.ar_composedtashkeel; /** Do some extra double ligatures. */ public static final int AR_LIG = ArabicLigaturizer.ar_lig; /** * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits. */ public static final int DIGITS_EN2AN = ArabicLigaturizer.DIGITS_EN2AN; /** * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039). */ public static final int DIGITS_AN2EN = ArabicLigaturizer.DIGITS_AN2EN; /** * Digit shaping option: * Replace European digits (U+0030...U+0039) by Arabic-Indic digits * if the most recent strongly directional character * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). * The initial state at the start of the text is assumed to be not an Arabic, * letter, so European digits at the start of the text will not change. * Compare to DIGITS_ALEN2AN_INIT_AL. */ public static final int DIGITS_EN2AN_INIT_LR = ArabicLigaturizer.DIGITS_EN2AN_INIT_LR; /** * Digit shaping option: * Replace European digits (U+0030...U+0039) by Arabic-Indic digits * if the most recent strongly directional character * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). * The initial state at the start of the text is assumed to be an Arabic, * letter, so European digits at the start of the text will change. * Compare to DIGITS_ALEN2AN_INT_LR. */ public static final int DIGITS_EN2AN_INIT_AL = ArabicLigaturizer.DIGITS_EN2AN_INIT_AL; /** * Digit type option: Use Arabic-Indic digits (U+0660...U+0669). */ public static final int DIGIT_TYPE_AN = ArabicLigaturizer.DIGIT_TYPE_AN; /** * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9). */ public static final int DIGIT_TYPE_AN_EXTENDED = ArabicLigaturizer.DIGIT_TYPE_AN_EXTENDED; protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT; /** the space char ratio */ public static final float GLOBAL_SPACE_CHAR_RATIO = 0; /** Initial value of the status. */ public static final int START_COLUMN = 0; /** Signals that there is no more text available. */ public static final int NO_MORE_TEXT = 1; /** Signals that there is no more column. */ public static final int NO_MORE_COLUMN = 2; /** The column is valid. */ protected static final int LINE_STATUS_OK = 0; /** The line is out the column limits. */ protected static final int LINE_STATUS_OFFLIMITS = 1; /** The line cannot fit this column position. */ protected static final int LINE_STATUS_NOLINE = 2; /** Upper bound of the column. */ protected float maxY; /** Lower bound of the column. */ protected float minY; protected float leftX; protected float rightX; /** The column alignment. Default is left alignment. */ protected int alignment = Element.ALIGN_LEFT; /** The left column bound. */ protected ArrayList leftWall; /** The right column bound. */ protected ArrayList rightWall; /** The chunks that form the text. */ // protected ArrayList chunks = new ArrayList(); protected BidiLine bidiLine; /** The current y line location. Text will be written at this line minus the leading. */ protected float yLine; /** The leading for the current line. */ protected float currentLeading = 16; /** The fixed text leading. */ protected float fixedLeading = 16; /** The text leading that is multiplied by the biggest font size in the line. */ protected float multipliedLeading = 0; /** The PdfContent where the text will be written to. */ protected PdfContentByte canvas; protected PdfContentByte[] canvases; /** The line status when trying to fit a line to a column. */ protected int lineStatus; /** The first paragraph line indent. */ protected float indent = 0; /** The following paragraph lines indent. */ protected float followingIndent = 0; /** The right paragraph lines indent. */ protected float rightIndent = 0; /** The extra space between paragraphs. */ protected float extraParagraphSpace = 0; /** The width of the line when the column is defined as a simple rectangle. */ protected float rectangularWidth = -1; protected boolean rectangularMode = false; /** Holds value of property spaceCharRatio. */ private float spaceCharRatio = GLOBAL_SPACE_CHAR_RATIO; private boolean lastWasNewline = true; /** Holds value of property linesWritten. */ private int linesWritten; private float firstLineY; private boolean firstLineYDone = false; /** Holds value of property arabicOptions. */ private int arabicOptions = 0; protected float descender; protected boolean composite = false; protected ColumnText compositeColumn; protected LinkedList compositeElements; protected int listIdx = 0; private boolean splittedRow; protected Phrase waitPhrase; /** if true, first line height is adjusted so that the max ascender touches the top */ private boolean useAscender = false; /** Holds value of property filledWidth. */ private float filledWidth; private boolean adjustFirstLine = true; /** * Creates a ColumnText. * * @param canvas the place where the text will be written to. Can * be a template. */ public ColumnText(PdfContentByte canvas) { this.canvas = canvas; } /** * Creates an independent duplicated of the instance org. * * @param org the original ColumnText * @return the duplicated */ public static ColumnText duplicate(ColumnText org) { ColumnText ct = new ColumnText(null); ct.setACopy(org); return ct; } /** * Makes this instance an independent copy of org. * * @param org the original ColumnText * @return itself */ public ColumnText setACopy(ColumnText org) { setSimpleVars(org); if (org.bidiLine != null) bidiLine = new BidiLine(org.bidiLine); return this; } protected void setSimpleVars(ColumnText org) { maxY = org.maxY; minY = org.minY; alignment = org.alignment; leftWall = null; if (org.leftWall != null) leftWall = new ArrayList(org.leftWall); rightWall = null; if (org.rightWall != null) rightWall = new ArrayList(org.rightWall); yLine = org.yLine; currentLeading = org.currentLeading; fixedLeading = org.fixedLeading; multipliedLeading = org.multipliedLeading; canvas = org.canvas; canvases = org.canvases; lineStatus = org.lineStatus; indent = org.indent; followingIndent = org.followingIndent; rightIndent = org.rightIndent; extraParagraphSpace = org.extraParagraphSpace; rectangularWidth = org.rectangularWidth; rectangularMode = org.rectangularMode; spaceCharRatio = org.spaceCharRatio; lastWasNewline = org.lastWasNewline; linesWritten = org.linesWritten; arabicOptions = org.arabicOptions; runDirection = org.runDirection; descender = org.descender; composite = org.composite; splittedRow = org.splittedRow; if (org.composite) { compositeElements = new LinkedList(org.compositeElements); if (splittedRow) { PdfPTable table = (PdfPTable)compositeElements.getFirst(); compositeElements.set(0, new PdfPTable(table)); } if (org.compositeColumn != null) compositeColumn = duplicate(org.compositeColumn); } listIdx = org.listIdx; firstLineY = org.firstLineY; leftX = org.leftX; rightX = org.rightX; firstLineYDone = org.firstLineYDone; waitPhrase = org.waitPhrase; useAscender = org.useAscender; filledWidth = org.filledWidth; adjustFirstLine = org.adjustFirstLine; } private void addWaitingPhrase() { if (bidiLine == null && waitPhrase != null) { bidiLine = new BidiLine(); for (Iterator j = waitPhrase.getChunks().iterator(); j.hasNext();) { bidiLine.addChunk(new PdfChunk((Chunk)j.next(), null)); } waitPhrase = null; } } /** * Adds a Phrase to the current text array. * Will not have any effect if addElement() was called before. * * @param phrase the text */ public void addText(Phrase phrase) { if (phrase == null || composite) return; addWaitingPhrase(); if (bidiLine == null) { waitPhrase = phrase; return; } for (Iterator j = phrase.getChunks().iterator(); j.hasNext();) { bidiLine.addChunk(new PdfChunk((Chunk)j.next(), null)); } } /** * Replaces the current text array with this Phrase. * Anything added previously with addElement() is lost. * * @param phrase the text */ public void setText(Phrase phrase) { bidiLine = null; composite = false; compositeColumn = null; compositeElements = null; listIdx = 0; splittedRow = false; waitPhrase = phrase; } /** * Adds a Chunk to the current text array. * Will not have any effect if addElement() was called before. * * @param chunk the text */ public void addText(Chunk chunk) { if (chunk == null || composite) return; addText(new Phrase(chunk)); } /** * Adds an element. Elements supported are Paragraph, * List, PdfPTable, Image and * Graphic. *

* It removes all the text placed with addText(). * * @param element the Element */ public void addElement(Element element) { if (element == null) return; if (element instanceof Image) { Image img = (Image)element; PdfPTable t = new PdfPTable(1); float w = img.getWidthPercentage(); if (w == 0) { t.setTotalWidth(img.getScaledWidth()); t.setLockedWidth(true); } else t.setWidthPercentage(w); t.setSpacingAfter(img.getSpacingAfter()); t.setSpacingBefore(img.getSpacingBefore()); switch (img.getAlignment()) { case Image.LEFT: t.setHorizontalAlignment(Element.ALIGN_LEFT); break; case Image.RIGHT: t.setHorizontalAlignment(Element.ALIGN_RIGHT); break; default: t.setHorizontalAlignment(Element.ALIGN_CENTER); break; } PdfPCell c = new PdfPCell(img, true); c.setPadding(0); c.setBorder(img.getBorder()); c.setBorderColor(img.getBorderColor()); c.setBorderWidth(img.getBorderWidth()); c.setBackgroundColor(img.getBackgroundColor()); t.addCell(c); element = t; } if (element.type() == Element.CHUNK) { element = new Paragraph((Chunk)element); } else if (element.type() == Element.PHRASE) { element = new Paragraph((Phrase)element); } if (element instanceof SimpleTable) { try { element = ((SimpleTable)element).createPdfPTable(); } catch (DocumentException e) { throw new IllegalArgumentException("Element not allowed."); } } else if (element.type() != Element.PARAGRAPH && element.type() != Element.LIST && element.type() != Element.PTABLE && element.type() != Element.YMARK) throw new IllegalArgumentException("Element not allowed."); if (!composite) { composite = true; compositeElements = new LinkedList(); bidiLine = null; waitPhrase = null; } compositeElements.add(element); } /** * Converts a sequence of lines representing one of the column bounds into * an internal format. *

* Each array element will contain a float[4] representing * the line x = ax + b. * * @param cLine the column array * @return the converted array */ protected ArrayList convertColumn(float cLine[]) { if (cLine.length < 4) throw new RuntimeException("No valid column line found."); ArrayList cc = new ArrayList(); for (int k = 0; k < cLine.length - 2; k += 2) { float x1 = cLine[k]; float y1 = cLine[k + 1]; float x2 = cLine[k + 2]; float y2 = cLine[k + 3]; if (y1 == y2) continue; // x = ay + b float a = (x1 - x2) / (y1 - y2); float b = x1 - a * y1; float r[] = new float[4]; r[0] = Math.min(y1, y2); r[1] = Math.max(y1, y2); r[2] = a; r[3] = b; cc.add(r); maxY = Math.max(maxY, r[1]); minY = Math.min(minY, r[0]); } if (cc.isEmpty()) throw new RuntimeException("No valid column line found."); return cc; } /** * Finds the intersection between the yLine and the column. It will * set the lineStatus appropriately. * * @param wall the column to intersect * @return the x coordinate of the intersection */ protected float findLimitsPoint(ArrayList wall) { lineStatus = LINE_STATUS_OK; if (yLine < minY || yLine > maxY) { lineStatus = LINE_STATUS_OFFLIMITS; return 0; } for (int k = 0; k < wall.size(); ++k) { float r[] = (float[])wall.get(k); if (yLine < r[0] || yLine > r[1]) continue; return r[2] * yLine + r[3]; } lineStatus = LINE_STATUS_NOLINE; return 0; } /** * Finds the intersection between the yLine and the two * column bounds. It will set the lineStatus appropriately. * * @return a float[2]with the x coordinates of the intersection */ protected float[] findLimitsOneLine() { float x1 = findLimitsPoint(leftWall); if (lineStatus == LINE_STATUS_OFFLIMITS || lineStatus == LINE_STATUS_NOLINE) return null; float x2 = findLimitsPoint(rightWall); if (lineStatus == LINE_STATUS_NOLINE) return null; return new float[]{x1, x2}; } /** * Finds the intersection between the yLine, * the yLine-leadingand the two column bounds. * It will set the lineStatus appropriately. * * @return a float[4]with the x coordinates of the intersection */ protected float[] findLimitsTwoLines() { boolean repeat = false; for (;;) { if (repeat && currentLeading == 0) return null; repeat = true; float x1[] = findLimitsOneLine(); if (lineStatus == LINE_STATUS_OFFLIMITS) return null; yLine -= currentLeading; if (lineStatus == LINE_STATUS_NOLINE) { continue; } float x2[] = findLimitsOneLine(); if (lineStatus == LINE_STATUS_OFFLIMITS) return null; if (lineStatus == LINE_STATUS_NOLINE) { yLine -= currentLeading; continue; } if (x1[0] >= x2[1] || x2[0] >= x1[1]) continue; return new float[]{x1[0], x1[1], x2[0], x2[1]}; } } /** * Sets the columns bounds. Each column bound is described by a * float[] with the line points [x1,y1,x2,y2,...]. * The array must have at least 4 elements. * * @param leftLine the left column bound * @param rightLine the right column bound */ public void setColumns(float leftLine[], float rightLine[]) { maxY = -10e20f; minY = 10e20f; setYLine(Math.max(leftLine[1], leftLine[leftLine.length - 1])); rightWall = convertColumn(rightLine); leftWall = convertColumn(leftLine); rectangularWidth = -1; rectangularMode = false; } /** * Simplified method for rectangular columns. * * @param phrase a Phrase * @param llx the lower left x corner * @param lly the lower left y corner * @param urx the upper right x corner * @param ury the upper right y corner * @param leading the leading * @param alignment the column alignment */ public void setSimpleColumn(Phrase phrase, float llx, float lly, float urx, float ury, float leading, int alignment) { addText(phrase); setSimpleColumn(llx, lly, urx, ury, leading, alignment); } /** * Simplified method for rectangular columns. * * @param llx the lower left x corner * @param lly the lower left y corner * @param urx the upper right x corner * @param ury the upper right y corner * @param leading the leading * @param alignment the column alignment */ public void setSimpleColumn(float llx, float lly, float urx, float ury, float leading, int alignment) { setLeading(leading); this.alignment = alignment; setSimpleColumn(llx, lly, urx, ury); } /** * Simplified method for rectangular columns. * * @param llx * @param lly * @param urx * @param ury */ public void setSimpleColumn(float llx, float lly, float urx, float ury) { leftX = Math.min(llx, urx); maxY = Math.max(lly, ury); minY = Math.min(lly, ury); rightX = Math.max(llx, urx); yLine = maxY; rectangularWidth = rightX - leftX; if (rectangularWidth < 0) rectangularWidth = 0; rectangularMode = true; } /** * Sets the leading to fixed. * * @param leading the leading */ public void setLeading(float leading) { fixedLeading = leading; multipliedLeading = 0; } /** * Sets the leading fixed and variable. The resultant leading will be * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the * size of the biggest font in the line. * * @param fixedLeading the fixed leading * @param multipliedLeading the variable leading */ public void setLeading(float fixedLeading, float multipliedLeading) { this.fixedLeading = fixedLeading; this.multipliedLeading = multipliedLeading; } /** * Gets the fixed leading. * * @return the leading */ public float getLeading() { return fixedLeading; } /** * Gets the variable leading. * * @return the leading */ public float getMultipliedLeading() { return multipliedLeading; } /** * Sets the yLine. The line will be written to yLine-leading. * * @param yLine the yLine */ public void setYLine(float yLine) { this.yLine = yLine; } /** * Gets the yLine. * * @return the yLine */ public float getYLine() { return yLine; } /** * Sets the alignment. * * @param alignment the alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * Gets the alignment. * * @return the alignment */ public int getAlignment() { return alignment; } /** * Sets the first paragraph line indent. * * @param indent the indent */ public void setIndent(float indent) { this.indent = indent; lastWasNewline = true; } /** * Gets the first paragraph line indent. * * @return the indent */ public float getIndent() { return indent; } /** * Sets the following paragraph lines indent. * * @param indent the indent */ public void setFollowingIndent(float indent) { this.followingIndent = indent; lastWasNewline = true; } /** * Gets the following paragraph lines indent. * * @return the indent */ public float getFollowingIndent() { return followingIndent; } /** * Sets the right paragraph lines indent. * * @param indent the indent */ public void setRightIndent(float indent) { this.rightIndent = indent; lastWasNewline = true; } /** * Gets the right paragraph lines indent. * * @return the indent */ public float getRightIndent() { return rightIndent; } /** * Outputs the lines to the document. It is equivalent to go(false). * * @return returns the result of the operation. It can be NO_MORE_TEXT * and/or NO_MORE_COLUMN * @throws DocumentException on error */ public int go() throws DocumentException { return go(false); } /** * Outputs the lines to the document. The output can be simulated. * @param simulate true to simulate the writing to the document * @return returns the result of the operation. It can be NO_MORE_TEXT * and/or NO_MORE_COLUMN * @throws DocumentException on error */ public int go(boolean simulate) throws DocumentException { if (composite) return goComposite(simulate); addWaitingPhrase(); if (bidiLine == null) return NO_MORE_TEXT; descender = 0; linesWritten = 0; boolean dirty = false; float ratio = spaceCharRatio; Object currentValues[] = new Object[2]; PdfFont currentFont = null; Float lastBaseFactor = new Float(0); currentValues[1] = lastBaseFactor; PdfDocument pdf = null; PdfContentByte graphics = null; PdfContentByte text = null; firstLineY = Float.NaN; int localRunDirection = PdfWriter.RUN_DIRECTION_NO_BIDI; if (runDirection != PdfWriter.RUN_DIRECTION_DEFAULT) localRunDirection = runDirection; if (canvas != null) { graphics = canvas; pdf = canvas.getPdfDocument(); text = canvas.getDuplicate(); } else if (!simulate) throw new NullPointerException("ColumnText.go with simulate==false and text==null."); if (!simulate) { if (ratio == GLOBAL_SPACE_CHAR_RATIO) ratio = text.getPdfWriter().getSpaceCharRatio(); else if (ratio < 0.001f) ratio = 0.001f; } float firstIndent = 0; PdfLine line; float x1; int status = 0; while(true) { firstIndent = (lastWasNewline ? indent : followingIndent); // if (rectangularMode) { if (rectangularWidth <= firstIndent + rightIndent) { status = NO_MORE_COLUMN; if (bidiLine.isEmpty()) status |= NO_MORE_TEXT; break; } if (bidiLine.isEmpty()) { status = NO_MORE_TEXT; break; } line = bidiLine.processLine(leftX, rectangularWidth - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); if (line == null) { status = NO_MORE_TEXT; break; } float[] maxSize = line.getMaxSize(); if (isUseAscender() && Float.isNaN(firstLineY)) currentLeading = line.getAscender(); else currentLeading = Math.max(fixedLeading + maxSize[0] * multipliedLeading, maxSize[1]); if (yLine > maxY || yLine - currentLeading < minY ) { status = NO_MORE_COLUMN; bidiLine.restore(); break; } yLine -= currentLeading; if (!simulate && !dirty) { text.beginText(); dirty = true; } if (Float.isNaN(firstLineY)) firstLineY = yLine; updateFilledWidth(rectangularWidth - line.widthLeft()); x1 = leftX; } else { float yTemp = yLine; float xx[] = findLimitsTwoLines(); if (xx == null) { status = NO_MORE_COLUMN; if (bidiLine.isEmpty()) status |= NO_MORE_TEXT; yLine = yTemp; break; } if (bidiLine.isEmpty()) { status = NO_MORE_TEXT; yLine = yTemp; break; } x1 = Math.max(xx[0], xx[2]); float x2 = Math.min(xx[1], xx[3]); if (x2 - x1 <= firstIndent + rightIndent) continue; if (!simulate && !dirty) { text.beginText(); dirty = true; } line = bidiLine.processLine(x1, x2 - x1 - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); if (line == null) { status = NO_MORE_TEXT; yLine = yTemp; break; } } if (!simulate) { currentValues[0] = currentFont; text.setTextMatrix(x1 + (line.isRTL() ? rightIndent : firstIndent) + line.indentLeft(), yLine); pdf.writeLineToContent(line, text, graphics, currentValues, ratio); currentFont = (PdfFont)currentValues[0]; } lastWasNewline = line.isNewlineSplit(); yLine -= line.isNewlineSplit() ? extraParagraphSpace : 0; ++linesWritten; descender = line.getDescender(); } if (dirty) { text.endText(); canvas.add(text); } return status; } /** * Sets the extra space between paragraphs. * * @return the extra space between paragraphs */ public float getExtraParagraphSpace() { return extraParagraphSpace; } /** * Sets the extra space between paragraphs. * * @param extraParagraphSpace the extra space between paragraphs */ public void setExtraParagraphSpace(float extraParagraphSpace) { this.extraParagraphSpace = extraParagraphSpace; } /** * Clears the chunk array. * A call to go() will always return NO_MORE_TEXT. */ public void clearChunks() { if (bidiLine != null) bidiLine.clearChunks(); } /** * Gets the space/character extra spacing ratio for fully justified text. * * @return the space/character extra spacing ratio */ public float getSpaceCharRatio() { return spaceCharRatio; } /** * Sets the ratio between the extra word spacing and the extra character * spacing when the text is fully justified. * Extra word spacing will grow spaceCharRatio times more * than extra character spacing. * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the * extra character spacing will be zero. * * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing */ public void setSpaceCharRatio(float spaceCharRatio) { this.spaceCharRatio = spaceCharRatio; } /** * Sets the run direction. * * @param runDirection the run direction */ public void setRunDirection(int runDirection) { if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) throw new RuntimeException("Invalid run direction: " + runDirection); this.runDirection = runDirection; } /** * Gets the run direction. * * @return the run direction */ public int getRunDirection() { return runDirection; } /** * Gets the number of lines written. * * @return the number of lines written */ public int getLinesWritten() { return this.linesWritten; } /** * Gets the arabic shaping options. * * @return the arabic shaping options */ public int getArabicOptions() { return this.arabicOptions; } /** * Sets the arabic shaping options. The option can be AR_NOVOWEL, * AR_COMPOSEDTASHKEEL and AR_LIG. * * @param arabicOptions the arabic shaping options */ public void setArabicOptions(int arabicOptions) { this.arabicOptions = arabicOptions; } /** * Gets the biggest descender value of the last line written. * * @return the biggest descender value of the last line written */ public float getDescender() { return descender; } /** * Gets the width that the line will occupy after writing. * Only the width of the first line is returned. * * @param phrase the Phrase containing the line * @param runDirection the run direction * @param arabicOptions the options for the arabic shaping * @return the width of the line */ public static float getWidth(Phrase phrase, int runDirection, int arabicOptions) { ColumnText ct = new ColumnText(null); ct.addText(phrase); ct.addWaitingPhrase(); PdfLine line = ct.bidiLine.processLine(0, 20000, Element.ALIGN_LEFT, runDirection, arabicOptions); if (line == null) return 0; else return 20000 - line.widthLeft(); } /** * Gets the width that the line will occupy after writing. * Only the width of the first line is returned. * * @param phrase the Phrase containing the line * @return the width of the line */ public static float getWidth(Phrase phrase) { return getWidth(phrase, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); } /** * Shows a line of text. Only the first line is written. * * @param canvas where the text is to be written to * @param alignment the alignment. It is not influenced by the run direction * @param phrase the Phrase with the text * @param x the x reference position * @param y the y reference position * @param rotation the rotation to be applied in degrees counterclockwise * @param runDirection the run direction * @param arabicOptions the options for the arabic shaping */ public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation, int runDirection, int arabicOptions) { if (alignment != Element.ALIGN_LEFT && alignment != Element.ALIGN_CENTER && alignment != Element.ALIGN_RIGHT) alignment = Element.ALIGN_LEFT; canvas.saveState(); ColumnText ct = new ColumnText(canvas); float lly = -1; float ury = 2; float llx; float urx; switch (alignment) { case Element.ALIGN_LEFT: llx = 0; urx = 20000; break; case Element.ALIGN_RIGHT: llx = -20000; urx = 0; break; default: llx = -20000; urx = 20000; break; } if (rotation == 0) { llx += x; lly += y; urx += x; ury += y; } else { double alpha = rotation * Math.PI / 180.0; float cos = (float)Math.cos(alpha); float sin = (float)Math.sin(alpha); canvas.concatCTM(cos, sin, -sin, cos, x, y); } ct.setSimpleColumn(phrase, llx, lly, urx, ury, 2, alignment); if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { if (alignment == Element.ALIGN_LEFT) alignment = Element.ALIGN_RIGHT; else if (alignment == Element.ALIGN_RIGHT) alignment = Element.ALIGN_LEFT; } ct.setAlignment(alignment); ct.setArabicOptions(arabicOptions); ct.setRunDirection(runDirection); try { ct.go(); } catch (DocumentException e) { throw new ExceptionConverter(e); } canvas.restoreState(); } /** * Shows a line of text. Only the first line is written. * * @param canvas where the text is to be written to * @param alignment the alignment * @param phrase the Phrase with the text * @param x the x reference position * @param y the y reference position * @param rotation the rotation to be applied in degrees counterclockwise */ public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation) { showTextAligned(canvas, alignment, phrase, x, y, rotation, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); } protected int goComposite(boolean simulate) throws DocumentException { if (!rectangularMode) throw new DocumentException("Irregular columns are not supported in composite mode."); linesWritten = 0; descender = 0; boolean firstPass = adjustFirstLine; main_loop: while (true) { if (compositeElements.isEmpty()) return NO_MORE_TEXT; Element element = (Element)compositeElements.getFirst(); if (element.type() == Element.PARAGRAPH) { Paragraph para = (Paragraph)element; int status = 0; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; boolean createHere = false; if (compositeColumn == null) { compositeColumn = new ColumnText(canvas); compositeColumn.setUseAscender(firstPass ? useAscender : false); compositeColumn.setAlignment(para.getAlignment()); compositeColumn.setIndent(para.getIndentationLeft() + para.getFirstLineIndent()); compositeColumn.setExtraParagraphSpace(para.getExtraParagraphSpace()); compositeColumn.setFollowingIndent(para.getIndentationLeft()); compositeColumn.setRightIndent(para.getIndentationRight()); compositeColumn.setLeading(para.getLeading(), para.getMultipliedLeading()); compositeColumn.setRunDirection(runDirection); compositeColumn.setArabicOptions(arabicOptions); compositeColumn.setSpaceCharRatio(spaceCharRatio); compositeColumn.addText(para); if (!firstPass) { yLine -= para.getSpacingBefore(); } createHere = true; } compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; boolean keepCandidate = (para.getKeepTogether() && createHere && !firstPass); status = compositeColumn.go(simulate || (keepCandidate && keep == 0)); updateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { compositeColumn = null; yLine = lastY; return NO_MORE_COLUMN; } if (simulate || !keepCandidate) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } firstPass = false; yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; compositeElements.removeFirst(); yLine -= para.getSpacingAfter(); } if ((status & NO_MORE_COLUMN) != 0) { return NO_MORE_COLUMN; } } else if (element.type() == Element.LIST) { com.lowagie.text.List list = (com.lowagie.text.List)element; ArrayList items = list.getItems(); ListItem item = null; float listIndentation = list.getIndentationLeft(); int count = 0; Stack stack = new Stack(); for (int k = 0; k < items.size(); ++k) { Object obj = items.get(k); if (obj instanceof ListItem) { if (count == listIdx) { item = (ListItem)obj; break; } else ++count; } else if (obj instanceof com.lowagie.text.List) { stack.push(new Object[]{list, new Integer(k), new Float(listIndentation)}); list = (com.lowagie.text.List)obj; items = list.getItems(); listIndentation += list.getIndentationLeft(); k = -1; continue; } if (k == items.size() - 1) { if (!stack.isEmpty()) { Object objs[] = (Object[])stack.pop(); list = (com.lowagie.text.List)objs[0]; items = list.getItems(); k = ((Integer)objs[1]).intValue(); listIndentation = ((Float)objs[2]).floatValue(); } } } int status = 0; for (int keep = 0; keep < 2; ++keep) { float lastY = yLine; boolean createHere = false; if (compositeColumn == null) { if (item == null) { listIdx = 0; compositeElements.removeFirst(); continue main_loop; } compositeColumn = new ColumnText(canvas); compositeColumn.setUseAscender(firstPass ? useAscender : false); compositeColumn.setAlignment(item.getAlignment()); compositeColumn.setIndent(item.getIndentationLeft() + listIndentation + item.getFirstLineIndent()); compositeColumn.setExtraParagraphSpace(item.getExtraParagraphSpace()); compositeColumn.setFollowingIndent(compositeColumn.getIndent()); compositeColumn.setRightIndent(item.getIndentationRight() + list.getIndentationRight()); compositeColumn.setLeading(item.getLeading(), item.getMultipliedLeading()); compositeColumn.setRunDirection(runDirection); compositeColumn.setArabicOptions(arabicOptions); compositeColumn.setSpaceCharRatio(spaceCharRatio); compositeColumn.addText(item); if (!firstPass) { yLine -= item.getSpacingBefore(); } createHere = true; } compositeColumn.leftX = leftX; compositeColumn.rightX = rightX; compositeColumn.yLine = yLine; compositeColumn.rectangularWidth = rectangularWidth; compositeColumn.rectangularMode = rectangularMode; compositeColumn.minY = minY; compositeColumn.maxY = maxY; boolean keepCandidate = (item.getKeepTogether() && createHere && !firstPass); status = compositeColumn.go(simulate || (keepCandidate && keep == 0)); updateFilledWidth(compositeColumn.filledWidth); if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { compositeColumn = null; yLine = lastY; return NO_MORE_COLUMN; } if (simulate || !keepCandidate) break; if (keep == 0) { compositeColumn = null; yLine = lastY; } } firstPass = false; yLine = compositeColumn.yLine; linesWritten += compositeColumn.linesWritten; descender = compositeColumn.descender; if (!Float.isNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) { if (!simulate) showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.getListSymbol()), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0); compositeColumn.firstLineYDone = true; } if ((status & NO_MORE_TEXT) != 0) { compositeColumn = null; ++listIdx; yLine -= item.getSpacingAfter(); } if ((status & NO_MORE_COLUMN) != 0) return NO_MORE_COLUMN; } else if (element.type() == Element.PTABLE) { // don't write anything in the current column if there's no more space available if (yLine < minY || yLine > maxY) return NO_MORE_COLUMN; // get the PdfPTable element PdfPTable table = (PdfPTable)element; // we ignore tables without a body if (table.size() <= table.getHeaderRows()) { compositeElements.removeFirst(); continue; } // offsets float yTemp = yLine; if (!firstPass && listIdx == 0) yTemp -= table.spacingBefore(); float yLineWrite = yTemp; // don't write anything in the current column if there's no more space available if (yTemp < minY || yTemp > maxY) return NO_MORE_COLUMN; // coordinates currentLeading = 0; float x1 = leftX; float tableWidth; if (table.isLockedWidth()) { tableWidth = table.getTotalWidth(); updateFilledWidth(tableWidth); } else { tableWidth = rectangularWidth * table.getWidthPercentage() / 100f; table.setTotalWidth(tableWidth); } // how many header rows are real header rows; how many are footer rows? int headerRows = table.getHeaderRows(); int footerRows = table.getFooterRows(); if (footerRows > headerRows) footerRows = headerRows; int realHeaderRows = headerRows - footerRows; float headerHeight = table.getHeaderHeight(); float footerHeight = table.getFooterHeight(); // make sure the header and footer fit on the page boolean skipHeader = (!firstPass && table.isSkipFirstHeader() && listIdx <= headerRows); if (!skipHeader) { yTemp -= headerHeight; if (yTemp < minY || yTemp > maxY) { if (firstPass) { compositeElements.removeFirst(); continue; } return NO_MORE_COLUMN; } } // how many real rows (not header or footer rows) fit on a page? int k; if (listIdx < headerRows) listIdx = headerRows; if (!table.isComplete()) yTemp -= footerHeight; for (k = listIdx; k < table.size(); ++k) { float rowHeight = table.getRowHeight(k); if (yTemp - rowHeight < minY) break; yTemp -= rowHeight; } if (!table.isComplete()) yTemp += footerHeight; // either k is the first row that doesn't fit on the page (break); if (k < table.size()) { if (table.isSplitRows() && (!table.isSplitLate() || (k == listIdx && firstPass))) { if (!splittedRow) { splittedRow = true; table = new PdfPTable(table); compositeElements.set(0, table); ArrayList rows = table.getRows(); for (int i = headerRows; i < listIdx; ++i) rows.set(i, null); } float h = yTemp - minY; PdfPRow newRow = table.getRow(k).splitRow(table, k, h); if (newRow == null) { if (k == listIdx) return NO_MORE_COLUMN; } else { yTemp = minY; table.getRows().add(++k, newRow); } } else if (!table.isSplitRows() && k == listIdx && firstPass) { compositeElements.removeFirst(); splittedRow = false; continue; } else if (k == listIdx && !firstPass && (!table.isSplitRows() || table.isSplitLate()) && (table.getFooterRows() == 0 || table.isComplete())) return NO_MORE_COLUMN; } // or k is the number of rows in the table (for loop was done). firstPass = false; // we draw the table (for real now) if (!simulate) { // set the alignment switch (table.getHorizontalAlignment()) { case Element.ALIGN_LEFT: break; case Element.ALIGN_RIGHT: x1 += rectangularWidth - tableWidth; break; default: x1 += (rectangularWidth - tableWidth) / 2f; } // copy the rows that fit on the page in a new table nt PdfPTable nt = PdfPTable.shallowCopy(table); ArrayList sub = nt.getRows(); // first we add the real header rows (if necessary) if (!skipHeader) { for (int j = 0; j < realHeaderRows; ++j) { PdfPRow headerRow = table.getRow(j); sub.add(headerRow); } } else nt.setHeaderRows(footerRows); // then we add the real content sub.addAll(table.getRows(listIdx, k)); // if k < table.size(), we must indicate that the new table is complete; // otherwise no footers will be added (because iText thinks the table continues on the same page) boolean showFooter = !table.isSkipLastFooter(); if (k < table.size()) { nt.setComplete(true); showFooter = true; } // we add the footer rows if necessary (not for incomplete tables) for (int j = 0; j < footerRows && nt.isComplete() && showFooter; ++j) sub.add(table.getRow(j + realHeaderRows)); // we need a correction if the last row needs to be extended float rowHeight = 0; PdfPRow last = (PdfPRow)sub.get(sub.size() - 1 - footerRows); if (table.isExtendLastRow()) { rowHeight = last.getMaxHeights(); last.setMaxHeights(yTemp - minY + rowHeight); yTemp = minY; } // now we render the rows of the new table if (canvases != null) nt.writeSelectedRows(0, -1, x1, yLineWrite, canvases); else nt.writeSelectedRows(0, -1, x1, yLineWrite, canvas); if (table.isExtendLastRow()) { last.setMaxHeights(rowHeight); } } else if (table.isExtendLastRow() && minY > PdfPRow.BOTTOM_LIMIT) yTemp = minY; yLine = yTemp; if (!(skipHeader || table.isComplete())) yLine += footerHeight; if (k >= table.size()) { yLine -= table.spacingAfter(); compositeElements.removeFirst(); splittedRow = false; listIdx = 0; } else { if (splittedRow) { ArrayList rows = table.getRows(); for (int i = listIdx; i < k; ++i) rows.set(i, null); } listIdx = k; return NO_MORE_COLUMN; } } else if (element.type() == Element.YMARK) { if (!simulate) { DrawInterface zh = (DrawInterface)element; zh.draw(canvas, leftX, minY, rightX, maxY, yLine); } compositeElements.removeFirst(); } else compositeElements.removeFirst(); } } /** * Gets the canvas. * If a set of four canvases exists, the TEXTCANVAS is returned. * * @return a PdfContentByte. */ public PdfContentByte getCanvas() { return canvas; } /** * Sets the canvas. * If before a set of four canvases was set, it is being unset. * * @param canvas */ public void setCanvas(PdfContentByte canvas) { this.canvas = canvas; this.canvases = null; if (compositeColumn != null) compositeColumn.setCanvas(canvas); } /** * Sets the canvases. * * @param canvases */ public void setCanvases(PdfContentByte[] canvases) { this.canvases = canvases; this.canvas = canvases[PdfPTable.TEXTCANVAS]; if (compositeColumn != null) compositeColumn.setCanvases(canvases); } /** * Gets the canvases. * * @return an array of PdfContentByte */ public PdfContentByte[] getCanvases() { return canvases; } /** * Checks if the element has a height of 0. * * @return true or false * @since 2.1.2 */ public boolean zeroHeightElement() { return composite && !compositeElements.isEmpty() && ((Element)compositeElements.getFirst()).type() == Element.YMARK; } /** * Checks if UseAscender is enabled/disabled. * * @return true is the adjustment of the first line height is based on max ascender. */ public boolean isUseAscender() { return useAscender; } /** * Enables/Disables adjustment of first line height based on max ascender. * * @param useAscender enable adjustment if true */ public void setUseAscender(boolean useAscender) { this.useAscender = useAscender; } /** * Checks the status variable and looks if there's still some text. */ public static boolean hasMoreText(int status) { return (status & ColumnText.NO_MORE_TEXT) == 0; } /** * Gets the real width used by the largest line. * * @return the real width used by the largest line */ public float getFilledWidth() { return filledWidth; } /** * Sets the real width used by the largest line. * Only used to set it to zero to start another measurement. * * @param filledWidth the real width used by the largest line */ public void setFilledWidth(float filledWidth) { this.filledWidth = filledWidth; } /** * Replaces the filledWidth if greater than the existing one. * * @param w the new filledWidth if greater than the existing one */ public void updateFilledWidth(float w) { if (w > filledWidth) filledWidth = w; } /** * Gets the first line adjustment property. * * @return the first line adjustment property. */ public boolean isAdjustFirstLine() { return adjustFirstLine; } /** * Sets the first line adjustment. * Some objects have properties, like spacing before, that behave * differently if the object is the first to be written after go() or not. * The first line adjustment is true by default but can be * changed if several objects are to be placed one after the other in the * same column calling go() several times. * * @param adjustFirstLine true to adjust the first line, false otherwise */ public void setAdjustFirstLine(boolean adjustFirstLine) { this.adjustFirstLine = adjustFirstLine; } } src/core/com/lowagie/text/pdf/DefaultFontMapper.java100644 0 0 25763 11000354131 20132 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Font; import java.io.File; import java.util.HashMap; import com.lowagie.text.ExceptionConverter; /** Default class to map awt fonts to BaseFont. * @author Paulo Soares (psoares@consiste.pt) */ public class DefaultFontMapper implements FontMapper { /** A representation of BaseFont parameters. */ public static class BaseFontParameters { /** The font name. */ public String fontName; /** The encoding for that font. */ public String encoding; /** The embedding for that font. */ public boolean embedded; /** Whether the font is cached of not. */ public boolean cached; /** The font bytes for ttf and afm. */ public byte ttfAfm[]; /** The font bytes for pfb. */ public byte pfb[]; /** Constructs default BaseFont parameters. * @param fontName the font name or location */ public BaseFontParameters(String fontName) { this.fontName = fontName; encoding = BaseFont.CP1252; embedded = BaseFont.EMBEDDED; cached = BaseFont.CACHED; } } /** Maps aliases to names. */ private HashMap aliases = new HashMap(); /** Maps names to BaseFont parameters. */ private HashMap mapper = new HashMap(); /** * Returns a BaseFont which can be used to represent the given AWT Font * * @param font the font to be converted * @return a BaseFont which has similar properties to the provided Font */ public BaseFont awtToPdf(Font font) { try { BaseFontParameters p = getBaseFontParameters(font.getFontName()); if (p != null) return BaseFont.createFont(p.fontName, p.encoding, p.embedded, p.cached, p.ttfAfm, p.pfb); String fontKey = null; String logicalName = font.getName(); if (logicalName.equalsIgnoreCase("DialogInput") || logicalName.equalsIgnoreCase("Monospaced") || logicalName.equalsIgnoreCase("Courier")) { if (font.isItalic()) { if (font.isBold()) { fontKey = BaseFont.COURIER_BOLDOBLIQUE; } else { fontKey = BaseFont.COURIER_OBLIQUE; } } else { if (font.isBold()) { fontKey = BaseFont.COURIER_BOLD; } else { fontKey = BaseFont.COURIER; } } } else if (logicalName.equalsIgnoreCase("Serif") || logicalName.equalsIgnoreCase("TimesRoman")) { if (font.isItalic()) { if (font.isBold()) { fontKey = BaseFont.TIMES_BOLDITALIC; } else { fontKey = BaseFont.TIMES_ITALIC; } } else { if (font.isBold()) { fontKey = BaseFont.TIMES_BOLD; } else { fontKey = BaseFont.TIMES_ROMAN; } } } else { // default, this catches Dialog and SansSerif if (font.isItalic()) { if (font.isBold()) { fontKey = BaseFont.HELVETICA_BOLDOBLIQUE; } else { fontKey = BaseFont.HELVETICA_OBLIQUE; } } else { if (font.isBold()) { fontKey = BaseFont.HELVETICA_BOLD; } else { fontKey = BaseFont.HELVETICA; } } } return BaseFont.createFont(fontKey, BaseFont.CP1252, false); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Returns an AWT Font which can be used to represent the given BaseFont * * @param font the font to be converted * @param size the desired point size of the resulting font * @return a Font which has similar properties to the provided BaseFont */ public Font pdfToAwt(BaseFont font, int size) { String names[][] = font.getFullFontName(); if (names.length == 1) return new Font(names[0][3], 0, size); String name10 = null; String name3x = null; for (int k = 0; k < names.length; ++k) { String name[] = names[k]; if (name[0].equals("1") && name[1].equals("0")) name10 = name[3]; else if (name[2].equals("1033")) { name3x = name[3]; break; } } String finalName = name3x; if (finalName == null) finalName = name10; if (finalName == null) finalName = names[0][3]; return new Font(finalName, 0, size); } /** Maps a name to a BaseFont parameter. * @param awtName the name * @param parameters the BaseFont parameter */ public void putName(String awtName, BaseFontParameters parameters) { mapper.put(awtName, parameters); } /** Maps an alias to a name. * @param alias the alias * @param awtName the name */ public void putAlias(String alias, String awtName) { aliases.put(alias, awtName); } /** Looks for a BaseFont parameter associated with a name. * @param name the name * @return the BaseFont parameter or null if not found. */ public BaseFontParameters getBaseFontParameters(String name) { String alias = (String)aliases.get(name); if (alias == null) return (BaseFontParameters)mapper.get(name); BaseFontParameters p = (BaseFontParameters)mapper.get(alias); if (p == null) return (BaseFontParameters)mapper.get(name); else return p; } /** * Inserts the names in this map. * @param allNames the returned value of calling {@link BaseFont#getAllFontNames(String, String, byte[])} * @param path the full path to the font */ public void insertNames(Object allNames[], String path) { String names[][] = (String[][])allNames[2]; String main = null; for (int k = 0; k < names.length; ++k) { String name[] = names[k]; if (name[2].equals("1033")) { main = name[3]; break; } } if (main == null) main = names[0][3]; BaseFontParameters p = new BaseFontParameters(path); mapper.put(main, p); for (int k = 0; k < names.length; ++k) { aliases.put(names[k][3], main); } aliases.put(allNames[0], main); } /** Inserts all the fonts recognized by iText in the * directory into the map. The encoding * will be BaseFont.CP1252 but can be * changed later. * @param dir the directory to scan * @return the number of files processed */ public int insertDirectory(String dir) { File file = new File(dir); if (!file.exists() || !file.isDirectory()) return 0; File files[] = file.listFiles(); if (files == null) return 0; int count = 0; for (int k = 0; k < files.length; ++k) { file = files[k]; String name = file.getPath().toLowerCase(); try { if (name.endsWith(".ttf") || name.endsWith(".otf") || name.endsWith(".afm")) { Object allNames[] = BaseFont.getAllFontNames(file.getPath(), BaseFont.CP1252, null); insertNames(allNames, file.getPath()); ++count; } else if (name.endsWith(".ttc")) { String ttcs[] = BaseFont.enumerateTTCNames(file.getPath()); for (int j = 0; j < ttcs.length; ++j) { String nt = file.getPath() + "," + j; Object allNames[] = BaseFont.getAllFontNames(nt, BaseFont.CP1252, null); insertNames(allNames, nt); } ++count; } } catch (Exception e) { } } return count; } public HashMap getMapper() { return mapper; } public HashMap getAliases() { return aliases; } } src/core/com/lowagie/text/pdf/DefaultSplitCharacter.java100644 0 0 11013 11036112746 20763 0ustar 0 0 /* * $Id: DefaultSplitCharacter.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2008 Bruno Lowagie and Xavier Le Vourch * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.SplitCharacter; /** * The default class that is used to determine whether or not a character * is a split character. You can subclass this class to define your own * split characters. * @since 2.1.2 */ public class DefaultSplitCharacter implements SplitCharacter { /** * An instance of the default SplitCharacter. */ public static final SplitCharacter DEFAULT = new DefaultSplitCharacter(); /** * Checks if a character can be used to split a PdfString. *

* for the moment every character less than or equal to SPACE, the character '-' * and some specific unicode ranges are 'splitCharacters'. * * @param start start position in the array * @param current current position in the array * @param end end position in the array * @param cc the character array that has to be checked * @param ck chunk array * @return true if the character can be used to split a string, false otherwise */ public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { char c = getCurrentCharacter(current, cc, ck); if (c <= ' ' || c == '-' || c == '\u2010') { return true; } if (c < 0x2002) return false; return ((c >= 0x2002 && c <= 0x200b) || (c >= 0x2e80 && c < 0xd7a0) || (c >= 0xf900 && c < 0xfb00) || (c >= 0xfe30 && c < 0xfe50) || (c >= 0xff61 && c < 0xffa0)); } /** * Returns the current character * @param current current position in the array * @param cc the character array that has to be checked * @param ck chunk array * @return the current character */ protected char getCurrentCharacter(int current, char[] cc, PdfChunk[] ck) { if (ck == null) { return cc[current]; } return (char)ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]); } } src/core/com/lowagie/text/pdf/DocumentFont.java100644 0 0 64525 11224570760 17176 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.HashMap; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; /** * * @author psoares */ public class DocumentFont extends BaseFont { // code, [glyph, width] private HashMap metrics = new HashMap(); private String fontName; private PRIndirectReference refFont; private PdfDictionary font; private IntHashtable uni2byte = new IntHashtable(); private IntHashtable diffmap; private float Ascender = 800; private float CapHeight = 700; private float Descender = -200; private float ItalicAngle = 0; private float llx = -50; private float lly = -200; private float urx = 100; private float ury = 900; private boolean isType0 = false; private BaseFont cjkMirror; private static String cjkNames[] = {"HeiseiMin-W3", "HeiseiKakuGo-W5", "STSong-Light", "MHei-Medium", "MSung-Light", "HYGoThic-Medium", "HYSMyeongJo-Medium", "MSungStd-Light", "STSongStd-Light", "HYSMyeongJoStd-Medium", "KozMinPro-Regular"}; private static String cjkEncs[] = {"UniJIS-UCS2-H", "UniJIS-UCS2-H", "UniGB-UCS2-H", "UniCNS-UCS2-H", "UniCNS-UCS2-H", "UniKS-UCS2-H", "UniKS-UCS2-H", "UniCNS-UCS2-H", "UniGB-UCS2-H", "UniKS-UCS2-H", "UniJIS-UCS2-H"}; private static String cjkNames2[] = {"MSungStd-Light", "STSongStd-Light", "HYSMyeongJoStd-Medium", "KozMinPro-Regular"}; private static String cjkEncs2[] = {"UniCNS-UCS2-H", "UniGB-UCS2-H", "UniKS-UCS2-H", "UniJIS-UCS2-H", "UniCNS-UTF16-H", "UniGB-UTF16-H", "UniKS-UTF16-H", "UniJIS-UTF16-H"}; private static final int stdEnc[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 32,33,34,35,36,37,38,8217,40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, 8216,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,161,162,163,8260,165,402,167,164,39,8220,171,8249,8250,64257,64258, 0,8211,8224,8225,183,0,182,8226,8218,8222,8221,187,8230,8240,0,191, 0,96,180,710,732,175,728,729,168,0,730,184,0,733,731,711, 8212,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,198,0,170,0,0,0,0,321,216,338,186,0,0,0,0, 0,230,0,0,0,305,0,0,322,248,339,223,0,0,0,0}; /** Creates a new instance of DocumentFont */ DocumentFont(PRIndirectReference refFont) { encoding = ""; fontSpecific = false; this.refFont = refFont; fontType = FONT_TYPE_DOCUMENT; font = (PdfDictionary)PdfReader.getPdfObject(refFont); fontName = PdfName.decodeName(font.getAsName(PdfName.BASEFONT).toString()); PdfName subType = font.getAsName(PdfName.SUBTYPE); if (PdfName.TYPE1.equals(subType) || PdfName.TRUETYPE.equals(subType)) doType1TT(); else { for (int k = 0; k < cjkNames.length; ++k) { if (fontName.startsWith(cjkNames[k])) { fontName = cjkNames[k]; try { cjkMirror = BaseFont.createFont(fontName, cjkEncs[k], false); } catch (Exception e) { throw new ExceptionConverter(e); } return; } } String enc = PdfName.decodeName(font.getAsName(PdfName.ENCODING).toString()); for (int k = 0; k < cjkEncs2.length; ++k) { if (enc.startsWith(cjkEncs2[k])) { try { if (k > 3) k -= 4; cjkMirror = BaseFont.createFont(cjkNames2[k], cjkEncs2[k], false); } catch (Exception e) { throw new ExceptionConverter(e); } return; } } if (PdfName.TYPE0.equals(subType) && enc.equals("Identity-H")) { processType0(font); isType0 = true; } } } private void processType0(PdfDictionary font) { try { PdfObject toUniObject = PdfReader.getPdfObjectRelease(font.get(PdfName.TOUNICODE)); PdfArray df = (PdfArray)PdfReader.getPdfObjectRelease(font.get(PdfName.DESCENDANTFONTS)); PdfDictionary cidft = (PdfDictionary)PdfReader.getPdfObjectRelease(df.getPdfObject(0)); PdfNumber dwo = (PdfNumber)PdfReader.getPdfObjectRelease(cidft.get(PdfName.DW)); int dw = 1000; if (dwo != null) dw = dwo.intValue(); IntHashtable widths = readWidths((PdfArray)PdfReader.getPdfObjectRelease(cidft.get(PdfName.W))); PdfDictionary fontDesc = (PdfDictionary)PdfReader.getPdfObjectRelease(cidft.get(PdfName.FONTDESCRIPTOR)); fillFontDesc(fontDesc); if (toUniObject != null){ fillMetrics(PdfReader.getStreamBytes((PRStream)toUniObject), widths, dw); } } catch (Exception e) { throw new ExceptionConverter(e); } } private IntHashtable readWidths(PdfArray ws) { IntHashtable hh = new IntHashtable(); if (ws == null) return hh; for (int k = 0; k < ws.size(); ++k) { int c1 = ((PdfNumber)PdfReader.getPdfObjectRelease(ws.getPdfObject(k))).intValue(); PdfObject obj = PdfReader.getPdfObjectRelease(ws.getPdfObject(++k)); if (obj.isArray()) { PdfArray a2 = (PdfArray)obj; for (int j = 0; j < a2.size(); ++j) { int c2 = ((PdfNumber)PdfReader.getPdfObjectRelease(a2.getPdfObject(j))).intValue(); hh.put(c1++, c2); } } else { int c2 = ((PdfNumber)obj).intValue(); int w = ((PdfNumber)PdfReader.getPdfObjectRelease(ws.getPdfObject(++k))).intValue(); for (; c1 <= c2; ++c1) hh.put(c1, w); } } return hh; } private String decodeString(PdfString ps) { if (ps.isHexWriting()) return PdfEncodings.convertToString(ps.getBytes(), "UnicodeBigUnmarked"); else return ps.toUnicodeString(); } private void fillMetrics(byte[] touni, IntHashtable widths, int dw) { try { PdfContentParser ps = new PdfContentParser(new PRTokeniser(touni)); PdfObject ob = null; PdfObject last = null; while ((ob = ps.readPRObject()) != null) { if (ob.type() == PdfContentParser.COMMAND_TYPE) { if (ob.toString().equals("beginbfchar")) { int n = ((PdfNumber)last).intValue(); for (int k = 0; k < n; ++k) { String cid = decodeString((PdfString)ps.readPRObject()); String uni = decodeString((PdfString)ps.readPRObject()); if (uni.length() == 1) { int cidc = cid.charAt(0); int unic = uni.charAt(uni.length() - 1); int w = dw; if (widths.containsKey(cidc)) w = widths.get(cidc); metrics.put(new Integer(unic), new int[]{cidc, w}); } } } else if (ob.toString().equals("beginbfrange")) { int n = ((PdfNumber)last).intValue(); for (int k = 0; k < n; ++k) { String cid1 = decodeString((PdfString)ps.readPRObject()); String cid2 = decodeString((PdfString)ps.readPRObject()); int cid1c = cid1.charAt(0); int cid2c = cid2.charAt(0); PdfObject ob2 = ps.readPRObject(); if (ob2.isString()) { String uni = decodeString((PdfString)ob2); if (uni.length() == 1) { int unic = uni.charAt(uni.length() - 1); for (; cid1c <= cid2c; cid1c++, unic++) { int w = dw; if (widths.containsKey(cid1c)) w = widths.get(cid1c); metrics.put(new Integer(unic), new int[]{cid1c, w}); } } } else { PdfArray a = (PdfArray)ob2; for (int j = 0; j < a.size(); ++j, ++cid1c) { String uni = decodeString(a.getAsString(j)); if (uni.length() == 1) { int unic = uni.charAt(uni.length() - 1); int w = dw; if (widths.containsKey(cid1c)) w = widths.get(cid1c); metrics.put(new Integer(unic), new int[]{cid1c, w}); } } } } } } else last = ob; } } catch (Exception e) { throw new ExceptionConverter(e); } } private void doType1TT() { PdfObject enc = PdfReader.getPdfObject(font.get(PdfName.ENCODING)); if (enc == null) fillEncoding(null); else { if (enc.isName()) fillEncoding((PdfName)enc); else { PdfDictionary encDic = (PdfDictionary)enc; enc = PdfReader.getPdfObject(encDic.get(PdfName.BASEENCODING)); if (enc == null) fillEncoding(null); else fillEncoding((PdfName)enc); PdfArray diffs = encDic.getAsArray(PdfName.DIFFERENCES); if (diffs != null) { diffmap = new IntHashtable(); int currentNumber = 0; for (int k = 0; k < diffs.size(); ++k) { PdfObject obj = diffs.getPdfObject(k); if (obj.isNumber()) currentNumber = ((PdfNumber)obj).intValue(); else { int c[] = GlyphList.nameToUnicode(PdfName.decodeName(((PdfName)obj).toString())); if (c != null && c.length > 0) { uni2byte.put(c[0], currentNumber); diffmap.put(c[0], currentNumber); } ++currentNumber; } } } } } PdfArray newWidths = font.getAsArray(PdfName.WIDTHS); PdfNumber first = font.getAsNumber(PdfName.FIRSTCHAR); PdfNumber last = font.getAsNumber(PdfName.LASTCHAR); if (BuiltinFonts14.containsKey(fontName)) { BaseFont bf; try { bf = BaseFont.createFont(fontName, WINANSI, false); } catch (Exception e) { throw new ExceptionConverter(e); } int e[] = uni2byte.toOrderedKeys(); for (int k = 0; k < e.length; ++k) { int n = uni2byte.get(e[k]); widths[n] = bf.getRawWidth(n, GlyphList.unicodeToName(e[k])); } if (diffmap != null) { //widths for diffmap must override existing ones e = diffmap.toOrderedKeys(); for (int k = 0; k < e.length; ++k) { int n = diffmap.get(e[k]); widths[n] = bf.getRawWidth(n, GlyphList.unicodeToName(e[k])); } diffmap = null; } Ascender = bf.getFontDescriptor(ASCENT, 1000); CapHeight = bf.getFontDescriptor(CAPHEIGHT, 1000); Descender = bf.getFontDescriptor(DESCENT, 1000); ItalicAngle = bf.getFontDescriptor(ITALICANGLE, 1000); llx = bf.getFontDescriptor(BBOXLLX, 1000); lly = bf.getFontDescriptor(BBOXLLY, 1000); urx = bf.getFontDescriptor(BBOXURX, 1000); ury = bf.getFontDescriptor(BBOXURY, 1000); } if (first != null && last != null && newWidths != null) { int f = first.intValue(); for (int k = 0; k < newWidths.size(); ++k) { widths[f + k] = newWidths.getAsNumber(k).intValue(); } } fillFontDesc(font.getAsDict(PdfName.FONTDESCRIPTOR)); } private void fillFontDesc(PdfDictionary fontDesc) { if (fontDesc == null) return; PdfNumber v = fontDesc.getAsNumber(PdfName.ASCENT); if (v != null) Ascender = v.floatValue(); v = fontDesc.getAsNumber(PdfName.CAPHEIGHT); if (v != null) CapHeight = v.floatValue(); v = fontDesc.getAsNumber(PdfName.DESCENT); if (v != null) Descender = v.floatValue(); v = fontDesc.getAsNumber(PdfName.ITALICANGLE); if (v != null) ItalicAngle = v.floatValue(); PdfArray bbox = fontDesc.getAsArray(PdfName.FONTBBOX); if (bbox != null) { llx = bbox.getAsNumber(0).floatValue(); lly = bbox.getAsNumber(1).floatValue(); urx = bbox.getAsNumber(2).floatValue(); ury = bbox.getAsNumber(3).floatValue(); if (llx > urx) { float t = llx; llx = urx; urx = t; } if (lly > ury) { float t = lly; lly = ury; ury = t; } } } private void fillEncoding(PdfName encoding) { if (PdfName.MAC_ROMAN_ENCODING.equals(encoding) || PdfName.WIN_ANSI_ENCODING.equals(encoding)) { byte b[] = new byte[256]; for (int k = 0; k < 256; ++k) b[k] = (byte)k; String enc = WINANSI; if (PdfName.MAC_ROMAN_ENCODING.equals(encoding)) enc = MACROMAN; String cv = PdfEncodings.convertToString(b, enc); char arr[] = cv.toCharArray(); for (int k = 0; k < 256; ++k) { uni2byte.put(arr[k], k); } } else { for (int k = 0; k < 256; ++k) { uni2byte.put(stdEnc[k], k); } } } /** Gets the family name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the family name of the font * */ public String[][] getFamilyFontName() { return getFullFontName(); } /** Gets the font parameter identified by key. Valid values * for key are ASCENT, CAPHEIGHT, DESCENT, * ITALICANGLE, BBOXLLX, BBOXLLY, BBOXURX * and BBOXURY. * @param key the parameter to be extracted * @param fontSize the font size in points * @return the parameter in points * */ public float getFontDescriptor(int key, float fontSize) { if (cjkMirror != null) return cjkMirror.getFontDescriptor(key, fontSize); switch (key) { case AWT_ASCENT: case ASCENT: return Ascender * fontSize / 1000; case CAPHEIGHT: return CapHeight * fontSize / 1000; case AWT_DESCENT: case DESCENT: return Descender * fontSize / 1000; case ITALICANGLE: return ItalicAngle; case BBOXLLX: return llx * fontSize / 1000; case BBOXLLY: return lly * fontSize / 1000; case BBOXURX: return urx * fontSize / 1000; case BBOXURY: return ury * fontSize / 1000; case AWT_LEADING: return 0; case AWT_MAXADVANCE: return (urx - llx) * fontSize / 1000; } return 0; } /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font * */ public String[][] getFullFontName() { return new String[][]{{"", "", "", fontName}}; } /** Gets all the entries of the names-table. If it is a True Type font * each array element will have {Name ID, Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
* For the other fonts the array has a single element with {"4", "", "", "", * font name}. * @return the full name of the font * @since 2.0.8 */ public String[][] getAllNameEntries() { return new String[][]{{"4", "", "", "", fontName}}; } /** Gets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @return the kerning to be applied * */ public int getKerning(int char1, int char2) { return 0; } /** Gets the postscript font name. * @return the postscript font name * */ public String getPostscriptFontName() { return fontName; } /** Gets the width from the font according to the Unicode char c * or the name. If the name is null it's a symbolic font. * @param c the unicode char * @param name the glyph name * @return the width of the char * */ int getRawWidth(int c, String name) { return 0; } /** Checks if the font has any kerning pairs. * @return true if the font has any kerning pairs * */ public boolean hasKernPairs() { return false; } /** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param params several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object * */ void writeFont(PdfWriter writer, PdfIndirectReference ref, Object[] params) throws DocumentException, IOException { } /** * Always returns null. * @return null * @since 2.1.3 */ public PdfStream getFullFontStream() { return null; } /** * Gets the width of a char in normalized 1000 units. * @param char1 the unicode char to get the width of * @return the width in normalized 1000 units */ public int getWidth(int char1) { if (cjkMirror != null) return cjkMirror.getWidth(char1); else if (isType0) { int[] ws = (int[])metrics.get(new Integer(char1)); if (ws != null) return ws[1]; else return 0; } else return super.getWidth(char1); } public int getWidth(String text) { if (cjkMirror != null) return cjkMirror.getWidth(text); else if (isType0) { char[] chars = text.toCharArray(); int len = chars.length; int total = 0; for (int k = 0; k < len; ++k) { int[] ws = (int[])metrics.get(new Integer(chars[k])); if (ws != null) total += ws[1]; } return total; } else return super.getWidth(text); } byte[] convertToBytes(String text) { if (cjkMirror != null) return PdfEncodings.convertToBytes(text, CJKFont.CJK_ENCODING); else if (isType0) { char[] chars = text.toCharArray(); int len = chars.length; byte[] b = new byte[len * 2]; int bptr = 0; for (int k = 0; k < len; ++k) { int[] ws = (int[])metrics.get(new Integer(chars[k])); if (ws != null) { int g = ws[0]; b[bptr++] = (byte)(g / 256); b[bptr++] = (byte)(g); } } if (bptr == b.length) return b; else { byte[] nb = new byte[bptr]; System.arraycopy(b, 0, nb, 0, bptr); return nb; } } else { char cc[] = text.toCharArray(); byte b[] = new byte[cc.length]; int ptr = 0; for (int k = 0; k < cc.length; ++k) { if (uni2byte.containsKey(cc[k])) b[ptr++] = (byte)uni2byte.get(cc[k]); } if (ptr == b.length) return b; else { byte[] b2 = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } } } byte[] convertToBytes(int char1) { if (cjkMirror != null) return PdfEncodings.convertToBytes((char)char1, CJKFont.CJK_ENCODING); else if (isType0) { int[] ws = (int[])metrics.get(new Integer(char1)); if (ws != null) { int g = ws[0]; return new byte[]{(byte)(g / 256), (byte)(g)}; } else return new byte[0]; } else { if (uni2byte.containsKey(char1)) return new byte[]{(byte)uni2byte.get(char1)}; else return new byte[0]; } } PdfIndirectReference getIndirectReference() { return refFont; } public boolean charExists(int c) { if (cjkMirror != null) return cjkMirror.charExists(c); else if (isType0) { return metrics.containsKey(new Integer(c)); } else return super.charExists(c); } /** * Sets the font name that will appear in the pdf font dictionary. * It does nothing in this case as the font is already in the document. * @param name the new font name */ public void setPostscriptFontName(String name) { } public boolean setKerning(int char1, int char2, int kern) { return false; } public int[] getCharBBox(int c) { return null; } protected int[] getRawCharBBox(int c, String name) { return null; } /** * Exposes the unicode - > CID map that is constructed from the font's encoding * @return the unicode to CID map * @since 2.1.7 */ IntHashtable getUni2Byte(){ return uni2byte; } }src/core/com/lowagie/text/pdf/EnumerateTTC.java100644 0 0 11210 11012562273 17043 0ustar 0 0 /* * $Id: EnumerateTTC.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.HashMap; import com.lowagie.text.DocumentException; /** Enumerates all the fonts inside a True Type Collection. * * @author Paulo Soares (psoares@consiste.pt) */ class EnumerateTTC extends TrueTypeFont{ protected String[] names; EnumerateTTC(String ttcFile) throws DocumentException, IOException { fileName = ttcFile; rf = new RandomAccessFileOrArray(ttcFile); findNames(); } EnumerateTTC(byte ttcArray[]) throws DocumentException, IOException { fileName = "Byte array TTC"; rf = new RandomAccessFileOrArray(ttcArray); findNames(); } void findNames() throws DocumentException, IOException { tables = new HashMap(); try { String mainTag = readStandardString(4); if (!mainTag.equals("ttcf")) throw new DocumentException(fileName + " is not a valid TTC file."); rf.skipBytes(4); int dirCount = rf.readInt(); names = new String[dirCount]; int dirPos = rf.getFilePointer(); for (int dirIdx = 0; dirIdx < dirCount; ++dirIdx) { tables.clear(); rf.seek(dirPos); rf.skipBytes(dirIdx * 4); directoryOffset = rf.readInt(); rf.seek(directoryOffset); if (rf.readInt() != 0x00010000) throw new DocumentException(fileName + " is not a valid TTF file."); int num_tables = rf.readUnsignedShort(); rf.skipBytes(6); for (int k = 0; k < num_tables; ++k) { String tag = readStandardString(4); rf.skipBytes(4); int table_location[] = new int[2]; table_location[0] = rf.readInt(); table_location[1] = rf.readInt(); tables.put(tag, table_location); } names[dirIdx] = getBaseFont(); } } finally { if (rf != null) rf.close(); } } String[] getNames() { return names; } } src/core/com/lowagie/text/pdf/ExtendedColor.java100644 0 0 10501 11012562273 17304 0ustar 0 0 /* * $Id: ExtendedColor.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; /** * * @author Paulo Soares (psoares@consiste.pt) */ public abstract class ExtendedColor extends Color{ private static final long serialVersionUID = 2722660170712380080L; /** a type of extended color. */ public static final int TYPE_RGB = 0; /** a type of extended color. */ public static final int TYPE_GRAY = 1; /** a type of extended color. */ public static final int TYPE_CMYK = 2; /** a type of extended color. */ public static final int TYPE_SEPARATION = 3; /** a type of extended color. */ public static final int TYPE_PATTERN = 4; /** a type of extended color. */ public static final int TYPE_SHADING = 5; protected int type; /** * Constructs an extended color of a certain type. * @param type */ public ExtendedColor(int type) { super(0, 0, 0); this.type = type; } /** * Constructs an extended color of a certain type and a certain color. * @param type * @param red * @param green * @param blue */ public ExtendedColor(int type, float red, float green, float blue) { super(normalize(red), normalize(green), normalize(blue)); this.type = type; } /** * Gets the type of this color. * @return one of the types (see constants) */ public int getType() { return type; } /** * Gets the type of a given color. * @param color * @return one of the types (see constants) */ public static int getType(Color color) { if (color instanceof ExtendedColor) return ((ExtendedColor)color).getType(); return TYPE_RGB; } static final float normalize(float value) { if (value < 0) return 0; if (value > 1) return 1; return value; } }src/core/com/lowagie/text/pdf/ExtraEncoding.java100644 0 0 7514 11000354131 17256 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Classes implementing this interface can create custom encodings or * replace existing ones. It is used in the context of PdfEncoding. * @author Paulo Soares (psoares@consiste.pt) */ public interface ExtraEncoding { /** * Converts an Unicode string to a byte array according to some encoding. * @param text the Unicode string * @param encoding the requested encoding. It's mainly of use if the same class * supports more than one encoding. * @return the conversion or null if no conversion is supported */ public byte[] charToByte(String text, String encoding); /** * Converts an Unicode char to a byte array according to some encoding. * @param char1 the Unicode char * @param encoding the requested encoding. It's mainly of use if the same class * supports more than one encoding. * @return the conversion or null if no conversion is supported */ public byte[] charToByte(char char1, String encoding); /** * Converts a byte array to an Unicode string according to some encoding. * @param b the input byte array * @param encoding the requested encoding. It's mainly of use if the same class * supports more than one encoding. * @return the conversion or null if no conversion is supported */ public String byteToChar(byte b[], String encoding); }src/core/com/lowagie/text/pdf/FdfReader.java100644 0 0 17216 11154165266 16411 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; /** Reads an FDF form and makes the fields available * @author Paulo Soares (psoares@consiste.pt) */ public class FdfReader extends PdfReader { HashMap fields; String fileSpec; PdfName encoding; /** Reads an FDF form. * @param filename the file name of the form * @throws IOException on error */ public FdfReader(String filename) throws IOException { super(filename); } /** Reads an FDF form. * @param pdfIn the byte array with the form * @throws IOException on error */ public FdfReader(byte pdfIn[]) throws IOException { super(pdfIn); } /** Reads an FDF form. * @param url the URL of the document * @throws IOException on error */ public FdfReader(URL url) throws IOException { super(url); } /** Reads an FDF form. * @param is the InputStream containing the document. The stream is read to the * end but is not closed * @throws IOException on error */ public FdfReader(InputStream is) throws IOException { super(is); } protected void readPdf() throws IOException { fields = new HashMap(); try { tokens.checkFdfHeader(); rebuildXref(); readDocObj(); } finally { try { tokens.close(); } catch (Exception e) { // empty on purpose } } readFields(); } protected void kidNode(PdfDictionary merged, String name) { PdfArray kids = merged.getAsArray(PdfName.KIDS); if (kids == null || kids.isEmpty()) { if (name.length() > 0) name = name.substring(1); fields.put(name, merged); } else { merged.remove(PdfName.KIDS); for (int k = 0; k < kids.size(); ++k) { PdfDictionary dic = new PdfDictionary(); dic.merge(merged); PdfDictionary newDic = kids.getAsDict(k); PdfString t = newDic.getAsString(PdfName.T); String newName = name; if (t != null) newName += "." + t.toUnicodeString(); dic.merge(newDic); dic.remove(PdfName.T); kidNode(dic, newName); } } } protected void readFields() { catalog = trailer.getAsDict(PdfName.ROOT); PdfDictionary fdf = catalog.getAsDict(PdfName.FDF); if (fdf == null) return; PdfString fs = fdf.getAsString(PdfName.F); if (fs != null) fileSpec = fs.toUnicodeString(); PdfArray fld = fdf.getAsArray(PdfName.FIELDS); if (fld == null) return; encoding = fdf.getAsName(PdfName.ENCODING); PdfDictionary merged = new PdfDictionary(); merged.put(PdfName.KIDS, fld); kidNode(merged, ""); } /** Gets all the fields. The map is keyed by the fully qualified * field name and the value is a merged PdfDictionary * with the field content. * @return all the fields */ public HashMap getFields() { return fields; } /** Gets the field dictionary. * @param name the fully qualified field name * @return the field dictionary */ public PdfDictionary getField(String name) { return (PdfDictionary)fields.get(name); } /** Gets the field value or null if the field does not * exist or has no value defined. * @param name the fully qualified field name * @return the field value or null */ public String getFieldValue(String name) { PdfDictionary field = (PdfDictionary)fields.get(name); if (field == null) return null; PdfObject v = getPdfObject(field.get(PdfName.V)); if (v == null) return null; if (v.isName()) return PdfName.decodeName(((PdfName)v).toString()); else if (v.isString()) { PdfString vs = (PdfString)v; if (encoding == null || vs.getEncoding() != null) return vs.toUnicodeString(); byte b[] = vs.getBytes(); if (b.length >= 2 && b[0] == (byte)254 && b[1] == (byte)255) return vs.toUnicodeString(); try { if (encoding.equals(PdfName.SHIFT_JIS)) return new String(b, "SJIS"); else if (encoding.equals(PdfName.UHC)) return new String(b, "MS949"); else if (encoding.equals(PdfName.GBK)) return new String(b, "GBK"); else if (encoding.equals(PdfName.BIGFIVE)) return new String(b, "Big5"); } catch (Exception e) { } return vs.toUnicodeString(); } return null; } /** Gets the PDF file specification contained in the FDF. * @return the PDF file specification contained in the FDF */ public String getFileSpec() { return fileSpec; } }src/core/com/lowagie/text/pdf/FdfWriter.java100644 0 0 31472 11154165266 16463 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import com.lowagie.text.DocWriter; /** Writes an FDF form. * @author Paulo Soares (psoares@consiste.pt) */ public class FdfWriter { private static final byte[] HEADER_FDF = DocWriter.getISOBytes("%FDF-1.2\n%\u00e2\u00e3\u00cf\u00d3\n"); HashMap fields = new HashMap(); /** The PDF file associated with the FDF. */ private String file; /** Creates a new FdfWriter. */ public FdfWriter() { } /** Writes the content to a stream. * @param os the stream * @throws IOException on error */ public void writeTo(OutputStream os) throws IOException { Wrt wrt = new Wrt(os, this); wrt.writeTo(); } boolean setField(String field, PdfObject value) { HashMap map = fields; StringTokenizer tk = new StringTokenizer(field, "."); if (!tk.hasMoreTokens()) return false; while (true) { String s = tk.nextToken(); Object obj = map.get(s); if (tk.hasMoreTokens()) { if (obj == null) { obj = new HashMap(); map.put(s, obj); map = (HashMap)obj; continue; } else if (obj instanceof HashMap) map = (HashMap)obj; else return false; } else { if (!(obj instanceof HashMap)) { map.put(s, value); return true; } else return false; } } } void iterateFields(HashMap values, HashMap map, String name) { for (Iterator it = map.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String s = (String) entry.getKey(); Object obj = entry.getValue(); if (obj instanceof HashMap) iterateFields(values, (HashMap)obj, name + "." + s); else values.put((name + "." + s).substring(1), obj); } } /** Removes the field value. * @param field the field name * @return true if the field was found and removed, * false otherwise */ public boolean removeField(String field) { HashMap map = fields; StringTokenizer tk = new StringTokenizer(field, "."); if (!tk.hasMoreTokens()) return false; ArrayList hist = new ArrayList(); while (true) { String s = tk.nextToken(); Object obj = map.get(s); if (obj == null) return false; hist.add(map); hist.add(s); if (tk.hasMoreTokens()) { if (obj instanceof HashMap) map = (HashMap)obj; else return false; } else { if (obj instanceof HashMap) return false; else break; } } for (int k = hist.size() - 2; k >= 0; k -= 2) { map = (HashMap)hist.get(k); String s = (String)hist.get(k + 1); map.remove(s); if (!map.isEmpty()) break; } return true; } /** Gets all the fields. The map is keyed by the fully qualified * field name and the values are PdfObject. * @return a map with all the fields */ public HashMap getFields() { HashMap values = new HashMap(); iterateFields(values, fields, ""); return values; } /** Gets the field value. * @param field the field name * @return the field value or null if not found */ public String getField(String field) { HashMap map = fields; StringTokenizer tk = new StringTokenizer(field, "."); if (!tk.hasMoreTokens()) return null; while (true) { String s = tk.nextToken(); Object obj = map.get(s); if (obj == null) return null; if (tk.hasMoreTokens()) { if (obj instanceof HashMap) map = (HashMap)obj; else return null; } else { if (obj instanceof HashMap) return null; else { if (((PdfObject)obj).isString()) return ((PdfString)obj).toUnicodeString(); else return PdfName.decodeName(obj.toString()); } } } } /** Sets the field value as a name. * @param field the fully qualified field name * @param value the value * @return true if the value was inserted, * false if the name is incompatible with * an existing field */ public boolean setFieldAsName(String field, String value) { return setField(field, new PdfName(value)); } /** Sets the field value as a string. * @param field the fully qualified field name * @param value the value * @return true if the value was inserted, * false if the name is incompatible with * an existing field */ public boolean setFieldAsString(String field, String value) { return setField(field, new PdfString(value, PdfObject.TEXT_UNICODE)); } /** * Sets the field value as a PDFAction. * For example, this method allows setting a form submit button action using {@link PdfAction#createSubmitForm(String, Object[], int)}. * This method creates an A entry for the specified field in the underlying FDF file. * Method contributed by Philippe Laflamme (plaflamme) * @param field the fully qualified field name * @param action the field's action * @return true if the value was inserted, * false if the name is incompatible with * an existing field * @since 2.1.5 */ public boolean setFieldAsAction(String field, PdfAction action) { return setField(field, action); } /** Sets all the fields from this FdfReader * @param fdf the FdfReader */ public void setFields(FdfReader fdf) { HashMap map = fdf.getFields(); for (Iterator it = map.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); PdfDictionary dic = (PdfDictionary) entry.getValue(); PdfObject v = dic.get(PdfName.V); if (v != null) { setField(key, v); } v = dic.get(PdfName.A); // (plaflamme) if (v != null) { setField(key, v); } } } /** Sets all the fields from this PdfReader * @param pdf the PdfReader */ public void setFields(PdfReader pdf) { setFields(pdf.getAcroFields()); } /** Sets all the fields from this AcroFields * @param af the AcroFields */ public void setFields(AcroFields af) { for (Iterator it = af.getFields().entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); String fn = (String)entry.getKey(); AcroFields.Item item = (AcroFields.Item)entry.getValue(); PdfDictionary dic = item.getMerged(0); PdfObject v = PdfReader.getPdfObjectRelease(dic.get(PdfName.V)); if (v == null) continue; PdfObject ft = PdfReader.getPdfObjectRelease(dic.get(PdfName.FT)); if (ft == null || PdfName.SIG.equals(ft)) continue; setField(fn, v); } } /** Gets the PDF file name associated with the FDF. * @return the PDF file name associated with the FDF */ public String getFile() { return this.file; } /** Sets the PDF file name associated with the FDF. * @param file the PDF file name associated with the FDF * */ public void setFile(String file) { this.file = file; } static class Wrt extends PdfWriter { private FdfWriter fdf; Wrt(OutputStream os, FdfWriter fdf) throws IOException { super(new PdfDocument(), os); this.fdf = fdf; this.os.write(HEADER_FDF); body = new PdfBody(this); } void writeTo() throws IOException { PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.FIELDS, calculate(fdf.fields)); if (fdf.file != null) dic.put(PdfName.F, new PdfString(fdf.file, PdfObject.TEXT_UNICODE)); PdfDictionary fd = new PdfDictionary(); fd.put(PdfName.FDF, dic); PdfIndirectReference ref = addToBody(fd).getIndirectReference(); os.write(getISOBytes("trailer\n")); PdfDictionary trailer = new PdfDictionary(); trailer.put(PdfName.ROOT, ref); trailer.toPdf(null, os); os.write(getISOBytes("\n%%EOF\n")); os.close(); } PdfArray calculate(HashMap map) throws IOException { PdfArray ar = new PdfArray(); for (Iterator it = map.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String key = (String) entry.getKey(); Object v = entry.getValue(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.T, new PdfString(key, PdfObject.TEXT_UNICODE)); if (v instanceof HashMap) { dic.put(PdfName.KIDS, calculate((HashMap)v)); } else if(v instanceof PdfAction) { // (plaflamme) dic.put(PdfName.A, (PdfAction)v); } else { dic.put(PdfName.V, (PdfObject)v); } ar.add(dic); } return ar; } } } src/core/com/lowagie/text/pdf/FontDetails.java100644 0 0 26201 11213370070 16760 0ustar 0 0 /* * $Id: FontDetails.java 3869 2009-04-17 18:03:45Z blowagie $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.font.GlyphVector; import java.io.UnsupportedEncodingException; import java.util.HashMap; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Utilities; /** * Each font in the document will have an instance of this class * where the characters used will be represented. * * @author Paulo Soares (psoares@consiste.pt) */ class FontDetails { /** * The indirect reference to this font */ PdfIndirectReference indirectReference; /** * The font name that appears in the document body stream */ PdfName fontName; /** * The font */ BaseFont baseFont; /** * The font if it's an instance of TrueTypeFontUnicode */ TrueTypeFontUnicode ttu; /** * The font if it's an instance of CJKFont */ CJKFont cjkFont; /** * The array used with single byte encodings */ byte shortTag[]; /** * The map used with double byte encodings. The key is Integer(glyph) and * the value is int[]{glyph, width, Unicode code} */ HashMap longTag; /** * IntHashtable with CIDs of CJK glyphs that are used in the text. */ IntHashtable cjkTag; /** * The font type */ int fontType; /** * true if the font is symbolic */ boolean symbolic; /** * Indicates if only a subset of the glyphs and widths for that particular * encoding should be included in the document. */ protected boolean subset = true; /** * Each font used in a document has an instance of this class. * This class stores the characters used in the document and other * specifics unique to the current working document. * @param fontName the font name * @param indirectReference the indirect reference to the font * @param baseFont the BaseFont */ FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) { this.fontName = fontName; this.indirectReference = indirectReference; this.baseFont = baseFont; fontType = baseFont.getFontType(); switch (fontType) { case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: shortTag = new byte[256]; break; case BaseFont.FONT_TYPE_CJK: cjkTag = new IntHashtable(); cjkFont = (CJKFont)baseFont; break; case BaseFont.FONT_TYPE_TTUNI: longTag = new HashMap(); ttu = (TrueTypeFontUnicode)baseFont; symbolic = baseFont.isFontSpecific(); break; } } /** * Gets the indirect reference to this font. * @return the indirect reference to this font */ PdfIndirectReference getIndirectReference() { return indirectReference; } /** * Gets the font name as it appears in the document body. * @return the font name */ PdfName getFontName() { return fontName; } /** * Gets the BaseFont of this font. * @return the BaseFont of this font */ BaseFont getBaseFont() { return baseFont; } /** * Converts the text into bytes to be placed in the document. * The conversion is done according to the font and the encoding and the characters * used are stored. * @param text the text to convert * @return the conversion */ byte[] convertToBytes(String text) { byte b[] = null; switch (fontType) { case BaseFont.FONT_TYPE_T3: return baseFont.convertToBytes(text); case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: { b = baseFont.convertToBytes(text); int len = b.length; for (int k = 0; k < len; ++k) shortTag[b[k] & 0xff] = 1; break; } case BaseFont.FONT_TYPE_CJK: { int len = text.length(); for (int k = 0; k < len; ++k) cjkTag.put(cjkFont.getCidCode(text.charAt(k)), 0); b = baseFont.convertToBytes(text); break; } case BaseFont.FONT_TYPE_DOCUMENT: { b = baseFont.convertToBytes(text); break; } case BaseFont.FONT_TYPE_TTUNI: { try { int len = text.length(); int metrics[] = null; char glyph[] = new char[len]; int i = 0; if (symbolic) { b = PdfEncodings.convertToBytes(text, "symboltt"); len = b.length; for (int k = 0; k < len; ++k) { metrics = ttu.getMetricsTT(b[k] & 0xff); if (metrics == null) continue; longTag.put(new Integer(metrics[0]), new int[]{metrics[0], metrics[1], ttu.getUnicodeDifferences(b[k] & 0xff)}); glyph[i++] = (char)metrics[0]; } } else { for (int k = 0; k < len; ++k) { int val; if (Utilities.isSurrogatePair(text, k)) { val = Utilities.convertToUtf32(text, k); k++; } else { val = text.charAt(k); } metrics = ttu.getMetricsTT(val); if (metrics == null) continue; int m0 = metrics[0]; Integer gl = new Integer(m0); if (!longTag.containsKey(gl)) longTag.put(gl, new int[]{m0, metrics[1], val}); glyph[i++] = (char)m0; } } String s = new String(glyph, 0, i); b = s.getBytes(CJKFont.CJK_ENCODING); } catch (UnsupportedEncodingException e) { throw new ExceptionConverter(e); } break; } } return b; } /** * Writes the font definition to the document. * @param writer the PdfWriter of this document */ void writeFont(PdfWriter writer) { try { switch (fontType) { case BaseFont.FONT_TYPE_T3: baseFont.writeFont(writer, indirectReference, null); break; case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: { int firstChar; int lastChar; for (firstChar = 0; firstChar < 256; ++firstChar) { if (shortTag[firstChar] != 0) break; } for (lastChar = 255; lastChar >= firstChar; --lastChar) { if (shortTag[lastChar] != 0) break; } if (firstChar > 255) { firstChar = 255; lastChar = 255; } baseFont.writeFont(writer, indirectReference, new Object[]{new Integer(firstChar), new Integer(lastChar), shortTag, Boolean.valueOf(subset)}); break; } case BaseFont.FONT_TYPE_CJK: baseFont.writeFont(writer, indirectReference, new Object[]{cjkTag}); break; case BaseFont.FONT_TYPE_TTUNI: baseFont.writeFont(writer, indirectReference, new Object[]{longTag, Boolean.valueOf(subset)}); break; } } catch(Exception e) { throw new ExceptionConverter(e); } } /** * Indicates if all the glyphs and widths for that particular * encoding should be included in the document. * @return false to include all the glyphs and widths. */ public boolean isSubset() { return subset; } /** * Indicates if all the glyphs and widths for that particular * encoding should be included in the document. Set to false * to include all. * @param subset new value of property subset */ public void setSubset(boolean subset) { this.subset = subset; } } src/core/com/lowagie/text/pdf/FontMapper.java100644 0 0 6557 11000354131 16605 0ustar 0 0 /* * Copyright 2002 by Jeremy Bowman . * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Font; /** * A FontMapper implementation handles mappings between AWT Fonts and PDF * fonts. An interface is used instead of a fixed class because there isn't * an exact correlation between the font types, so each application is free * to define a mapping which is appropriate for it. */ public interface FontMapper { /** * Returns a BaseFont which can be used to represent the given AWT Font * * @param font the font to be converted * @return a BaseFont which has similar properties to the provided Font */ public BaseFont awtToPdf(Font font); /** * Returns an AWT Font which can be used to represent the given BaseFont * * @param font the font to be converted * @param size the desired point size of the resulting font * @return a Font which has similar properties to the provided BaseFont */ public Font pdfToAwt(BaseFont font, int size); } src/core/com/lowagie/text/pdf/FontSelector.java100644 0 0 13556 11012562273 17171 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.Font; import com.lowagie.text.Phrase; import com.lowagie.text.Utilities; /** Selects the appropriate fonts that contain the glyphs needed to * render text correctly. The fonts are checked in order until the * character is found. *

* The built in fonts "Symbol" and "ZapfDingbats", if used, have a special encoding * to allow the characters to be referred by Unicode. * @author Paulo Soares (psoares@consiste.pt) */ public class FontSelector { protected ArrayList fonts = new ArrayList(); /** * Adds a Font to be searched for valid characters. * @param font the Font */ public void addFont(Font font) { if (font.getBaseFont() != null) { fonts.add(font); return; } BaseFont bf = font.getCalculatedBaseFont(true); Font f2 = new Font(bf, font.getSize(), font.getCalculatedStyle(), font.getColor()); fonts.add(f2); } /** * Process the text so that it will render with a combination of fonts * if needed. * @param text the text * @return a Phrase with one or more chunks */ public Phrase process(String text) { int fsize = fonts.size(); if (fsize == 0) throw new IndexOutOfBoundsException("No font is defined."); char cc[] = text.toCharArray(); int len = cc.length; StringBuffer sb = new StringBuffer(); Font font = null; int lastidx = -1; Phrase ret = new Phrase(); for (int k = 0; k < len; ++k) { char c = cc[k]; if (c == '\n' || c == '\r') { sb.append(c); continue; } if (Utilities.isSurrogatePair(cc, k)) { int u = Utilities.convertToUtf32(cc, k); for (int f = 0; f < fsize; ++f) { font = (Font)fonts.get(f); if (font.getBaseFont().charExists(u)) { if (lastidx != f) { if (sb.length() > 0 && lastidx != -1) { Chunk ck = new Chunk(sb.toString(), (Font)fonts.get(lastidx)); ret.add(ck); sb.setLength(0); } lastidx = f; } sb.append(c); sb.append(cc[++k]); break; } } } else { for (int f = 0; f < fsize; ++f) { font = (Font)fonts.get(f); if (font.getBaseFont().charExists(c)) { if (lastidx != f) { if (sb.length() > 0 && lastidx != -1) { Chunk ck = new Chunk(sb.toString(), (Font)fonts.get(lastidx)); ret.add(ck); sb.setLength(0); } lastidx = f; } sb.append(c); break; } } } } if (sb.length() > 0) { Chunk ck = new Chunk(sb.toString(), (Font)fonts.get(lastidx == -1 ? 0 : lastidx)); ret.add(ck); } return ret; } } src/core/com/lowagie/text/pdf/GlyphList.java100644 0 0 11743 11012562273 16475 0ustar 0 0 /* * $Id: GlyphList.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001-2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.HashMap; import java.util.StringTokenizer; import com.lowagie.text.pdf.fonts.FontsResourceAnchor; public class GlyphList { private static HashMap unicode2names = new HashMap(); private static HashMap names2unicode = new HashMap(); static { InputStream is = null; try { is = BaseFont.getResourceStream(BaseFont.RESOURCE_PATH + "glyphlist.txt", new FontsResourceAnchor().getClass().getClassLoader()); if (is == null) { String msg = "glyphlist.txt not found as resource. (It must exist as resource in the package com.lowagie.text.pdf.fonts)"; throw new Exception(msg); } byte buf[] = new byte[1024]; ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { int size = is.read(buf); if (size < 0) break; out.write(buf, 0, size); } is.close(); is = null; String s = PdfEncodings.convertToString(out.toByteArray(), null); StringTokenizer tk = new StringTokenizer(s, "\r\n"); while (tk.hasMoreTokens()) { String line = tk.nextToken(); if (line.startsWith("#")) continue; StringTokenizer t2 = new StringTokenizer(line, " ;\r\n\t\f"); String name = null; String hex = null; if (!t2.hasMoreTokens()) continue; name = t2.nextToken(); if (!t2.hasMoreTokens()) continue; hex = t2.nextToken(); Integer num = Integer.valueOf(hex, 16); unicode2names.put(num, name); names2unicode.put(name, new int[]{num.intValue()}); } } catch (Exception e) { System.err.println("glyphlist.txt loading error: " + e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (Exception e) { // empty on purpose } } } } public static int[] nameToUnicode(String name) { return (int[])names2unicode.get(name); } public static String unicodeToName(int num) { return (String)unicode2names.get(new Integer(num)); } }src/core/com/lowagie/text/pdf/GrayColor.java100644 0 0 6443 11036112746 16442 0ustar 0 0 /* * $Id: GrayColor.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * * @author Paulo Soares (psoares@consiste.pt) */ public class GrayColor extends ExtendedColor { private static final long serialVersionUID = -6571835680819282746L; private float gray; public static final GrayColor GRAYBLACK = new GrayColor(0f); public static final GrayColor GRAYWHITE = new GrayColor(1f); public GrayColor(int intGray) { this(intGray / 255f); } public GrayColor(float floatGray) { super(TYPE_GRAY, floatGray, floatGray, floatGray); gray = normalize(floatGray); } public float getGray() { return gray; } public boolean equals(Object obj) { return obj instanceof GrayColor && ((GrayColor)obj).gray == this.gray; } public int hashCode() { return Float.floatToIntBits(gray); } } src/core/com/lowagie/text/pdf/HyphenationAuto.java100644 0 0 12370 11000354131 17657 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.pdf.hyphenation.Hyphenation; import com.lowagie.text.pdf.hyphenation.Hyphenator; /** Hyphenates words automatically accordingly to the language and country. * The hyphenator engine was taken from FOP and uses the TEX patterns. If a language * is not provided and a TEX pattern for it exists, it can be easily adapted. * * @author Paulo Soares (psoares@consiste.pt) */ public class HyphenationAuto implements HyphenationEvent { /** The hyphenator engine. */ protected Hyphenator hyphenator; /** The second part of the hyphenated word. */ protected String post; /** Creates a new hyphenation instance usable in Chunk. * @param lang the language ("en" for English, for example) * @param country the country ("GB" for Great-Britain or "none" for no country, for example) * @param leftMin the minimum number of letters before the hyphen * @param rightMin the minimum number of letters after the hyphen */ public HyphenationAuto(String lang, String country, int leftMin, int rightMin) { hyphenator = new Hyphenator(lang, country, leftMin, rightMin); } /** Gets the hyphen symbol. * @return the hyphen symbol */ public String getHyphenSymbol() { return "-"; } /** Hyphenates a word and returns the first part of it. To get * the second part of the hyphenated word call getHyphenatedWordPost(). * @param word the word to hyphenate * @param font the font used by this word * @param fontSize the font size used by this word * @param remainingWidth the width available to fit this word in * @return the first part of the hyphenated word including * the hyphen symbol, if any */ public String getHyphenatedWordPre(String word, BaseFont font, float fontSize, float remainingWidth) { post = word; String hyphen = getHyphenSymbol(); float hyphenWidth = font.getWidthPoint(hyphen, fontSize); if (hyphenWidth > remainingWidth) return ""; Hyphenation hyphenation = hyphenator.hyphenate(word); if (hyphenation == null) { return ""; } int len = hyphenation.length(); int k; for (k = 0; k < len; ++k) { if (font.getWidthPoint(hyphenation.getPreHyphenText(k), fontSize) + hyphenWidth > remainingWidth) break; } --k; if (k < 0) return ""; post = hyphenation.getPostHyphenText(k); return hyphenation.getPreHyphenText(k) + hyphen; } /** Gets the second part of the hyphenated word. Must be called * after getHyphenatedWordPre(). * @return the second part of the hyphenated word */ public String getHyphenatedWordPost() { return post; } } src/core/com/lowagie/text/pdf/HyphenationEvent.java100644 0 0 6733 11000354131 20016 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** Called by Chunk to hyphenate a word. * * @author Paulo Soares (psoares@consiste.pt) */ public interface HyphenationEvent { /** Gets the hyphen symbol. * @return the hyphen symbol */ public String getHyphenSymbol(); /** Hyphenates a word and returns the first part of it. To get * the second part of the hyphenated word call getHyphenatedWordPost(). * @param word the word to hyphenate * @param font the font used by this word * @param fontSize the font size used by this word * @param remainingWidth the width available to fit this word in * @return the first part of the hyphenated word including * the hyphen symbol, if any */ public String getHyphenatedWordPre(String word, BaseFont font, float fontSize, float remainingWidth); /** Gets the second part of the hyphenated word. Must be called * after getHyphenatedWordPre(). * @return the second part of the hyphenated word */ public String getHyphenatedWordPost(); } src/core/com/lowagie/text/pdf/IntHashtable.java100644 0 0 35131 11000354131 17106 0ustar 0 0 /* * This class is based on org.apache.IntHashMap.commons.lang * http://jakarta.apache.org/commons/lang/xref/org/apache/commons/lang/IntHashMap.html * It was adapted by Bruno Lowagie for use in iText, * reusing methods that were written by Paulo Soares. * Instead of being a hashtable that stores objects with an int as key, * it stores int values with an int as key. * * This is the original license of the original class IntHashMap: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Note: originally released under the GNU LGPL v2.1, * but rereleased by the original author under the ASF license (above). */ package com.lowagie.text.pdf; import java.util.Arrays; import java.util.Iterator; import java.util.NoSuchElementException; /*** *

A hash map that uses primitive ints for the key rather than objects.

* *

Note that this class is for internal optimization purposes only, and may * not be supported in future releases of Jakarta Commons Lang. Utilities of * this sort may be included in future releases of Jakarta Commons Collections.

* * @author Justin Couch * @author Alex Chaffee (alex@apache.org) * @author Stephen Colebourne * @author Bruno Lowagie (change Objects as keys into int values) * @author Paulo Soares (added extra methods) */ public class IntHashtable implements Cloneable { /*** * The hash table data. */ private transient Entry table[]; /*** * The total number of entries in the hash table. */ private transient int count; /*** * The table is rehashed when its size exceeds this threshold. (The * value of this field is (int)(capacity * loadFactor).) * * @serial */ private int threshold; /*** * The load factor for the hashtable. * * @serial */ private float loadFactor; /*** *

Constructs a new, empty hashtable with a default capacity and load * factor, which is 20 and 0.75 respectively.

*/ public IntHashtable() { this(150, 0.75f); } /*** *

Constructs a new, empty hashtable with the specified initial capacity * and default load factor, which is 0.75.

* * @param initialCapacity the initial capacity of the hashtable. * @throws IllegalArgumentException if the initial capacity is less * than zero. */ public IntHashtable(int initialCapacity) { this(initialCapacity, 0.75f); } /*** *

Constructs a new, empty hashtable with the specified initial * capacity and the specified load factor.

* * @param initialCapacity the initial capacity of the hashtable. * @param loadFactor the load factor of the hashtable. * @throws IllegalArgumentException if the initial capacity is less * than zero, or if the load factor is nonpositive. */ public IntHashtable(int initialCapacity, float loadFactor) { super(); if (initialCapacity < 0) { throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); } if (loadFactor <= 0) { throw new IllegalArgumentException("Illegal Load: " + loadFactor); } if (initialCapacity == 0) { initialCapacity = 1; } this.loadFactor = loadFactor; table = new Entry[initialCapacity]; threshold = (int) (initialCapacity * loadFactor); } /*** *

Returns the number of keys in this hashtable.

* * @return the number of keys in this hashtable. */ public int size() { return count; } /*** *

Tests if this hashtable maps no keys to values.

* * @return true if this hashtable maps no keys to values; * false otherwise. */ public boolean isEmpty() { return count == 0; } /*** *

Tests if some key maps into the specified value in this hashtable. * This operation is more expensive than the containsKey * method.

* *

Note that this method is identical in functionality to containsValue, * (which is part of the Map interface in the collections framework).

* * @param value a value to search for. * @return true if and only if some key maps to the * value argument in this hashtable as * determined by the equals method; * false otherwise. * @throws NullPointerException if the value is null. * @see #containsKey(int) * @see #containsValue(int) * @see java.util.Map */ public boolean contains(int value) { Entry tab[] = table; for (int i = tab.length; i-- > 0;) { for (Entry e = tab[i]; e != null; e = e.next) { if (e.value == value) { return true; } } } return false; } /*** *

Returns true if this HashMap maps one or more keys * to this value.

* *

Note that this method is identical in functionality to contains * (which predates the Map interface).

* * @param value value whose presence in this HashMap is to be tested. * @return boolean true if the value is contained * @see java.util.Map * @since JDK1.2 */ public boolean containsValue(int value) { return contains(value); } /*** *

Tests if the specified int is a key in this hashtable.

* * @param key possible key. * @return true if and only if the specified int is a * key in this hashtable, as determined by the equals * method; false otherwise. * @see #contains(int) */ public boolean containsKey(int key) { Entry tab[] = table; int hash = key; int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index]; e != null; e = e.next) { if (e.hash == hash && e.key == key) { return true; } } return false; } /*** *

Returns the value to which the specified key is mapped in this map.

* * @param key a key in the hashtable. * @return the value to which the key is mapped in this hashtable; * null if the key is not mapped to any value in * this hashtable. * @see #put(int, int) */ public int get(int key) { Entry tab[] = table; int hash = key; int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index]; e != null; e = e.next) { if (e.hash == hash && e.key == key) { return e.value; } } return 0; } /*** *

Increases the capacity of and internally reorganizes this * hashtable, in order to accommodate and access its entries more * efficiently.

* *

This method is called automatically when the number of keys * in the hashtable exceeds this hashtable's capacity and load * factor.

*/ protected void rehash() { int oldCapacity = table.length; Entry oldMap[] = table; int newCapacity = oldCapacity * 2 + 1; Entry newMap[] = new Entry[newCapacity]; threshold = (int) (newCapacity * loadFactor); table = newMap; for (int i = oldCapacity; i-- > 0;) { for (Entry old = oldMap[i]; old != null;) { Entry e = old; old = old.next; int index = (e.hash & 0x7FFFFFFF) % newCapacity; e.next = newMap[index]; newMap[index] = e; } } } /*** *

Maps the specified key to the specified * value in this hashtable. The key cannot be * null.

* *

The value can be retrieved by calling the get method * with a key that is equal to the original key.

* * @param key the hashtable key. * @param value the value. * @return the previous value of the specified key in this hashtable, * or null if it did not have one. * @throws NullPointerException if the key is null. * @see #get(int) */ public int put(int key, int value) { // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key; int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index]; e != null; e = e.next) { if (e.hash == hash && e.key == key) { int old = e.value; e.value = value; return old; } } if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry e = new Entry(hash, key, value, tab[index]); tab[index] = e; count++; return 0; } /*** *

Removes the key (and its corresponding value) from this * hashtable.

* *

This method does nothing if the key is not present in the * hashtable.

* * @param key the key that needs to be removed. * @return the value to which the key had been mapped in this hashtable, * or null if the key did not have a mapping. */ public int remove(int key) { Entry tab[] = table; int hash = key; int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next) { if (e.hash == hash && e.key == key) { if (prev != null) { prev.next = e.next; } else { tab[index] = e.next; } count--; int oldValue = e.value; e.value = 0; return oldValue; } } return 0; } /*** *

Clears this hashtable so that it contains no keys.

*/ public void clear() { Entry tab[] = table; for (int index = tab.length; --index >= 0;) { tab[index] = null; } count = 0; } /*** *

Innerclass that acts as a datastructure to create a new entry in the * table.

*/ static class Entry { int hash; int key; int value; Entry next; /*** *

Create a new entry with the given values.

* * @param hash The code used to hash the int with * @param key The key used to enter this in the table * @param value The value for this key * @param next A reference to the next entry in the table */ protected Entry(int hash, int key, int value, Entry next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } // extra methods for inner class Entry by Paulo public int getKey() { return key; } public int getValue() { return value; } protected Object clone() { Entry entry = new Entry(hash, key, value, (next != null) ? (Entry)next.clone() : null); return entry; } } // extra inner class by Paulo static class IntHashtableIterator implements Iterator { int index; Entry table[]; Entry entry; IntHashtableIterator(Entry table[]) { this.table = table; this.index = table.length; } public boolean hasNext() { if (entry != null) { return true; } while (index-- > 0) { if ((entry = table[index]) != null) { return true; } } return false; } public Object next() { if (entry == null) { while ((index-- > 0) && ((entry = table[index]) == null)); } if (entry != null) { Entry e = entry; entry = e.next; return e; } throw new NoSuchElementException("IntHashtableIterator"); } public void remove() { throw new UnsupportedOperationException("remove() not supported."); } } // extra methods by Paulo Soares: public Iterator getEntryIterator() { return new IntHashtableIterator(table); } public int[] toOrderedKeys() { int res[] = getKeys(); Arrays.sort(res); return res; } public int[] getKeys() { int res[] = new int[count]; int ptr = 0; int index = table.length; Entry entry = null; while (true) { if (entry == null) while ((index-- > 0) && ((entry = table[index]) == null)); if (entry == null) break; Entry e = entry; entry = e.next; res[ptr++] = e.key; } return res; } public int getOneKey() { if (count == 0) return 0; int index = table.length; Entry entry = null; while ((index-- > 0) && ((entry = table[index]) == null)); if (entry == null) return 0; return entry.key; } public Object clone() { try { IntHashtable t = (IntHashtable)super.clone(); t.table = new Entry[table.length]; for (int i = table.length ; i-- > 0 ; ) { t.table[i] = (table[i] != null) ? (Entry)table[i].clone() : null; } return t; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } }src/core/com/lowagie/text/pdf/LZWDecoder.java100644 0 0 16636 11000354131 16513 0ustar 0 0 /* * Copyright 2002-2008 by Paulo Soares. * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageioimpl.plugins.tiff.TIFFLZWDecompressor.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.ExceptionConverter; /** * A class for performing LZW decoding. * * */ public class LZWDecoder { byte stringTable[][]; byte data[] = null; OutputStream uncompData; int tableIndex, bitsToGet = 9; int bytePointer, bitPointer; int nextData = 0; int nextBits = 0; int andTable[] = { 511, 1023, 2047, 4095 }; public LZWDecoder() { } /** * Method to decode LZW compressed data. * * @param data The compressed data. * @param uncompData Array to return the uncompressed data in. */ public void decode(byte data[], OutputStream uncompData) { if(data[0] == (byte)0x00 && data[1] == (byte)0x01) { throw new RuntimeException("LZW flavour not supported."); } initializeStringTable(); this.data = data; this.uncompData = uncompData; // Initialize pointers bytePointer = 0; bitPointer = 0; nextData = 0; nextBits = 0; int code, oldCode = 0; byte string[]; while ((code = getNextCode()) != 257) { if (code == 256) { initializeStringTable(); code = getNextCode(); if (code == 257) { break; } writeString(stringTable[code]); oldCode = code; } else { if (code < tableIndex) { string = stringTable[code]; writeString(string); addStringToTable(stringTable[oldCode], string[0]); oldCode = code; } else { string = stringTable[oldCode]; string = composeString(string, string[0]); writeString(string); addStringToTable(string); oldCode = code; } } } } /** * Initialize the string table. */ public void initializeStringTable() { stringTable = new byte[8192][]; for (int i=0; i<256; i++) { stringTable[i] = new byte[1]; stringTable[i][0] = (byte)i; } tableIndex = 258; bitsToGet = 9; } /** * Write out the string just uncompressed. */ public void writeString(byte string[]) { try { uncompData.write(string); } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Add a new string to the string table. */ public void addStringToTable(byte oldString[], byte newString) { int length = oldString.length; byte string[] = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Add a new string to the string table. */ public void addStringToTable(byte string[]) { // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Append newString to the end of oldString. */ public byte[] composeString(byte oldString[], byte newString) { int length = oldString.length; byte string[] = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; return string; } // Returns the next 9, 10, 11 or 12 bits public int getNextCode() { // Attempt to get the next code. The exception is caught to make // this robust to cases wherein the EndOfInformation code has been // omitted from a strip. Examples of such cases have been observed // in practice. try { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; if (nextBits < bitsToGet) { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; } int code = (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9]; nextBits -= bitsToGet; return code; } catch(ArrayIndexOutOfBoundsException e) { // Strip not terminated as expected: return EndOfInformation code. return 257; } } } src/core/com/lowagie/text/pdf/MappedRandomAccessFile.java100644 0 0 16643 11012562273 21053 0ustar 0 0 /* * $Id: MappedRandomAccessFile.java 3314 2008-05-01 23:48:39Z xlv $ * * Copyright 2006 Joakim Sandstroem * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.Method; import java.nio.BufferUnderflowException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.security.AccessController; import java.security.PrivilegedAction; /** * A {@link java.nio.MappedByteBuffer} wrapped as a {@link java.io.RandomAccessFile} * * @author Joakim Sandstroem * Created on 6.9.2006 */ public class MappedRandomAccessFile { private MappedByteBuffer mappedByteBuffer = null; private FileChannel channel = null; /** * Constructs a new MappedRandomAccessFile instance * @param filename String * @param mode String r, w or rw * @throws FileNotFoundException * @throws IOException */ public MappedRandomAccessFile(String filename, String mode) throws FileNotFoundException, IOException { if (mode.equals("rw")) init( new java.io.RandomAccessFile(filename, mode).getChannel(), FileChannel.MapMode.READ_WRITE); else init( new FileInputStream(filename).getChannel(), FileChannel.MapMode.READ_ONLY); } /** * initializes the channel and mapped bytebuffer * @param channel FileChannel * @param mapMode FileChannel.MapMode * @throws IOException */ private void init(FileChannel channel, FileChannel.MapMode mapMode) throws IOException { this.channel = channel; this.mappedByteBuffer = channel.map(mapMode, 0L, channel.size()); mappedByteBuffer.load(); } /** * @since 2.0.8 */ public FileChannel getChannel() { return channel; } /** * @see java.io.RandomAccessFile#read() * @return int next integer or -1 on EOF */ public int read() { try { byte b = mappedByteBuffer.get(); int n = b & 0xff; return n; } catch (BufferUnderflowException e) { return -1; // EOF } } /** * @see java.io.RandomAccessFile#read(byte[], int, int) * @param bytes byte[] * @param off int offset * @param len int length * @return int bytes read or -1 on EOF */ public int read(byte bytes[], int off, int len) { int pos = mappedByteBuffer.position(); int limit = mappedByteBuffer.limit(); if (pos == limit) return -1; // EOF int newlimit = pos + len - off; if (newlimit > limit) { len = limit - pos; // don't read beyond EOF } mappedByteBuffer.get(bytes, off, len); return len; } /** * @see java.io.RandomAccessFile#getFilePointer() * @return long */ public long getFilePointer() { return mappedByteBuffer.position(); } /** * @see java.io.RandomAccessFile#seek(long) * @param pos long position */ public void seek(long pos) { mappedByteBuffer.position((int) pos); } /** * @see java.io.RandomAccessFile#length() * @return long length */ public long length() { return mappedByteBuffer.limit(); } /** * @see java.io.RandomAccessFile#close() * Cleans the mapped bytebuffer and closes the channel */ public void close() throws IOException { clean(mappedByteBuffer); mappedByteBuffer = null; if (channel != null) channel.close(); channel = null; } /** * invokes the close method * @see java.lang.Object#finalize() */ protected void finalize() throws Throwable { close(); super.finalize(); } /** * invokes the clean method on the ByteBuffer's cleaner * @param buffer ByteBuffer * @return boolean true on success */ public static boolean clean(final java.nio.ByteBuffer buffer) { if (buffer == null || !buffer.isDirect()) return false; Boolean b = (Boolean) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { Boolean success = Boolean.FALSE; try { Method getCleanerMethod = buffer.getClass().getMethod("cleaner", (Class[])null); getCleanerMethod.setAccessible(true); Object cleaner = getCleanerMethod.invoke(buffer, (Object[])null); Method clean = cleaner.getClass().getMethod("clean", (Class[])null); clean.invoke(cleaner, (Object[])null); success = Boolean.TRUE; } catch (Exception e) { // This really is a show stopper on windows //e.printStackTrace(); } return success; } }); return b.booleanValue(); } } src/core/com/lowagie/text/pdf/MultiColumnText.java100644 0 0 47633 11213370070 17675 0ustar 0 0 /* * $Id: MultiColumnText.java 3936 2009-05-27 12:40:12Z blowagie $ * * Copyright 2004 Steve Appling * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementListener; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; /** * Formats content into one or more columns bounded by a * rectangle. The columns may be simple rectangles or * more complicated shapes. Add all of the columns before * adding content. Column continuation is supported. A MultiColumnText object may be added to * a document using Document.add. * @author Steve Appling */ public class MultiColumnText implements Element { /** special constant for automatic calculation of height */ public static final float AUTOMATIC = -1f; /** * total desiredHeight of columns. If AUTOMATIC, this means fill pages until done. * This may be larger than one page */ private float desiredHeight; /** * total height of element written out so far */ private float totalHeight; /** * true if all the text could not be written out due to height restriction */ private boolean overflow; /** * Top of the columns - y position on starting page. * If AUTOMATIC, it means current y position when added to document */ private float top; /** * ColumnText object used to do all the real work. This same object is used for all columns */ private ColumnText columnText; /** * Array of ColumnDef objects used to define the columns */ private ArrayList columnDefs; /** * true if all columns are simple (rectangular) */ private boolean simple = true; private int currentColumn = 0; private float nextY = AUTOMATIC; private boolean columnsRightToLeft = false; private PdfDocument document; /** * Default constructor. Sets height to AUTOMATIC. * Columns will repeat on each page as necessary to accommodate content length. */ public MultiColumnText() { this(AUTOMATIC); } /** * Construct a MultiColumnText container of the specified height. * If height is AUTOMATIC, fill complete pages until done. * If a specific height is used, it may span one or more pages. * * @param height */ public MultiColumnText(float height) { columnDefs = new ArrayList(); desiredHeight = height; top = AUTOMATIC; // canvas will be set later columnText = new ColumnText(null); totalHeight = 0f; } /** * Construct a MultiColumnText container of the specified height * starting at the specified Y position. * * @param height * @param top */ public MultiColumnText(float top, float height) { columnDefs = new ArrayList(); desiredHeight = height; this.top = top; nextY = top; // canvas will be set later columnText = new ColumnText(null); totalHeight = 0f; } /** * Indicates that all of the text did not fit in the * specified height. Note that isOverflow will return * false before the MultiColumnText object has been * added to the document. It will always be false if * the height is AUTOMATIC. * * @return true if there is still space left in the column */ public boolean isOverflow() { return overflow; } /** * Copy the parameters from the specified ColumnText to use * when rendering. Parameters like setArabicOptions * must be set in this way. * * @param sourceColumn */ public void useColumnParams(ColumnText sourceColumn) { // note that canvas will be overwritten later columnText.setSimpleVars(sourceColumn); } /** * Add a new column. The parameters are limits for each column * wall in the format of a sequence of points (x1,y1,x2,y2,...). * * @param left limits for left column * @param right limits for right column */ public void addColumn(float[] left, float[] right) { ColumnDef nextDef = new ColumnDef(left, right); if (!nextDef.isSimple()) simple = false; columnDefs.add(nextDef); } /** * Add a simple rectangular column with specified left * and right x position boundaries. * * @param left left boundary * @param right right boundary */ public void addSimpleColumn(float left, float right) { ColumnDef newCol = new ColumnDef(left, right); columnDefs.add(newCol); } /** * Add the specified number of evenly spaced rectangular columns. * Columns will be separated by the specified gutterWidth. * * @param left left boundary of first column * @param right right boundary of last column * @param gutterWidth width of gutter spacing between columns * @param numColumns number of columns to add */ public void addRegularColumns(float left, float right, float gutterWidth, int numColumns) { float currX = left; float width = right - left; float colWidth = (width - (gutterWidth * (numColumns - 1))) / numColumns; for (int i = 0; i < numColumns; i++) { addSimpleColumn(currX, currX + colWidth); currX += colWidth + gutterWidth; } } /** * Adds a Phrase to the current text array. * Will not have any effect if addElement() was called before. * @param phrase the text * @since 2.1.5 */ public void addText(Phrase phrase) { columnText.addText(phrase); } /** * Adds a Chunk to the current text array. * Will not have any effect if addElement() was called before. * @param chunk the text * @since 2.1.5 */ public void addText(Chunk chunk) { columnText.addText(chunk); } /** * Add an element to be rendered in a column. * Note that you can only add a Phrase * or a Chunk if the columns are * not all simple. This is an underlying restriction in * {@link com.lowagie.text.pdf.ColumnText} * * @param element element to add * @throws DocumentException if element can't be added */ public void addElement(Element element) throws DocumentException { if (simple) { columnText.addElement(element); } else if (element instanceof Phrase) { columnText.addText((Phrase) element); } else if (element instanceof Chunk) { columnText.addText((Chunk) element); } else { throw new DocumentException("Can't add " + element.getClass() + " to MultiColumnText with complex columns"); } } /** * Write out the columns. After writing, use * {@link #isOverflow()} to see if all text was written. * @param canvas PdfContentByte to write with * @param document document to write to (only used to get page limit info) * @param documentY starting y position to begin writing at * @return the current height (y position) after writing the columns * @throws DocumentException on error */ public float write(PdfContentByte canvas, PdfDocument document, float documentY) throws DocumentException { this.document = document; columnText.setCanvas(canvas); if (columnDefs.isEmpty()) { throw new DocumentException("MultiColumnText has no columns"); } overflow = false; float currentHeight = 0; boolean done = false; try { while (!done) { if (top == AUTOMATIC) { top = document.getVerticalPosition(true); // RS - 07/07/2005 - Get current doc writing position for top of columns on new page. } else if (nextY == AUTOMATIC) { nextY = document.getVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page. } ColumnDef currentDef = (ColumnDef) columnDefs.get(getCurrentColumn()); columnText.setYLine(top); float[] left = currentDef.resolvePositions(Rectangle.LEFT); float[] right = currentDef.resolvePositions(Rectangle.RIGHT); if (document.isMarginMirroring() && document.getPageNumber() % 2 == 0){ float delta = document.rightMargin() - document.left(); left = (float[])left.clone(); right = (float[])right.clone(); for (int i = 0; i < left.length; i += 2) { left[i] -= delta; } for (int i = 0; i < right.length; i += 2) { right[i] -= delta; } } currentHeight = Math.max(currentHeight, getHeight(left, right)); if (currentDef.isSimple()) { columnText.setSimpleColumn(left[2], left[3], right[0], right[1]); } else { columnText.setColumns(left, right); } int result = columnText.go(); if ((result & ColumnText.NO_MORE_TEXT) != 0) { done = true; top = columnText.getYLine(); } else if (shiftCurrentColumn()) { top = nextY; } else { // check if we are done because of height totalHeight += currentHeight; if ((desiredHeight != AUTOMATIC) && (totalHeight >= desiredHeight)) { overflow = true; break; } else { // need to start new page and reset the columns documentY = nextY; newPage(); currentHeight = 0; } } } } catch (DocumentException ex) { ex.printStackTrace(); throw ex; } if (desiredHeight == AUTOMATIC && columnDefs.size() == 1) { currentHeight = documentY - columnText.getYLine(); } return currentHeight; } private void newPage() throws DocumentException { resetCurrentColumn(); if (desiredHeight == AUTOMATIC) { top = nextY = AUTOMATIC; } else { top = nextY; } totalHeight = 0; if (document != null) { document.newPage(); } } /** * Figure out the height of a column from the border extents * * @param left left border * @param right right border * @return height */ private float getHeight(float[] left, float[] right) { float max = Float.MIN_VALUE; float min = Float.MAX_VALUE; for (int i = 0; i < left.length; i += 2) { min = Math.min(min, left[i + 1]); max = Math.max(max, left[i + 1]); } for (int i = 0; i < right.length; i += 2) { min = Math.min(min, right[i + 1]); max = Math.max(max, right[i + 1]); } return max - min; } /** * Processes the element by adding it to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch (DocumentException de) { return false; } } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.MULTI_COLUMN_TEXT; } /** * Returns null - not used * * @return null */ public ArrayList getChunks() { return null; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return false; } /** * Calculates the appropriate y position for the bottom * of the columns on this page. * * @return the y position of the bottom of the columns */ private float getColumnBottom() { if (desiredHeight == AUTOMATIC) { return document.bottom(); } else { return Math.max(top - (desiredHeight - totalHeight), document.bottom()); } } /** * Moves the text insertion point to the beginning of the next column, issuing a page break if * needed. * @throws DocumentException on error */ public void nextColumn() throws DocumentException { currentColumn = (currentColumn + 1) % columnDefs.size(); top = nextY; if (currentColumn == 0) { newPage(); } } /** * Gets the current column. * @return the current column */ public int getCurrentColumn() { if (columnsRightToLeft) { return (columnDefs.size() - currentColumn - 1); } return currentColumn; } /** * Resets the current column. */ public void resetCurrentColumn() { currentColumn = 0; } /** * Shifts the current column. * @return true if the current column has changed */ public boolean shiftCurrentColumn() { if (currentColumn + 1 < columnDefs.size()) { currentColumn++; return true; } return false; } /** * Sets the direction of the columns. * @param direction true = right2left; false = left2right */ public void setColumnsRightToLeft(boolean direction) { columnsRightToLeft = direction; } /** Sets the ratio between the extra word spacing and the extra character spacing * when the text is fully justified. * Extra word spacing will grow spaceCharRatio times more than extra character spacing. * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the extra character spacing * will be zero. * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing */ public void setSpaceCharRatio(float spaceCharRatio) { columnText.setSpaceCharRatio(spaceCharRatio); } /** Sets the run direction. * @param runDirection the run direction */ public void setRunDirection(int runDirection) { columnText.setRunDirection(runDirection); } /** Sets the arabic shaping options. The option can be AR_NOVOWEL, * AR_COMPOSEDTASHKEEL and AR_LIG. * @param arabicOptions the arabic shaping options */ public void setArabicOptions(int arabicOptions) { columnText.setArabicOptions(arabicOptions); } /** Sets the default alignment * @param alignment the default alignment */ public void setAlignment(int alignment) { columnText.setAlignment(alignment); } /** * Inner class used to define a column */ private class ColumnDef { private float[] left; private float[] right; ColumnDef(float[] newLeft, float[] newRight) { left = newLeft; right = newRight; } ColumnDef(float leftPosition, float rightPosition) { left = new float[4]; left[0] = leftPosition; // x1 left[1] = top; // y1 left[2] = leftPosition; // x2 if (desiredHeight == AUTOMATIC || top == AUTOMATIC) { left[3] = AUTOMATIC; } else { left[3] = top - desiredHeight; } right = new float[4]; right[0] = rightPosition; // x1 right[1] = top; // y1 right[2] = rightPosition; // x2 if (desiredHeight == AUTOMATIC || top == AUTOMATIC) { right[3] = AUTOMATIC; } else { right[3] = top - desiredHeight; } } /** * Resolves the positions for the specified side of the column * into real numbers once the top of the column is known. * * @param side either Rectangle.LEFT * or Rectangle.RIGHT * @return the array of floats for the side */ float[] resolvePositions(int side) { if (side == Rectangle.LEFT) { return resolvePositions(left); } else { return resolvePositions(right); } } private float[] resolvePositions(float[] positions) { if (!isSimple()) { positions[1] = top; return positions; } if (top == AUTOMATIC) { // this is bad - must be programmer error throw new RuntimeException("resolvePositions called with top=AUTOMATIC (-1). " + "Top position must be set befure lines can be resolved"); } positions[1] = top; positions[3] = getColumnBottom(); return positions; } /** * Checks if column definition is a simple rectangle * @return true if it is a simple column */ private boolean isSimple() { return (left.length == 4 && right.length == 4) && (left[0] == left[2] && right[0] == right[2]); } } } src/core/com/lowagie/text/pdf/OcspClient.java100644 0 0 5306 11215636056 16605 0ustar 0 0 /* * $Id: OcspClient.java 3959 2009-06-09 08:31:05Z blowagie $ * * Copyright 2009 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Interface for the OCSP Client. * @since 2.1.6 */ public interface OcspClient { /** * Gets an encoded byte array. * @return a byte array */ public byte[] getEncoded(); } src/core/com/lowagie/text/pdf/OcspClientBouncyCastle.java100644 0 0 17271 11215636056 21145 0ustar 0 0 /* * $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $ * * Copyright 2009 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.ExceptionConverter; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; import java.security.Security; import java.security.cert.X509Certificate; import java.util.Vector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.ocsp.BasicOCSPResp; import org.bouncycastle.ocsp.CertificateID; import org.bouncycastle.ocsp.CertificateStatus; import org.bouncycastle.ocsp.OCSPException; import org.bouncycastle.ocsp.OCSPReq; import org.bouncycastle.ocsp.OCSPReqGenerator; import org.bouncycastle.ocsp.OCSPResp; import org.bouncycastle.ocsp.SingleResp; /** * OcspClient implementation using BouncyCastle. * @author psoares * @since 2.1.6 */ public class OcspClientBouncyCastle implements OcspClient { /** root certificate */ private X509Certificate rootCert; /** check certificate */ private X509Certificate checkCert; /** OCSP URL */ private String url; /** * Creates an instance of an OcspClient that will be using BouncyCastle. * @param checkCert the check certificate * @param rootCert the root certificate * @param url the OCSP URL */ public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) { this.checkCert = checkCert; this.rootCert = rootCert; this.url = url; } /** * Generates an OCSP request using BouncyCastle. * @param issuerCert certificate of the issues * @param serialNumber serial number * @return an OCSP request * @throws OCSPException * @throws IOException */ private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException { //Add provider BC Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // Generate the id for the certificate we are looking for CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); // basic request generation with nonce OCSPReqGenerator gen = new OCSPReqGenerator(); gen.addRequest(id); // create details for nonce extension Vector oids = new Vector(); Vector values = new Vector(); oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); gen.setRequestExtensions(new X509Extensions(oids, values)); return gen.generate(); } /** * @return a byte array * @see com.lowagie.text.pdf.OcspClient#getEncoded() */ public byte[] getEncoded() { try { OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber()); byte[] array = request.getEncoded(); URL urlt = new URL(url); HttpURLConnection con = (HttpURLConnection)urlt.openConnection(); con.setRequestProperty("Content-Type", "application/ocsp-request"); con.setRequestProperty("Accept", "application/ocsp-response"); con.setDoOutput(true); OutputStream out = con.getOutputStream(); DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out)); dataOut.write(array); dataOut.flush(); dataOut.close(); if (con.getResponseCode() / 100 != 2) { throw new IOException("Invalid HTTP response"); } //Get Response InputStream in = (InputStream) con.getContent(); OCSPResp ocspResponse = new OCSPResp(in); if (ocspResponse.getStatus() != 0) throw new IOException("Invalid status: " + ocspResponse.getStatus()); BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); if (basicResponse != null) { SingleResp[] responses = basicResponse.getResponses(); if (responses.length == 1) { SingleResp resp = responses[0]; Object status = resp.getCertStatus(); if (status == CertificateStatus.GOOD) { return basicResponse.getEncoded(); } else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { throw new IOException("OCSP Status is revoked!"); } else { throw new IOException("OCSP Status is unknown!"); } } } } catch (Exception ex) { throw new ExceptionConverter(ex); } return null; } } src/core/com/lowagie/text/pdf/OutputStreamCounter.java100644 0 0 15513 11000354131 20556 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; /** * * @author psoares */ public class OutputStreamCounter extends OutputStream { protected OutputStream out; protected int counter = 0; /** Creates a new instance of OutputStreamCounter */ public OutputStreamCounter(OutputStream out) { this.out = out; } /** Closes this output stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the output stream. A closed stream cannot perform * output operations and cannot be reopened. *

* The close method of OutputStream does nothing. * * @exception IOException if an I/O error occurs. * */ public void close() throws IOException { out.close(); } /** Flushes this output stream and forces any buffered output bytes * to be written out. The general contract of flush is * that calling it is an indication that, if any bytes previously * written have been buffered by the implementation of the output * stream, such bytes should immediately be written to their * intended destination. *

* The flush method of OutputStream does nothing. * * @exception IOException if an I/O error occurs. * */ public void flush() throws IOException { out.flush(); } /** Writes b.length bytes from the specified byte array * to this output stream. The general contract for write(b) * is that it should have exactly the same effect as the call * write(b, 0, b.length). * * @param b the data. * @exception IOException if an I/O error occurs. * @see java.io.OutputStream#write(byte[], int, int) * */ public void write(byte[] b) throws IOException { counter += b.length; out.write(b); } /** Writes the specified byte to this output stream. The general * contract for write is that one byte is written * to the output stream. The byte to be written is the eight * low-order bits of the argument b. The 24 * high-order bits of b are ignored. *

* Subclasses of OutputStream must provide an * implementation for this method. * * @param b the byte. * @exception IOException if an I/O error occurs. In particular, * an IOException may be thrown if the * output stream has been closed. * */ public void write(int b) throws IOException { ++counter; out.write(b); } /** Writes len bytes from the specified byte array * starting at offset off to this output stream. * The general contract for write(b, off, len) is that * some of the bytes in the array b are written to the * output stream in order; element b[off] is the first * byte written and b[off+len-1] is the last byte written * by this operation. *

* The write method of OutputStream calls * the write method of one argument on each of the bytes to be * written out. Subclasses are encouraged to override this method and * provide a more efficient implementation. *

* If b is null, a * NullPointerException is thrown. *

* If off is negative, or len is negative, or * off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is thrown. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception IOException if an I/O error occurs. In particular, * an IOException is thrown if the output * stream is closed. * */ public void write(byte[] b, int off, int len) throws IOException { counter += len; out.write(b, off, len); } public int getCounter() { return counter; } public void resetCounter() { counter = 0; } } src/core/com/lowagie/text/pdf/OutputStreamEncryption.java100644 0 0 21263 11000354131 21270 0ustar 0 0 /* * $Id: OutputStreamEncryption.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.pdf.crypto.AESCipher; import com.lowagie.text.pdf.crypto.IVGenerator; import com.lowagie.text.pdf.crypto.ARCFOUREncryption; import java.io.IOException; import java.io.OutputStream; public class OutputStreamEncryption extends OutputStream { protected OutputStream out; protected ARCFOUREncryption arcfour; protected AESCipher cipher; private byte[] sb = new byte[1]; private static final int AES_128 = 4; private boolean aes; private boolean finished; /** Creates a new instance of OutputStreamCounter */ public OutputStreamEncryption(OutputStream out, byte key[], int off, int len, int revision) { try { this.out = out; aes = revision == AES_128; if (aes) { byte[] iv = IVGenerator.getIV(); byte[] nkey = new byte[len]; System.arraycopy(key, off, nkey, 0, len); cipher = new AESCipher(true, nkey, iv); write(iv); } else { arcfour = new ARCFOUREncryption(); arcfour.prepareARCFOURKey(key, off, len); } } catch (Exception ex) { throw new ExceptionConverter(ex); } } public OutputStreamEncryption(OutputStream out, byte key[], int revision) { this(out, key, 0, key.length, revision); } /** Closes this output stream and releases any system resources * associated with this stream. The general contract of close * is that it closes the output stream. A closed stream cannot perform * output operations and cannot be reopened. *

* The close method of OutputStream does nothing. * * @exception IOException if an I/O error occurs. * */ public void close() throws IOException { finish(); out.close(); } /** Flushes this output stream and forces any buffered output bytes * to be written out. The general contract of flush is * that calling it is an indication that, if any bytes previously * written have been buffered by the implementation of the output * stream, such bytes should immediately be written to their * intended destination. *

* The flush method of OutputStream does nothing. * * @exception IOException if an I/O error occurs. * */ public void flush() throws IOException { out.flush(); } /** Writes b.length bytes from the specified byte array * to this output stream. The general contract for write(b) * is that it should have exactly the same effect as the call * write(b, 0, b.length). * * @param b the data. * @exception IOException if an I/O error occurs. * @see java.io.OutputStream#write(byte[], int, int) * */ public void write(byte[] b) throws IOException { write(b, 0, b.length); } /** Writes the specified byte to this output stream. The general * contract for write is that one byte is written * to the output stream. The byte to be written is the eight * low-order bits of the argument b. The 24 * high-order bits of b are ignored. *

* Subclasses of OutputStream must provide an * implementation for this method. * * @param b the byte. * @exception IOException if an I/O error occurs. In particular, * an IOException may be thrown if the * output stream has been closed. * */ public void write(int b) throws IOException { sb[0] = (byte)b; write(sb, 0, 1); } /** Writes len bytes from the specified byte array * starting at offset off to this output stream. * The general contract for write(b, off, len) is that * some of the bytes in the array b are written to the * output stream in order; element b[off] is the first * byte written and b[off+len-1] is the last byte written * by this operation. *

* The write method of OutputStream calls * the write method of one argument on each of the bytes to be * written out. Subclasses are encouraged to override this method and * provide a more efficient implementation. *

* If b is null, a * NullPointerException is thrown. *

* If off is negative, or len is negative, or * off+len is greater than the length of the array * b, then an IndexOutOfBoundsException is thrown. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception IOException if an I/O error occurs. In particular, * an IOException is thrown if the output * stream is closed. * */ public void write(byte[] b, int off, int len) throws IOException { if (aes) { byte[] b2 = cipher.update(b, off, len); if (b2 == null || b2.length == 0) return; out.write(b2, 0, b2.length); } else { byte[] b2 = new byte[Math.min(len, 4192)]; while (len > 0) { int sz = Math.min(len, b2.length); arcfour.encryptARCFOUR(b, off, sz, b2, 0); out.write(b2, 0, sz); len -= sz; off += sz; } } } public void finish() throws IOException { if (!finished) { finished = true; if (aes) { byte[] b; try { b = cipher.doFinal(); } catch (Exception ex) { throw new ExceptionConverter(ex); } out.write(b, 0, b.length); } } } }src/core/com/lowagie/text/pdf/PRAcroForm.java100644 0 0 17654 11154165266 16547 0ustar 0 0 /* * $Id: PRAcroForm.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * This class written by Mark Thompson, Copyright (C) 2002 by Mark Thompson. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; /** * This class captures an AcroForm on input. Basically, it extends Dictionary * by indexing the fields of an AcroForm * @author Mark Thompson */ public class PRAcroForm extends PdfDictionary { /** * This class holds the information for a single field */ public static class FieldInformation { String name; PdfDictionary info; PRIndirectReference ref; FieldInformation(String name, PdfDictionary info, PRIndirectReference ref) { this.name = name; this.info = info; this.ref = ref; } public String getName() { return name; } public PdfDictionary getInfo() { return info; } public PRIndirectReference getRef() { return ref; } }; ArrayList fields; ArrayList stack; HashMap fieldByName; PdfReader reader; /** * Constructor * @param reader reader of the input file */ public PRAcroForm(PdfReader reader) { this.reader = reader; fields = new ArrayList(); fieldByName = new HashMap(); stack = new ArrayList(); } /** * Number of fields found * @return size */ public int size() { return fields.size(); } public ArrayList getFields() { return fields; } public FieldInformation getField(String name) { return (FieldInformation)fieldByName.get(name); } /** * Given the title (/T) of a reference, return the associated reference * @param name a string containing the path * @return a reference to the field, or null */ public PRIndirectReference getRefByName(String name) { FieldInformation fi = (FieldInformation)fieldByName.get(name); if (fi == null) return null; return fi.getRef(); } /** * Read, and comprehend the acroform * @param root the document root */ public void readAcroForm(PdfDictionary root) { if (root == null) return; hashMap = root.hashMap; pushAttrib(root); PdfArray fieldlist = (PdfArray)PdfReader.getPdfObjectRelease(root.get(PdfName.FIELDS)); iterateFields(fieldlist, null, null); } /** * After reading, we index all of the fields. Recursive. * @param fieldlist An array of fields * @param fieldDict the last field dictionary we encountered (recursively) * @param title the pathname of the field, up to this point or null */ protected void iterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String title) { for (Iterator it = fieldlist.listIterator(); it.hasNext();) { PRIndirectReference ref = (PRIndirectReference)it.next(); PdfDictionary dict = (PdfDictionary) PdfReader.getPdfObjectRelease(ref); // if we are not a field dictionary, pass our parent's values PRIndirectReference myFieldDict = fieldDict; String myTitle = title; PdfString tField = (PdfString)dict.get(PdfName.T); boolean isFieldDict = tField != null; if (isFieldDict) { myFieldDict = ref; if (title == null) myTitle = tField.toString(); else myTitle = title + '.' + tField.toString(); } PdfArray kids = (PdfArray)dict.get(PdfName.KIDS); if (kids != null) { pushAttrib(dict); iterateFields(kids, myFieldDict, myTitle); stack.remove(stack.size() - 1); // pop } else { // leaf node if (myFieldDict != null) { PdfDictionary mergedDict = (PdfDictionary)stack.get(stack.size() - 1); if (isFieldDict) mergedDict = mergeAttrib(mergedDict, dict); mergedDict.put(PdfName.T, new PdfString(myTitle)); FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict); fields.add(fi); fieldByName.put(myTitle, fi); } } } } /** * merge field attributes from two dictionaries * @param parent one dictionary * @param child the other dictionary * @return a merged dictionary */ protected PdfDictionary mergeAttrib(PdfDictionary parent, PdfDictionary child) { PdfDictionary targ = new PdfDictionary(); if (parent != null) targ.putAll(parent); for (Iterator it = child.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName) it.next(); if (key.equals(PdfName.DR) || key.equals(PdfName.DA) || key.equals(PdfName.Q) || key.equals(PdfName.FF) || key.equals(PdfName.DV) || key.equals(PdfName.V) || key.equals(PdfName.FT) || key.equals(PdfName.F)) { targ.put(key,child.get(key)); } } return targ; } /** * stack a level of dictionary. Merge in a dictionary from this level */ protected void pushAttrib(PdfDictionary dict) { PdfDictionary dic = null; if (!stack.isEmpty()) { dic = (PdfDictionary)stack.get(stack.size() - 1); } dic = mergeAttrib(dic, dict); stack.add(dic); } } src/core/com/lowagie/text/pdf/PRIndirectReference.java100644 0 0 7475 11213370070 20362 0ustar 0 0 /* * $Id: PRIndirectReference.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; public class PRIndirectReference extends PdfIndirectReference { protected PdfReader reader; // membervariables // constructors /** * Constructs a PdfIndirectReference. * * @param reader a PdfReader * @param number the object number. * @param generation the generation number. */ PRIndirectReference(PdfReader reader, int number, int generation) { type = INDIRECT; this.number = number; this.generation = generation; this.reader = reader; } /** * Constructs a PdfIndirectReference. * * @param reader a PdfReader * @param number the object number. */ PRIndirectReference(PdfReader reader, int number) { this(reader, number, 0); } // methods public void toPdf(PdfWriter writer, OutputStream os) throws IOException { int n = writer.getNewObjectNumber(reader, number, generation); os.write(PdfEncodings.convertToBytes(new StringBuffer().append(n).append(" 0 R").toString(), null)); } public PdfReader getReader() { return reader; } public void setNumber(int number, int generation) { this.number = number; this.generation = generation; } }src/core/com/lowagie/text/pdf/PRStream.java100644 0 0 20421 11154165267 16255 0ustar 0 0 /* * $Id: PRStream.java 3633 2008-12-23 18:42:06Z xlv $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import com.lowagie.text.Document; import com.lowagie.text.ExceptionConverter; public class PRStream extends PdfStream { protected PdfReader reader; protected int offset; protected int length; //added by ujihara for decryption protected int objNum = 0; protected int objGen = 0; public PRStream(PRStream stream, PdfDictionary newDic) { reader = stream.reader; offset = stream.offset; length = stream.length; compressed = stream.compressed; compressionLevel = stream.compressionLevel; streamBytes = stream.streamBytes; bytes = stream.bytes; objNum = stream.objNum; objGen = stream.objGen; if (newDic != null) putAll(newDic); else hashMap.putAll(stream.hashMap); } public PRStream(PRStream stream, PdfDictionary newDic, PdfReader reader) { this(stream, newDic); this.reader = reader; } public PRStream(PdfReader reader, int offset) { this.reader = reader; this.offset = offset; } public PRStream(PdfReader reader, byte conts[]) { this(reader, conts, DEFAULT_COMPRESSION); } /** * Creates a new PDF stream object that will replace a stream * in a existing PDF file. * @param reader the reader that holds the existing PDF * @param conts the new content * @param compressionLevel the compression level for the content * @since 2.1.3 (replacing the existing constructor without param compressionLevel) */ public PRStream(PdfReader reader, byte[] conts, int compressionLevel) { this.reader = reader; this.offset = -1; if (Document.compress) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); Deflater deflater = new Deflater(compressionLevel); DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater); zip.write(conts); zip.close(); deflater.end(); bytes = stream.toByteArray(); } catch (IOException ioe) { throw new ExceptionConverter(ioe); } put(PdfName.FILTER, PdfName.FLATEDECODE); } else bytes = conts; setLength(bytes.length); } /** * Sets the data associated with the stream, either compressed or * uncompressed. Note that the data will never be compressed if * Document.compress is set to false. * * @param data raw data, decrypted and uncompressed. * @param compress true if you want the stream to be compressed. * @since iText 2.1.1 */ public void setData(byte[] data, boolean compress) { setData(data, compress, DEFAULT_COMPRESSION); } /** * Sets the data associated with the stream, either compressed or * uncompressed. Note that the data will never be compressed if * Document.compress is set to false. * * @param data raw data, decrypted and uncompressed. * @param compress true if you want the stream to be compressed. * @param compressionLevel a value between -1 and 9 (ignored if compress == false) * @since iText 2.1.3 */ public void setData(byte[] data, boolean compress, int compressionLevel) { remove(PdfName.FILTER); this.offset = -1; if (Document.compress && compress) { try { ByteArrayOutputStream stream = new ByteArrayOutputStream(); Deflater deflater = new Deflater(compressionLevel); DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater); zip.write(data); zip.close(); deflater.end(); bytes = stream.toByteArray(); this.compressionLevel = compressionLevel; } catch (IOException ioe) { throw new ExceptionConverter(ioe); } put(PdfName.FILTER, PdfName.FLATEDECODE); } else bytes = data; setLength(bytes.length); } /**Sets the data associated with the stream * @param data raw data, decrypted and uncompressed. */ public void setData(byte[] data) { setData(data, true); } public void setLength(int length) { this.length = length; put(PdfName.LENGTH, new PdfNumber(length)); } public int getOffset() { return offset; } public int getLength() { return length; } public PdfReader getReader() { return reader; } public byte[] getBytes() { return bytes; } public void setObjNum(int objNum, int objGen) { this.objNum = objNum; this.objGen = objGen; } int getObjNum() { return objNum; } int getObjGen() { return objGen; } public void toPdf(PdfWriter writer, OutputStream os) throws IOException { byte[] b = PdfReader.getStreamBytesRaw(this); PdfEncryption crypto = null; if (writer != null) crypto = writer.getEncryption(); PdfObject objLen = get(PdfName.LENGTH); int nn = b.length; if (crypto != null) nn = crypto.calculateStreamSize(nn); put(PdfName.LENGTH, new PdfNumber(nn)); superToPdf(writer, os); put(PdfName.LENGTH, objLen); os.write(STARTSTREAM); if (length > 0) { if (crypto != null && !crypto.isEmbeddedFilesOnly()) b = crypto.encryptByteArray(b); os.write(b); } os.write(ENDSTREAM); } }src/core/com/lowagie/text/pdf/PRTokeniser.java100644 0 0 50471 11213370070 16757 0ustar 0 0 /* * $Id: PRTokeniser.java 3947 2009-06-02 17:51:05Z trumpetinc $ * * Copyright 2001, 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; /** * * @author Paulo Soares (psoares@consiste.pt) */ public class PRTokeniser { public static final int TK_NUMBER = 1; public static final int TK_STRING = 2; public static final int TK_NAME = 3; public static final int TK_COMMENT = 4; public static final int TK_START_ARRAY = 5; public static final int TK_END_ARRAY = 6; public static final int TK_START_DIC = 7; public static final int TK_END_DIC = 8; public static final int TK_REF = 9; public static final int TK_OTHER = 10; public static final boolean delims[] = { true, true, false, false, false, false, false, false, false, false, true, true, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, true, false, false, true, true, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false}; static final String EMPTY = ""; protected RandomAccessFileOrArray file; protected int type; protected String stringValue; protected int reference; protected int generation; protected boolean hexString; public PRTokeniser(String filename) throws IOException { file = new RandomAccessFileOrArray(filename); } public PRTokeniser(byte pdfIn[]) { file = new RandomAccessFileOrArray(pdfIn); } public PRTokeniser(RandomAccessFileOrArray file) { this.file = file; } public void seek(int pos) throws IOException { file.seek(pos); } public int getFilePointer() throws IOException { return file.getFilePointer(); } public void close() throws IOException { file.close(); } public int length() throws IOException { return file.length(); } public int read() throws IOException { return file.read(); } public RandomAccessFileOrArray getSafeFile() { return new RandomAccessFileOrArray(file); } public RandomAccessFileOrArray getFile() { return file; } public String readString(int size) throws IOException { StringBuffer buf = new StringBuffer(); int ch; while ((size--) > 0) { ch = file.read(); if (ch == -1) break; buf.append((char)ch); } return buf.toString(); } public static final boolean isWhitespace(int ch) { return (ch == 0 || ch == 9 || ch == 10 || ch == 12 || ch == 13 || ch == 32); } public static final boolean isDelimiter(int ch) { return (ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '/' || ch == '%'); } public static final boolean isDelimiterWhitespace(int ch) { return delims[ch + 1]; } public int getTokenType() { return type; } public String getStringValue() { return stringValue; } public int getReference() { return reference; } public int getGeneration() { return generation; } public void backOnePosition(int ch) { if (ch != -1) file.pushBack((byte)ch); } public void throwError(String error) throws IOException { throw new IOException(error + " at file pointer " + file.getFilePointer()); } public char checkPdfHeader() throws IOException { file.setStartOffset(0); String str = readString(1024); int idx = str.indexOf("%PDF-"); if (idx < 0) throw new IOException("PDF header signature not found."); file.setStartOffset(idx); return str.charAt(idx + 7); } public void checkFdfHeader() throws IOException { file.setStartOffset(0); String str = readString(1024); int idx = str.indexOf("%FDF-1.2"); if (idx < 0) throw new IOException("FDF header signature not found."); file.setStartOffset(idx); } public int getStartxref() throws IOException { int size = Math.min(1024, file.length()); int pos = file.length() - size; file.seek(pos); String str = readString(1024); int idx = str.lastIndexOf("startxref"); if (idx < 0) throw new IOException("PDF startxref not found."); return pos + idx; } public static int getHex(int v) { if (v >= '0' && v <= '9') return v - '0'; if (v >= 'A' && v <= 'F') return v - 'A' + 10; if (v >= 'a' && v <= 'f') return v - 'a' + 10; return -1; } public void nextValidToken() throws IOException { int level = 0; String n1 = null; String n2 = null; int ptr = 0; while (nextToken()) { if (type == TK_COMMENT) continue; switch (level) { case 0: { if (type != TK_NUMBER) return; ptr = file.getFilePointer(); n1 = stringValue; ++level; break; } case 1: { if (type != TK_NUMBER) { file.seek(ptr); type = TK_NUMBER; stringValue = n1; return; } n2 = stringValue; ++level; break; } default: { if (type != TK_OTHER || !stringValue.equals("R")) { file.seek(ptr); type = TK_NUMBER; stringValue = n1; return; } type = TK_REF; reference = Integer.parseInt(n1); generation = Integer.parseInt(n2); return; } } } // if we hit here, the file is either corrupt (stream ended unexpectedly), // or the last token ended exactly at the end of a stream. This last // case can occur inside an Object Stream. } public boolean nextToken() throws IOException { int ch = 0; do { ch = file.read(); } while (ch != -1 && isWhitespace(ch)); if (ch == -1) return false; // Note: We have to initialize stringValue here, after we've looked for the end of the stream, // to ensure that we don't lose the value of a token that might end exactly at the end // of the stream StringBuffer outBuf = null; stringValue = EMPTY; switch (ch) { case '[': type = TK_START_ARRAY; break; case ']': type = TK_END_ARRAY; break; case '/': { outBuf = new StringBuffer(); type = TK_NAME; while (true) { ch = file.read(); if (delims[ch + 1]) break; if (ch == '#') { ch = (getHex(file.read()) << 4) + getHex(file.read()); } outBuf.append((char)ch); } backOnePosition(ch); break; } case '>': ch = file.read(); if (ch != '>') throwError("'>' not expected"); type = TK_END_DIC; break; case '<': { int v1 = file.read(); if (v1 == '<') { type = TK_START_DIC; break; } outBuf = new StringBuffer(); type = TK_STRING; hexString = true; int v2 = 0; while (true) { while (isWhitespace(v1)) v1 = file.read(); if (v1 == '>') break; v1 = getHex(v1); if (v1 < 0) break; v2 = file.read(); while (isWhitespace(v2)) v2 = file.read(); if (v2 == '>') { ch = v1 << 4; outBuf.append((char)ch); break; } v2 = getHex(v2); if (v2 < 0) break; ch = (v1 << 4) + v2; outBuf.append((char)ch); v1 = file.read(); } if (v1 < 0 || v2 < 0) throwError("Error reading string"); break; } case '%': type = TK_COMMENT; do { ch = file.read(); } while (ch != -1 && ch != '\r' && ch != '\n'); break; case '(': { outBuf = new StringBuffer(); type = TK_STRING; hexString = false; int nesting = 0; while (true) { ch = file.read(); if (ch == -1) break; if (ch == '(') { ++nesting; } else if (ch == ')') { --nesting; } else if (ch == '\\') { boolean lineBreak = false; ch = file.read(); switch (ch) { case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case 'b': ch = '\b'; break; case 'f': ch = '\f'; break; case '(': case ')': case '\\': break; case '\r': lineBreak = true; ch = file.read(); if (ch != '\n') backOnePosition(ch); break; case '\n': lineBreak = true; break; default: { if (ch < '0' || ch > '7') { break; } int octal = ch - '0'; ch = file.read(); if (ch < '0' || ch > '7') { backOnePosition(ch); ch = octal; break; } octal = (octal << 3) + ch - '0'; ch = file.read(); if (ch < '0' || ch > '7') { backOnePosition(ch); ch = octal; break; } octal = (octal << 3) + ch - '0'; ch = octal & 0xff; break; } } if (lineBreak) continue; if (ch < 0) break; } else if (ch == '\r') { ch = file.read(); if (ch < 0) break; if (ch != '\n') { backOnePosition(ch); ch = '\n'; } } if (nesting == -1) break; outBuf.append((char)ch); } if (ch == -1) throwError("Error reading string"); break; } default: { outBuf = new StringBuffer(); if (ch == '-' || ch == '+' || ch == '.' || (ch >= '0' && ch <= '9')) { type = TK_NUMBER; do { outBuf.append((char)ch); ch = file.read(); } while (ch != -1 && ((ch >= '0' && ch <= '9') || ch == '.')); } else { type = TK_OTHER; do { outBuf.append((char)ch); ch = file.read(); } while (!delims[ch + 1]); } backOnePosition(ch); break; } } if (outBuf != null) stringValue = outBuf.toString(); return true; } public int intValue() { return Integer.parseInt(stringValue); } public boolean readLineSegment(byte input[]) throws IOException { int c = -1; boolean eol = false; int ptr = 0; int len = input.length; // ssteward, pdftk-1.10, 040922: // skip initial whitespace; added this because PdfReader.rebuildXref() // assumes that line provided by readLineSegment does not have init. whitespace; if ( ptr < len ) { while ( isWhitespace( (c = read()) ) ); } while ( !eol && ptr < len ) { switch (c) { case -1: case '\n': eol = true; break; case '\r': eol = true; int cur = getFilePointer(); if ((read()) != '\n') { seek(cur); } break; default: input[ptr++] = (byte)c; break; } // break loop? do it before we read() again if( eol || len <= ptr ) { break; } else { c = read(); } } if (ptr >= len) { eol = false; while (!eol) { switch (c = read()) { case -1: case '\n': eol = true; break; case '\r': eol = true; int cur = getFilePointer(); if ((read()) != '\n') { seek(cur); } break; } } } if ((c == -1) && (ptr == 0)) { return false; } if (ptr + 2 <= len) { input[ptr++] = (byte)' '; input[ptr] = (byte)'X'; } return true; } public static int[] checkObjectStart(byte line[]) { try { PRTokeniser tk = new PRTokeniser(line); int num = 0; int gen = 0; if (!tk.nextToken() || tk.getTokenType() != TK_NUMBER) return null; num = tk.intValue(); if (!tk.nextToken() || tk.getTokenType() != TK_NUMBER) return null; gen = tk.intValue(); if (!tk.nextToken()) return null; if (!tk.getStringValue().equals("obj")) return null; return new int[]{num, gen}; } catch (Exception ioe) { // empty on purpose } return null; } public boolean isHexString() { return this.hexString; } } src/core/com/lowagie/text/pdf/PageResources.java100644 0 0 16576 11000354131 17323 0ustar 0 0 /* * $Id: PageResources.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2003-2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.HashMap; import java.util.Iterator; class PageResources { protected PdfDictionary fontDictionary = new PdfDictionary(); protected PdfDictionary xObjectDictionary = new PdfDictionary(); protected PdfDictionary colorDictionary = new PdfDictionary(); protected PdfDictionary patternDictionary = new PdfDictionary(); protected PdfDictionary shadingDictionary = new PdfDictionary(); protected PdfDictionary extGStateDictionary = new PdfDictionary(); protected PdfDictionary propertyDictionary = new PdfDictionary(); protected HashMap forbiddenNames; protected PdfDictionary originalResources; protected int namePtr[] = {0}; protected HashMap usedNames; PageResources() { } void setOriginalResources(PdfDictionary resources, int newNamePtr[]) { if (newNamePtr != null) namePtr = newNamePtr; forbiddenNames = new HashMap(); usedNames = new HashMap(); if (resources == null) return; originalResources = new PdfDictionary(); originalResources.merge(resources); for (Iterator i = resources.getKeys().iterator(); i.hasNext();) { PdfName key = (PdfName)i.next(); PdfObject sub = PdfReader.getPdfObject(resources.get(key)); if (sub != null && sub.isDictionary()) { PdfDictionary dic = (PdfDictionary)sub; for (Iterator j = dic.getKeys().iterator(); j.hasNext();) { forbiddenNames.put(j.next(), null); } PdfDictionary dic2 = new PdfDictionary(); dic2.merge(dic); originalResources.put(key, dic2); } } } PdfName translateName(PdfName name) { PdfName translated = name; if (forbiddenNames != null) { translated = (PdfName)usedNames.get(name); if (translated == null) { while (true) { translated = new PdfName("Xi" + (namePtr[0]++)); if (!forbiddenNames.containsKey(translated)) break; } usedNames.put(name, translated); } } return translated; } PdfName addFont(PdfName name, PdfIndirectReference reference) { name = translateName(name); fontDictionary.put(name, reference); return name; } PdfName addXObject(PdfName name, PdfIndirectReference reference) { name = translateName(name); xObjectDictionary.put(name, reference); return name; } PdfName addColor(PdfName name, PdfIndirectReference reference) { name = translateName(name); colorDictionary.put(name, reference); return name; } void addDefaultColor(PdfName name, PdfObject obj) { if (obj == null || obj.isNull()) colorDictionary.remove(name); else colorDictionary.put(name, obj); } void addDefaultColor(PdfDictionary dic) { colorDictionary.merge(dic); } void addDefaultColorDiff(PdfDictionary dic) { colorDictionary.mergeDifferent(dic); } PdfName addShading(PdfName name, PdfIndirectReference reference) { name = translateName(name); shadingDictionary.put(name, reference); return name; } PdfName addPattern(PdfName name, PdfIndirectReference reference) { name = translateName(name); patternDictionary.put(name, reference); return name; } PdfName addExtGState(PdfName name, PdfIndirectReference reference) { name = translateName(name); extGStateDictionary.put(name, reference); return name; } PdfName addProperty(PdfName name, PdfIndirectReference reference) { name = translateName(name); propertyDictionary.put(name, reference); return name; } PdfDictionary getResources() { PdfResources resources = new PdfResources(); if (originalResources != null) resources.putAll(originalResources); resources.put(PdfName.PROCSET, new PdfLiteral("[/PDF /Text /ImageB /ImageC /ImageI]")); resources.add(PdfName.FONT, fontDictionary); resources.add(PdfName.XOBJECT, xObjectDictionary); resources.add(PdfName.COLORSPACE, colorDictionary); resources.add(PdfName.PATTERN, patternDictionary); resources.add(PdfName.SHADING, shadingDictionary); resources.add(PdfName.EXTGSTATE, extGStateDictionary); resources.add(PdfName.PROPERTIES, propertyDictionary); return resources; } boolean hasResources() { return (fontDictionary.size() > 0 || xObjectDictionary.size() > 0 || colorDictionary.size() > 0 || patternDictionary.size() > 0 || shadingDictionary.size() > 0 || extGStateDictionary.size() > 0 || propertyDictionary.size() > 0); } }src/core/com/lowagie/text/pdf/PatternColor.java100644 0 0 6353 11036112746 17155 0ustar 0 0 /* * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** Represents a pattern. Can be used in high-level constructs (Paragraph, Cell, etc.). */ public class PatternColor extends ExtendedColor { private static final long serialVersionUID = -1185448552860615964L; /** * The actual pattern. */ PdfPatternPainter painter; /** Creates a color representing a pattern. * @param painter the actual pattern */ public PatternColor(PdfPatternPainter painter) { super(TYPE_PATTERN, .5f, .5f, .5f); this.painter = painter; } /** Gets the pattern. * @return the pattern */ public PdfPatternPainter getPainter() { return this.painter; } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return painter.hashCode(); } } src/core/com/lowagie/text/pdf/PdfAcroForm.java100644 0 0 61464 11213370070 16720 0ustar 0 0 /* * $Id: PdfAcroForm.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** * Each PDF document can contain maximum 1 AcroForm. */ public class PdfAcroForm extends PdfDictionary { private PdfWriter writer; /** This is a map containing FieldTemplates. */ private HashMap fieldTemplates = new HashMap(); /** This is an array containing DocumentFields. */ private PdfArray documentFields = new PdfArray(); /** This is an array containing the calculationorder of the fields. */ private PdfArray calculationOrder = new PdfArray(); /** Contains the signature flags. */ private int sigFlags = 0; /** Creates new PdfAcroForm * @param writer */ public PdfAcroForm(PdfWriter writer) { super(); this.writer = writer; } public void setNeedAppearances(boolean value) { put(PdfName.NEEDAPPEARANCES, new PdfBoolean(value)); } /** * Adds fieldTemplates. * @param ft */ public void addFieldTemplates(HashMap ft) { fieldTemplates.putAll(ft); } /** * Adds documentFields. * @param ref */ public void addDocumentField(PdfIndirectReference ref) { documentFields.add(ref); } /** * Checks if the Acroform is valid * @return true if the Acroform is valid */ public boolean isValid() { if (documentFields.size() == 0) return false; put(PdfName.FIELDS, documentFields); if (sigFlags != 0) put(PdfName.SIGFLAGS, new PdfNumber(sigFlags)); if (calculationOrder.size() > 0) put(PdfName.CO, calculationOrder); if (fieldTemplates.isEmpty()) return true; PdfDictionary dic = new PdfDictionary(); for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) { PdfTemplate template = (PdfTemplate)it.next(); PdfFormField.mergeResources(dic, (PdfDictionary)template.getResources()); } put(PdfName.DR, dic); put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); PdfDictionary fonts = (PdfDictionary)dic.get(PdfName.FONT); if (fonts != null) { writer.eliminateFontSubset(fonts); } return true; } /** * Adds an object to the calculationOrder. * @param formField */ public void addCalculationOrder(PdfFormField formField) { calculationOrder.add(formField.getIndirectReference()); } /** * Sets the signature flags. * @param f */ public void setSigFlags(int f) { sigFlags |= f; } /** * Adds a formfield to the AcroForm. * @param formField */ public void addFormField(PdfFormField formField) { writer.addAnnotation(formField); } /** * @param name * @param caption * @param value * @param url * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addHtmlPostButton(String name, String caption, String value, String url, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT); PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value); drawButton(button, caption, font, fontSize, llx, lly, urx, ury); addFormField(button); return button; } /** * @param name * @param caption * @param value * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addResetButton(String name, String caption, String value, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfAction action = PdfAction.createResetForm(null, 0); PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value); drawButton(button, caption, font, fontSize, llx, lly, urx, ury); addFormField(button); return button; } /** * @param name * @param value * @param url * @param appearance * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addMap(String name, String value, String url, PdfContentByte appearance, float llx, float lly, float urx, float ury) { PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_COORDINATES); PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, null); PdfAppearance pa = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); pa.add(appearance); button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa); addFormField(button); return button; } /** * @param button * @param characteristics * @param name * @param value */ public void setButtonParams(PdfFormField button, int characteristics, String name, String value) { button.setButton(characteristics); button.setFlags(PdfAnnotation.FLAGS_PRINT); button.setPage(); button.setFieldName(name); if (value != null) button.setValueAsString(value); } /** * @param button * @param caption * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury */ public void drawButton(PdfFormField button, String caption, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfAppearance pa = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); pa.drawButton(0f, 0f, urx - llx, ury - lly, caption, font, fontSize); button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa); } /** * @param name * @param value * @return a PdfFormField */ public PdfFormField addHiddenField(String name, String value) { PdfFormField hidden = PdfFormField.createEmpty(writer); hidden.setFieldName(name); hidden.setValueAsName(value); addFormField(hidden); return hidden; } /** * @param name * @param text * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addSingleLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PLAINTEXT, 0); setTextFieldParams(field, text, name, llx, lly, urx, ury); drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury); addFormField(field); return field; } /** * @param name * @param text * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addMultiLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.MULTILINE, PdfFormField.PLAINTEXT, 0); setTextFieldParams(field, text, name, llx, lly, urx, ury); drawMultiLineOfText(field, text, font, fontSize, llx, lly, urx, ury); addFormField(field); return field; } /** * @param name * @param text * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return PdfFormField */ public PdfFormField addSingleLinePasswordField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PASSWORD, 0); setTextFieldParams(field, text, name, llx, lly, urx, ury); drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury); addFormField(field); return field; } /** * @param field * @param text * @param name * @param llx * @param lly * @param urx * @param ury */ public void setTextFieldParams(PdfFormField field, String text, String name, float llx, float lly, float urx, float ury) { field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); field.setValueAsString(text); field.setDefaultValueAsString(text); field.setFieldName(name); field.setFlags(PdfAnnotation.FLAGS_PRINT); field.setPage(); } /** * @param field * @param text * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury */ public void drawSingleLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate(); tp2.setFontAndSize(font, fontSize); tp2.resetRGBColorFill(); field.setDefaultAppearanceString(tp2); tp.drawTextField(0f, 0f, urx - llx, ury - lly); tp.beginVariableText(); tp.saveState(); tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f); tp.clip(); tp.newPath(); tp.beginText(); tp.setFontAndSize(font, fontSize); tp.resetRGBColorFill(); tp.setTextMatrix(4, (ury - lly) / 2 - (fontSize * 0.3f)); tp.showText(text); tp.endText(); tp.restoreState(); tp.endVariableText(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); } /** * @param field * @param text * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury */ public void drawMultiLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate(); tp2.setFontAndSize(font, fontSize); tp2.resetRGBColorFill(); field.setDefaultAppearanceString(tp2); tp.drawTextField(0f, 0f, urx - llx, ury - lly); tp.beginVariableText(); tp.saveState(); tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f); tp.clip(); tp.newPath(); tp.beginText(); tp.setFontAndSize(font, fontSize); tp.resetRGBColorFill(); tp.setTextMatrix(4, 5); java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(text, "\n"); float yPos = ury - lly; while (tokenizer.hasMoreTokens()) { yPos -= fontSize * 1.2f; tp.showTextAligned(PdfContentByte.ALIGN_LEFT, tokenizer.nextToken(), 3, yPos, 0); } tp.endText(); tp.restoreState(); tp.endVariableText(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); } /** * @param name * @param value * @param status * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addCheckBox(String name, String value, boolean status, float llx, float lly, float urx, float ury) { PdfFormField field = PdfFormField.createCheckBox(writer); setCheckBoxParams(field, name, value, status, llx, lly, urx, ury); drawCheckBoxAppearences(field, value, llx, lly, urx, ury); addFormField(field); return field; } /** * @param field * @param name * @param value * @param status * @param llx * @param lly * @param urx * @param ury */ public void setCheckBoxParams(PdfFormField field, String name, String value, boolean status, float llx, float lly, float urx, float ury) { field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE); field.setFieldName(name); if (status) { field.setValueAsName(value); field.setAppearanceState(value); } else { field.setValueAsName("Off"); field.setAppearanceState("Off"); } field.setFlags(PdfAnnotation.FLAGS_PRINT); field.setPage(); field.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID)); } /** * @param field * @param value * @param llx * @param lly * @param urx * @param ury */ public void drawCheckBoxAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) { BaseFont font = null; try { font = BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); } catch(Exception e) { throw new ExceptionConverter(e); } float size = (ury - lly); PdfAppearance tpOn = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); PdfAppearance tp2 = (PdfAppearance)tpOn.getDuplicate(); tp2.setFontAndSize(font, size); tp2.resetRGBColorFill(); field.setDefaultAppearanceString(tp2); tpOn.drawTextField(0f, 0f, urx - llx, ury - lly); tpOn.saveState(); tpOn.resetRGBColorFill(); tpOn.beginText(); tpOn.setFontAndSize(font, size); tpOn.showTextAligned(PdfContentByte.ALIGN_CENTER, "4", (urx - llx) / 2, (ury - lly) / 2 - (size * 0.3f), 0); tpOn.endText(); tpOn.restoreState(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn); PdfAppearance tpOff = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); tpOff.drawTextField(0f, 0f, urx - llx, ury - lly); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff); } /** * @param name * @param defaultValue * @param noToggleToOff * @return a PdfFormField */ public PdfFormField getRadioGroup(String name, String defaultValue, boolean noToggleToOff) { PdfFormField radio = PdfFormField.createRadioButton(writer, noToggleToOff); radio.setFieldName(name); radio.setValueAsName(defaultValue); return radio; } /** * @param radiogroup */ public void addRadioGroup(PdfFormField radiogroup) { addFormField(radiogroup); } /** * @param radiogroup * @param value * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addRadioButton(PdfFormField radiogroup, String value, float llx, float lly, float urx, float ury) { PdfFormField radio = PdfFormField.createEmpty(writer); radio.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE); String name = ((PdfName)radiogroup.get(PdfName.V)).toString().substring(1); if (name.equals(value)) { radio.setAppearanceState(value); } else { radio.setAppearanceState("Off"); } drawRadioAppearences(radio, value, llx, lly, urx, ury); radiogroup.addKid(radio); return radio; } /** * @param field * @param value * @param llx * @param lly * @param urx * @param ury */ public void drawRadioAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) { PdfAppearance tpOn = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); tpOn.drawRadioField(0f, 0f, urx - llx, ury - lly, true); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn); PdfAppearance tpOff = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); tpOff.drawRadioField(0f, 0f, urx - llx, ury - lly, false); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff); } /** * @param name * @param options * @param defaultValue * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addSelectList(String name, String[] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField choice = PdfFormField.createList(writer, options, 0); setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); StringBuffer text = new StringBuffer(); for (int i = 0; i < options.length; i++) { text.append(options[i]).append('\n'); } drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury); addFormField(choice); return choice; } /** * @param name * @param options * @param defaultValue * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addSelectList(String name, String[][] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField choice = PdfFormField.createList(writer, options, 0); setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); StringBuffer text = new StringBuffer(); for (int i = 0; i < options.length; i++) { text.append(options[i][1]).append('\n'); } drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury); addFormField(choice); return choice; } /** * @param name * @param options * @param defaultValue * @param editable * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addComboBox(String name, String[] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0); setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); if (defaultValue == null) { defaultValue = options[0]; } drawSingleLineOfText(choice, defaultValue, font, fontSize, llx, lly, urx, ury); addFormField(choice); return choice; } /** * @param name * @param options * @param defaultValue * @param editable * @param font * @param fontSize * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addComboBox(String name, String[][] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0); setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); String value = null; for (int i = 0; i < options.length; i++) { if (options[i][0].equals(defaultValue)) { value = options[i][1]; break; } } if (value == null) { value = options[0][1]; } drawSingleLineOfText(choice, value, font, fontSize, llx, lly, urx, ury); addFormField(choice); return choice; } /** * @param field * @param name * @param defaultValue * @param llx * @param lly * @param urx * @param ury */ public void setChoiceParams(PdfFormField field, String name, String defaultValue, float llx, float lly, float urx, float ury) { field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); if (defaultValue != null) { field.setValueAsString(defaultValue); field.setDefaultValueAsString(defaultValue); } field.setFieldName(name); field.setFlags(PdfAnnotation.FLAGS_PRINT); field.setPage(); field.setBorderStyle(new PdfBorderDictionary(2, PdfBorderDictionary.STYLE_SOLID)); } /** * @param name * @param llx * @param lly * @param urx * @param ury * @return a PdfFormField */ public PdfFormField addSignature(String name, float llx, float lly, float urx, float ury) { PdfFormField signature = PdfFormField.createSignature(writer); setSignatureParams(signature, name, llx, lly, urx, ury); drawSignatureAppearences(signature, llx, lly, urx, ury); addFormField(signature); return signature; } /** * @param field * @param name * @param llx * @param lly * @param urx * @param ury */ public void setSignatureParams(PdfFormField field, String name, float llx, float lly, float urx, float ury) { field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); field.setFieldName(name); field.setFlags(PdfAnnotation.FLAGS_PRINT); field.setPage(); field.setMKBorderColor(java.awt.Color.black); field.setMKBackgroundColor(java.awt.Color.white); } /** * @param field * @param llx * @param lly * @param urx * @param ury */ public void drawSignatureAppearences(PdfFormField field, float llx, float lly, float urx, float ury) { PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly); tp.setGrayFill(1.0f); tp.rectangle(0, 0, urx - llx, ury - lly); tp.fill(); tp.setGrayStroke(0); tp.setLineWidth(1); tp.rectangle(0.5f, 0.5f, urx - llx - 0.5f, ury - lly - 0.5f); tp.closePathStroke(); tp.saveState(); tp.rectangle(1, 1, urx - llx - 2, ury - lly - 2); tp.clip(); tp.newPath(); tp.restoreState(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); } }src/core/com/lowagie/text/pdf/PdfAction.java100644 0 0 54717 11213370070 16430 0ustar 0 0 /* * $Id: PdfAction.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 2000 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import com.lowagie.text.pdf.collection.PdfTargetDictionary; /** * A PdfAction defines an action that can be triggered from a PDF file. * * @see PdfDictionary */ public class PdfAction extends PdfDictionary { /** A named action to go to the first page. */ public static final int FIRSTPAGE = 1; /** A named action to go to the previous page. */ public static final int PREVPAGE = 2; /** A named action to go to the next page. */ public static final int NEXTPAGE = 3; /** A named action to go to the last page. */ public static final int LASTPAGE = 4; /** A named action to open a print dialog. */ public static final int PRINTDIALOG = 5; /** a possible submitvalue */ public static final int SUBMIT_EXCLUDE = 1; /** a possible submitvalue */ public static final int SUBMIT_INCLUDE_NO_VALUE_FIELDS = 2; /** a possible submitvalue */ public static final int SUBMIT_HTML_FORMAT = 4; /** a possible submitvalue */ public static final int SUBMIT_HTML_GET = 8; /** a possible submitvalue */ public static final int SUBMIT_COORDINATES = 16; /** a possible submitvalue */ public static final int SUBMIT_XFDF = 32; /** a possible submitvalue */ public static final int SUBMIT_INCLUDE_APPEND_SAVES = 64; /** a possible submitvalue */ public static final int SUBMIT_INCLUDE_ANNOTATIONS = 128; /** a possible submitvalue */ public static final int SUBMIT_PDF = 256; /** a possible submitvalue */ public static final int SUBMIT_CANONICAL_FORMAT = 512; /** a possible submitvalue */ public static final int SUBMIT_EXCL_NON_USER_ANNOTS = 1024; /** a possible submitvalue */ public static final int SUBMIT_EXCL_F_KEY = 2048; /** a possible submitvalue */ public static final int SUBMIT_EMBED_FORM = 8196; /** a possible submitvalue */ public static final int RESET_EXCLUDE = 1; // constructors /** Create an empty action. */ public PdfAction() { } /** * Constructs a new PdfAction of Subtype URI. * * @param url the Url to go to */ public PdfAction(URL url) { this(url.toExternalForm()); } /** * Construct a new PdfAction of Subtype URI that accepts the x and y coordinate of the position that was clicked. * @param url * @param isMap */ public PdfAction(URL url, boolean isMap) { this(url.toExternalForm(), isMap); } /** * Constructs a new PdfAction of Subtype URI. * * @param url the url to go to */ public PdfAction(String url) { this(url, false); } /** * Construct a new PdfAction of Subtype URI that accepts the x and y coordinate of the position that was clicked. * @param url * @param isMap */ public PdfAction(String url, boolean isMap) { put(PdfName.S, PdfName.URI); put(PdfName.URI, new PdfString(url)); if (isMap) put(PdfName.ISMAP, PdfBoolean.PDFTRUE); } /** * Constructs a new PdfAction of Subtype GoTo. * @param destination the destination to go to */ PdfAction(PdfIndirectReference destination) { put(PdfName.S, PdfName.GOTO); put(PdfName.D, destination); } /** * Constructs a new PdfAction of Subtype GoToR. * @param filename the file name to go to * @param name the named destination to go to */ public PdfAction(String filename, String name) { put(PdfName.S, PdfName.GOTOR); put(PdfName.F, new PdfString(filename)); put(PdfName.D, new PdfString(name)); } /** * Constructs a new PdfAction of Subtype GoToR. * @param filename the file name to go to * @param page the page destination to go to */ public PdfAction(String filename, int page) { put(PdfName.S, PdfName.GOTOR); put(PdfName.F, new PdfString(filename)); put(PdfName.D, new PdfLiteral("[" + (page - 1) + " /FitH 10000]")); } /** Implements name actions. The action can be FIRSTPAGE, LASTPAGE, * NEXTPAGE, PREVPAGE and PRINTDIALOG. * @param named the named action */ public PdfAction(int named) { put(PdfName.S, PdfName.NAMED); switch (named) { case FIRSTPAGE: put(PdfName.N, PdfName.FIRSTPAGE); break; case LASTPAGE: put(PdfName.N, PdfName.LASTPAGE); break; case NEXTPAGE: put(PdfName.N, PdfName.NEXTPAGE); break; case PREVPAGE: put(PdfName.N, PdfName.PREVPAGE); break; case PRINTDIALOG: put(PdfName.S, PdfName.JAVASCRIPT); put(PdfName.JS, new PdfString("this.print(true);\r")); break; default: throw new RuntimeException("Invalid named action."); } } /** Launches an application or a document. * @param application the application to be launched or the document to be opened or printed. * @param parameters (Windows-specific) A parameter string to be passed to the application. * It can be null. * @param operation (Windows-specific) the operation to perform: "open" - Open a document, * "print" - Print a document. * It can be null. * @param defaultDir (Windows-specific) the default directory in standard DOS syntax. * It can be null. */ public PdfAction(String application, String parameters, String operation, String defaultDir) { put(PdfName.S, PdfName.LAUNCH); if (parameters == null && operation == null && defaultDir == null) put(PdfName.F, new PdfString(application)); else { PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.F, new PdfString(application)); if (parameters != null) dic.put(PdfName.P, new PdfString(parameters)); if (operation != null) dic.put(PdfName.O, new PdfString(operation)); if (defaultDir != null) dic.put(PdfName.D, new PdfString(defaultDir)); put(PdfName.WIN, dic); } } /** Launches an application or a document. * @param application the application to be launched or the document to be opened or printed. * @param parameters (Windows-specific) A parameter string to be passed to the application. * It can be null. * @param operation (Windows-specific) the operation to perform: "open" - Open a document, * "print" - Print a document. * It can be null. * @param defaultDir (Windows-specific) the default directory in standard DOS syntax. * It can be null. * @return a Launch action */ public static PdfAction createLaunch(String application, String parameters, String operation, String defaultDir) { return new PdfAction(application, parameters, operation, defaultDir); } /**Creates a Rendition action * @param file * @param fs * @param mimeType * @param ref * @return a Media Clip action * @throws IOException */ public static PdfAction rendition(String file, PdfFileSpecification fs, String mimeType, PdfIndirectReference ref) throws IOException { PdfAction js = new PdfAction(); js.put(PdfName.S, PdfName.RENDITION); js.put(PdfName.R, new PdfRendition(file, fs, mimeType)); js.put(new PdfName("OP"), new PdfNumber(0)); js.put(new PdfName("AN"), ref); return js; } /** Creates a JavaScript action. If the JavaScript is smaller than * 50 characters it will be placed as a string, otherwise it will * be placed as a compressed stream. * @param code the JavaScript code * @param writer the writer for this action * @param unicode select JavaScript unicode. Note that the internal * Acrobat JavaScript engine does not support unicode, * so this may or may not work for you * @return the JavaScript action */ public static PdfAction javaScript(String code, PdfWriter writer, boolean unicode) { PdfAction js = new PdfAction(); js.put(PdfName.S, PdfName.JAVASCRIPT); if (unicode && code.length() < 50) { js.put(PdfName.JS, new PdfString(code, PdfObject.TEXT_UNICODE)); } else if (!unicode && code.length() < 100) { js.put(PdfName.JS, new PdfString(code)); } else { try { byte b[] = PdfEncodings.convertToBytes(code, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING); PdfStream stream = new PdfStream(b); stream.flateCompress(writer.getCompressionLevel()); js.put(PdfName.JS, writer.addToBody(stream).getIndirectReference()); } catch (Exception e) { js.put(PdfName.JS, new PdfString(code)); } } return js; } /** Creates a JavaScript action. If the JavaScript is smaller than * 50 characters it will be place as a string, otherwise it will * be placed as a compressed stream. * @param code the JavaScript code * @param writer the writer for this action * @return the JavaScript action */ public static PdfAction javaScript(String code, PdfWriter writer) { return javaScript(code, writer, false); } /** * A Hide action hides or shows an object. * @param obj object to hide or show * @param hide true is hide, false is show * @return a Hide Action */ static PdfAction createHide(PdfObject obj, boolean hide) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.HIDE); action.put(PdfName.T, obj); if (!hide) action.put(PdfName.H, PdfBoolean.PDFFALSE); return action; } /** * A Hide action hides or shows an annotation. * @param annot * @param hide * @return A Hide Action */ public static PdfAction createHide(PdfAnnotation annot, boolean hide) { return createHide(annot.getIndirectReference(), hide); } /** * A Hide action hides or shows an annotation. * @param name * @param hide * @return A Hide Action */ public static PdfAction createHide(String name, boolean hide) { return createHide(new PdfString(name), hide); } static PdfArray buildArray(Object names[]) { PdfArray array = new PdfArray(); for (int k = 0; k < names.length; ++k) { Object obj = names[k]; if (obj instanceof String) array.add(new PdfString((String)obj)); else if (obj instanceof PdfAnnotation) array.add(((PdfAnnotation)obj).getIndirectReference()); else throw new RuntimeException("The array must contain String or PdfAnnotation."); } return array; } /** * A Hide action hides or shows objects. * @param names * @param hide * @return A Hide Action */ public static PdfAction createHide(Object names[], boolean hide) { return createHide(buildArray(names), hide); } /** * Creates a submit form. * @param file the URI to submit the form to * @param names the objects to submit * @param flags submit properties * @return A PdfAction */ public static PdfAction createSubmitForm(String file, Object names[], int flags) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.SUBMITFORM); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.F, new PdfString(file)); dic.put(PdfName.FS, PdfName.URL); action.put(PdfName.F, dic); if (names != null) action.put(PdfName.FIELDS, buildArray(names)); action.put(PdfName.FLAGS, new PdfNumber(flags)); return action; } /** * Creates a resetform. * @param names the objects to reset * @param flags submit properties * @return A PdfAction */ public static PdfAction createResetForm(Object names[], int flags) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.RESETFORM); if (names != null) action.put(PdfName.FIELDS, buildArray(names)); action.put(PdfName.FLAGS, new PdfNumber(flags)); return action; } /** * Creates an Import field. * @param file * @return A PdfAction */ public static PdfAction createImportData(String file) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.IMPORTDATA); action.put(PdfName.F, new PdfString(file)); return action; } /** Add a chained action. * @param na the next action */ public void next(PdfAction na) { PdfObject nextAction = get(PdfName.NEXT); if (nextAction == null) put(PdfName.NEXT, na); else if (nextAction.isDictionary()) { PdfArray array = new PdfArray(nextAction); array.add(na); put(PdfName.NEXT, array); } else { ((PdfArray)nextAction).add(na); } } /** Creates a GoTo action to an internal page. * @param page the page to go. First page is 1 * @param dest the destination for the page * @param writer the writer for this action * @return a GoTo action */ public static PdfAction gotoLocalPage(int page, PdfDestination dest, PdfWriter writer) { PdfIndirectReference ref = writer.getPageReference(page); dest.addPage(ref); PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.GOTO); action.put(PdfName.D, dest); return action; } /** * Creates a GoTo action to a named destination. * @param dest the named destination * @param isName if true sets the destination as a name, if false sets it as a String * @return a GoTo action */ public static PdfAction gotoLocalPage(String dest, boolean isName) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.GOTO); if (isName) action.put(PdfName.D, new PdfName(dest)); else action.put(PdfName.D, new PdfString(dest, null)); return action; } /** * Creates a GoToR action to a named destination. * @param filename the file name to go to * @param dest the destination name * @param isName if true sets the destination as a name, if false sets it as a String * @param newWindow open the document in a new window if true, if false the current document is replaced by the new document. * @return a GoToR action */ public static PdfAction gotoRemotePage(String filename, String dest, boolean isName, boolean newWindow) { PdfAction action = new PdfAction(); action.put(PdfName.F, new PdfString(filename)); action.put(PdfName.S, PdfName.GOTOR); if (isName) action.put(PdfName.D, new PdfName(dest)); else action.put(PdfName.D, new PdfString(dest, null)); if (newWindow) action.put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE); return action; } /** * Creates a GoToE action to an embedded file. * @param filename the root document of the target (null if the target is in the same document) * @param dest the named destination * @param isName if true sets the destination as a name, if false sets it as a String * @return a GoToE action */ public static PdfAction gotoEmbedded(String filename, PdfTargetDictionary target, String dest, boolean isName, boolean newWindow) { if (isName) return gotoEmbedded(filename, target, new PdfName(dest), newWindow); else return gotoEmbedded(filename, target, new PdfString(dest, null), newWindow); } /** * Creates a GoToE action to an embedded file. * @param filename the root document of the target (null if the target is in the same document) * @param target a path to the target document of this action * @param dest the destination inside the target document, can be of type PdfDestination, PdfName, or PdfString * @param newWindow if true, the destination document should be opened in a new window * @return a GoToE action */ public static PdfAction gotoEmbedded(String filename, PdfTargetDictionary target, PdfObject dest, boolean newWindow) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.GOTOE); action.put(PdfName.T, target); action.put(PdfName.D, dest); action.put(PdfName.NEWWINDOW, new PdfBoolean(newWindow)); if (filename != null) { action.put(PdfName.F, new PdfString(filename)); } return action; } /** * A set-OCG-state action (PDF 1.5) sets the state of one or more optional content * groups. * @param state an array consisting of any number of sequences beginning with a PdfName * or String (ON, OFF, or Toggle) followed by one or more optional content group dictionaries * PdfLayer or a PdfIndirectReference to a PdfLayer.
* The array elements are processed from left to right; each name is applied * to the subsequent groups until the next name is encountered: *

    *
  • ON sets the state of subsequent groups to ON
  • *
  • OFF sets the state of subsequent groups to OFF
  • *
  • Toggle reverses the state of subsequent groups
  • *
* @param preserveRB if true, indicates that radio-button state relationships between optional * content groups (as specified by the RBGroups entry in the current configuration * dictionary) should be preserved when the states in the * state array are applied. That is, if a group is set to ON (either by ON or Toggle) during * processing of the state array, any other groups belong to the same radio-button * group are turned OFF. If a group is set to OFF, there is no effect on other groups.
* If false, radio-button state relationships, if any, are ignored * @return the action */ public static PdfAction setOCGstate(ArrayList state, boolean preserveRB) { PdfAction action = new PdfAction(); action.put(PdfName.S, PdfName.SETOCGSTATE); PdfArray a = new PdfArray(); for (int k = 0; k < state.size(); ++k) { Object o = state.get(k); if (o == null) continue; if (o instanceof PdfIndirectReference) a.add((PdfIndirectReference)o); else if (o instanceof PdfLayer) a.add(((PdfLayer)o).getRef()); else if (o instanceof PdfName) a.add((PdfName)o); else if (o instanceof String) { PdfName name = null; String s = (String)o; if (s.equalsIgnoreCase("on")) name = PdfName.ON; else if (s.equalsIgnoreCase("off")) name = PdfName.OFF; else if (s.equalsIgnoreCase("toggle")) name = PdfName.TOGGLE; else throw new IllegalArgumentException("A string '" + s + " was passed in state. Only 'ON', 'OFF' and 'Toggle' are allowed."); a.add(name); } else throw new IllegalArgumentException("Invalid type was passed in state: " + o.getClass().getName()); } action.put(PdfName.STATE, a); if (!preserveRB) action.put(PdfName.PRESERVERB, PdfBoolean.PDFFALSE); return action; } } src/core/com/lowagie/text/pdf/PdfAnnotation.java100644 0 0 100105 11213370070 17324 0ustar 0 0 /* * $Id: PdfAnnotation.java 3917 2009-04-27 12:52:16Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.util.HashMap; import com.lowagie.text.Rectangle; /** * A PdfAnnotation is a note that is associated with a page. * * @see PdfDictionary */ public class PdfAnnotation extends PdfDictionary { /** highlight attributename */ public static final PdfName HIGHLIGHT_NONE = PdfName.N; /** highlight attributename */ public static final PdfName HIGHLIGHT_INVERT = PdfName.I; /** highlight attributename */ public static final PdfName HIGHLIGHT_OUTLINE = PdfName.O; /** highlight attributename */ public static final PdfName HIGHLIGHT_PUSH = PdfName.P; /** highlight attributename */ public static final PdfName HIGHLIGHT_TOGGLE = PdfName.T; /** flagvalue */ public static final int FLAGS_INVISIBLE = 1; /** flagvalue */ public static final int FLAGS_HIDDEN = 2; /** flagvalue */ public static final int FLAGS_PRINT = 4; /** flagvalue */ public static final int FLAGS_NOZOOM = 8; /** flagvalue */ public static final int FLAGS_NOROTATE = 16; /** flagvalue */ public static final int FLAGS_NOVIEW = 32; /** flagvalue */ public static final int FLAGS_READONLY = 64; /** flagvalue */ public static final int FLAGS_LOCKED = 128; /** flagvalue */ public static final int FLAGS_TOGGLENOVIEW = 256; /** appearance attributename */ public static final PdfName APPEARANCE_NORMAL = PdfName.N; /** appearance attributename */ public static final PdfName APPEARANCE_ROLLOVER = PdfName.R; /** appearance attributename */ public static final PdfName APPEARANCE_DOWN = PdfName.D; /** attributevalue */ public static final PdfName AA_ENTER = PdfName.E; /** attributevalue */ public static final PdfName AA_EXIT = PdfName.X; /** attributevalue */ public static final PdfName AA_DOWN = PdfName.D; /** attributevalue */ public static final PdfName AA_UP = PdfName.U; /** attributevalue */ public static final PdfName AA_FOCUS = PdfName.FO; /** attributevalue */ public static final PdfName AA_BLUR = PdfName.BL; /** attributevalue */ public static final PdfName AA_JS_KEY = PdfName.K; /** attributevalue */ public static final PdfName AA_JS_FORMAT = PdfName.F; /** attributevalue */ public static final PdfName AA_JS_CHANGE = PdfName.V; /** attributevalue */ public static final PdfName AA_JS_OTHER_CHANGE = PdfName.C; /** attributevalue */ public static final int MARKUP_HIGHLIGHT = 0; /** attributevalue */ public static final int MARKUP_UNDERLINE = 1; /** attributevalue */ public static final int MARKUP_STRIKEOUT = 2; /** * attributevalue * @since 2.1.3 */ public static final int MARKUP_SQUIGGLY = 3; protected PdfWriter writer; /** * Reference to this annotation. * @since 2.1.6; was removed in 2.1.5, but restored in 2.1.6 */ protected PdfIndirectReference reference; protected HashMap templates; protected boolean form = false; protected boolean annotation = true; /** Holds value of property used. */ protected boolean used = false; /** Holds value of property placeInPage. */ private int placeInPage = -1; // constructors public PdfAnnotation(PdfWriter writer, Rectangle rect) { this.writer = writer; if (rect != null) put(PdfName.RECT, new PdfRectangle(rect)); } /** * Constructs a new PdfAnnotation of subtype text. * @param writer * @param llx * @param lly * @param urx * @param ury * @param title * @param content */ public PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfString title, PdfString content) { this.writer = writer; put(PdfName.SUBTYPE, PdfName.TEXT); put(PdfName.T, title); put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury)); put(PdfName.CONTENTS, content); } /** * Constructs a new PdfAnnotation of subtype link (Action). * @param writer * @param llx * @param lly * @param urx * @param ury * @param action */ public PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) { this.writer = writer; put(PdfName.SUBTYPE, PdfName.LINK); put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury)); put(PdfName.A, action); put(PdfName.BORDER, new PdfBorderArray(0, 0, 0)); put(PdfName.C, new PdfColor(0x00, 0x00, 0xFF)); } /** * Creates a screen PdfAnnotation * @param writer * @param rect * @param clipTitle * @param fs * @param mimeType * @param playOnDisplay * @return a screen PdfAnnotation * @throws IOException */ public static PdfAnnotation createScreen(PdfWriter writer, Rectangle rect, String clipTitle, PdfFileSpecification fs, String mimeType, boolean playOnDisplay) throws IOException { PdfAnnotation ann = new PdfAnnotation(writer, rect); ann.put(PdfName.SUBTYPE, PdfName.SCREEN); ann.put (PdfName.F, new PdfNumber(FLAGS_PRINT)); ann.put(PdfName.TYPE, PdfName.ANNOT); ann.setPage(); PdfIndirectReference ref = ann.getIndirectReference(); PdfAction action = PdfAction.rendition(clipTitle,fs,mimeType, ref); PdfIndirectReference actionRef = writer.addToBody(action).getIndirectReference(); // for play on display add trigger event if (playOnDisplay) { PdfDictionary aa = new PdfDictionary(); aa.put(new PdfName("PV"), actionRef); ann.put(PdfName.AA, aa); } ann.put(PdfName.A, actionRef); return ann; } /** * Returns an indirect reference to the annotation * @return the indirect reference */ public PdfIndirectReference getIndirectReference() { if (reference == null) { reference = writer.getPdfIndirectReference(); } return reference; } /** * @param writer * @param rect * @param title * @param contents * @param open * @param icon * @return a PdfAnnotation */ public static PdfAnnotation createText(PdfWriter writer, Rectangle rect, String title, String contents, boolean open, String icon) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.TEXT); if (title != null) annot.put(PdfName.T, new PdfString(title, PdfObject.TEXT_UNICODE)); if (contents != null) annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); if (open) annot.put(PdfName.OPEN, PdfBoolean.PDFTRUE); if (icon != null) { annot.put(PdfName.NAME, new PdfName(icon)); } return annot; } /** * Creates a link. * @param writer * @param rect * @param highlight * @return A PdfAnnotation */ protected static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.LINK); if (!highlight.equals(HIGHLIGHT_INVERT)) annot.put(PdfName.H, highlight); return annot; } /** * Creates an Annotation with an Action. * @param writer * @param rect * @param highlight * @param action * @return A PdfAnnotation */ public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, PdfAction action) { PdfAnnotation annot = createLink(writer, rect, highlight); annot.putEx(PdfName.A, action); return annot; } /** * Creates an Annotation with an local destination. * @param writer * @param rect * @param highlight * @param namedDestination * @return A PdfAnnotation */ public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, String namedDestination) { PdfAnnotation annot = createLink(writer, rect, highlight); annot.put(PdfName.DEST, new PdfString(namedDestination)); return annot; } /** * Creates an Annotation with a PdfDestination. * @param writer * @param rect * @param highlight * @param page * @param dest * @return A PdfAnnotation */ public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, int page, PdfDestination dest) { PdfAnnotation annot = createLink(writer, rect, highlight); PdfIndirectReference ref = writer.getPageReference(page); dest.addPage(ref); annot.put(PdfName.DEST, dest); return annot; } /** * Add some free text to the document. * @param writer * @param rect * @param contents * @param defaultAppearance * @return A PdfAnnotation */ public static PdfAnnotation createFreeText(PdfWriter writer, Rectangle rect, String contents, PdfContentByte defaultAppearance) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.FREETEXT); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); annot.setDefaultAppearanceString(defaultAppearance); return annot; } /** * Adds a line to the document. Move over the line and a tooltip is shown. * @param writer * @param rect * @param contents * @param x1 * @param y1 * @param x2 * @param y2 * @return A PdfAnnotation */ public static PdfAnnotation createLine(PdfWriter writer, Rectangle rect, String contents, float x1, float y1, float x2, float y2) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.LINE); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); PdfArray array = new PdfArray(new PdfNumber(x1)); array.add(new PdfNumber(y1)); array.add(new PdfNumber(x2)); array.add(new PdfNumber(y2)); annot.put(PdfName.L, array); return annot; } /** * Adds a circle or a square that shows a tooltip when you pass over it. * @param writer * @param rect * @param contents The tooltip * @param square true if you want a square, false if you want a circle * @return A PdfAnnotation */ public static PdfAnnotation createSquareCircle(PdfWriter writer, Rectangle rect, String contents, boolean square) { PdfAnnotation annot = new PdfAnnotation(writer, rect); if (square) annot.put(PdfName.SUBTYPE, PdfName.SQUARE); else annot.put(PdfName.SUBTYPE, PdfName.CIRCLE); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); return annot; } public static PdfAnnotation createMarkup(PdfWriter writer, Rectangle rect, String contents, int type, float quadPoints[]) { PdfAnnotation annot = new PdfAnnotation(writer, rect); PdfName name = PdfName.HIGHLIGHT; switch (type) { case MARKUP_UNDERLINE: name = PdfName.UNDERLINE; break; case MARKUP_STRIKEOUT: name = PdfName.STRIKEOUT; break; case MARKUP_SQUIGGLY: name = PdfName.SQUIGGLY; break; } annot.put(PdfName.SUBTYPE, name); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); PdfArray array = new PdfArray(); for (int k = 0; k < quadPoints.length; ++k) array.add(new PdfNumber(quadPoints[k])); annot.put(PdfName.QUADPOINTS, array); return annot; } /** * Adds a Stamp to your document. Move over the stamp and a tooltip is shown * @param writer * @param rect * @param contents * @param name * @return A PdfAnnotation */ public static PdfAnnotation createStamp(PdfWriter writer, Rectangle rect, String contents, String name) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.STAMP); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); annot.put(PdfName.NAME, new PdfName(name)); return annot; } public static PdfAnnotation createInk(PdfWriter writer, Rectangle rect, String contents, float inkList[][]) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.INK); annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); PdfArray outer = new PdfArray(); for (int k = 0; k < inkList.length; ++k) { PdfArray inner = new PdfArray(); float deep[] = inkList[k]; for (int j = 0; j < deep.length; ++j) inner.add(new PdfNumber(deep[j])); outer.add(inner); } annot.put(PdfName.INKLIST, outer); return annot; } /** Creates a file attachment annotation. * @param writer the PdfWriter * @param rect the dimensions in the page of the annotation * @param contents the file description * @param fileStore an array with the file. If it's null * the file will be read from the disk * @param file the path to the file. It will only be used if * fileStore is not null * @param fileDisplay the actual file name stored in the pdf * @throws IOException on error * @return the annotation */ public static PdfAnnotation createFileAttachment(PdfWriter writer, Rectangle rect, String contents, byte fileStore[], String file, String fileDisplay) throws IOException { return createFileAttachment(writer, rect, contents, PdfFileSpecification.fileEmbedded(writer, file, fileDisplay, fileStore)); } /** Creates a file attachment annotation * @param writer * @param rect * @param contents * @param fs * @return the annotation * @throws IOException */ public static PdfAnnotation createFileAttachment(PdfWriter writer, Rectangle rect, String contents, PdfFileSpecification fs) throws IOException { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.FILEATTACHMENT); if (contents != null) annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); annot.put(PdfName.FS, fs.getReference()); return annot; } /** * Adds a popup to your document. * @param writer * @param rect * @param contents * @param open * @return A PdfAnnotation */ public static PdfAnnotation createPopup(PdfWriter writer, Rectangle rect, String contents, boolean open) { PdfAnnotation annot = new PdfAnnotation(writer, rect); annot.put(PdfName.SUBTYPE, PdfName.POPUP); if (contents != null) annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); if (open) annot.put(PdfName.OPEN, PdfBoolean.PDFTRUE); return annot; } public void setDefaultAppearanceString(PdfContentByte cb) { byte b[] = cb.getInternalBuffer().toByteArray(); int len = b.length; for (int k = 0; k < len; ++k) { if (b[k] == '\n') b[k] = 32; } put(PdfName.DA, new PdfString(b)); } public void setFlags(int flags) { if (flags == 0) remove(PdfName.F); else put(PdfName.F, new PdfNumber(flags)); } public void setBorder(PdfBorderArray border) { put(PdfName.BORDER, border); } public void setBorderStyle(PdfBorderDictionary border) { put(PdfName.BS, border); } /** * Sets the annotation's highlighting mode. The values can be * HIGHLIGHT_NONE, HIGHLIGHT_INVERT, * HIGHLIGHT_OUTLINE and HIGHLIGHT_PUSH; * @param highlight the annotation's highlighting mode */ public void setHighlighting(PdfName highlight) { if (highlight.equals(HIGHLIGHT_INVERT)) remove(PdfName.H); else put(PdfName.H, highlight); } public void setAppearance(PdfName ap, PdfTemplate template) { PdfDictionary dic = (PdfDictionary)get(PdfName.AP); if (dic == null) dic = new PdfDictionary(); dic.put(ap, template.getIndirectReference()); put(PdfName.AP, dic); if (!form) return; if (templates == null) templates = new HashMap(); templates.put(template, null); } public void setAppearance(PdfName ap, String state, PdfTemplate template) { PdfDictionary dicAp = (PdfDictionary)get(PdfName.AP); if (dicAp == null) dicAp = new PdfDictionary(); PdfDictionary dic; PdfObject obj = dicAp.get(ap); if (obj != null && obj.isDictionary()) dic = (PdfDictionary)obj; else dic = new PdfDictionary(); dic.put(new PdfName(state), template.getIndirectReference()); dicAp.put(ap, dic); put(PdfName.AP, dicAp); if (!form) return; if (templates == null) templates = new HashMap(); templates.put(template, null); } public void setAppearanceState(String state) { if (state == null) { remove(PdfName.AS); return; } put(PdfName.AS, new PdfName(state)); } public void setColor(Color color) { put(PdfName.C, new PdfColor(color)); } public void setTitle(String title) { if (title == null) { remove(PdfName.T); return; } put(PdfName.T, new PdfString(title, PdfObject.TEXT_UNICODE)); } public void setPopup(PdfAnnotation popup) { put(PdfName.POPUP, popup.getIndirectReference()); popup.put(PdfName.PARENT, getIndirectReference()); } public void setAction(PdfAction action) { put(PdfName.A, action); } public void setAdditionalActions(PdfName key, PdfAction action) { PdfDictionary dic; PdfObject obj = get(PdfName.AA); if (obj != null && obj.isDictionary()) dic = (PdfDictionary)obj; else dic = new PdfDictionary(); dic.put(key, action); put(PdfName.AA, dic); } /** Getter for property used. * @return Value of property used. */ public boolean isUsed() { return used; } /** Setter for property used. */ public void setUsed() { used = true; } public HashMap getTemplates() { return templates; } /** Getter for property form. * @return Value of property form. */ public boolean isForm() { return form; } /** Getter for property annotation. * @return Value of property annotation. */ public boolean isAnnotation() { return annotation; } public void setPage(int page) { put(PdfName.P, writer.getPageReference(page)); } public void setPage() { put(PdfName.P, writer.getCurrentPage()); } /** Getter for property placeInPage. * @return Value of property placeInPage. */ public int getPlaceInPage() { return placeInPage; } /** Places the annotation in a specified page that must be greater * or equal to the current one. With PdfStamper the page * can be any. The first page is 1. * @param placeInPage New value of property placeInPage. */ public void setPlaceInPage(int placeInPage) { this.placeInPage = placeInPage; } public void setRotate(int v) { put(PdfName.ROTATE, new PdfNumber(v)); } PdfDictionary getMK() { PdfDictionary mk = (PdfDictionary)get(PdfName.MK); if (mk == null) { mk = new PdfDictionary(); put(PdfName.MK, mk); } return mk; } public void setMKRotation(int rotation) { getMK().put(PdfName.R, new PdfNumber(rotation)); } public static PdfArray getMKColor(Color color) { PdfArray array = new PdfArray(); int type = ExtendedColor.getType(color); switch (type) { case ExtendedColor.TYPE_GRAY: { array.add(new PdfNumber(((GrayColor)color).getGray())); break; } case ExtendedColor.TYPE_CMYK: { CMYKColor cmyk = (CMYKColor)color; array.add(new PdfNumber(cmyk.getCyan())); array.add(new PdfNumber(cmyk.getMagenta())); array.add(new PdfNumber(cmyk.getYellow())); array.add(new PdfNumber(cmyk.getBlack())); break; } case ExtendedColor.TYPE_SEPARATION: case ExtendedColor.TYPE_PATTERN: case ExtendedColor.TYPE_SHADING: throw new RuntimeException("Separations, patterns and shadings are not allowed in MK dictionary."); default: array.add(new PdfNumber(color.getRed() / 255f)); array.add(new PdfNumber(color.getGreen() / 255f)); array.add(new PdfNumber(color.getBlue() / 255f)); } return array; } public void setMKBorderColor(Color color) { if (color == null) getMK().remove(PdfName.BC); else getMK().put(PdfName.BC, getMKColor(color)); } public void setMKBackgroundColor(Color color) { if (color == null) getMK().remove(PdfName.BG); else getMK().put(PdfName.BG, getMKColor(color)); } public void setMKNormalCaption(String caption) { getMK().put(PdfName.CA, new PdfString(caption, PdfObject.TEXT_UNICODE)); } public void setMKRolloverCaption(String caption) { getMK().put(PdfName.RC, new PdfString(caption, PdfObject.TEXT_UNICODE)); } public void setMKAlternateCaption(String caption) { getMK().put(PdfName.AC, new PdfString(caption, PdfObject.TEXT_UNICODE)); } public void setMKNormalIcon(PdfTemplate template) { getMK().put(PdfName.I, template.getIndirectReference()); } public void setMKRolloverIcon(PdfTemplate template) { getMK().put(PdfName.RI, template.getIndirectReference()); } public void setMKAlternateIcon(PdfTemplate template) { getMK().put(PdfName.IX, template.getIndirectReference()); } public void setMKIconFit(PdfName scale, PdfName scalingType, float leftoverLeft, float leftoverBottom, boolean fitInBounds) { PdfDictionary dic = new PdfDictionary(); if (!scale.equals(PdfName.A)) dic.put(PdfName.SW, scale); if (!scalingType.equals(PdfName.P)) dic.put(PdfName.S, scalingType); if (leftoverLeft != 0.5f || leftoverBottom != 0.5f) { PdfArray array = new PdfArray(new PdfNumber(leftoverLeft)); array.add(new PdfNumber(leftoverBottom)); dic.put(PdfName.A, array); } if (fitInBounds) dic.put(PdfName.FB, PdfBoolean.PDFTRUE); getMK().put(PdfName.IF, dic); } public void setMKTextPosition(int tp) { getMK().put(PdfName.TP, new PdfNumber(tp)); } /** * Sets the layer this annotation belongs to. * @param layer the layer this annotation belongs to */ public void setLayer(PdfOCG layer) { put(PdfName.OC, layer.getRef()); } /** * Sets the name of the annotation. * With this name the annotation can be identified among * all the annotations on a page (it has to be unique). */ public void setName(String name) { put(PdfName.NM, new PdfString(name)); } /** * This class processes links from imported pages so that they may be active. The following example code reads a group * of files and places them all on the output PDF, four pages in a single page, keeping the links active. *
     * String[] files = new String[] {"input1.pdf", "input2.pdf"};
     * String outputFile = "output.pdf";
     * int firstPage=1;
     * Document document = new Document();
     * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputFile));
     * document.setPageSize(PageSize.A4);
     * float W = PageSize.A4.getWidth() / 2;
     * float H = PageSize.A4.getHeight() / 2;
     * document.open();
     * PdfContentByte cb = writer.getDirectContent();
     * for (int i = 0; i < files.length; i++) {
     *    PdfReader currentReader = new PdfReader(files[i]);
     *    currentReader.consolidateNamedDestinations();
     *    for (int page = 1; page <= currentReader.getNumberOfPages(); page++) {
     *        PdfImportedPage importedPage = writer.getImportedPage(currentReader, page);
     *        float a = 0.5f;
     *        float e = (page % 2 == 0) ? W : 0;
     *        float f = (page % 4 == 1 || page % 4 == 2) ? H : 0;
     *        ArrayList links = currentReader.getLinks(page);
     *        cb.addTemplate(importedPage, a, 0, 0, a, e, f);
     *        for (int j = 0; j < links.size(); j++) {
     *            PdfAnnotation.PdfImportedLink link = (PdfAnnotation.PdfImportedLink)links.get(j);
     *            if (link.isInternal()) {
     *                int dPage = link.getDestinationPage();
     *                int newDestPage = (dPage-1)/4 + firstPage;
     *                float ee = (dPage % 2 == 0) ? W : 0;
     *                float ff = (dPage % 4 == 1 || dPage % 4 == 2) ? H : 0;
     *                link.setDestinationPage(newDestPage);
     *                link.transformDestination(a, 0, 0, a, ee, ff);
     *            }
     *            link.transformRect(a, 0, 0, a, e, f);
     *            writer.addAnnotation(link.createAnnotation(writer));
     *        }
     *        if (page % 4 == 0)
     *        document.newPage();
     *    }
     *    if (i < files.length - 1)
     *    document.newPage();
     *    firstPage += (currentReader.getNumberOfPages()+3)/4;
     * }
     * document.close();
     * 
*/ public static class PdfImportedLink { float llx, lly, urx, ury; HashMap parameters = new HashMap(); PdfArray destination = null; int newPage=0; PdfImportedLink(PdfDictionary annotation) { parameters.putAll(annotation.hashMap); try { destination = (PdfArray) parameters.remove(PdfName.DEST); } catch (ClassCastException ex) { throw new IllegalArgumentException("You have to consolidate the named destinations of your reader."); } if (destination != null) { destination = new PdfArray(destination); } PdfArray rc = (PdfArray) parameters.remove(PdfName.RECT); llx = rc.getAsNumber(0).floatValue(); lly = rc.getAsNumber(1).floatValue(); urx = rc.getAsNumber(2).floatValue(); ury = rc.getAsNumber(3).floatValue(); } public boolean isInternal() { return destination != null; } public int getDestinationPage() { if (!isInternal()) return 0; // here destination is something like // [132 0 R, /XYZ, 29.3898, 731.864502, null] PdfIndirectReference ref = destination.getAsIndirectObject(0); PRIndirectReference pr = (PRIndirectReference) ref; PdfReader r = pr.getReader(); for (int i = 1; i <= r.getNumberOfPages(); i++) { PRIndirectReference pp = r.getPageOrigRef(i); if (pp.getGeneration() == pr.getGeneration() && pp.getNumber() == pr.getNumber()) return i; } throw new IllegalArgumentException("Page not found."); } public void setDestinationPage(int newPage) { if (!isInternal()) throw new IllegalArgumentException("Cannot change destination of external link"); this.newPage=newPage; } public void transformDestination(float a, float b, float c, float d, float e, float f) { if (!isInternal()) throw new IllegalArgumentException("Cannot change destination of external link"); if (destination.getAsName(1).equals(PdfName.XYZ)) { float x = destination.getAsNumber(2).floatValue(); float y = destination.getAsNumber(3).floatValue(); float xx = x * a + y * c + e; float yy = x * b + y * d + f; destination.set(2, new PdfNumber(xx)); destination.set(3, new PdfNumber(yy)); } } public void transformRect(float a, float b, float c, float d, float e, float f) { float x = llx * a + lly * c + e; float y = llx * b + lly * d + f; llx = x; lly = y; x = urx * a + ury * c + e; y = urx * b + ury * d + f; urx = x; ury = y; } public PdfAnnotation createAnnotation(PdfWriter writer) { PdfAnnotation annotation = new PdfAnnotation(writer, new Rectangle(llx, lly, urx, ury)); if (newPage != 0) { PdfIndirectReference ref = writer.getPageReference(newPage); destination.set(0, ref); } if (destination != null) annotation.put(PdfName.DEST, destination); annotation.hashMap.putAll(parameters); return annotation; } /** * Returns a String representation of the link. * @return a String representation of the imported link * @since 2.1.6 */ public String toString() { StringBuffer buf = new StringBuffer("Imported link: location ["); buf.append(llx); buf.append(' '); buf.append(lly); buf.append(' '); buf.append(urx); buf.append(' '); buf.append(ury); buf.append("] destination "); buf.append(destination); buf.append(" parameters "); buf.append(parameters); return buf.toString(); } } } src/core/com/lowagie/text/pdf/PdfAppearance.java100644 0 0 16222 11000354131 17231 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.HashMap; import com.lowagie.text.Rectangle; /** * Implements the appearance stream to be used with form fields.. */ public class PdfAppearance extends PdfTemplate { public static final HashMap stdFieldFontNames = new HashMap(); static { stdFieldFontNames.put("Courier-BoldOblique", new PdfName("CoBO")); stdFieldFontNames.put("Courier-Bold", new PdfName("CoBo")); stdFieldFontNames.put("Courier-Oblique", new PdfName("CoOb")); stdFieldFontNames.put("Courier", new PdfName("Cour")); stdFieldFontNames.put("Helvetica-BoldOblique", new PdfName("HeBO")); stdFieldFontNames.put("Helvetica-Bold", new PdfName("HeBo")); stdFieldFontNames.put("Helvetica-Oblique", new PdfName("HeOb")); stdFieldFontNames.put("Helvetica", PdfName.HELV); stdFieldFontNames.put("Symbol", new PdfName("Symb")); stdFieldFontNames.put("Times-BoldItalic", new PdfName("TiBI")); stdFieldFontNames.put("Times-Bold", new PdfName("TiBo")); stdFieldFontNames.put("Times-Italic", new PdfName("TiIt")); stdFieldFontNames.put("Times-Roman", new PdfName("TiRo")); stdFieldFontNames.put("ZapfDingbats", PdfName.ZADB); stdFieldFontNames.put("HYSMyeongJo-Medium", new PdfName("HySm")); stdFieldFontNames.put("HYGoThic-Medium", new PdfName("HyGo")); stdFieldFontNames.put("HeiseiKakuGo-W5", new PdfName("KaGo")); stdFieldFontNames.put("HeiseiMin-W3", new PdfName("KaMi")); stdFieldFontNames.put("MHei-Medium", new PdfName("MHei")); stdFieldFontNames.put("MSung-Light", new PdfName("MSun")); stdFieldFontNames.put("STSong-Light", new PdfName("STSo")); stdFieldFontNames.put("MSungStd-Light", new PdfName("MSun")); stdFieldFontNames.put("STSongStd-Light", new PdfName("STSo")); stdFieldFontNames.put("HYSMyeongJoStd-Medium", new PdfName("HySm")); stdFieldFontNames.put("KozMinPro-Regular", new PdfName("KaMi")); } /** *Creates a PdfAppearance. */ PdfAppearance() { super(); separator = ' '; } PdfAppearance(PdfIndirectReference iref) { thisReference = iref; } /** * Creates new PdfTemplate * * @param wr the PdfWriter */ PdfAppearance(PdfWriter wr) { super(wr); separator = ' '; } /** * Creates a new appearance to be used with form fields. * * @param writer the PdfWriter to use * @param width the bounding box width * @param height the bounding box height * @return the appearance created */ public static PdfAppearance createAppearance(PdfWriter writer, float width, float height) { return createAppearance(writer, width, height, null); } static PdfAppearance createAppearance(PdfWriter writer, float width, float height, PdfName forcedName) { PdfAppearance template = new PdfAppearance(writer); template.setWidth(width); template.setHeight(height); writer.addDirectTemplateSimple(template, forcedName); return template; } /** * Set the font and the size for the subsequent text writing. * * @param bf the font * @param size the font size in points */ public void setFontAndSize(BaseFont bf, float size) { checkWriter(); state.size = size; if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { state.fontDetails = new FontDetails(null, ((DocumentFont)bf).getIndirectReference(), bf); } else state.fontDetails = writer.addSimple(bf); PdfName psn = (PdfName)stdFieldFontNames.get(bf.getPostscriptFontName()); if (psn == null) { if (bf.isSubset() && bf.getFontType() == BaseFont.FONT_TYPE_TTUNI) psn = state.fontDetails.getFontName(); else { psn = new PdfName(bf.getPostscriptFontName()); state.fontDetails.setSubset(false); } } PageResources prs = getPageResources(); // PdfName name = state.fontDetails.getFontName(); prs.addFont(psn, state.fontDetails.getIndirectReference()); content.append(psn.getBytes()).append(' ').append(size).append(" Tf").append_i(separator); } public PdfContentByte getDuplicate() { PdfAppearance tpl = new PdfAppearance(); tpl.writer = writer; tpl.pdf = pdf; tpl.thisReference = thisReference; tpl.pageResources = pageResources; tpl.bBox = new Rectangle(bBox); tpl.group = group; tpl.layer = layer; if (matrix != null) { tpl.matrix = new PdfArray(matrix); } tpl.separator = separator; return tpl; } }src/core/com/lowagie/text/pdf/PdfArray.java100644 0 0 45414 11154234212 16264 0ustar 0 0 /* * $Id: PdfArray.java 3761 2009-03-06 16:33:57Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; /** * PdfArray is the PDF Array object. *

* An array is a sequence of PDF objects. An array may contain a mixture of * object types. * An array is written as a left square bracket ([), followed by a sequence of * objects, followed by a right square bracket (]).
* This object is described in the 'Portable Document Format Reference Manual * version 1.7' section 3.2.5 (page 58). * * @see PdfObject */ public class PdfArray extends PdfObject { // CLASS VARIABLES /** this is the actual array of PdfObjects */ protected ArrayList arrayList; // constructors /** * Constructs an empty PdfArray-object. */ public PdfArray() { super(ARRAY); arrayList = new ArrayList(); } /** * Constructs an PdfArray-object, containing 1 * PdfObject. * * @param object a PdfObject that has to be added to the array */ public PdfArray(PdfObject object) { super(ARRAY); arrayList = new ArrayList(); arrayList.add(object); } /** * Constructs a PdfArray-object, containing all * float values in a specified array. * * The float values are internally converted to * PdfNumber objects. * * @param values an array of float values to be added */ public PdfArray(float values[]) { super(ARRAY); arrayList = new ArrayList(); add(values); } /** * Constructs a PdfArray-object, containing all * int values in a specified array. * * The int values are internally converted to * PdfNumber objects. * * @param values an array of int values to be added */ public PdfArray(int values[]) { super(ARRAY); arrayList = new ArrayList(); add(values); } /** * Constructs a PdfArray, containing all elements of a * specified ArrayList. * * @param l an ArrayList with PdfObjects to be * added to the array * @throws ClassCastException if the ArrayList contains * something that isn't a PdfObject * @since 2.1.3 */ public PdfArray(ArrayList l) { this(); for (Iterator i = l.iterator(); i.hasNext(); ) add((PdfObject)i.next()); } /** * Constructs an PdfArray-object, containing all * PdfObjects in a specified PdfArray. * * @param array a PdfArray to be added to the array */ public PdfArray(PdfArray array) { super(ARRAY); arrayList = new ArrayList(array.arrayList); } // METHODS OVERRIDING SOME PDFOBJECT METHODS /** * Writes the PDF representation of this PdfArray as an array * of byte to the specified OutputStream. * * @param writer for backwards compatibility * @param os the OutputStream to write the bytes to. */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { os.write('['); Iterator i = arrayList.iterator(); PdfObject object; int type = 0; if (i.hasNext()) { object = (PdfObject) i.next(); if (object == null) object = PdfNull.PDFNULL; object.toPdf(writer, os); } while (i.hasNext()) { object = (PdfObject) i.next(); if (object == null) object = PdfNull.PDFNULL; type = object.type(); if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) os.write(' '); object.toPdf(writer, os); } os.write(']'); } /** * Returns a string representation of this PdfArray. * * The string representation consists of a list of all * PdfObjects contained in this PdfArray, * enclosed in square brackets ("[]"). Adjacent elements are separated * by the characters ", " (comma and space). * * @return the string representation of this PdfArray */ public String toString() { return arrayList.toString(); } // ARRAY CONTENT METHODS /** * Overwrites a specified location of the array, returning the previous * value * * @param idx The index of the element to be overwritten * @param obj new value for the specified index * @throws IndexOutOfBoundsException if the specified position doesn't exist * @return the previous value * @since 2.1.5 */ public PdfObject set(int idx, PdfObject obj) { return (PdfObject) arrayList.set(idx, obj); } /** * Remove the element at the specified position from the array. * * Shifts any subsequent elements to the left (subtracts one from their * indices). * * @param idx The index of the element to be removed. * @throws IndexOutOfBoundsException the specified position doesn't exist * @since 2.1.5 */ public PdfObject remove(int idx) { return (PdfObject) arrayList.remove(idx); } /** * Get the internal arrayList for this PdfArray. Not Recommended. * * @deprecated * @return the internal ArrayList. Naughty Naughty. */ public ArrayList getArrayList() { return arrayList; } /** * Returns the number of entries in the array. * * @return the size of the ArrayList */ public int size() { return arrayList.size(); } /** * Returns true if the array is empty. * * @return true if the array is empty * @since 2.1.5 */ public boolean isEmpty() { return arrayList.isEmpty(); } /** * Adds a PdfObject to the end of the PdfArray. * * The PdfObject will be the last element. * * @param object PdfObject to add * @return always true */ public boolean add(PdfObject object) { return arrayList.add(object); } /** * Adds an array of float values to end of the * PdfArray. * * The values will be the last elements. * The float values are internally converted to * PdfNumber objects. * * @param values An array of float values to add * @return always true */ public boolean add(float values[]) { for (int k = 0; k < values.length; ++k) arrayList.add(new PdfNumber(values[k])); return true; } /** * Adds an array of int values to end of the PdfArray. * * The values will be the last elements. * The int values are internally converted to * PdfNumber objects. * * @param values An array of int values to add * @return always true */ public boolean add(int values[]) { for (int k = 0; k < values.length; ++k) arrayList.add(new PdfNumber(values[k])); return true; } /** * Inserts the specified element at the specified position. * * Shifts the element currently at that position (if any) and * any subsequent elements to the right (adds one to their indices). * * @param index The index at which the specified element is to be inserted * @param element The element to be inserted * @throws IndexOutOfBoundsException if the specified index is larger than the * last position currently set, plus 1. * @since 2.1.5 */ public void add(int index, PdfObject element) { arrayList.add(index, element); } /** * Inserts a PdfObject at the beginning of the * PdfArray. * * The PdfObject will be the first element, any other elements * will be shifted to the right (adds one to their indices). * * @param object The PdfObject to add */ public void addFirst(PdfObject object) { arrayList.add(0, object); } /** * Checks if the PdfArray already contains a certain * PdfObject. * * @param object The PdfObject to check * @return true */ public boolean contains(PdfObject object) { return arrayList.contains(object); } /** * Returns the list iterator for the array. * * @return a ListIterator */ public ListIterator listIterator() { return arrayList.listIterator(); } /** * Returns the PdfObject with the specified index. * * A possible indirect references is not resolved, so the returned * PdfObject may be either a direct object or an indirect * reference, depending on how the object is stored in the * PdfArray. * * @param idx The index of the PdfObject to be returned * @return A PdfObject */ public PdfObject getPdfObject(int idx) { return (PdfObject)arrayList.get(idx); } /** * Returns the PdfObject with the specified index, resolving * a possible indirect reference to a direct object. * * Thus this method will never return a PdfIndirectReference * object. * * @param idx The index of the PdfObject to be returned * @return A direct PdfObject or null */ public PdfObject getDirectObject(int idx) { return PdfReader.getPdfObject(getPdfObject(idx)); } // DOWNCASTING GETTERS // @author Mark A Storer (2/17/06) /** * Returns a PdfObject as a PdfDictionary, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolvedto a direct object. * If it is a PdfDictionary, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfDictionary object, * or null */ public PdfDictionary getAsDict(int idx) { PdfDictionary dict = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isDictionary()) dict = (PdfDictionary) orig; return dict; } /** * Returns a PdfObject as a PdfArray, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfArray, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfArray object, * or null */ public PdfArray getAsArray(int idx) { PdfArray array = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isArray()) array = (PdfArray) orig; return array; } /** * Returns a PdfObject as a PdfStream, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfStream, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfStream object, * or null */ public PdfStream getAsStream(int idx) { PdfStream stream = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isStream()) stream = (PdfStream) orig; return stream; } /** * Returns a PdfObject as a PdfString, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfString, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfString object, * or null */ public PdfString getAsString(int idx) { PdfString string = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isString()) string = (PdfString) orig; return string; } /** * Returns a PdfObject as a PdfNumber, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfNumber, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfNumber object, * or null */ public PdfNumber getAsNumber(int idx) { PdfNumber number = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isNumber()) number = (PdfNumber) orig; return number; } /** * Returns a PdfObject as a PdfName, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfName, it is cast down and returned as such. * Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfName object, * or null */ public PdfName getAsName(int idx) { PdfName name = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isName()) name = (PdfName) orig; return name; } /** * Returns a PdfObject as a PdfBoolean, * resolving indirect references. * * The object corresponding to the specified index is retrieved and * resolved to a direct object. * If it is a PdfBoolean, it is cast down and returned as * such. Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfBoolean object, * or null */ public PdfBoolean getAsBoolean(int idx) { PdfBoolean bool = null; PdfObject orig = getDirectObject(idx); if (orig != null && orig.isBoolean()) bool = (PdfBoolean) orig; return bool; } /** * Returns a PdfObject as a PdfIndirectReference. * * The object corresponding to the specified index is retrieved. * If it is a PdfIndirectReference, it is cast down and * returned as such. Otherwise null is returned. * * @param idx The index of the PdfObject to be returned * @return the corresponding PdfIndirectReference object, * or null */ public PdfIndirectReference getAsIndirectObject(int idx) { PdfIndirectReference ref = null; PdfObject orig = getPdfObject(idx); // not getDirect this time. if (orig != null && orig.isIndirect()) ref = (PdfIndirectReference) orig; return ref; } } src/core/com/lowagie/text/pdf/PdfBoolean.java100644 0 0 11271 11012562273 16563 0ustar 0 0 /* * $Id: PdfBoolean.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfBoolean is the boolean object represented by the keywords true or false. *

* This object is described in the 'Portable Document Format Reference Manual version 1.7' * section 3.2.1 (page 52). * * @see PdfObject * @see BadPdfFormatException */ public class PdfBoolean extends PdfObject { // static membervariables (possible values of a boolean object) public static final PdfBoolean PDFTRUE = new PdfBoolean(true); public static final PdfBoolean PDFFALSE = new PdfBoolean(false); /** A possible value of PdfBoolean */ public static final String TRUE = "true"; /** A possible value of PdfBoolean */ public static final String FALSE = "false"; // membervariables /** the boolean value of this object */ private boolean value; // constructors /** * Constructs a PdfBoolean-object. * * @param value the value of the new PdfObject */ public PdfBoolean(boolean value) { super(BOOLEAN); if (value) { setContent(TRUE); } else { setContent(FALSE); } this.value = value; } /** * Constructs a PdfBoolean-object. * * @param value the value of the new PdfObject, represented as a String * * @throws BadPdfFormatException thrown if the value isn't 'true' or 'false' */ public PdfBoolean(String value) throws BadPdfFormatException { super(BOOLEAN, value); if (value.equals(TRUE)) { this.value = true; } else if (value.equals(FALSE)) { this.value = false; } else { throw new BadPdfFormatException("The value has to be 'true' of 'false', instead of '" + value + "'."); } } // methods returning the value of this object /** * Returns the primitive value of the PdfBoolean-object. * * @return the actual value of the object. */ public boolean booleanValue() { return value; } public String toString() { return value ? TRUE : FALSE; } }src/core/com/lowagie/text/pdf/PdfBorderArray.java100644 0 0 6264 11012562273 17406 0ustar 0 0 /* * $Id: PdfBorderArray.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * A PdfBorderArray defines the border of a PdfAnnotation. * * @see PdfArray */ public class PdfBorderArray extends PdfArray { // constructors /** * Constructs a new PdfBorderArray. */ public PdfBorderArray(float hRadius, float vRadius, float width) { this(hRadius, vRadius, width, null); } /** * Constructs a new PdfBorderArray. */ public PdfBorderArray(float hRadius, float vRadius, float width, PdfDashPattern dash) { super(new PdfNumber(hRadius)); add(new PdfNumber(vRadius)); add(new PdfNumber(width)); if (dash != null) add(dash); } }src/core/com/lowagie/text/pdf/PdfBorderDictionary.java100644 0 0 7712 11012562273 20434 0ustar 0 0 /* * $Id: PdfBorderDictionary.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * A PdfBorderDictionary define the appearance of a Border (Annotations). * * @see PdfDictionary */ public class PdfBorderDictionary extends PdfDictionary { public static final int STYLE_SOLID = 0; public static final int STYLE_DASHED = 1; public static final int STYLE_BEVELED = 2; public static final int STYLE_INSET = 3; public static final int STYLE_UNDERLINE = 4; // constructors /** * Constructs a PdfBorderDictionary. */ public PdfBorderDictionary(float borderWidth, int borderStyle, PdfDashPattern dashes) { put(PdfName.W, new PdfNumber(borderWidth)); switch (borderStyle) { case STYLE_SOLID: put(PdfName.S, PdfName.S); break; case STYLE_DASHED: if (dashes != null) put(PdfName.D, dashes); put(PdfName.S, PdfName.D); break; case STYLE_BEVELED: put(PdfName.S, PdfName.B); break; case STYLE_INSET: put(PdfName.S, PdfName.I); break; case STYLE_UNDERLINE: put(PdfName.S, PdfName.U); break; default: throw new IllegalArgumentException("Invalid border style."); } } public PdfBorderDictionary(float borderWidth, int borderStyle) { this(borderWidth, borderStyle, null); } }src/core/com/lowagie/text/pdf/PdfCell.java100644 0 0 73236 11154165267 16105 0ustar 0 0 /* * $Id: PdfCell.java 3671 2009-02-01 14:46:09Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Anchor; import com.lowagie.text.Cell; import com.lowagie.text.Chunk; import com.lowagie.text.Element; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; /** * A PdfCell is the PDF translation of a Cell. *

* A PdfCell is an ArrayList of PdfLines. *

* When using variable borders ({@link com.lowagie.text.Rectangle#isUseVariableBorders isUseVariableBorders()} == true), * the borders are drawn completely inside the cell Rectangle * so that adjacent cell borders will not overlap. * Otherwise, the borders are drawn on top of the edges of the * cell Rectangle and will overlap the borders of adjacent * cells. * * @see com.lowagie.text.Rectangle * @see com.lowagie.text.Cell * @see PdfLine * @see PdfTable */ public class PdfCell extends Rectangle { // membervariables /** * These are the PdfLines in the Cell. */ private ArrayList lines; /** * These are the PdfLines in the Cell. */ private PdfLine line; /** * These are the Images in the Cell. */ private ArrayList images; /** * This is the leading of the lines. */ private float leading; /** * This is the number of the row the cell is in. */ private int rownumber; /** * This is the rowspan of the cell. */ private int rowspan; /** * This is the cellspacing of the cell. */ private float cellspacing; /** * This is the cellpadding of the cell. */ private float cellpadding; /** * Indicates if this cell belongs to the header of a PdfTable */ private boolean header = false; /** * This is the total height of the content of the cell. Note that the actual cell * height may be larger due to another cell on the row * */ private float contentHeight = 0.0f; /** * Indicates that the largest ascender height should be used to * determine the height of the first line. Setting this to true can help * with vertical alignment problems. */ private boolean useAscender; /** * Indicates that the largest descender height should be added to the height of * the last line (so characters like y don't dip into the border). */ private boolean useDescender; /** * Adjusts the cell contents to compensate for border widths. */ private boolean useBorderPadding; private int verticalAlignment; private PdfLine firstLine; private PdfLine lastLine; // constructors /** * Constructs a PdfCell-object. * * @param cell the original Cell * @param rownumber the number of the Row the Cell was in. * @param left the left border of the PdfCell * @param right the right border of the PdfCell * @param top the top border of the PdfCell * @param cellspacing the cellspacing of the Table * @param cellpadding the cellpadding of the Table */ public PdfCell(Cell cell, int rownumber, float left, float right, float top, float cellspacing, float cellpadding) { // constructs a Rectangle (the bottomvalue will be changed afterwards) super(left, top, right, top); // copying the other Rectangle attributes from class Cell cloneNonPositionParameters(cell); this.cellpadding = cellpadding; this.cellspacing = cellspacing; this.verticalAlignment = cell.getVerticalAlignment(); this.useAscender = cell.isUseAscender(); this.useDescender = cell.isUseDescender(); this.useBorderPadding = cell.isUseBorderPadding(); // initialization of some parameters PdfChunk chunk; Element element; PdfChunk overflow; lines = new ArrayList(); images = new ArrayList(); leading = cell.getLeading(); int alignment = cell.getHorizontalAlignment(); left += cellspacing + cellpadding; right -= cellspacing + cellpadding; left += getBorderWidthInside(LEFT); right -= getBorderWidthInside(RIGHT); contentHeight = 0; rowspan = cell.getRowspan(); ArrayList allActions; int aCounter; // we loop over all the elements of the cell for (Iterator i = cell.getElements(); i.hasNext();) { element = (Element) i.next(); switch (element.type()) { case Element.JPEG: case Element.JPEG2000: case Element.JBIG2: case Element.IMGRAW: case Element.IMGTEMPLATE: addImage((Image) element, left, right, 0.4f * leading, alignment); // break; // if the element is a list case Element.LIST: if (line != null && line.size() > 0) { line.resetAlignment(); addLine(line); } // we loop over all the listitems addList((List)element, left, right, alignment); line = new PdfLine(left, right, alignment, leading); break; // if the element is something else default: allActions = new ArrayList(); processActions(element, null, allActions); aCounter = 0; float currentLineLeading = leading; float currentLeft = left; float currentRight = right; if (element instanceof Phrase) { currentLineLeading = ((Phrase) element).getLeading(); } if (element instanceof Paragraph) { Paragraph p = (Paragraph) element; currentLeft += p.getIndentationLeft(); currentRight -= p.getIndentationRight(); } if (line == null) { line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); } // we loop over the chunks ArrayList chunks = element.getChunks(); if (chunks.isEmpty()) { addLine(line); // add empty line - all cells need some lines even if they are empty line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); } else { for (Iterator j = chunks.iterator(); j.hasNext();) { Chunk c = (Chunk) j.next(); chunk = new PdfChunk(c, (PdfAction) (allActions.get(aCounter++))); while ((overflow = line.add(chunk)) != null) { addLine(line); line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); chunk = overflow; } } } // if the element is a paragraph, section or chapter, we reset the alignment and add the line switch (element.type()) { case Element.PARAGRAPH: case Element.SECTION: case Element.CHAPTER: line.resetAlignment(); flushCurrentLine(); } } } flushCurrentLine(); if (lines.size() > cell.getMaxLines()) { while (lines.size() > cell.getMaxLines()) { removeLine(lines.size() - 1); } if (cell.getMaxLines() > 0) { String more = cell.getShowTruncation(); if (more != null && more.length() > 0) { // Denote that the content has been truncated lastLine = (PdfLine) lines.get(lines.size() - 1); if (lastLine.size() >= 0) { PdfChunk lastChunk = lastLine.getChunk(lastLine.size() - 1); float moreWidth = new PdfChunk(more, lastChunk).width(); while (lastChunk.toString().length() > 0 && lastChunk.width() + moreWidth > right - left) { // Remove characters to leave room for the 'more' indicator lastChunk.setValue(lastChunk.toString().substring(0, lastChunk.length() - 1)); } lastChunk.setValue(lastChunk.toString() + more); } else { lastLine.add(new PdfChunk(new Chunk(more), null)); } } } } // we set some additional parameters if (useDescender && lastLine != null) { contentHeight -= lastLine.getDescender(); } // adjust first line height so that it touches the top if (!lines.isEmpty()) { firstLine = (PdfLine) lines.get(0); float firstLineRealHeight = firstLineRealHeight(); contentHeight -= firstLine.height(); firstLine.height = firstLineRealHeight; contentHeight += firstLineRealHeight; } float newBottom = top - contentHeight - (2f * cellpadding()) - (2f * cellspacing()); newBottom -= getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM); setBottom(newBottom); this.rownumber = rownumber; } private void addList(List list, float left, float right, int alignment) { PdfChunk chunk; PdfChunk overflow; ArrayList allActions = new ArrayList(); processActions(list, null, allActions); int aCounter = 0; for (Iterator it = list.getItems().iterator(); it.hasNext();) { Element ele = (Element)it.next(); switch (ele.type()) { case Element.LISTITEM: ListItem item = (ListItem)ele; line = new PdfLine(left + item.getIndentationLeft(), right, alignment, item.getLeading()); line.setListItem(item); for (Iterator j = item.getChunks().iterator(); j.hasNext();) { chunk = new PdfChunk((Chunk) j.next(), (PdfAction) (allActions.get(aCounter++))); while ((overflow = line.add(chunk)) != null) { addLine(line); line = new PdfLine(left + item.getIndentationLeft(), right, alignment, item.getLeading()); chunk = overflow; } line.resetAlignment(); addLine(line); line = new PdfLine(left + item.getIndentationLeft(), right, alignment, leading); } break; case Element.LIST: List sublist = (List)ele; addList(sublist, left + sublist.getIndentationLeft(), right, alignment); break; } } } // overriding of the Rectangle methods /** * Sets the bottom of the Rectangle and determines the proper {link #verticalOffset} * to appropriately align the contents vertically. * @param value */ public void setBottom(float value) { super.setBottom(value); float firstLineRealHeight = firstLineRealHeight(); float totalHeight = ury - value; // can't use top (already compensates for cellspacing) float nonContentHeight = (cellpadding() * 2f) + (cellspacing() * 2f); nonContentHeight += getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM); float interiorHeight = totalHeight - nonContentHeight; float extraHeight = 0.0f; switch (verticalAlignment) { case Element.ALIGN_BOTTOM: extraHeight = interiorHeight - contentHeight; break; case Element.ALIGN_MIDDLE: extraHeight = (interiorHeight - contentHeight) / 2.0f; break; default: // ALIGN_TOP extraHeight = 0f; } extraHeight += cellpadding() + cellspacing(); extraHeight += getBorderWidthInside(TOP); if (firstLine != null) { firstLine.height = firstLineRealHeight + extraHeight; } } /** * Returns the lower left x-coordinate. * * @return the lower left x-coordinate */ public float getLeft() { return super.getLeft(cellspacing); } /** * Returns the upper right x-coordinate. * * @return the upper right x-coordinate */ public float getRight() { return super.getRight(cellspacing); } /** * Returns the upper right y-coordinate. * * @return the upper right y-coordinate */ public float getTop() { return super.getTop(cellspacing); } /** * Returns the lower left y-coordinate. * * @return the lower left y-coordinate */ public float getBottom() { return super.getBottom(cellspacing); } // methods private void addLine(PdfLine line) { lines.add(line); contentHeight += line.height(); lastLine = line; this.line = null; } private PdfLine removeLine(int index) { PdfLine oldLine = (PdfLine) lines.remove(index); contentHeight -= oldLine.height(); if (index == 0) { if (!lines.isEmpty()) { firstLine = (PdfLine) lines.get(0); float firstLineRealHeight = firstLineRealHeight(); contentHeight -= firstLine.height(); firstLine.height = firstLineRealHeight; contentHeight += firstLineRealHeight; } } return oldLine; } private void flushCurrentLine() { if (line != null && line.size() > 0) { addLine(line); } } /** * Calculates what the height of the first line should be so that the content will be * flush with the top. For text, this is the height of the ascender. For an image, * it is the actual height of the image. * @return the real height of the first line */ private float firstLineRealHeight() { float firstLineRealHeight = 0f; if (firstLine != null) { PdfChunk chunk = firstLine.getChunk(0); if (chunk != null) { Image image = chunk.getImage(); if (image != null) { firstLineRealHeight = firstLine.getChunk(0).getImage().getScaledHeight(); } else { firstLineRealHeight = useAscender ? firstLine.getAscender() : leading; } } } return firstLineRealHeight; } /** * Gets the amount of the border for the specified side that is inside the Rectangle. * For non-variable width borders this is only 1/2 the border width on that side. This * always returns 0 if {@link #useBorderPadding} is false; * @param side the side to check. One of the side constants in {@link com.lowagie.text.Rectangle} * @return the borderwidth inside the cell */ private float getBorderWidthInside(int side) { float width = 0f; if (useBorderPadding) { switch (side) { case Rectangle.LEFT: width = getBorderWidthLeft(); break; case Rectangle.RIGHT: width = getBorderWidthRight(); break; case Rectangle.TOP: width = getBorderWidthTop(); break; default: // default and BOTTOM width = getBorderWidthBottom(); break; } // non-variable (original style) borders overlap the rectangle (only 1/2 counts) if (!isUseVariableBorders()) { width = width / 2f; } } return width; } /** * Adds an image to this Cell. * * @param i the image to add * @param left the left border * @param right the right border * @param extraHeight extra height to add above image * @param alignment horizontal alignment (constant from Element class) * @return the height of the image */ private float addImage(Image i, float left, float right, float extraHeight, int alignment) { Image image = Image.getInstance(i); if (image.getScaledWidth() > right - left) { image.scaleToFit(right - left, Float.MAX_VALUE); } flushCurrentLine(); if (line == null) { line = new PdfLine(left, right, alignment, leading); } PdfLine imageLine = line; // left and right in chunk is relative to the start of the line right = right - left; left = 0f; if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) { left = right - image.getScaledWidth(); } else if ((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE) { left = left + ((right - left - image.getScaledWidth()) / 2f); } Chunk imageChunk = new Chunk(image, left, 0); imageLine.add(new PdfChunk(imageChunk, null)); addLine(imageLine); return imageLine.height(); } /** * Gets the lines of a cell that can be drawn between certain limits. *

* Remark: all the lines that can be drawn are removed from the object! * * @param top the top of the part of the table that can be drawn * @param bottom the bottom of the part of the table that can be drawn * @return an ArrayList of PdfLines */ public ArrayList getLines(float top, float bottom) { float lineHeight; float currentPosition = Math.min(getTop(), top); setTop(currentPosition + cellspacing); ArrayList result = new ArrayList(); // if the bottom of the page is higher than the top of the cell: do nothing if (getTop() < bottom) { return result; } // we loop over the lines int size = lines.size(); boolean aboveBottom = true; for (int i = 0; i < size && aboveBottom; i++) { line = (PdfLine) lines.get(i); lineHeight = line.height(); currentPosition -= lineHeight; // if the currentPosition is higher than the bottom, we add the line to the result if (currentPosition > (bottom + cellpadding + getBorderWidthInside(BOTTOM))) { result.add(line); } else { aboveBottom = false; } } // if the bottom of the cell is higher than the bottom of the page, the cell is written, so we can remove all lines float difference = 0f; if (!header) { if (aboveBottom) { lines = new ArrayList(); contentHeight = 0f; } else { size = result.size(); for (int i = 0; i < size; i++) { line = removeLine(0); difference += line.height(); } } } if (difference > 0) { Image image; for (Iterator i = images.iterator(); i.hasNext();) { image = (Image) i.next(); image.setAbsolutePosition(image.getAbsoluteX(), image.getAbsoluteY() - difference - leading); } } return result; } /** * Gets the images of a cell that can be drawn between certain limits. *

* Remark: all the lines that can be drawn are removed from the object! * * @param top the top of the part of the table that can be drawn * @param bottom the bottom of the part of the table that can be drawn * @return an ArrayList of Images */ public ArrayList getImages(float top, float bottom) { // if the bottom of the page is higher than the top of the cell: do nothing if (getTop() < bottom) { return new ArrayList(); } top = Math.min(getTop(), top); // initializations Image image; float height; ArrayList result = new ArrayList(); // we loop over the images for (Iterator i = images.iterator(); i.hasNext() && !header;) { image = (Image) i.next(); height = image.getAbsoluteY(); // if the currentPosition is higher than the bottom, we add the line to the result if (top - height > (bottom + cellpadding)) { image.setAbsolutePosition(image.getAbsoluteX(), top - height); result.add(image); i.remove(); } } return result; } /** * Checks if this cell belongs to the header of a PdfTable. * * @return void */ boolean isHeader() { return header; } /** * Indicates that this cell belongs to the header of a PdfTable. */ void setHeader() { header = true; } /** * Checks if the cell may be removed. *

* Headers may always be removed, even if they are drawn only partially: * they will be repeated on each following page anyway! * * @return true if all the lines are already drawn; false otherwise. */ boolean mayBeRemoved() { return (header || (lines.isEmpty() && images.isEmpty())); } /** * Returns the number of lines in the cell. * * @return a value */ public int size() { return lines.size(); } /** * Returns the total height of all the lines in the cell. * * @return a value */ private float remainingLinesHeight() { if (lines.isEmpty()) return 0; float result = 0; int size = lines.size(); PdfLine line; for (int i = 0; i < size; i++) { line = (PdfLine) lines.get(i); result += line.height(); } return result; } /** * Returns the height needed to draw the remaining text. * * @return a height */ public float remainingHeight() { float result = 0f; for (Iterator i = images.iterator(); i.hasNext();) { Image image = (Image) i.next(); result += image.getScaledHeight(); } return remainingLinesHeight() + cellspacing + 2 * cellpadding + result; } // methods to retrieve membervariables /** * Gets the leading of a cell. * * @return the leading of the lines is the cell. */ public float leading() { return leading; } /** * Gets the number of the row this cell is in.. * * @return a number */ public int rownumber() { return rownumber; } /** * Gets the rowspan of a cell. * * @return the rowspan of the cell */ public int rowspan() { return rowspan; } /** * Gets the cellspacing of a cell. * * @return a value */ public float cellspacing() { return cellspacing; } /** * Gets the cellpadding of a cell.. * * @return a value */ public float cellpadding() { return cellpadding; } /** * Processes all actions contained in the cell. * @param element an element in the cell * @param action an action that should be coupled to the cell * @param allActions */ protected void processActions(Element element, PdfAction action, ArrayList allActions) { if (element.type() == Element.ANCHOR) { String url = ((Anchor) element).getReference(); if (url != null) { action = new PdfAction(url); } } Iterator i; switch (element.type()) { case Element.PHRASE: case Element.SECTION: case Element.ANCHOR: case Element.CHAPTER: case Element.LISTITEM: case Element.PARAGRAPH: for (i = ((ArrayList) element).iterator(); i.hasNext();) { processActions((Element) i.next(), action, allActions); } break; case Element.CHUNK: allActions.add(action); break; case Element.LIST: for (i = ((List) element).getItems().iterator(); i.hasNext();) { processActions((Element) i.next(), action, allActions); } break; default: int n = element.getChunks().size(); while (n-- > 0) allActions.add(action); break; } } /** * This is the number of the group the cell is in. */ private int groupNumber; /** * Gets the number of the group this cell is in.. * * @return a number */ public int getGroupNumber() { return groupNumber; } /** * Sets the group number. * @param number */ void setGroupNumber(int number) { groupNumber = number; } /** * Gets a Rectangle that is altered to fit on the page. * * @param top the top position * @param bottom the bottom position * @return a Rectangle */ public Rectangle rectangle(float top, float bottom) { Rectangle tmp = new Rectangle(getLeft(), getBottom(), getRight(), getTop()); tmp.cloneNonPositionParameters(this); if (getTop() > top) { tmp.setTop(top); tmp.setBorder(border - (border & TOP)); } if (getBottom() < bottom) { tmp.setBottom(bottom); tmp.setBorder(border - (border & BOTTOM)); } return tmp; } /** * Sets the value of useAscender. * @param use use ascender height if true */ public void setUseAscender(boolean use) { useAscender = use; } /** * Gets the value of useAscender * @return useAscender */ public boolean isUseAscender() { return useAscender; } /** * Sets the value of useDescender. * @param use use descender height if true */ public void setUseDescender(boolean use) { useDescender = use; } /** * gets the value of useDescender * @return useDescender */ public boolean isUseDescender() { return useDescender; } /** * Sets the value of useBorderPadding. * @param use adjust layout for borders if true */ public void setUseBorderPadding(boolean use) { useBorderPadding = use; } /** * Gets the value of useBorderPadding. * @return useBorderPadding */ public boolean isUseBorderPadding() { return useBorderPadding; } } src/core/com/lowagie/text/pdf/PdfChunk.java100644 0 0 67267 11015056763 16301 0ustar 0 0 /* * $Id: PdfChunk.java 3407 2008-05-21 16:56:55Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.lowagie.text.Chunk; import com.lowagie.text.Font; import com.lowagie.text.Image; import com.lowagie.text.SplitCharacter; import com.lowagie.text.Utilities; /** * A PdfChunk is the PDF translation of a Chunk. *

* A PdfChunk is a PdfString in a certain * PdfFont and Color. * * @see PdfString * @see com.lowagie.text.Chunk * @see com.lowagie.text.Font */ public class PdfChunk { private static final char singleSpace[] = {' '}; private static final PdfChunk thisChunk[] = new PdfChunk[1]; private static final float ITALIC_ANGLE = 0.21256f; /** The allowed attributes in variable attributes. */ private static final HashMap keysAttributes = new HashMap(); /** The allowed attributes in variable noStroke. */ private static final HashMap keysNoStroke = new HashMap(); static { keysAttributes.put(Chunk.ACTION, null); keysAttributes.put(Chunk.UNDERLINE, null); keysAttributes.put(Chunk.REMOTEGOTO, null); keysAttributes.put(Chunk.LOCALGOTO, null); keysAttributes.put(Chunk.LOCALDESTINATION, null); keysAttributes.put(Chunk.GENERICTAG, null); keysAttributes.put(Chunk.NEWPAGE, null); keysAttributes.put(Chunk.IMAGE, null); keysAttributes.put(Chunk.BACKGROUND, null); keysAttributes.put(Chunk.PDFANNOTATION, null); keysAttributes.put(Chunk.SKEW, null); keysAttributes.put(Chunk.HSCALE, null); keysAttributes.put(Chunk.SEPARATOR, null); keysAttributes.put(Chunk.TAB, null); keysNoStroke.put(Chunk.SUBSUPSCRIPT, null); keysNoStroke.put(Chunk.SPLITCHARACTER, null); keysNoStroke.put(Chunk.HYPHENATION, null); keysNoStroke.put(Chunk.TEXTRENDERMODE, null); } // membervariables /** The value of this object. */ protected String value = PdfObject.NOTHING; /** The encoding. */ protected String encoding = BaseFont.WINANSI; /** The font for this PdfChunk. */ protected PdfFont font; protected BaseFont baseFont; protected SplitCharacter splitCharacter; /** * Metric attributes. *

* This attributes require the measurement of characters widths when rendering * such as underline. */ protected HashMap attributes = new HashMap(); /** * Non metric attributes. *

* This attributes do not require the measurement of characters widths when rendering * such as Color. */ protected HashMap noStroke = new HashMap(); /** true if the chunk split was cause by a newline. */ protected boolean newlineSplit; /** The image in this PdfChunk, if it has one */ protected Image image; /** The offset in the x direction for the image */ protected float offsetX; /** The offset in the y direction for the image */ protected float offsetY; /** Indicates if the height and offset of the Image has to be taken into account */ protected boolean changeLeading = false; // constructors /** * Constructs a PdfChunk-object. * * @param string the content of the PdfChunk-object * @param other Chunk with the same style you want for the new Chunk */ PdfChunk(String string, PdfChunk other) { thisChunk[0] = this; value = string; this.font = other.font; this.attributes = other.attributes; this.noStroke = other.noStroke; this.baseFont = other.baseFont; Object obj[] = (Object[])attributes.get(Chunk.IMAGE); if (obj == null) image = null; else { image = (Image)obj[0]; offsetX = ((Float)obj[1]).floatValue(); offsetY = ((Float)obj[2]).floatValue(); changeLeading = ((Boolean)obj[3]).booleanValue(); } encoding = font.getFont().getEncoding(); splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); if (splitCharacter == null) splitCharacter = DefaultSplitCharacter.DEFAULT; } /** * Constructs a PdfChunk-object. * * @param chunk the original Chunk-object * @param action the PdfAction if the Chunk comes from an Anchor */ PdfChunk(Chunk chunk, PdfAction action) { thisChunk[0] = this; value = chunk.getContent(); Font f = chunk.getFont(); float size = f.getSize(); if (size == Font.UNDEFINED) size = 12; baseFont = f.getBaseFont(); int style = f.getStyle(); if (style == Font.UNDEFINED) { style = Font.NORMAL; } if (baseFont == null) { // translation of the font-family to a PDF font-family baseFont = f.getCalculatedBaseFont(false); } else { // bold simulation if ((style & Font.BOLD) != 0) attributes.put(Chunk.TEXTRENDERMODE, new Object[]{new Integer(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), new Float(size / 30f), null}); // italic simulation if ((style & Font.ITALIC) != 0) attributes.put(Chunk.SKEW, new float[]{0, ITALIC_ANGLE}); } font = new PdfFont(baseFont, size); // other style possibilities HashMap attr = chunk.getAttributes(); if (attr != null) { for (Iterator i = attr.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); Object name = entry.getKey(); if (keysAttributes.containsKey(name)) { attributes.put(name, entry.getValue()); } else if (keysNoStroke.containsKey(name)) { noStroke.put(name, entry.getValue()); } } if ("".equals(attr.get(Chunk.GENERICTAG))) { attributes.put(Chunk.GENERICTAG, chunk.getContent()); } } if (f.isUnderlined()) { Object obj[] = {null, new float[]{0, 1f / 15, 0, -1f / 3, 0}}; Object unders[][] = Utilities.addToArray((Object[][])attributes.get(Chunk.UNDERLINE), obj); attributes.put(Chunk.UNDERLINE, unders); } if (f.isStrikethru()) { Object obj[] = {null, new float[]{0, 1f / 15, 0, 1f / 3, 0}}; Object unders[][] = Utilities.addToArray((Object[][])attributes.get(Chunk.UNDERLINE), obj); attributes.put(Chunk.UNDERLINE, unders); } if (action != null) attributes.put(Chunk.ACTION, action); // the color can't be stored in a PdfFont noStroke.put(Chunk.COLOR, f.getColor()); noStroke.put(Chunk.ENCODING, font.getFont().getEncoding()); Object obj[] = (Object[])attributes.get(Chunk.IMAGE); if (obj == null) { image = null; } else { attributes.remove(Chunk.HSCALE); // images are scaled in other ways image = (Image)obj[0]; offsetX = ((Float)obj[1]).floatValue(); offsetY = ((Float)obj[2]).floatValue(); changeLeading = ((Boolean)obj[3]).booleanValue(); } font.setImage(image); Float hs = (Float)attributes.get(Chunk.HSCALE); if (hs != null) font.setHorizontalScaling(hs.floatValue()); encoding = font.getFont().getEncoding(); splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); if (splitCharacter == null) splitCharacter = DefaultSplitCharacter.DEFAULT; } // methods /** Gets the Unicode equivalent to a CID. * The (inexistent) CID is translated as '\n'. * It has only meaning with CJK fonts with Identity encoding. * @param c the CID code * @return the Unicode equivalent */ public int getUnicodeEquivalent(int c) { return baseFont.getUnicodeEquivalent(c); } protected int getWord(String text, int start) { int len = text.length(); while (start < len) { if (!Character.isLetter(text.charAt(start))) break; ++start; } return start; } /** * Splits this PdfChunk if it's too long for the given width. *

* Returns null if the PdfChunk wasn't truncated. * * @param width a given width * @return the PdfChunk that doesn't fit into the width. */ PdfChunk split(float width) { newlineSplit = false; if (image != null) { if (image.getScaledWidth() > width) { PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this); value = ""; attributes = new HashMap(); image = null; font = PdfFont.getDefaultFont(); return pc; } else return null; } HyphenationEvent hyphenationEvent = (HyphenationEvent)noStroke.get(Chunk.HYPHENATION); int currentPosition = 0; int splitPosition = -1; float currentWidth = 0; // loop over all the characters of a string // or until the totalWidth is reached int lastSpace = -1; float lastSpaceWidth = 0; int length = value.length(); char valueArray[] = value.toCharArray(); char character = 0; BaseFont ft = font.getFont(); boolean surrogate = false; if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { while (currentPosition < length) { // the width of every character is added to the currentWidth char cidChar = valueArray[currentPosition]; character = (char)ft.getUnicodeEquivalent(cidChar); // if a newLine or carriageReturn is encountered if (character == '\n') { newlineSplit = true; String returnValue = value.substring(currentPosition + 1); value = value.substring(0, currentPosition); if (value.length() < 1) { value = "\u0001"; } PdfChunk pc = new PdfChunk(returnValue, this); return pc; } currentWidth += font.width(cidChar); if (character == ' ') { lastSpace = currentPosition + 1; lastSpaceWidth = currentWidth; } if (currentWidth > width) break; // if a split-character is encountered, the splitPosition is altered if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, thisChunk)) splitPosition = currentPosition + 1; currentPosition++; } } else { while (currentPosition < length) { // the width of every character is added to the currentWidth character = valueArray[currentPosition]; // if a newLine or carriageReturn is encountered if (character == '\r' || character == '\n') { newlineSplit = true; int inc = 1; if (character == '\r' && currentPosition + 1 < length && valueArray[currentPosition + 1] == '\n') inc = 2; String returnValue = value.substring(currentPosition + inc); value = value.substring(0, currentPosition); if (value.length() < 1) { value = " "; } PdfChunk pc = new PdfChunk(returnValue, this); return pc; } surrogate = Utilities.isSurrogatePair(valueArray, currentPosition); if (surrogate) currentWidth += font.width(Utilities.convertToUtf32(valueArray[currentPosition], valueArray[currentPosition + 1])); else currentWidth += font.width(character); if (character == ' ') { lastSpace = currentPosition + 1; lastSpaceWidth = currentWidth; } if (surrogate) currentPosition++; if (currentWidth > width) break; // if a split-character is encountered, the splitPosition is altered if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, null)) splitPosition = currentPosition + 1; currentPosition++; } } // if all the characters fit in the total width, null is returned (there is no overflow) if (currentPosition == length) { return null; } // otherwise, the string has to be truncated if (splitPosition < 0) { String returnValue = value; value = ""; PdfChunk pc = new PdfChunk(returnValue, this); return pc; } if (lastSpace > splitPosition && splitCharacter.isSplitCharacter(0, 0, 1, singleSpace, null)) splitPosition = lastSpace; if (hyphenationEvent != null && lastSpace >= 0 && lastSpace < currentPosition) { int wordIdx = getWord(value, lastSpace); if (wordIdx > lastSpace) { String pre = hyphenationEvent.getHyphenatedWordPre(value.substring(lastSpace, wordIdx), font.getFont(), font.size(), width - lastSpaceWidth); String post = hyphenationEvent.getHyphenatedWordPost(); if (pre.length() > 0) { String returnValue = post + value.substring(wordIdx); value = trim(value.substring(0, lastSpace) + pre); PdfChunk pc = new PdfChunk(returnValue, this); return pc; } } } String returnValue = value.substring(splitPosition); value = trim(value.substring(0, splitPosition)); PdfChunk pc = new PdfChunk(returnValue, this); return pc; } /** * Truncates this PdfChunk if it's too long for the given width. *

* Returns null if the PdfChunk wasn't truncated. * * @param width a given width * @return the PdfChunk that doesn't fit into the width. */ PdfChunk truncate(float width) { if (image != null) { if (image.getScaledWidth() > width) { PdfChunk pc = new PdfChunk("", this); value = ""; attributes.remove(Chunk.IMAGE); image = null; font = PdfFont.getDefaultFont(); return pc; } else return null; } int currentPosition = 0; float currentWidth = 0; // it's no use trying to split if there isn't even enough place for a space if (width < font.width()) { String returnValue = value.substring(1); value = value.substring(0, 1); PdfChunk pc = new PdfChunk(returnValue, this); return pc; } // loop over all the characters of a string // or until the totalWidth is reached int length = value.length(); boolean surrogate = false; char character; while (currentPosition < length) { // the width of every character is added to the currentWidth surrogate = Utilities.isSurrogatePair(value, currentPosition); if (surrogate) currentWidth += font.width(Utilities.convertToUtf32(value, currentPosition)); else currentWidth += font.width(value.charAt(currentPosition)); if (currentWidth > width) break; if (surrogate) currentPosition++; currentPosition++; } // if all the characters fit in the total width, null is returned (there is no overflow) if (currentPosition == length) { return null; } // otherwise, the string has to be truncated //currentPosition -= 2; // we have to chop off minimum 1 character from the chunk if (currentPosition == 0) { currentPosition = 1; if (surrogate) ++currentPosition; } String returnValue = value.substring(currentPosition); value = value.substring(0, currentPosition); PdfChunk pc = new PdfChunk(returnValue, this); return pc; } // methods to retrieve the membervariables /** * Returns the font of this Chunk. * * @return a PdfFont */ PdfFont font() { return font; } /** * Returns the color of this Chunk. * * @return a Color */ Color color() { return (Color)noStroke.get(Chunk.COLOR); } /** * Returns the width of this PdfChunk. * * @return a width */ float width() { return font.width(value); } /** * Checks if the PdfChunk split was caused by a newline. * @return true if the PdfChunk split was caused by a newline. */ public boolean isNewlineSplit() { return newlineSplit; } /** * Gets the width of the PdfChunk taking into account the * extra character and word spacing. * @param charSpacing the extra character spacing * @param wordSpacing the extra word spacing * @return the calculated width */ public float getWidthCorrected(float charSpacing, float wordSpacing) { if (image != null) { return image.getScaledWidth() + charSpacing; } int numberOfSpaces = 0; int idx = -1; while ((idx = value.indexOf(' ', idx + 1)) >= 0) ++numberOfSpaces; return width() + (value.length() * charSpacing + numberOfSpaces * wordSpacing); } /** * Gets the text displacement relative to the baseline. * @return a displacement in points */ public float getTextRise() { Float f = (Float) getAttribute(Chunk.SUBSUPSCRIPT); if (f != null) { return f.floatValue(); } return 0.0f; } /** * Trims the last space. * @return the width of the space trimmed, otherwise 0 */ public float trimLastSpace() { BaseFont ft = font.getFont(); if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { if (value.length() > 1 && value.endsWith("\u0001")) { value = value.substring(0, value.length() - 1); return font.width('\u0001'); } } else { if (value.length() > 1 && value.endsWith(" ")) { value = value.substring(0, value.length() - 1); return font.width(' '); } } return 0; } public float trimFirstSpace() { BaseFont ft = font.getFont(); if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { if (value.length() > 1 && value.startsWith("\u0001")) { value = value.substring(1); return font.width('\u0001'); } } else { if (value.length() > 1 && value.startsWith(" ")) { value = value.substring(1); return font.width(' '); } } return 0; } /** * Gets an attribute. The search is made in attributes * and noStroke. * @param name the attribute key * @return the attribute value or null if not found */ Object getAttribute(String name) { if (attributes.containsKey(name)) return attributes.get(name); return noStroke.get(name); } /** *Checks if the attribute exists. * @param name the attribute key * @return true if the attribute exists */ boolean isAttribute(String name) { if (attributes.containsKey(name)) return true; return noStroke.containsKey(name); } /** * Checks if this PdfChunk needs some special metrics handling. * @return true if this PdfChunk needs some special metrics handling. */ boolean isStroked() { return (!attributes.isEmpty()); } /** * Checks if this PdfChunk is a Separator Chunk. * @return true if this chunk is a separator. * @since 2.1.2 */ boolean isSeparator() { return isAttribute(Chunk.SEPARATOR); } /** * Checks if this PdfChunk is a horizontal Separator Chunk. * @return true if this chunk is a horizontal separator. * @since 2.1.2 */ boolean isHorizontalSeparator() { if (isAttribute(Chunk.SEPARATOR)) { Object[] o = (Object[])getAttribute(Chunk.SEPARATOR); return !((Boolean)o[1]).booleanValue(); } return false; } /** * Checks if this PdfChunk is a tab Chunk. * @return true if this chunk is a separator. * @since 2.1.2 */ boolean isTab() { return isAttribute(Chunk.TAB); } /** * Correction for the tab position based on the left starting position. * @param newValue the new value for the left X. * @since 2.1.2 */ void adjustLeft(float newValue) { Object[] o = (Object[])attributes.get(Chunk.TAB); if (o != null) { attributes.put(Chunk.TAB, new Object[]{o[0], o[1], o[2], new Float(newValue)}); } } /** * Checks if there is an image in the PdfChunk. * @return true if an image is present */ boolean isImage() { return image != null; } /** * Gets the image in the PdfChunk. * @return the image or null */ Image getImage() { return image; } /** * Sets the image offset in the x direction * @param offsetX the image offset in the x direction */ void setImageOffsetX(float offsetX) { this.offsetX = offsetX; } /** * Gets the image offset in the x direction * @return the image offset in the x direction */ float getImageOffsetX() { return offsetX; } /** * Sets the image offset in the y direction * @param offsetY the image offset in the y direction */ void setImageOffsetY(float offsetY) { this.offsetY = offsetY; } /** * Gets the image offset in the y direction * @return Gets the image offset in the y direction */ float getImageOffsetY() { return offsetY; } /** * sets the value. * @param value content of the Chunk */ void setValue(String value) { this.value = value; } /** * @see java.lang.Object#toString() */ public String toString() { return value; } /** * Tells you if this string is in Chinese, Japanese, Korean or Identity-H. * @return true if the Chunk has a special encoding */ boolean isSpecialEncoding() { return encoding.equals(CJKFont.CJK_ENCODING) || encoding.equals(BaseFont.IDENTITY_H); } /** * Gets the encoding of this string. * * @return a String */ String getEncoding() { return encoding; } int length() { return value.length(); } int lengthUtf32() { if (!BaseFont.IDENTITY_H.equals(encoding)) return value.length(); int total = 0; int len = value.length(); for (int k = 0; k < len; ++k) { if (Utilities.isSurrogateHigh(value.charAt(k))) ++k; ++total; } return total; } boolean isExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { return splitCharacter.isSplitCharacter(start, current, end, cc, ck); } /** * Removes all the ' ' and '-'-characters on the right of a String. *

* @param string the String that has to be trimmed. * @return the trimmed String */ String trim(String string) { BaseFont ft = font.getFont(); if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { while (string.endsWith("\u0001")) { string = string.substring(0, string.length() - 1); } } else { while (string.endsWith(" ") || string.endsWith("\t")) { string = string.substring(0, string.length() - 1); } } return string; } public boolean changeLeading() { return changeLeading; } float getCharWidth(int c) { if (noPrint(c)) return 0; return font.width(c); } public static boolean noPrint(int c) { return ((c >= 0x200b && c <= 0x200f) || (c >= 0x202a && c <= 0x202e)); } } src/core/com/lowagie/text/pdf/PdfColor.java100644 0 0 6321 11012562273 16242 0ustar 0 0 /* * $Id: PdfColor.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; /** * A PdfColor defines a Color (it's a PdfArray containing 3 values). * * @see PdfDictionary */ class PdfColor extends PdfArray { // constructors /** * Constructs a new PdfColor. * * @param red a value between 0 and 255 * @param green a value between 0 and 255 * @param blue a value between 0 and 255 */ PdfColor(int red, int green, int blue) { super(new PdfNumber((double)(red & 0xFF) / 0xFF)); add(new PdfNumber((double)(green & 0xFF) / 0xFF)); add(new PdfNumber((double)(blue & 0xFF) / 0xFF)); } PdfColor(Color color) { this(color.getRed(), color.getGreen(), color.getBlue()); } }src/core/com/lowagie/text/pdf/PdfContentByte.java100644 0 0 341075 11213370070 17465 0ustar 0 0 /* * $Id: PdfContentByte.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.print.PrinterJob; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.Annotation; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgJBIG2; import com.lowagie.text.Rectangle; import com.lowagie.text.exceptions.IllegalPdfSyntaxException; import com.lowagie.text.pdf.internal.PdfAnnotationsImp; import com.lowagie.text.pdf.internal.PdfXConformanceImp; /** * PdfContentByte is an object containing the user positioned * text and graphic contents of a page. It knows how to apply the proper * font encoding. */ public class PdfContentByte { /** * This class keeps the graphic state of the current page */ static class GraphicState { /** This is the font in use */ FontDetails fontDetails; /** This is the color in use */ ColorDetails colorDetails; /** This is the font size in use */ float size; /** The x position of the text line matrix. */ protected float xTLM = 0; /** The y position of the text line matrix. */ protected float yTLM = 0; /** The current text leading. */ protected float leading = 0; /** The current horizontal scaling */ protected float scale = 100; /** The current character spacing */ protected float charSpace = 0; /** The current word spacing */ protected float wordSpace = 0; GraphicState() { } GraphicState(GraphicState cp) { fontDetails = cp.fontDetails; colorDetails = cp.colorDetails; size = cp.size; xTLM = cp.xTLM; yTLM = cp.yTLM; leading = cp.leading; scale = cp.scale; charSpace = cp.charSpace; wordSpace = cp.wordSpace; } } /** The alignment is center */ public static final int ALIGN_CENTER = Element.ALIGN_CENTER; /** The alignment is left */ public static final int ALIGN_LEFT = Element.ALIGN_LEFT; /** The alignment is right */ public static final int ALIGN_RIGHT = Element.ALIGN_RIGHT; /** A possible line cap value */ public static final int LINE_CAP_BUTT = 0; /** A possible line cap value */ public static final int LINE_CAP_ROUND = 1; /** A possible line cap value */ public static final int LINE_CAP_PROJECTING_SQUARE = 2; /** A possible line join value */ public static final int LINE_JOIN_MITER = 0; /** A possible line join value */ public static final int LINE_JOIN_ROUND = 1; /** A possible line join value */ public static final int LINE_JOIN_BEVEL = 2; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_FILL = 0; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_STROKE = 1; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_FILL_STROKE = 2; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_INVISIBLE = 3; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_FILL_CLIP = 4; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_STROKE_CLIP = 5; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_FILL_STROKE_CLIP = 6; /** A possible text rendering value */ public static final int TEXT_RENDER_MODE_CLIP = 7; private static final float[] unitRect = {0, 0, 0, 1, 1, 0, 1, 1}; // membervariables /** This is the actual content */ protected ByteBuffer content = new ByteBuffer(); /** This is the writer */ protected PdfWriter writer; /** This is the PdfDocument */ protected PdfDocument pdf; /** This is the GraphicState in use */ protected GraphicState state = new GraphicState(); /** The list were we save/restore the state */ protected ArrayList stateList = new ArrayList(); /** The list were we save/restore the layer depth */ protected ArrayList layerDepth; /** The separator between commands. */ protected int separator = '\n'; private int mcDepth = 0; private boolean inText = false; private static HashMap abrev = new HashMap(); static { abrev.put(PdfName.BITSPERCOMPONENT, "/BPC "); abrev.put(PdfName.COLORSPACE, "/CS "); abrev.put(PdfName.DECODE, "/D "); abrev.put(PdfName.DECODEPARMS, "/DP "); abrev.put(PdfName.FILTER, "/F "); abrev.put(PdfName.HEIGHT, "/H "); abrev.put(PdfName.IMAGEMASK, "/IM "); abrev.put(PdfName.INTENT, "/Intent "); abrev.put(PdfName.INTERPOLATE, "/I "); abrev.put(PdfName.WIDTH, "/W "); } // constructors /** * Constructs a new PdfContentByte-object. * * @param wr the writer associated to this content */ public PdfContentByte(PdfWriter wr) { if (wr != null) { writer = wr; pdf = writer.getPdfDocument(); } } // methods to get the content of this object /** * Returns the String representation of this PdfContentByte-object. * * @return a String */ public String toString() { return content.toString(); } /** * Gets the internal buffer. * @return the internal buffer */ public ByteBuffer getInternalBuffer() { return content; } /** Returns the PDF representation of this PdfContentByte-object. * * @param writer the PdfWriter * @return a byte array with the representation */ public byte[] toPdf(PdfWriter writer) { sanityCheck(); return content.toByteArray(); } // methods to add graphical content /** * Adds the content of another PdfContent-object to this object. * * @param other another PdfByteContent-object */ public void add(PdfContentByte other) { if (other.writer != null && writer != other.writer) throw new RuntimeException("Inconsistent writers. Are you mixing two documents?"); content.append(other.content); } /** * Gets the x position of the text line matrix. * * @return the x position of the text line matrix */ public float getXTLM() { return state.xTLM; } /** * Gets the y position of the text line matrix. * * @return the y position of the text line matrix */ public float getYTLM() { return state.yTLM; } /** * Gets the current text leading. * * @return the current text leading */ public float getLeading() { return state.leading; } /** * Gets the current character spacing. * * @return the current character spacing */ public float getCharacterSpacing() { return state.charSpace; } /** * Gets the current word spacing. * * @return the current word spacing */ public float getWordSpacing() { return state.wordSpace; } /** * Gets the current character spacing. * * @return the current character spacing */ public float getHorizontalScaling() { return state.scale; } /** * Changes the Flatness. *

* Flatness sets the maximum permitted distance in device pixels between the * mathematically correct path and an approximation constructed from straight line segments.
* * @param flatness a value */ public void setFlatness(float flatness) { if (flatness >= 0 && flatness <= 100) { content.append(flatness).append(" i").append_i(separator); } } /** * Changes the Line cap style. *

* The line cap style specifies the shape to be used at the end of open subpaths * when they are stroked.
* Allowed values are LINE_CAP_BUTT, LINE_CAP_ROUND and LINE_CAP_PROJECTING_SQUARE.
* * @param style a value */ public void setLineCap(int style) { if (style >= 0 && style <= 2) { content.append(style).append(" J").append_i(separator); } } /** * Changes the value of the line dash pattern. *

* The line dash pattern controls the pattern of dashes and gaps used to stroke paths. * It is specified by an array and a phase. The array specifies the length * of the alternating dashes and gaps. The phase specifies the distance into the dash * pattern to start the dash.
* * @param phase the value of the phase */ public void setLineDash(float phase) { content.append("[] ").append(phase).append(" d").append_i(separator); } /** * Changes the value of the line dash pattern. *

* The line dash pattern controls the pattern of dashes and gaps used to stroke paths. * It is specified by an array and a phase. The array specifies the length * of the alternating dashes and gaps. The phase specifies the distance into the dash * pattern to start the dash.
* * @param phase the value of the phase * @param unitsOn the number of units that must be 'on' (equals the number of units that must be 'off'). */ public void setLineDash(float unitsOn, float phase) { content.append("[").append(unitsOn).append("] ").append(phase).append(" d").append_i(separator); } /** * Changes the value of the line dash pattern. *

* The line dash pattern controls the pattern of dashes and gaps used to stroke paths. * It is specified by an array and a phase. The array specifies the length * of the alternating dashes and gaps. The phase specifies the distance into the dash * pattern to start the dash.
* * @param phase the value of the phase * @param unitsOn the number of units that must be 'on' * @param unitsOff the number of units that must be 'off' */ public void setLineDash(float unitsOn, float unitsOff, float phase) { content.append("[").append(unitsOn).append(' ').append(unitsOff).append("] ").append(phase).append(" d").append_i(separator); } /** * Changes the value of the line dash pattern. *

* The line dash pattern controls the pattern of dashes and gaps used to stroke paths. * It is specified by an array and a phase. The array specifies the length * of the alternating dashes and gaps. The phase specifies the distance into the dash * pattern to start the dash.
* * @param array length of the alternating dashes and gaps * @param phase the value of the phase */ public final void setLineDash(float[] array, float phase) { content.append("["); for (int i = 0; i < array.length; i++) { content.append(array[i]); if (i < array.length - 1) content.append(' '); } content.append("] ").append(phase).append(" d").append_i(separator); } /** * Changes the Line join style. *

* The line join style specifies the shape to be used at the corners of paths * that are stroked.
* Allowed values are LINE_JOIN_MITER (Miter joins), LINE_JOIN_ROUND (Round joins) and LINE_JOIN_BEVEL (Bevel joins).
* * @param style a value */ public void setLineJoin(int style) { if (style >= 0 && style <= 2) { content.append(style).append(" j").append_i(separator); } } /** * Changes the line width. *

* The line width specifies the thickness of the line used to stroke a path and is measured * in user space units.
* * @param w a width */ public void setLineWidth(float w) { content.append(w).append(" w").append_i(separator); } /** * Changes the Miter limit. *

* When two line segments meet at a sharp angle and mitered joins have been specified as the * line join style, it is possible for the miter to extend far beyond the thickness of the line * stroking path. The miter limit imposes a maximum on the ratio of the miter length to the line * witdh. When the limit is exceeded, the join is converted from a miter to a bevel.
* * @param miterLimit a miter limit */ public void setMiterLimit(float miterLimit) { if (miterLimit > 1) { content.append(miterLimit).append(" M").append_i(separator); } } /** * Modify the current clipping path by intersecting it with the current path, using the * nonzero winding number rule to determine which regions lie inside the clipping * path. */ public void clip() { content.append("W").append_i(separator); } /** * Modify the current clipping path by intersecting it with the current path, using the * even-odd rule to determine which regions lie inside the clipping path. */ public void eoClip() { content.append("W*").append_i(separator); } /** * Changes the currentgray tint for filling paths (device dependent colors!). *

* Sets the color space to DeviceGray (or the DefaultGray color space), * and sets the gray tint to use for filling paths.

* * @param gray a value between 0 (black) and 1 (white) */ public void setGrayFill(float gray) { content.append(gray).append(" g").append_i(separator); } /** * Changes the current gray tint for filling paths to black. */ public void resetGrayFill() { content.append("0 g").append_i(separator); } /** * Changes the currentgray tint for stroking paths (device dependent colors!). *

* Sets the color space to DeviceGray (or the DefaultGray color space), * and sets the gray tint to use for stroking paths.

* * @param gray a value between 0 (black) and 1 (white) */ public void setGrayStroke(float gray) { content.append(gray).append(" G").append_i(separator); } /** * Changes the current gray tint for stroking paths to black. */ public void resetGrayStroke() { content.append("0 G").append_i(separator); } /** * Helper to validate and write the RGB color components * @param red the intensity of red. A value between 0 and 1 * @param green the intensity of green. A value between 0 and 1 * @param blue the intensity of blue. A value between 0 and 1 */ private void HelperRGB(float red, float green, float blue) { PdfXConformanceImp.checkPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_RGB, null); if (red < 0) red = 0.0f; else if (red > 1.0f) red = 1.0f; if (green < 0) green = 0.0f; else if (green > 1.0f) green = 1.0f; if (blue < 0) blue = 0.0f; else if (blue > 1.0f) blue = 1.0f; content.append(red).append(' ').append(green).append(' ').append(blue); } /** * Changes the current color for filling paths (device dependent colors!). *

* Sets the color space to DeviceRGB (or the DefaultRGB color space), * and sets the color to use for filling paths.

*

* Following the PDF manual, each operand must be a number between 0 (minimum intensity) and * 1 (maximum intensity).

* * @param red the intensity of red. A value between 0 and 1 * @param green the intensity of green. A value between 0 and 1 * @param blue the intensity of blue. A value between 0 and 1 */ public void setRGBColorFillF(float red, float green, float blue) { HelperRGB(red, green, blue); content.append(" rg").append_i(separator); } /** * Changes the current color for filling paths to black. */ public void resetRGBColorFill() { content.append("0 g").append_i(separator); } /** * Changes the current color for stroking paths (device dependent colors!). *

* Sets the color space to DeviceRGB (or the DefaultRGB color space), * and sets the color to use for stroking paths.

*

* Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and * 1 (maximum intensity). * * @param red the intensity of red. A value between 0 and 1 * @param green the intensity of green. A value between 0 and 1 * @param blue the intensity of blue. A value between 0 and 1 */ public void setRGBColorStrokeF(float red, float green, float blue) { HelperRGB(red, green, blue); content.append(" RG").append_i(separator); } /** * Changes the current color for stroking paths to black. * */ public void resetRGBColorStroke() { content.append("0 G").append_i(separator); } /** * Helper to validate and write the CMYK color components. * * @param cyan the intensity of cyan. A value between 0 and 1 * @param magenta the intensity of magenta. A value between 0 and 1 * @param yellow the intensity of yellow. A value between 0 and 1 * @param black the intensity of black. A value between 0 and 1 */ private void HelperCMYK(float cyan, float magenta, float yellow, float black) { if (cyan < 0) cyan = 0.0f; else if (cyan > 1.0f) cyan = 1.0f; if (magenta < 0) magenta = 0.0f; else if (magenta > 1.0f) magenta = 1.0f; if (yellow < 0) yellow = 0.0f; else if (yellow > 1.0f) yellow = 1.0f; if (black < 0) black = 0.0f; else if (black > 1.0f) black = 1.0f; content.append(cyan).append(' ').append(magenta).append(' ').append(yellow).append(' ').append(black); } /** * Changes the current color for filling paths (device dependent colors!). *

* Sets the color space to DeviceCMYK (or the DefaultCMYK color space), * and sets the color to use for filling paths.

*

* Following the PDF manual, each operand must be a number between 0 (no ink) and * 1 (maximum ink).

* * @param cyan the intensity of cyan. A value between 0 and 1 * @param magenta the intensity of magenta. A value between 0 and 1 * @param yellow the intensity of yellow. A value between 0 and 1 * @param black the intensity of black. A value between 0 and 1 */ public void setCMYKColorFillF(float cyan, float magenta, float yellow, float black) { HelperCMYK(cyan, magenta, yellow, black); content.append(" k").append_i(separator); } /** * Changes the current color for filling paths to black. * */ public void resetCMYKColorFill() { content.append("0 0 0 1 k").append_i(separator); } /** * Changes the current color for stroking paths (device dependent colors!). *

* Sets the color space to DeviceCMYK (or the DefaultCMYK color space), * and sets the color to use for stroking paths.

*

* Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and * 1 (maximum intensity). * * @param cyan the intensity of cyan. A value between 0 and 1 * @param magenta the intensity of magenta. A value between 0 and 1 * @param yellow the intensity of yellow. A value between 0 and 1 * @param black the intensity of black. A value between 0 and 1 */ public void setCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) { HelperCMYK(cyan, magenta, yellow, black); content.append(" K").append_i(separator); } /** * Changes the current color for stroking paths to black. * */ public void resetCMYKColorStroke() { content.append("0 0 0 1 K").append_i(separator); } /** * Move the current point (x, y), omitting any connecting line segment. * * @param x new x-coordinate * @param y new y-coordinate */ public void moveTo(float x, float y) { content.append(x).append(' ').append(y).append(" m").append_i(separator); } /** * Appends a straight line segment from the current point (x, y). The new current * point is (x, y). * * @param x new x-coordinate * @param y new y-coordinate */ public void lineTo(float x, float y) { content.append(x).append(' ').append(y).append(" l").append_i(separator); } /** * Appends a Bêzier curve to the path, starting from the current point. * * @param x1 x-coordinate of the first control point * @param y1 y-coordinate of the first control point * @param x2 x-coordinate of the second control point * @param y2 y-coordinate of the second control point * @param x3 x-coordinate of the ending point (= new current point) * @param y3 y-coordinate of the ending point (= new current point) */ public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) { content.append(x1).append(' ').append(y1).append(' ').append(x2).append(' ').append(y2).append(' ').append(x3).append(' ').append(y3).append(" c").append_i(separator); } /** * Appends a Bêzier curve to the path, starting from the current point. * * @param x2 x-coordinate of the second control point * @param y2 y-coordinate of the second control point * @param x3 x-coordinate of the ending point (= new current point) * @param y3 y-coordinate of the ending point (= new current point) */ public void curveTo(float x2, float y2, float x3, float y3) { content.append(x2).append(' ').append(y2).append(' ').append(x3).append(' ').append(y3).append(" v").append_i(separator); } /** * Appends a Bêzier curve to the path, starting from the current point. * * @param x1 x-coordinate of the first control point * @param y1 y-coordinate of the first control point * @param x3 x-coordinate of the ending point (= new current point) * @param y3 y-coordinate of the ending point (= new current point) */ public void curveFromTo(float x1, float y1, float x3, float y3) { content.append(x1).append(' ').append(y1).append(' ').append(x3).append(' ').append(y3).append(" y").append_i(separator); } /** Draws a circle. The endpoint will (x+r, y). * * @param x x center of circle * @param y y center of circle * @param r radius of circle */ public void circle(float x, float y, float r) { float b = 0.5523f; moveTo(x + r, y); curveTo(x + r, y + r * b, x + r * b, y + r, x, y + r); curveTo(x - r * b, y + r, x - r, y + r * b, x - r, y); curveTo(x - r, y - r * b, x - r * b, y - r, x, y - r); curveTo(x + r * b, y - r, x + r, y - r * b, x + r, y); } /** * Adds a rectangle to the current path. * * @param x x-coordinate of the starting point * @param y y-coordinate of the starting point * @param w width * @param h height */ public void rectangle(float x, float y, float w, float h) { content.append(x).append(' ').append(y).append(' ').append(w).append(' ').append(h).append(" re").append_i(separator); } private boolean compareColors(Color c1, Color c2) { if (c1 == null && c2 == null) return true; if (c1 == null || c2 == null) return false; if (c1 instanceof ExtendedColor) return c1.equals(c2); return c2.equals(c1); } /** * Adds a variable width border to the current path. * Only use if {@link com.lowagie.text.Rectangle#isUseVariableBorders() Rectangle.isUseVariableBorders} * = true. * @param rect a Rectangle */ public void variableRectangle(Rectangle rect) { float t = rect.getTop(); float b = rect.getBottom(); float r = rect.getRight(); float l = rect.getLeft(); float wt = rect.getBorderWidthTop(); float wb = rect.getBorderWidthBottom(); float wr = rect.getBorderWidthRight(); float wl = rect.getBorderWidthLeft(); Color ct = rect.getBorderColorTop(); Color cb = rect.getBorderColorBottom(); Color cr = rect.getBorderColorRight(); Color cl = rect.getBorderColorLeft(); saveState(); setLineCap(PdfContentByte.LINE_CAP_BUTT); setLineJoin(PdfContentByte.LINE_JOIN_MITER); float clw = 0; boolean cdef = false; Color ccol = null; boolean cdefi = false; Color cfil = null; // draw top if (wt > 0) { setLineWidth(clw = wt); cdef = true; if (ct == null) resetRGBColorStroke(); else setColorStroke(ct); ccol = ct; moveTo(l, t - wt / 2f); lineTo(r, t - wt / 2f); stroke(); } // Draw bottom if (wb > 0) { if (wb != clw) setLineWidth(clw = wb); if (!cdef || !compareColors(ccol, cb)) { cdef = true; if (cb == null) resetRGBColorStroke(); else setColorStroke(cb); ccol = cb; } moveTo(r, b + wb / 2f); lineTo(l, b + wb / 2f); stroke(); } // Draw right if (wr > 0) { if (wr != clw) setLineWidth(clw = wr); if (!cdef || !compareColors(ccol, cr)) { cdef = true; if (cr == null) resetRGBColorStroke(); else setColorStroke(cr); ccol = cr; } boolean bt = compareColors(ct, cr); boolean bb = compareColors(cb, cr); moveTo(r - wr / 2f, bt ? t : t - wt); lineTo(r - wr / 2f, bb ? b : b + wb); stroke(); if (!bt || !bb) { cdefi = true; if (cr == null) resetRGBColorFill(); else setColorFill(cr); cfil = cr; if (!bt) { moveTo(r, t); lineTo(r, t - wt); lineTo(r - wr, t - wt); fill(); } if (!bb) { moveTo(r, b); lineTo(r, b + wb); lineTo(r - wr, b + wb); fill(); } } } // Draw Left if (wl > 0) { if (wl != clw) setLineWidth(wl); if (!cdef || !compareColors(ccol, cl)) { if (cl == null) resetRGBColorStroke(); else setColorStroke(cl); } boolean bt = compareColors(ct, cl); boolean bb = compareColors(cb, cl); moveTo(l + wl / 2f, bt ? t : t - wt); lineTo(l + wl / 2f, bb ? b : b + wb); stroke(); if (!bt || !bb) { if (!cdefi || !compareColors(cfil, cl)) { if (cl == null) resetRGBColorFill(); else setColorFill(cl); } if (!bt) { moveTo(l, t); lineTo(l, t - wt); lineTo(l + wl, t - wt); fill(); } if (!bb) { moveTo(l, b); lineTo(l, b + wb); lineTo(l + wl, b + wb); fill(); } } } restoreState(); } /** * Adds a border (complete or partially) to the current path.. * * @param rectangle a Rectangle */ public void rectangle(Rectangle rectangle) { // the coordinates of the border are retrieved float x1 = rectangle.getLeft(); float y1 = rectangle.getBottom(); float x2 = rectangle.getRight(); float y2 = rectangle.getTop(); // the backgroundcolor is set Color background = rectangle.getBackgroundColor(); if (background != null) { setColorFill(background); rectangle(x1, y1, x2 - x1, y2 - y1); fill(); resetRGBColorFill(); } // if the element hasn't got any borders, nothing is added if (! rectangle.hasBorders()) { return; } // if any of the individual border colors are set // we draw the borders all around using the // different colors if (rectangle.isUseVariableBorders()) { variableRectangle(rectangle); } else { // the width is set to the width of the element if (rectangle.getBorderWidth() != Rectangle.UNDEFINED) { setLineWidth(rectangle.getBorderWidth()); } // the color is set to the color of the element Color color = rectangle.getBorderColor(); if (color != null) { setColorStroke(color); } // if the box is a rectangle, it is added as a rectangle if (rectangle.hasBorder(Rectangle.BOX)) { rectangle(x1, y1, x2 - x1, y2 - y1); } // if the border isn't a rectangle, the different sides are added apart else { if (rectangle.hasBorder(Rectangle.RIGHT)) { moveTo(x2, y1); lineTo(x2, y2); } if (rectangle.hasBorder(Rectangle.LEFT)) { moveTo(x1, y1); lineTo(x1, y2); } if (rectangle.hasBorder(Rectangle.BOTTOM)) { moveTo(x1, y1); lineTo(x2, y1); } if (rectangle.hasBorder(Rectangle.TOP)) { moveTo(x1, y2); lineTo(x2, y2); } } stroke(); if (color != null) { resetRGBColorStroke(); } } } /** * Closes the current subpath by appending a straight line segment from the current point * to the starting point of the subpath. */ public void closePath() { content.append("h").append_i(separator); } /** * Ends the path without filling or stroking it. */ public void newPath() { content.append("n").append_i(separator); } /** * Strokes the path. */ public void stroke() { content.append("S").append_i(separator); } /** * Closes the path and strokes it. */ public void closePathStroke() { content.append("s").append_i(separator); } /** * Fills the path, using the non-zero winding number rule to determine the region to fill. */ public void fill() { content.append("f").append_i(separator); } /** * Fills the path, using the even-odd rule to determine the region to fill. */ public void eoFill() { content.append("f*").append_i(separator); } /** * Fills the path using the non-zero winding number rule to determine the region to fill and strokes it. */ public void fillStroke() { content.append("B").append_i(separator); } /** * Closes the path, fills it using the non-zero winding number rule to determine the region to fill and strokes it. */ public void closePathFillStroke() { content.append("b").append_i(separator); } /** * Fills the path, using the even-odd rule to determine the region to fill and strokes it. */ public void eoFillStroke() { content.append("B*").append_i(separator); } /** * Closes the path, fills it using the even-odd rule to determine the region to fill and strokes it. */ public void closePathEoFillStroke() { content.append("b*").append_i(separator); } /** * Adds an Image to the page. The Image must have * absolute positioning. * @param image the Image object * @throws DocumentException if the Image does not have absolute positioning */ public void addImage(Image image) throws DocumentException { addImage(image, false); } /** * Adds an Image to the page. The Image must have * absolute positioning. The image can be placed inline. * @param image the Image object * @param inlineImage true to place this image inline, false otherwise * @throws DocumentException if the Image does not have absolute positioning */ public void addImage(Image image, boolean inlineImage) throws DocumentException { if (!image.hasAbsoluteY()) throw new DocumentException("The image must have absolute positioning."); float matrix[] = image.matrix(); matrix[Image.CX] = image.getAbsoluteX() - matrix[Image.CX]; matrix[Image.CY] = image.getAbsoluteY() - matrix[Image.CY]; addImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], inlineImage); } /** * Adds an Image to the page. The positioning of the Image * is done with the transformation matrix. To position an image at (x,y) * use addImage(image, image_width, 0, 0, image_height, x, y). * @param image the Image object * @param a an element of the transformation matrix * @param b an element of the transformation matrix * @param c an element of the transformation matrix * @param d an element of the transformation matrix * @param e an element of the transformation matrix * @param f an element of the transformation matrix * @throws DocumentException on error */ public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { addImage(image, a, b, c, d, e, f, false); } /** * Adds an Image to the page. The positioning of the Image * is done with the transformation matrix. To position an image at (x,y) * use addImage(image, image_width, 0, 0, image_height, x, y). The image can be placed inline. * @param image the Image object * @param a an element of the transformation matrix * @param b an element of the transformation matrix * @param c an element of the transformation matrix * @param d an element of the transformation matrix * @param e an element of the transformation matrix * @param f an element of the transformation matrix * @param inlineImage true to place this image inline, false otherwise * @throws DocumentException on error */ public void addImage(Image image, float a, float b, float c, float d, float e, float f, boolean inlineImage) throws DocumentException { try { if (image.getLayer() != null) beginLayer(image.getLayer()); if (image.isImgTemplate()) { writer.addDirectImageSimple(image); PdfTemplate template = image.getTemplateData(); float w = template.getWidth(); float h = template.getHeight(); addTemplate(template, a / w, b / w, c / h, d / h, e, f); } else { content.append("q "); content.append(a).append(' '); content.append(b).append(' '); content.append(c).append(' '); content.append(d).append(' '); content.append(e).append(' '); content.append(f).append(" cm"); if (inlineImage) { content.append("\nBI\n"); PdfImage pimage = new PdfImage(image, "", null); if (image instanceof ImgJBIG2) { byte[] globals = ((ImgJBIG2)image).getGlobalBytes(); if (globals != null) { PdfDictionary decodeparms = new PdfDictionary(); decodeparms.put(PdfName.JBIG2GLOBALS, writer.getReferenceJBIG2Globals(globals)); pimage.put(PdfName.DECODEPARMS, decodeparms); } } for (Iterator it = pimage.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); PdfObject value = pimage.get(key); String s = (String)abrev.get(key); if (s == null) continue; content.append(s); boolean check = true; if (key.equals(PdfName.COLORSPACE) && value.isArray()) { PdfArray ar = (PdfArray)value; if (ar.size() == 4 && PdfName.INDEXED.equals(ar.getAsName(0)) && ar.getPdfObject(1).isName() && ar.getPdfObject(2).isNumber() && ar.getPdfObject(3).isString() ) { check = false; } } if (check && key.equals(PdfName.COLORSPACE) && !value.isName()) { PdfName cs = writer.getColorspaceName(); PageResources prs = getPageResources(); prs.addColor(cs, writer.addToBody(value).getIndirectReference()); value = cs; } value.toPdf(null, content); content.append('\n'); } content.append("ID\n"); pimage.writeContent(content); content.append("\nEI\nQ").append_i(separator); } else { PdfName name; PageResources prs = getPageResources(); Image maskImage = image.getImageMask(); if (maskImage != null) { name = writer.addDirectImageSimple(maskImage); prs.addXObject(name, writer.getImageReference(name)); } name = writer.addDirectImageSimple(image); name = prs.addXObject(name, writer.getImageReference(name)); content.append(' ').append(name.getBytes()).append(" Do Q").append_i(separator); } } if (image.hasBorders()) { saveState(); float w = image.getWidth(); float h = image.getHeight(); concatCTM(a / w, b / w, c / h, d / h, e, f); rectangle(image); restoreState(); } if (image.getLayer() != null) endLayer(); Annotation annot = image.getAnnotation(); if (annot == null) return; float[] r = new float[unitRect.length]; for (int k = 0; k < unitRect.length; k += 2) { r[k] = a * unitRect[k] + c * unitRect[k + 1] + e; r[k + 1] = b * unitRect[k] + d * unitRect[k + 1] + f; } float llx = r[0]; float lly = r[1]; float urx = llx; float ury = lly; for (int k = 2; k < r.length; k += 2) { llx = Math.min(llx, r[k]); lly = Math.min(lly, r[k + 1]); urx = Math.max(urx, r[k]); ury = Math.max(ury, r[k + 1]); } annot = new Annotation(annot); annot.setDimensions(llx, lly, urx, ury); PdfAnnotation an = PdfAnnotationsImp.convertAnnotation(writer, annot, new Rectangle(llx, lly, urx, ury)); if (an == null) return; addAnnotation(an); } catch (Exception ee) { throw new DocumentException(ee); } } /** * Makes this PdfContentByte empty. * Calls reset( true ) */ public void reset() { reset( true ); } /** * Makes this PdfContentByte empty. * @param validateContent will call sanityCheck() if true. * @since 2.1.6 */ public void reset( boolean validateContent ) { content.reset(); if (validateContent) { sanityCheck(); } state = new GraphicState(); } /** * Starts the writing of text. */ public void beginText() { if (inText) { throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." ); } inText = true; state.xTLM = 0; state.yTLM = 0; content.append("BT").append_i(separator); } /** * Ends the writing of text and makes the current font invalid. */ public void endText() { if (!inText) { throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." ); } inText = false; content.append("ET").append_i(separator); } /** * Saves the graphic state. saveState and * restoreState must be balanced. */ public void saveState() { content.append("q").append_i(separator); stateList.add(new GraphicState(state)); } /** * Restores the graphic state. saveState and * restoreState must be balanced. */ public void restoreState() { content.append("Q").append_i(separator); int idx = stateList.size() - 1; if (idx < 0) throw new IllegalPdfSyntaxException("Unbalanced save/restore state operators."); state = (GraphicState)stateList.get(idx); stateList.remove(idx); } /** * Sets the character spacing parameter. * * @param charSpace a parameter */ public void setCharacterSpacing(float charSpace) { state.charSpace = charSpace; content.append(charSpace).append(" Tc").append_i(separator); } /** * Sets the word spacing parameter. * * @param wordSpace a parameter */ public void setWordSpacing(float wordSpace) { state.wordSpace = wordSpace; content.append(wordSpace).append(" Tw").append_i(separator); } /** * Sets the horizontal scaling parameter. * * @param scale a parameter */ public void setHorizontalScaling(float scale) { state.scale = scale; content.append(scale).append(" Tz").append_i(separator); } /** * Sets the text leading parameter. *

* The leading parameter is measured in text space units. It specifies the vertical distance * between the baselines of adjacent lines of text.

* * @param leading the new leading */ public void setLeading(float leading) { state.leading = leading; content.append(leading).append(" TL").append_i(separator); } /** * Set the font and the size for the subsequent text writing. * * @param bf the font * @param size the font size in points */ public void setFontAndSize(BaseFont bf, float size) { checkWriter(); if (size < 0.0001f && size > -0.0001f) throw new IllegalArgumentException("Font size too small: " + size); state.size = size; state.fontDetails = writer.addSimple(bf); PageResources prs = getPageResources(); PdfName name = state.fontDetails.getFontName(); name = prs.addFont(name, state.fontDetails.getIndirectReference()); content.append(name.getBytes()).append(' ').append(size).append(" Tf").append_i(separator); } /** * Sets the text rendering parameter. * * @param rendering a parameter */ public void setTextRenderingMode(int rendering) { content.append(rendering).append(" Tr").append_i(separator); } /** * Sets the text rise parameter. *

* This allows to write text in subscript or superscript mode.

* * @param rise a parameter */ public void setTextRise(float rise) { content.append(rise).append(" Ts").append_i(separator); } /** * A helper to insert into the content stream the text * converted to bytes according to the font's encoding. * * @param text the text to write */ private void showText2(String text) { if (state.fontDetails == null) throw new NullPointerException("Font and size must be set before writing any text"); byte b[] = state.fontDetails.convertToBytes(text); escapeString(b, content); } /** * Shows the text. * * @param text the text to write */ public void showText(String text) { showText2(text); content.append("Tj").append_i(separator); } /** * Constructs a kern array for a text in a certain font * @param text the text * @param font the font * @return a PdfTextArray */ public static PdfTextArray getKernArray(String text, BaseFont font) { PdfTextArray pa = new PdfTextArray(); StringBuffer acc = new StringBuffer(); int len = text.length() - 1; char c[] = text.toCharArray(); if (len >= 0) acc.append(c, 0, 1); for (int k = 0; k < len; ++k) { char c2 = c[k + 1]; int kern = font.getKerning(c[k], c2); if (kern == 0) { acc.append(c2); } else { pa.add(acc.toString()); acc.setLength(0); acc.append(c, k + 1, 1); pa.add(-kern); } } pa.add(acc.toString()); return pa; } /** * Shows the text kerned. * * @param text the text to write */ public void showTextKerned(String text) { if (state.fontDetails == null) throw new NullPointerException("Font and size must be set before writing any text"); BaseFont bf = state.fontDetails.getBaseFont(); if (bf.hasKernPairs()) showText(getKernArray(text, bf)); else showText(text); } /** * Moves to the next line and shows text. * * @param text the text to write */ public void newlineShowText(String text) { state.yTLM -= state.leading; showText2(text); content.append("'").append_i(separator); } /** * Moves to the next line and shows text string, using the given values of the character and word spacing parameters. * * @param wordSpacing a parameter * @param charSpacing a parameter * @param text the text to write */ public void newlineShowText(float wordSpacing, float charSpacing, String text) { state.yTLM -= state.leading; content.append(wordSpacing).append(' ').append(charSpacing); showText2(text); content.append("\"").append_i(separator); // The " operator sets charSpace and wordSpace into graphics state // (cfr PDF reference v1.6, table 5.6) state.charSpace = charSpacing; state.wordSpace = wordSpacing; } /** * Changes the text matrix. *

* Remark: this operation also initializes the current point position.

* * @param a operand 1,1 in the matrix * @param b operand 1,2 in the matrix * @param c operand 2,1 in the matrix * @param d operand 2,2 in the matrix * @param x operand 3,1 in the matrix * @param y operand 3,2 in the matrix */ public void setTextMatrix(float a, float b, float c, float d, float x, float y) { state.xTLM = x; state.yTLM = y; content.append(a).append(' ').append(b).append_i(' ') .append(c).append_i(' ').append(d).append_i(' ') .append(x).append_i(' ').append(y).append(" Tm").append_i(separator); } /** * Changes the text matrix. The first four parameters are {1,0,0,1}. *

* Remark: this operation also initializes the current point position.

* * @param x operand 3,1 in the matrix * @param y operand 3,2 in the matrix */ public void setTextMatrix(float x, float y) { setTextMatrix(1, 0, 0, 1, x, y); } /** * Moves to the start of the next line, offset from the start of the current line. * * @param x x-coordinate of the new current point * @param y y-coordinate of the new current point */ public void moveText(float x, float y) { state.xTLM += x; state.yTLM += y; content.append(x).append(' ').append(y).append(" Td").append_i(separator); } /** * Moves to the start of the next line, offset from the start of the current line. *

* As a side effect, this sets the leading parameter in the text state.

* * @param x offset of the new current point * @param y y-coordinate of the new current point */ public void moveTextWithLeading(float x, float y) { state.xTLM += x; state.yTLM += y; state.leading = -y; content.append(x).append(' ').append(y).append(" TD").append_i(separator); } /** * Moves to the start of the next line. */ public void newlineText() { state.yTLM -= state.leading; content.append("T*").append_i(separator); } /** * Gets the size of this content. * * @return the size of the content */ int size() { return content.size(); } /** * Escapes a byte array according to the PDF conventions. * * @param b the byte array to escape * @return an escaped byte array */ static byte[] escapeString(byte b[]) { ByteBuffer content = new ByteBuffer(); escapeString(b, content); return content.toByteArray(); } /** * Escapes a byte array according to the PDF conventions. * * @param b the byte array to escape * @param content the content */ static void escapeString(byte b[], ByteBuffer content) { content.append_i('('); for (int k = 0; k < b.length; ++k) { byte c = b[k]; switch (c) { case '\r': content.append("\\r"); break; case '\n': content.append("\\n"); break; case '\t': content.append("\\t"); break; case '\b': content.append("\\b"); break; case '\f': content.append("\\f"); break; case '(': case ')': case '\\': content.append_i('\\').append_i(c); break; default: content.append_i(c); } } content.append(")"); } /** * Adds a named outline to the document. * * @param outline the outline * @param name the name for the local destination */ public void addOutline(PdfOutline outline, String name) { checkWriter(); pdf.addOutline(outline, name); } /** * Gets the root outline. * * @return the root outline */ public PdfOutline getRootOutline() { checkWriter(); return pdf.getRootOutline(); } /** * Computes the width of the given string taking in account * the current values of "Character spacing", "Word Spacing" * and "Horizontal Scaling". * The additional spacing is not computed for the last character * of the string. * @param text the string to get width of * @param kerned the kerning option * @return the width */ public float getEffectiveStringWidth(String text, boolean kerned) { BaseFont bf = state.fontDetails.getBaseFont(); float w; if (kerned) w = bf.getWidthPointKerned(text, state.size); else w = bf.getWidthPoint(text, state.size); if (state.charSpace != 0.0f && text.length() > 1) { w += state.charSpace * (text.length() -1); } int ft = bf.getFontType(); if (state.wordSpace != 0.0f && (ft == BaseFont.FONT_TYPE_T1 || ft == BaseFont.FONT_TYPE_TT || ft == BaseFont.FONT_TYPE_T3)) { for (int i = 0; i < (text.length() -1); i++) { if (text.charAt(i) == ' ') w += state.wordSpace; } } if (state.scale != 100.0) w = (w * state.scale) / 100.0f; //System.out.println("String width = " + Float.toString(w)); return w; } /** * Shows text right, left or center aligned with rotation. * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT * @param text the text to show * @param x the x pivot position * @param y the y pivot position * @param rotation the rotation to be applied in degrees counterclockwise */ public void showTextAligned(int alignment, String text, float x, float y, float rotation) { showTextAligned(alignment, text, x, y, rotation, false); } private void showTextAligned(int alignment, String text, float x, float y, float rotation, boolean kerned) { if (state.fontDetails == null) throw new NullPointerException("Font and size must be set before writing any text"); if (rotation == 0) { switch (alignment) { case ALIGN_CENTER: x -= getEffectiveStringWidth(text, kerned) / 2; break; case ALIGN_RIGHT: x -= getEffectiveStringWidth(text, kerned); break; } setTextMatrix(x, y); if (kerned) showTextKerned(text); else showText(text); } else { double alpha = rotation * Math.PI / 180.0; float cos = (float)Math.cos(alpha); float sin = (float)Math.sin(alpha); float len; switch (alignment) { case ALIGN_CENTER: len = getEffectiveStringWidth(text, kerned) / 2; x -= len * cos; y -= len * sin; break; case ALIGN_RIGHT: len = getEffectiveStringWidth(text, kerned); x -= len * cos; y -= len * sin; break; } setTextMatrix(cos, sin, -sin, cos, x, y); if (kerned) showTextKerned(text); else showText(text); setTextMatrix(0f, 0f); } } /** * Shows text kerned right, left or center aligned with rotation. * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT * @param text the text to show * @param x the x pivot position * @param y the y pivot position * @param rotation the rotation to be applied in degrees counterclockwise */ public void showTextAlignedKerned(int alignment, String text, float x, float y, float rotation) { showTextAligned(alignment, text, x, y, rotation, true); } /** * Concatenate a matrix to the current transformation matrix. * @param a an element of the transformation matrix * @param b an element of the transformation matrix * @param c an element of the transformation matrix * @param d an element of the transformation matrix * @param e an element of the transformation matrix * @param f an element of the transformation matrix **/ public void concatCTM(float a, float b, float c, float d, float e, float f) { content.append(a).append(' ').append(b).append(' ').append(c).append(' '); content.append(d).append(' ').append(e).append(' ').append(f).append(" cm").append_i(separator); } /** * Generates an array of bezier curves to draw an arc. *

* (x1, y1) and (x2, y2) are the corners of the enclosing rectangle. * Angles, measured in degrees, start with 0 to the right (the positive X * axis) and increase counter-clockwise. The arc extends from startAng * to startAng+extent. I.e. startAng=0 and extent=180 yields an openside-down * semi-circle. *

* The resulting coordinates are of the form float[]{x1,y1,x2,y2,x3,y3, x4,y4} * such that the curve goes from (x1, y1) to (x4, y4) with (x2, y2) and * (x3, y3) as their respective Bezier control points. *

* Note: this code was taken from ReportLab (www.reportlab.org), an excellent * PDF generator for Python (BSD license: http://www.reportlab.org/devfaq.html#1.3 ). * * @param x1 a corner of the enclosing rectangle * @param y1 a corner of the enclosing rectangle * @param x2 a corner of the enclosing rectangle * @param y2 a corner of the enclosing rectangle * @param startAng starting angle in degrees * @param extent angle extent in degrees * @return a list of float[] with the bezier curves */ public static ArrayList bezierArc(float x1, float y1, float x2, float y2, float startAng, float extent) { float tmp; if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; } if (y2 > y1) { tmp = y1; y1 = y2; y2 = tmp; } float fragAngle; int Nfrag; if (Math.abs(extent) <= 90f) { fragAngle = extent; Nfrag = 1; } else { Nfrag = (int)(Math.ceil(Math.abs(extent)/90f)); fragAngle = extent / Nfrag; } float x_cen = (x1+x2)/2f; float y_cen = (y1+y2)/2f; float rx = (x2-x1)/2f; float ry = (y2-y1)/2f; float halfAng = (float)(fragAngle * Math.PI / 360.); float kappa = (float)(Math.abs(4. / 3. * (1. - Math.cos(halfAng)) / Math.sin(halfAng))); ArrayList pointList = new ArrayList(); for (int i = 0; i < Nfrag; ++i) { float theta0 = (float)((startAng + i*fragAngle) * Math.PI / 180.); float theta1 = (float)((startAng + (i+1)*fragAngle) * Math.PI / 180.); float cos0 = (float)Math.cos(theta0); float cos1 = (float)Math.cos(theta1); float sin0 = (float)Math.sin(theta0); float sin1 = (float)Math.sin(theta1); if (fragAngle > 0f) { pointList.add(new float[]{x_cen + rx * cos0, y_cen - ry * sin0, x_cen + rx * (cos0 - kappa * sin0), y_cen - ry * (sin0 + kappa * cos0), x_cen + rx * (cos1 + kappa * sin1), y_cen - ry * (sin1 - kappa * cos1), x_cen + rx * cos1, y_cen - ry * sin1}); } else { pointList.add(new float[]{x_cen + rx * cos0, y_cen - ry * sin0, x_cen + rx * (cos0 + kappa * sin0), y_cen - ry * (sin0 - kappa * cos0), x_cen + rx * (cos1 - kappa * sin1), y_cen - ry * (sin1 + kappa * cos1), x_cen + rx * cos1, y_cen - ry * sin1}); } } return pointList; } /** * Draws a partial ellipse inscribed within the rectangle x1,y1,x2,y2, * starting at startAng degrees and covering extent degrees. Angles * start with 0 to the right (+x) and increase counter-clockwise. * * @param x1 a corner of the enclosing rectangle * @param y1 a corner of the enclosing rectangle * @param x2 a corner of the enclosing rectangle * @param y2 a corner of the enclosing rectangle * @param startAng starting angle in degrees * @param extent angle extent in degrees */ public void arc(float x1, float y1, float x2, float y2, float startAng, float extent) { ArrayList ar = bezierArc(x1, y1, x2, y2, startAng, extent); if (ar.isEmpty()) return; float pt[] = (float [])ar.get(0); moveTo(pt[0], pt[1]); for (int k = 0; k < ar.size(); ++k) { pt = (float [])ar.get(k); curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); } } /** * Draws an ellipse inscribed within the rectangle x1,y1,x2,y2. * * @param x1 a corner of the enclosing rectangle * @param y1 a corner of the enclosing rectangle * @param x2 a corner of the enclosing rectangle * @param y2 a corner of the enclosing rectangle */ public void ellipse(float x1, float y1, float x2, float y2) { arc(x1, y1, x2, y2, 0f, 360f); } /** * Create a new colored tiling pattern. * * @param width the width of the pattern * @param height the height of the pattern * @param xstep the desired horizontal spacing between pattern cells. * May be either positive or negative, but not zero. * @param ystep the desired vertical spacing between pattern cells. * May be either positive or negative, but not zero. * @return the PdfPatternPainter where the pattern will be created */ public PdfPatternPainter createPattern(float width, float height, float xstep, float ystep) { checkWriter(); if ( xstep == 0.0f || ystep == 0.0f ) throw new RuntimeException("XStep or YStep can not be ZERO."); PdfPatternPainter painter = new PdfPatternPainter(writer); painter.setWidth(width); painter.setHeight(height); painter.setXStep(xstep); painter.setYStep(ystep); writer.addSimplePattern(painter); return painter; } /** * Create a new colored tiling pattern. Variables xstep and ystep are set to the same values * of width and height. * @param width the width of the pattern * @param height the height of the pattern * @return the PdfPatternPainter where the pattern will be created */ public PdfPatternPainter createPattern(float width, float height) { return createPattern(width, height, width, height); } /** * Create a new uncolored tiling pattern. * * @param width the width of the pattern * @param height the height of the pattern * @param xstep the desired horizontal spacing between pattern cells. * May be either positive or negative, but not zero. * @param ystep the desired vertical spacing between pattern cells. * May be either positive or negative, but not zero. * @param color the default color. Can be null * @return the PdfPatternPainter where the pattern will be created */ public PdfPatternPainter createPattern(float width, float height, float xstep, float ystep, Color color) { checkWriter(); if ( xstep == 0.0f || ystep == 0.0f ) throw new RuntimeException("XStep or YStep can not be ZERO."); PdfPatternPainter painter = new PdfPatternPainter(writer, color); painter.setWidth(width); painter.setHeight(height); painter.setXStep(xstep); painter.setYStep(ystep); writer.addSimplePattern(painter); return painter; } /** * Create a new uncolored tiling pattern. * Variables xstep and ystep are set to the same values * of width and height. * @param width the width of the pattern * @param height the height of the pattern * @param color the default color. Can be null * @return the PdfPatternPainter where the pattern will be created */ public PdfPatternPainter createPattern(float width, float height, Color color) { return createPattern(width, height, width, height, color); } /** * Creates a new template. *

* Creates a new template that is nothing more than a form XObject. This template can be included * in this PdfContentByte or in another template. Templates are only written * to the output when the document is closed permitting things like showing text in the first page * that is only defined in the last page. * * @param width the bounding box width * @param height the bounding box height * @return the created template */ public PdfTemplate createTemplate(float width, float height) { return createTemplate(width, height, null); } PdfTemplate createTemplate(float width, float height, PdfName forcedName) { checkWriter(); PdfTemplate template = new PdfTemplate(writer); template.setWidth(width); template.setHeight(height); writer.addDirectTemplateSimple(template, forcedName); return template; } /** * Creates a new appearance to be used with form fields. * * @param width the bounding box width * @param height the bounding box height * @return the appearance created */ public PdfAppearance createAppearance(float width, float height) { return createAppearance(width, height, null); } PdfAppearance createAppearance(float width, float height, PdfName forcedName) { checkWriter(); PdfAppearance template = new PdfAppearance(writer); template.setWidth(width); template.setHeight(height); writer.addDirectTemplateSimple(template, forcedName); return template; } /** * Adds a PostScript XObject to this content. * * @param psobject the object */ public void addPSXObject(PdfPSXObject psobject) { checkWriter(); PdfName name = writer.addDirectTemplateSimple(psobject, null); PageResources prs = getPageResources(); name = prs.addXObject(name, psobject.getIndirectReference()); content.append(name.getBytes()).append(" Do").append_i(separator); } /** * Adds a template to this content. * * @param template the template * @param a an element of the transformation matrix * @param b an element of the transformation matrix * @param c an element of the transformation matrix * @param d an element of the transformation matrix * @param e an element of the transformation matrix * @param f an element of the transformation matrix */ public void addTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) { checkWriter(); checkNoPattern(template); PdfName name = writer.addDirectTemplateSimple(template, null); PageResources prs = getPageResources(); name = prs.addXObject(name, template.getIndirectReference()); content.append("q "); content.append(a).append(' '); content.append(b).append(' '); content.append(c).append(' '); content.append(d).append(' '); content.append(e).append(' '); content.append(f).append(" cm "); content.append(name.getBytes()).append(" Do Q").append_i(separator); } void addTemplateReference(PdfIndirectReference template, PdfName name, float a, float b, float c, float d, float e, float f) { checkWriter(); PageResources prs = getPageResources(); name = prs.addXObject(name, template); content.append("q "); content.append(a).append(' '); content.append(b).append(' '); content.append(c).append(' '); content.append(d).append(' '); content.append(e).append(' '); content.append(f).append(" cm "); content.append(name.getBytes()).append(" Do Q").append_i(separator); } /** * Adds a template to this content. * * @param template the template * @param x the x location of this template * @param y the y location of this template */ public void addTemplate(PdfTemplate template, float x, float y) { addTemplate(template, 1, 0, 0, 1, x, y); } /** * Changes the current color for filling paths (device dependent colors!). *

* Sets the color space to DeviceCMYK (or the DefaultCMYK color space), * and sets the color to use for filling paths.

*

* This method is described in the 'Portable Document Format Reference Manual version 1.3' * section 8.5.2.1 (page 331).

*

* Following the PDF manual, each operand must be a number between 0 (no ink) and * 1 (maximum ink). This method however accepts only integers between 0x00 and 0xFF.

* * @param cyan the intensity of cyan * @param magenta the intensity of magenta * @param yellow the intensity of yellow * @param black the intensity of black */ public void setCMYKColorFill(int cyan, int magenta, int yellow, int black) { content.append((float)(cyan & 0xFF) / 0xFF); content.append(' '); content.append((float)(magenta & 0xFF) / 0xFF); content.append(' '); content.append((float)(yellow & 0xFF) / 0xFF); content.append(' '); content.append((float)(black & 0xFF) / 0xFF); content.append(" k").append_i(separator); } /** * Changes the current color for stroking paths (device dependent colors!). *

* Sets the color space to DeviceCMYK (or the DefaultCMYK color space), * and sets the color to use for stroking paths.

*

* This method is described in the 'Portable Document Format Reference Manual version 1.3' * section 8.5.2.1 (page 331).

* Following the PDF manual, each operand must be a number between 0 (minimum intensity) and * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF. * * @param cyan the intensity of red * @param magenta the intensity of green * @param yellow the intensity of blue * @param black the intensity of black */ public void setCMYKColorStroke(int cyan, int magenta, int yellow, int black) { content.append((float)(cyan & 0xFF) / 0xFF); content.append(' '); content.append((float)(magenta & 0xFF) / 0xFF); content.append(' '); content.append((float)(yellow & 0xFF) / 0xFF); content.append(' '); content.append((float)(black & 0xFF) / 0xFF); content.append(" K").append_i(separator); } /** * Changes the current color for filling paths (device dependent colors!). *

* Sets the color space to DeviceRGB (or the DefaultRGB color space), * and sets the color to use for filling paths.

*

* This method is described in the 'Portable Document Format Reference Manual version 1.3' * section 8.5.2.1 (page 331).

*

* Following the PDF manual, each operand must be a number between 0 (minimum intensity) and * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF.

* * @param red the intensity of red * @param green the intensity of green * @param blue the intensity of blue */ public void setRGBColorFill(int red, int green, int blue) { HelperRGB((float)(red & 0xFF) / 0xFF, (float)(green & 0xFF) / 0xFF, (float)(blue & 0xFF) / 0xFF); content.append(" rg").append_i(separator); } /** * Changes the current color for stroking paths (device dependent colors!). *

* Sets the color space to DeviceRGB (or the DefaultRGB color space), * and sets the color to use for stroking paths.

*

* This method is described in the 'Portable Document Format Reference Manual version 1.3' * section 8.5.2.1 (page 331).

* Following the PDF manual, each operand must be a number between 0 (minimum intensity) and * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF. * * @param red the intensity of red * @param green the intensity of green * @param blue the intensity of blue */ public void setRGBColorStroke(int red, int green, int blue) { HelperRGB((float)(red & 0xFF) / 0xFF, (float)(green & 0xFF) / 0xFF, (float)(blue & 0xFF) / 0xFF); content.append(" RG").append_i(separator); } /** Sets the stroke color. color can be an * ExtendedColor. * @param color the color */ public void setColorStroke(Color color) { PdfXConformanceImp.checkPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, color); int type = ExtendedColor.getType(color); switch (type) { case ExtendedColor.TYPE_GRAY: { setGrayStroke(((GrayColor)color).getGray()); break; } case ExtendedColor.TYPE_CMYK: { CMYKColor cmyk = (CMYKColor)color; setCMYKColorStrokeF(cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()); break; } case ExtendedColor.TYPE_SEPARATION: { SpotColor spot = (SpotColor)color; setColorStroke(spot.getPdfSpotColor(), spot.getTint()); break; } case ExtendedColor.TYPE_PATTERN: { PatternColor pat = (PatternColor) color; setPatternStroke(pat.getPainter()); break; } case ExtendedColor.TYPE_SHADING: { ShadingColor shading = (ShadingColor) color; setShadingStroke(shading.getPdfShadingPattern()); break; } default: setRGBColorStroke(color.getRed(), color.getGreen(), color.getBlue()); } } /** Sets the fill color. color can be an * ExtendedColor. * @param color the color */ public void setColorFill(Color color) { PdfXConformanceImp.checkPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, color); int type = ExtendedColor.getType(color); switch (type) { case ExtendedColor.TYPE_GRAY: { setGrayFill(((GrayColor)color).getGray()); break; } case ExtendedColor.TYPE_CMYK: { CMYKColor cmyk = (CMYKColor)color; setCMYKColorFillF(cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()); break; } case ExtendedColor.TYPE_SEPARATION: { SpotColor spot = (SpotColor)color; setColorFill(spot.getPdfSpotColor(), spot.getTint()); break; } case ExtendedColor.TYPE_PATTERN: { PatternColor pat = (PatternColor) color; setPatternFill(pat.getPainter()); break; } case ExtendedColor.TYPE_SHADING: { ShadingColor shading = (ShadingColor) color; setShadingFill(shading.getPdfShadingPattern()); break; } default: setRGBColorFill(color.getRed(), color.getGreen(), color.getBlue()); } } /** Sets the fill color to a spot color. * @param sp the spot color * @param tint the tint for the spot color. 0 is no color and 1 * is 100% color */ public void setColorFill(PdfSpotColor sp, float tint) { checkWriter(); state.colorDetails = writer.addSimple(sp); PageResources prs = getPageResources(); PdfName name = state.colorDetails.getColorName(); name = prs.addColor(name, state.colorDetails.getIndirectReference()); content.append(name.getBytes()).append(" cs ").append(tint).append(" scn").append_i(separator); } /** Sets the stroke color to a spot color. * @param sp the spot color * @param tint the tint for the spot color. 0 is no color and 1 * is 100% color */ public void setColorStroke(PdfSpotColor sp, float tint) { checkWriter(); state.colorDetails = writer.addSimple(sp); PageResources prs = getPageResources(); PdfName name = state.colorDetails.getColorName(); name = prs.addColor(name, state.colorDetails.getIndirectReference()); content.append(name.getBytes()).append(" CS ").append(tint).append(" SCN").append_i(separator); } /** Sets the fill color to a pattern. The pattern can be * colored or uncolored. * @param p the pattern */ public void setPatternFill(PdfPatternPainter p) { if (p.isStencil()) { setPatternFill(p, p.getDefaultColor()); return; } checkWriter(); PageResources prs = getPageResources(); PdfName name = writer.addSimplePattern(p); name = prs.addPattern(name, p.getIndirectReference()); content.append(PdfName.PATTERN.getBytes()).append(" cs ").append(name.getBytes()).append(" scn").append_i(separator); } /** Outputs the color values to the content. * @param color The color * @param tint the tint if it is a spot color, ignored otherwise */ void outputColorNumbers(Color color, float tint) { PdfXConformanceImp.checkPDFXConformance(writer, PdfXConformanceImp.PDFXKEY_COLOR, color); int type = ExtendedColor.getType(color); switch (type) { case ExtendedColor.TYPE_RGB: content.append((float)(color.getRed()) / 0xFF); content.append(' '); content.append((float)(color.getGreen()) / 0xFF); content.append(' '); content.append((float)(color.getBlue()) / 0xFF); break; case ExtendedColor.TYPE_GRAY: content.append(((GrayColor)color).getGray()); break; case ExtendedColor.TYPE_CMYK: { CMYKColor cmyk = (CMYKColor)color; content.append(cmyk.getCyan()).append(' ').append(cmyk.getMagenta()); content.append(' ').append(cmyk.getYellow()).append(' ').append(cmyk.getBlack()); break; } case ExtendedColor.TYPE_SEPARATION: content.append(tint); break; default: throw new RuntimeException("Invalid color type."); } } /** Sets the fill color to an uncolored pattern. * @param p the pattern * @param color the color of the pattern */ public void setPatternFill(PdfPatternPainter p, Color color) { if (ExtendedColor.getType(color) == ExtendedColor.TYPE_SEPARATION) setPatternFill(p, color, ((SpotColor)color).getTint()); else setPatternFill(p, color, 0); } /** Sets the fill color to an uncolored pattern. * @param p the pattern * @param color the color of the pattern * @param tint the tint if the color is a spot color, ignored otherwise */ public void setPatternFill(PdfPatternPainter p, Color color, float tint) { checkWriter(); if (!p.isStencil()) throw new RuntimeException("An uncolored pattern was expected."); PageResources prs = getPageResources(); PdfName name = writer.addSimplePattern(p); name = prs.addPattern(name, p.getIndirectReference()); ColorDetails csDetail = writer.addSimplePatternColorspace(color); PdfName cName = prs.addColor(csDetail.getColorName(), csDetail.getIndirectReference()); content.append(cName.getBytes()).append(" cs").append_i(separator); outputColorNumbers(color, tint); content.append(' ').append(name.getBytes()).append(" scn").append_i(separator); } /** Sets the stroke color to an uncolored pattern. * @param p the pattern * @param color the color of the pattern */ public void setPatternStroke(PdfPatternPainter p, Color color) { if (ExtendedColor.getType(color) == ExtendedColor.TYPE_SEPARATION) setPatternStroke(p, color, ((SpotColor)color).getTint()); else setPatternStroke(p, color, 0); } /** Sets the stroke color to an uncolored pattern. * @param p the pattern * @param color the color of the pattern * @param tint the tint if the color is a spot color, ignored otherwise */ public void setPatternStroke(PdfPatternPainter p, Color color, float tint) { checkWriter(); if (!p.isStencil()) throw new RuntimeException("An uncolored pattern was expected."); PageResources prs = getPageResources(); PdfName name = writer.addSimplePattern(p); name = prs.addPattern(name, p.getIndirectReference()); ColorDetails csDetail = writer.addSimplePatternColorspace(color); PdfName cName = prs.addColor(csDetail.getColorName(), csDetail.getIndirectReference()); content.append(cName.getBytes()).append(" CS").append_i(separator); outputColorNumbers(color, tint); content.append(' ').append(name.getBytes()).append(" SCN").append_i(separator); } /** Sets the stroke color to a pattern. The pattern can be * colored or uncolored. * @param p the pattern */ public void setPatternStroke(PdfPatternPainter p) { if (p.isStencil()) { setPatternStroke(p, p.getDefaultColor()); return; } checkWriter(); PageResources prs = getPageResources(); PdfName name = writer.addSimplePattern(p); name = prs.addPattern(name, p.getIndirectReference()); content.append(PdfName.PATTERN.getBytes()).append(" CS ").append(name.getBytes()).append(" SCN").append_i(separator); } /** * Paints using a shading object. * @param shading the shading object */ public void paintShading(PdfShading shading) { writer.addSimpleShading(shading); PageResources prs = getPageResources(); PdfName name = prs.addShading(shading.getShadingName(), shading.getShadingReference()); content.append(name.getBytes()).append(" sh").append_i(separator); ColorDetails details = shading.getColorDetails(); if (details != null) prs.addColor(details.getColorName(), details.getIndirectReference()); } /** * Paints using a shading pattern. * @param shading the shading pattern */ public void paintShading(PdfShadingPattern shading) { paintShading(shading.getShading()); } /** * Sets the shading fill pattern. * @param shading the shading pattern */ public void setShadingFill(PdfShadingPattern shading) { writer.addSimpleShadingPattern(shading); PageResources prs = getPageResources(); PdfName name = prs.addPattern(shading.getPatternName(), shading.getPatternReference()); content.append(PdfName.PATTERN.getBytes()).append(" cs ").append(name.getBytes()).append(" scn").append_i(separator); ColorDetails details = shading.getColorDetails(); if (details != null) prs.addColor(details.getColorName(), details.getIndirectReference()); } /** * Sets the shading stroke pattern * @param shading the shading pattern */ public void setShadingStroke(PdfShadingPattern shading) { writer.addSimpleShadingPattern(shading); PageResources prs = getPageResources(); PdfName name = prs.addPattern(shading.getPatternName(), shading.getPatternReference()); content.append(PdfName.PATTERN.getBytes()).append(" CS ").append(name.getBytes()).append(" SCN").append_i(separator); ColorDetails details = shading.getColorDetails(); if (details != null) prs.addColor(details.getColorName(), details.getIndirectReference()); } /** Check if we have a valid PdfWriter. * */ protected void checkWriter() { if (writer == null) throw new NullPointerException("The writer in PdfContentByte is null."); } /** * Show an array of text. * @param text array of text */ public void showText(PdfTextArray text) { if (state.fontDetails == null) throw new NullPointerException("Font and size must be set before writing any text"); content.append("["); ArrayList arrayList = text.getArrayList(); boolean lastWasNumber = false; for (int k = 0; k < arrayList.size(); ++k) { Object obj = arrayList.get(k); if (obj instanceof String) { showText2((String)obj); lastWasNumber = false; } else { if (lastWasNumber) content.append(' '); else lastWasNumber = true; content.append(((Float)obj).floatValue()); } } content.append("]TJ").append_i(separator); } /** * Gets the PdfWriter in use by this object. * @return the PdfWriter in use by this object */ public PdfWriter getPdfWriter() { return writer; } /** * Gets the PdfDocument in use by this object. * @return the PdfDocument in use by this object */ public PdfDocument getPdfDocument() { return pdf; } /** * Implements a link to other part of the document. The jump will * be made to a local destination with the same name, that must exist. * @param name the name for this link * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ public void localGoto(String name, float llx, float lly, float urx, float ury) { pdf.localGoto(name, llx, lly, urx, ury); } /** * The local destination to where a local goto with the same * name will jump. * @param name the name of this local destination * @param destination the PdfDestination with the jump coordinates * @return true if the local destination was added, * false if a local destination with the same name * already exists */ public boolean localDestination(String name, PdfDestination destination) { return pdf.localDestination(name, destination); } /** * Gets a duplicate of this PdfContentByte. All * the members are copied by reference but the buffer stays different. * * @return a copy of this PdfContentByte */ public PdfContentByte getDuplicate() { return new PdfContentByte(writer); } /** * Implements a link to another document. * @param filename the filename for the remote document * @param name the name to jump to * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ public void remoteGoto(String filename, String name, float llx, float lly, float urx, float ury) { pdf.remoteGoto(filename, name, llx, lly, urx, ury); } /** * Implements a link to another document. * @param filename the filename for the remote document * @param page the page to jump to * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ public void remoteGoto(String filename, int page, float llx, float lly, float urx, float ury) { pdf.remoteGoto(filename, page, llx, lly, urx, ury); } /** * Adds a round rectangle to the current path. * * @param x x-coordinate of the starting point * @param y y-coordinate of the starting point * @param w width * @param h height * @param r radius of the arc corner */ public void roundRectangle(float x, float y, float w, float h, float r) { if (w < 0) { x += w; w = -w; } if (h < 0) { y += h; h = -h; } if (r < 0) r = -r; float b = 0.4477f; moveTo(x + r, y); lineTo(x + w - r, y); curveTo(x + w - r * b, y, x + w, y + r * b, x + w, y + r); lineTo(x + w, y + h - r); curveTo(x + w, y + h - r * b, x + w - r * b, y + h, x + w - r, y + h); lineTo(x + r, y + h); curveTo(x + r * b, y + h, x, y + h - r * b, x, y + h - r); lineTo(x, y + r); curveTo(x, y + r * b, x + r * b, y, x + r, y); } /** Implements an action in an area. * @param action the PdfAction * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ public void setAction(PdfAction action, float llx, float lly, float urx, float ury) { pdf.setAction(action, llx, lly, urx, ury); } /** Outputs a String directly to the content. * @param s the String */ public void setLiteral(String s) { content.append(s); } /** Outputs a char directly to the content. * @param c the char */ public void setLiteral(char c) { content.append(c); } /** Outputs a float directly to the content. * @param n the float */ public void setLiteral(float n) { content.append(n); } /** Throws an error if it is a pattern. * @param t the object to check */ void checkNoPattern(PdfTemplate t) { if (t.getType() == PdfTemplate.TYPE_PATTERN) throw new RuntimeException("Invalid use of a pattern. A template was expected."); } /** * Draws a TextField. * @param llx * @param lly * @param urx * @param ury * @param on */ public void drawRadioField(float llx, float lly, float urx, float ury, boolean on) { if (llx > urx) { float x = llx; llx = urx; urx = x; } if (lly > ury) { float y = lly; lly = ury; ury = y; } // silver circle setLineWidth(1); setLineCap(1); setColorStroke(new Color(0xC0, 0xC0, 0xC0)); arc(llx + 1f, lly + 1f, urx - 1f, ury - 1f, 0f, 360f); stroke(); // gray circle-segment setLineWidth(1); setLineCap(1); setColorStroke(new Color(0xA0, 0xA0, 0xA0)); arc(llx + 0.5f, lly + 0.5f, urx - 0.5f, ury - 0.5f, 45, 180); stroke(); // black circle-segment setLineWidth(1); setLineCap(1); setColorStroke(new Color(0x00, 0x00, 0x00)); arc(llx + 1.5f, lly + 1.5f, urx - 1.5f, ury - 1.5f, 45, 180); stroke(); if (on) { // gray circle setLineWidth(1); setLineCap(1); setColorFill(new Color(0x00, 0x00, 0x00)); arc(llx + 4f, lly + 4f, urx - 4f, ury - 4f, 0, 360); fill(); } } /** * Draws a TextField. * @param llx * @param lly * @param urx * @param ury */ public void drawTextField(float llx, float lly, float urx, float ury) { if (llx > urx) { float x = llx; llx = urx; urx = x; } if (lly > ury) { float y = lly; lly = ury; ury = y; } // silver rectangle not filled setColorStroke(new Color(0xC0, 0xC0, 0xC0)); setLineWidth(1); setLineCap(0); rectangle(llx, lly, urx - llx, ury - lly); stroke(); // white rectangle filled setLineWidth(1); setLineCap(0); setColorFill(new Color(0xFF, 0xFF, 0xFF)); rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f); fill(); // silver lines setColorStroke(new Color(0xC0, 0xC0, 0xC0)); setLineWidth(1); setLineCap(0); moveTo(llx + 1f, lly + 1.5f); lineTo(urx - 1.5f, lly + 1.5f); lineTo(urx - 1.5f, ury - 1f); stroke(); // gray lines setColorStroke(new Color(0xA0, 0xA0, 0xA0)); setLineWidth(1); setLineCap(0); moveTo(llx + 1f, lly + 1); lineTo(llx + 1f, ury - 1f); lineTo(urx - 1f, ury - 1f); stroke(); // black lines setColorStroke(new Color(0x00, 0x00, 0x00)); setLineWidth(1); setLineCap(0); moveTo(llx + 2f, lly + 2f); lineTo(llx + 2f, ury - 2f); lineTo(urx - 2f, ury - 2f); stroke(); } /** * Draws a button. * @param llx * @param lly * @param urx * @param ury * @param text * @param bf * @param size */ public void drawButton(float llx, float lly, float urx, float ury, String text, BaseFont bf, float size) { if (llx > urx) { float x = llx; llx = urx; urx = x; } if (lly > ury) { float y = lly; lly = ury; ury = y; } // black rectangle not filled setColorStroke(new Color(0x00, 0x00, 0x00)); setLineWidth(1); setLineCap(0); rectangle(llx, lly, urx - llx, ury - lly); stroke(); // silver rectangle filled setLineWidth(1); setLineCap(0); setColorFill(new Color(0xC0, 0xC0, 0xC0)); rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f); fill(); // white lines setColorStroke(new Color(0xFF, 0xFF, 0xFF)); setLineWidth(1); setLineCap(0); moveTo(llx + 1f, lly + 1f); lineTo(llx + 1f, ury - 1f); lineTo(urx - 1f, ury - 1f); stroke(); // dark grey lines setColorStroke(new Color(0xA0, 0xA0, 0xA0)); setLineWidth(1); setLineCap(0); moveTo(llx + 1f, lly + 1f); lineTo(urx - 1f, lly + 1f); lineTo(urx - 1f, ury - 1f); stroke(); // text resetRGBColorFill(); beginText(); setFontAndSize(bf, size); showTextAligned(PdfContentByte.ALIGN_CENTER, text, llx + (urx - llx) / 2, lly + (ury - lly - size) / 2, 0); endText(); } /** Gets a Graphics2D to write on. The graphics * are translated to PDF commands as shapes. No PDF fonts will appear. * @param width the width of the panel * @param height the height of the panel * @return a Graphics2D */ public java.awt.Graphics2D createGraphicsShapes(float width, float height) { return new PdfGraphics2D(this, width, height, null, true, false, 0); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands as shapes. No PDF fonts will appear. * @param width the width of the panel * @param height the height of the panel * @param printerJob a printer job * @return a Graphics2D */ public java.awt.Graphics2D createPrinterGraphicsShapes(float width, float height, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, null, true, false, 0, printerJob); } /** Gets a Graphics2D to write on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @return a Graphics2D */ public java.awt.Graphics2D createGraphics(float width, float height) { return new PdfGraphics2D(this, width, height, null, false, false, 0); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param printerJob * @return a Graphics2D */ public java.awt.Graphics2D createPrinterGraphics(float width, float height, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, null, false, false, 0, printerJob); } /** Gets a Graphics2D to write on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param convertImagesToJPEG * @param quality * @return a Graphics2D */ public java.awt.Graphics2D createGraphics(float width, float height, boolean convertImagesToJPEG, float quality) { return new PdfGraphics2D(this, width, height, null, false, convertImagesToJPEG, quality); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param convertImagesToJPEG * @param quality * @param printerJob * @return a Graphics2D */ public java.awt.Graphics2D createPrinterGraphics(float width, float height, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, null, false, convertImagesToJPEG, quality, printerJob); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width * @param height * @param convertImagesToJPEG * @param quality * @return A Graphics2D object */ public java.awt.Graphics2D createGraphicsShapes(float width, float height, boolean convertImagesToJPEG, float quality) { return new PdfGraphics2D(this, width, height, null, true, convertImagesToJPEG, quality); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width * @param height * @param convertImagesToJPEG * @param quality * @param printerJob * @return a Graphics2D object */ public java.awt.Graphics2D createPrinterGraphicsShapes(float width, float height, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, null, true, convertImagesToJPEG, quality, printerJob); } /** Gets a Graphics2D to write on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param fontMapper the mapping from awt fonts to BaseFont * @return a Graphics2D */ public java.awt.Graphics2D createGraphics(float width, float height, FontMapper fontMapper) { return new PdfGraphics2D(this, width, height, fontMapper, false, false, 0); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param fontMapper the mapping from awt fonts to BaseFont * @param printerJob a printer job * @return a Graphics2D */ public java.awt.Graphics2D createPrinterGraphics(float width, float height, FontMapper fontMapper, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, fontMapper, false, false, 0, printerJob); } /** Gets a Graphics2D to write on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param fontMapper the mapping from awt fonts to BaseFont * @param convertImagesToJPEG converts awt images to jpeg before inserting in pdf * @param quality the quality of the jpeg * @return a Graphics2D */ public java.awt.Graphics2D createGraphics(float width, float height, FontMapper fontMapper, boolean convertImagesToJPEG, float quality) { return new PdfGraphics2D(this, width, height, fontMapper, false, convertImagesToJPEG, quality); } /** Gets a Graphics2D to print on. The graphics * are translated to PDF commands. * @param width the width of the panel * @param height the height of the panel * @param fontMapper the mapping from awt fonts to BaseFont * @param convertImagesToJPEG converts awt images to jpeg before inserting in pdf * @param quality the quality of the jpeg * @param printerJob a printer job * @return a Graphics2D */ public java.awt.Graphics2D createPrinterGraphics(float width, float height, FontMapper fontMapper, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { return new PdfPrinterGraphics2D(this, width, height, fontMapper, false, convertImagesToJPEG, quality, printerJob); } PageResources getPageResources() { return pdf.getPageResources(); } /** Sets the graphic state * @param gstate the graphic state */ public void setGState(PdfGState gstate) { PdfObject obj[] = writer.addSimpleExtGState(gstate); PageResources prs = getPageResources(); PdfName name = prs.addExtGState((PdfName)obj[0], (PdfIndirectReference)obj[1]); content.append(name.getBytes()).append(" gs").append_i(separator); } /** * Begins a graphic block whose visibility is controlled by the layer. * Blocks can be nested. Each block must be terminated by an {@link #endLayer()}.

* Note that nested layers with {@link PdfLayer#addChild(PdfLayer)} only require a single * call to this method and a single call to {@link #endLayer()}; all the nesting control * is built in. * @param layer the layer */ public void beginLayer(PdfOCG layer) { if ((layer instanceof PdfLayer) && ((PdfLayer)layer).getTitle() != null) throw new IllegalArgumentException("A title is not a layer"); if (layerDepth == null) layerDepth = new ArrayList(); if (layer instanceof PdfLayerMembership) { layerDepth.add(new Integer(1)); beginLayer2(layer); return; } int n = 0; PdfLayer la = (PdfLayer)layer; while (la != null) { if (la.getTitle() == null) { beginLayer2(la); ++n; } la = la.getParent(); } layerDepth.add(new Integer(n)); } private void beginLayer2(PdfOCG layer) { PdfName name = (PdfName)writer.addSimpleProperty(layer, layer.getRef())[0]; PageResources prs = getPageResources(); name = prs.addProperty(name, layer.getRef()); content.append("/OC ").append(name.getBytes()).append(" BDC").append_i(separator); } /** * Ends a layer controlled graphic block. It will end the most recent open block. */ public void endLayer() { int n = 1; if (layerDepth != null && !layerDepth.isEmpty()) { n = ((Integer)layerDepth.get(layerDepth.size() - 1)).intValue(); layerDepth.remove(layerDepth.size() - 1); } else { throw new IllegalPdfSyntaxException("Unbalanced layer operators." ); } while (n-- > 0) content.append("EMC").append_i(separator); } /** Concatenates a transformation to the current transformation * matrix. * @param af the transformation */ public void transform(AffineTransform af) { double arr[] = new double[6]; af.getMatrix(arr); content.append(arr[0]).append(' ').append(arr[1]).append(' ').append(arr[2]).append(' '); content.append(arr[3]).append(' ').append(arr[4]).append(' ').append(arr[5]).append(" cm").append_i(separator); } void addAnnotation(PdfAnnotation annot) { writer.addAnnotation(annot); } /** * Sets the default colorspace. * @param name the name of the colorspace. It can be PdfName.DEFAULTGRAY, PdfName.DEFAULTRGB * or PdfName.DEFAULTCMYK * @param obj the colorspace. A null or PdfNull removes any colorspace with the same name */ public void setDefaultColorspace(PdfName name, PdfObject obj) { PageResources prs = getPageResources(); prs.addDefaultColor(name, obj); } /** * Begins a marked content sequence. This sequence will be tagged with the structure struc. * The same structure can be used several times to connect text that belongs to the same logical segment * but is in a different location, like the same paragraph crossing to another page, for example. * @param struc the tagging structure */ public void beginMarkedContentSequence(PdfStructureElement struc) { PdfObject obj = struc.get(PdfName.K); int mark = pdf.getMarkPoint(); if (obj != null) { PdfArray ar = null; if (obj.isNumber()) { ar = new PdfArray(); ar.add(obj); struc.put(PdfName.K, ar); } else if (obj.isArray()) { ar = (PdfArray)obj; if (!(ar.getPdfObject(0)).isNumber()) throw new IllegalArgumentException("The structure has kids."); } else throw new IllegalArgumentException("Unknown object at /K " + obj.getClass().toString()); PdfDictionary dic = new PdfDictionary(PdfName.MCR); dic.put(PdfName.PG, writer.getCurrentPage()); dic.put(PdfName.MCID, new PdfNumber(mark)); ar.add(dic); struc.setPageMark(writer.getPageNumber() - 1, -1); } else { struc.setPageMark(writer.getPageNumber() - 1, mark); struc.put(PdfName.PG, writer.getCurrentPage()); } pdf.incMarkPoint(); mcDepth++; content.append(struc.get(PdfName.S).getBytes()).append(" <> BDC").append_i(separator); } /** * Ends a marked content sequence */ public void endMarkedContentSequence() { if (mcDepth == 0) { throw new IllegalPdfSyntaxException("Unbalanced begin/end marked content operators." ); } --mcDepth; content.append("EMC").append_i(separator); } /** * Begins a marked content sequence. If property is null the mark will be of the type * BMC otherwise it will be BDC. * @param tag the tag * @param property the property * @param inline true to include the property in the content or false * to include the property in the resource dictionary with the possibility of reusing */ public void beginMarkedContentSequence(PdfName tag, PdfDictionary property, boolean inline) { if (property == null) { content.append(tag.getBytes()).append(" BMC").append_i(separator); return; } content.append(tag.getBytes()).append(' '); if (inline) try { property.toPdf(writer, content); } catch (Exception e) { throw new ExceptionConverter(e); } else { PdfObject[] objs; if (writer.propertyExists(property)) objs = writer.addSimpleProperty(property, null); else objs = writer.addSimpleProperty(property, writer.getPdfIndirectReference()); PdfName name = (PdfName)objs[0]; PageResources prs = getPageResources(); name = prs.addProperty(name, (PdfIndirectReference)objs[1]); content.append(name.getBytes()); } content.append(" BDC").append_i(separator); ++mcDepth; } /** * This is just a shorthand to beginMarkedContentSequence(tag, null, false). * @param tag the tag */ public void beginMarkedContentSequence(PdfName tag) { beginMarkedContentSequence(tag, null, false); } /** * Checks for any dangling state: Mismatched save/restore state, begin/end text, * begin/end layer, or begin/end marked content sequence. * If found, this function will throw. This function is called automatically * during a reset() (from Document.newPage() for example), and before writing * itself out in toPdf(). * One possible cause: not calling myPdfGraphics2D.dispose() will leave dangling * saveState() calls. * @since 2.1.6 * @throws IllegalPdfSyntaxException (a runtime exception) */ public void sanityCheck() { if (mcDepth != 0) { throw new IllegalPdfSyntaxException("Unbalanced marked content operators." ); } if (inText) { throw new IllegalPdfSyntaxException("Unbalanced begin/end text operators." ); } if (layerDepth != null && !layerDepth.isEmpty()) { throw new IllegalPdfSyntaxException("Unbalanced layer operators." ); } if (!stateList.isEmpty()) { throw new IllegalPdfSyntaxException("Unbalanced save/restore state operators." ); } } } src/core/com/lowagie/text/pdf/PdfContentParser.java100644 0 0 17057 11000354131 17770 0ustar 0 0 /* * $Id: PdfContentParser.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.ArrayList; /** * Parses the page or template content. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfContentParser { /** * Commands have this type. */ public static final int COMMAND_TYPE = 200; /** * Holds value of property tokeniser. */ private PRTokeniser tokeniser; /** * Creates a new instance of PdfContentParser * @param tokeniser the tokeniser with the content */ public PdfContentParser(PRTokeniser tokeniser) { this.tokeniser = tokeniser; } /** * Parses a single command from the content. Each command is output as an array of arguments * having the command itself as the last element. The returned array will be empty if the * end of content was reached. * @param ls an ArrayList to use. It will be cleared before using. If it's * null will create a new ArrayList * @return the same ArrayList given as argument or a new one * @throws IOException on error */ public ArrayList parse(ArrayList ls) throws IOException { if (ls == null) ls = new ArrayList(); else ls.clear(); PdfObject ob = null; while ((ob = readPRObject()) != null) { ls.add(ob); if (ob.type() == COMMAND_TYPE) break; } return ls; } /** * Gets the tokeniser. * @return the tokeniser. */ public PRTokeniser getTokeniser() { return this.tokeniser; } /** * Sets the tokeniser. * @param tokeniser the tokeniser */ public void setTokeniser(PRTokeniser tokeniser) { this.tokeniser = tokeniser; } /** * Reads a dictionary. The tokeniser must be positioned past the "<<" token. * @return the dictionary * @throws IOException on error */ public PdfDictionary readDictionary() throws IOException { PdfDictionary dic = new PdfDictionary(); while (true) { if (!nextValidToken()) throw new IOException("Unexpected end of file."); if (tokeniser.getTokenType() == PRTokeniser.TK_END_DIC) break; if (tokeniser.getTokenType() != PRTokeniser.TK_NAME) throw new IOException("Dictionary key is not a name."); PdfName name = new PdfName(tokeniser.getStringValue(), false); PdfObject obj = readPRObject(); int type = obj.type(); if (-type == PRTokeniser.TK_END_DIC) throw new IOException("Unexpected '>>'"); if (-type == PRTokeniser.TK_END_ARRAY) throw new IOException("Unexpected ']'"); dic.put(name, obj); } return dic; } /** * Reads an array. The tokeniser must be positioned past the "[" token. * @return an array * @throws IOException on error */ public PdfArray readArray() throws IOException { PdfArray array = new PdfArray(); while (true) { PdfObject obj = readPRObject(); int type = obj.type(); if (-type == PRTokeniser.TK_END_ARRAY) break; if (-type == PRTokeniser.TK_END_DIC) throw new IOException("Unexpected '>>'"); array.add(obj); } return array; } /** * Reads a pdf object. * @return the pdf object * @throws IOException on error */ public PdfObject readPRObject() throws IOException { if (!nextValidToken()) return null; int type = tokeniser.getTokenType(); switch (type) { case PRTokeniser.TK_START_DIC: { PdfDictionary dic = readDictionary(); return dic; } case PRTokeniser.TK_START_ARRAY: return readArray(); case PRTokeniser.TK_STRING: PdfString str = new PdfString(tokeniser.getStringValue(), null).setHexWriting(tokeniser.isHexString()); return str; case PRTokeniser.TK_NAME: return new PdfName(tokeniser.getStringValue(), false); case PRTokeniser.TK_NUMBER: return new PdfNumber(tokeniser.getStringValue()); case PRTokeniser.TK_OTHER: return new PdfLiteral(COMMAND_TYPE, tokeniser.getStringValue()); default: return new PdfLiteral(-type, tokeniser.getStringValue()); } } /** * Reads the next token skipping over the comments. * @return true if a token was read, false if the end of content was reached * @throws IOException on error */ public boolean nextValidToken() throws IOException { while (tokeniser.nextToken()) { if (tokeniser.getTokenType() == PRTokeniser.TK_COMMENT) continue; return true; } return false; } }src/core/com/lowagie/text/pdf/PdfContents.java100644 0 0 14631 11154165267 17015 0ustar 0 0 /* * $Id: PdfContents.java 3634 2008-12-23 18:44:04Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.Rectangle; /** * PdfContents is a PdfStream containing the contents (text + graphics) of a PdfPage. */ class PdfContents extends PdfStream { static final byte SAVESTATE[] = DocWriter.getISOBytes("q\n"); static final byte RESTORESTATE[] = DocWriter.getISOBytes("Q\n"); static final byte ROTATE90[] = DocWriter.getISOBytes("0 1 -1 0 "); static final byte ROTATE180[] = DocWriter.getISOBytes("-1 0 0 -1 "); static final byte ROTATE270[] = DocWriter.getISOBytes("0 -1 1 0 "); static final byte ROTATEFINAL[] = DocWriter.getISOBytes(" cm\n"); // constructor /** * Constructs a PdfContents-object, containing text and general graphics. * * @param under the direct content that is under all others * @param content the graphics in a page * @param text the text in a page * @param secondContent the direct content that is over all others * @throws BadPdfFormatException on error */ PdfContents(PdfContentByte under, PdfContentByte content, PdfContentByte text, PdfContentByte secondContent, Rectangle page) throws BadPdfFormatException { super(); try { OutputStream out = null; Deflater deflater = null; streamBytes = new ByteArrayOutputStream(); if (Document.compress) { compressed = true; compressionLevel = text.getPdfWriter().getCompressionLevel(); deflater = new Deflater(compressionLevel); out = new DeflaterOutputStream(streamBytes, deflater); } else out = streamBytes; int rotation = page.getRotation(); switch (rotation) { case 90: out.write(ROTATE90); out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.getTop()))); out.write(' '); out.write('0'); out.write(ROTATEFINAL); break; case 180: out.write(ROTATE180); out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.getRight()))); out.write(' '); out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.getTop()))); out.write(ROTATEFINAL); break; case 270: out.write(ROTATE270); out.write('0'); out.write(' '); out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.getRight()))); out.write(ROTATEFINAL); break; } if (under.size() > 0) { out.write(SAVESTATE); under.getInternalBuffer().writeTo(out); out.write(RESTORESTATE); } if (content.size() > 0) { out.write(SAVESTATE); content.getInternalBuffer().writeTo(out); out.write(RESTORESTATE); } if (text != null) { out.write(SAVESTATE); text.getInternalBuffer().writeTo(out); out.write(RESTORESTATE); } if (secondContent.size() > 0) { secondContent.getInternalBuffer().writeTo(out); } out.close(); if (deflater != null) { deflater.end(); } } catch (Exception e) { throw new BadPdfFormatException(e.getMessage()); } put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); if (compressed) put(PdfName.FILTER, PdfName.FLATEDECODE); } }src/core/com/lowagie/text/pdf/PdfCopy.java100644 0 0 73536 11213370070 16125 0ustar 0 0 /* * $Id: PdfCopy.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright (C) 2002 Mark Thompson * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; import java.util.ArrayList; /** * Make copies of PDF documents. Documents can be edited after reading and * before writing them out. * @author Mark Thompson */ public class PdfCopy extends PdfWriter { /** * This class holds information about indirect references, since they are * renumbered by iText. */ static class IndirectReferences { PdfIndirectReference theRef; boolean hasCopied; IndirectReferences(PdfIndirectReference ref) { theRef = ref; hasCopied = false; } void setCopied() { hasCopied = true; } boolean getCopied() { return hasCopied; } PdfIndirectReference getRef() { return theRef; } }; protected HashMap indirects; protected HashMap indirectMap; protected int currentObjectNum = 1; protected PdfReader reader; protected PdfIndirectReference acroForm; protected int[] namePtr = {0}; /** Holds value of property rotateContents. */ private boolean rotateContents = true; protected PdfArray fieldArray; protected HashMap fieldTemplates; /** * A key to allow us to hash indirect references */ protected static class RefKey { int num; int gen; RefKey(int num, int gen) { this.num = num; this.gen = gen; } RefKey(PdfIndirectReference ref) { num = ref.getNumber(); gen = ref.getGeneration(); } RefKey(PRIndirectReference ref) { num = ref.getNumber(); gen = ref.getGeneration(); } public int hashCode() { return (gen<<16)+num; } public boolean equals(Object o) { if (!(o instanceof RefKey)) return false; RefKey other = (RefKey)o; return this.gen == other.gen && this.num == other.num; } public String toString() { return Integer.toString(num) + ' ' + gen; } } /** * Constructor * @param document * @param os outputstream */ public PdfCopy(Document document, OutputStream os) throws DocumentException { super(new PdfDocument(), os); document.addDocListener(pdf); pdf.addWriter(this); indirectMap = new HashMap(); } /** Getter for property rotateContents. * @return Value of property rotateContents. * */ public boolean isRotateContents() { return this.rotateContents; } /** Setter for property rotateContents. * @param rotateContents New value of property rotateContents. * */ public void setRotateContents(boolean rotateContents) { this.rotateContents = rotateContents; } /** * Grabs a page from the input document * @param reader the reader of the document * @param pageNumber which page to get * @return the page */ public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { if (currentPdfReaderInstance != null) { if (currentPdfReaderInstance.getReader() != reader) { try { currentPdfReaderInstance.getReader().close(); currentPdfReaderInstance.getReaderFile().close(); } catch (IOException ioe) { // empty on purpose } currentPdfReaderInstance = reader.getPdfReaderInstance(this); } } else { currentPdfReaderInstance = reader.getPdfReaderInstance(this); } return currentPdfReaderInstance.getImportedPage(pageNumber); } /** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected PdfIndirectReference copyIndirect(PRIndirectReference in) throws IOException, BadPdfFormatException { PdfIndirectReference theRef; RefKey key = new RefKey(in); IndirectReferences iRef = (IndirectReferences)indirects.get(key); if (iRef != null) { theRef = iRef.getRef(); if (iRef.getCopied()) { return theRef; } } else { theRef = body.getPdfIndirectReference(); iRef = new IndirectReferences(theRef); indirects.put(key, iRef); } PdfObject obj = PdfReader.getPdfObjectRelease(in); if (obj != null && obj.isDictionary()) { PdfObject type = PdfReader.getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.TYPE)); if (type != null && PdfName.PAGE.equals(type)) { return theRef; } } iRef.setCopied(); obj = copyObject(obj); addToBody(obj, theRef); return theRef; } /** * Translate a PRDictionary to a PdfDictionary. Also translate all of the * objects contained in it. */ protected PdfDictionary copyDictionary(PdfDictionary in) throws IOException, BadPdfFormatException { PdfDictionary out = new PdfDictionary(); PdfObject type = PdfReader.getPdfObjectRelease(in.get(PdfName.TYPE)); for (Iterator it = in.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); PdfObject value = in.get(key); // System.out.println("Copy " + key); if (type != null && PdfName.PAGE.equals(type)) { if (!key.equals(PdfName.B) && !key.equals(PdfName.PARENT)) out.put(key, copyObject(value)); } else out.put(key, copyObject(value)); } return out; } /** * Translate a PRStream to a PdfStream. The data part copies itself. */ protected PdfStream copyStream(PRStream in) throws IOException, BadPdfFormatException { PRStream out = new PRStream(in, null); for (Iterator it = in.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName) it.next(); PdfObject value = in.get(key); out.put(key, copyObject(value)); } return out; } /** * Translate a PRArray to a PdfArray. Also translate all of the objects contained * in it */ protected PdfArray copyArray(PdfArray in) throws IOException, BadPdfFormatException { PdfArray out = new PdfArray(); for (Iterator i = in.listIterator(); i.hasNext();) { PdfObject value = (PdfObject)i.next(); out.add(copyObject(value)); } return out; } /** * Translate a PR-object to a Pdf-object */ protected PdfObject copyObject(PdfObject in) throws IOException,BadPdfFormatException { if (in == null) return PdfNull.PDFNULL; switch (in.type) { case PdfObject.DICTIONARY: // System.out.println("Dictionary: " + in.toString()); return copyDictionary((PdfDictionary)in); case PdfObject.INDIRECT: return copyIndirect((PRIndirectReference)in); case PdfObject.ARRAY: return copyArray((PdfArray)in); case PdfObject.NUMBER: case PdfObject.NAME: case PdfObject.STRING: case PdfObject.NULL: case PdfObject.BOOLEAN: case 0: return in; case PdfObject.STREAM: return copyStream((PRStream)in); // return in; default: if (in.type < 0) { String lit = ((PdfLiteral)in).toString(); if (lit.equals("true") || lit.equals("false")) { return new PdfBoolean(lit); } return new PdfLiteral(lit); } System.out.println("CANNOT COPY type " + in.type); return null; } } /** * convenience method. Given an imported page, set our "globals" */ protected int setFromIPage(PdfImportedPage iPage) { int pageNum = iPage.getPageNumber(); PdfReaderInstance inst = currentPdfReaderInstance = iPage.getPdfReaderInstance(); reader = inst.getReader(); setFromReader(reader); return pageNum; } /** * convenience method. Given a reader, set our "globals" */ protected void setFromReader(PdfReader reader) { this.reader = reader; indirects = (HashMap)indirectMap.get(reader); if (indirects == null) { indirects = new HashMap(); indirectMap.put(reader,indirects); PdfDictionary catalog = reader.getCatalog(); PRIndirectReference ref = null; PdfObject o = catalog.get(PdfName.ACROFORM); if (o == null || o.type() != PdfObject.INDIRECT) return; ref = (PRIndirectReference)o; if (acroForm == null) acroForm = body.getPdfIndirectReference(); indirects.put(new RefKey(ref), new IndirectReferences(acroForm)); } } /** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void addPage(PdfImportedPage iPage) throws IOException, BadPdfFormatException { int pageNum = setFromIPage(iPage); PdfDictionary thePage = reader.getPageN(pageNum); PRIndirectReference origRef = reader.getPageOrigRef(pageNum); reader.releasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef = (IndirectReferences)indirects.get(key); if (iRef != null && !iRef.getCopied()) { pageReferences.add(iRef.getRef()); iRef.setCopied(); } pageRef = getCurrentPage(); if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects.put(key, iRef); } iRef.setCopied(); PdfDictionary newPage = copyDictionary(thePage); root.addPage(newPage); ++currentPageNumber; } /** * Adds a blank page. * @param rect The page dimension * @param rotation The rotation angle in degrees * @since 2.1.5 */ public void addPage(Rectangle rect, int rotation) { PdfRectangle mediabox = new PdfRectangle(rect, rotation); PageResources resources = new PageResources(); PdfPage page = new PdfPage(mediabox, new HashMap(), resources.getResources(), 0); page.put(PdfName.TABS, getTabs()); root.addPage(page); ++currentPageNumber; } /** * Copy the acroform for an input document. Note that you can only have one, * we make no effort to merge them. * @param reader The reader of the input file that is being copied * @throws IOException, BadPdfFormatException */ public void copyAcroForm(PdfReader reader) throws IOException, BadPdfFormatException { setFromReader(reader); PdfDictionary catalog = reader.getCatalog(); PRIndirectReference hisRef = null; PdfObject o = catalog.get(PdfName.ACROFORM); if (o != null && o.type() == PdfObject.INDIRECT) hisRef = (PRIndirectReference)o; if (hisRef == null) return; // bugfix by John Englar RefKey key = new RefKey(hisRef); PdfIndirectReference myRef; IndirectReferences iRef = (IndirectReferences)indirects.get(key); if (iRef != null) { acroForm = myRef = iRef.getRef(); } else { acroForm = myRef = body.getPdfIndirectReference(); iRef = new IndirectReferences(myRef); indirects.put(key, iRef); } if (! iRef.getCopied()) { iRef.setCopied(); PdfDictionary theForm = copyDictionary((PdfDictionary)PdfReader.getPdfObject(hisRef)); addToBody(theForm, myRef); } } /* * the getCatalog method is part of PdfWriter. * we wrap this so that we can extend it */ protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { try { PdfDictionary theCat = pdf.getCatalog(rootObj); if (fieldArray == null) { if (acroForm != null) theCat.put(PdfName.ACROFORM, acroForm); } else addFieldResources(theCat); return theCat; } catch (IOException e) { throw new ExceptionConverter(e); } } private void addFieldResources(PdfDictionary catalog) throws IOException { if (fieldArray == null) return; PdfDictionary acroForm = new PdfDictionary(); catalog.put(PdfName.ACROFORM, acroForm); acroForm.put(PdfName.FIELDS, fieldArray); acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); if (fieldTemplates.isEmpty()) return; PdfDictionary dr = new PdfDictionary(); acroForm.put(PdfName.DR, dr); for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) { PdfTemplate template = (PdfTemplate)it.next(); PdfFormField.mergeResources(dr, (PdfDictionary)template.getResources()); } // if (dr.get(PdfName.ENCODING) == null) dr.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING); PdfDictionary fonts = dr.getAsDict(PdfName.FONT); if (fonts == null) { fonts = new PdfDictionary(); dr.put(PdfName.FONT, fonts); } if (!fonts.contains(PdfName.HELV)) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.BASEFONT, PdfName.HELVETICA); dic.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING); dic.put(PdfName.NAME, PdfName.HELV); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); fonts.put(PdfName.HELV, addToBody(dic).getIndirectReference()); } if (!fonts.contains(PdfName.ZADB)) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS); dic.put(PdfName.NAME, PdfName.ZADB); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); fonts.put(PdfName.ZADB, addToBody(dic).getIndirectReference()); } } /** * Signals that the Document was closed and that no other * Elements will be added. *

* The pages-tree is built and written to the outputstream. * A Catalog is constructed, as well as an Info-object, * the reference table is composed and everything is written * to the outputstream embedded in a Trailer. */ public void close() { if (open) { PdfReaderInstance ri = currentPdfReaderInstance; pdf.close(); super.close(); if (ri != null) { try { ri.getReader().close(); ri.getReaderFile().close(); } catch (IOException ioe) { // empty on purpose } } } } public PdfIndirectReference add(PdfOutline outline) { return null; } public void addAnnotation(PdfAnnotation annot) { } PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { return null; } public void freeReader(PdfReader reader) throws IOException { indirectMap.remove(reader); if (currentPdfReaderInstance != null) { if (currentPdfReaderInstance.getReader() == reader) { try { currentPdfReaderInstance.getReader().close(); currentPdfReaderInstance.getReaderFile().close(); } catch (IOException ioe) { // empty on purpose } currentPdfReaderInstance = null; } } } /** * Create a page stamp. New content and annotations, including new fields, are allowed. * The fields added cannot have parents in another pages. This method modifies the PdfReader instance.

* The general usage to stamp something in a page is: *

*

     * PdfImportedPage page = copy.getImportedPage(reader, 1);
     * PdfCopy.PageStamp ps = copy.createPageStamp(page);
     * ps.addAnnotation(PdfAnnotation.createText(copy, new Rectangle(50, 180, 70, 200), "Hello", "No Thanks", true, "Comment"));
     * PdfContentByte under = ps.getUnderContent();
     * under.addImage(img);
     * PdfContentByte over = ps.getOverContent();
     * over.beginText();
     * over.setFontAndSize(bf, 18);
     * over.setTextMatrix(30, 30);
     * over.showText("total page " + totalPage);
     * over.endText();
     * ps.alterContents();
     * copy.addPage(page);
     * 
* @param iPage an imported page * @return the PageStamp */ public PageStamp createPageStamp(PdfImportedPage iPage) { int pageNum = iPage.getPageNumber(); PdfReader reader = iPage.getPdfReaderInstance().getReader(); PdfDictionary pageN = reader.getPageN(pageNum); return new PageStamp(reader, pageN, this); } public static class PageStamp { PdfDictionary pageN; PdfCopy.StampContent under; PdfCopy.StampContent over; PageResources pageResources; PdfReader reader; PdfCopy cstp; PageStamp(PdfReader reader, PdfDictionary pageN, PdfCopy cstp) { this.pageN = pageN; this.reader = reader; this.cstp = cstp; } public PdfContentByte getUnderContent(){ if (under == null) { if (pageResources == null) { pageResources = new PageResources(); PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES); pageResources.setOriginalResources(resources, cstp.namePtr); } under = new PdfCopy.StampContent(cstp, pageResources); } return under; } public PdfContentByte getOverContent(){ if (over == null) { if (pageResources == null) { pageResources = new PageResources(); PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES); pageResources.setOriginalResources(resources, cstp.namePtr); } over = new PdfCopy.StampContent(cstp, pageResources); } return over; } public void alterContents() throws IOException { if (over == null && under == null) return; PdfArray ar = null; PdfObject content = PdfReader.getPdfObject(pageN.get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } else if (content.isArray()) { ar = (PdfArray)content; } else if (content.isStream()) { ar = new PdfArray(); ar.add(pageN.get(PdfName.CONTENTS)); pageN.put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } ByteBuffer out = new ByteBuffer(); if (under != null) { out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(under.getInternalBuffer()); out.append(PdfContents.RESTORESTATE); } if (over != null) out.append(PdfContents.SAVESTATE); PdfStream stream = new PdfStream(out.toByteArray()); stream.flateCompress(cstp.getCompressionLevel()); PdfIndirectReference ref1 = cstp.addToBody(stream).getIndirectReference(); ar.addFirst(ref1); out.reset(); if (over != null) { out.append(' '); out.append(PdfContents.RESTORESTATE); out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(over.getInternalBuffer()); out.append(PdfContents.RESTORESTATE); stream = new PdfStream(out.toByteArray()); stream.flateCompress(cstp.getCompressionLevel()); ar.add(cstp.addToBody(stream).getIndirectReference()); } pageN.put(PdfName.RESOURCES, pageResources.getResources()); } void applyRotation(PdfDictionary pageN, ByteBuffer out) { if (!cstp.rotateContents) return; Rectangle page = reader.getPageSizeWithRotation(pageN); int rotation = page.getRotation(); switch (rotation) { case 90: out.append(PdfContents.ROTATE90); out.append(page.getTop()); out.append(' ').append('0').append(PdfContents.ROTATEFINAL); break; case 180: out.append(PdfContents.ROTATE180); out.append(page.getRight()); out.append(' '); out.append(page.getTop()); out.append(PdfContents.ROTATEFINAL); break; case 270: out.append(PdfContents.ROTATE270); out.append('0').append(' '); out.append(page.getRight()); out.append(PdfContents.ROTATEFINAL); break; } } private void addDocumentField(PdfIndirectReference ref) { if (cstp.fieldArray == null) cstp.fieldArray = new PdfArray(); cstp.fieldArray.add(ref); } private void expandFields(PdfFormField field, ArrayList allAnnots) { allAnnots.add(field); ArrayList kids = field.getKids(); if (kids != null) { for (int k = 0; k < kids.size(); ++k) expandFields((PdfFormField)kids.get(k), allAnnots); } } public void addAnnotation(PdfAnnotation annot) { try { ArrayList allAnnots = new ArrayList(); if (annot.isForm()) { PdfFormField field = (PdfFormField)annot; if (field.getParent() != null) return; expandFields(field, allAnnots); if (cstp.fieldTemplates == null) cstp.fieldTemplates = new HashMap(); } else allAnnots.add(annot); for (int k = 0; k < allAnnots.size(); ++k) { annot = (PdfAnnotation)allAnnots.get(k); if (annot.isForm()) { if (!annot.isUsed()) { HashMap templates = annot.getTemplates(); if (templates != null) cstp.fieldTemplates.putAll(templates); } PdfFormField field = (PdfFormField)annot; if (field.getParent() == null) addDocumentField(field.getIndirectReference()); } if (annot.isAnnotation()) { PdfObject pdfobj = PdfReader.getPdfObject(pageN.get(PdfName.ANNOTS), pageN); PdfArray annots = null; if (pdfobj == null || !pdfobj.isArray()) { annots = new PdfArray(); pageN.put(PdfName.ANNOTS, annots); } else annots = (PdfArray)pdfobj; annots.add(annot.getIndirectReference()); if (!annot.isUsed()) { PdfRectangle rect = (PdfRectangle)annot.get(PdfName.RECT); if (rect != null && (rect.left() != 0 || rect.right() != 0 || rect.top() != 0 || rect.bottom() != 0)) { int rotation = reader.getPageRotation(pageN); Rectangle pageSize = reader.getPageSizeWithRotation(pageN); switch (rotation) { case 90: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getTop() - rect.bottom(), rect.left(), pageSize.getTop() - rect.top(), rect.right())); break; case 180: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getRight() - rect.left(), pageSize.getTop() - rect.bottom(), pageSize.getRight() - rect.right(), pageSize.getTop() - rect.top())); break; case 270: annot.put(PdfName.RECT, new PdfRectangle( rect.bottom(), pageSize.getRight() - rect.left(), rect.top(), pageSize.getRight() - rect.right())); break; } } } } if (!annot.isUsed()) { annot.setUsed(); cstp.addToBody(annot, annot.getIndirectReference()); } } } catch (IOException e) { throw new ExceptionConverter(e); } } } public static class StampContent extends PdfContentByte { PageResources pageResources; /** Creates a new instance of StampContent */ StampContent(PdfWriter writer, PageResources pageResources) { super(writer); this.pageResources = pageResources; } /** * Gets a duplicate of this PdfContentByte. All * the members are copied by reference but the buffer stays different. * * @return a copy of this PdfContentByte */ public PdfContentByte getDuplicate() { return new PdfCopy.StampContent(writer, pageResources); } PageResources getPageResources() { return pageResources; } } }src/core/com/lowagie/text/pdf/PdfCopyFields.java100644 0 0 23251 11154165267 17257 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.security.cert.Certificate; import java.util.List; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.interfaces.PdfEncryptionSettings; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; /** * Concatenates PDF documents including form fields. The rules for the form field * concatenation are the same as in Acrobat. All the documents are kept in memory unlike * PdfCopy. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfCopyFields implements PdfViewerPreferences, PdfEncryptionSettings { private PdfCopyFieldsImp fc; /** * Creates a new instance. * @param os the output stream * @throws DocumentException on error */ public PdfCopyFields(OutputStream os) throws DocumentException { fc = new PdfCopyFieldsImp(os); } /** * Creates a new instance. * @param os the output stream * @param pdfVersion the pdf version the output will have * @throws DocumentException on error */ public PdfCopyFields(OutputStream os, char pdfVersion) throws DocumentException { fc = new PdfCopyFieldsImp(os, pdfVersion); } /** * Concatenates a PDF document. * @param reader the PDF document * @throws DocumentException on error */ public void addDocument(PdfReader reader) throws DocumentException, IOException { fc.addDocument(reader); } /** * Concatenates a PDF document selecting the pages to keep. The pages are described as a * List of Integer. The page ordering can be changed but * no page repetitions are allowed. * @param reader the PDF document * @param pagesToKeep the pages to keep * @throws DocumentException on error */ public void addDocument(PdfReader reader, List pagesToKeep) throws DocumentException, IOException { fc.addDocument(reader, pagesToKeep); } /** * Concatenates a PDF document selecting the pages to keep. The pages are described as * ranges. The page ordering can be changed but * no page repetitions are allowed. * @param reader the PDF document * @param ranges the comma separated ranges as described in {@link SequenceList} * @throws DocumentException on error */ public void addDocument(PdfReader reader, String ranges) throws DocumentException, IOException { fc.addDocument(reader, SequenceList.expand(ranges, reader.getNumberOfPages())); } /** Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @throws DocumentException if the document is already open */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { fc.setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param strength true for 128 bit key length. false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if the document is already open */ public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength); } /** * Closes the output document. */ public void close() { fc.close(); } /** * Opens the document. This is usually not needed as addDocument() will do it * automatically. */ public void open() { fc.openDoc(); } /** * Adds JavaScript to the global document * @param js the JavaScript */ public void addJavaScript(String js) { fc.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js)); } /** * Sets the bookmarks. The list structure is defined in * SimpleBookmark#. * @param outlines the bookmarks or null to remove any */ public void setOutlines(List outlines) { fc.setOutlines(outlines); } /** Gets the underlying PdfWriter. * @return the underlying PdfWriter */ public PdfWriter getWriter() { return fc; } /** * Gets the 1.5 compression status. * @return true if the 1.5 compression is on */ public boolean isFullCompression() { return fc.isFullCompression(); } /** * Sets the document's compression to the new 1.5 mode with object streams and xref * streams. It can be set at any time but once set it can't be unset. *

* If set before opening the document it will also set the pdf version to 1.5. */ public void setFullCompression() { fc.setFullCompression(); } /** * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int) */ public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) throws DocumentException { fc.setEncryption(userPassword, ownerPassword, permissions, encryptionType); } /** * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */ public void addViewerPreference(PdfName key, PdfObject value) { fc.addViewerPreference(key, value); } /** * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */ public void setViewerPreferences(int preferences) { fc.setViewerPreferences(preferences); } /** * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int) */ public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException { fc.setEncryption(certs, permissions, encryptionType); } }src/core/com/lowagie/text/pdf/PdfCopyFieldsImp.java100644 0 0 63437 11154242542 17727 0ustar 0 0 /* * $Id: PdfCopyFieldsImp.java 3763 2009-03-06 17:30:30Z blowagie $ * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.exceptions.BadPasswordException; /** * * @author psoares */ class PdfCopyFieldsImp extends PdfWriter { private static final PdfName iTextTag = new PdfName("_iTextTag_"); private static final Integer zero = new Integer(0); ArrayList readers = new ArrayList(); HashMap readers2intrefs = new HashMap(); HashMap pages2intrefs = new HashMap(); HashMap visited = new HashMap(); ArrayList fields = new ArrayList(); RandomAccessFileOrArray file; HashMap fieldTree = new HashMap(); ArrayList pageRefs = new ArrayList(); ArrayList pageDics = new ArrayList(); PdfDictionary resources = new PdfDictionary(); PdfDictionary form; boolean closing = false; Document nd; private HashMap tabOrder; private ArrayList calculationOrder = new ArrayList(); private ArrayList calculationOrderRefs; private boolean hasSignature; PdfCopyFieldsImp(OutputStream os) throws DocumentException { this(os, '\0'); } PdfCopyFieldsImp(OutputStream os, char pdfVersion) throws DocumentException { super(new PdfDocument(), os); pdf.addWriter(this); if (pdfVersion != 0) super.setPdfVersion(pdfVersion); nd = new Document(); nd.addDocListener(pdf); } void addDocument(PdfReader reader, List pagesToKeep) throws DocumentException, IOException { if (!readers2intrefs.containsKey(reader) && reader.isTampered()) throw new DocumentException("The document was reused."); reader = new PdfReader(reader); reader.selectPages(pagesToKeep); if (reader.getNumberOfPages() == 0) return; reader.setTampered(false); addDocument(reader); } void addDocument(PdfReader reader) throws DocumentException, IOException { if (!reader.isOpenedWithFullPermissions()) throw new BadPasswordException("PdfReader not opened with owner password"); openDoc(); if (readers2intrefs.containsKey(reader)) { reader = new PdfReader(reader); } else { if (reader.isTampered()) throw new DocumentException("The document was reused."); reader.consolidateNamedDestinations(); reader.setTampered(true); } reader.shuffleSubsetNames(); readers2intrefs.put(reader, new IntHashtable()); readers.add(reader); int len = reader.getNumberOfPages(); IntHashtable refs = new IntHashtable(); for (int p = 1; p <= len; ++p) { refs.put(reader.getPageOrigRef(p).getNumber(), 1); reader.releasePage(p); } pages2intrefs.put(reader, refs); visited.put(reader, new IntHashtable()); fields.add(reader.getAcroFields()); updateCalculationOrder(reader); } private static String getCOName(PdfReader reader, PRIndirectReference ref) { String name = ""; while (ref != null) { PdfObject obj = PdfReader.getPdfObject(ref); if (obj == null || obj.type() != PdfObject.DICTIONARY) break; PdfDictionary dic = (PdfDictionary)obj; PdfString t = dic.getAsString(PdfName.T); if (t != null) { name = t.toUnicodeString()+ "." + name; } ref = (PRIndirectReference)dic.get(PdfName.PARENT); } if (name.endsWith(".")) name = name.substring(0, name.length() - 1); return name; } /** * @since 2.1.5; before 2.1.5 the method was private */ protected void updateCalculationOrder(PdfReader reader) { PdfDictionary catalog = reader.getCatalog(); PdfDictionary acro = catalog.getAsDict(PdfName.ACROFORM); if (acro == null) return; PdfArray co = acro.getAsArray(PdfName.CO); if (co == null || co.size() == 0) return; AcroFields af = reader.getAcroFields(); for (int k = 0; k < co.size(); ++k) { PdfObject obj = co.getPdfObject(k); if (obj == null || !obj.isIndirect()) continue; String name = getCOName(reader, (PRIndirectReference)obj); if (af.getFieldItem(name) == null) continue; name = "." + name; if (calculationOrder.contains(name)) continue; calculationOrder.add(name); } } void propagate(PdfObject obj, PdfIndirectReference refo, boolean restricted) throws IOException { if (obj == null) return; // if (refo != null) // addToBody(obj, refo); if (obj instanceof PdfIndirectReference) return; switch (obj.type()) { case PdfObject.DICTIONARY: case PdfObject.STREAM: { PdfDictionary dic = (PdfDictionary)obj; for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); if (restricted && (key.equals(PdfName.PARENT) || key.equals(PdfName.KIDS))) continue; PdfObject ob = dic.get(key); if (ob != null && ob.isIndirect()) { PRIndirectReference ind = (PRIndirectReference)ob; if (!setVisited(ind) && !isPage(ind)) { PdfIndirectReference ref = getNewReference(ind); propagate(PdfReader.getPdfObjectRelease(ind), ref, restricted); } } else propagate(ob, null, restricted); } break; } case PdfObject.ARRAY: { //PdfArray arr = new PdfArray(); for (Iterator it = ((PdfArray)obj).listIterator(); it.hasNext();) { PdfObject ob = (PdfObject)it.next(); if (ob != null && ob.isIndirect()) { PRIndirectReference ind = (PRIndirectReference)ob; if (!isVisited(ind) && !isPage(ind)) { PdfIndirectReference ref = getNewReference(ind); propagate(PdfReader.getPdfObjectRelease(ind), ref, restricted); } } else propagate(ob, null, restricted); } break; } case PdfObject.INDIRECT: { throw new RuntimeException("Reference pointing to reference."); } } } private void adjustTabOrder(PdfArray annots, PdfIndirectReference ind, PdfNumber nn) { int v = nn.intValue(); ArrayList t = (ArrayList)tabOrder.get(annots); if (t == null) { t = new ArrayList(); int size = annots.size() - 1; for (int k = 0; k < size; ++k) { t.add(zero); } t.add(new Integer(v)); tabOrder.put(annots, t); annots.add(ind); } else { int size = t.size() - 1; for (int k = size; k >= 0; --k) { if (((Integer)t.get(k)).intValue() <= v) { t.add(k + 1, new Integer(v)); annots.add(k + 1, ind); size = -2; break; } } if (size != -2) { t.add(0, new Integer(v)); annots.add(0, ind); } } } protected PdfArray branchForm(HashMap level, PdfIndirectReference parent, String fname) throws IOException { PdfArray arr = new PdfArray(); for (Iterator it = level.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String name = (String) entry.getKey(); Object obj = entry.getValue(); PdfIndirectReference ind = getPdfIndirectReference(); PdfDictionary dic = new PdfDictionary(); if (parent != null) dic.put(PdfName.PARENT, parent); dic.put(PdfName.T, new PdfString(name, PdfObject.TEXT_UNICODE)); String fname2 = fname + "." + name; int coidx = calculationOrder.indexOf(fname2); if (coidx >= 0) calculationOrderRefs.set(coidx, ind); if (obj instanceof HashMap) { dic.put(PdfName.KIDS, branchForm((HashMap)obj, ind, fname2)); arr.add(ind); addToBody(dic, ind); } else { ArrayList list = (ArrayList)obj; dic.mergeDifferent((PdfDictionary)list.get(0)); if (list.size() == 3) { dic.mergeDifferent((PdfDictionary)list.get(2)); int page = ((Integer)list.get(1)).intValue(); PdfDictionary pageDic = (PdfDictionary)pageDics.get(page - 1); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots == null) { annots = new PdfArray(); pageDic.put(PdfName.ANNOTS, annots); } PdfNumber nn = (PdfNumber)dic.get(iTextTag); dic.remove(iTextTag); adjustTabOrder(annots, ind, nn); } else { PdfArray kids = new PdfArray(); for (int k = 1; k < list.size(); k += 2) { int page = ((Integer)list.get(k)).intValue(); PdfDictionary pageDic = (PdfDictionary)pageDics.get(page - 1); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots == null) { annots = new PdfArray(); pageDic.put(PdfName.ANNOTS, annots); } PdfDictionary widget = new PdfDictionary(); widget.merge((PdfDictionary)list.get(k + 1)); widget.put(PdfName.PARENT, ind); PdfNumber nn = (PdfNumber)widget.get(iTextTag); widget.remove(iTextTag); PdfIndirectReference wref = addToBody(widget).getIndirectReference(); adjustTabOrder(annots, wref, nn); kids.add(wref); propagate(widget, null, false); } dic.put(PdfName.KIDS, kids); } arr.add(ind); addToBody(dic, ind); propagate(dic, null, false); } } return arr; } protected void createAcroForms() throws IOException { if (fieldTree.isEmpty()) return; form = new PdfDictionary(); form.put(PdfName.DR, resources); propagate(resources, null, false); form.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); tabOrder = new HashMap(); calculationOrderRefs = new ArrayList(calculationOrder); form.put(PdfName.FIELDS, branchForm(fieldTree, null, "")); if (hasSignature) form.put(PdfName.SIGFLAGS, new PdfNumber(3)); PdfArray co = new PdfArray(); for (int k = 0; k < calculationOrderRefs.size(); ++k) { Object obj = calculationOrderRefs.get(k); if (obj instanceof PdfIndirectReference) co.add((PdfIndirectReference)obj); } if (co.size() > 0) form.put(PdfName.CO, co); } public void close() { if (closing) { super.close(); return; } closing = true; try { closeIt(); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Creates the new PDF by merging the fields and forms. */ protected void closeIt() throws IOException { for (int k = 0; k < readers.size(); ++k) { ((PdfReader)readers.get(k)).removeFields(); } for (int r = 0; r < readers.size(); ++r) { PdfReader reader = (PdfReader)readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { pageRefs.add(getNewReference(reader.getPageOrigRef(page))); pageDics.add(reader.getPageN(page)); } } mergeFields(); createAcroForms(); for (int r = 0; r < readers.size(); ++r) { PdfReader reader = (PdfReader)readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { PdfDictionary dic = reader.getPageN(page); PdfIndirectReference pageRef = getNewReference(reader.getPageOrigRef(page)); PdfIndirectReference parent = root.addPageRef(pageRef); dic.put(PdfName.PARENT, parent); propagate(dic, pageRef, false); } } for (Iterator it = readers2intrefs.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); PdfReader reader = (PdfReader) entry.getKey(); try { file = reader.getSafeFile(); file.reOpen(); IntHashtable t = (IntHashtable) entry.getValue(); int keys[] = t.toOrderedKeys(); for (int k = 0; k < keys.length; ++k) { PRIndirectReference ref = new PRIndirectReference(reader, keys[k]); addToBody(PdfReader.getPdfObjectRelease(ref), t.get(keys[k])); } } finally { try { file.close(); reader.close(); } catch (Exception e) { // empty on purpose } } } pdf.close(); } void addPageOffsetToField(HashMap fd, int pageOffset) { if (pageOffset == 0) return; for (Iterator it = fd.values().iterator(); it.hasNext();) { AcroFields.Item item = (AcroFields.Item)it.next(); for (int k = 0; k < item.size(); ++k) { int p = item.getPage(k).intValue(); item.forcePage(k, p + pageOffset); } } } void createWidgets(ArrayList list, AcroFields.Item item) { for (int k = 0; k < item.size(); ++k) { list.add(item.getPage(k)); PdfDictionary merged = item.getMerged(k); PdfObject dr = merged.get(PdfName.DR); if (dr != null) PdfFormField.mergeResources(resources, (PdfDictionary)PdfReader.getPdfObject(dr)); PdfDictionary widget = new PdfDictionary(); for (Iterator it = merged.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); if (widgetKeys.containsKey(key)) widget.put(key, merged.get(key)); } widget.put(iTextTag, new PdfNumber(item.getTabOrder(k).intValue() + 1)); list.add(widget); } } void mergeField(String name, AcroFields.Item item) { HashMap map = fieldTree; StringTokenizer tk = new StringTokenizer(name, "."); if (!tk.hasMoreTokens()) return; while (true) { String s = tk.nextToken(); Object obj = map.get(s); if (tk.hasMoreTokens()) { if (obj == null) { obj = new HashMap(); map.put(s, obj); map = (HashMap)obj; continue; } else if (obj instanceof HashMap) map = (HashMap)obj; else return; } else { if (obj instanceof HashMap) return; PdfDictionary merged = item.getMerged(0); if (obj == null) { PdfDictionary field = new PdfDictionary(); if (PdfName.SIG.equals(merged.get(PdfName.FT))) hasSignature = true; for (Iterator it = merged.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); if (fieldKeys.containsKey(key)) field.put(key, merged.get(key)); } ArrayList list = new ArrayList(); list.add(field); createWidgets(list, item); map.put(s, list); } else { ArrayList list = (ArrayList)obj; PdfDictionary field = (PdfDictionary)list.get(0); PdfName type1 = (PdfName)field.get(PdfName.FT); PdfName type2 = (PdfName)merged.get(PdfName.FT); if (type1 == null || !type1.equals(type2)) return; int flag1 = 0; PdfObject f1 = field.get(PdfName.FF); if (f1 != null && f1.isNumber()) flag1 = ((PdfNumber)f1).intValue(); int flag2 = 0; PdfObject f2 = merged.get(PdfName.FF); if (f2 != null && f2.isNumber()) flag2 = ((PdfNumber)f2).intValue(); if (type1.equals(PdfName.BTN)) { if (((flag1 ^ flag2) & PdfFormField.FF_PUSHBUTTON) != 0) return; if ((flag1 & PdfFormField.FF_PUSHBUTTON) == 0 && ((flag1 ^ flag2) & PdfFormField.FF_RADIO) != 0) return; } else if (type1.equals(PdfName.CH)) { if (((flag1 ^ flag2) & PdfFormField.FF_COMBO) != 0) return; } createWidgets(list, item); } return; } } } void mergeWithMaster(HashMap fd) { for (Iterator it = fd.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String name = (String) entry.getKey(); mergeField(name, (AcroFields.Item) entry.getValue()); } } void mergeFields() { int pageOffset = 0; for (int k = 0; k < fields.size(); ++k) { HashMap fd = ((AcroFields)fields.get(k)).getFields(); addPageOffsetToField(fd, pageOffset); mergeWithMaster(fd); pageOffset += ((PdfReader)readers.get(k)).getNumberOfPages(); } } public PdfIndirectReference getPageReference(int page) { return (PdfIndirectReference)pageRefs.get(page - 1); } protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { try { PdfDictionary cat = pdf.getCatalog(rootObj); if (form != null) { PdfIndirectReference ref = addToBody(form).getIndirectReference(); cat.put(PdfName.ACROFORM, ref); } return cat; } catch (IOException e) { throw new ExceptionConverter(e); } } protected PdfIndirectReference getNewReference(PRIndirectReference ref) { return new PdfIndirectReference(0, getNewObjectNumber(ref.getReader(), ref.getNumber(), 0)); } protected int getNewObjectNumber(PdfReader reader, int number, int generation) { IntHashtable refs = (IntHashtable)readers2intrefs.get(reader); int n = refs.get(number); if (n == 0) { n = getIndirectReferenceNumber(); refs.put(number, n); } return n; } /** * Sets a reference to "visited" in the copy process. * @param ref the reference that needs to be set to "visited" * @return true if the reference was set to visited */ protected boolean setVisited(PRIndirectReference ref) { IntHashtable refs = (IntHashtable)visited.get(ref.getReader()); if (refs != null) return (refs.put(ref.getNumber(), 1) != 0); else return false; } /** * Checks if a reference has already been "visited" in the copy process. * @param ref the reference that needs to be checked * @return true if the reference was already visited */ protected boolean isVisited(PRIndirectReference ref) { IntHashtable refs = (IntHashtable)visited.get(ref.getReader()); if (refs != null) return refs.containsKey(ref.getNumber()); else return false; } protected boolean isVisited(PdfReader reader, int number, int generation) { IntHashtable refs = (IntHashtable)readers2intrefs.get(reader); return refs.containsKey(number); } /** * Checks if a reference refers to a page object. * @param ref the reference that needs to be checked * @return true is the reference refers to a page object. */ protected boolean isPage(PRIndirectReference ref) { IntHashtable refs = (IntHashtable)pages2intrefs.get(ref.getReader()); if (refs != null) return refs.containsKey(ref.getNumber()); else return false; } RandomAccessFileOrArray getReaderFile(PdfReader reader) { return file; } public void openDoc() { if (!nd.isOpen()) nd.open(); } protected static final HashMap widgetKeys = new HashMap(); protected static final HashMap fieldKeys = new HashMap(); static { Integer one = new Integer(1); widgetKeys.put(PdfName.SUBTYPE, one); widgetKeys.put(PdfName.CONTENTS, one); widgetKeys.put(PdfName.RECT, one); widgetKeys.put(PdfName.NM, one); widgetKeys.put(PdfName.M, one); widgetKeys.put(PdfName.F, one); widgetKeys.put(PdfName.BS, one); widgetKeys.put(PdfName.BORDER, one); widgetKeys.put(PdfName.AP, one); widgetKeys.put(PdfName.AS, one); widgetKeys.put(PdfName.C, one); widgetKeys.put(PdfName.A, one); widgetKeys.put(PdfName.STRUCTPARENT, one); widgetKeys.put(PdfName.OC, one); widgetKeys.put(PdfName.H, one); widgetKeys.put(PdfName.MK, one); widgetKeys.put(PdfName.DA, one); widgetKeys.put(PdfName.Q, one); fieldKeys.put(PdfName.AA, one); fieldKeys.put(PdfName.FT, one); fieldKeys.put(PdfName.TU, one); fieldKeys.put(PdfName.TM, one); fieldKeys.put(PdfName.FF, one); fieldKeys.put(PdfName.V, one); fieldKeys.put(PdfName.DV, one); fieldKeys.put(PdfName.DS, one); fieldKeys.put(PdfName.RV, one); fieldKeys.put(PdfName.OPT, one); fieldKeys.put(PdfName.MAXLEN, one); fieldKeys.put(PdfName.TI, one); fieldKeys.put(PdfName.I, one); fieldKeys.put(PdfName.LOCK, one); fieldKeys.put(PdfName.SV, one); } } src/core/com/lowagie/text/pdf/PdfCopyForms.java100644 0 0 23273 11154165266 17142 0ustar 0 0 /* * $Id: PdfCopyForms.java 3665 2009-01-26 22:32:15Z xlv $ * * Copyright 2009 Holger Plankermann (inspired by Paulo Soares) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.security.cert.Certificate; import java.util.List; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.interfaces.PdfEncryptionSettings; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; /** * Allows you to add one (or more) existing PDF document(s) to * create a new PDF and add the form of another PDF document to * this new PDF. * @since 2.1.5 */ public class PdfCopyForms implements PdfViewerPreferences, PdfEncryptionSettings { /** The class with the actual implementations. */ private PdfCopyFormsImp fc; /** * Creates a new instance. * @param os the output stream * @throws DocumentException on error */ public PdfCopyForms(OutputStream os) throws DocumentException { fc = new PdfCopyFormsImp(os); } /** * Concatenates a PDF document. * @param reader the PDF document * @throws DocumentException on error */ public void addDocument(PdfReader reader) throws DocumentException, IOException { fc.addDocument(reader); } /** * Concatenates a PDF document selecting the pages to keep. The pages are described as a * List of Integer. The page ordering can be changed but * no page repetitions are allowed. * @param reader the PDF document * @param pagesToKeep the pages to keep * @throws DocumentException on error */ public void addDocument(PdfReader reader, List pagesToKeep) throws DocumentException, IOException { fc.addDocument(reader, pagesToKeep); } /** * Concatenates a PDF document selecting the pages to keep. The pages are described as * ranges. The page ordering can be changed but * no page repetitions are allowed. * @param reader the PDF document * @param ranges the comma separated ranges as described in {@link SequenceList} * @throws DocumentException on error */ public void addDocument(PdfReader reader, String ranges) throws DocumentException, IOException { fc.addDocument(reader, SequenceList.expand(ranges, reader.getNumberOfPages())); } /** *Copies the form fields of this PDFDocument onto the PDF-Document which was added * @param reader the PDF document * @throws DocumentException on error */ public void copyDocumentFields(PdfReader reader) throws DocumentException{ fc.copyDocumentFields(reader); } /** Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @throws DocumentException if the document is already open */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { fc.setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param strength true for 128 bit key length. false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if the document is already open */ public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength); } /** * Closes the output document. */ public void close() { fc.close(); } /** * Opens the document. This is usually not needed as addDocument() will do it * automatically. */ public void open() { fc.openDoc(); } /** * Adds JavaScript to the global document * @param js the JavaScript */ public void addJavaScript(String js) { fc.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js)); } /** * Sets the bookmarks. The list structure is defined in * SimpleBookmark#. * @param outlines the bookmarks or null to remove any */ public void setOutlines(List outlines) { fc.setOutlines(outlines); } /** Gets the underlying PdfWriter. * @return the underlying PdfWriter */ public PdfWriter getWriter() { return fc; } /** * Gets the 1.5 compression status. * @return true if the 1.5 compression is on */ public boolean isFullCompression() { return fc.isFullCompression(); } /** * Sets the document's compression to the new 1.5 mode with object streams and xref * streams. It can be set at any time but once set it can't be unset. *

* If set before opening the document it will also set the pdf version to 1.5. */ public void setFullCompression() { fc.setFullCompression(); } /** * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int) */ public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) throws DocumentException { fc.setEncryption(userPassword, ownerPassword, permissions, encryptionType); } /** * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */ public void addViewerPreference(PdfName key, PdfObject value) { fc.addViewerPreference(key, value); } /** * @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */ public void setViewerPreferences(int preferences) { fc.setViewerPreferences(preferences); } /** * @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int) */ public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException { fc.setEncryption(certs, permissions, encryptionType); } }src/core/com/lowagie/text/pdf/PdfCopyFormsImp.java100644 0 0 10262 11154165266 17602 0ustar 0 0 /* * $Id: PdfCopyFormsImp.java 3665 2009-01-26 22:32:15Z xlv $ * * Copyright 2009 Bruno Lowagie (inspired by Paulo Soares) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.DocumentException; import java.io.OutputStream; import java.util.HashMap; /** * Allows you to add one (or more) existing PDF document(s) * and add the form(s) of (an)other PDF document(s). * @since 2.1.5 */ class PdfCopyFormsImp extends PdfCopyFieldsImp { /** * This sets up the output document * @param os The Outputstream pointing to the output document * @throws DocumentException */ PdfCopyFormsImp(OutputStream os) throws DocumentException { super(os); } /** * This method feeds in the source document * @param reader The PDF reader containing the source document * @throws DocumentException */ public void copyDocumentFields(PdfReader reader) throws DocumentException { if (!reader.isOpenedWithFullPermissions()) throw new IllegalArgumentException("PdfReader not opened with owner password"); if (readers2intrefs.containsKey(reader)) { reader = new PdfReader(reader); } else { if (reader.isTampered()) throw new DocumentException("The document was reused."); reader.consolidateNamedDestinations(); reader.setTampered(true); } reader.shuffleSubsetNames(); readers2intrefs.put(reader, new IntHashtable()); fields.add(reader.getAcroFields()); updateCalculationOrder(reader); } /** * This merge fields is slightly different from the mergeFields method * of PdfCopyFields. */ void mergeFields() { for (int k = 0; k < fields.size(); ++k) { HashMap fd = ((AcroFields)fields.get(k)).getFields(); mergeWithMaster(fd); } } }src/core/com/lowagie/text/pdf/PdfDashPattern.java100644 0 0 10637 11012562273 17426 0ustar 0 0 /* * $Id: PdfDashPattern.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; /** * A PdfDashPattern defines a dash pattern as described in * the PDF Reference Manual version 1.3 p 325 (section 8.4.3). * * @see PdfArray */ public class PdfDashPattern extends PdfArray { // membervariables /** This is the length of a dash. */ private float dash = -1; /** This is the length of a gap. */ private float gap = -1; /** This is the phase. */ private float phase = -1; // constructors /** * Constructs a new PdfDashPattern. */ public PdfDashPattern() { super(); } /** * Constructs a new PdfDashPattern. */ public PdfDashPattern(float dash) { super(new PdfNumber(dash)); this.dash = dash; } /** * Constructs a new PdfDashPattern. */ public PdfDashPattern(float dash, float gap) { super(new PdfNumber(dash)); add(new PdfNumber(gap)); this.dash = dash; this.gap = gap; } /** * Constructs a new PdfDashPattern. */ public PdfDashPattern(float dash, float gap, float phase) { super(new PdfNumber(dash)); add(new PdfNumber(gap)); this.dash = dash; this.gap = gap; this.phase = phase; } public void add(float n) { add(new PdfNumber(n)); } /** * Returns the PDF representation of this PdfArray. */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { os.write('['); if (dash >= 0) { new PdfNumber(dash).toPdf(writer, os); if (gap >= 0) { os.write(' '); new PdfNumber(gap).toPdf(writer, os); } } os.write(']'); if (phase >=0) { os.write(' '); new PdfNumber(phase).toPdf(writer, os); } } }src/core/com/lowagie/text/pdf/PdfDate.java100644 0 0 22343 11000354131 16050 0ustar 0 0 /* * $Id: PdfDate.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.SimpleTimeZone; /** * PdfDate is the PDF date object. *

* PDF defines a standard date format. The PDF date format closely follows the format * defined by the international standard ASN.1 (Abstract Syntax Notation One, defined * in CCITT X.208 or ISO/IEC 8824). A date is a PdfString of the form: *

* (D:YYYYMMDDHHmmSSOHH'mm') *

* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 7.2 (page 183-184) * * @see PdfString * @see java.util.GregorianCalendar */ public class PdfDate extends PdfString { private static final int DATE_SPACE[] = {Calendar.YEAR, 4, 0, Calendar.MONTH, 2, -1, Calendar.DAY_OF_MONTH, 2, 0, Calendar.HOUR_OF_DAY, 2, 0, Calendar.MINUTE, 2, 0, Calendar.SECOND, 2, 0}; // constructors /** * Constructs a PdfDate-object. * * @param d the date that has to be turned into a PdfDate-object */ public PdfDate(Calendar d) { super(); StringBuffer date = new StringBuffer("D:"); date.append(setLength(d.get(Calendar.YEAR), 4)); date.append(setLength(d.get(Calendar.MONTH) + 1, 2)); date.append(setLength(d.get(Calendar.DATE), 2)); date.append(setLength(d.get(Calendar.HOUR_OF_DAY), 2)); date.append(setLength(d.get(Calendar.MINUTE), 2)); date.append(setLength(d.get(Calendar.SECOND), 2)); int timezone = (d.get(Calendar.ZONE_OFFSET) + d.get(Calendar.DST_OFFSET)) / (60 * 60 * 1000); if (timezone == 0) { date.append('Z'); } else if (timezone < 0) { date.append('-'); timezone = -timezone; } else { date.append('+'); } if (timezone != 0) { date.append(setLength(timezone, 2)).append('\''); int zone = Math.abs((d.get(Calendar.ZONE_OFFSET) + d.get(Calendar.DST_OFFSET)) / (60 * 1000)) - (timezone * 60); date.append(setLength(zone, 2)).append('\''); } value = date.toString(); } /** * Constructs a PdfDate-object, representing the current day and time. */ public PdfDate() { this(new GregorianCalendar()); } /** * Adds a number of leading zeros to a given String in order to get a String * of a certain length. * * @param i a given number * @param length the length of the resulting String * @return the resulting String */ private String setLength(int i, int length) { // 1.3-1.4 problem fixed by Finn Bock StringBuffer tmp = new StringBuffer(); tmp.append(i); while (tmp.length() < length) { tmp.insert(0, "0"); } tmp.setLength(length); return tmp.toString(); } /** * Gives the W3C format of the PdfDate. * @return a formatted date */ public String getW3CDate() { return getW3CDate(value); } /** * Gives the W3C format of the PdfDate. * @param d the date in the format D:YYYYMMDDHHmmSSOHH'mm' * @return a formatted date */ public static String getW3CDate(String d) { if (d.startsWith("D:")) d = d.substring(2); StringBuffer sb = new StringBuffer(); if (d.length() < 4) return "0000"; sb.append(d.substring(0, 4)); //year d = d.substring(4); if (d.length() < 2) return sb.toString(); sb.append('-').append(d.substring(0, 2)); //month d = d.substring(2); if (d.length() < 2) return sb.toString(); sb.append('-').append(d.substring(0, 2)); //day d = d.substring(2); if (d.length() < 2) return sb.toString(); sb.append('T').append(d.substring(0, 2)); //hour d = d.substring(2); if (d.length() < 2) { sb.append(":00Z"); return sb.toString(); } sb.append(':').append(d.substring(0, 2)); //minute d = d.substring(2); if (d.length() < 2) { sb.append('Z'); return sb.toString(); } sb.append(':').append(d.substring(0, 2)); //second d = d.substring(2); if (d.startsWith("-") || d.startsWith("+")) { String sign = d.substring(0, 1); d = d.substring(1); String h = "00"; String m = "00"; if (d.length() >= 2) { h = d.substring(0, 2); if (d.length() > 2) { d = d.substring(3); if (d.length() >= 2) m = d.substring(0, 2); } sb.append(sign).append(h).append(':').append(m); return sb.toString(); } } sb.append('Z'); return sb.toString(); } /** * Converts a PDF string representing a date into a Calendar. * @param s the PDF string representing a date * @return a Calendar representing the date or null if the string * was not a date */ public static Calendar decode(String s) { try { if (s.startsWith("D:")) s = s.substring(2); GregorianCalendar calendar; int slen = s.length(); int idx = s.indexOf('Z'); if (idx >= 0) { slen = idx; calendar = new GregorianCalendar(new SimpleTimeZone(0, "ZPDF")); } else { int sign = 1; idx = s.indexOf('+'); if (idx < 0) { idx = s.indexOf('-'); if (idx >= 0) sign = -1; } if (idx < 0) calendar = new GregorianCalendar(); else { int offset = Integer.parseInt(s.substring(idx + 1, idx + 3)) * 60; if (idx + 5 < s.length()) offset += Integer.parseInt(s.substring(idx + 4, idx + 6)); calendar = new GregorianCalendar(new SimpleTimeZone(offset * sign * 60000, "ZPDF")); slen = idx; } } calendar.clear(); idx = 0; for (int k = 0; k < DATE_SPACE.length; k += 3) { if (idx >= slen) break; calendar.set(DATE_SPACE[k], Integer.parseInt(s.substring(idx, idx + DATE_SPACE[k + 1])) + DATE_SPACE[k + 2]); idx += DATE_SPACE[k + 1]; } return calendar; } catch (Exception e) { return null; } } }src/core/com/lowagie/text/pdf/PdfDestination.java100644 0 0 17064 11012562273 17473 0ustar 0 0 /* * $Id: PdfDestination.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * A PdfColor defines a Color (it's a PdfArray containing 3 values). * * @see PdfDictionary */ public class PdfDestination extends PdfArray { // public static final member-variables /** This is a possible destination type */ public static final int XYZ = 0; /** This is a possible destination type */ public static final int FIT = 1; /** This is a possible destination type */ public static final int FITH = 2; /** This is a possible destination type */ public static final int FITV = 3; /** This is a possible destination type */ public static final int FITR = 4; /** This is a possible destination type */ public static final int FITB = 5; /** This is a possible destination type */ public static final int FITBH = 6; /** This is a possible destination type */ public static final int FITBV = 7; // member variables /** Is the indirect reference to a page already added? */ private boolean status = false; // constructors /** * Constructs a new PdfDestination. *

* If type equals FITB, the bounding box of a page * will fit the window of the Reader. Otherwise the type will be set to * FIT so that the entire page will fit to the window. * * @param type The destination type */ public PdfDestination(int type) { super(); if (type == FITB) { add(PdfName.FITB); } else { add(PdfName.FIT); } } /** * Constructs a new PdfDestination. *

* If type equals FITBH / FITBV, * the width / height of the bounding box of a page will fit the window * of the Reader. The parameter will specify the y / x coordinate of the * top / left edge of the window. If the type equals FITH * or FITV the width / height of the entire page will fit * the window and the parameter will specify the y / x coordinate of the * top / left edge. In all other cases the type will be set to FITH. * * @param type the destination type * @param parameter a parameter to combined with the destination type */ public PdfDestination(int type, float parameter) { super(new PdfNumber(parameter)); switch(type) { default: addFirst(PdfName.FITH); break; case FITV: addFirst(PdfName.FITV); break; case FITBH: addFirst(PdfName.FITBH); break; case FITBV: addFirst(PdfName.FITBV); } } /** Constructs a new PdfDestination. *

* Display the page, with the coordinates (left, top) positioned * at the top-left corner of the window and the contents of the page magnified * by the factor zoom. A negative value for any of the parameters left or top, or a * zoom value of 0 specifies that the current value of that parameter is to be retained unchanged. * @param type must be a PdfDestination.XYZ * @param left the left value. Negative to place a null * @param top the top value. Negative to place a null * @param zoom The zoom factor. A value of 0 keeps the current value */ public PdfDestination(int type, float left, float top, float zoom) { super(PdfName.XYZ); if (left < 0) add(PdfNull.PDFNULL); else add(new PdfNumber(left)); if (top < 0) add(PdfNull.PDFNULL); else add(new PdfNumber(top)); add(new PdfNumber(zoom)); } /** Constructs a new PdfDestination. *

* Display the page, with its contents magnified just enough * to fit the rectangle specified by the coordinates left, bottom, right, and top * entirely within the window both horizontally and vertically. If the required * horizontal and vertical magnification factors are different, use the smaller of * the two, centering the rectangle within the window in the other dimension. * * @param type must be PdfDestination.FITR * @param left a parameter * @param bottom a parameter * @param right a parameter * @param top a parameter * @since iText0.38 */ public PdfDestination(int type, float left, float bottom, float right, float top) { super(PdfName.FITR); add(new PdfNumber(left)); add(new PdfNumber(bottom)); add(new PdfNumber(right)); add(new PdfNumber(top)); } // methods /** * Checks if an indirect reference to a page has been added. * * @return true or false */ public boolean hasPage() { return status; } /** Adds the indirect reference of the destination page. * * @param page an indirect reference * @return true if the page reference was added */ public boolean addPage(PdfIndirectReference page) { if (!status) { addFirst(page); status = true; return true; } return false; } }src/core/com/lowagie/text/pdf/PdfDeveloperExtension.java100644 0 0 11745 11161724620 21035 0ustar 0 0 /* * $Id: $ * * Copyright 2009 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Beginning with BaseVersion 1.7, the extensions dictionary lets developers * designate that a given document contains extensions to PDF. The presence * of the extension dictionary in a document indicates that it may contain * developer-specific PDF properties that extend a particular base version * of the PDF specification. * The extensions dictionary enables developers to identify their own extensions * relative to a base version of PDF. Additionally, the convention identifies * extension levels relative to that base version. The intent of this dictionary * is to enable developers of PDF-producing applications to identify company-specific * specifications (such as this one) that PDF-consuming applications use to * interpret the extensions. * @since 2.1.6 */ public class PdfDeveloperExtension { /** An instance of this class for Adobe 1.7 Extension level 3. */ public static final PdfDeveloperExtension ADOBE_1_7_EXTENSIONLEVEL3 = new PdfDeveloperExtension(PdfName.ADBE, PdfWriter.PDF_VERSION_1_7, 3); /** The prefix used in the Extensions dictionary added to the Catalog. */ protected PdfName prefix; /** The base version. */ protected PdfName baseversion; /** The extension level within the baseversion. */ protected int extensionLevel; /** * Creates a PdfDeveloperExtension object. * @param prefix the prefix referring to the developer * @param baseversion the number of the base version * @param extensionLevel the extension level within the baseverion. */ public PdfDeveloperExtension(PdfName prefix, PdfName baseversion, int extensionLevel) { this.prefix = prefix; this.baseversion = baseversion; this.extensionLevel = extensionLevel; } /** * Gets the prefix name. * @return a PdfName */ public PdfName getPrefix() { return prefix; } /** * Gets the baseversion name. * @return a PdfName */ public PdfName getBaseversion() { return baseversion; } /** * Gets the extension level within the baseversion. * @return an integer */ public int getExtensionLevel() { return extensionLevel; } /** * Generations the developer extension dictionary corresponding * with the prefix. * @return a PdfDictionary */ public PdfDictionary getDeveloperExtensions() { PdfDictionary developerextensions = new PdfDictionary(); developerextensions.put(PdfName.BASEVERSION, baseversion); developerextensions.put(PdfName.EXTENSIONLEVEL, new PdfNumber(extensionLevel)); return developerextensions; } } src/core/com/lowagie/text/pdf/PdfDictionary.java100644 0 0 44027 11154236326 17322 0ustar 0 0 /* * $Id: PdfDictionary.java 3762 2009-03-06 16:53:44Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Set; /** * PdfDictionary is the Pdf dictionary object. *

* A dictionary is an associative table containing pairs of objects. * The first element of each pair is called the key and the second * element is called the value. * Unlike dictionaries in the PostScript language, a key must be a * PdfName. * A value can be any kind of PdfObject, including a dictionary. * A dictionary is generally used to collect and tie together the attributes * of a complex object, with each key-value pair specifying the name and value * of an attribute.
* A dictionary is represented by two left angle brackets (<<), followed by a * sequence of key-value pairs, followed by two right angle brackets (>>).
* This object is described in the 'Portable Document Format Reference Manual * version 1.7' section 3.2.6 (page 59-60). *

* * @see PdfObject * @see PdfName * @see BadPdfFormatException */ public class PdfDictionary extends PdfObject { // CONSTANTS /** This is a possible type of dictionary */ public static final PdfName FONT = PdfName.FONT; /** This is a possible type of dictionary */ public static final PdfName OUTLINES = PdfName.OUTLINES; /** This is a possible type of dictionary */ public static final PdfName PAGE = PdfName.PAGE; /** This is a possible type of dictionary */ public static final PdfName PAGES = PdfName.PAGES; /** This is a possible type of dictionary */ public static final PdfName CATALOG = PdfName.CATALOG; // CLASS VARIABLES /** This is the type of this dictionary */ private PdfName dictionaryType = null; /** This is the hashmap that contains all the values and keys of the dictionary */ protected HashMap hashMap; // CONSTRUCTORS /** * Constructs an empty PdfDictionary-object. */ public PdfDictionary() { super(DICTIONARY); hashMap = new HashMap(); } /** * Constructs a PdfDictionary-object of a certain type. * * @param type a PdfName */ public PdfDictionary(PdfName type) { this(); dictionaryType = type; put(PdfName.TYPE, dictionaryType); } // METHODS OVERRIDING SOME PDFOBJECT METHODS /** * Writes the PDF representation of this PdfDictionary as an * array of byte to the given OutputStream. * * @param writer for backwards compatibility * @param os the OutputStream to write the bytes to. * @throws IOException */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { os.write('<'); os.write('<'); // loop over all the object-pairs in the HashMap PdfName key; PdfObject value; int type = 0; for (Iterator i = hashMap.keySet().iterator(); i.hasNext(); ) { key = (PdfName) i.next(); value = (PdfObject) hashMap.get(key); key.toPdf(writer, os); type = value.type(); if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) os.write(' '); value.toPdf(writer, os); } os.write('>'); os.write('>'); } /** * Returns a string representation of this PdfDictionary. * * The string doesn't contain any of the content of this dictionary. * Rather the string "dictionary" is returned, possibly followed by the * type of this PdfDictionary, if set. * * @return the string representation of this PdfDictionary * @see com.lowagie.text.pdf.PdfObject#toString() */ public String toString() { if (get(PdfName.TYPE) == null) return "Dictionary"; return "Dictionary of type: " + get(PdfName.TYPE); } // DICTIONARY CONTENT METHODS /** * Associates the specified PdfObject as value with * the specified PdfName as key in this map. * * If the map previously contained a mapping for this key, the * old value is replaced. If the value is * null or PdfNull the key is deleted. * * @param key a PdfName * @param object the PdfObject to be associated with the * key */ public void put(PdfName key, PdfObject object) { if (object == null || object.isNull()) hashMap.remove(key); else hashMap.put(key, object); } /** * Associates the specified PdfObject as value to the * specified PdfName as key in this map. * * If the value is a PdfNull, it is treated just as * any other PdfObject. If the value is * null however nothing is done. * * @param key a PdfName * @param value the PdfObject to be associated to the * key */ public void putEx(PdfName key, PdfObject value) { if (value == null) return; put(key, value); } /** * Copies all of the mappings from the specified PdfDictionary * to this PdfDictionary. * * These mappings will replace any mappings previously contained in this * PdfDictionary. * * @param dic The PdfDictionary with the mappings to be * copied over */ public void putAll(PdfDictionary dic) { hashMap.putAll(dic.hashMap); } /** * Removes a PdfObject and its key from the * PdfDictionary. * * @param key a PdfName */ public void remove(PdfName key) { hashMap.remove(key); } /** * Returns the PdfObject associated to the specified * key. * * @param key a PdfName * @return the PdfObject previously associated to the * key */ public PdfObject get(PdfName key) { return (PdfObject) hashMap.get(key); } /** * Returns the PdfObject associated to the specified * key, resolving a possible indirect reference to a direct * object. * * This method will never return a PdfIndirectReference * object. * * @param key A key for the PdfObject to be returned * @return A direct PdfObject or null */ public PdfObject getDirectObject(PdfName key) { return PdfReader.getPdfObject(get(key)); } /** * Get all keys that are set. * * @return true if it is, otherwise false. */ public Set getKeys() { return hashMap.keySet(); } /** * Returns the number of key-value mappings in this * PdfDictionary. * * @return the number of key-value mappings in this * PdfDictionary. */ public int size() { return hashMap.size(); } /** * Returns true if this PdfDictionary contains a * mapping for the specified key. * * @return true if the key is set, otherwise false. */ public boolean contains(PdfName key) { return hashMap.containsKey(key); } // DICTIONARY TYPE METHODS /** * Checks if a Dictionary is of the type FONT. * * @return true if it is, otherwise false. */ public boolean isFont() { return FONT.equals(dictionaryType); } /** * Checks if a Dictionary is of the type PAGE. * * @return true if it is, otherwise false. */ public boolean isPage() { return PAGE.equals(dictionaryType); } /** * Checks if a Dictionary is of the type PAGES. * * @return true if it is, otherwise false. */ public boolean isPages() { return PAGES.equals(dictionaryType); } /** * Checks if a Dictionary is of the type CATALOG. * * @return true if it is, otherwise false. */ public boolean isCatalog() { return CATALOG.equals(dictionaryType); } /** * Checks if a Dictionary is of the type OUTLINES. * * @return true if it is, otherwise false. */ public boolean isOutlineTree() { return OUTLINES.equals(dictionaryType); } // OTHER METHODS public void merge(PdfDictionary other) { hashMap.putAll(other.hashMap); } public void mergeDifferent(PdfDictionary other) { for (Iterator i = other.hashMap.keySet().iterator(); i.hasNext();) { Object key = i.next(); if (!hashMap.containsKey(key)) hashMap.put(key, other.hashMap.get(key)); } } // DOWNCASTING GETTERS // @author Mark A Storer (2/17/06) /** * Returns a PdfObject as a PdfDictionary, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfDictionary, it is cast down and returned as * such. Otherwise null is returned. * * @param key A PdfName * @return the associated PdfDictionary object, * or null */ public PdfDictionary getAsDict(PdfName key) { PdfDictionary dict = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isDictionary()) dict = (PdfDictionary) orig; return dict; } /** * Returns a PdfObject as a PdfArray, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfArray, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfArray object, * or null */ public PdfArray getAsArray(PdfName key) { PdfArray array = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isArray()) array = (PdfArray) orig; return array; } /** * Returns a PdfObject as a PdfStream, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfStream, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfStream object, * or null */ public PdfStream getAsStream(PdfName key) { PdfStream stream = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isStream()) stream = (PdfStream) orig; return stream; } /** * Returns a PdfObject as a PdfString, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfString, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfString object, * or null */ public PdfString getAsString(PdfName key) { PdfString string = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isString()) string = (PdfString) orig; return string; } /** * Returns a PdfObject as a PdfNumber, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfNumber, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfNumber object, * or null */ public PdfNumber getAsNumber(PdfName key) { PdfNumber number = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isNumber()) number = (PdfNumber) orig; return number; } /** * Returns a PdfObject as a PdfName, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfName, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfName object, * or null */ public PdfName getAsName(PdfName key) { PdfName name = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isName()) name = (PdfName) orig; return name; } /** * Returns a PdfObject as a PdfBoolean, * resolving indirect references. * * The object associated with the PdfName given is retrieved * and resolved to a direct object. * If it is a PdfBoolean, it is cast down and returned as such. * Otherwise null is returned. * * @param key A PdfName * @return the associated PdfBoolean object, * or null */ public PdfBoolean getAsBoolean(PdfName key) { PdfBoolean bool = null; PdfObject orig = getDirectObject(key); if (orig != null && orig.isBoolean()) bool = (PdfBoolean)orig; return bool; } /** * Returns a PdfObject as a PdfIndirectReference. * * The object associated with the PdfName given is retrieved * If it is a PdfIndirectReference, it is cast down and returned * as such. Otherwise null is returned. * * @param key A PdfName * @return the associated PdfIndirectReference object, * or null */ public PdfIndirectReference getAsIndirectObject(PdfName key) { PdfIndirectReference ref = null; PdfObject orig = get(key); // not getDirect this time. if (orig != null && orig.isIndirect()) ref = (PdfIndirectReference) orig; return ref; } }src/core/com/lowagie/text/pdf/PdfDocument.java100644 0 0 345310 11213370070 17001 0ustar 0 0 /* * $Id: PdfDocument.java 3939 2009-05-27 13:09:45Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import com.lowagie.text.Anchor; import com.lowagie.text.Annotation; import com.lowagie.text.BadElementException; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Font; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.MarkedObject; import com.lowagie.text.MarkedSection; import com.lowagie.text.Meta; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.Section; import com.lowagie.text.SimpleTable; import com.lowagie.text.Table; import com.lowagie.text.pdf.collection.PdfCollection; import com.lowagie.text.pdf.draw.DrawInterface; import com.lowagie.text.pdf.internal.PdfAnnotationsImp; import com.lowagie.text.pdf.internal.PdfViewerPreferencesImp; import java.text.DecimalFormat; /** * PdfDocument is the class that is used by PdfWriter * to translate a Document into a PDF with different pages. *

* A PdfDocument always listens to a Document * and adds the Pdf representation of every Element that is * added to the Document. * * @see com.lowagie.text.Document * @see com.lowagie.text.DocListener * @see PdfWriter * @since 2.0.8 (class was package-private before) */ public class PdfDocument extends Document { /** * PdfInfo is the PDF InfoDictionary. *

* A document's trailer may contain a reference to an Info dictionary that provides information * about the document. This optional dictionary may contain one or more keys, whose values * should be strings.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 6.10 (page 120-121) * @since 2.0.8 (PdfDocument was package-private before) */ public static class PdfInfo extends PdfDictionary { /** * Construct a PdfInfo-object. */ PdfInfo() { super(); addProducer(); addCreationDate(); } /** * Constructs a PdfInfo-object. * * @param author name of the author of the document * @param title title of the document * @param subject subject of the document */ PdfInfo(String author, String title, String subject) { this(); addTitle(title); addSubject(subject); addAuthor(author); } /** * Adds the title of the document. * * @param title the title of the document */ void addTitle(String title) { put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); } /** * Adds the subject to the document. * * @param subject the subject of the document */ void addSubject(String subject) { put(PdfName.SUBJECT, new PdfString(subject, PdfObject.TEXT_UNICODE)); } /** * Adds some keywords to the document. * * @param keywords the keywords of the document */ void addKeywords(String keywords) { put(PdfName.KEYWORDS, new PdfString(keywords, PdfObject.TEXT_UNICODE)); } /** * Adds the name of the author to the document. * * @param author the name of the author */ void addAuthor(String author) { put(PdfName.AUTHOR, new PdfString(author, PdfObject.TEXT_UNICODE)); } /** * Adds the name of the creator to the document. * * @param creator the name of the creator */ void addCreator(String creator) { put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE)); } /** * Adds the name of the producer to the document. */ void addProducer() { put(PdfName.PRODUCER, new PdfString(getVersion())); } /** * Adds the date of creation to the document. */ void addCreationDate() { PdfString date = new PdfDate(); put(PdfName.CREATIONDATE, date); put(PdfName.MODDATE, date); } void addkey(String key, String value) { if (key.equals("Producer") || key.equals("CreationDate")) return; put(new PdfName(key), new PdfString(value, PdfObject.TEXT_UNICODE)); } } /** * PdfCatalog is the PDF Catalog-object. *

* The Catalog is a dictionary that is the root node of the document. It contains a reference * to the tree of pages contained in the document, a reference to the tree of objects representing * the document's outline, a reference to the document's article threads, and the list of named * destinations. In addition, the Catalog indicates whether the document's outline or thumbnail * page images should be displayed automatically when the document is viewed and whether some location * other than the first page should be shown when the document is opened.
* In this class however, only the reference to the tree of pages is implemented.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 6.2 (page 67-71) */ static class PdfCatalog extends PdfDictionary { /** The writer writing the PDF for which we are creating this catalog object. */ PdfWriter writer; /** * Constructs a PdfCatalog. * * @param pages an indirect reference to the root of the document's Pages tree. * @param writer the writer the catalog applies to */ PdfCatalog(PdfIndirectReference pages, PdfWriter writer) { super(CATALOG); this.writer = writer; put(PdfName.PAGES, pages); } /** * Adds the names of the named destinations to the catalog. * @param localDestinations the local destinations * @param documentLevelJS the javascript used in the document * @param documentFileAttachment the attached files * @param writer the writer the catalog applies to */ void addNames(TreeMap localDestinations, HashMap documentLevelJS, HashMap documentFileAttachment, PdfWriter writer) { if (localDestinations.isEmpty() && documentLevelJS.isEmpty() && documentFileAttachment.isEmpty()) return; try { PdfDictionary names = new PdfDictionary(); if (!localDestinations.isEmpty()) { PdfArray ar = new PdfArray(); for (Iterator i = localDestinations.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String name = (String) entry.getKey(); Object obj[] = (Object[]) entry.getValue(); if (obj[2] == null) //no destination continue; PdfIndirectReference ref = (PdfIndirectReference)obj[1]; ar.add(new PdfString(name, null)); ar.add(ref); } if (ar.size() > 0) { PdfDictionary dests = new PdfDictionary(); dests.put(PdfName.NAMES, ar); names.put(PdfName.DESTS, writer.addToBody(dests).getIndirectReference()); } } if (!documentLevelJS.isEmpty()) { PdfDictionary tree = PdfNameTree.writeTree(documentLevelJS, writer); names.put(PdfName.JAVASCRIPT, writer.addToBody(tree).getIndirectReference()); } if (!documentFileAttachment.isEmpty()) { names.put(PdfName.EMBEDDEDFILES, writer.addToBody(PdfNameTree.writeTree(documentFileAttachment, writer)).getIndirectReference()); } if (names.size() > 0) put(PdfName.NAMES, writer.addToBody(names).getIndirectReference()); } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Adds an open action to the catalog. * @param action the action that will be triggered upon opening the document */ void setOpenAction(PdfAction action) { put(PdfName.OPENACTION, action); } /** * Sets the document level additional actions. * @param actions dictionary of actions */ void setAdditionalActions(PdfDictionary actions) { try { put(PdfName.AA, writer.addToBody(actions).getIndirectReference()); } catch (Exception e) { throw new ExceptionConverter(e); } } } // CONSTRUCTING A PdfDocument/PdfWriter INSTANCE /** * Constructs a new PDF document. */ public PdfDocument() { super(); addProducer(); addCreationDate(); } /** The PdfWriter. */ protected PdfWriter writer; /** * Adds a PdfWriter to the PdfDocument. * * @param writer the PdfWriter that writes everything * what is added to this document to an outputstream. * @throws DocumentException on error */ public void addWriter(PdfWriter writer) throws DocumentException { if (this.writer == null) { this.writer = writer; annotationsImp = new PdfAnnotationsImp(writer); return; } throw new DocumentException("You can only add a writer to a PdfDocument once."); } // LISTENER METHODS START // [L0] ElementListener interface /** This is the PdfContentByte object, containing the text. */ protected PdfContentByte text; /** This is the PdfContentByte object, containing the borders and other Graphics. */ protected PdfContentByte graphics; /** This represents the leading of the lines. */ protected float leading = 0; /** * Getter for the current leading. * @return the current leading * @since 2.1.2 */ public float getLeading() { return leading; } /** * Setter for the current leading. * @param leading the current leading * @since 2.1.6 */ void setLeading(float leading) { this.leading = leading; } /** This represents the current alignment of the PDF Elements. */ protected int alignment = Element.ALIGN_LEFT; /** This is the current height of the document. */ protected float currentHeight = 0; /** * Signals that onParagraph is valid (to avoid that a Chapter/Section title is treated as a Paragraph). * @since 2.1.2 */ protected boolean isSectionTitle = false; /** * Signals that the current leading has to be subtracted from a YMark object when positive. * @since 2.1.2 */ protected int leadingCount = 0; /** The current active PdfAction when processing an Anchor. */ protected PdfAction anchorAction = null; /** * Signals that an Element was added to the Document. * * @param element the element to add * @return true if the element was added, false if not. * @throws DocumentException when a document isn't open yet, or has been closed */ public boolean add(Element element) throws DocumentException { if (writer != null && writer.isPaused()) { return false; } try { switch(element.type()) { // Information (headers) case Element.HEADER: info.addkey(((Meta)element).getName(), ((Meta)element).getContent()); break; case Element.TITLE: info.addTitle(((Meta)element).getContent()); break; case Element.SUBJECT: info.addSubject(((Meta)element).getContent()); break; case Element.KEYWORDS: info.addKeywords(((Meta)element).getContent()); break; case Element.AUTHOR: info.addAuthor(((Meta)element).getContent()); break; case Element.CREATOR: info.addCreator(((Meta)element).getContent()); break; case Element.PRODUCER: // you can not change the name of the producer info.addProducer(); break; case Element.CREATIONDATE: // you can not set the creation date, only reset it info.addCreationDate(); break; // content (text) case Element.CHUNK: { // if there isn't a current line available, we make one if (line == null) { carriageReturn(); } // we cast the element to a chunk PdfChunk chunk = new PdfChunk((Chunk) element, anchorAction); // we try to add the chunk to the line, until we succeed { PdfChunk overflow; while ((overflow = line.add(chunk)) != null) { carriageReturn(); chunk = overflow; chunk.trimFirstSpace(); } } pageEmpty = false; if (chunk.isAttribute(Chunk.NEWPAGE)) { newPage(); } break; } case Element.ANCHOR: { leadingCount++; Anchor anchor = (Anchor) element; String url = anchor.getReference(); leading = anchor.getLeading(); if (url != null) { anchorAction = new PdfAction(url); } // we process the element element.process(this); anchorAction = null; leadingCount--; break; } case Element.ANNOTATION: { if (line == null) { carriageReturn(); } Annotation annot = (Annotation) element; Rectangle rect = new Rectangle(0, 0); if (line != null) rect = new Rectangle(annot.llx(indentRight() - line.widthLeft()), annot.lly(indentTop() - currentHeight), annot.urx(indentRight() - line.widthLeft() + 20), annot.ury(indentTop() - currentHeight - 20)); PdfAnnotation an = PdfAnnotationsImp.convertAnnotation(writer, annot, rect); annotationsImp.addPlainAnnotation(an); pageEmpty = false; break; } case Element.PHRASE: { leadingCount++; // we cast the element to a phrase and set the leading of the document leading = ((Phrase) element).getLeading(); // we process the element element.process(this); leadingCount--; break; } case Element.PARAGRAPH: { leadingCount++; // we cast the element to a paragraph Paragraph paragraph = (Paragraph) element; addSpacing(paragraph.getSpacingBefore(), leading, paragraph.getFont()); // we adjust the parameters of the document alignment = paragraph.getAlignment(); leading = paragraph.getTotalLeading(); carriageReturn(); // we don't want to make orphans/widows if (currentHeight + line.height() + leading > indentTop() - indentBottom()) { newPage(); } indentation.indentLeft += paragraph.getIndentationLeft(); indentation.indentRight += paragraph.getIndentationRight(); carriageReturn(); PdfPageEvent pageEvent = writer.getPageEvent(); if (pageEvent != null && !isSectionTitle) pageEvent.onParagraph(writer, this, indentTop() - currentHeight); // if a paragraph has to be kept together, we wrap it in a table object if (paragraph.getKeepTogether()) { carriageReturn(); PdfPTable table = new PdfPTable(1); table.setWidthPercentage(100f); PdfPCell cell = new PdfPCell(); cell.addElement(paragraph); cell.setBorder(Table.NO_BORDER); cell.setPadding(0); table.addCell(cell); indentation.indentLeft -= paragraph.getIndentationLeft(); indentation.indentRight -= paragraph.getIndentationRight(); this.add(table); indentation.indentLeft += paragraph.getIndentationLeft(); indentation.indentRight += paragraph.getIndentationRight(); } else { line.setExtraIndent(paragraph.getFirstLineIndent()); element.process(this); carriageReturn(); addSpacing(paragraph.getSpacingAfter(), paragraph.getTotalLeading(), paragraph.getFont()); } if (pageEvent != null && !isSectionTitle) pageEvent.onParagraphEnd(writer, this, indentTop() - currentHeight); alignment = Element.ALIGN_LEFT; indentation.indentLeft -= paragraph.getIndentationLeft(); indentation.indentRight -= paragraph.getIndentationRight(); carriageReturn(); leadingCount--; break; } case Element.SECTION: case Element.CHAPTER: { // Chapters and Sections only differ in their constructor // so we cast both to a Section Section section = (Section) element; PdfPageEvent pageEvent = writer.getPageEvent(); boolean hasTitle = section.isNotAddedYet() && section.getTitle() != null; // if the section is a chapter, we begin a new page if (section.isTriggerNewPage()) { newPage(); } if (hasTitle) { float fith = indentTop() - currentHeight; int rotation = pageSize.getRotation(); if (rotation == 90 || rotation == 180) fith = pageSize.getHeight() - fith; PdfDestination destination = new PdfDestination(PdfDestination.FITH, fith); while (currentOutline.level() >= section.getDepth()) { currentOutline = currentOutline.parent(); } PdfOutline outline = new PdfOutline(currentOutline, destination, section.getBookmarkTitle(), section.isBookmarkOpen()); currentOutline = outline; } // some values are set carriageReturn(); indentation.sectionIndentLeft += section.getIndentationLeft(); indentation.sectionIndentRight += section.getIndentationRight(); if (section.isNotAddedYet() && pageEvent != null) if (element.type() == Element.CHAPTER) pageEvent.onChapter(writer, this, indentTop() - currentHeight, section.getTitle()); else pageEvent.onSection(writer, this, indentTop() - currentHeight, section.getDepth(), section.getTitle()); // the title of the section (if any has to be printed) if (hasTitle) { isSectionTitle = true; add(section.getTitle()); isSectionTitle = false; } indentation.sectionIndentLeft += section.getIndentation(); // we process the section element.process(this); flushLines(); // some parameters are set back to normal again indentation.sectionIndentLeft -= (section.getIndentationLeft() + section.getIndentation()); indentation.sectionIndentRight -= section.getIndentationRight(); if (section.isComplete() && pageEvent != null) if (element.type() == Element.CHAPTER) pageEvent.onChapterEnd(writer, this, indentTop() - currentHeight); else pageEvent.onSectionEnd(writer, this, indentTop() - currentHeight); break; } case Element.LIST: { // we cast the element to a List List list = (List) element; if (list.isAlignindent()) { list.normalizeIndentation(); } // we adjust the document indentation.listIndentLeft += list.getIndentationLeft(); indentation.indentRight += list.getIndentationRight(); // we process the items in the list element.process(this); // some parameters are set back to normal again indentation.listIndentLeft -= list.getIndentationLeft(); indentation.indentRight -= list.getIndentationRight(); carriageReturn(); break; } case Element.LISTITEM: { leadingCount++; // we cast the element to a ListItem ListItem listItem = (ListItem) element; addSpacing(listItem.getSpacingBefore(), leading, listItem.getFont()); // we adjust the document alignment = listItem.getAlignment(); indentation.listIndentLeft += listItem.getIndentationLeft(); indentation.indentRight += listItem.getIndentationRight(); leading = listItem.getTotalLeading(); carriageReturn(); // we prepare the current line to be able to show us the listsymbol line.setListItem(listItem); // we process the item element.process(this); addSpacing(listItem.getSpacingAfter(), listItem.getTotalLeading(), listItem.getFont()); // if the last line is justified, it should be aligned to the left if (line.hasToBeJustified()) { line.resetAlignment(); } // some parameters are set back to normal again carriageReturn(); indentation.listIndentLeft -= listItem.getIndentationLeft(); indentation.indentRight -= listItem.getIndentationRight(); leadingCount--; break; } case Element.RECTANGLE: { Rectangle rectangle = (Rectangle) element; graphics.rectangle(rectangle); pageEmpty = false; break; } case Element.PTABLE: { PdfPTable ptable = (PdfPTable)element; if (ptable.size() <= ptable.getHeaderRows()) break; //nothing to do // before every table, we add a new line and flush all lines ensureNewLine(); flushLines(); addPTable(ptable); pageEmpty = false; newLine(); break; } case Element.MULTI_COLUMN_TEXT: { ensureNewLine(); flushLines(); MultiColumnText multiText = (MultiColumnText) element; float height = multiText.write(writer.getDirectContent(), this, indentTop() - currentHeight); currentHeight += height; text.moveText(0, -1f* height); pageEmpty = false; break; } case Element.TABLE : { if (element instanceof SimpleTable) { PdfPTable ptable = ((SimpleTable)element).createPdfPTable(); if (ptable.size() <= ptable.getHeaderRows()) break; //nothing to do // before every table, we add a new line and flush all lines ensureNewLine(); flushLines(); addPTable(ptable); pageEmpty = false; break; } else if (element instanceof Table) { try { PdfPTable ptable = ((Table)element).createPdfPTable(); if (ptable.size() <= ptable.getHeaderRows()) break; //nothing to do // before every table, we add a new line and flush all lines ensureNewLine(); flushLines(); addPTable(ptable); pageEmpty = false; break; } catch(BadElementException bee) { // constructing the PdfTable // Before the table, add a blank line using offset or default leading float offset = ((Table)element).getOffset(); if (Float.isNaN(offset)) offset = leading; carriageReturn(); lines.add(new PdfLine(indentLeft(), indentRight(), alignment, offset)); currentHeight += offset; addPdfTable((Table)element); } } else { return false; } break; } case Element.JPEG: case Element.JPEG2000: case Element.JBIG2: case Element.IMGRAW: case Element.IMGTEMPLATE: { //carriageReturn(); suggestion by Marc Campforts add((Image) element); break; } case Element.YMARK: { DrawInterface zh = (DrawInterface)element; zh.draw(graphics, indentLeft(), indentBottom(), indentRight(), indentTop(), indentTop() - currentHeight - (leadingCount > 0 ? leading : 0)); pageEmpty = false; break; } case Element.MARKED: { MarkedObject mo; if (element instanceof MarkedSection) { mo = ((MarkedSection)element).getTitle(); if (mo != null) { mo.process(this); } } mo = (MarkedObject)element; mo.process(this); break; } default: return false; } lastElementType = element.type(); return true; } catch(Exception e) { throw new DocumentException(e); } } // [L1] DocListener interface /** * Opens the document. *

* You have to open the document before you can begin to add content * to the body of the document. */ public void open() { if (!open) { super.open(); writer.open(); rootOutline = new PdfOutline(writer); currentOutline = rootOutline; } try { initPage(); } catch(DocumentException de) { throw new ExceptionConverter(de); } } // [L2] DocListener interface /** * Closes the document. * * Once all the content has been written in the body, you have to close * the body. After that nothing can be written to the body anymore. */ public void close() { if (close) { return; } try { boolean wasImage = (imageWait != null); newPage(); if (imageWait != null || wasImage) newPage(); if (annotationsImp.hasUnusedAnnotations()) throw new RuntimeException("Not all annotations could be added to the document (the document doesn't have enough pages)."); PdfPageEvent pageEvent = writer.getPageEvent(); if (pageEvent != null) pageEvent.onCloseDocument(writer, this); super.close(); writer.addLocalDestinations(localDestinations); calculateOutlineCount(); writeOutlines(); } catch(Exception e) { throw ExceptionConverter.convertException(e); } writer.close(); } // [L3] DocListener interface protected int textEmptySize; // [C9] Metadata for the page /** XMP Metadata for the page. */ protected byte[] xmpMetadata = null; /** * Use this method to set the XMP Metadata. * @param xmpMetadata The xmpMetadata to set. */ public void setXmpMetadata(byte[] xmpMetadata) { this.xmpMetadata = xmpMetadata; } /** * Makes a new page and sends it to the PdfWriter. * * @return a boolean */ public boolean newPage() { lastElementType = -1; if (writer == null || (writer.getDirectContent().size() == 0 && writer.getDirectContentUnder().size() == 0 && (pageEmpty || writer.isPaused()))) { setNewPageSizeAndMargins(); return false; } if (!open || close) { throw new RuntimeException("The document isn't open."); } PdfPageEvent pageEvent = writer.getPageEvent(); if (pageEvent != null) pageEvent.onEndPage(writer, this); //Added to inform any listeners that we are moving to a new page (added by David Freels) super.newPage(); // the following 2 lines were added by Pelikan Stephan indentation.imageIndentLeft = 0; indentation.imageIndentRight = 0; try { // we flush the arraylist with recently written lines flushLines(); // we prepare the elements of the page dictionary // [U1] page size and rotation int rotation = pageSize.getRotation(); // [C10] if (writer.isPdfX()) { if (thisBoxSize.containsKey("art") && thisBoxSize.containsKey("trim")) throw new PdfXConformanceException("Only one of ArtBox or TrimBox can exist in the page."); if (!thisBoxSize.containsKey("art") && !thisBoxSize.containsKey("trim")) { if (thisBoxSize.containsKey("crop")) thisBoxSize.put("trim", thisBoxSize.get("crop")); else thisBoxSize.put("trim", new PdfRectangle(pageSize, pageSize.getRotation())); } } // [M1] pageResources.addDefaultColorDiff(writer.getDefaultColorspace()); if (writer.isRgbTransparencyBlending()) { PdfDictionary dcs = new PdfDictionary(); dcs.put(PdfName.CS, PdfName.DEVICERGB); pageResources.addDefaultColorDiff(dcs); } PdfDictionary resources = pageResources.getResources(); // we create the page dictionary PdfPage page = new PdfPage(new PdfRectangle(pageSize, rotation), thisBoxSize, resources, rotation); page.put(PdfName.TABS, writer.getTabs()); // we complete the page dictionary // [C9] if there is XMP data to add: add it if (xmpMetadata != null) { PdfStream xmp = new PdfStream(xmpMetadata); xmp.put(PdfName.TYPE, PdfName.METADATA); xmp.put(PdfName.SUBTYPE, PdfName.XML); PdfEncryption crypto = writer.getEncryption(); if (crypto != null && !crypto.isMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.add(PdfName.CRYPT); xmp.put(PdfName.FILTER, ar); } page.put(PdfName.METADATA, writer.addToBody(xmp).getIndirectReference()); } // [U3] page actions: transition, duration, additional actions if (this.transition!=null) { page.put(PdfName.TRANS, this.transition.getTransitionDictionary()); transition = null; } if (this.duration>0) { page.put(PdfName.DUR,new PdfNumber(this.duration)); duration = 0; } if (pageAA != null) { page.put(PdfName.AA, writer.addToBody(pageAA).getIndirectReference()); pageAA = null; } // [U4] we add the thumbs if (thumb != null) { page.put(PdfName.THUMB, thumb); thumb = null; } // [U8] we check if the userunit is defined if (writer.getUserunit() > 0f) { page.put(PdfName.USERUNIT, new PdfNumber(writer.getUserunit())); } // [C5] and [C8] we add the annotations if (annotationsImp.hasUnusedAnnotations()) { PdfArray array = annotationsImp.rotateAnnotations(writer, pageSize); if (array.size() != 0) page.put(PdfName.ANNOTS, array); } // [F12] we add tag info if (writer.isTagged()) page.put(PdfName.STRUCTPARENTS, new PdfNumber(writer.getCurrentPageNumber() - 1)); if (text.size() > textEmptySize) text.endText(); else text = null; writer.add(page, new PdfContents(writer.getDirectContentUnder(), graphics, text, writer.getDirectContent(), pageSize)); // we initialize the new page initPage(); } catch(DocumentException de) { // maybe this never happens, but it's better to check. throw new ExceptionConverter(de); } catch (IOException ioe) { throw new ExceptionConverter(ioe); } return true; } // [L4] DocListener interface /** * Sets the pagesize. * * @param pageSize the new pagesize * @return true if the page size was set */ public boolean setPageSize(Rectangle pageSize) { if (writer != null && writer.isPaused()) { return false; } nextPageSize = new Rectangle(pageSize); return true; } // [L5] DocListener interface /** margin in x direction starting from the left. Will be valid in the next page */ protected float nextMarginLeft; /** margin in x direction starting from the right. Will be valid in the next page */ protected float nextMarginRight; /** margin in y direction starting from the top. Will be valid in the next page */ protected float nextMarginTop; /** margin in y direction starting from the bottom. Will be valid in the next page */ protected float nextMarginBottom; /** * Sets the margins. * * @param marginLeft the margin on the left * @param marginRight the margin on the right * @param marginTop the margin on the top * @param marginBottom the margin on the bottom * @return a boolean */ public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { if (writer != null && writer.isPaused()) { return false; } nextMarginLeft = marginLeft; nextMarginRight = marginRight; nextMarginTop = marginTop; nextMarginBottom = marginBottom; return true; } // [L6] DocListener interface /** * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) */ public boolean setMarginMirroring(boolean MarginMirroring) { if (writer != null && writer.isPaused()) { return false; } return super.setMarginMirroring(MarginMirroring); } /** * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) * @since 2.1.6 */ public boolean setMarginMirroringTopBottom(boolean MarginMirroringTopBottom) { if (writer != null && writer.isPaused()) { return false; } return super.setMarginMirroringTopBottom(MarginMirroringTopBottom); } // [L7] DocListener interface /** * Sets the page number. * * @param pageN the new page number */ public void setPageCount(int pageN) { if (writer != null && writer.isPaused()) { return; } super.setPageCount(pageN); } // [L8] DocListener interface /** * Sets the page number to 0. */ public void resetPageCount() { if (writer != null && writer.isPaused()) { return; } super.resetPageCount(); } // [L9] DocListener interface /** * Changes the header of this document. * * @param header the new header */ public void setHeader(HeaderFooter header) { if (writer != null && writer.isPaused()) { return; } super.setHeader(header); } // [L10] DocListener interface /** * Resets the header of this document. */ public void resetHeader() { if (writer != null && writer.isPaused()) { return; } super.resetHeader(); } // [L11] DocListener interface /** * Changes the footer of this document. * * @param footer the new footer */ public void setFooter(HeaderFooter footer) { if (writer != null && writer.isPaused()) { return; } super.setFooter(footer); } // [L12] DocListener interface /** * Resets the footer of this document. */ public void resetFooter() { if (writer != null && writer.isPaused()) { return; } super.resetFooter(); } // DOCLISTENER METHODS END /** Signals that OnOpenDocument should be called. */ protected boolean firstPageEvent = true; /** * Initializes a page. *

* If the footer/header is set, it is printed. * @throws DocumentException on error */ protected void initPage() throws DocumentException { // the pagenumber is incremented pageN++; // initialization of some page objects annotationsImp.resetAnnotations(); pageResources = new PageResources(); writer.resetContent(); graphics = new PdfContentByte(writer); text = new PdfContentByte(writer); text.reset(); text.beginText(); textEmptySize = text.size(); markPoint = 0; setNewPageSizeAndMargins(); imageEnd = -1; indentation.imageIndentRight = 0; indentation.imageIndentLeft = 0; indentation.indentBottom = 0; indentation.indentTop = 0; currentHeight = 0; // backgroundcolors, etc... thisBoxSize = new HashMap(boxSize); if (pageSize.getBackgroundColor() != null || pageSize.hasBorders() || pageSize.getBorderColor() != null) { add(pageSize); } float oldleading = leading; int oldAlignment = alignment; // if there is a footer, the footer is added doFooter(); // we move to the left/top position of the page text.moveText(left(), top()); doHeader(); pageEmpty = true; // if there is an image waiting to be drawn, draw it try { if (imageWait != null) { add(imageWait); imageWait = null; } } catch(Exception e) { throw new ExceptionConverter(e); } leading = oldleading; alignment = oldAlignment; carriageReturn(); PdfPageEvent pageEvent = writer.getPageEvent(); if (pageEvent != null) { if (firstPageEvent) { pageEvent.onOpenDocument(writer, this); } pageEvent.onStartPage(writer, this); } firstPageEvent = false; } /** The line that is currently being written. */ protected PdfLine line = null; /** The lines that are written until now. */ protected ArrayList lines = new ArrayList(); /** * Adds the current line to the list of lines and also adds an empty line. * @throws DocumentException on error */ protected void newLine() throws DocumentException { lastElementType = -1; carriageReturn(); if (lines != null && !lines.isEmpty()) { lines.add(line); currentHeight += line.height(); } line = new PdfLine(indentLeft(), indentRight(), alignment, leading); } /** * If the current line is not empty or null, it is added to the arraylist * of lines and a new empty line is added. */ protected void carriageReturn() { // the arraylist with lines may not be null if (lines == null) { lines = new ArrayList(); } // If the current line is not null if (line != null) { // we check if the end of the page is reached (bugfix by Francois Gravel) if (currentHeight + line.height() + leading < indentTop() - indentBottom()) { // if so nonempty lines are added and the height is augmented if (line.size() > 0) { currentHeight += line.height(); lines.add(line); pageEmpty = false; } } // if the end of the line is reached, we start a new page else { newPage(); } } if (imageEnd > -1 && currentHeight > imageEnd) { imageEnd = -1; indentation.imageIndentRight = 0; indentation.imageIndentLeft = 0; } // a new current line is constructed line = new PdfLine(indentLeft(), indentRight(), alignment, leading); } /** * Gets the current vertical page position. * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects * for elements that do not terminate the lines they've started because those lines will get * terminated. * @return The current vertical page position. */ public float getVerticalPosition(boolean ensureNewLine) { // ensuring that a new line has been started. if (ensureNewLine) { ensureNewLine(); } return top() - currentHeight - indentation.indentTop; } /** Holds the type of the last element, that has been added to the document. */ protected int lastElementType = -1; /** * Ensures that a new line has been started. */ protected void ensureNewLine() { try { if ((lastElementType == Element.PHRASE) || (lastElementType == Element.CHUNK)) { newLine(); flushLines(); } } catch (DocumentException ex) { throw new ExceptionConverter(ex); } } /** * Writes all the lines to the text-object. * * @return the displacement that was caused * @throws DocumentException on error */ protected float flushLines() throws DocumentException { // checks if the ArrayList with the lines is not null if (lines == null) { return 0; } // checks if a new Line has to be made. if (line != null && line.size() > 0) { lines.add(line); line = new PdfLine(indentLeft(), indentRight(), alignment, leading); } // checks if the ArrayList with the lines is empty if (lines.isEmpty()) { return 0; } // initialization of some parameters Object currentValues[] = new Object[2]; PdfFont currentFont = null; float displacement = 0; PdfLine l; Float lastBaseFactor = new Float(0); currentValues[1] = lastBaseFactor; // looping over all the lines for (Iterator i = lines.iterator(); i.hasNext(); ) { // this is a line in the loop l = (PdfLine) i.next(); float moveTextX = l.indentLeft() - indentLeft() + indentation.indentLeft + indentation.listIndentLeft + indentation.sectionIndentLeft; text.moveText(moveTextX, -l.height()); // is the line preceded by a symbol? if (l.listSymbol() != null) { ColumnText.showTextAligned(graphics, Element.ALIGN_LEFT, new Phrase(l.listSymbol()), text.getXTLM() - l.listIndent(), text.getYTLM(), 0); } currentValues[0] = currentFont; writeLineToContent(l, text, graphics, currentValues, writer.getSpaceCharRatio()); currentFont = (PdfFont)currentValues[0]; displacement += l.height(); text.moveText(-moveTextX, 0); } lines = new ArrayList(); return displacement; } /** The characters to be applied the hanging punctuation. */ static final String hangingPunctuation = ".,;:'"; /** * Writes a text line to the document. It takes care of all the attributes. *

* Before entering the line position must have been established and the * text argument must be in text object scope (beginText()). * @param line the line to be written * @param text the PdfContentByte where the text will be written to * @param graphics the PdfContentByte where the graphics will be written to * @param currentValues the current font and extra spacing values * @param ratio * @throws DocumentException on error */ void writeLineToContent(PdfLine line, PdfContentByte text, PdfContentByte graphics, Object currentValues[], float ratio) throws DocumentException { PdfFont currentFont = (PdfFont)(currentValues[0]); float lastBaseFactor = ((Float)(currentValues[1])).floatValue(); PdfChunk chunk; int numberOfSpaces; int lineLen; boolean isJustified; float hangingCorrection = 0; float hScale = 1; float lastHScale = Float.NaN; float baseWordSpacing = 0; float baseCharacterSpacing = 0; float glueWidth = 0; numberOfSpaces = line.numberOfSpaces(); lineLen = line.GetLineLengthUtf32(); // does the line need to be justified? isJustified = line.hasToBeJustified() && (numberOfSpaces != 0 || lineLen > 1); int separatorCount = line.getSeparatorCount(); if (separatorCount > 0) { glueWidth = line.widthLeft() / separatorCount; } else if (isJustified) { if (line.isNewlineSplit() && line.widthLeft() >= (lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1))) { if (line.isRTL()) { text.moveText(line.widthLeft() - lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1), 0); } baseWordSpacing = ratio * lastBaseFactor; baseCharacterSpacing = lastBaseFactor; } else { float width = line.widthLeft(); PdfChunk last = line.getChunk(line.size() - 1); if (last != null) { String s = last.toString(); char c; if (s.length() > 0 && hangingPunctuation.indexOf((c = s.charAt(s.length() - 1))) >= 0) { float oldWidth = width; width += last.font().width(c) * 0.4f; hangingCorrection = width - oldWidth; } } float baseFactor = width / (ratio * numberOfSpaces + lineLen - 1); baseWordSpacing = ratio * baseFactor; baseCharacterSpacing = baseFactor; lastBaseFactor = baseFactor; } } int lastChunkStroke = line.getLastStrokeChunk(); int chunkStrokeIdx = 0; float xMarker = text.getXTLM(); float baseXMarker = xMarker; float yMarker = text.getYTLM(); boolean adjustMatrix = false; float tabPosition = 0; // looping over all the chunks in 1 line for (Iterator j = line.iterator(); j.hasNext(); ) { chunk = (PdfChunk) j.next(); Color color = chunk.color(); hScale = 1; if (chunkStrokeIdx <= lastChunkStroke) { float width; if (isJustified) { width = chunk.getWidthCorrected(baseCharacterSpacing, baseWordSpacing); } else { width = chunk.width(); } if (chunk.isStroked()) { PdfChunk nextChunk = line.getChunk(chunkStrokeIdx + 1); if (chunk.isSeparator()) { width = glueWidth; Object[] sep = (Object[])chunk.getAttribute(Chunk.SEPARATOR); DrawInterface di = (DrawInterface)sep[0]; Boolean vertical = (Boolean)sep[1]; float fontSize = chunk.font().size(); float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); if (vertical.booleanValue()) { di.draw(graphics, baseXMarker, yMarker + descender, baseXMarker + line.getOriginalWidth(), ascender - descender, yMarker); } else { di.draw(graphics, xMarker, yMarker + descender, xMarker + width, ascender - descender, yMarker); } } if (chunk.isTab()) { Object[] tab = (Object[])chunk.getAttribute(Chunk.TAB); DrawInterface di = (DrawInterface)tab[0]; tabPosition = ((Float)tab[1]).floatValue() + ((Float)tab[3]).floatValue(); float fontSize = chunk.font().size(); float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); if (tabPosition > xMarker) { di.draw(graphics, xMarker, yMarker + descender, tabPosition, ascender - descender, yMarker); } float tmp = xMarker; xMarker = tabPosition; tabPosition = tmp; } if (chunk.isAttribute(Chunk.BACKGROUND)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.BACKGROUND)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; float fontSize = chunk.font().size(); float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); Object bgr[] = (Object[])chunk.getAttribute(Chunk.BACKGROUND); graphics.setColorFill((Color)bgr[0]); float extra[] = (float[])bgr[1]; graphics.rectangle(xMarker - extra[0], yMarker + descender - extra[1] + chunk.getTextRise(), width - subtract + extra[0] + extra[2], ascender - descender + extra[1] + extra[3]); graphics.fill(); graphics.setGrayFill(0); } if (chunk.isAttribute(Chunk.UNDERLINE)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.UNDERLINE)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; Object unders[][] = (Object[][])chunk.getAttribute(Chunk.UNDERLINE); Color scolor = null; for (int k = 0; k < unders.length; ++k) { Object obj[] = unders[k]; scolor = (Color)obj[0]; float ps[] = (float[])obj[1]; if (scolor == null) scolor = color; if (scolor != null) graphics.setColorStroke(scolor); float fsize = chunk.font().size(); graphics.setLineWidth(ps[0] + fsize * ps[1]); float shift = ps[2] + fsize * ps[3]; int cap2 = (int)ps[4]; if (cap2 != 0) graphics.setLineCap(cap2); graphics.moveTo(xMarker, yMarker + shift); graphics.lineTo(xMarker + width - subtract, yMarker + shift); graphics.stroke(); if (scolor != null) graphics.resetGrayStroke(); if (cap2 != 0) graphics.setLineCap(0); } graphics.setLineWidth(1); } if (chunk.isAttribute(Chunk.ACTION)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.ACTION)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; text.addAnnotation(new PdfAnnotation(writer, xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size(), (PdfAction)chunk.getAttribute(Chunk.ACTION))); } if (chunk.isAttribute(Chunk.REMOTEGOTO)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.REMOTEGOTO)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; Object obj[] = (Object[])chunk.getAttribute(Chunk.REMOTEGOTO); String filename = (String)obj[0]; if (obj[1] instanceof String) remoteGoto(filename, (String)obj[1], xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); else remoteGoto(filename, ((Integer)obj[1]).intValue(), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); } if (chunk.isAttribute(Chunk.LOCALGOTO)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALGOTO)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; localGoto((String)chunk.getAttribute(Chunk.LOCALGOTO), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); } if (chunk.isAttribute(Chunk.LOCALDESTINATION)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALDESTINATION)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; localDestination((String)chunk.getAttribute(Chunk.LOCALDESTINATION), new PdfDestination(PdfDestination.XYZ, xMarker, yMarker + chunk.font().size(), 0)); } if (chunk.isAttribute(Chunk.GENERICTAG)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.GENERICTAG)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; Rectangle rect = new Rectangle(xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); PdfPageEvent pev = writer.getPageEvent(); if (pev != null) pev.onGenericTag(writer, this, rect, (String)chunk.getAttribute(Chunk.GENERICTAG)); } if (chunk.isAttribute(Chunk.PDFANNOTATION)) { float subtract = lastBaseFactor; if (nextChunk != null && nextChunk.isAttribute(Chunk.PDFANNOTATION)) subtract = 0; if (nextChunk == null) subtract += hangingCorrection; float fontSize = chunk.font().size(); float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); PdfAnnotation annot = PdfFormField.shallowDuplicate((PdfAnnotation)chunk.getAttribute(Chunk.PDFANNOTATION)); annot.put(PdfName.RECT, new PdfRectangle(xMarker, yMarker + descender, xMarker + width - subtract, yMarker + ascender)); text.addAnnotation(annot); } float params[] = (float[])chunk.getAttribute(Chunk.SKEW); Float hs = (Float)chunk.getAttribute(Chunk.HSCALE); if (params != null || hs != null) { float b = 0, c = 0; if (params != null) { b = params[0]; c = params[1]; } if (hs != null) hScale = hs.floatValue(); text.setTextMatrix(hScale, b, c, 1, xMarker, yMarker); } if (chunk.isImage()) { Image image = chunk.getImage(); float matrix[] = image.matrix(); matrix[Image.CX] = xMarker + chunk.getImageOffsetX() - matrix[Image.CX]; matrix[Image.CY] = yMarker + chunk.getImageOffsetY() - matrix[Image.CY]; graphics.addImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); text.moveText(xMarker + lastBaseFactor + image.getScaledWidth() - text.getXTLM(), 0); } } xMarker += width; ++chunkStrokeIdx; } if (chunk.font().compareTo(currentFont) != 0) { currentFont = chunk.font(); text.setFontAndSize(currentFont.getFont(), currentFont.size()); } float rise = 0; Object textRender[] = (Object[])chunk.getAttribute(Chunk.TEXTRENDERMODE); int tr = 0; float strokeWidth = 1; Color strokeColor = null; Float fr = (Float)chunk.getAttribute(Chunk.SUBSUPSCRIPT); if (textRender != null) { tr = ((Integer)textRender[0]).intValue() & 3; if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL) text.setTextRenderingMode(tr); if (tr == PdfContentByte.TEXT_RENDER_MODE_STROKE || tr == PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE) { strokeWidth = ((Float)textRender[1]).floatValue(); if (strokeWidth != 1) text.setLineWidth(strokeWidth); strokeColor = (Color)textRender[2]; if (strokeColor == null) strokeColor = color; if (strokeColor != null) text.setColorStroke(strokeColor); } } if (fr != null) rise = fr.floatValue(); if (color != null) text.setColorFill(color); if (rise != 0) text.setTextRise(rise); if (chunk.isImage()) { adjustMatrix = true; } else if (chunk.isHorizontalSeparator()) { PdfTextArray array = new PdfTextArray(); array.add(-glueWidth * 1000f / chunk.font.size() / hScale); text.showText(array); } else if (chunk.isTab()) { PdfTextArray array = new PdfTextArray(); array.add((tabPosition - xMarker) * 1000f / chunk.font.size() / hScale); text.showText(array); } // If it is a CJK chunk or Unicode TTF we will have to simulate the // space adjustment. else if (isJustified && numberOfSpaces > 0 && chunk.isSpecialEncoding()) { if (hScale != lastHScale) { lastHScale = hScale; text.setWordSpacing(baseWordSpacing / hScale); text.setCharacterSpacing(baseCharacterSpacing / hScale); } String s = chunk.toString(); int idx = s.indexOf(' '); if (idx < 0) text.showText(s); else { float spaceCorrection = - baseWordSpacing * 1000f / chunk.font.size() / hScale; PdfTextArray textArray = new PdfTextArray(s.substring(0, idx)); int lastIdx = idx; while ((idx = s.indexOf(' ', lastIdx + 1)) >= 0) { textArray.add(spaceCorrection); textArray.add(s.substring(lastIdx, idx)); lastIdx = idx; } textArray.add(spaceCorrection); textArray.add(s.substring(lastIdx)); text.showText(textArray); } } else { if (isJustified && hScale != lastHScale) { lastHScale = hScale; text.setWordSpacing(baseWordSpacing / hScale); text.setCharacterSpacing(baseCharacterSpacing / hScale); } text.showText(chunk.toString()); } if (rise != 0) text.setTextRise(0); if (color != null) text.resetRGBColorFill(); if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL) text.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); if (strokeColor != null) text.resetRGBColorStroke(); if (strokeWidth != 1) text.setLineWidth(1); if (chunk.isAttribute(Chunk.SKEW) || chunk.isAttribute(Chunk.HSCALE)) { adjustMatrix = true; text.setTextMatrix(xMarker, yMarker); } } if (isJustified) { text.setWordSpacing(0); text.setCharacterSpacing(0); if (line.isNewlineSplit()) lastBaseFactor = 0; } if (adjustMatrix) text.moveText(baseXMarker - text.getXTLM(), 0); currentValues[0] = currentFont; currentValues[1] = new Float(lastBaseFactor); } protected Indentation indentation = new Indentation(); /** * @since 2.0.8 (PdfDocument was package-private before) */ public static class Indentation { /** This represents the current indentation of the PDF Elements on the left side. */ float indentLeft = 0; /** Indentation to the left caused by a section. */ float sectionIndentLeft = 0; /** This represents the current indentation of the PDF Elements on the left side. */ float listIndentLeft = 0; /** This is the indentation caused by an image on the left. */ float imageIndentLeft = 0; /** This represents the current indentation of the PDF Elements on the right side. */ float indentRight = 0; /** Indentation to the right caused by a section. */ float sectionIndentRight = 0; /** This is the indentation caused by an image on the right. */ float imageIndentRight = 0; /** This represents the current indentation of the PDF Elements on the top side. */ float indentTop = 0; /** This represents the current indentation of the PDF Elements on the bottom side. */ float indentBottom = 0; } /** * Gets the indentation on the left side. * * @return a margin */ protected float indentLeft() { return left(indentation.indentLeft + indentation.listIndentLeft + indentation.imageIndentLeft + indentation.sectionIndentLeft); } /** * Gets the indentation on the right side. * * @return a margin */ protected float indentRight() { return right(indentation.indentRight + indentation.sectionIndentRight + indentation.imageIndentRight); } /** * Gets the indentation on the top side. * * @return a margin */ protected float indentTop() { return top(indentation.indentTop); } /** * Gets the indentation on the bottom side. * * @return a margin */ float indentBottom() { return bottom(indentation.indentBottom); } /** * Adds extra space. * This method should probably be rewritten. */ protected void addSpacing(float extraspace, float oldleading, Font f) { if (extraspace == 0) return; if (pageEmpty) return; if (currentHeight + line.height() + leading > indentTop() - indentBottom()) return; leading = extraspace; carriageReturn(); if (f.isUnderlined() || f.isStrikethru()) { f = new Font(f); int style = f.getStyle(); style &= ~Font.UNDERLINE; style &= ~Font.STRIKETHRU; f.setStyle(style); } Chunk space = new Chunk(" ", f); space.process(this); carriageReturn(); leading = oldleading; } // Info Dictionary and Catalog /** some meta information about the Document. */ protected PdfInfo info = new PdfInfo(); /** * Gets the PdfInfo-object. * * @return PdfInfo */ PdfInfo getInfo() { return info; } /** * Gets the PdfCatalog-object. * * @param pages an indirect reference to this document pages * @return PdfCatalog */ PdfCatalog getCatalog(PdfIndirectReference pages) { PdfCatalog catalog = new PdfCatalog(pages, writer); // [C1] outlines if (rootOutline.getKids().size() > 0) { catalog.put(PdfName.PAGEMODE, PdfName.USEOUTLINES); catalog.put(PdfName.OUTLINES, rootOutline.indirectReference()); } // [C2] version writer.getPdfVersion().addToCatalog(catalog); // [C3] preferences viewerPreferences.addToCatalog(catalog); // [C4] pagelabels if (pageLabels != null) { catalog.put(PdfName.PAGELABELS, pageLabels.getDictionary(writer)); } // [C5] named objects catalog.addNames(localDestinations, getDocumentLevelJS(), documentFileAttachment, writer); // [C6] actions if (openActionName != null) { PdfAction action = getLocalGotoAction(openActionName); catalog.setOpenAction(action); } else if (openActionAction != null) catalog.setOpenAction(openActionAction); if (additionalActions != null) { catalog.setAdditionalActions(additionalActions); } // [C7] portable collections if (collection != null) { catalog.put(PdfName.COLLECTION, collection); } // [C8] AcroForm if (annotationsImp.hasValidAcroForm()) { try { catalog.put(PdfName.ACROFORM, writer.addToBody(annotationsImp.getAcroForm()).getIndirectReference()); } catch (IOException e) { throw new ExceptionConverter(e); } } return catalog; } // [C1] outlines /** This is the root outline of the document. */ protected PdfOutline rootOutline; /** This is the current PdfOutline in the hierarchy of outlines. */ protected PdfOutline currentOutline; /** * Adds a named outline to the document . * @param outline the outline to be added * @param name the name of this local destination */ void addOutline(PdfOutline outline, String name) { localDestination(name, outline.getPdfDestination()); } /** * Gets the root outline. All the outlines must be created with a parent. * The first level is created with this outline. * @return the root outline */ public PdfOutline getRootOutline() { return rootOutline; } /** * Updates the count in the outlines. */ void calculateOutlineCount() { if (rootOutline.getKids().size() == 0) return; traverseOutlineCount(rootOutline); } /** * Recursive method to update the count in the outlines. */ void traverseOutlineCount(PdfOutline outline) { ArrayList kids = outline.getKids(); PdfOutline parent = outline.parent(); if (kids.isEmpty()) { if (parent != null) { parent.setCount(parent.getCount() + 1); } } else { for (int k = 0; k < kids.size(); ++k) { traverseOutlineCount((PdfOutline)kids.get(k)); } if (parent != null) { if (outline.isOpen()) { parent.setCount(outline.getCount() + parent.getCount() + 1); } else { parent.setCount(parent.getCount() + 1); outline.setCount(-outline.getCount()); } } } } /** * Writes the outline tree to the body of the PDF document. */ void writeOutlines() throws IOException { if (rootOutline.getKids().size() == 0) return; outlineTree(rootOutline); writer.addToBody(rootOutline, rootOutline.indirectReference()); } /** * Recursive method used to write outlines. */ void outlineTree(PdfOutline outline) throws IOException { outline.setIndirectReference(writer.getPdfIndirectReference()); if (outline.parent() != null) outline.put(PdfName.PARENT, outline.parent().indirectReference()); ArrayList kids = outline.getKids(); int size = kids.size(); for (int k = 0; k < size; ++k) outlineTree((PdfOutline)kids.get(k)); for (int k = 0; k < size; ++k) { if (k > 0) ((PdfOutline)kids.get(k)).put(PdfName.PREV, ((PdfOutline)kids.get(k - 1)).indirectReference()); if (k < size - 1) ((PdfOutline)kids.get(k)).put(PdfName.NEXT, ((PdfOutline)kids.get(k + 1)).indirectReference()); } if (size > 0) { outline.put(PdfName.FIRST, ((PdfOutline)kids.get(0)).indirectReference()); outline.put(PdfName.LAST, ((PdfOutline)kids.get(size - 1)).indirectReference()); } for (int k = 0; k < size; ++k) { PdfOutline kid = (PdfOutline)kids.get(k); writer.addToBody(kid, kid.indirectReference()); } } // [C3] PdfViewerPreferences interface /** Contains the Viewer preferences of this PDF document. */ protected PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp(); /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */ void setViewerPreferences(int preferences) { this.viewerPreferences.setViewerPreferences(preferences); } /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */ void addViewerPreference(PdfName key, PdfObject value) { this.viewerPreferences.addViewerPreference(key, value); } // [C4] Page labels protected PdfPageLabels pageLabels; /** * Sets the page labels * @param pageLabels the page labels */ void setPageLabels(PdfPageLabels pageLabels) { this.pageLabels = pageLabels; } // [C5] named objects: local destinations, javascript, embedded files /** * Implements a link to other part of the document. The jump will * be made to a local destination with the same name, that must exist. * @param name the name for this link * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ void localGoto(String name, float llx, float lly, float urx, float ury) { PdfAction action = getLocalGotoAction(name); annotationsImp.addPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action)); } /** * Implements a link to another document. * @param filename the filename for the remote document * @param name the name to jump to * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ void remoteGoto(String filename, String name, float llx, float lly, float urx, float ury) { annotationsImp.addPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, name))); } /** * Implements a link to another document. * @param filename the filename for the remote document * @param page the page to jump to * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ void remoteGoto(String filename, int page, float llx, float lly, float urx, float ury) { addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, page))); } /** Implements an action in an area. * @param action the PdfAction * @param llx the lower left x corner of the activation area * @param lly the lower left y corner of the activation area * @param urx the upper right x corner of the activation area * @param ury the upper right y corner of the activation area */ void setAction(PdfAction action, float llx, float lly, float urx, float ury) { addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action)); } /** * Stores the destinations keyed by name. Value is * Object[]{PdfAction,PdfIndirectReference,PdfDestintion}. */ protected TreeMap localDestinations = new TreeMap(); PdfAction getLocalGotoAction(String name) { PdfAction action; Object obj[] = (Object[])localDestinations.get(name); if (obj == null) obj = new Object[3]; if (obj[0] == null) { if (obj[1] == null) { obj[1] = writer.getPdfIndirectReference(); } action = new PdfAction((PdfIndirectReference)obj[1]); obj[0] = action; localDestinations.put(name, obj); } else { action = (PdfAction)obj[0]; } return action; } /** * The local destination to where a local goto with the same * name will jump to. * @param name the name of this local destination * @param destination the PdfDestination with the jump coordinates * @return true if the local destination was added, * false if a local destination with the same name * already existed */ boolean localDestination(String name, PdfDestination destination) { Object obj[] = (Object[])localDestinations.get(name); if (obj == null) obj = new Object[3]; if (obj[2] != null) return false; obj[2] = destination; localDestinations.put(name, obj); destination.addPage(writer.getCurrentPage()); return true; } /** * Stores a list of document level JavaScript actions. */ int jsCounter; protected HashMap documentLevelJS = new HashMap(); protected static final DecimalFormat SIXTEEN_DIGITS = new DecimalFormat("0000000000000000"); void addJavaScript(PdfAction js) { if (js.get(PdfName.JS) == null) throw new RuntimeException("Only JavaScript actions are allowed."); try { documentLevelJS.put(SIXTEEN_DIGITS.format(jsCounter++), writer.addToBody(js).getIndirectReference()); } catch (IOException e) { throw new ExceptionConverter(e); } } void addJavaScript(String name, PdfAction js) { if (js.get(PdfName.JS) == null) throw new RuntimeException("Only JavaScript actions are allowed."); try { documentLevelJS.put(name, writer.addToBody(js).getIndirectReference()); } catch (IOException e) { throw new ExceptionConverter(e); } } HashMap getDocumentLevelJS() { return documentLevelJS; } protected HashMap documentFileAttachment = new HashMap(); void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { if (description == null) { PdfString desc = (PdfString)fs.get(PdfName.DESC); if (desc == null) { description = ""; } else { description = PdfEncodings.convertToString(desc.getBytes(), null); } } fs.addDescription(description, true); if (description.length() == 0) description = "Unnamed"; String fn = PdfEncodings.convertToString(new PdfString(description, PdfObject.TEXT_UNICODE).getBytes(), null); int k = 0; while (documentFileAttachment.containsKey(fn)) { ++k; fn = PdfEncodings.convertToString(new PdfString(description + " " + k, PdfObject.TEXT_UNICODE).getBytes(), null); } documentFileAttachment.put(fn, fs.getReference()); } HashMap getDocumentFileAttachment() { return documentFileAttachment; } // [C6] document level actions protected String openActionName; void setOpenAction(String name) { openActionName = name; openActionAction = null; } protected PdfAction openActionAction; void setOpenAction(PdfAction action) { openActionAction = action; openActionName = null; } protected PdfDictionary additionalActions; void addAdditionalAction(PdfName actionType, PdfAction action) { if (additionalActions == null) { additionalActions = new PdfDictionary(); } if (action == null) additionalActions.remove(actionType); else additionalActions.put(actionType, action); if (additionalActions.size() == 0) additionalActions = null; } // [C7] portable collections protected PdfCollection collection; /** * Sets the collection dictionary. * @param collection a dictionary of type PdfCollection */ public void setCollection(PdfCollection collection) { this.collection = collection; } // [C8] AcroForm PdfAnnotationsImp annotationsImp; /** * Gets the AcroForm object. * @return the PdfAcroform object of the PdfDocument */ PdfAcroForm getAcroForm() { return annotationsImp.getAcroForm(); } void setSigFlags(int f) { annotationsImp.setSigFlags(f); } void addCalculationOrder(PdfFormField formField) { annotationsImp.addCalculationOrder(formField); } void addAnnotation(PdfAnnotation annot) { pageEmpty = false; annotationsImp.addAnnotation(annot); } // [F12] tagged PDF protected int markPoint; int getMarkPoint() { return markPoint; } void incMarkPoint() { ++markPoint; } // [U1] page sizes /** This is the size of the next page. */ protected Rectangle nextPageSize = null; /** This is the size of the several boxes of the current Page. */ protected HashMap thisBoxSize = new HashMap(); /** This is the size of the several boxes that will be used in * the next page. */ protected HashMap boxSize = new HashMap(); void setCropBoxSize(Rectangle crop) { setBoxSize("crop", crop); } void setBoxSize(String boxName, Rectangle size) { if (size == null) boxSize.remove(boxName); else boxSize.put(boxName, new PdfRectangle(size)); } protected void setNewPageSizeAndMargins() { pageSize = nextPageSize; if (marginMirroring && (getPageNumber() & 1) == 0) { marginRight = nextMarginLeft; marginLeft = nextMarginRight; } else { marginLeft = nextMarginLeft; marginRight = nextMarginRight; } if (marginMirroringTopBottom && (getPageNumber() & 1) == 0) { marginTop = nextMarginBottom; marginBottom = nextMarginTop; } else { marginTop = nextMarginTop; marginBottom = nextMarginBottom; } } /** * Gives the size of a trim, art, crop or bleed box, or null if not defined. * @param boxName crop, trim, art or bleed */ Rectangle getBoxSize(String boxName) { PdfRectangle r = (PdfRectangle)thisBoxSize.get(boxName); if (r != null) return r.getRectangle(); return null; } // [U2] empty pages /** This checks if the page is empty. */ protected boolean pageEmpty = true; void setPageEmpty(boolean pageEmpty) { this.pageEmpty = pageEmpty; } // [U3] page actions /** The duration of the page */ protected int duration=-1; // negative values will indicate no duration /** The page transition */ protected PdfTransition transition=null; /** * Sets the display duration for the page (for presentations) * @param seconds the number of seconds to display the page */ void setDuration(int seconds) { if (seconds > 0) this.duration=seconds; else this.duration=-1; } /** * Sets the transition for the page * @param transition the PdfTransition object */ void setTransition(PdfTransition transition) { this.transition=transition; } protected PdfDictionary pageAA = null; void setPageAction(PdfName actionType, PdfAction action) { if (pageAA == null) { pageAA = new PdfDictionary(); } pageAA.put(actionType, action); } // [U8] thumbnail images protected PdfIndirectReference thumb; void setThumbnail(Image image) throws PdfException, DocumentException { thumb = writer.getImageReference(writer.addDirectImageSimple(image)); } // [M0] Page resources contain references to fonts, extgstate, images,... /** This are the page resources of the current Page. */ protected PageResources pageResources; PageResources getPageResources() { return pageResources; } // [M3] Images /** Holds value of property strictImageSequence. */ protected boolean strictImageSequence = false; /** Getter for property strictImageSequence. * @return Value of property strictImageSequence. * */ boolean isStrictImageSequence() { return this.strictImageSequence; } /** Setter for property strictImageSequence. * @param strictImageSequence New value of property strictImageSequence. * */ void setStrictImageSequence(boolean strictImageSequence) { this.strictImageSequence = strictImageSequence; } /** This is the position where the image ends. */ protected float imageEnd = -1; /** * Method added by Pelikan Stephan */ public void clearTextWrap() { float tmpHeight = imageEnd - currentHeight; if (line != null) { tmpHeight += line.height(); } if ((imageEnd > -1) && (tmpHeight > 0)) { carriageReturn(); currentHeight += tmpHeight; } } /** This is the image that could not be shown on a previous page. */ protected Image imageWait = null; /** * Adds an image to the document. * @param image the Image to add * @throws PdfException on error * @throws DocumentException on error */ protected void add(Image image) throws PdfException, DocumentException { if (image.hasAbsoluteY()) { graphics.addImage(image); pageEmpty = false; return; } // if there isn't enough room for the image on this page, save it for the next page if (currentHeight != 0 && indentTop() - currentHeight - image.getScaledHeight() < indentBottom()) { if (!strictImageSequence && imageWait == null) { imageWait = image; return; } newPage(); if (currentHeight != 0 && indentTop() - currentHeight - image.getScaledHeight() < indentBottom()) { imageWait = image; return; } } pageEmpty = false; // avoid endless loops if (image == imageWait) imageWait = null; boolean textwrap = (image.getAlignment() & Image.TEXTWRAP) == Image.TEXTWRAP && !((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE); boolean underlying = (image.getAlignment() & Image.UNDERLYING) == Image.UNDERLYING; float diff = leading / 2; if (textwrap) { diff += leading; } float lowerleft = indentTop() - currentHeight - image.getScaledHeight() -diff; float mt[] = image.matrix(); float startPosition = indentLeft() - mt[4]; if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) startPosition = indentRight() - image.getScaledWidth() - mt[4]; if ((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE) startPosition = indentLeft() + ((indentRight() - indentLeft() - image.getScaledWidth()) / 2) - mt[4]; if (image.hasAbsoluteX()) startPosition = image.getAbsoluteX(); if (textwrap) { if (imageEnd < 0 || imageEnd < currentHeight + image.getScaledHeight() + diff) { imageEnd = currentHeight + image.getScaledHeight() + diff; } if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) { // indentation suggested by Pelikan Stephan indentation.imageIndentRight += image.getScaledWidth() + image.getIndentationLeft(); } else { // indentation suggested by Pelikan Stephan indentation.imageIndentLeft += image.getScaledWidth() + image.getIndentationRight(); } } else { if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) startPosition -= image.getIndentationRight(); else if ((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE) startPosition += image.getIndentationLeft() - image.getIndentationRight(); else startPosition += image.getIndentationLeft(); } graphics.addImage(image, mt[0], mt[1], mt[2], mt[3], startPosition, lowerleft - mt[5]); if (!(textwrap || underlying)) { currentHeight += image.getScaledHeight() + diff; flushLines(); text.moveText(0, - (image.getScaledHeight() + diff)); newLine(); } } // [M4] Adding a PdfPTable /** Adds a PdfPTable to the document. * @param ptable the PdfPTable to be added to the document. * @throws DocumentException on error */ void addPTable(PdfPTable ptable) throws DocumentException { ColumnText ct = new ColumnText(writer.getDirectContent()); // if the table prefers to be on a single page, and it wouldn't //fit on the current page, start a new page. if (ptable.getKeepTogether() && !fitsPage(ptable, 0f) && currentHeight > 0) { newPage(); } // add dummy paragraph if we aren't at the top of a page, so that // spacingBefore will be taken into account by ColumnText if (currentHeight > 0) { Paragraph p = new Paragraph(); p.setLeading(0); ct.addElement(p); } ct.addElement(ptable); boolean he = ptable.isHeadersInEvent(); ptable.setHeadersInEvent(true); int loop = 0; while (true) { ct.setSimpleColumn(indentLeft(), indentBottom(), indentRight(), indentTop() - currentHeight); int status = ct.go(); if ((status & ColumnText.NO_MORE_TEXT) != 0) { text.moveText(0, ct.getYLine() - indentTop() + currentHeight); currentHeight = indentTop() - ct.getYLine(); break; } if (indentTop() - currentHeight == ct.getYLine()) ++loop; else loop = 0; if (loop == 3) { add(new Paragraph("ERROR: Infinite table loop")); break; } newPage(); } ptable.setHeadersInEvent(he); } /** * Checks if a PdfPTable fits the current page of the PdfDocument. * * @param table the table that has to be checked * @param margin a certain margin * @return true if the PdfPTable fits the page, false otherwise. */ boolean fitsPage(PdfPTable table, float margin) { if (!table.isLockedWidth()) { float totalWidth = (indentRight() - indentLeft()) * table.getWidthPercentage() / 100; table.setTotalWidth(totalWidth); } // ensuring that a new line has been started. ensureNewLine(); return table.getTotalHeight() + ((currentHeight > 0) ? table.spacingBefore() : 0f) <= indentTop() - currentHeight - indentBottom() - margin; } // [M4'] Adding a Table /** * This is a helper class for adding a Table to a document. * @since 2.0.8 (PdfDocument was package-private before) */ protected static class RenderingContext { float pagetop = -1; float oldHeight = -1; PdfContentByte cellGraphics = null; float lostTableBottom; float maxCellBottom; float maxCellHeight; Map rowspanMap; Map pageMap = new HashMap(); /** * A PdfPTable */ public PdfTable table; /** * Consumes the rowspan * @param c * @return a rowspan. */ public int consumeRowspan(PdfCell c) { if (c.rowspan() == 1) { return 1; } Integer i = (Integer) rowspanMap.get(c); if (i == null) { i = new Integer(c.rowspan()); } i = new Integer(i.intValue() - 1); rowspanMap.put(c, i); if (i.intValue() < 1) { return 1; } return i.intValue(); } /** * Looks at the current rowspan. * @param c * @return the current rowspan */ public int currentRowspan(PdfCell c) { Integer i = (Integer) rowspanMap.get(c); if (i == null) { return c.rowspan(); } else { return i.intValue(); } } public int cellRendered(PdfCell cell, int pageNumber) { Integer i = (Integer) pageMap.get(cell); if (i == null) { i = new Integer(1); } else { i = new Integer(i.intValue() + 1); } pageMap.put(cell, i); Integer pageInteger = new Integer(pageNumber); Set set = (Set) pageMap.get(pageInteger); if (set == null) { set = new HashSet(); pageMap.put(pageInteger, set); } set.add(cell); return i.intValue(); } public int numCellRendered(PdfCell cell) { Integer i = (Integer) pageMap.get(cell); if (i == null) { i = new Integer(0); } return i.intValue(); } public boolean isCellRenderedOnPage(PdfCell cell, int pageNumber) { Integer pageInteger = new Integer(pageNumber); Set set = (Set) pageMap.get(pageInteger); if (set != null) { return set.contains(cell); } return false; } }; /** * Adds a new table to the document. * @param t Table to add. Rendered rows will be deleted after processing. * @throws DocumentException * @since iText 2.0.8 */ private void addPdfTable(Table t) throws DocumentException { // before every table, we flush all lines flushLines(); PdfTable table = new PdfTable(t, indentLeft(), indentRight(), indentTop() - currentHeight); RenderingContext ctx = new RenderingContext(); ctx.pagetop = indentTop(); ctx.oldHeight = currentHeight; ctx.cellGraphics = new PdfContentByte(writer); ctx.rowspanMap = new HashMap(); ctx.table = table; // initialization of parameters PdfCell cell; // drawing the table ArrayList headercells = table.getHeaderCells(); ArrayList cells = table.getCells(); ArrayList rows = extractRows(cells, ctx); boolean isContinue = false; while (!cells.isEmpty()) { // initialization of some extra parameters; ctx.lostTableBottom = 0; // loop over the cells boolean cellsShown = false; // draw the cells (line by line) Iterator iterator = rows.iterator(); boolean atLeastOneFits = false; while (iterator.hasNext()) { ArrayList row = (ArrayList) iterator.next(); analyzeRow(rows, ctx); renderCells(ctx, row, table.hasToFitPageCells() & atLeastOneFits); if (!mayBeRemoved(row)) { break; } consumeRowspan(row, ctx); iterator.remove(); atLeastOneFits = true; } // compose cells array list for subsequent code cells.clear(); Set opt = new HashSet(); iterator = rows.iterator(); while (iterator.hasNext()) { ArrayList row = (ArrayList) iterator.next(); Iterator cellIterator = row.iterator(); while (cellIterator.hasNext()) { cell = (PdfCell) cellIterator.next(); if (!opt.contains(cell)) { cells.add(cell); opt.add(cell); } } } // we paint the graphics of the table after looping through all the cells Rectangle tablerec = new Rectangle(table); tablerec.setBorder(table.getBorder()); tablerec.setBorderWidth(table.getBorderWidth()); tablerec.setBorderColor(table.getBorderColor()); tablerec.setBackgroundColor(table.getBackgroundColor()); PdfContentByte under = writer.getDirectContentUnder(); under.rectangle(tablerec.rectangle(top(), indentBottom())); under.add(ctx.cellGraphics); // bugfix by Gerald Fehringer: now again add the border for the table // since it might have been covered by cell backgrounds tablerec.setBackgroundColor(null); tablerec = tablerec.rectangle(top(), indentBottom()); tablerec.setBorder(table.getBorder()); under.rectangle(tablerec); // end bugfix ctx.cellGraphics = new PdfContentByte(null); // if the table continues on the next page if (!rows.isEmpty()) { isContinue = true; graphics.setLineWidth(table.getBorderWidth()); if (cellsShown && (table.getBorder() & Rectangle.BOTTOM) == Rectangle.BOTTOM) { // Draw the bottom line // the color is set to the color of the element Color tColor = table.getBorderColor(); if (tColor != null) { graphics.setColorStroke(tColor); } graphics.moveTo(table.getLeft(), Math.max(table.getBottom(), indentBottom())); graphics.lineTo(table.getRight(), Math.max(table.getBottom(), indentBottom())); graphics.stroke(); if (tColor != null) { graphics.resetRGBColorStroke(); } } // old page pageEmpty = false; float difference = ctx.lostTableBottom; // new page newPage(); // G.F.: if something added in page event i.e. currentHeight > 0 float heightCorrection = 0; boolean somethingAdded = false; if (currentHeight > 0) { heightCorrection = 6; currentHeight += heightCorrection; somethingAdded = true; newLine(); flushLines(); indentation.indentTop = currentHeight - leading; currentHeight = 0; } else { flushLines(); } // this part repeats the table headers (if any) int size = headercells.size(); if (size > 0) { // this is the top of the headersection cell = (PdfCell) headercells.get(0); float oldTop = cell.getTop(0); // loop over all the cells of the table header for (int i = 0; i < size; i++) { cell = (PdfCell) headercells.get(i); // calculation of the new cellpositions cell.setTop(indentTop() - oldTop + cell.getTop(0)); cell.setBottom(indentTop() - oldTop + cell.getBottom(0)); ctx.pagetop = cell.getBottom(); // we paint the borders of the cell ctx.cellGraphics.rectangle(cell.rectangle(indentTop(), indentBottom())); // we write the text of the cell ArrayList images = cell.getImages(indentTop(), indentBottom()); for (Iterator im = images.iterator(); im.hasNext();) { cellsShown = true; Image image = (Image) im.next(); graphics.addImage(image); } lines = cell.getLines(indentTop(), indentBottom()); float cellTop = cell.getTop(indentTop()); text.moveText(0, cellTop-heightCorrection); float cellDisplacement = flushLines() - cellTop+heightCorrection; text.moveText(0, cellDisplacement); } currentHeight = indentTop() - ctx.pagetop + table.cellspacing(); text.moveText(0, ctx.pagetop - indentTop() - currentHeight); } else { if (somethingAdded) { ctx.pagetop = indentTop(); text.moveText(0, -table.cellspacing()); } } ctx.oldHeight = currentHeight - heightCorrection; // calculating the new positions of the table and the cells size = Math.min(cells.size(), table.columns()); int i = 0; while (i < size) { cell = (PdfCell) cells.get(i); if (cell.getTop(-table.cellspacing()) > ctx.lostTableBottom) { float newBottom = ctx.pagetop - difference + cell.getBottom(); float neededHeight = cell.remainingHeight(); if (newBottom > ctx.pagetop - neededHeight) { difference += newBottom - (ctx.pagetop - neededHeight); } } i++; } size = cells.size(); table.setTop(indentTop()); table.setBottom(ctx.pagetop - difference + table.getBottom(table.cellspacing())); for (i = 0; i < size; i++) { cell = (PdfCell) cells.get(i); float newBottom = ctx.pagetop - difference + cell.getBottom(); float newTop = ctx.pagetop - difference + cell.getTop(-table.cellspacing()); if (newTop > indentTop() - currentHeight) { newTop = indentTop() - currentHeight; } cell.setTop(newTop ); cell.setBottom(newBottom ); } } } float tableHeight = table.getTop() - table.getBottom(); // bugfix by Adauto Martins when have more than two tables and more than one page // If continuation of table in other page (bug report #1460051) if (isContinue) { currentHeight = tableHeight; text.moveText(0, -(tableHeight - (ctx.oldHeight * 2))); } else { currentHeight = ctx.oldHeight + tableHeight; text.moveText(0, -tableHeight); } // end bugfix pageEmpty = false; } protected void analyzeRow(ArrayList rows, RenderingContext ctx) { ctx.maxCellBottom = indentBottom(); // determine whether row(index) is in a rowspan int rowIndex = 0; ArrayList row = (ArrayList) rows.get(rowIndex); int maxRowspan = 1; Iterator iterator = row.iterator(); while (iterator.hasNext()) { PdfCell cell = (PdfCell) iterator.next(); maxRowspan = Math.max(ctx.currentRowspan(cell), maxRowspan); } rowIndex += maxRowspan; boolean useTop = true; if (rowIndex == rows.size()) { rowIndex = rows.size() - 1; useTop = false; } if (rowIndex < 0 || rowIndex >= rows.size()) return; row = (ArrayList) rows.get(rowIndex); iterator = row.iterator(); while (iterator.hasNext()) { PdfCell cell = (PdfCell) iterator.next(); Rectangle cellRect = cell.rectangle(ctx.pagetop, indentBottom()); if (useTop) { ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.getTop()); } else { if (ctx.currentRowspan(cell) == 1) { ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.getBottom()); } } } } protected boolean mayBeRemoved(ArrayList row) { Iterator iterator = row.iterator(); boolean mayBeRemoved = true; while (iterator.hasNext()) { PdfCell cell = (PdfCell) iterator.next(); mayBeRemoved &= cell.mayBeRemoved(); } return mayBeRemoved; } protected void consumeRowspan(ArrayList row, RenderingContext ctx) { Iterator iterator = row.iterator(); while (iterator.hasNext()) { PdfCell c = (PdfCell) iterator.next(); ctx.consumeRowspan(c); } } protected ArrayList extractRows(ArrayList cells, RenderingContext ctx) { PdfCell cell; PdfCell previousCell = null; ArrayList rows = new ArrayList(); java.util.List rowCells = new ArrayList(); Iterator iterator = cells.iterator(); while (iterator.hasNext()) { cell = (PdfCell) iterator.next(); boolean isAdded = false; boolean isEndOfRow = !iterator.hasNext(); boolean isCurrentCellPartOfRow = !iterator.hasNext(); if (previousCell != null) { if (cell.getLeft() <= previousCell.getLeft()) { isEndOfRow = true; isCurrentCellPartOfRow = false; } } if (isCurrentCellPartOfRow) { rowCells.add(cell); isAdded = true; } if (isEndOfRow) { if (!rowCells.isEmpty()) { // add to rowlist rows.add(rowCells); } // start a new list for next line rowCells = new ArrayList(); } if (!isAdded) { rowCells.add(cell); } previousCell = cell; } if (!rowCells.isEmpty()) { rows.add(rowCells); } // fill row information with rowspan cells to get complete "scan lines" for (int i = rows.size() - 1; i >= 0; i--) { ArrayList row = (ArrayList) rows.get(i); // iterator through row for (int j = 0; j < row.size(); j++) { PdfCell c = (PdfCell) row.get(j); int rowspan = c.rowspan(); // fill in missing rowspan cells to complete "scan line" for (int k = 1; k < rowspan && rows.size() < i+k; k++) { ArrayList spannedRow = ((ArrayList) rows.get(i + k)); if (spannedRow.size() > j) spannedRow.add(j, c); } } } return rows; } protected void renderCells(RenderingContext ctx, java.util.List cells, boolean hasToFit) throws DocumentException { PdfCell cell; Iterator iterator; if (hasToFit) { iterator = cells.iterator(); while (iterator.hasNext()) { cell = (PdfCell) iterator.next(); if (!cell.isHeader()) { if (cell.getBottom() < indentBottom()) return; } } } iterator = cells.iterator(); while (iterator.hasNext()) { cell = (PdfCell) iterator.next(); if (!ctx.isCellRenderedOnPage(cell, getPageNumber())) { float correction = 0; if (ctx.numCellRendered(cell) >= 1) { correction = 1.0f; } lines = cell.getLines(ctx.pagetop, indentBottom() - correction); // if there is still text to render we render it if (lines != null && !lines.isEmpty()) { // we write the text float cellTop = cell.getTop(ctx.pagetop - ctx.oldHeight); text.moveText(0, cellTop); float cellDisplacement = flushLines() - cellTop; text.moveText(0, cellDisplacement); if (ctx.oldHeight + cellDisplacement > currentHeight) { currentHeight = ctx.oldHeight + cellDisplacement; } ctx.cellRendered(cell, getPageNumber()); } float indentBottom = Math.max(cell.getBottom(), indentBottom()); Rectangle tableRect = ctx.table.rectangle(ctx.pagetop, indentBottom()); indentBottom = Math.max(tableRect.getBottom(), indentBottom); // we paint the borders of the cells Rectangle cellRect = cell.rectangle(tableRect.getTop(), indentBottom); //cellRect.setBottom(cellRect.bottom()); if (cellRect.getHeight() > 0) { ctx.lostTableBottom = indentBottom; ctx.cellGraphics.rectangle(cellRect); } // and additional graphics ArrayList images = cell.getImages(ctx.pagetop, indentBottom()); for (Iterator i = images.iterator(); i.hasNext();) { Image image = (Image) i.next(); graphics.addImage(image); } } } } /** * Returns the bottomvalue of a Table if it were added to this document. * * @param table the table that may or may not be added to this document * @return a bottom value */ float bottom(Table table) { // constructing a PdfTable PdfTable tmp = new PdfTable(table, indentLeft(), indentRight(), indentTop() - currentHeight); return tmp.getBottom(); } // [M5] header/footer protected void doFooter() throws DocumentException { if (footer == null) return; // Begin added by Edgar Leonardo Prieto Perilla // Avoid footer indentation float tmpIndentLeft = indentation.indentLeft; float tmpIndentRight = indentation.indentRight; // Begin added: Bonf (Marc Schneider) 2003-07-29 float tmpListIndentLeft = indentation.listIndentLeft; float tmpImageIndentLeft = indentation.imageIndentLeft; float tmpImageIndentRight = indentation.imageIndentRight; // End added: Bonf (Marc Schneider) 2003-07-29 indentation.indentLeft = indentation.indentRight = 0; // Begin added: Bonf (Marc Schneider) 2003-07-29 indentation.listIndentLeft = 0; indentation.imageIndentLeft = 0; indentation.imageIndentRight = 0; // End added: Bonf (Marc Schneider) 2003-07-29 // End Added by Edgar Leonardo Prieto Perilla footer.setPageNumber(pageN); leading = footer.paragraph().getTotalLeading(); add(footer.paragraph()); // adding the footer limits the height indentation.indentBottom = currentHeight; text.moveText(left(), indentBottom()); flushLines(); text.moveText(-left(), -bottom()); footer.setTop(bottom(currentHeight)); footer.setBottom(bottom() - (0.75f * leading)); footer.setLeft(left()); footer.setRight(right()); graphics.rectangle(footer); indentation.indentBottom = currentHeight + leading * 2; currentHeight = 0; // Begin added by Edgar Leonardo Prieto Perilla indentation.indentLeft = tmpIndentLeft; indentation.indentRight = tmpIndentRight; // Begin added: Bonf (Marc Schneider) 2003-07-29 indentation.listIndentLeft = tmpListIndentLeft; indentation.imageIndentLeft = tmpImageIndentLeft; indentation.imageIndentRight = tmpImageIndentRight; // End added: Bonf (Marc Schneider) 2003-07-29 // End added by Edgar Leonardo Prieto Perilla } protected void doHeader() throws DocumentException { // if there is a header, the header = added if (header == null) return; // Begin added by Edgar Leonardo Prieto Perilla // Avoid header indentation float tmpIndentLeft = indentation.indentLeft; float tmpIndentRight = indentation.indentRight; // Begin added: Bonf (Marc Schneider) 2003-07-29 float tmpListIndentLeft = indentation.listIndentLeft; float tmpImageIndentLeft = indentation.imageIndentLeft; float tmpImageIndentRight = indentation.imageIndentRight; // End added: Bonf (Marc Schneider) 2003-07-29 indentation.indentLeft = indentation.indentRight = 0; // Added: Bonf indentation.listIndentLeft = 0; indentation.imageIndentLeft = 0; indentation.imageIndentRight = 0; // End added: Bonf // Begin added by Edgar Leonardo Prieto Perilla header.setPageNumber(pageN); leading = header.paragraph().getTotalLeading(); text.moveText(0, leading); add(header.paragraph()); newLine(); indentation.indentTop = currentHeight - leading; header.setTop(top() + leading); header.setBottom(indentTop() + leading * 2 / 3); header.setLeft(left()); header.setRight(right()); graphics.rectangle(header); flushLines(); currentHeight = 0; // Begin added by Edgar Leonardo Prieto Perilla // Restore indentation indentation.indentLeft = tmpIndentLeft; indentation.indentRight = tmpIndentRight; // Begin added: Bonf (Marc Schneider) 2003-07-29 indentation.listIndentLeft = tmpListIndentLeft; indentation.imageIndentLeft = tmpImageIndentLeft; indentation.imageIndentRight = tmpImageIndentRight; // End added: Bonf (Marc Schneider) 2003-07-29 // End Added by Edgar Leonardo Prieto Perilla } }src/core/com/lowagie/text/pdf/PdfEFStream.java100644 0 0 15414 11154165266 16665 0ustar 0 0 /* * $Id: PdfEFStream.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright (c) 2008 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; /** * Extends PdfStream and should be used to create Streams for Embedded Files * (file attachments). * @since 2.1.3 */ public class PdfEFStream extends PdfStream { /** * Creates a Stream object using an InputStream and a PdfWriter object * @param in the InputStream that will be read to get the Stream object * @param writer the writer to which the stream will be added */ public PdfEFStream(InputStream in, PdfWriter writer) { super(in, writer); } /** * Creates a Stream object using a byte array * @param fileStore the bytes for the stream */ public PdfEFStream(byte[] fileStore) { super(fileStore); } /** * @see com.lowagie.text.pdf.PdfDictionary#toPdf(com.lowagie.text.pdf.PdfWriter, java.io.OutputStream) */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { if (inputStream != null && compressed) put(PdfName.FILTER, PdfName.FLATEDECODE); PdfEncryption crypto = null; if (writer != null) crypto = writer.getEncryption(); if (crypto != null) { PdfObject filter = get(PdfName.FILTER); if (filter != null) { if (PdfName.CRYPT.equals(filter)) crypto = null; else if (filter.isArray()) { PdfArray a = (PdfArray)filter; if (!a.isEmpty() && PdfName.CRYPT.equals(a.getPdfObject(0))) crypto = null; } } } if (crypto != null && crypto.isEmbeddedFilesOnly()) { PdfArray filter = new PdfArray(); PdfArray decodeparms = new PdfArray(); PdfDictionary crypt = new PdfDictionary(); crypt.put(PdfName.NAME, PdfName.STDCF); filter.add(PdfName.CRYPT); decodeparms.add(crypt); if (compressed) { filter.add(PdfName.FLATEDECODE); decodeparms.add(new PdfNull()); } put(PdfName.FILTER, filter); put(PdfName.DECODEPARMS, decodeparms); } PdfObject nn = get(PdfName.LENGTH); if (crypto != null && nn != null && nn.isNumber()) { int sz = ((PdfNumber)nn).intValue(); put(PdfName.LENGTH, new PdfNumber(crypto.calculateStreamSize(sz))); superToPdf(writer, os); put(PdfName.LENGTH, nn); } else superToPdf(writer, os); os.write(STARTSTREAM); if (inputStream != null) { rawLength = 0; DeflaterOutputStream def = null; OutputStreamCounter osc = new OutputStreamCounter(os); OutputStreamEncryption ose = null; OutputStream fout = osc; if (crypto != null) fout = ose = crypto.getEncryptionStream(fout); Deflater deflater = null; if (compressed) { deflater = new Deflater(compressionLevel); fout = def = new DeflaterOutputStream(fout, deflater, 0x8000); } byte buf[] = new byte[4192]; while (true) { int n = inputStream.read(buf); if (n <= 0) break; fout.write(buf, 0, n); rawLength += n; } if (def != null) { def.finish(); deflater.end(); } if (ose != null) ose.finish(); inputStreamLength = osc.getCounter(); } else { if (crypto == null) { if (streamBytes != null) streamBytes.writeTo(os); else os.write(bytes); } else { byte b[]; if (streamBytes != null) { b = crypto.encryptByteArray(streamBytes.toByteArray()); } else { b = crypto.encryptByteArray(bytes); } os.write(b); } } os.write(ENDSTREAM); } } src/core/com/lowagie/text/pdf/PdfEncodings.java100644 0 0 104414 11036112746 17141 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.StringTokenizer; import com.lowagie.text.ExceptionConverter; /** Supports fast encodings for winansi and PDFDocEncoding. * Supports conversions from CJK encodings to CID. * Supports custom encodings. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfEncodings { protected static final int CIDNONE = 0; protected static final int CIDRANGE = 1; protected static final int CIDCHAR = 2; static final char winansiByteToChar[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 8364, 65533, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 65533, 381, 65533, 65533, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 65533, 382, 376, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; static final char pdfEncodingByteToChar[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 65533, 0x20ac, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; static final IntHashtable winansi = new IntHashtable(); static final IntHashtable pdfEncoding = new IntHashtable(); static HashMap extraEncodings = new HashMap(); static { for (int k = 128; k < 161; ++k) { char c = winansiByteToChar[k]; if (c != 65533) winansi.put(c, k); } for (int k = 128; k < 161; ++k) { char c = pdfEncodingByteToChar[k]; if (c != 65533) pdfEncoding.put(c, k); } addExtraEncoding("Wingdings", new WingdingsConversion()); addExtraEncoding("Symbol", new SymbolConversion(true)); addExtraEncoding("ZapfDingbats", new SymbolConversion(false)); addExtraEncoding("SymbolTT", new SymbolTTConversion()); addExtraEncoding("Cp437", new Cp437Conversion()); } /** Converts a String to a byte array according * to the font's encoding. * @return an array of byte representing the conversion according to the font's encoding * @param encoding the encoding * @param text the String to be converted */ public static final byte[] convertToBytes(String text, String encoding) { if (text == null) return new byte[0]; if (encoding == null || encoding.length() == 0) { int len = text.length(); byte b[] = new byte[len]; for (int k = 0; k < len; ++k) b[k] = (byte)text.charAt(k); return b; } ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase()); if (extra != null) { byte b[] = extra.charToByte(text, encoding); if (b != null) return b; } IntHashtable hash = null; if (encoding.equals(BaseFont.WINANSI)) hash = winansi; else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING)) hash = pdfEncoding; if (hash != null) { char cc[] = text.toCharArray(); int len = cc.length; int ptr = 0; byte b[] = new byte[len]; int c = 0; for (int k = 0; k < len; ++k) { char char1 = cc[k]; if (char1 < 128 || (char1 > 160 && char1 <= 255)) c = char1; else c = hash.get(char1); if (c != 0) b[ptr++] = (byte)c; } if (ptr == len) return b; byte b2[] = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } if (encoding.equals(PdfObject.TEXT_UNICODE)) { // workaround for jdk 1.2.2 bug char cc[] = text.toCharArray(); int len = cc.length; byte b[] = new byte[cc.length * 2 + 2]; b[0] = -2; b[1] = -1; int bptr = 2; for (int k = 0; k < len; ++k) { char c = cc[k]; b[bptr++] = (byte)(c >> 8); b[bptr++] = (byte)(c & 0xff); } return b; } try { return text.getBytes(encoding); } catch (UnsupportedEncodingException e) { throw new ExceptionConverter(e); } } /** Converts a String to a byte array according * to the font's encoding. * @return an array of byte representing the conversion according to the font's encoding * @param encoding the encoding * @param char1 the char to be converted */ public static final byte[] convertToBytes(char char1, String encoding) { if (encoding == null || encoding.length() == 0) return new byte[]{(byte)char1}; ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase()); if (extra != null) { byte b[] = extra.charToByte(char1, encoding); if (b != null) return b; } IntHashtable hash = null; if (encoding.equals(BaseFont.WINANSI)) hash = winansi; else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING)) hash = pdfEncoding; if (hash != null) { int c = 0; if (char1 < 128 || (char1 > 160 && char1 <= 255)) c = char1; else c = hash.get(char1); if (c != 0) return new byte[]{(byte)c}; else return new byte[0]; } if (encoding.equals(PdfObject.TEXT_UNICODE)) { // workaround for jdk 1.2.2 bug byte b[] = new byte[4]; b[0] = -2; b[1] = -1; b[2] = (byte)(char1 >> 8); b[3] = (byte)(char1 & 0xff); return b; } try { return String.valueOf(char1).getBytes(encoding); } catch (UnsupportedEncodingException e) { throw new ExceptionConverter(e); } } /** Converts a byte array to a String according * to the some encoding. * @param bytes the bytes to convert * @param encoding the encoding * @return the converted String */ public static final String convertToString(byte bytes[], String encoding) { if (bytes == null) return PdfObject.NOTHING; if (encoding == null || encoding.length() == 0) { char c[] = new char[bytes.length]; for (int k = 0; k < bytes.length; ++k) c[k] = (char)(bytes[k] & 0xff); return new String(c); } ExtraEncoding extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase()); if (extra != null) { String text = extra.byteToChar(bytes, encoding); if (text != null) return text; } char ch[] = null; if (encoding.equals(BaseFont.WINANSI)) ch = winansiByteToChar; else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING)) ch = pdfEncodingByteToChar; if (ch != null) { int len = bytes.length; char c[] = new char[len]; for (int k = 0; k < len; ++k) { c[k] = ch[bytes[k] & 0xff]; } return new String(c); } try { return new String(bytes, encoding); } catch (UnsupportedEncodingException e) { throw new ExceptionConverter(e); } } /** Checks is text only has PdfDocEncoding characters. * @param text the String to test * @return true if only PdfDocEncoding characters are present */ public static boolean isPdfDocEncoding(String text) { if (text == null) return true; int len = text.length(); for (int k = 0; k < len; ++k) { char char1 = text.charAt(k); if (char1 < 128 || (char1 > 160 && char1 <= 255)) continue; if (!pdfEncoding.containsKey(char1)) return false; } return true; } static final HashMap cmaps = new HashMap(); /** Assumes that '\\n' and '\\r\\n' are the newline sequences. It may not work for * all CJK encodings. To be used with loadCmap(). */ public static final byte CRLF_CID_NEWLINE[][] = new byte[][]{{(byte)'\n'}, {(byte)'\r', (byte)'\n'}}; /** Clears the CJK cmaps from the cache. If name is the * empty string then all the cache is cleared. Calling this method * has no consequences other than the need to reload the cmap * if needed. * @param name the name of the cmap to clear or all the cmaps if the empty string */ public static void clearCmap(String name) { synchronized (cmaps) { if (name.length() == 0) cmaps.clear(); else cmaps.remove(name); } } /** Loads a CJK cmap to the cache with the option of associating * sequences to the newline. * @param name the CJK cmap name * @param newline the sequences to be replaced by a newline in the resulting CID. See CRLF_CID_NEWLINE */ public static void loadCmap(String name, byte newline[][]) { try { char planes[][] = null; synchronized (cmaps) { planes = (char[][])cmaps.get(name); } if (planes == null) { planes = readCmap(name, newline); synchronized (cmaps) { cmaps.put(name, planes); } } } catch (IOException e) { throw new ExceptionConverter(e); } } /** Converts a byte array encoded as name * to a CID string. This is needed to reach some CJK characters * that don't exist in 16 bit Unicode.

* The font to use this result must use the encoding "Identity-H" * or "Identity-V".

* See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/. * @param name the CJK encoding name * @param seq the byte array to be decoded * @return the CID string */ public static String convertCmap(String name, byte seq[]) { return convertCmap(name, seq, 0, seq.length); } /** Converts a byte array encoded as name * to a CID string. This is needed to reach some CJK characters * that don't exist in 16 bit Unicode.

* The font to use this result must use the encoding "Identity-H" * or "Identity-V".

* See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/. * @param name the CJK encoding name * @param start the start offset in the data * @param length the number of bytes to convert * @param seq the byte array to be decoded * @return the CID string */ public static String convertCmap(String name, byte seq[], int start, int length) { try { char planes[][] = null; synchronized (cmaps) { planes = (char[][])cmaps.get(name); } if (planes == null) { planes = readCmap(name, (byte[][])null); synchronized (cmaps) { cmaps.put(name, planes); } } return decodeSequence(seq, start, length, planes); } catch (IOException e) { throw new ExceptionConverter(e); } } static String decodeSequence(byte seq[], int start, int length, char planes[][]) { StringBuffer buf = new StringBuffer(); int end = start + length; int currentPlane = 0; for (int k = start; k < end; ++k) { int one = seq[k] & 0xff; char plane[] = planes[currentPlane]; int cid = plane[one]; if ((cid & 0x8000) == 0) { buf.append((char)cid); currentPlane = 0; } else currentPlane = cid & 0x7fff; } return buf.toString(); } static char[][] readCmap(String name, byte newline[][]) throws IOException { ArrayList planes = new ArrayList(); planes.add(new char[256]); readCmap(name, planes); if (newline != null) { for (int k = 0; k < newline.length; ++k) encodeSequence(newline[k].length, newline[k], BaseFont.CID_NEWLINE, planes); } char ret[][] = new char[planes.size()][]; return (char[][])planes.toArray(ret); } static void readCmap(String name, ArrayList planes) throws IOException { String fullName = BaseFont.RESOURCE_PATH + "cmaps/" + name; InputStream in = BaseFont.getResourceStream(fullName); if (in == null) throw new IOException("The Cmap " + name + " was not found."); encodeStream(in, planes); in.close(); } static void encodeStream(InputStream in, ArrayList planes) throws IOException { BufferedReader rd = new BufferedReader(new InputStreamReader(in, "iso-8859-1")); String line = null; int state = CIDNONE; byte seqs[] = new byte[7]; while ((line = rd.readLine()) != null) { if (line.length() < 6) continue; switch (state) { case CIDNONE: { if (line.indexOf("begincidrange") >= 0) state = CIDRANGE; else if (line.indexOf("begincidchar") >= 0) state = CIDCHAR; else if (line.indexOf("usecmap") >= 0) { StringTokenizer tk = new StringTokenizer(line); String t = tk.nextToken(); readCmap(t.substring(1), planes); } break; } case CIDRANGE: { if (line.indexOf("endcidrange") >= 0) { state = CIDNONE; break; } StringTokenizer tk = new StringTokenizer(line); String t = tk.nextToken(); int size = t.length() / 2 - 1; long start = Long.parseLong(t.substring(1, t.length() - 1), 16); t = tk.nextToken(); long end = Long.parseLong(t.substring(1, t.length() - 1), 16); t = tk.nextToken(); int cid = Integer.parseInt(t); for (long k = start; k <= end; ++k) { breakLong(k, size, seqs); encodeSequence(size, seqs, (char)cid, planes); ++cid; } break; } case CIDCHAR: { if (line.indexOf("endcidchar") >= 0) { state = CIDNONE; break; } StringTokenizer tk = new StringTokenizer(line); String t = tk.nextToken(); int size = t.length() / 2 - 1; long start = Long.parseLong(t.substring(1, t.length() - 1), 16); t = tk.nextToken(); int cid = Integer.parseInt(t); breakLong(start, size, seqs); encodeSequence(size, seqs, (char)cid, planes); break; } } } } static void breakLong(long n, int size, byte seqs[]) { for (int k = 0; k < size; ++k) { seqs[k] = (byte)(n >> ((size - 1 - k) * 8)); } } static void encodeSequence(int size, byte seqs[], char cid, ArrayList planes) { --size; int nextPlane = 0; for (int idx = 0; idx < size; ++idx) { char plane[] = (char[])planes.get(nextPlane); int one = seqs[idx] & 0xff; char c = plane[one]; if (c != 0 && (c & 0x8000) == 0) throw new RuntimeException("Inconsistent mapping."); if (c == 0) { planes.add(new char[256]); c = (char)((planes.size() - 1) | 0x8000); plane[one] = c; } nextPlane = c & 0x7fff; } char plane[] = (char[])planes.get(nextPlane); int one = seqs[size] & 0xff; char c = plane[one]; if ((c & 0x8000) != 0) throw new RuntimeException("Inconsistent mapping."); plane[one] = cid; } /** Adds an extra encoding. * @param name the name of the encoding. The encoding recognition is case insensitive * @param enc the conversion class */ public static void addExtraEncoding(String name, ExtraEncoding enc) { synchronized (extraEncodings) { // This serializes concurrent updates HashMap newEncodings = (HashMap)extraEncodings.clone(); newEncodings.put(name.toLowerCase(), enc); extraEncodings = newEncodings; // This swap does not require synchronization with reader } } private static class WingdingsConversion implements ExtraEncoding { public byte[] charToByte(char char1, String encoding) { if (char1 == ' ') return new byte[]{(byte)char1}; else if (char1 >= '\u2701' && char1 <= '\u27BE') { byte v = table[char1 - 0x2700]; if (v != 0) return new byte[]{v}; } return new byte[0]; } public byte[] charToByte(String text, String encoding) { char cc[] = text.toCharArray(); byte b[] = new byte[cc.length]; int ptr = 0; int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; if (c == ' ') b[ptr++] = (byte)c; else if (c >= '\u2701' && c <= '\u27BE') { byte v = table[c - 0x2700]; if (v != 0) b[ptr++] = v; } } if (ptr == len) return b; byte b2[] = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } public String byteToChar(byte[] b, String encoding) { return null; } private final static byte table[] = { 0, 35, 34, 0, 0, 0, 41, 62, 81, 42, 0, 0, 65, 63, 0, 0, 0, 0, 0, -4, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 86, 0, 88, 89, 0, 0, 0, 0, 0, 0, 0, 0, -75, 0, 0, 0, 0, 0, -74, 0, 0, 0, -83, -81, -84, 0, 0, 0, 0, 0, 0, 0, 0, 124, 123, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, -90, 0, 0, 0, 113, 114, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 125, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24, -40, 0, 0, -60, -58, 0, 0, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; } private static class Cp437Conversion implements ExtraEncoding { private static IntHashtable c2b = new IntHashtable(); public byte[] charToByte(String text, String encoding) { char cc[] = text.toCharArray(); byte b[] = new byte[cc.length]; int ptr = 0; int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; if (c < 128) b[ptr++] = (byte)c; else { byte v = (byte)c2b.get(c); if (v != 0) b[ptr++] = v; } } if (ptr == len) return b; byte b2[] = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } public byte[] charToByte(char char1, String encoding) { if (char1 < 128) return new byte[]{(byte)char1}; else { byte v = (byte)c2b.get(char1); if (v != 0) return new byte[]{v}; else return new byte[0]; } } public String byteToChar(byte[] b, String encoding) { int len = b.length; char cc[] = new char[len]; int ptr = 0; for (int k = 0; k < len; ++k) { int c = b[k] & 0xff; if (c < ' ') continue; if (c < 128) cc[ptr++] = (char)c; else { char v = table[c - 128]; cc[ptr++] = v; } } return new String(cc, 0, ptr); } private final static char table[] = { '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', '\u00FF', '\u00D6', '\u00DC', '\u00A2', '\u00A3', '\u00A5', '\u20A7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', '\u00AA', '\u00BA', '\u00BF', '\u2310', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '\u2591', '\u2592', '\u2593', '\u2502', '\u2524', '\u2561', '\u2562', '\u2556', '\u2555', '\u2563', '\u2551', '\u2557', '\u255D', '\u255C', '\u255B', '\u2510', '\u2514', '\u2534', '\u252C', '\u251C', '\u2500', '\u253C', '\u255E', '\u255F', '\u255A', '\u2554', '\u2569', '\u2566', '\u2560', '\u2550', '\u256C', '\u2567', '\u2568', '\u2564', '\u2565', '\u2559', '\u2558', '\u2552', '\u2553', '\u256B', '\u256A', '\u2518', '\u250C', '\u2588', '\u2584', '\u258C', '\u2590', '\u2580', '\u03B1', '\u00DF', '\u0393', '\u03C0', '\u03A3', '\u03C3', '\u00B5', '\u03C4', '\u03A6', '\u0398', '\u03A9', '\u03B4', '\u221E', '\u03C6', '\u03B5', '\u2229', '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0' }; static { for (int k = 0; k < table.length; ++k) c2b.put(table[k], k + 128); } } private static class SymbolConversion implements ExtraEncoding { private static final IntHashtable t1 = new IntHashtable(); private static final IntHashtable t2 = new IntHashtable(); private IntHashtable translation; SymbolConversion(boolean symbol) { if (symbol) translation = t1; else translation = t2; } public byte[] charToByte(String text, String encoding) { char cc[] = text.toCharArray(); byte b[] = new byte[cc.length]; int ptr = 0; int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; byte v = (byte)translation.get(c); if (v != 0) b[ptr++] = v; } if (ptr == len) return b; byte b2[] = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } public byte[] charToByte(char char1, String encoding) { byte v = (byte)translation.get(char1); if (v != 0) return new byte[]{v}; else return new byte[0]; } public String byteToChar(byte[] b, String encoding) { return null; } private final static char table1[] = { ' ','!','\u2200','#','\u2203','%','&','\u220b','(',')','*','+',',','-','.','/', '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', '\u2245','\u0391','\u0392','\u03a7','\u0394','\u0395','\u03a6','\u0393','\u0397','\u0399','\u03d1','\u039a','\u039b','\u039c','\u039d','\u039f', '\u03a0','\u0398','\u03a1','\u03a3','\u03a4','\u03a5','\u03c2','\u03a9','\u039e','\u03a8','\u0396','[','\u2234',']','\u22a5','_', '\u0305','\u03b1','\u03b2','\u03c7','\u03b4','\u03b5','\u03d5','\u03b3','\u03b7','\u03b9','\u03c6','\u03ba','\u03bb','\u03bc','\u03bd','\u03bf', '\u03c0','\u03b8','\u03c1','\u03c3','\u03c4','\u03c5','\u03d6','\u03c9','\u03be','\u03c8','\u03b6','{','|','}','~','\0', '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', '\u20ac','\u03d2','\u2032','\u2264','\u2044','\u221e','\u0192','\u2663','\u2666','\u2665','\u2660','\u2194','\u2190','\u2191','\u2192','\u2193', '\u00b0','\u00b1','\u2033','\u2265','\u00d7','\u221d','\u2202','\u2022','\u00f7','\u2260','\u2261','\u2248','\u2026','\u2502','\u2500','\u21b5', '\u2135','\u2111','\u211c','\u2118','\u2297','\u2295','\u2205','\u2229','\u222a','\u2283','\u2287','\u2284','\u2282','\u2286','\u2208','\u2209', '\u2220','\u2207','\u00ae','\u00a9','\u2122','\u220f','\u221a','\u2022','\u00ac','\u2227','\u2228','\u21d4','\u21d0','\u21d1','\u21d2','\u21d3', '\u25ca','\u2329','\0','\0','\0','\u2211','\u239b','\u239c','\u239d','\u23a1','\u23a2','\u23a3','\u23a7','\u23a8','\u23a9','\u23aa', '\0','\u232a','\u222b','\u2320','\u23ae','\u2321','\u239e','\u239f','\u23a0','\u23a4','\u23a5','\u23a6','\u23ab','\u23ac','\u23ad','\0' }; private final static char table2[] = { '\u0020','\u2701','\u2702','\u2703','\u2704','\u260e','\u2706','\u2707','\u2708','\u2709','\u261b','\u261e','\u270C','\u270D','\u270E','\u270F', '\u2710','\u2711','\u2712','\u2713','\u2714','\u2715','\u2716','\u2717','\u2718','\u2719','\u271A','\u271B','\u271C','\u271D','\u271E','\u271F', '\u2720','\u2721','\u2722','\u2723','\u2724','\u2725','\u2726','\u2727','\u2605','\u2729','\u272A','\u272B','\u272C','\u272D','\u272E','\u272F', '\u2730','\u2731','\u2732','\u2733','\u2734','\u2735','\u2736','\u2737','\u2738','\u2739','\u273A','\u273B','\u273C','\u273D','\u273E','\u273F', '\u2740','\u2741','\u2742','\u2743','\u2744','\u2745','\u2746','\u2747','\u2748','\u2749','\u274A','\u274B','\u25cf','\u274D','\u25a0','\u274F', '\u2750','\u2751','\u2752','\u25b2','\u25bc','\u25c6','\u2756','\u25d7','\u2758','\u2759','\u275A','\u275B','\u275C','\u275D','\u275E','\u0000', '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', '\u0000','\u2761','\u2762','\u2763','\u2764','\u2765','\u2766','\u2767','\u2663','\u2666','\u2665','\u2660','\u2460','\u2461','\u2462','\u2463', '\u2464','\u2465','\u2466','\u2467','\u2468','\u2469','\u2776','\u2777','\u2778','\u2779','\u277A','\u277B','\u277C','\u277D','\u277E','\u277F', '\u2780','\u2781','\u2782','\u2783','\u2784','\u2785','\u2786','\u2787','\u2788','\u2789','\u278A','\u278B','\u278C','\u278D','\u278E','\u278F', '\u2790','\u2791','\u2792','\u2793','\u2794','\u2192','\u2194','\u2195','\u2798','\u2799','\u279A','\u279B','\u279C','\u279D','\u279E','\u279F', '\u27A0','\u27A1','\u27A2','\u27A3','\u27A4','\u27A5','\u27A6','\u27A7','\u27A8','\u27A9','\u27AA','\u27AB','\u27AC','\u27AD','\u27AE','\u27AF', '\u0000','\u27B1','\u27B2','\u27B3','\u27B4','\u27B5','\u27B6','\u27B7','\u27B8','\u27B9','\u27BA','\u27BB','\u27BC','\u27BD','\u27BE','\u0000' }; static { for (int k = 0; k < table1.length; ++k) { int v = table1[k]; if (v != 0) t1.put(v, k + 32); } for (int k = 0; k < table2.length; ++k) { int v = table2[k]; if (v != 0) t2.put(v, k + 32); } } } private static class SymbolTTConversion implements ExtraEncoding { public byte[] charToByte(char char1, String encoding) { if ((char1 & 0xff00) == 0 || (char1 & 0xff00) == 0xf000) return new byte[]{(byte)char1}; else return new byte[0]; } public byte[] charToByte(String text, String encoding) { char ch[] = text.toCharArray(); byte b[] = new byte[ch.length]; int ptr = 0; int len = ch.length; for (int k = 0; k < len; ++k) { char c = ch[k]; if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000) b[ptr++] = (byte)c; } if (ptr == len) return b; byte b2[] = new byte[ptr]; System.arraycopy(b, 0, b2, 0, ptr); return b2; } public String byteToChar(byte[] b, String encoding) { return null; } } } src/core/com/lowagie/text/pdf/PdfEncryption.java100644 0 0 44231 11154165267 17351 0ustar 0 0 /* * $Id: PdfEncryption.java 3707 2009-02-20 18:47:51Z xlv $ * * Copyright 2001-2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.pdf.crypto.ARCFOUREncryption; import java.io.IOException; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.security.MessageDigest; import java.security.cert.Certificate; import com.lowagie.text.ExceptionConverter; /** * * @author Paulo Soares (psoares@consiste.pt) * @author Kazuya Ujihara */ public class PdfEncryption { public static final int STANDARD_ENCRYPTION_40 = 2; public static final int STANDARD_ENCRYPTION_128 = 3; public static final int AES_128 = 4; private static final byte[] pad = { (byte) 0x28, (byte) 0xBF, (byte) 0x4E, (byte) 0x5E, (byte) 0x4E, (byte) 0x75, (byte) 0x8A, (byte) 0x41, (byte) 0x64, (byte) 0x00, (byte) 0x4E, (byte) 0x56, (byte) 0xFF, (byte) 0xFA, (byte) 0x01, (byte) 0x08, (byte) 0x2E, (byte) 0x2E, (byte) 0x00, (byte) 0xB6, (byte) 0xD0, (byte) 0x68, (byte) 0x3E, (byte) 0x80, (byte) 0x2F, (byte) 0x0C, (byte) 0xA9, (byte) 0xFE, (byte) 0x64, (byte) 0x53, (byte) 0x69, (byte) 0x7A }; private static final byte[] salt = { (byte) 0x73, (byte) 0x41, (byte) 0x6c, (byte) 0x54 }; private static final byte[] metadataPad = { (byte) 255, (byte) 255, (byte) 255, (byte) 255 }; /** The encryption key for a particular object/generation */ byte key[]; /** The encryption key length for a particular object/generation */ int keySize; /** The global encryption key */ byte mkey[]; /** Work area to prepare the object/generation bytes */ byte extra[] = new byte[5]; /** The message digest algorithm MD5 */ MessageDigest md5; /** The encryption key for the owner */ byte ownerKey[] = new byte[32]; /** The encryption key for the user */ byte userKey[] = new byte[32]; /** The public key security handler for certificate encryption */ protected PdfPublicKeySecurityHandler publicKeyHandler = null; int permissions; byte documentID[]; static long seq = System.currentTimeMillis(); private int revision; private ARCFOUREncryption arcfour = new ARCFOUREncryption(); /** The generic key length. It may be 40 or 128. */ private int keyLength; private boolean encryptMetadata; /** * Indicates if the encryption is only necessary for embedded files. * @since 2.1.3 */ private boolean embeddedFilesOnly; private int cryptoMode; public PdfEncryption() { try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { throw new ExceptionConverter(e); } publicKeyHandler = new PdfPublicKeySecurityHandler(); } public PdfEncryption(PdfEncryption enc) { this(); mkey = (byte[]) enc.mkey.clone(); ownerKey = (byte[]) enc.ownerKey.clone(); userKey = (byte[]) enc.userKey.clone(); permissions = enc.permissions; if (enc.documentID != null) documentID = (byte[]) enc.documentID.clone(); revision = enc.revision; keyLength = enc.keyLength; encryptMetadata = enc.encryptMetadata; embeddedFilesOnly = enc.embeddedFilesOnly; publicKeyHandler = enc.publicKeyHandler; } public void setCryptoMode(int mode, int kl) { cryptoMode = mode; encryptMetadata = (mode & PdfWriter.DO_NOT_ENCRYPT_METADATA) == 0; embeddedFilesOnly = (mode & PdfWriter.EMBEDDED_FILES_ONLY) != 0; mode &= PdfWriter.ENCRYPTION_MASK; switch (mode) { case PdfWriter.STANDARD_ENCRYPTION_40: encryptMetadata = true; embeddedFilesOnly = false; keyLength = 40; revision = STANDARD_ENCRYPTION_40; break; case PdfWriter.STANDARD_ENCRYPTION_128: embeddedFilesOnly = false; if (kl > 0) keyLength = kl; else keyLength = 128; revision = STANDARD_ENCRYPTION_128; break; case PdfWriter.ENCRYPTION_AES_128: keyLength = 128; revision = AES_128; break; default: throw new IllegalArgumentException("No valid encryption mode"); } } public int getCryptoMode() { return cryptoMode; } public boolean isMetadataEncrypted() { return encryptMetadata; } /** * Indicates if only the embedded files have to be encrypted. * @return if true only the embedded files will be encrypted * @since 2.1.3 */ public boolean isEmbeddedFilesOnly() { return embeddedFilesOnly; } /** */ private byte[] padPassword(byte userPassword[]) { byte userPad[] = new byte[32]; if (userPassword == null) { System.arraycopy(pad, 0, userPad, 0, 32); } else { System.arraycopy(userPassword, 0, userPad, 0, Math.min( userPassword.length, 32)); if (userPassword.length < 32) System.arraycopy(pad, 0, userPad, userPassword.length, 32 - userPassword.length); } return userPad; } /** */ private byte[] computeOwnerKey(byte userPad[], byte ownerPad[]) { byte ownerKey[] = new byte[32]; byte digest[] = md5.digest(ownerPad); if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) { byte mkey[] = new byte[keyLength / 8]; // only use for the input as many bit as the key consists of for (int k = 0; k < 50; ++k) System.arraycopy(md5.digest(digest), 0, digest, 0, mkey.length); System.arraycopy(userPad, 0, ownerKey, 0, 32); for (int i = 0; i < 20; ++i) { for (int j = 0; j < mkey.length; ++j) mkey[j] = (byte) (digest[j] ^ i); arcfour.prepareARCFOURKey(mkey); arcfour.encryptARCFOUR(ownerKey); } } else { arcfour.prepareARCFOURKey(digest, 0, 5); arcfour.encryptARCFOUR(userPad, ownerKey); } return ownerKey; } /** * * ownerKey, documentID must be setup */ private void setupGlobalEncryptionKey(byte[] documentID, byte userPad[], byte ownerKey[], int permissions) { this.documentID = documentID; this.ownerKey = ownerKey; this.permissions = permissions; // use variable keylength mkey = new byte[keyLength / 8]; // fixed by ujihara in order to follow PDF reference md5.reset(); md5.update(userPad); md5.update(ownerKey); byte ext[] = new byte[4]; ext[0] = (byte) permissions; ext[1] = (byte) (permissions >> 8); ext[2] = (byte) (permissions >> 16); ext[3] = (byte) (permissions >> 24); md5.update(ext, 0, 4); if (documentID != null) md5.update(documentID); if (!encryptMetadata) md5.update(metadataPad); byte digest[] = new byte[mkey.length]; System.arraycopy(md5.digest(), 0, digest, 0, mkey.length); // only use the really needed bits as input for the hash if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) { for (int k = 0; k < 50; ++k) System.arraycopy(md5.digest(digest), 0, digest, 0, mkey.length); } System.arraycopy(digest, 0, mkey, 0, mkey.length); } /** * * mkey must be setup */ // use the revision to choose the setup method private void setupUserKey() { if (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) { md5.update(pad); byte digest[] = md5.digest(documentID); System.arraycopy(digest, 0, userKey, 0, 16); for (int k = 16; k < 32; ++k) userKey[k] = 0; for (int i = 0; i < 20; ++i) { for (int j = 0; j < mkey.length; ++j) digest[j] = (byte) (mkey[j] ^ i); arcfour.prepareARCFOURKey(digest, 0, mkey.length); arcfour.encryptARCFOUR(userKey, 0, 16); } } else { arcfour.prepareARCFOURKey(mkey); arcfour.encryptARCFOUR(pad, userKey); } } // gets keylength and revision and uses revision to choose the initial values // for permissions public void setupAllKeys(byte userPassword[], byte ownerPassword[], int permissions) { if (ownerPassword == null || ownerPassword.length == 0) ownerPassword = md5.digest(createDocumentId()); permissions |= (revision == STANDARD_ENCRYPTION_128 || revision == AES_128) ? 0xfffff0c0 : 0xffffffc0; permissions &= 0xfffffffc; // PDF reference 3.5.2 Standard Security Handler, Algorithm 3.3-1 // If there is no owner password, use the user password instead. byte userPad[] = padPassword(userPassword); byte ownerPad[] = padPassword(ownerPassword); this.ownerKey = computeOwnerKey(userPad, ownerPad); documentID = createDocumentId(); setupByUserPad(this.documentID, userPad, this.ownerKey, permissions); } public static byte[] createDocumentId() { MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { throw new ExceptionConverter(e); } long time = System.currentTimeMillis(); long mem = Runtime.getRuntime().freeMemory(); String s = time + "+" + mem + "+" + (seq++); return md5.digest(s.getBytes()); } /** */ public void setupByUserPassword(byte[] documentID, byte userPassword[], byte ownerKey[], int permissions) { setupByUserPad(documentID, padPassword(userPassword), ownerKey, permissions); } /** */ private void setupByUserPad(byte[] documentID, byte userPad[], byte ownerKey[], int permissions) { setupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions); setupUserKey(); } /** */ public void setupByOwnerPassword(byte[] documentID, byte ownerPassword[], byte userKey[], byte ownerKey[], int permissions) { setupByOwnerPad(documentID, padPassword(ownerPassword), userKey, ownerKey, permissions); } private void setupByOwnerPad(byte[] documentID, byte ownerPad[], byte userKey[], byte ownerKey[], int permissions) { byte userPad[] = computeOwnerKey(ownerKey, ownerPad); // userPad will // be set in // this.ownerKey setupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions); // step // 3 setupUserKey(); } public void setupByEncryptionKey(byte[] key, int keylength) { mkey = new byte[keylength / 8]; System.arraycopy(key, 0, mkey, 0, mkey.length); } public void setHashKey(int number, int generation) { md5.reset(); // added by ujihara extra[0] = (byte) number; extra[1] = (byte) (number >> 8); extra[2] = (byte) (number >> 16); extra[3] = (byte) generation; extra[4] = (byte) (generation >> 8); md5.update(mkey); md5.update(extra); if (revision == AES_128) md5.update(salt); key = md5.digest(); keySize = mkey.length + 5; if (keySize > 16) keySize = 16; } public static PdfObject createInfoId(byte id[]) { ByteBuffer buf = new ByteBuffer(90); buf.append('[').append('<'); for (int k = 0; k < 16; ++k) buf.appendHex(id[k]); buf.append('>').append('<'); id = createDocumentId(); for (int k = 0; k < 16; ++k) buf.appendHex(id[k]); buf.append('>').append(']'); return new PdfLiteral(buf.toByteArray()); } public PdfDictionary getEncryptionDictionary() { PdfDictionary dic = new PdfDictionary(); if (publicKeyHandler.getRecipientsSize() > 0) { PdfArray recipients = null; dic.put(PdfName.FILTER, PdfName.PUBSEC); dic.put(PdfName.R, new PdfNumber(revision)); try { recipients = publicKeyHandler.getEncodedRecipients(); } catch (Exception f) { throw new ExceptionConverter(f); } if (revision == STANDARD_ENCRYPTION_40) { dic.put(PdfName.V, new PdfNumber(1)); dic.put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4); dic.put(PdfName.RECIPIENTS, recipients); } else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) { dic.put(PdfName.V, new PdfNumber(2)); dic.put(PdfName.LENGTH, new PdfNumber(128)); dic.put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S4); dic.put(PdfName.RECIPIENTS, recipients); } else { dic.put(PdfName.R, new PdfNumber(AES_128)); dic.put(PdfName.V, new PdfNumber(4)); dic.put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_S5); PdfDictionary stdcf = new PdfDictionary(); stdcf.put(PdfName.RECIPIENTS, recipients); if (!encryptMetadata) stdcf.put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE); if (revision == AES_128) stdcf.put(PdfName.CFM, PdfName.AESV2); else stdcf.put(PdfName.CFM, PdfName.V2); PdfDictionary cf = new PdfDictionary(); cf.put(PdfName.DEFAULTCRYPTFILTER, stdcf); dic.put(PdfName.CF, cf);if (embeddedFilesOnly) { dic.put(PdfName.EFF, PdfName.DEFAULTCRYPTFILTER); dic.put(PdfName.STRF, PdfName.IDENTITY); dic.put(PdfName.STMF, PdfName.IDENTITY); } else { dic.put(PdfName.STRF, PdfName.DEFAULTCRYPTFILTER); dic.put(PdfName.STMF, PdfName.DEFAULTCRYPTFILTER); } } MessageDigest md = null; byte[] encodedRecipient = null; try { md = MessageDigest.getInstance("SHA-1"); md.update(publicKeyHandler.getSeed()); for (int i = 0; i < publicKeyHandler.getRecipientsSize(); i++) { encodedRecipient = publicKeyHandler.getEncodedRecipient(i); md.update(encodedRecipient); } if (!encryptMetadata) md.update(new byte[] { (byte) 255, (byte) 255, (byte) 255, (byte) 255 }); } catch (Exception f) { throw new ExceptionConverter(f); } byte[] mdResult = md.digest(); setupByEncryptionKey(mdResult, keyLength); } else { dic.put(PdfName.FILTER, PdfName.STANDARD); dic.put(PdfName.O, new PdfLiteral(PdfContentByte .escapeString(ownerKey))); dic.put(PdfName.U, new PdfLiteral(PdfContentByte .escapeString(userKey))); dic.put(PdfName.P, new PdfNumber(permissions)); dic.put(PdfName.R, new PdfNumber(revision)); if (revision == STANDARD_ENCRYPTION_40) { dic.put(PdfName.V, new PdfNumber(1)); } else if (revision == STANDARD_ENCRYPTION_128 && encryptMetadata) { dic.put(PdfName.V, new PdfNumber(2)); dic.put(PdfName.LENGTH, new PdfNumber(128)); } else { if (!encryptMetadata) dic.put(PdfName.ENCRYPTMETADATA, PdfBoolean.PDFFALSE); dic.put(PdfName.R, new PdfNumber(AES_128)); dic.put(PdfName.V, new PdfNumber(4)); dic.put(PdfName.LENGTH, new PdfNumber(128)); PdfDictionary stdcf = new PdfDictionary(); stdcf.put(PdfName.LENGTH, new PdfNumber(16)); if (embeddedFilesOnly) { stdcf.put(PdfName.AUTHEVENT, PdfName.EFOPEN); dic.put(PdfName.EFF, PdfName.STDCF); dic.put(PdfName.STRF, PdfName.IDENTITY); dic.put(PdfName.STMF, PdfName.IDENTITY); } else { stdcf.put(PdfName.AUTHEVENT, PdfName.DOCOPEN); dic.put(PdfName.STRF, PdfName.STDCF); dic.put(PdfName.STMF, PdfName.STDCF); } if (revision == AES_128) stdcf.put(PdfName.CFM, PdfName.AESV2); else stdcf.put(PdfName.CFM, PdfName.V2); PdfDictionary cf = new PdfDictionary(); cf.put(PdfName.STDCF, stdcf); dic.put(PdfName.CF, cf); } } return dic; } public PdfObject getFileID() { return createInfoId(documentID); } public OutputStreamEncryption getEncryptionStream(OutputStream os) { return new OutputStreamEncryption(os, key, 0, keySize, revision); } public int calculateStreamSize(int n) { if (revision == AES_128) return (n & 0x7ffffff0) + 32; else return n; } public byte[] encryptByteArray(byte[] b) { try { ByteArrayOutputStream ba = new ByteArrayOutputStream(); OutputStreamEncryption os2 = getEncryptionStream(ba); os2.write(b); os2.finish(); return ba.toByteArray(); } catch (IOException ex) { throw new ExceptionConverter(ex); } } public StandardDecryption getDecryptor() { return new StandardDecryption(key, 0, keySize, revision); } public byte[] decryptByteArray(byte[] b) { try { ByteArrayOutputStream ba = new ByteArrayOutputStream(); StandardDecryption dec = getDecryptor(); byte[] b2 = dec.update(b, 0, b.length); if (b2 != null) ba.write(b2); b2 = dec.finish(); if (b2 != null) ba.write(b2); return ba.toByteArray(); } catch (IOException ex) { throw new ExceptionConverter(ex); } } public void addRecipient(Certificate cert, int permission) { documentID = createDocumentId(); publicKeyHandler.addRecipient(new PdfPublicKeyRecipient(cert, permission)); } public byte[] computeUserPassword(byte[] ownerPassword) { byte[] userPad = computeOwnerKey(ownerKey, padPassword(ownerPassword)); for (int i = 0; i < userPad.length; i++) { boolean match = true; for (int j = 0; j < userPad.length - i; j++) { if (userPad[i + j] != pad[j]) { match = false; break; } } if (!match) continue; byte[] userPassword = new byte[i]; System.arraycopy(userPad, 0, userPassword, 0, i); return userPassword; } return userPad; } }src/core/com/lowagie/text/pdf/PdfEncryptor.java100644 0 0 37614 11000663663 17204 0ustar 0 0 /* /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import com.lowagie.text.DocumentException; /** This class takes any PDF and returns exactly the same but * encrypted. All the content, links, outlines, etc, are kept. * It is also possible to change the info dictionary. */ public final class PdfEncryptor { private PdfEncryptor(){ } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); stamper.close(); } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @param newInfo an optional String map to add or change * the info dictionary. Entries with null * values delete the key in the original info dictionary * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits, HashMap newInfo) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); stamper.setMoreInfo(newInfo); stamper.close(); } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param strength true for 128 bit key length, false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(strength, userPassword, ownerPassword, permissions); stamper.close(); } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param strength true for 128 bit key length, false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param newInfo an optional String map to add or change * the info dictionary. Entries with null * values delete the key in the original info dictionary * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, boolean strength, String userPassword, String ownerPassword, int permissions, HashMap newInfo) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(strength, userPassword, ownerPassword, permissions); stamper.setMoreInfo(newInfo); stamper.close(); } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param type the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param newInfo an optional String map to add or change * the info dictionary. Entries with null * values delete the key in the original info dictionary * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, int type, String userPassword, String ownerPassword, int permissions, HashMap newInfo) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(type, userPassword, ownerPassword, permissions); stamper.setMoreInfo(newInfo); stamper.close(); } /** Entry point to encrypt a PDF document. The encryption parameters are the same as in * PdfWriter. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param reader the read PDF * @param os the output destination * @param type the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * values delete the key in the original info dictionary * @throws DocumentException on error * @throws IOException on error */ public static void encrypt(PdfReader reader, OutputStream os, int type, String userPassword, String ownerPassword, int permissions) throws DocumentException, IOException { PdfStamper stamper = new PdfStamper(reader, os); stamper.setEncryption(type, userPassword, ownerPassword, permissions); stamper.close(); } /** * Give you a verbose analysis of the permissions. * @param permissions the permissions value of a PDF file * @return a String that explains the meaning of the permissions value */ public static String getPermissionsVerbose(int permissions) { StringBuffer buf = new StringBuffer("Allowed:"); if ((PdfWriter.ALLOW_PRINTING & permissions) == PdfWriter.ALLOW_PRINTING) buf.append(" Printing"); if ((PdfWriter.ALLOW_MODIFY_CONTENTS & permissions) == PdfWriter.ALLOW_MODIFY_CONTENTS) buf.append(" Modify contents"); if ((PdfWriter.ALLOW_COPY & permissions) == PdfWriter.ALLOW_COPY) buf.append(" Copy"); if ((PdfWriter.ALLOW_MODIFY_ANNOTATIONS & permissions) == PdfWriter.ALLOW_MODIFY_ANNOTATIONS) buf.append(" Modify annotations"); if ((PdfWriter.ALLOW_FILL_IN & permissions) == PdfWriter.ALLOW_FILL_IN) buf.append(" Fill in"); if ((PdfWriter.ALLOW_SCREENREADERS & permissions) == PdfWriter.ALLOW_SCREENREADERS) buf.append(" Screen readers"); if ((PdfWriter.ALLOW_ASSEMBLY & permissions) == PdfWriter.ALLOW_ASSEMBLY) buf.append(" Assembly"); if ((PdfWriter.ALLOW_DEGRADED_PRINTING & permissions) == PdfWriter.ALLOW_DEGRADED_PRINTING) buf.append(" Degraded printing"); return buf.toString(); } /** * Tells you if printing is allowed. * @param permissions the permissions value of a PDF file * @return true if printing is allowed * * @since 2.0.7 */ public static boolean isPrintingAllowed(int permissions) { return (PdfWriter.ALLOW_PRINTING & permissions) == PdfWriter.ALLOW_PRINTING; } /** * Tells you if modifying content is allowed. * @param permissions the permissions value of a PDF file * @return true if modifying content is allowed * * @since 2.0.7 */ public static boolean isModifyContentsAllowed(int permissions) { return (PdfWriter.ALLOW_MODIFY_CONTENTS & permissions) == PdfWriter.ALLOW_MODIFY_CONTENTS; } /** * Tells you if copying is allowed. * @param permissions the permissions value of a PDF file * @return true if copying is allowed * * @since 2.0.7 */ public static boolean isCopyAllowed(int permissions) { return (PdfWriter.ALLOW_COPY & permissions) == PdfWriter.ALLOW_COPY; } /** * Tells you if modifying annotations is allowed. * @param permissions the permissions value of a PDF file * @return true if modifying annotations is allowed * * @since 2.0.7 */ public static boolean isModifyAnnotationsAllowed(int permissions) { return (PdfWriter.ALLOW_MODIFY_ANNOTATIONS & permissions) == PdfWriter.ALLOW_MODIFY_ANNOTATIONS; } /** * Tells you if filling in fields is allowed. * @param permissions the permissions value of a PDF file * @return true if filling in fields is allowed * * @since 2.0.7 */ public static boolean isFillInAllowed(int permissions) { return (PdfWriter.ALLOW_FILL_IN & permissions) == PdfWriter.ALLOW_FILL_IN; } /** * Tells you if repurposing for screenreaders is allowed. * @param permissions the permissions value of a PDF file * @return true if repurposing for screenreaders is allowed * * @since 2.0.7 */ public static boolean isScreenReadersAllowed(int permissions) { return (PdfWriter.ALLOW_SCREENREADERS & permissions) == PdfWriter.ALLOW_SCREENREADERS; } /** * Tells you if document assembly is allowed. * @param permissions the permissions value of a PDF file * @return true if document assembly is allowed * * @since 2.0.7 */ public static boolean isAssemblyAllowed(int permissions) { return (PdfWriter.ALLOW_ASSEMBLY & permissions) == PdfWriter.ALLOW_ASSEMBLY; } /** * Tells you if degraded printing is allowed. * @param permissions the permissions value of a PDF file * @return true if degraded printing is allowed * * @since 2.0.7 */ public static boolean isDegradedPrintingAllowed(int permissions) { return (PdfWriter.ALLOW_DEGRADED_PRINTING & permissions) == PdfWriter.ALLOW_DEGRADED_PRINTING; } } src/core/com/lowagie/text/pdf/PdfException.java100644 0 0 6260 11012562273 17124 0ustar 0 0 /* * $Id: PdfException.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.DocumentException; /** * Signals that an unspecified problem while constructing a PDF document. * * @see BadPdfFormatException */ public class PdfException extends DocumentException { // constructors private static final long serialVersionUID = 6767433960955483999L; public PdfException(Exception ex) { super(ex); } /** * Constructs a PdfException without a message. */ PdfException() { super(); } /** * Constructs a PdfException with a message. * * @param message a message describing the exception */ PdfException(String message) { super(message); } }src/core/com/lowagie/text/pdf/PdfFileSpecification.java100644 0 0 32354 11161724620 20572 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import com.lowagie.text.pdf.collection.PdfCollectionItem; /** Specifies a file or an URL. The file can be extern or embedded. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfFileSpecification extends PdfDictionary { protected PdfWriter writer; protected PdfIndirectReference ref; /** Creates a new instance of PdfFileSpecification. The static methods are preferred. */ public PdfFileSpecification() { super(PdfName.FILESPEC); } /** * Creates a file specification of type URL. * @param writer the PdfWriter * @param url the URL * @return the file specification */ public static PdfFileSpecification url(PdfWriter writer, String url) { PdfFileSpecification fs = new PdfFileSpecification(); fs.writer = writer; fs.put(PdfName.FS, PdfName.URL); fs.put(PdfName.F, new PdfString(url)); return fs; } /** * Creates a file specification with the file embedded. The file may * come from the file system or from a byte array. The data is flate compressed. * @param writer the PdfWriter * @param filePath the file path * @param fileDisplay the file information that is presented to the user * @param fileStore the byte array with the file. If it is not null * it takes precedence over filePath * @throws IOException on error * @return the file specification */ public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[]) throws IOException { return fileEmbedded(writer, filePath, fileDisplay, fileStore, PdfStream.BEST_COMPRESSION); } /** * Creates a file specification with the file embedded. The file may * come from the file system or from a byte array. The data is flate compressed. * @param writer the PdfWriter * @param filePath the file path * @param fileDisplay the file information that is presented to the user * @param fileStore the byte array with the file. If it is not null * it takes precedence over filePath * @param compressionLevel the compression level to be used for compressing the file * it takes precedence over filePath * @throws IOException on error * @return the file specification * @since 2.1.3 */ public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], int compressionLevel) throws IOException { return fileEmbedded(writer, filePath, fileDisplay, fileStore, null, null, compressionLevel); } /** * Creates a file specification with the file embedded. The file may * come from the file system or from a byte array. * @param writer the PdfWriter * @param filePath the file path * @param fileDisplay the file information that is presented to the user * @param fileStore the byte array with the file. If it is not null * it takes precedence over filePath * @param compress sets the compression on the data. Multimedia content will benefit little * from compression * @throws IOException on error * @return the file specification */ public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], boolean compress) throws IOException { return fileEmbedded(writer, filePath, fileDisplay, fileStore, null, null, compress ? PdfStream.BEST_COMPRESSION : PdfStream.NO_COMPRESSION); } /** * Creates a file specification with the file embedded. The file may * come from the file system or from a byte array. * @param writer the PdfWriter * @param filePath the file path * @param fileDisplay the file information that is presented to the user * @param fileStore the byte array with the file. If it is not null * it takes precedence over filePath * @param compress sets the compression on the data. Multimedia content will benefit little * from compression * @param mimeType the optional mimeType * @param fileParameter the optional extra file parameters such as the creation or modification date * @throws IOException on error * @return the file specification */ public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], boolean compress, String mimeType, PdfDictionary fileParameter) throws IOException { return fileEmbedded(writer, filePath, fileDisplay, fileStore, null, null, compress ? PdfStream.BEST_COMPRESSION : PdfStream.NO_COMPRESSION); } /** * Creates a file specification with the file embedded. The file may * come from the file system or from a byte array. * @param writer the PdfWriter * @param filePath the file path * @param fileDisplay the file information that is presented to the user * @param fileStore the byte array with the file. If it is not null * it takes precedence over filePath * @param mimeType the optional mimeType * @param fileParameter the optional extra file parameters such as the creation or modification date * @param compressionLevel the level of compression * @throws IOException on error * @return the file specification * @since 2.1.3 */ public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], String mimeType, PdfDictionary fileParameter, int compressionLevel) throws IOException { PdfFileSpecification fs = new PdfFileSpecification(); fs.writer = writer; fs.put(PdfName.F, new PdfString(fileDisplay)); fs.setUnicodeFileName(fileDisplay, false); PdfEFStream stream; InputStream in = null; PdfIndirectReference ref; PdfIndirectReference refFileLength; try { refFileLength = writer.getPdfIndirectReference(); if (fileStore == null) { File file = new File(filePath); if (file.canRead()) { in = new FileInputStream(filePath); } else { if (filePath.startsWith("file:/") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("jar:")) { in = new URL(filePath).openStream(); } else { in = BaseFont.getResourceStream(filePath); if (in == null) throw new IOException(filePath + " not found as file or resource."); } } stream = new PdfEFStream(in, writer); } else stream = new PdfEFStream(fileStore); stream.put(PdfName.TYPE, PdfName.EMBEDDEDFILE); stream.flateCompress(compressionLevel); stream.put(PdfName.PARAMS, refFileLength); if (mimeType != null) stream.put(PdfName.SUBTYPE, new PdfName(mimeType)); ref = writer.addToBody(stream).getIndirectReference(); if (fileStore == null) { stream.writeLength(); } PdfDictionary params = new PdfDictionary(); if (fileParameter != null) params.merge(fileParameter); params.put(PdfName.SIZE, new PdfNumber(stream.getRawLength())); writer.addToBody(params, refFileLength); } finally { if (in != null) try{in.close();}catch(Exception e){} } PdfDictionary f = new PdfDictionary(); f.put(PdfName.F, ref); f.put(PdfName.UF, ref); fs.put(PdfName.EF, f); return fs; } /** * Creates a file specification for an external file. * @param writer the PdfWriter * @param filePath the file path * @return the file specification */ public static PdfFileSpecification fileExtern(PdfWriter writer, String filePath) { PdfFileSpecification fs = new PdfFileSpecification(); fs.writer = writer; fs.put(PdfName.F, new PdfString(filePath)); fs.setUnicodeFileName(filePath, false); return fs; } /** * Gets the indirect reference to this file specification. * Multiple invocations will retrieve the same value. * @throws IOException on error * @return the indirect reference */ public PdfIndirectReference getReference() throws IOException { if (ref != null) return ref; ref = writer.addToBody(this).getIndirectReference(); return ref; } /** * Sets the file name (the key /F) string as an hex representation * to support multi byte file names. The name must have the slash and * backslash escaped according to the file specification rules * @param fileName the file name as a byte array */ public void setMultiByteFileName(byte fileName[]) { put(PdfName.F, new PdfString(fileName).setHexWriting(true)); } /** * Adds the unicode file name (the key /UF). This entry was introduced * in PDF 1.7. The filename must have the slash and backslash escaped * according to the file specification rules. * @param filename the filename * @param unicode if true, the filename is UTF-16BE encoded; otherwise PDFDocEncoding is used; */ public void setUnicodeFileName(String filename, boolean unicode) { put(PdfName.UF, new PdfString(filename, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING)); } /** * Sets a flag that indicates whether an external file referenced by the file * specification is volatile. If the value is true, applications should never * cache a copy of the file. * @param volatile_file if true, the external file should not be cached */ public void setVolatile(boolean volatile_file) { put(PdfName.V, new PdfBoolean(volatile_file)); } /** * Adds a description for the file that is specified here. * @param description some text * @param unicode if true, the text is added as a unicode string */ public void addDescription(String description, boolean unicode) { put(PdfName.DESC, new PdfString(description, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING)); } /** * Adds the Collection item dictionary. */ public void addCollectionItem(PdfCollectionItem ci) { put(PdfName.CI, ci); } }src/core/com/lowagie/text/pdf/PdfFont.java100644 0 0 13230 11012562273 16107 0ustar 0 0 /* * $Id: PdfFont.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; /** * PdfFont is the Pdf Font object. *

* Limitation: in this class only base 14 Type 1 fonts (courier, courier bold, courier oblique, * courier boldoblique, helvetica, helvetica bold, helvetica oblique, helvetica boldoblique, * symbol, times roman, times bold, times italic, times bolditalic, zapfdingbats) and their * standard encoding (standard, MacRoman, (MacExpert,) WinAnsi) are supported.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 7.7 (page 198-203). * * @see PdfName * @see PdfDictionary * @see BadPdfFormatException */ class PdfFont implements Comparable { /** the font metrics. */ private BaseFont font; /** the size. */ private float size; /** an image. */ protected Image image; protected float hScale = 1; // constructors PdfFont(BaseFont bf, float size) { this.size = size; font = bf; } // methods /** * Compares this PdfFont with another * * @param object the other PdfFont * @return a value */ public int compareTo(Object object) { if (image != null) return 0; if (object == null) { return -1; } PdfFont pdfFont; try { pdfFont = (PdfFont) object; if (font != pdfFont.font) { return 1; } if (this.size() != pdfFont.size()) { return 2; } return 0; } catch(ClassCastException cce) { return -2; } } /** * Returns the size of this font. * * @return a size */ float size() { if (image == null) return size; else { return image.getScaledHeight(); } } /** * Returns the approximative width of 1 character of this font. * * @return a width in Text Space */ float width() { return width(' '); } /** * Returns the width of a certain character of this font. * * @param character a certain character * @return a width in Text Space */ float width(int character) { if (image == null) return font.getWidthPoint(character, size) * hScale; else return image.getScaledWidth(); } float width(String s) { if (image == null) return font.getWidthPoint(s, size) * hScale; else return image.getScaledWidth(); } BaseFont getFont() { return font; } void setImage(Image image) { this.image = image; } static PdfFont getDefaultFont() { try { BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, false); return new PdfFont(bf, 12); } catch (Exception ee) { throw new ExceptionConverter(ee); } } void setHorizontalScaling(float hScale) { this.hScale = hScale; } } src/core/com/lowagie/text/pdf/PdfFormField.java100644 0 0 31601 11213370070 17045 0ustar 0 0 /* * Copyright 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Rectangle; /** Implements form fields. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfFormField extends PdfAnnotation { public static final int FF_READ_ONLY = 1; public static final int FF_REQUIRED = 2; public static final int FF_NO_EXPORT = 4; public static final int FF_NO_TOGGLE_TO_OFF = 16384; public static final int FF_RADIO = 32768; public static final int FF_PUSHBUTTON = 65536; public static final int FF_MULTILINE = 4096; public static final int FF_PASSWORD = 8192; public static final int FF_COMBO = 131072; public static final int FF_EDIT = 262144; public static final int FF_FILESELECT = 1048576; public static final int FF_MULTISELECT = 2097152; public static final int FF_DONOTSPELLCHECK = 4194304; public static final int FF_DONOTSCROLL = 8388608; public static final int FF_COMB = 16777216; public static final int FF_RADIOSINUNISON = 1 << 25; public static final int Q_LEFT = 0; public static final int Q_CENTER = 1; public static final int Q_RIGHT = 2; public static final int MK_NO_ICON = 0; public static final int MK_NO_CAPTION = 1; public static final int MK_CAPTION_BELOW = 2; public static final int MK_CAPTION_ABOVE = 3; public static final int MK_CAPTION_RIGHT = 4; public static final int MK_CAPTION_LEFT = 5; public static final int MK_CAPTION_OVERLAID = 6; public static final PdfName IF_SCALE_ALWAYS = PdfName.A; public static final PdfName IF_SCALE_BIGGER = PdfName.B; public static final PdfName IF_SCALE_SMALLER = PdfName.S; public static final PdfName IF_SCALE_NEVER = PdfName.N; public static final PdfName IF_SCALE_ANAMORPHIC = PdfName.A; public static final PdfName IF_SCALE_PROPORTIONAL = PdfName.P; public static final boolean MULTILINE = true; public static final boolean SINGLELINE = false; public static final boolean PLAINTEXT = false; public static final boolean PASSWORD = true; static PdfName mergeTarget[] = {PdfName.FONT, PdfName.XOBJECT, PdfName.COLORSPACE, PdfName.PATTERN}; /** Holds value of property parent. */ protected PdfFormField parent; protected ArrayList kids; /** * Constructs a new PdfAnnotation of subtype link (Action). */ public PdfFormField(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) { super(writer, llx, lly, urx, ury, action); put(PdfName.TYPE, PdfName.ANNOT); put(PdfName.SUBTYPE, PdfName.WIDGET); annotation = true; } /** Creates new PdfFormField */ protected PdfFormField(PdfWriter writer) { super(writer, null); form = true; annotation = false; } public void setWidget(Rectangle rect, PdfName highlight) { put(PdfName.TYPE, PdfName.ANNOT); put(PdfName.SUBTYPE, PdfName.WIDGET); put(PdfName.RECT, new PdfRectangle(rect)); annotation = true; if (highlight != null && !highlight.equals(HIGHLIGHT_INVERT)) put(PdfName.H, highlight); } public static PdfFormField createEmpty(PdfWriter writer) { PdfFormField field = new PdfFormField(writer); return field; } public void setButton(int flags) { put(PdfName.FT, PdfName.BTN); if (flags != 0) put(PdfName.FF, new PdfNumber(flags)); } protected static PdfFormField createButton(PdfWriter writer, int flags) { PdfFormField field = new PdfFormField(writer); field.setButton(flags); return field; } public static PdfFormField createPushButton(PdfWriter writer) { return createButton(writer, FF_PUSHBUTTON); } public static PdfFormField createCheckBox(PdfWriter writer) { return createButton(writer, 0); } public static PdfFormField createRadioButton(PdfWriter writer, boolean noToggleToOff) { return createButton(writer, FF_RADIO + (noToggleToOff ? FF_NO_TOGGLE_TO_OFF : 0)); } public static PdfFormField createTextField(PdfWriter writer, boolean multiline, boolean password, int maxLen) { PdfFormField field = new PdfFormField(writer); field.put(PdfName.FT, PdfName.TX); int flags = (multiline ? FF_MULTILINE : 0); flags += (password ? FF_PASSWORD : 0); field.put(PdfName.FF, new PdfNumber(flags)); if (maxLen > 0) field.put(PdfName.MAXLEN, new PdfNumber(maxLen)); return field; } protected static PdfFormField createChoice(PdfWriter writer, int flags, PdfArray options, int topIndex) { PdfFormField field = new PdfFormField(writer); field.put(PdfName.FT, PdfName.CH); field.put(PdfName.FF, new PdfNumber(flags)); field.put(PdfName.OPT, options); if (topIndex > 0) field.put(PdfName.TI, new PdfNumber(topIndex)); return field; } public static PdfFormField createList(PdfWriter writer, String options[], int topIndex) { return createChoice(writer, 0, processOptions(options), topIndex); } public static PdfFormField createList(PdfWriter writer, String options[][], int topIndex) { return createChoice(writer, 0, processOptions(options), topIndex); } public static PdfFormField createCombo(PdfWriter writer, boolean edit, String options[], int topIndex) { return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), processOptions(options), topIndex); } public static PdfFormField createCombo(PdfWriter writer, boolean edit, String options[][], int topIndex) { return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), processOptions(options), topIndex); } protected static PdfArray processOptions(String options[]) { PdfArray array = new PdfArray(); for (int k = 0; k < options.length; ++k) { array.add(new PdfString(options[k], PdfObject.TEXT_UNICODE)); } return array; } protected static PdfArray processOptions(String options[][]) { PdfArray array = new PdfArray(); for (int k = 0; k < options.length; ++k) { String subOption[] = options[k]; PdfArray ar2 = new PdfArray(new PdfString(subOption[0], PdfObject.TEXT_UNICODE)); ar2.add(new PdfString(subOption[1], PdfObject.TEXT_UNICODE)); array.add(ar2); } return array; } public static PdfFormField createSignature(PdfWriter writer) { PdfFormField field = new PdfFormField(writer); field.put(PdfName.FT, PdfName.SIG); return field; } /** Getter for property parent. * @return Value of property parent. */ public PdfFormField getParent() { return parent; } public void addKid(PdfFormField field) { field.parent = this; if (kids == null) kids = new ArrayList(); kids.add(field); } public ArrayList getKids() { return kids; } public int setFieldFlags(int flags) { PdfNumber obj = (PdfNumber)get(PdfName.FF); int old; if (obj == null) old = 0; else old = obj.intValue(); int v = old | flags; put(PdfName.FF, new PdfNumber(v)); return old; } public void setValueAsString(String s) { put(PdfName.V, new PdfString(s, PdfObject.TEXT_UNICODE)); } public void setValueAsName(String s) { put(PdfName.V, new PdfName(s)); } public void setValue(PdfSignature sig) { put(PdfName.V, sig); } public void setDefaultValueAsString(String s) { put(PdfName.DV, new PdfString(s, PdfObject.TEXT_UNICODE)); } public void setDefaultValueAsName(String s) { put(PdfName.DV, new PdfName(s)); } public void setFieldName(String s) { if (s != null) put(PdfName.T, new PdfString(s, PdfObject.TEXT_UNICODE)); } public void setUserName(String s) { put(PdfName.TU, new PdfString(s, PdfObject.TEXT_UNICODE)); } public void setMappingName(String s) { put(PdfName.TM, new PdfString(s, PdfObject.TEXT_UNICODE)); } public void setQuadding(int v) { put(PdfName.Q, new PdfNumber(v)); } static void mergeResources(PdfDictionary result, PdfDictionary source, PdfStamperImp writer) { PdfDictionary dic = null; PdfDictionary res = null; PdfName target = null; for (int k = 0; k < mergeTarget.length; ++k) { target = mergeTarget[k]; PdfDictionary pdfDict = source.getAsDict(target); if ((dic = pdfDict) != null) { if ((res = (PdfDictionary)PdfReader.getPdfObject(result.get(target), result)) == null) { res = new PdfDictionary(); } res.mergeDifferent(dic); result.put(target, res); if (writer != null) writer.markUsed(res); } } } static void mergeResources(PdfDictionary result, PdfDictionary source) { mergeResources(result, source, null); } public void setUsed() { used = true; if (parent != null) put(PdfName.PARENT, parent.getIndirectReference()); if (kids != null) { PdfArray array = new PdfArray(); for (int k = 0; k < kids.size(); ++k) array.add(((PdfFormField)kids.get(k)).getIndirectReference()); put(PdfName.KIDS, array); } if (templates == null) return; PdfDictionary dic = new PdfDictionary(); for (Iterator it = templates.keySet().iterator(); it.hasNext();) { PdfTemplate template = (PdfTemplate)it.next(); mergeResources(dic, (PdfDictionary)template.getResources()); } put(PdfName.DR, dic); } public static PdfAnnotation shallowDuplicate(PdfAnnotation annot) { PdfAnnotation dup; if (annot.isForm()) { dup = new PdfFormField(annot.writer); PdfFormField dupField = (PdfFormField)dup; PdfFormField srcField = (PdfFormField)annot; dupField.parent = srcField.parent; dupField.kids = srcField.kids; } else dup = new PdfAnnotation(annot.writer, null); dup.merge(annot); dup.form = annot.form; dup.annotation = annot.annotation; dup.templates = annot.templates; return dup; } } src/core/com/lowagie/text/pdf/PdfFormXObject.java100644 0 0 10133 11213370070 17355 0ustar 0 0 /* * $Id: PdfFormXObject.java 3903 2009-04-24 10:03:48Z blowagie $ * * Copyright 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfFormObject is a type of XObject containing a template-object. */ public class PdfFormXObject extends PdfStream { // public static final variables /** This is a PdfNumber representing 0. */ public static final PdfNumber ZERO = new PdfNumber(0); /** This is a PdfNumber representing 1. */ public static final PdfNumber ONE = new PdfNumber(1); /** This is the 1 - matrix. */ public static final PdfLiteral MATRIX = new PdfLiteral("[1 0 0 1 0 0]"); /** * Constructs a PdfFormXObject-object. * * @param template the template * @param compressionLevel the compression level for the stream * @since 2.1.3 (Replacing the existing constructor with param compressionLevel) */ PdfFormXObject(PdfTemplate template, int compressionLevel) // throws BadPdfFormatException { super(); put(PdfName.TYPE, PdfName.XOBJECT); put(PdfName.SUBTYPE, PdfName.FORM); put(PdfName.RESOURCES, template.getResources()); put(PdfName.BBOX, new PdfRectangle(template.getBoundingBox())); put(PdfName.FORMTYPE, ONE); if (template.getLayer() != null) put(PdfName.OC, template.getLayer().getRef()); if (template.getGroup() != null) put(PdfName.GROUP, template.getGroup()); PdfArray matrix = template.getMatrix(); if (matrix == null) put(PdfName.MATRIX, MATRIX); else put(PdfName.MATRIX, matrix); bytes = template.toPdf(null); put(PdfName.LENGTH, new PdfNumber(bytes.length)); flateCompress(compressionLevel); } } src/core/com/lowagie/text/pdf/PdfFunction.java100644 0 0 14516 11036112746 17000 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import com.lowagie.text.ExceptionConverter; /** Implements PDF functions. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfFunction { protected PdfWriter writer; protected PdfIndirectReference reference; protected PdfDictionary dictionary; /** Creates new PdfFunction */ protected PdfFunction(PdfWriter writer) { this.writer = writer; } PdfIndirectReference getReference() { try { if (reference == null) { reference = writer.addToBody(dictionary).getIndirectReference(); } } catch (IOException ioe) { throw new ExceptionConverter(ioe); } return reference; } public static PdfFunction type0(PdfWriter writer, float domain[], float range[], int size[], int bitsPerSample, int order, float encode[], float decode[], byte stream[]) { PdfFunction func = new PdfFunction(writer); func.dictionary = new PdfStream(stream); ((PdfStream)func.dictionary).flateCompress(writer.getCompressionLevel()); func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(0)); func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); func.dictionary.put(PdfName.RANGE, new PdfArray(range)); func.dictionary.put(PdfName.SIZE, new PdfArray(size)); func.dictionary.put(PdfName.BITSPERSAMPLE, new PdfNumber(bitsPerSample)); if (order != 1) func.dictionary.put(PdfName.ORDER, new PdfNumber(order)); if (encode != null) func.dictionary.put(PdfName.ENCODE, new PdfArray(encode)); if (decode != null) func.dictionary.put(PdfName.DECODE, new PdfArray(decode)); return func; } public static PdfFunction type2(PdfWriter writer, float domain[], float range[], float c0[], float c1[], float n) { PdfFunction func = new PdfFunction(writer); func.dictionary = new PdfDictionary(); func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(2)); func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); if (range != null) func.dictionary.put(PdfName.RANGE, new PdfArray(range)); if (c0 != null) func.dictionary.put(PdfName.C0, new PdfArray(c0)); if (c1 != null) func.dictionary.put(PdfName.C1, new PdfArray(c1)); func.dictionary.put(PdfName.N, new PdfNumber(n)); return func; } public static PdfFunction type3(PdfWriter writer, float domain[], float range[], PdfFunction functions[], float bounds[], float encode[]) { PdfFunction func = new PdfFunction(writer); func.dictionary = new PdfDictionary(); func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(3)); func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); if (range != null) func.dictionary.put(PdfName.RANGE, new PdfArray(range)); PdfArray array = new PdfArray(); for (int k = 0; k < functions.length; ++k) array.add(functions[k].getReference()); func.dictionary.put(PdfName.FUNCTIONS, array); func.dictionary.put(PdfName.BOUNDS, new PdfArray(bounds)); func.dictionary.put(PdfName.ENCODE, new PdfArray(encode)); return func; } public static PdfFunction type4(PdfWriter writer, float domain[], float range[], String postscript) { byte b[] = new byte[postscript.length()]; for (int k = 0; k < b.length; ++k) b[k] = (byte)postscript.charAt(k); PdfFunction func = new PdfFunction(writer); func.dictionary = new PdfStream(b); ((PdfStream)func.dictionary).flateCompress(writer.getCompressionLevel()); func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(4)); func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); func.dictionary.put(PdfName.RANGE, new PdfArray(range)); return func; } } src/core/com/lowagie/text/pdf/PdfGState.java100644 0 0 13751 11000354131 16365 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** The graphic state dictionary. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfGState extends PdfDictionary { /** A possible blend mode */ public static final PdfName BM_NORMAL = new PdfName("Normal"); /** A possible blend mode */ public static final PdfName BM_COMPATIBLE = new PdfName("Compatible"); /** A possible blend mode */ public static final PdfName BM_MULTIPLY = new PdfName("Multiply"); /** A possible blend mode */ public static final PdfName BM_SCREEN = new PdfName("Screen"); /** A possible blend mode */ public static final PdfName BM_OVERLAY = new PdfName("Overlay"); /** A possible blend mode */ public static final PdfName BM_DARKEN = new PdfName("Darken"); /** A possible blend mode */ public static final PdfName BM_LIGHTEN = new PdfName("Lighten"); /** A possible blend mode */ public static final PdfName BM_COLORDODGE = new PdfName("ColorDodge"); /** A possible blend mode */ public static final PdfName BM_COLORBURN = new PdfName("ColorBurn"); /** A possible blend mode */ public static final PdfName BM_HARDLIGHT = new PdfName("HardLight"); /** A possible blend mode */ public static final PdfName BM_SOFTLIGHT = new PdfName("SoftLight"); /** A possible blend mode */ public static final PdfName BM_DIFFERENCE = new PdfName("Difference"); /** A possible blend mode */ public static final PdfName BM_EXCLUSION = new PdfName("Exclusion"); /** * Sets the flag whether to apply overprint for stroking. * @param ov */ public void setOverPrintStroking(boolean ov) { put(PdfName.OP, ov ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); } /** * Sets the flag whether to apply overprint for non stroking painting operations. * @param ov */ public void setOverPrintNonStroking(boolean ov) { put(PdfName.op, ov ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); } /** * Sets the flag whether to toggle knockout behavior for overprinted objects. * @param ov - accepts 0 or 1 */ public void setOverPrintMode(int ov) { put(PdfName.OPM, new PdfNumber(ov==0 ? 0 : 1)); } /** * Sets the current stroking alpha constant, specifying the constant shape or * constant opacity value to be used for stroking operations in the transparent * imaging model. * @param n */ public void setStrokeOpacity(float n) { put(PdfName.CA, new PdfNumber(n)); } /** * Sets the current stroking alpha constant, specifying the constant shape or * constant opacity value to be used for nonstroking operations in the transparent * imaging model. * @param n */ public void setFillOpacity(float n) { put(PdfName.ca, new PdfNumber(n)); } /** * The alpha source flag specifying whether the current soft mask * and alpha constant are to be interpreted as shape values (true) * or opacity values (false). * @param v */ public void setAlphaIsShape(boolean v) { put(PdfName.AIS, v ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); } /** * Determines the behavior of overlapping glyphs within a text object * in the transparent imaging model. * @param v */ public void setTextKnockout(boolean v) { put(PdfName.TK, v ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); } /** * The current blend mode to be used in the transparent imaging model. * @param bm */ public void setBlendMode(PdfName bm) { put(PdfName.BM, bm); } } src/core/com/lowagie/text/pdf/PdfGraphics2D.java100644 0 0 160763 11106243445 17166 0ustar 0 0 /* * $Id: PdfGraphics2D.java 3611 2008-11-05 19:45:31Z blowagie $ * * Copyright 2002 by Jim Moore . * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Paint; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.TexturePaint; import java.awt.Transparency; import java.awt.RenderingHints.Key; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.font.TextAttribute; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.awt.image.renderable.RenderableImage; import java.io.ByteArrayOutputStream; import java.text.AttributedCharacterIterator; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Set; import com.lowagie.text.pdf.internal.PolylineShape; import java.util.Locale; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; public class PdfGraphics2D extends Graphics2D { private static final int FILL = 1; private static final int STROKE = 2; private static final int CLIP = 3; private BasicStroke strokeOne = new BasicStroke(1); private static final AffineTransform IDENTITY = new AffineTransform(); private Font font; private BaseFont baseFont; private float fontSize; private AffineTransform transform; private Paint paint; private Color background; private float width; private float height; private Area clip; private RenderingHints rhints = new RenderingHints(null); private Stroke stroke; private Stroke originalStroke; private PdfContentByte cb; /** Storage for BaseFont objects created. */ private HashMap baseFonts; private boolean disposeCalled = false; private FontMapper fontMapper; private ArrayList kids; private boolean kid = false; private Graphics2D dg2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB).createGraphics(); private boolean onlyShapes = false; private Stroke oldStroke; private Paint paintFill; private Paint paintStroke; private MediaTracker mediaTracker; // Added by Jurij Bilas protected boolean underline; // indicates if the font style is underlined protected PdfGState fillGState[] = new PdfGState[256]; protected PdfGState strokeGState[] = new PdfGState[256]; protected int currentFillGState = 255; protected int currentStrokeGState = 255; public static final int AFM_DIVISOR = 1000; // used to calculate coordinates private boolean convertImagesToJPEG = false; private float jpegQuality = .95f; // Added by Alexej Suchov private float alpha; // Added by Alexej Suchov private Composite composite; // Added by Alexej Suchov private Paint realPaint; private PdfGraphics2D() { dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); setRenderingHint(HyperLinkKey.KEY_INSTANCE, HyperLinkKey.VALUE_HYPERLINKKEY_OFF); } /** * Constructor for PDFGraphics2D. * */ PdfGraphics2D(PdfContentByte cb, float width, float height, FontMapper fontMapper, boolean onlyShapes, boolean convertImagesToJPEG, float quality) { super(); dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); setRenderingHint(HyperLinkKey.KEY_INSTANCE, HyperLinkKey.VALUE_HYPERLINKKEY_OFF); this.convertImagesToJPEG = convertImagesToJPEG; this.jpegQuality = quality; this.onlyShapes = onlyShapes; this.transform = new AffineTransform(); this.baseFonts = new HashMap(); if (!onlyShapes) { this.fontMapper = fontMapper; if (this.fontMapper == null) this.fontMapper = new DefaultFontMapper(); } paint = Color.black; background = Color.white; setFont(new Font("sanserif", Font.PLAIN, 12)); this.cb = cb; cb.saveState(); this.width = width; this.height = height; clip = new Area(new Rectangle2D.Float(0, 0, width, height)); clip(clip); originalStroke = stroke = oldStroke = strokeOne; setStrokeDiff(stroke, null); cb.saveState(); } /** * @see Graphics2D#draw(Shape) */ public void draw(Shape s) { followPath(s, STROKE); } /** * @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver) */ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { return drawImage(img, null, xform, null, obs); } /** * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int) */ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { BufferedImage result = img; if (op != null) { result = op.createCompatibleDestImage(img, img.getColorModel()); result = op.filter(img, result); } drawImage(result, x, y, null); } /** * @see Graphics2D#drawRenderedImage(RenderedImage, AffineTransform) */ public void drawRenderedImage(RenderedImage img, AffineTransform xform) { BufferedImage image = null; if (img instanceof BufferedImage) { image = (BufferedImage)img; } else { ColorModel cm = img.getColorModel(); int width = img.getWidth(); int height = img.getHeight(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); Hashtable properties = new Hashtable(); String[] keys = img.getPropertyNames(); if (keys!=null) { for (int i = 0; i < keys.length; i++) { properties.put(keys[i], img.getProperty(keys[i])); } } BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties); img.copyData(raster); image=result; } drawImage(image, xform, null); } /** * @see Graphics2D#drawRenderableImage(RenderableImage, AffineTransform) */ public void drawRenderableImage(RenderableImage img, AffineTransform xform) { drawRenderedImage(img.createDefaultRendering(), xform); } /** * @see Graphics#drawString(String, int, int) */ public void drawString(String s, int x, int y) { drawString(s, (float)x, (float)y); } /** * Calculates position and/or stroke thickness depending on the font size * @param d value to be converted * @param i font size * @return position and/or stroke thickness depending on the font size */ public static double asPoints(double d, int i) { return d * i / AFM_DIVISOR; } /** * This routine goes through the attributes and sets the font * before calling the actual string drawing routine * @param iter */ protected void doAttributes(AttributedCharacterIterator iter) { underline = false; Set set = iter.getAttributes().keySet(); for(Iterator iterator = set.iterator(); iterator.hasNext();) { AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute)iterator.next(); if (!(attribute instanceof TextAttribute)) continue; TextAttribute textattribute = (TextAttribute)attribute; if(textattribute.equals(TextAttribute.FONT)) { Font font = (Font)iter.getAttributes().get(textattribute); setFont(font); } else if(textattribute.equals(TextAttribute.UNDERLINE)) { if(iter.getAttributes().get(textattribute) == TextAttribute.UNDERLINE_ON) underline = true; } else if(textattribute.equals(TextAttribute.SIZE)) { Object obj = iter.getAttributes().get(textattribute); if(obj instanceof Integer) { int i = ((Integer)obj).intValue(); setFont(getFont().deriveFont(getFont().getStyle(), i)); } else if(obj instanceof Float) { float f = ((Float)obj).floatValue(); setFont(getFont().deriveFont(getFont().getStyle(), f)); } } else if(textattribute.equals(TextAttribute.FOREGROUND)) { setColor((Color) iter.getAttributes().get(textattribute)); } else if(textattribute.equals(TextAttribute.FAMILY)) { Font font = getFont(); Map fontAttributes = font.getAttributes(); fontAttributes.put(TextAttribute.FAMILY, iter.getAttributes().get(textattribute)); setFont(font.deriveFont(fontAttributes)); } else if(textattribute.equals(TextAttribute.POSTURE)) { Font font = getFont(); Map fontAttributes = font.getAttributes(); fontAttributes.put(TextAttribute.POSTURE, iter.getAttributes().get(textattribute)); setFont(font.deriveFont(fontAttributes)); } else if(textattribute.equals(TextAttribute.WEIGHT)) { Font font = getFont(); Map fontAttributes = font.getAttributes(); fontAttributes.put(TextAttribute.WEIGHT, iter.getAttributes().get(textattribute)); setFont(font.deriveFont(fontAttributes)); } } } /** * @see Graphics2D#drawString(String, float, float) */ public void drawString(String s, float x, float y) { if (s.length() == 0) return; setFillPaint(); if (onlyShapes) { drawGlyphVector(this.font.layoutGlyphVector(getFontRenderContext(), s.toCharArray(), 0, s.length(), java.awt.Font.LAYOUT_LEFT_TO_RIGHT), x, y); // Use the following line to compile in JDK 1.3 // drawGlyphVector(this.font.createGlyphVector(getFontRenderContext(), s), x, y); } else { boolean restoreTextRenderingMode = false; AffineTransform at = getTransform(); AffineTransform at2 = getTransform(); at2.translate(x, y); at2.concatenate(font.getTransform()); setTransform(at2); AffineTransform inverse = this.normalizeMatrix(); AffineTransform flipper = AffineTransform.getScaleInstance(1,-1); inverse.concatenate(flipper); double[] mx = new double[6]; inverse.getMatrix(mx); cb.beginText(); cb.setFontAndSize(baseFont, fontSize); // Check if we need to simulate an italic font. // When there are different fonts for italic, bold, italic bold // the font.getName() will be different from the font.getFontName() // value. When they are the same value then we are normally dealing // with a single font that has been made into an italic or bold // font. if (font.isItalic() && font.getFontName().equals(font.getName())) { float angle = baseFont.getFontDescriptor(BaseFont.ITALICANGLE, 1000); float angle2 = font.getItalicAngle(); // We don't have an italic version of this font so we need // to set the font angle ourselves to produce an italic font. if (angle2 == 0) { // The JavaVM didn't have an angle setting for making // the font an italic font so use a default of // italic angle of 15 degrees. angle2 = 15.0f; } else { // This sign of the angle for Java and PDF seams // seams to be reversed. angle2 = -angle2; } if (angle == 0) { mx[2] = angle2 / 100.0f; } } cb.setTextMatrix((float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]); Float fontTextAttributeWidth = (Float)font.getAttributes().get(TextAttribute.WIDTH); fontTextAttributeWidth = (fontTextAttributeWidth == null) ? TextAttribute.WIDTH_REGULAR : fontTextAttributeWidth; if (!TextAttribute.WIDTH_REGULAR.equals(fontTextAttributeWidth)) cb.setHorizontalScaling(100.0f / fontTextAttributeWidth.floatValue()); // Check if we need to simulate a bold font. // Do nothing if the BaseFont is already bold. This test is not foolproof but it will work most of the times. if (baseFont.getPostscriptFontName().toLowerCase().indexOf("bold") < 0) { // Get the weight of the font so we can detect fonts with a weight // that makes them bold, but the Font.isBold() value is false. Float weight = (Float) font.getAttributes().get(TextAttribute.WEIGHT); if (weight == null) { weight = (font.isBold()) ? TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR; } if ((font.isBold() || (weight.floatValue() >= TextAttribute.WEIGHT_SEMIBOLD.floatValue())) && (font.getFontName().equals(font.getName()))) { // Simulate a bold font. float strokeWidth = font.getSize2D() * (weight.floatValue() - TextAttribute.WEIGHT_REGULAR.floatValue()) / 30f; if (strokeWidth != 1) { if(realPaint instanceof Color){ cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); cb.setLineWidth(strokeWidth); Color color = (Color)realPaint; int alpha = color.getAlpha(); if (alpha != currentStrokeGState) { currentStrokeGState = alpha; PdfGState gs = strokeGState[alpha]; if (gs == null) { gs = new PdfGState(); gs.setStrokeOpacity(alpha / 255f); strokeGState[alpha] = gs; } cb.setGState(gs); } cb.setColorStroke(color); restoreTextRenderingMode = true; } } } } double width = 0; if (font.getSize2D() > 0) { float scale = 1000 / font.getSize2D(); Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale)); width = derivedFont.getStringBounds(s, getFontRenderContext()).getWidth(); if (derivedFont.isTransformed()) width /= scale; } // if the hyperlink flag is set add an action to the text Object url = getRenderingHint(HyperLinkKey.KEY_INSTANCE); if (url != null && !url.equals(HyperLinkKey.VALUE_HYPERLINKKEY_OFF)) { float scale = 1000 / font.getSize2D(); Font derivedFont = font.deriveFont(AffineTransform.getScaleInstance(scale, scale)); double height = derivedFont.getStringBounds(s, getFontRenderContext()).getHeight(); if (derivedFont.isTransformed()) height /= scale; double leftX = cb.getXTLM(); double leftY = cb.getYTLM(); PdfAction action = new PdfAction(url.toString()); cb.setAction(action, (float)leftX, (float)leftY, (float)(leftX+width), (float)(leftY+height)); } if (s.length() > 1) { float adv = ((float)width - baseFont.getWidthPoint(s, fontSize)) / (s.length() - 1); cb.setCharacterSpacing(adv); } cb.showText(s); if (s.length() > 1) { cb.setCharacterSpacing(0); } if (!TextAttribute.WIDTH_REGULAR.equals(fontTextAttributeWidth)) cb.setHorizontalScaling(100); // Restore the original TextRenderingMode if needed. if (restoreTextRenderingMode) { cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); } cb.endText(); setTransform(at); if(underline) { // These two are supposed to be taken from the .AFM file //int UnderlinePosition = -100; int UnderlineThickness = 50; // double d = asPoints(UnderlineThickness, (int)fontSize); Stroke savedStroke = originalStroke; setStroke(new BasicStroke((float)d)); y = (float)(y + asPoints(UnderlineThickness, (int)fontSize)); Line2D line = new Line2D.Double(x, y, width+x, y); draw(line); setStroke(savedStroke); } } } /** * @see Graphics#drawString(AttributedCharacterIterator, int, int) */ public void drawString(AttributedCharacterIterator iterator, int x, int y) { drawString(iterator, (float)x, (float)y); } /** * @see Graphics2D#drawString(AttributedCharacterIterator, float, float) */ public void drawString(AttributedCharacterIterator iter, float x, float y) { /* StringBuffer sb = new StringBuffer(); for(char c = iter.first(); c != AttributedCharacterIterator.DONE; c = iter.next()) { sb.append(c); } drawString(sb.toString(),x,y); */ StringBuffer stringbuffer = new StringBuffer(iter.getEndIndex()); for(char c = iter.first(); c != '\uFFFF'; c = iter.next()) { if(iter.getIndex() == iter.getRunStart()) { if(stringbuffer.length() > 0) { drawString(stringbuffer.toString(), x, y); FontMetrics fontmetrics = getFontMetrics(); x = (float)(x + fontmetrics.getStringBounds(stringbuffer.toString(), this).getWidth()); stringbuffer.delete(0, stringbuffer.length()); } doAttributes(iter); } stringbuffer.append(c); } drawString(stringbuffer.toString(), x, y); underline = false; } /** * @see Graphics2D#drawGlyphVector(GlyphVector, float, float) */ public void drawGlyphVector(GlyphVector g, float x, float y) { Shape s = g.getOutline(x, y); fill(s); } /** * @see Graphics2D#fill(Shape) */ public void fill(Shape s) { followPath(s, FILL); } /** * @see Graphics2D#hit(Rectangle, Shape, boolean) */ public boolean hit(Rectangle rect, Shape s, boolean onStroke) { if (onStroke) { s = stroke.createStrokedShape(s); } s = transform.createTransformedShape(s); Area area = new Area(s); if (clip != null) area.intersect(clip); return area.intersects(rect.x, rect.y, rect.width, rect.height); } /** * @see Graphics2D#getDeviceConfiguration() */ public GraphicsConfiguration getDeviceConfiguration() { return dg2.getDeviceConfiguration(); } /** * Method contributed by Alexej Suchov * @see Graphics2D#setComposite(Composite) */ public void setComposite(Composite comp) { if (comp instanceof AlphaComposite) { AlphaComposite composite = (AlphaComposite) comp; if (composite.getRule() == 3) { alpha = composite.getAlpha(); this.composite = composite; if (realPaint != null && (realPaint instanceof Color)) { Color c = (Color) realPaint; paint = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (c.getAlpha() * alpha)); } return; } } this.composite = comp; alpha = 1.0F; } /** * Method contributed by Alexej Suchov * @see Graphics2D#setPaint(Paint) */ public void setPaint(Paint paint) { if (paint == null) return; this.paint = paint; realPaint = paint; if ((composite instanceof AlphaComposite) && (paint instanceof Color)) { AlphaComposite co = (AlphaComposite) composite; if (co.getRule() == 3) { Color c = (Color) paint; this.paint = new Color(c.getRed(), c.getGreen(), c.getBlue(), (int) (c.getAlpha() * alpha)); realPaint = paint; } } } private Stroke transformStroke(Stroke stroke) { if (!(stroke instanceof BasicStroke)) return stroke; BasicStroke st = (BasicStroke)stroke; float scale = (float)Math.sqrt(Math.abs(transform.getDeterminant())); float dash[] = st.getDashArray(); if (dash != null) { for (int k = 0; k < dash.length; ++k) dash[k] *= scale; } return new BasicStroke(st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st.getDashPhase() * scale); } private void setStrokeDiff(Stroke newStroke, Stroke oldStroke) { if (newStroke == oldStroke) return; if (!(newStroke instanceof BasicStroke)) return; BasicStroke nStroke = (BasicStroke)newStroke; boolean oldOk = (oldStroke instanceof BasicStroke); BasicStroke oStroke = null; if (oldOk) oStroke = (BasicStroke)oldStroke; if (!oldOk || nStroke.getLineWidth() != oStroke.getLineWidth()) cb.setLineWidth(nStroke.getLineWidth()); if (!oldOk || nStroke.getEndCap() != oStroke.getEndCap()) { switch (nStroke.getEndCap()) { case BasicStroke.CAP_BUTT: cb.setLineCap(0); break; case BasicStroke.CAP_SQUARE: cb.setLineCap(2); break; default: cb.setLineCap(1); } } if (!oldOk || nStroke.getLineJoin() != oStroke.getLineJoin()) { switch (nStroke.getLineJoin()) { case BasicStroke.JOIN_MITER: cb.setLineJoin(0); break; case BasicStroke.JOIN_BEVEL: cb.setLineJoin(2); break; default: cb.setLineJoin(1); } } if (!oldOk || nStroke.getMiterLimit() != oStroke.getMiterLimit()) cb.setMiterLimit(nStroke.getMiterLimit()); boolean makeDash; if (oldOk) { if (nStroke.getDashArray() != null) { if (nStroke.getDashPhase() != oStroke.getDashPhase()) { makeDash = true; } else if (!java.util.Arrays.equals(nStroke.getDashArray(), oStroke.getDashArray())) { makeDash = true; } else makeDash = false; } else if (oStroke.getDashArray() != null) { makeDash = true; } else makeDash = false; } else { makeDash = true; } if (makeDash) { float dash[] = nStroke.getDashArray(); if (dash == null) cb.setLiteral("[]0 d\n"); else { cb.setLiteral('['); int lim = dash.length; for (int k = 0; k < lim; ++k) { cb.setLiteral(dash[k]); cb.setLiteral(' '); } cb.setLiteral(']'); cb.setLiteral(nStroke.getDashPhase()); cb.setLiteral(" d\n"); } } } /** * @see Graphics2D#setStroke(Stroke) */ public void setStroke(Stroke s) { originalStroke = s; this.stroke = transformStroke(s); } /** * Sets a rendering hint * @param arg0 * @param arg1 */ public void setRenderingHint(Key arg0, Object arg1) { if (arg1 != null) { rhints.put(arg0, arg1); } else { if (arg0 instanceof HyperLinkKey) { rhints.put(arg0, HyperLinkKey.VALUE_HYPERLINKKEY_OFF); } else { rhints.remove(arg0); } } } /** * @param arg0 a key * @return the rendering hint */ public Object getRenderingHint(Key arg0) { return rhints.get(arg0); } /** * @see Graphics2D#setRenderingHints(Map) */ public void setRenderingHints(Map hints) { rhints.clear(); rhints.putAll(hints); } /** * @see Graphics2D#addRenderingHints(Map) */ public void addRenderingHints(Map hints) { rhints.putAll(hints); } /** * @see Graphics2D#getRenderingHints() */ public RenderingHints getRenderingHints() { return rhints; } /** * @see Graphics#translate(int, int) */ public void translate(int x, int y) { translate((double)x, (double)y); } /** * @see Graphics2D#translate(double, double) */ public void translate(double tx, double ty) { transform.translate(tx,ty); } /** * @see Graphics2D#rotate(double) */ public void rotate(double theta) { transform.rotate(theta); } /** * @see Graphics2D#rotate(double, double, double) */ public void rotate(double theta, double x, double y) { transform.rotate(theta, x, y); } /** * @see Graphics2D#scale(double, double) */ public void scale(double sx, double sy) { transform.scale(sx, sy); this.stroke = transformStroke(originalStroke); } /** * @see Graphics2D#shear(double, double) */ public void shear(double shx, double shy) { transform.shear(shx, shy); } /** * @see Graphics2D#transform(AffineTransform) */ public void transform(AffineTransform tx) { transform.concatenate(tx); this.stroke = transformStroke(originalStroke); } /** * @see Graphics2D#setTransform(AffineTransform) */ public void setTransform(AffineTransform t) { transform = new AffineTransform(t); this.stroke = transformStroke(originalStroke); } /** * @see Graphics2D#getTransform() */ public AffineTransform getTransform() { return new AffineTransform(transform); } /** * Method contributed by Alexej Suchov * @see Graphics2D#getPaint() */ public Paint getPaint() { if (realPaint != null) { return realPaint; } else { return paint; } } /** * @see Graphics2D#getComposite() */ public Composite getComposite() { return composite; } /** * @see Graphics2D#setBackground(Color) */ public void setBackground(Color color) { background = color; } /** * @see Graphics2D#getBackground() */ public Color getBackground() { return background; } /** * @see Graphics2D#getStroke() */ public Stroke getStroke() { return originalStroke; } /** * @see Graphics2D#getFontRenderContext() */ public FontRenderContext getFontRenderContext() { boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); return new FontRenderContext(new AffineTransform(), antialias, fractions); } /** * @see Graphics#create() */ public Graphics create() { PdfGraphics2D g2 = new PdfGraphics2D(); g2.rhints.putAll( this.rhints ); g2.onlyShapes = this.onlyShapes; g2.transform = new AffineTransform(this.transform); g2.baseFonts = this.baseFonts; g2.fontMapper = this.fontMapper; g2.paint = this.paint; g2.fillGState = this.fillGState; g2.currentFillGState = this.currentFillGState; g2.strokeGState = this.strokeGState; g2.background = this.background; g2.mediaTracker = this.mediaTracker; g2.convertImagesToJPEG = this.convertImagesToJPEG; g2.jpegQuality = this.jpegQuality; g2.setFont(this.font); g2.cb = this.cb.getDuplicate(); g2.cb.saveState(); g2.width = this.width; g2.height = this.height; g2.followPath(new Area(new Rectangle2D.Float(0, 0, width, height)), CLIP); if (this.clip != null) g2.clip = new Area(this.clip); g2.composite = composite; g2.stroke = stroke; g2.originalStroke = originalStroke; g2.strokeOne = (BasicStroke)g2.transformStroke(g2.strokeOne); g2.oldStroke = g2.strokeOne; g2.setStrokeDiff(g2.oldStroke, null); g2.cb.saveState(); if (g2.clip != null) g2.followPath(g2.clip, CLIP); g2.kid = true; if (this.kids == null) this.kids = new ArrayList(); this.kids.add(new Integer(cb.getInternalBuffer().size())); this.kids.add(g2); return g2; } public PdfContentByte getContent() { return this.cb; } /** * @see Graphics#getColor() */ public Color getColor() { if (paint instanceof Color) { return (Color)paint; } else { return Color.black; } } /** * @see Graphics#setColor(Color) */ public void setColor(Color color) { setPaint(color); } /** * @see Graphics#setPaintMode() */ public void setPaintMode() {} /** * @see Graphics#setXORMode(Color) */ public void setXORMode(Color c1) { } /** * @see Graphics#getFont() */ public Font getFont() { return font; } /** * @see Graphics#setFont(Font) */ /** * Sets the current font. */ public void setFont(Font f) { if (f == null) return; if (onlyShapes) { font = f; return; } if (f == font) return; font = f; fontSize = f.getSize2D(); baseFont = getCachedBaseFont(f); } private BaseFont getCachedBaseFont(Font f) { synchronized (baseFonts) { BaseFont bf = (BaseFont)baseFonts.get(f.getFontName()); if (bf == null) { bf = fontMapper.awtToPdf(f); baseFonts.put(f.getFontName(), bf); } return bf; } } /** * @see Graphics#getFontMetrics(Font) */ public FontMetrics getFontMetrics(Font f) { return dg2.getFontMetrics(f); } /** * @see Graphics#getClipBounds() */ public Rectangle getClipBounds() { if (clip == null) return null; return getClip().getBounds(); } /** * @see Graphics#clipRect(int, int, int, int) */ public void clipRect(int x, int y, int width, int height) { Rectangle2D rect = new Rectangle2D.Double(x,y,width,height); clip(rect); } /** * @see Graphics#setClip(int, int, int, int) */ public void setClip(int x, int y, int width, int height) { Rectangle2D rect = new Rectangle2D.Double(x,y,width,height); setClip(rect); } /** * @see Graphics2D#clip(Shape) */ public void clip(Shape s) { if (s == null) { setClip(null); return; } s = transform.createTransformedShape(s); if (clip == null) clip = new Area(s); else clip.intersect(new Area(s)); followPath(s, CLIP); } /** * @see Graphics#getClip() */ public Shape getClip() { try { return transform.createInverse().createTransformedShape(clip); } catch (NoninvertibleTransformException e) { return null; } } /** * @see Graphics#setClip(Shape) */ public void setClip(Shape s) { cb.restoreState(); cb.saveState(); if (s != null) s = transform.createTransformedShape(s); if (s == null) { clip = null; } else { clip = new Area(s); followPath(s, CLIP); } paintFill = paintStroke = null; currentFillGState = currentStrokeGState = 255; oldStroke = strokeOne; } /** * @see Graphics#copyArea(int, int, int, int, int, int) */ public void copyArea(int x, int y, int width, int height, int dx, int dy) { } /** * @see Graphics#drawLine(int, int, int, int) */ public void drawLine(int x1, int y1, int x2, int y2) { Line2D line = new Line2D.Double(x1, y1, x2, y2); draw(line); } /** * @see Graphics#fillRect(int, int, int, int) */ public void drawRect(int x, int y, int width, int height) { draw(new Rectangle(x, y, width, height)); } /** * @see Graphics#fillRect(int, int, int, int) */ public void fillRect(int x, int y, int width, int height) { fill(new Rectangle(x,y,width,height)); } /** * @see Graphics#clearRect(int, int, int, int) */ public void clearRect(int x, int y, int width, int height) { Paint temp = paint; setPaint(background); fillRect(x,y,width,height); setPaint(temp); } /** * @see Graphics#drawRoundRect(int, int, int, int, int, int) */ public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { RoundRectangle2D rect = new RoundRectangle2D.Double(x,y,width,height,arcWidth, arcHeight); draw(rect); } /** * @see Graphics#fillRoundRect(int, int, int, int, int, int) */ public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { RoundRectangle2D rect = new RoundRectangle2D.Double(x,y,width,height,arcWidth, arcHeight); fill(rect); } /** * @see Graphics#drawOval(int, int, int, int) */ public void drawOval(int x, int y, int width, int height) { Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); draw(oval); } /** * @see Graphics#fillOval(int, int, int, int) */ public void fillOval(int x, int y, int width, int height) { Ellipse2D oval = new Ellipse2D.Float(x, y, width, height); fill(oval); } /** * @see Graphics#drawArc(int, int, int, int, int, int) */ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { Arc2D arc = new Arc2D.Double(x,y,width,height,startAngle, arcAngle, Arc2D.OPEN); draw(arc); } /** * @see Graphics#fillArc(int, int, int, int, int, int) */ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { Arc2D arc = new Arc2D.Double(x,y,width,height,startAngle, arcAngle, Arc2D.PIE); fill(arc); } /** * @see Graphics#drawPolyline(int[], int[], int) */ public void drawPolyline(int[] x, int[] y, int nPoints) { PolylineShape polyline = new PolylineShape(x, y, nPoints); draw(polyline); } /** * @see Graphics#drawPolygon(int[], int[], int) */ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { Polygon poly = new Polygon(xPoints, yPoints, nPoints); draw(poly); } /** * @see Graphics#fillPolygon(int[], int[], int) */ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { Polygon poly = new Polygon(); for (int i = 0; i < nPoints; i++) { poly.addPoint(xPoints[i], yPoints[i]); } fill(poly); } /** * @see Graphics#drawImage(Image, int, int, ImageObserver) */ public boolean drawImage(Image img, int x, int y, ImageObserver observer) { return drawImage(img, x, y, null, observer); } /** * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver) */ public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { return drawImage(img, x, y, width, height, null, observer); } /** * @see Graphics#drawImage(Image, int, int, Color, ImageObserver) */ public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { waitForImage(img); return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), bgcolor, observer); } /** * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver) */ public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { waitForImage(img); double scalex = width/(double)img.getWidth(observer); double scaley = height/(double)img.getHeight(observer); AffineTransform tx = AffineTransform.getTranslateInstance(x,y); tx.scale(scalex,scaley); return drawImage(img, null, tx, bgcolor, observer); } /** * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, ImageObserver) */ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer); } /** * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, Color, ImageObserver) */ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { waitForImage(img); double dwidth = (double)dx2-dx1; double dheight = (double)dy2-dy1; double swidth = (double)sx2-sx1; double sheight = (double)sy2-sy1; //if either width or height is 0, then there is nothing to draw if (dwidth == 0 || dheight == 0 || swidth == 0 || sheight == 0) return true; double scalex = dwidth/swidth; double scaley = dheight/sheight; double transx = sx1*scalex; double transy = sy1*scaley; AffineTransform tx = AffineTransform.getTranslateInstance(dx1-transx,dy1-transy); tx.scale(scalex,scaley); BufferedImage mask = new BufferedImage(img.getWidth(observer), img.getHeight(observer), BufferedImage.TYPE_BYTE_BINARY); Graphics g = mask.getGraphics(); g.fillRect(sx1,sy1, (int)swidth, (int)sheight); drawImage(img, mask, tx, null, observer); g.dispose(); return true; } /** * @see Graphics#dispose() */ public void dispose() { if (kid) return; if (!disposeCalled) { disposeCalled = true; cb.restoreState(); cb.restoreState(); dg2.dispose(); dg2 = null; if (kids != null) { ByteBuffer buf = new ByteBuffer(); internalDispose(buf); ByteBuffer buf2 = cb.getInternalBuffer(); buf2.reset(); buf2.append(buf); } } } private void internalDispose(ByteBuffer buf) { int last = 0; int pos = 0; ByteBuffer buf2 = cb.getInternalBuffer(); if (kids != null) { for (int k = 0; k < kids.size(); k += 2) { pos = ((Integer)kids.get(k)).intValue(); PdfGraphics2D g2 = (PdfGraphics2D)kids.get(k + 1); g2.cb.restoreState(); g2.cb.restoreState(); buf.append(buf2.getBuffer(), last, pos - last); g2.dg2.dispose(); g2.dg2 = null; g2.internalDispose(buf); last = pos; } } buf.append(buf2.getBuffer(), last, buf2.size() - last); } /////////////////////////////////////////////// // // // implementation specific methods // // private void followPath(Shape s, int drawType) { if (s==null) return; if (drawType==STROKE) { if (!(stroke instanceof BasicStroke)) { s = stroke.createStrokedShape(s); followPath(s, FILL); return; } } if (drawType==STROKE) { setStrokeDiff(stroke, oldStroke); oldStroke = stroke; setStrokePaint(); } else if (drawType==FILL) setFillPaint(); PathIterator points; int traces = 0; if (drawType == CLIP) points = s.getPathIterator(IDENTITY); else points = s.getPathIterator(transform); float[] coords = new float[6]; while(!points.isDone()) { ++traces; int segtype = points.currentSegment(coords); normalizeY(coords); switch(segtype) { case PathIterator.SEG_CLOSE: cb.closePath(); break; case PathIterator.SEG_CUBICTO: cb.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_LINETO: cb.lineTo(coords[0], coords[1]); break; case PathIterator.SEG_MOVETO: cb.moveTo(coords[0], coords[1]); break; case PathIterator.SEG_QUADTO: cb.curveTo(coords[0], coords[1], coords[2], coords[3]); break; } points.next(); } switch (drawType) { case FILL: if (traces > 0) { if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) cb.eoFill(); else cb.fill(); } break; case STROKE: if (traces > 0) cb.stroke(); break; default: //drawType==CLIP if (traces == 0) cb.rectangle(0, 0, 0, 0); if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) cb.eoClip(); else cb.clip(); cb.newPath(); } } private float normalizeY(float y) { return this.height - y; } private void normalizeY(float[] coords) { coords[1] = normalizeY(coords[1]); coords[3] = normalizeY(coords[3]); coords[5] = normalizeY(coords[5]); } private AffineTransform normalizeMatrix() { double[] mx = new double[6]; AffineTransform result = AffineTransform.getTranslateInstance(0,0); result.getMatrix(mx); mx[3]=-1; mx[5]=height; result = new AffineTransform(mx); result.concatenate(transform); return result; } private boolean drawImage(Image img, Image mask, AffineTransform xform, Color bgColor, ImageObserver obs) { if (xform==null) xform = new AffineTransform(); else xform = new AffineTransform(xform); xform.translate(0, img.getHeight(obs)); xform.scale(img.getWidth(obs), img.getHeight(obs)); AffineTransform inverse = this.normalizeMatrix(); AffineTransform flipper = AffineTransform.getScaleInstance(1,-1); inverse.concatenate(xform); inverse.concatenate(flipper); double[] mx = new double[6]; inverse.getMatrix(mx); if (currentFillGState != 255) { PdfGState gs = fillGState[255]; if (gs == null) { gs = new PdfGState(); gs.setFillOpacity(1); fillGState[255] = gs; } cb.setGState(gs); } try { com.lowagie.text.Image image = null; if(!convertImagesToJPEG){ image = com.lowagie.text.Image.getInstance(img, bgColor); } else{ BufferedImage scaled = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g3 = scaled.createGraphics(); g3.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null); g3.dispose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault()); iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); iwparam.setCompressionQuality(jpegQuality);//Set here your compression rate ImageWriter iw = (ImageWriter)ImageIO.getImageWritersByFormatName("jpg").next(); ImageOutputStream ios = ImageIO.createImageOutputStream(baos); iw.setOutput(ios); iw.write(null, new IIOImage(scaled, null, null), iwparam); iw.dispose(); ios.close(); scaled.flush(); scaled = null; image = com.lowagie.text.Image.getInstance(baos.toByteArray()); } if (mask!=null) { com.lowagie.text.Image msk = com.lowagie.text.Image.getInstance(mask, null, true); msk.makeMask(); msk.setInverted(true); image.setImageMask(msk); } cb.addImage(image, (float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]); Object url = getRenderingHint(HyperLinkKey.KEY_INSTANCE); if (url != null && !url.equals(HyperLinkKey.VALUE_HYPERLINKKEY_OFF)) { PdfAction action = new PdfAction(url.toString()); cb.setAction(action, (float)mx[4], (float)mx[5], (float)(mx[0]+mx[4]), (float)(mx[3]+mx[5])); } } catch (Exception ex) { throw new IllegalArgumentException(); } if (currentFillGState != 255) { PdfGState gs = fillGState[currentFillGState]; cb.setGState(gs); } return true; } private boolean checkNewPaint(Paint oldPaint) { if (paint == oldPaint) return false; return !((paint instanceof Color) && paint.equals(oldPaint)); } private void setFillPaint() { if (checkNewPaint(paintFill)) { paintFill = paint; setPaint(false, 0, 0, true); } } private void setStrokePaint() { if (checkNewPaint(paintStroke)) { paintStroke = paint; setPaint(false, 0, 0, false); } } private void setPaint(boolean invert, double xoffset, double yoffset, boolean fill) { if (paint instanceof Color) { Color color = (Color)paint; int alpha = color.getAlpha(); if (fill) { if (alpha != currentFillGState) { currentFillGState = alpha; PdfGState gs = fillGState[alpha]; if (gs == null) { gs = new PdfGState(); gs.setFillOpacity(alpha / 255f); fillGState[alpha] = gs; } cb.setGState(gs); } cb.setColorFill(color); } else { if (alpha != currentStrokeGState) { currentStrokeGState = alpha; PdfGState gs = strokeGState[alpha]; if (gs == null) { gs = new PdfGState(); gs.setStrokeOpacity(alpha / 255f); strokeGState[alpha] = gs; } cb.setGState(gs); } cb.setColorStroke(color); } } else if (paint instanceof GradientPaint) { GradientPaint gp = (GradientPaint)paint; Point2D p1 = gp.getPoint1(); transform.transform(p1, p1); Point2D p2 = gp.getPoint2(); transform.transform(p2, p2); Color c1 = gp.getColor1(); Color c2 = gp.getColor2(); PdfShading shading = PdfShading.simpleAxial(cb.getPdfWriter(), (float)p1.getX(), normalizeY((float)p1.getY()), (float)p2.getX(), normalizeY((float)p2.getY()), c1, c2); PdfShadingPattern pat = new PdfShadingPattern(shading); if (fill) cb.setShadingFill(pat); else cb.setShadingStroke(pat); } else if (paint instanceof TexturePaint) { try { TexturePaint tp = (TexturePaint)paint; BufferedImage img = tp.getImage(); Rectangle2D rect = tp.getAnchorRect(); com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null); PdfPatternPainter pattern = cb.createPattern(image.getWidth(), image.getHeight()); AffineTransform inverse = this.normalizeMatrix(); inverse.translate(rect.getX(), rect.getY()); inverse.scale(rect.getWidth() / image.getWidth(), -rect.getHeight() / image.getHeight()); double[] mx = new double[6]; inverse.getMatrix(mx); pattern.setPatternMatrix((float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]) ; image.setAbsolutePosition(0,0); pattern.addImage(image); if (fill) cb.setPatternFill(pattern); else cb.setPatternStroke(pattern); } catch (Exception ex) { if (fill) cb.setColorFill(Color.gray); else cb.setColorStroke(Color.gray); } } else { try { BufferedImage img = null; int type = BufferedImage.TYPE_4BYTE_ABGR; if (paint.getTransparency() == Transparency.OPAQUE) { type = BufferedImage.TYPE_3BYTE_BGR; } img = new BufferedImage((int)width, (int)height, type); Graphics2D g = (Graphics2D)img.getGraphics(); g.transform(transform); AffineTransform inv = transform.createInverse(); Shape fillRect = new Rectangle2D.Double(0,0,img.getWidth(),img.getHeight()); fillRect = inv.createTransformedShape(fillRect); g.setPaint(paint); g.fill(fillRect); if (invert) { AffineTransform tx = new AffineTransform(); tx.scale(1,-1); tx.translate(-xoffset,-yoffset); g.drawImage(img,tx,null); } g.dispose(); g = null; com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null); PdfPatternPainter pattern = cb.createPattern(width, height); image.setAbsolutePosition(0,0); pattern.addImage(image); if (fill) cb.setPatternFill(pattern); else cb.setPatternStroke(pattern); } catch (Exception ex) { if (fill) cb.setColorFill(Color.gray); else cb.setColorStroke(Color.gray); } } } private synchronized void waitForImage(java.awt.Image image) { if (mediaTracker == null) mediaTracker = new MediaTracker(new PdfGraphics2D.FakeComponent()); mediaTracker.addImage(image, 0); try { mediaTracker.waitForID(0); } catch (InterruptedException e) { // empty on purpose } mediaTracker.removeImage(image); } static private class FakeComponent extends Component { private static final long serialVersionUID = 6450197945596086638L; } /** * @since 2.0.8 */ public static class HyperLinkKey extends RenderingHints.Key { public static final HyperLinkKey KEY_INSTANCE = new HyperLinkKey(9999); public static final Object VALUE_HYPERLINKKEY_OFF = "0"; protected HyperLinkKey(int arg0) { super(arg0); } public boolean isCompatibleValue(Object val) { return true; } public String toString() { return "HyperLinkKey"; } } } src/core/com/lowagie/text/pdf/PdfICCBased.java100644 0 0 7673 11036112746 16536 0ustar 0 0 /* * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.color.ICC_Profile; import com.lowagie.text.ExceptionConverter; /** * A PdfICCBased defines a ColorSpace * * @see PdfStream */ public class PdfICCBased extends PdfStream { /** * Creates an ICC stream. * @param profile an ICC profile */ public PdfICCBased(ICC_Profile profile) { this(profile, DEFAULT_COMPRESSION); } /** * Creates an ICC stream. * * @param compressionLevel the compressionLevel * * @param profile an ICC profile * @since 2.1.3 (replacing the constructor without param compressionLevel) */ public PdfICCBased(ICC_Profile profile, int compressionLevel) { super(); try { int numberOfComponents = profile.getNumComponents(); switch (numberOfComponents) { case 1: put(PdfName.ALTERNATE, PdfName.DEVICEGRAY); break; case 3: put(PdfName.ALTERNATE, PdfName.DEVICERGB); break; case 4: put(PdfName.ALTERNATE, PdfName.DEVICECMYK); break; default: throw new PdfException(numberOfComponents + " component(s) is not supported in PDF1.4"); } put(PdfName.N, new PdfNumber(numberOfComponents)); bytes = profile.getData(); flateCompress(compressionLevel); } catch (Exception e) { throw new ExceptionConverter(e); } } } src/core/com/lowagie/text/pdf/PdfImage.java100644 0 0 30713 11154165267 16241 0ustar 0 0 /* * $Id: PdfImage.java 3715 2009-02-23 15:02:23Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.lowagie.text.Image; /** * PdfImage is a PdfStream containing an image-Dictionary and -stream. */ public class PdfImage extends PdfStream { static final int TRANSFERSIZE = 4096; // membervariables /** This is the PdfName of the image. */ protected PdfName name = null; // constructor /** * Constructs a PdfImage-object. * * @param image the Image-object * @param name the PdfName for this image * @throws BadPdfFormatException on error */ public PdfImage(Image image, String name, PdfIndirectReference maskRef) throws BadPdfFormatException { super(); this.name = new PdfName(name); put(PdfName.TYPE, PdfName.XOBJECT); put(PdfName.SUBTYPE, PdfName.IMAGE); put(PdfName.WIDTH, new PdfNumber(image.getWidth())); put(PdfName.HEIGHT, new PdfNumber(image.getHeight())); if (image.getLayer() != null) put(PdfName.OC, image.getLayer().getRef()); if (image.isMask() && (image.getBpc() == 1 || image.getBpc() > 0xff)) put(PdfName.IMAGEMASK, PdfBoolean.PDFTRUE); if (maskRef != null) { if (image.isSmask()) put(PdfName.SMASK, maskRef); else put(PdfName.MASK, maskRef); } if (image.isMask() && image.isInverted()) put(PdfName.DECODE, new PdfLiteral("[1 0]")); if (image.isInterpolation()) put(PdfName.INTERPOLATE, PdfBoolean.PDFTRUE); InputStream is = null; try { // Raw Image data if (image.isImgRaw()) { // will also have the CCITT parameters int colorspace = image.getColorspace(); int transparency[] = image.getTransparency(); if (transparency != null && !image.isMask() && maskRef == null) { String s = "["; for (int k = 0; k < transparency.length; ++k) s += transparency[k] + " "; s += "]"; put(PdfName.MASK, new PdfLiteral(s)); } bytes = image.getRawData(); put(PdfName.LENGTH, new PdfNumber(bytes.length)); int bpc = image.getBpc(); if (bpc > 0xff) { if (!image.isMask()) put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); put(PdfName.BITSPERCOMPONENT, new PdfNumber(1)); put(PdfName.FILTER, PdfName.CCITTFAXDECODE); int k = bpc - Image.CCITTG3_1D; PdfDictionary decodeparms = new PdfDictionary(); if (k != 0) decodeparms.put(PdfName.K, new PdfNumber(k)); if ((colorspace & Image.CCITT_BLACKIS1) != 0) decodeparms.put(PdfName.BLACKIS1, PdfBoolean.PDFTRUE); if ((colorspace & Image.CCITT_ENCODEDBYTEALIGN) != 0) decodeparms.put(PdfName.ENCODEDBYTEALIGN, PdfBoolean.PDFTRUE); if ((colorspace & Image.CCITT_ENDOFLINE) != 0) decodeparms.put(PdfName.ENDOFLINE, PdfBoolean.PDFTRUE); if ((colorspace & Image.CCITT_ENDOFBLOCK) != 0) decodeparms.put(PdfName.ENDOFBLOCK, PdfBoolean.PDFFALSE); decodeparms.put(PdfName.COLUMNS, new PdfNumber(image.getWidth())); decodeparms.put(PdfName.ROWS, new PdfNumber(image.getHeight())); put(PdfName.DECODEPARMS, decodeparms); } else { switch(colorspace) { case 1: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); if (image.isInverted()) put(PdfName.DECODE, new PdfLiteral("[1 0]")); break; case 3: put(PdfName.COLORSPACE, PdfName.DEVICERGB); if (image.isInverted()) put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0]")); break; case 4: default: put(PdfName.COLORSPACE, PdfName.DEVICECMYK); if (image.isInverted()) put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]")); } PdfDictionary additional = image.getAdditional(); if (additional != null) putAll(additional); if (image.isMask() && (image.getBpc() == 1 || image.getBpc() > 8)) remove(PdfName.COLORSPACE); put(PdfName.BITSPERCOMPONENT, new PdfNumber(image.getBpc())); if (image.isDeflated()) put(PdfName.FILTER, PdfName.FLATEDECODE); else { flateCompress(image.getCompressionLevel()); } } return; } // GIF, JPEG or PNG String errorID; if (image.getRawData() == null){ is = image.getUrl().openStream(); errorID = image.getUrl().toString(); } else{ is = new java.io.ByteArrayInputStream(image.getRawData()); errorID = "Byte array"; } switch(image.type()) { case Image.JPEG: put(PdfName.FILTER, PdfName.DCTDECODE); switch(image.getColorspace()) { case 1: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); break; case 3: put(PdfName.COLORSPACE, PdfName.DEVICERGB); break; default: put(PdfName.COLORSPACE, PdfName.DEVICECMYK); if (image.isInverted()) { put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]")); } } put(PdfName.BITSPERCOMPONENT, new PdfNumber(8)); if (image.getRawData() != null){ bytes = image.getRawData(); put(PdfName.LENGTH, new PdfNumber(bytes.length)); return; } streamBytes = new ByteArrayOutputStream(); transferBytes(is, streamBytes, -1); break; case Image.JPEG2000: put(PdfName.FILTER, PdfName.JPXDECODE); if (image.getColorspace() > 0) { switch(image.getColorspace()) { case 1: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); break; case 3: put(PdfName.COLORSPACE, PdfName.DEVICERGB); break; default: put(PdfName.COLORSPACE, PdfName.DEVICECMYK); } put(PdfName.BITSPERCOMPONENT, new PdfNumber(image.getBpc())); } if (image.getRawData() != null){ bytes = image.getRawData(); put(PdfName.LENGTH, new PdfNumber(bytes.length)); return; } streamBytes = new ByteArrayOutputStream(); transferBytes(is, streamBytes, -1); break; case Image.JBIG2: put(PdfName.FILTER, PdfName.JBIG2DECODE); put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); put(PdfName.BITSPERCOMPONENT, new PdfNumber(1)); if (image.getRawData() != null){ bytes = image.getRawData(); put(PdfName.LENGTH, new PdfNumber(bytes.length)); return; } streamBytes = new ByteArrayOutputStream(); transferBytes(is, streamBytes, -1); break; default: throw new BadPdfFormatException(errorID + " is an unknown Image format."); } put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); } catch(IOException ioe) { throw new BadPdfFormatException(ioe.getMessage()); } finally { if (is != null) { try{ is.close(); } catch (Exception ee) { // empty on purpose } } } } /** * Returns the PdfName of the image. * * @return the name */ public PdfName name() { return name; } static void transferBytes(InputStream in, OutputStream out, int len) throws IOException { byte buffer[] = new byte[TRANSFERSIZE]; if (len < 0) len = 0x7ffffff; int size; while (len != 0) { size = in.read(buffer, 0, Math.min(len, TRANSFERSIZE)); if (size < 0) return; out.write(buffer, 0, size); len -= size; } } protected void importAll(PdfImage dup) { name = dup.name; compressed = dup.compressed; compressionLevel = dup.compressionLevel; streamBytes = dup.streamBytes; bytes = dup.bytes; hashMap = dup.hashMap; } } src/core/com/lowagie/text/pdf/PdfImportedPage.java100644 0 0 13274 11213370070 17564 0ustar 0 0 /* * $Id: PdfImportedPage.java 3929 2009-05-22 13:26:41Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; /** Represents an imported page. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfImportedPage extends com.lowagie.text.pdf.PdfTemplate { PdfReaderInstance readerInstance; int pageNumber; PdfImportedPage(PdfReaderInstance readerInstance, PdfWriter writer, int pageNumber) { this.readerInstance = readerInstance; this.pageNumber = pageNumber; this.writer = writer; bBox = readerInstance.getReader().getPageSize(pageNumber); setMatrix(1, 0, 0, 1, -bBox.getLeft(), -bBox.getBottom()); type = TYPE_IMPORTED; } /** Reads the content from this PdfImportedPage-object from a reader. * * @return self * */ public PdfImportedPage getFromReader() { return this; } public int getPageNumber() { return pageNumber; } /** Always throws an error. This operation is not allowed. * @param image dummy * @param a dummy * @param b dummy * @param c dummy * @param d dummy * @param e dummy * @param f dummy * @throws DocumentException dummy */ public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { throwError(); } /** Always throws an error. This operation is not allowed. * @param template dummy * @param a dummy * @param b dummy * @param c dummy * @param d dummy * @param e dummy * @param f dummy */ public void addTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) { throwError(); } /** Always throws an error. This operation is not allowed. * @return dummy */ public PdfContentByte getDuplicate() { throwError(); return null; } /** * Gets the stream representing this page. * * @param compressionLevel the compressionLevel * @return the stream representing this page * @since 2.1.3 (replacing the method without param compressionLevel) */ PdfStream getFormXObject(int compressionLevel) throws IOException { return readerInstance.getFormXObject(pageNumber, compressionLevel); } public void setColorFill(PdfSpotColor sp, float tint) { throwError(); } public void setColorStroke(PdfSpotColor sp, float tint) { throwError(); } PdfObject getResources() { return readerInstance.getResources(pageNumber); } /** Always throws an error. This operation is not allowed. * @param bf dummy * @param size dummy */ public void setFontAndSize(BaseFont bf, float size) { throwError(); } /** * Always throws an error. This operation is not allowed. * @param group New value of property group. * @since 2.1.6 */ public void setGroup(PdfTransparencyGroup group) { throwError(); } void throwError() { throw new RuntimeException("Content can not be added to a PdfImportedPage."); } PdfReaderInstance getPdfReaderInstance() { return readerInstance; } } src/core/com/lowagie/text/pdf/PdfIndirectObject.java100644 0 0 13501 11213370070 20065 0ustar 0 0 /* * $Id: PdfIndirectObject.java 3912 2009-04-26 08:38:15Z blowagie $ * $Name$ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; /** * PdfIndirectObject is the Pdf indirect object. *

* An indirect object is an object that has been labeled so that it can be referenced by * other objects. Any type of PdfObject may be labeled as an indirect object.
* An indirect object consists of an object identifier, a direct object, and the endobj * keyword. The object identifier consists of an integer object number, an integer * generation number, and the obj keyword.
* This object is described in the 'Portable Document Format Reference Manual version 1.7' * section 3.2.9 (page 63-65). * * @see PdfObject * @see PdfIndirectReference */ public class PdfIndirectObject { // membervariables /** The object number */ protected int number; /** the generation number */ protected int generation = 0; static final byte STARTOBJ[] = DocWriter.getISOBytes(" obj\n"); static final byte ENDOBJ[] = DocWriter.getISOBytes("\nendobj\n"); static final int SIZEOBJ = STARTOBJ.length + ENDOBJ.length; PdfObject object; PdfWriter writer; // constructors /** * Constructs a PdfIndirectObject. * * @param number the object number * @param object the direct object */ PdfIndirectObject(int number, PdfObject object, PdfWriter writer) { this(number, 0, object, writer); } PdfIndirectObject(PdfIndirectReference ref, PdfObject object, PdfWriter writer) { this(ref.getNumber(),ref.getGeneration(),object,writer); } /** * Constructs a PdfIndirectObject. * * @param number the object number * @param generation the generation number * @param object the direct object */ PdfIndirectObject(int number, int generation, PdfObject object, PdfWriter writer) { this.writer = writer; this.number = number; this.generation = generation; this.object = object; PdfEncryption crypto = null; if (writer != null) crypto = writer.getEncryption(); if (crypto != null) { crypto.setHashKey(number, generation); } } // methods /** * Return the length of this PdfIndirectObject. * * @return the length of the PDF-representation of this indirect object. */ // public int length() { // if (isStream) // return bytes.size() + SIZEOBJ + stream.getStreamLength(writer); // else // return bytes.size(); // } /** * Returns a PdfIndirectReference to this PdfIndirectObject. * * @return a PdfIndirectReference */ public PdfIndirectReference getIndirectReference() { return new PdfIndirectReference(object.type(), number, generation); } /** * Writes efficiently to a stream * * @param os the stream to write to * @throws IOException on write error */ void writeTo(OutputStream os) throws IOException { os.write(DocWriter.getISOBytes(String.valueOf(number))); os.write(' '); os.write(DocWriter.getISOBytes(String.valueOf(generation))); os.write(STARTOBJ); object.toPdf(writer, os); os.write(ENDOBJ); } } src/core/com/lowagie/text/pdf/PdfIndirectReference.java100644 0 0 11077 11213370070 20563 0ustar 0 0 /* * $Id: PdfIndirectReference.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfIndirectReference contains a reference to a PdfIndirectObject. *

* Any object used as an element of an array or as a value in a dictionary may be specified * by either a direct object of an indirect reference. An indirect reference is a reference * to an indirect object, and consists of the indirect object's object number, generation number * and the R keyword.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 4.11 (page 54). * * @see PdfObject * @see PdfIndirectObject */ public class PdfIndirectReference extends PdfObject { // membervariables /** the object number */ protected int number; /** the generation number */ protected int generation = 0; // constructors protected PdfIndirectReference() { super(0); } /** * Constructs a PdfIndirectReference. * * @param type the type of the PdfObject that is referenced to * @param number the object number. * @param generation the generation number. */ PdfIndirectReference(int type, int number, int generation) { super(0, new StringBuffer().append(number).append(" ").append(generation).append(" R").toString()); this.number = number; this.generation = generation; } /** * Constructs a PdfIndirectReference. * * @param type the type of the PdfObject that is referenced to * @param number the object number. */ PdfIndirectReference(int type, int number) { this(type, number, 0); } // methods /** * Returns the number of the object. * * @return a number. */ public int getNumber() { return number; } /** * Returns the generation of the object. * * @return a number. */ public int getGeneration() { return generation; } public String toString() { return new StringBuffer().append(number).append(" ").append(generation).append(" R").toString(); } }src/core/com/lowagie/text/pdf/PdfLayer.java100644 0 0 26524 11161724620 16270 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; /** * An optional content group is a dictionary representing a collection of graphics * that can be made visible or invisible dynamically by users of viewer applications. * In iText they are referenced as layers. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfLayer extends PdfDictionary implements PdfOCG { protected PdfIndirectReference ref; protected ArrayList children; protected PdfLayer parent; protected String title; /** * Holds value of property on. */ private boolean on = true; /** * Holds value of property onPanel. */ private boolean onPanel = true; PdfLayer(String title) { this.title = title; } /** * Creates a title layer. A title layer is not really a layer but a collection of layers * under the same title heading. * @param title the title text * @param writer the PdfWriter * @return the title layer */ public static PdfLayer createTitle(String title, PdfWriter writer) { if (title == null) throw new NullPointerException("Title cannot be null."); PdfLayer layer = new PdfLayer(title); writer.registerLayer(layer); return layer; } /** * Creates a new layer. * @param name the name of the layer * @param writer the writer */ public PdfLayer(String name, PdfWriter writer) { super(PdfName.OCG); setName(name); ref = writer.getPdfIndirectReference(); writer.registerLayer(this); } String getTitle() { return title; } /** * Adds a child layer. Nested layers can only have one parent. * @param child the child layer */ public void addChild(PdfLayer child) { if (child.parent != null) throw new IllegalArgumentException("The layer '" + ((PdfString)child.get(PdfName.NAME)).toUnicodeString() + "' already has a parent."); child.parent = this; if (children == null) children = new ArrayList(); children.add(child); } /** * Gets the parent layer. * @return the parent layer or null if the layer has no parent */ public PdfLayer getParent() { return parent; } /** * Gets the children layers. * @return the children layers or null if the layer has no children */ public ArrayList getChildren() { return children; } /** * Gets the PdfIndirectReference that represents this layer. * @return the PdfIndirectReference that represents this layer */ public PdfIndirectReference getRef() { return ref; } /** * Sets the PdfIndirectReference that represents this layer. * This can only be done from PdfStamperImp. * @param ref The reference to the OCG object * @since 2.1.2 */ void setRef(PdfIndirectReference ref) { this.ref = ref; } /** * Sets the name of this layer. * @param name the name of this layer */ public void setName(String name) { put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); } /** * Gets the dictionary representing the layer. It just returns this. * @return the dictionary representing the layer */ public PdfObject getPdfObject() { return this; } /** * Gets the initial visibility of the layer. * @return the initial visibility of the layer */ public boolean isOn() { return this.on; } /** * Sets the initial visibility of the layer. * @param on the initial visibility of the layer */ public void setOn(boolean on) { this.on = on; } private PdfDictionary getUsage() { PdfDictionary usage = (PdfDictionary)get(PdfName.USAGE); if (usage == null) { usage = new PdfDictionary(); put(PdfName.USAGE, usage); } return usage; } /** * Used by the creating application to store application-specific * data associated with this optional content group. * @param creator a text string specifying the application that created the group * @param subtype a string defining the type of content controlled by the group. Suggested * values include but are not limited to Artwork, for graphic-design or publishing * applications, and Technical, for technical designs such as building plans or * schematics */ public void setCreatorInfo(String creator, String subtype) { PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE)); dic.put(PdfName.SUBTYPE, new PdfName(subtype)); usage.put(PdfName.CREATORINFO, dic); } /** * Specifies the language of the content controlled by this * optional content group * @param lang a language string which specifies a language and possibly a locale * (for example, es-MX represents Mexican Spanish) * @param preferred used by viewer applications when there is a partial match but no exact * match between the system language and the language strings in all usage dictionaries */ public void setLanguage(String lang, boolean preferred) { PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.LANG, new PdfString(lang, PdfObject.TEXT_UNICODE)); if (preferred) dic.put(PdfName.PREFERRED, PdfName.ON); usage.put(PdfName.LANGUAGE, dic); } /** * Specifies the recommended state for content in this * group when the document (or part of it) is saved by a viewer application to a format * that does not support optional content (for example, an earlier version of * PDF or a raster image format). * @param export the export state */ public void setExport(boolean export) { PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.EXPORTSTATE, export ? PdfName.ON : PdfName.OFF); usage.put(PdfName.EXPORT, dic); } /** * Specifies a range of magnifications at which the content * in this optional content group is best viewed. * @param min the minimum recommended magnification factors at which the group * should be ON. A negative value will set the default to 0 * @param max the maximum recommended magnification factor at which the group * should be ON. A negative value will set the largest possible magnification supported by the * viewer application */ public void setZoom(float min, float max) { if (min <= 0 && max < 0) return; PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); if (min > 0) dic.put(PdfName.MIN_LOWER_CASE, new PdfNumber(min)); if (max >= 0) dic.put(PdfName.MAX_LOWER_CASE, new PdfNumber(max)); usage.put(PdfName.ZOOM, dic); } /** * Specifies that the content in this group is intended for * use in printing * @param subtype a name specifying the kind of content controlled by the group; * for example, Trapping, PrintersMarks and Watermark * @param printstate indicates that the group should be * set to that state when the document is printed from a viewer application */ public void setPrint(String subtype, boolean printstate) { PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.SUBTYPE, new PdfName(subtype)); dic.put(PdfName.PRINTSTATE, printstate ? PdfName.ON : PdfName.OFF); usage.put(PdfName.PRINT, dic); } /** * Indicates that the group should be set to that state when the * document is opened in a viewer application. * @param view the view state */ public void setView(boolean view) { PdfDictionary usage = getUsage(); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.VIEWSTATE, view ? PdfName.ON : PdfName.OFF); usage.put(PdfName.VIEW, dic); } /** * Gets the layer visibility in Acrobat's layer panel * @return the layer visibility in Acrobat's layer panel */ public boolean isOnPanel() { return this.onPanel; } /** * Sets the visibility of the layer in Acrobat's layer panel. If false * the layer cannot be directly manipulated by the user. Note that any children layers will * also be absent from the panel. * @param onPanel the visibility of the layer in Acrobat's layer panel */ public void setOnPanel(boolean onPanel) { this.onPanel = onPanel; } } src/core/com/lowagie/text/pdf/PdfLayerMembership.java100644 0 0 12171 11000354131 20261 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.Collection; import java.util.HashSet; /** * Content typically belongs to a single optional content group, * and is visible when the group is ON and invisible when it is OFF. To express more * complex visibility policies, content should not declare itself to belong to an optional * content group directly, but rather to an optional content membership dictionary * represented by this class. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfLayerMembership extends PdfDictionary implements PdfOCG { /** * Visible only if all of the entries are ON. */ public static final PdfName ALLON = new PdfName("AllOn"); /** * Visible if any of the entries are ON. */ public static final PdfName ANYON = new PdfName("AnyOn"); /** * Visible if any of the entries are OFF. */ public static final PdfName ANYOFF = new PdfName("AnyOff"); /** * Visible only if all of the entries are OFF. */ public static final PdfName ALLOFF = new PdfName("AllOff"); PdfIndirectReference ref; PdfArray members = new PdfArray(); HashSet layers = new HashSet(); /** * Creates a new, empty, membership layer. * @param writer the writer */ public PdfLayerMembership(PdfWriter writer) { super(PdfName.OCMD); put(PdfName.OCGS, members); ref = writer.getPdfIndirectReference(); } /** * Gets the PdfIndirectReference that represents this membership layer. * @return the PdfIndirectReference that represents this layer */ public PdfIndirectReference getRef() { return ref; } /** * Adds a new member to the layer. * @param layer the new member to the layer */ public void addMember(PdfLayer layer) { if (!layers.contains(layer)) { members.add(layer.getRef()); layers.add(layer); } } /** * Gets the member layers. * @return the member layers */ public Collection getLayers() { return layers; } /** * Sets the visibility policy for content belonging to this * membership dictionary. Possible values are ALLON, ANYON, ANYOFF and ALLOFF. * The default value is ANYON. * @param type the visibility policy */ public void setVisibilityPolicy(PdfName type) { put(PdfName.P, type); } /** * Gets the dictionary representing the membership layer. It just returns this. * @return the dictionary representing the layer */ public PdfObject getPdfObject() { return this; } } src/core/com/lowagie/text/pdf/PdfLine.java100644 0 0 41327 11224570760 16105 0ustar 0 0 /* * $Id: PdfLine.java 3994 2009-06-24 13:08:04Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Chunk; import com.lowagie.text.Element; import com.lowagie.text.ListItem; /** * PdfLine defines an array with PdfChunk-objects * that fit into 1 line. */ public class PdfLine { // membervariables /** The arraylist containing the chunks. */ protected ArrayList line; /** The left indentation of the line. */ protected float left; /** The width of the line. */ protected float width; /** The alignment of the line. */ protected int alignment; /** The height of the line. */ protected float height; /** The listsymbol (if necessary). */ protected Chunk listSymbol = null; /** The listsymbol (if necessary). */ protected float symbolIndent; /** true if the chunk splitting was caused by a newline. */ protected boolean newlineSplit = false; /** The original width. */ protected float originalWidth; protected boolean isRTL = false; // constructors /** * Constructs a new PdfLine-object. * * @param left the limit of the line at the left * @param right the limit of the line at the right * @param alignment the alignment of the line * @param height the height of the line */ PdfLine(float left, float right, int alignment, float height) { this.left = left; this.width = right - left; this.originalWidth = this.width; this.alignment = alignment; this.height = height; this.line = new ArrayList(); } /** * Creates a PdfLine object. * @param left the left offset * @param originalWidth the original width of the line * @param remainingWidth bigger than 0 if the line isn't completely filled * @param alignment the alignment of the line * @param newlineSplit was the line splitted (or does the paragraph end with this line) * @param line an array of PdfChunk objects * @param isRTL do you have to read the line from Right to Left? */ PdfLine(float left, float originalWidth, float remainingWidth, int alignment, boolean newlineSplit, ArrayList line, boolean isRTL) { this.left = left; this.originalWidth = originalWidth; this.width = remainingWidth; this.alignment = alignment; this.line = line; this.newlineSplit = newlineSplit; this.isRTL = isRTL; } // methods /** * Adds a PdfChunk to the PdfLine. * * @param chunk the PdfChunk to add * @return null if the chunk could be added completely; if not * a PdfChunk containing the part of the chunk that could * not be added is returned */ PdfChunk add(PdfChunk chunk) { // nothing happens if the chunk is null. if (chunk == null || chunk.toString().equals("")) { return null; } // we split the chunk to be added PdfChunk overflow = chunk.split(width); newlineSplit = (chunk.isNewlineSplit() || overflow == null); // if (chunk.isNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED) // alignment = Element.ALIGN_LEFT; if (chunk.isTab()) { Object[] tab = (Object[])chunk.getAttribute(Chunk.TAB); float tabPosition = ((Float)tab[1]).floatValue(); boolean newline = ((Boolean)tab[2]).booleanValue(); if (newline && tabPosition < originalWidth - width) { return chunk; } width = originalWidth - tabPosition; chunk.adjustLeft(left); addToLine(chunk); } // if the length of the chunk > 0 we add it to the line else if (chunk.length() > 0 || chunk.isImage()) { if (overflow != null) chunk.trimLastSpace(); width -= chunk.width(); addToLine(chunk); } // if the length == 0 and there were no other chunks added to the line yet, // we risk to end up in an endless loop trying endlessly to add the same chunk else if (line.size() < 1) { chunk = overflow; overflow = chunk.truncate(width); width -= chunk.width(); if (chunk.length() > 0) { addToLine(chunk); return overflow; } // if the chunk couldn't even be truncated, we add everything, so be it else { if (overflow != null) addToLine(overflow); return null; } } else { width += ((PdfChunk)(line.get(line.size() - 1))).trimLastSpace(); } return overflow; } private void addToLine(PdfChunk chunk) { if (chunk.changeLeading && chunk.isImage()) { float f = chunk.getImage().getScaledHeight() + chunk.getImageOffsetY() + chunk.getImage().getBorderWidthTop(); if (f > height) height = f; } line.add(chunk); } // methods to retrieve information /** * Returns the number of chunks in the line. * * @return a value */ public int size() { return line.size(); } /** * Returns an iterator of PdfChunks. * * @return an Iterator */ public Iterator iterator() { return line.iterator(); } /** * Returns the height of the line. * * @return a value */ float height() { return height; } /** * Returns the left indentation of the line taking the alignment of the line into account. * * @return a value */ float indentLeft() { if (isRTL) { switch (alignment) { case Element.ALIGN_LEFT: return left + width; case Element.ALIGN_CENTER: return left + (width / 2f); default: return left; } } else if (this.getSeparatorCount() == 0) { switch (alignment) { case Element.ALIGN_RIGHT: return left + width; case Element.ALIGN_CENTER: return left + (width / 2f); } } return left; } /** * Checks if this line has to be justified. * * @return true if the alignment equals ALIGN_JUSTIFIED and there is some width left. */ public boolean hasToBeJustified() { return ((alignment == Element.ALIGN_JUSTIFIED || alignment == Element.ALIGN_JUSTIFIED_ALL) && width != 0); } /** * Resets the alignment of this line. *

* The alignment of the last line of for instance a Paragraph * that has to be justified, has to be reset to ALIGN_LEFT. */ public void resetAlignment() { if (alignment == Element.ALIGN_JUSTIFIED) { alignment = Element.ALIGN_LEFT; } } /** Adds extra indentation to the left (for Paragraph.setFirstLineIndent). */ void setExtraIndent(float extra) { left += extra; width -= extra; } /** * Returns the width that is left, after a maximum of characters is added to the line. * * @return a value */ float widthLeft() { return width; } /** * Returns the number of space-characters in this line. * * @return a value */ int numberOfSpaces() { String string = toString(); int length = string.length(); int numberOfSpaces = 0; for (int i = 0; i < length; i++) { if (string.charAt(i) == ' ') { numberOfSpaces++; } } return numberOfSpaces; } /** * Sets the listsymbol of this line. *

* This is only necessary for the first line of a ListItem. * * @param listItem the list symbol */ public void setListItem(ListItem listItem) { this.listSymbol = listItem.getListSymbol(); this.symbolIndent = listItem.getIndentationLeft(); } /** * Returns the listsymbol of this line. * * @return a PdfChunk if the line has a listsymbol; null otherwise */ public Chunk listSymbol() { return listSymbol; } /** * Return the indentation needed to show the listsymbol. * * @return a value */ public float listIndent() { return symbolIndent; } /** * Get the string representation of what is in this line. * * @return a String */ public String toString() { StringBuffer tmp = new StringBuffer(); for (Iterator i = line.iterator(); i.hasNext(); ) { tmp.append(((PdfChunk) i.next()).toString()); } return tmp.toString(); } /** * Returns the length of a line in UTF32 characters * @return the length in UTF32 characters * @since 2.1.2 */ public int GetLineLengthUtf32() { int total = 0; for (Iterator i = line.iterator(); i.hasNext();) { total += ((PdfChunk)i.next()).lengthUtf32(); } return total; } /** * Checks if a newline caused the line split. * @return true if a newline caused the line split */ public boolean isNewlineSplit() { return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL); } /** * Gets the index of the last PdfChunk with metric attributes * @return the last PdfChunk with metric attributes */ public int getLastStrokeChunk() { int lastIdx = line.size() - 1; for (; lastIdx >= 0; --lastIdx) { PdfChunk chunk = (PdfChunk)line.get(lastIdx); if (chunk.isStroked()) break; } return lastIdx; } /** * Gets a PdfChunk by index. * @param idx the index * @return the PdfChunk or null if beyond the array */ public PdfChunk getChunk(int idx) { if (idx < 0 || idx >= line.size()) return null; return (PdfChunk)line.get(idx); } /** * Gets the original width of the line. * @return the original width of the line */ public float getOriginalWidth() { return originalWidth; } /* * Gets the maximum size of all the fonts used in this line * including images. * @return maximum size of all the fonts used in this line float getMaxSizeSimple() { float maxSize = 0; PdfChunk chunk; for (int k = 0; k < line.size(); ++k) { chunk = (PdfChunk)line.get(k); if (!chunk.isImage()) { maxSize = Math.max(chunk.font().size(), maxSize); } else { maxSize = Math.max(chunk.getImage().getScaledHeight() + chunk.getImageOffsetY() , maxSize); } } return maxSize; }*/ /** * Gets the difference between the "normal" leading and the maximum * size (for instance when there are images in the chunk). * @return an extra leading for images * @since 2.1.5 */ float[] getMaxSize() { float normal_leading = 0; float image_leading = -10000; PdfChunk chunk; for (int k = 0; k < line.size(); ++k) { chunk = (PdfChunk)line.get(k); if (!chunk.isImage()) { normal_leading = Math.max(chunk.font().size(), normal_leading); } else { image_leading = Math.max(chunk.getImage().getScaledHeight() + chunk.getImageOffsetY(), image_leading); } } return new float[]{normal_leading, image_leading}; } boolean isRTL() { return isRTL; } /** * Gets the number of separators in the line. * @return the number of separators in the line * @since 2.1.2 */ int getSeparatorCount() { int s = 0; PdfChunk ck; for (Iterator i = line.iterator(); i.hasNext(); ) { ck = (PdfChunk)i.next(); if (ck.isTab()) { return 0; } if (ck.isHorizontalSeparator()) { s++; } } return s; } /** * Gets a width corrected with a charSpacing and wordSpacing. * @param charSpacing * @param wordSpacing * @return a corrected width */ public float getWidthCorrected(float charSpacing, float wordSpacing) { float total = 0; for (int k = 0; k < line.size(); ++k) { PdfChunk ck = (PdfChunk)line.get(k); total += ck.getWidthCorrected(charSpacing, wordSpacing); } return total; } /** * Gets the maximum size of the ascender for all the fonts used * in this line. * @return maximum size of all the ascenders used in this line */ public float getAscender() { float ascender = 0; for (int k = 0; k < line.size(); ++k) { PdfChunk ck = (PdfChunk)line.get(k); if (ck.isImage()) ascender = Math.max(ascender, ck.getImage().getScaledHeight() + ck.getImageOffsetY()); else { PdfFont font = ck.font(); ascender = Math.max(ascender, font.getFont().getFontDescriptor(BaseFont.ASCENT, font.size())); } } return ascender; } /** * Gets the biggest descender for all the fonts used * in this line. Note that this is a negative number. * @return maximum size of all the ascenders used in this line */ public float getDescender() { float descender = 0; for (int k = 0; k < line.size(); ++k) { PdfChunk ck = (PdfChunk)line.get(k); if (ck.isImage()) descender = Math.min(descender, ck.getImageOffsetY()); else { PdfFont font = ck.font(); descender = Math.min(descender, font.getFont().getFontDescriptor(BaseFont.DESCENT, font.size())); } } return descender; } }src/core/com/lowagie/text/pdf/PdfLister.java100644 0 0 15055 11154165267 16463 0ustar 0 0 /* * $Id: PdfLister.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 2002 Mark Thompson * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * This class by Mark Thompson. Copyright (C) 2002 Mark Thompson * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.PrintStream; import java.util.Iterator; /** * List a PDF file in human-readable form (for debugging reasons mostly) * @author Mark Thompson */ public class PdfLister { /** the printStream you want to write the output to. */ PrintStream out; /** * Create a new lister object. * @param out */ public PdfLister(PrintStream out) { this.out = out; } /** * Visualizes a PDF object. * @param object a com.lowagie.text.pdf object */ public void listAnyObject(PdfObject object) { switch (object.type()) { case PdfObject.ARRAY: listArray((PdfArray)object); break; case PdfObject.DICTIONARY: listDict((PdfDictionary) object); break; case PdfObject.STRING: out.println("(" + object.toString() + ")"); break; default: out.println(object.toString()); break; } } /** * Visualizes a PdfDictionary object. * @param dictionary a com.lowagie.text.pdf.PdfDictionary object */ public void listDict(PdfDictionary dictionary) { out.println("<<"); PdfName key; PdfObject value; for (Iterator i = dictionary.getKeys().iterator(); i.hasNext(); ) { key = (PdfName) i.next(); value = dictionary.get(key); out.print(key.toString()); out.print(' '); listAnyObject(value); } out.println(">>"); } /** * Visualizes a PdfArray object. * @param array a com.lowagie.text.pdf.PdfArray object */ public void listArray(PdfArray array) { out.println('['); for (Iterator i = array.listIterator(); i.hasNext(); ) { PdfObject item = (PdfObject)i.next(); listAnyObject(item); } out.println(']'); } /** * Visualizes a Stream. * @param stream * @param reader */ public void listStream(PRStream stream, PdfReaderInstance reader) { try { listDict(stream); out.println("startstream"); byte[] b = PdfReader.getStreamBytes(stream); // byte buf[] = new byte[Math.min(stream.getLength(), 4096)]; // int r = 0; // stream.openStream(reader); // for (;;) { // r = stream.readStream(buf, 0, buf.length); // if (r == 0) break; // out.write(buf, 0, r); // } // stream.closeStream(); int len = b.length - 1; for (int k = 0; k < len; ++k) { if (b[k] == '\r' && b[k + 1] != '\n') b[k] = (byte)'\n'; } out.println(new String(b)); out.println("endstream"); } catch (IOException e) { System.err.println("I/O exception: " + e); // } catch (java.util.zip.DataFormatException e) { // System.err.println("Data Format Exception: " + e); } } /** * Visualizes an imported page * @param iPage */ public void listPage(PdfImportedPage iPage) { int pageNum = iPage.getPageNumber(); PdfReaderInstance readerInst = iPage.getPdfReaderInstance(); PdfReader reader = readerInst.getReader(); PdfDictionary page = reader.getPageN(pageNum); listDict(page); PdfObject obj = PdfReader.getPdfObject(page.get(PdfName.CONTENTS)); if (obj == null) return; switch (obj.type) { case PdfObject.STREAM: listStream((PRStream)obj, readerInst); break; case PdfObject.ARRAY: for (Iterator i = ((PdfArray)obj).listIterator(); i.hasNext();) { PdfObject o = PdfReader.getPdfObject((PdfObject)i.next()); listStream((PRStream)o, readerInst); out.println("-----------"); } break; } } } src/core/com/lowagie/text/pdf/PdfLiteral.java100644 0 0 7330 11012562273 16561 0ustar 0 0 /* * $Id: PdfLiteral.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * a Literal */ public class PdfLiteral extends PdfObject { /** * Holds value of property position. */ private int position; public PdfLiteral(String text) { super(0, text); } public PdfLiteral(byte b[]) { super(0, b); } public PdfLiteral(int size) { super(0, (byte[])null); bytes = new byte[size]; java.util.Arrays.fill(bytes, (byte)32); } public PdfLiteral(int type, String text) { super(type, text); } public PdfLiteral(int type, byte b[]) { super(type, b); } public void toPdf(PdfWriter writer, java.io.OutputStream os) throws java.io.IOException { if (os instanceof OutputStreamCounter) position = ((OutputStreamCounter)os).getCounter(); super.toPdf(writer, os); } /** * Getter for property position. * @return Value of property position. */ public int getPosition() { return this.position; } /** * Getter for property posLength. * @return Value of property posLength. */ public int getPosLength() { if (bytes != null) return bytes.length; else return 0; } }src/core/com/lowagie/text/pdf/PdfMediaClipData.java100644 0 0 5775 11000354131 17606 0ustar 0 0 /* * Copyright 2003 Galo Gimenez * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; public class PdfMediaClipData extends PdfDictionary { PdfMediaClipData(String file, PdfFileSpecification fs, String mimeType) throws IOException { put(PdfName.TYPE,new PdfName("MediaClip")); put(PdfName.S, new PdfName("MCD")); put(PdfName.N, new PdfString("Media clip for "+file)); put(new PdfName("CT"), new PdfString(mimeType)); PdfDictionary dic = new PdfDictionary(); dic.put(new PdfName("TF"), new PdfString("TEMPACCESS")); put(new PdfName("P"), dic); put(PdfName.D, fs.getReference()); } } src/core/com/lowagie/text/pdf/PdfName.java100644 0 0 205140 11213370070 16077 0ustar 0 0 /* * $Id: PdfName.java 3934 2009-05-27 11:23:23Z blowagie $ * * Copyright 1999-2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.*; /** * PdfName is an object that can be used as a name in a PDF-file. *

* A name, like a string, is a sequence of characters. * It must begin with a slash followed by a sequence of ASCII characters in * the range 32 through 136 except %, (, ), [, ], <, >, {, }, / and #. * Any character except 0x00 may be included in a name by writing its * two character hex code, preceded by #. The maximum number of characters * in a name is 127.
* This object is described in the 'Portable Document Format Reference Manual * version 1.7' section 3.2.4 (page 56-58). *

* * @see PdfObject * @see PdfDictionary * @see BadPdfFormatException */ public class PdfName extends PdfObject implements Comparable{ // CLASS CONSTANTS (a variety of standard names used in PDF)) /** * A name. * @since 2.1.6 */ public static final PdfName _3D = new PdfName("3D"); /** A name */ public static final PdfName A = new PdfName("A"); /** A name */ public static final PdfName AA = new PdfName("AA"); /** * A name * @since 2.1.5 renamed from ABSOLUTECALORIMETRIC */ public static final PdfName ABSOLUTECOLORIMETRIC = new PdfName("AbsoluteColorimetric"); /** A name */ public static final PdfName AC = new PdfName("AC"); /** A name */ public static final PdfName ACROFORM = new PdfName("AcroForm"); /** A name */ public static final PdfName ACTION = new PdfName("Action"); /** * A name. * @since 2.1.6 */ public static final PdfName ACTIVATION = new PdfName("Activation"); /** * A name. * @since 2.1.6 */ public static final PdfName ADBE = new PdfName("ADBE"); /** * a name used in PDF structure * @since 2.1.6 */ public static final PdfName ACTUALTEXT = new PdfName("ActualText"); /** A name */ public static final PdfName ADBE_PKCS7_DETACHED = new PdfName("adbe.pkcs7.detached"); /** A name */ public static final PdfName ADBE_PKCS7_S4 =new PdfName("adbe.pkcs7.s4"); /** A name */ public static final PdfName ADBE_PKCS7_S5 =new PdfName("adbe.pkcs7.s5"); /** A name */ public static final PdfName ADBE_PKCS7_SHA1 = new PdfName("adbe.pkcs7.sha1"); /** A name */ public static final PdfName ADBE_X509_RSA_SHA1 = new PdfName("adbe.x509.rsa_sha1"); /** A name */ public static final PdfName ADOBE_PPKLITE = new PdfName("Adobe.PPKLite"); /** A name */ public static final PdfName ADOBE_PPKMS = new PdfName("Adobe.PPKMS"); /** A name */ public static final PdfName AESV2 = new PdfName("AESV2"); /** A name */ public static final PdfName AIS = new PdfName("AIS"); /** A name */ public static final PdfName ALLPAGES = new PdfName("AllPages"); /** A name */ public static final PdfName ALT = new PdfName("Alt"); /** A name */ public static final PdfName ALTERNATE = new PdfName("Alternate"); /** * A name. * @since 2.1.6 */ public static final PdfName ANIMATION = new PdfName("Animation"); /** A name */ public static final PdfName ANNOT = new PdfName("Annot"); /** A name */ public static final PdfName ANNOTS = new PdfName("Annots"); /** A name */ public static final PdfName ANTIALIAS = new PdfName("AntiAlias"); /** A name */ public static final PdfName AP = new PdfName("AP"); /** A name */ public static final PdfName APPDEFAULT = new PdfName("AppDefault"); /** * A name * @since 2.1.6 */ public static final PdfName ART = new PdfName("Art"); /** A name */ public static final PdfName ARTBOX = new PdfName("ArtBox"); /** A name */ public static final PdfName ASCENT = new PdfName("Ascent"); /** A name */ public static final PdfName AS = new PdfName("AS"); /** A name */ public static final PdfName ASCII85DECODE = new PdfName("ASCII85Decode"); /** A name */ public static final PdfName ASCIIHEXDECODE = new PdfName("ASCIIHexDecode"); /** * A name. * @since 2.1.6 */ public static final PdfName ASSET = new PdfName("Asset"); /** * A name. * @since 2.1.6 */ public static final PdfName ASSETS = new PdfName("Assets"); /** A name */ public static final PdfName AUTHEVENT = new PdfName("AuthEvent"); /** A name */ public static final PdfName AUTHOR = new PdfName("Author"); /** A name */ public static final PdfName B = new PdfName("B"); /** * A name * @since 2.1.6 */ public static final PdfName BACKGROUND = new PdfName("Background"); /** A name */ public static final PdfName BASEENCODING = new PdfName("BaseEncoding"); /** A name */ public static final PdfName BASEFONT = new PdfName("BaseFont"); /** * A name * @since 2.1.6 */ public static final PdfName BASEVERSION = new PdfName("BaseVersion"); /** A name */ public static final PdfName BBOX = new PdfName("BBox"); /** A name */ public static final PdfName BC = new PdfName("BC"); /** A name */ public static final PdfName BG = new PdfName("BG"); /** * A name * @since 2.1.6 */ public static final PdfName BIBENTRY = new PdfName("BibEntry"); /** A name */ public static final PdfName BIGFIVE = new PdfName("BigFive"); /** * A name. * @since 2.1.6 */ public static final PdfName BINDING = new PdfName("Binding"); /** * A name. * @since 2.1.6 */ public static final PdfName BINDINGMATERIALNAME = new PdfName("BindingMaterialName"); /** A name */ public static final PdfName BITSPERCOMPONENT = new PdfName("BitsPerComponent"); /** A name */ public static final PdfName BITSPERSAMPLE = new PdfName("BitsPerSample"); /** A name */ public static final PdfName BL = new PdfName("Bl"); /** A name */ public static final PdfName BLACKIS1 = new PdfName("BlackIs1"); /** A name */ public static final PdfName BLACKPOINT = new PdfName("BlackPoint"); /** * A name * @since 2.1.6 */ public static final PdfName BLOCKQUOTE = new PdfName("BlockQuote"); /** A name */ public static final PdfName BLEEDBOX = new PdfName("BleedBox"); /** A name */ public static final PdfName BLINDS = new PdfName("Blinds"); /** A name */ public static final PdfName BM = new PdfName("BM"); /** A name */ public static final PdfName BORDER = new PdfName("Border"); /** A name */ public static final PdfName BOUNDS = new PdfName("Bounds"); /** A name */ public static final PdfName BOX = new PdfName("Box"); /** A name */ public static final PdfName BS = new PdfName("BS"); /** A name */ public static final PdfName BTN = new PdfName("Btn"); /** A name */ public static final PdfName BYTERANGE = new PdfName("ByteRange"); /** A name */ public static final PdfName C = new PdfName("C"); /** A name */ public static final PdfName C0 = new PdfName("C0"); /** A name */ public static final PdfName C1 = new PdfName("C1"); /** A name */ public static final PdfName CA = new PdfName("CA"); /** A name */ public static final PdfName ca = new PdfName("ca"); /** A name */ public static final PdfName CALGRAY = new PdfName("CalGray"); /** A name */ public static final PdfName CALRGB = new PdfName("CalRGB"); /** A name */ public static final PdfName CAPHEIGHT = new PdfName("CapHeight"); /** * A name * @since 2.1.6 */ public static final PdfName CAPTION = new PdfName("Caption"); /** A name */ public static final PdfName CATALOG = new PdfName("Catalog"); /** A name */ public static final PdfName CATEGORY = new PdfName("Category"); /** A name */ public static final PdfName CCITTFAXDECODE = new PdfName("CCITTFaxDecode"); /** * A name. * @since 2.1.6 */ public static final PdfName CENTER = new PdfName("Center"); /** A name */ public static final PdfName CENTERWINDOW = new PdfName("CenterWindow"); /** A name */ public static final PdfName CERT = new PdfName("Cert"); /** A name */ public static final PdfName CF = new PdfName("CF"); /** A name */ public static final PdfName CFM = new PdfName("CFM"); /** A name */ public static final PdfName CH = new PdfName("Ch"); /** A name */ public static final PdfName CHARPROCS = new PdfName("CharProcs"); /** A name */ public static final PdfName CI = new PdfName("CI"); /** A name */ public static final PdfName CIDFONTTYPE0 = new PdfName("CIDFontType0"); /** A name */ public static final PdfName CIDFONTTYPE2 = new PdfName("CIDFontType2"); /** * A name * @since 2.0.7 */ public static final PdfName CIDSET = new PdfName("CIDSet"); /** A name */ public static final PdfName CIDSYSTEMINFO = new PdfName("CIDSystemInfo"); /** A name */ public static final PdfName CIDTOGIDMAP = new PdfName("CIDToGIDMap"); /** A name */ public static final PdfName CIRCLE = new PdfName("Circle"); /** * A name. * @since 2.1.6 */ public static final PdfName CMD = new PdfName("CMD"); /** A name */ public static final PdfName CO = new PdfName("CO"); /** * A name * @since 2.1.6 */ public static final PdfName CODE = new PdfName("Code"); /** A name */ public static final PdfName COLORS = new PdfName("Colors"); /** A name */ public static final PdfName COLORSPACE = new PdfName("ColorSpace"); /** A name */ public static final PdfName COLLECTION = new PdfName("Collection"); /** A name */ public static final PdfName COLLECTIONFIELD = new PdfName("CollectionField"); /** A name */ public static final PdfName COLLECTIONITEM = new PdfName("CollectionItem"); /** A name */ public static final PdfName COLLECTIONSCHEMA = new PdfName("CollectionSchema"); /** A name */ public static final PdfName COLLECTIONSORT = new PdfName("CollectionSort"); /** A name */ public static final PdfName COLLECTIONSUBITEM = new PdfName("CollectionSubitem"); /** A name */ public static final PdfName COLUMNS = new PdfName("Columns"); /** * A name. * @since 2.1.6 */ public static final PdfName CONDITION = new PdfName("Condition"); /** * A name. * @since 2.1.6 */ public static final PdfName CONFIGURATION = new PdfName("Configuration"); /** * A name. * @since 2.1.6 */ public static final PdfName CONFIGURATIONS = new PdfName("Configurations"); /** A name */ public static final PdfName CONTACTINFO = new PdfName("ContactInfo"); /** A name */ public static final PdfName CONTENT = new PdfName("Content"); /** A name */ public static final PdfName CONTENTS = new PdfName("Contents"); /** A name */ public static final PdfName COORDS = new PdfName("Coords"); /** A name */ public static final PdfName COUNT = new PdfName("Count"); /** A name of a base 14 type 1 font */ public static final PdfName COURIER = new PdfName("Courier"); /** A name of a base 14 type 1 font */ public static final PdfName COURIER_BOLD = new PdfName("Courier-Bold"); /** A name of a base 14 type 1 font */ public static final PdfName COURIER_OBLIQUE = new PdfName("Courier-Oblique"); /** A name of a base 14 type 1 font */ public static final PdfName COURIER_BOLDOBLIQUE = new PdfName("Courier-BoldOblique"); /** A name */ public static final PdfName CREATIONDATE = new PdfName("CreationDate"); /** A name */ public static final PdfName CREATOR = new PdfName("Creator"); /** A name */ public static final PdfName CREATORINFO = new PdfName("CreatorInfo"); /** A name */ public static final PdfName CROPBOX = new PdfName("CropBox"); /** A name */ public static final PdfName CRYPT = new PdfName("Crypt"); /** A name */ public static final PdfName CS = new PdfName("CS"); /** * A name. * @since 2.1.6 */ public static final PdfName CUEPOINT = new PdfName("CuePoint"); /** * A name. * @since 2.1.6 */ public static final PdfName CUEPOINTS = new PdfName("CuePoints"); /** A name */ public static final PdfName D = new PdfName("D"); /** A name */ public static final PdfName DA = new PdfName("DA"); /** A name */ public static final PdfName DATA = new PdfName("Data"); /** A name */ public static final PdfName DC = new PdfName("DC"); /** A name */ public static final PdfName DCTDECODE = new PdfName("DCTDecode"); /** * A name. * @since 2.1.6 */ public static final PdfName DEACTIVATION = new PdfName("Deactivation"); /** A name */ public static final PdfName DECODE = new PdfName("Decode"); /** A name */ public static final PdfName DECODEPARMS = new PdfName("DecodeParms"); /** * A name * @since 2.1.6 */ public static final PdfName DEFAULT = new PdfName("Default"); /** * A name * @since 2.1.5 renamed from DEFAULTCRYPTFILER */ public static final PdfName DEFAULTCRYPTFILTER = new PdfName("DefaultCryptFilter"); /** A name */ public static final PdfName DEFAULTCMYK = new PdfName("DefaultCMYK"); /** A name */ public static final PdfName DEFAULTGRAY = new PdfName("DefaultGray"); /** A name */ public static final PdfName DEFAULTRGB = new PdfName("DefaultRGB"); /** A name */ public static final PdfName DESC = new PdfName("Desc"); /** A name */ public static final PdfName DESCENDANTFONTS = new PdfName("DescendantFonts"); /** A name */ public static final PdfName DESCENT = new PdfName("Descent"); /** A name */ public static final PdfName DEST = new PdfName("Dest"); /** A name */ public static final PdfName DESTOUTPUTPROFILE = new PdfName("DestOutputProfile"); /** A name */ public static final PdfName DESTS = new PdfName("Dests"); /** A name */ public static final PdfName DEVICEGRAY = new PdfName("DeviceGray"); /** A name */ public static final PdfName DEVICERGB = new PdfName("DeviceRGB"); /** A name */ public static final PdfName DEVICECMYK = new PdfName("DeviceCMYK"); /** A name */ public static final PdfName DI = new PdfName("Di"); /** A name */ public static final PdfName DIFFERENCES = new PdfName("Differences"); /** A name */ public static final PdfName DISSOLVE = new PdfName("Dissolve"); /** A name */ public static final PdfName DIRECTION = new PdfName("Direction"); /** A name */ public static final PdfName DISPLAYDOCTITLE = new PdfName("DisplayDocTitle"); /** A name */ public static final PdfName DIV = new PdfName("Div"); /** A name */ public static final PdfName DM = new PdfName("Dm"); /** A name */ public static final PdfName DOCMDP = new PdfName("DocMDP"); /** A name */ public static final PdfName DOCOPEN = new PdfName("DocOpen"); /** * A name. * @since 2.1.6 */ public static final PdfName DOCUMENT = new PdfName( "Document" ); /** A name */ public static final PdfName DOMAIN = new PdfName("Domain"); /** A name */ public static final PdfName DP = new PdfName("DP"); /** A name */ public static final PdfName DR = new PdfName("DR"); /** A name */ public static final PdfName DS = new PdfName("DS"); /** A name */ public static final PdfName DUR = new PdfName("Dur"); /** A name */ public static final PdfName DUPLEX = new PdfName("Duplex"); /** A name */ public static final PdfName DUPLEXFLIPSHORTEDGE = new PdfName("DuplexFlipShortEdge"); /** A name */ public static final PdfName DUPLEXFLIPLONGEDGE = new PdfName("DuplexFlipLongEdge"); /** A name */ public static final PdfName DV = new PdfName("DV"); /** A name */ public static final PdfName DW = new PdfName("DW"); /** A name */ public static final PdfName E = new PdfName("E"); /** A name */ public static final PdfName EARLYCHANGE = new PdfName("EarlyChange"); /** A name */ public static final PdfName EF = new PdfName("EF"); /** * A name * @since 2.1.3 */ public static final PdfName EFF = new PdfName("EFF"); /** * A name * @since 2.1.3 */ public static final PdfName EFOPEN = new PdfName("EFOpen"); /** * A name * @since 2.1.6 */ public static final PdfName EMBEDDED = new PdfName("Embedded"); /** A name */ public static final PdfName EMBEDDEDFILE = new PdfName("EmbeddedFile"); /** A name */ public static final PdfName EMBEDDEDFILES = new PdfName("EmbeddedFiles"); /** A name */ public static final PdfName ENCODE = new PdfName("Encode"); /** A name */ public static final PdfName ENCODEDBYTEALIGN = new PdfName("EncodedByteAlign"); /** A name */ public static final PdfName ENCODING = new PdfName("Encoding"); /** A name */ public static final PdfName ENCRYPT = new PdfName("Encrypt"); /** A name */ public static final PdfName ENCRYPTMETADATA = new PdfName("EncryptMetadata"); /** A name */ public static final PdfName ENDOFBLOCK = new PdfName("EndOfBlock"); /** A name */ public static final PdfName ENDOFLINE = new PdfName("EndOfLine"); /** A name */ public static final PdfName EXTEND = new PdfName("Extend"); /** * A name * @since 2.1.6 */ public static final PdfName EXTENSIONS = new PdfName("Extensions"); /** * A name * @since 2.1.6 */ public static final PdfName EXTENSIONLEVEL = new PdfName("ExtensionLevel"); /** A name */ public static final PdfName EXTGSTATE = new PdfName("ExtGState"); /** A name */ public static final PdfName EXPORT = new PdfName("Export"); /** A name */ public static final PdfName EXPORTSTATE = new PdfName("ExportState"); /** A name */ public static final PdfName EVENT = new PdfName("Event"); /** A name */ public static final PdfName F = new PdfName("F"); /** * A name. * @since 2.1.6 */ public static final PdfName FAR = new PdfName("Far"); /** A name */ public static final PdfName FB = new PdfName("FB"); /** A name */ public static final PdfName FDECODEPARMS = new PdfName("FDecodeParms"); /** A name */ public static final PdfName FDF = new PdfName("FDF"); /** A name */ public static final PdfName FF = new PdfName("Ff"); /** A name */ public static final PdfName FFILTER = new PdfName("FFilter"); /** A name */ public static final PdfName FIELDS = new PdfName("Fields"); /** * A name * @since 2.1.6 */ public static final PdfName FIGURE = new PdfName( "Figure" ); /** A name */ public static final PdfName FILEATTACHMENT = new PdfName("FileAttachment"); /** A name */ public static final PdfName FILESPEC = new PdfName("Filespec"); /** A name */ public static final PdfName FILTER = new PdfName("Filter"); /** A name */ public static final PdfName FIRST = new PdfName("First"); /** A name */ public static final PdfName FIRSTCHAR = new PdfName("FirstChar"); /** A name */ public static final PdfName FIRSTPAGE = new PdfName("FirstPage"); /** A name */ public static final PdfName FIT = new PdfName("Fit"); /** A name */ public static final PdfName FITH = new PdfName("FitH"); /** A name */ public static final PdfName FITV = new PdfName("FitV"); /** A name */ public static final PdfName FITR = new PdfName("FitR"); /** A name */ public static final PdfName FITB = new PdfName("FitB"); /** A name */ public static final PdfName FITBH = new PdfName("FitBH"); /** A name */ public static final PdfName FITBV = new PdfName("FitBV"); /** A name */ public static final PdfName FITWINDOW = new PdfName("FitWindow"); /** A name */ public static final PdfName FLAGS = new PdfName("Flags"); /** * A name. * @since 2.1.6 */ public static final PdfName FLASH = new PdfName("Flash"); /** * A name. * @since 2.1.6 */ public static final PdfName FLASHVARS = new PdfName("FlashVars"); /** A name */ public static final PdfName FLATEDECODE = new PdfName("FlateDecode"); /** A name */ public static final PdfName FO = new PdfName("Fo"); /** A name */ public static final PdfName FONT = new PdfName("Font"); /** A name */ public static final PdfName FONTBBOX = new PdfName("FontBBox"); /** A name */ public static final PdfName FONTDESCRIPTOR = new PdfName("FontDescriptor"); /** A name */ public static final PdfName FONTFILE = new PdfName("FontFile"); /** A name */ public static final PdfName FONTFILE2 = new PdfName("FontFile2"); /** A name */ public static final PdfName FONTFILE3 = new PdfName("FontFile3"); /** A name */ public static final PdfName FONTMATRIX = new PdfName("FontMatrix"); /** A name */ public static final PdfName FONTNAME = new PdfName("FontName"); /** * A name * @since 2.1.6 */ public static final PdfName FOREGROUND = new PdfName("Foreground"); /** A name */ public static final PdfName FORM = new PdfName("Form"); /** A name */ public static final PdfName FORMTYPE = new PdfName("FormType"); /** * A name * @since 2.1.6 */ public static final PdfName FORMULA = new PdfName( "Formula" ); /** A name */ public static final PdfName FREETEXT = new PdfName("FreeText"); /** A name */ public static final PdfName FRM = new PdfName("FRM"); /** A name */ public static final PdfName FS = new PdfName("FS"); /** A name */ public static final PdfName FT = new PdfName("FT"); /** A name */ public static final PdfName FULLSCREEN = new PdfName("FullScreen"); /** A name */ public static final PdfName FUNCTION = new PdfName("Function"); /** A name */ public static final PdfName FUNCTIONS = new PdfName("Functions"); /** A name */ public static final PdfName FUNCTIONTYPE = new PdfName("FunctionType"); /** A name of an attribute. */ public static final PdfName GAMMA = new PdfName("Gamma"); /** A name of an attribute. */ public static final PdfName GBK = new PdfName("GBK"); /** A name of an attribute. */ public static final PdfName GLITTER = new PdfName("Glitter"); /** A name of an attribute. */ public static final PdfName GOTO = new PdfName("GoTo"); /** A name of an attribute. */ public static final PdfName GOTOE = new PdfName("GoToE"); /** A name of an attribute. */ public static final PdfName GOTOR = new PdfName("GoToR"); /** A name of an attribute. */ public static final PdfName GROUP = new PdfName("Group"); /** A name of an attribute. */ public static final PdfName GTS_PDFA1 = new PdfName("GTS_PDFA1"); /** A name of an attribute. */ public static final PdfName GTS_PDFX = new PdfName("GTS_PDFX"); /** A name of an attribute. */ public static final PdfName GTS_PDFXVERSION = new PdfName("GTS_PDFXVersion"); /** A name of an attribute. */ public static final PdfName H = new PdfName("H"); /** * A name * @since 2.1.6 */ public static final PdfName H1 = new PdfName( "H1" ); /** * A name * @since 2.1.6 */ public static final PdfName H2 = new PdfName("H2"); /** * A name * @since 2.1.6 */ public static final PdfName H3 = new PdfName("H3"); /** * A name * @since 2.1.6 */ public static final PdfName H4 = new PdfName("H4"); /** * A name * @since 2.1.6 */ public static final PdfName H5 = new PdfName("H5"); /** * A name * @since 2.1.6 */ public static final PdfName H6 = new PdfName("H6"); /** * A name. * @since 2.1.6 */ public static final PdfName HALIGN = new PdfName("HAlign"); /** A name of an attribute. */ public static final PdfName HEIGHT = new PdfName("Height"); /** A name */ public static final PdfName HELV = new PdfName("Helv"); /** A name of a base 14 type 1 font */ public static final PdfName HELVETICA = new PdfName("Helvetica"); /** A name of a base 14 type 1 font */ public static final PdfName HELVETICA_BOLD = new PdfName("Helvetica-Bold"); /** A name of a base 14 type 1 font */ public static final PdfName HELVETICA_OBLIQUE = new PdfName("Helvetica-Oblique"); /** A name of a base 14 type 1 font */ public static final PdfName HELVETICA_BOLDOBLIQUE = new PdfName("Helvetica-BoldOblique"); /** A name */ public static final PdfName HID = new PdfName("Hid"); /** A name */ public static final PdfName HIDE = new PdfName("Hide"); /** A name */ public static final PdfName HIDEMENUBAR = new PdfName("HideMenubar"); /** A name */ public static final PdfName HIDETOOLBAR = new PdfName("HideToolbar"); /** A name */ public static final PdfName HIDEWINDOWUI = new PdfName("HideWindowUI"); /** A name */ public static final PdfName HIGHLIGHT = new PdfName("Highlight"); /** * A name. * @since 2.1.6 */ public static final PdfName HOFFSET = new PdfName("HOffset"); /** A name */ public static final PdfName I = new PdfName("I"); /** A name */ public static final PdfName ICCBASED = new PdfName("ICCBased"); /** A name */ public static final PdfName ID = new PdfName("ID"); /** A name */ public static final PdfName IDENTITY = new PdfName("Identity"); /** A name */ public static final PdfName IF = new PdfName("IF"); /** A name */ public static final PdfName IMAGE = new PdfName("Image"); /** A name */ public static final PdfName IMAGEB = new PdfName("ImageB"); /** A name */ public static final PdfName IMAGEC = new PdfName("ImageC"); /** A name */ public static final PdfName IMAGEI = new PdfName("ImageI"); /** A name */ public static final PdfName IMAGEMASK = new PdfName("ImageMask"); /** A name */ public static final PdfName INDEX = new PdfName("Index"); /** A name */ public static final PdfName INDEXED = new PdfName("Indexed"); /** A name */ public static final PdfName INFO = new PdfName("Info"); /** A name */ public static final PdfName INK = new PdfName("Ink"); /** A name */ public static final PdfName INKLIST = new PdfName("InkList"); /** * A name. * @since 2.1.6 */ public static final PdfName INSTANCES = new PdfName("Instances"); /** A name */ public static final PdfName IMPORTDATA = new PdfName("ImportData"); /** A name */ public static final PdfName INTENT = new PdfName("Intent"); /** A name */ public static final PdfName INTERPOLATE = new PdfName("Interpolate"); /** A name */ public static final PdfName ISMAP = new PdfName("IsMap"); /** A name */ public static final PdfName IRT = new PdfName("IRT"); /** A name */ public static final PdfName ITALICANGLE = new PdfName("ItalicAngle"); /** * A name * @since 2.1.6 */ public static final PdfName ITXT = new PdfName("ITXT"); /** A name */ public static final PdfName IX = new PdfName("IX"); /** A name */ public static final PdfName JAVASCRIPT = new PdfName("JavaScript"); /** * A name * @since 2.1.5 */ public static final PdfName JBIG2DECODE = new PdfName("JBIG2Decode"); /** * A name * @since 2.1.5 */ public static final PdfName JBIG2GLOBALS = new PdfName("JBIG2Globals"); /** A name */ public static final PdfName JPXDECODE = new PdfName("JPXDecode"); /** A name */ public static final PdfName JS = new PdfName("JS"); /** A name */ public static final PdfName K = new PdfName("K"); /** A name */ public static final PdfName KEYWORDS = new PdfName("Keywords"); /** A name */ public static final PdfName KIDS = new PdfName("Kids"); /** A name */ public static final PdfName L = new PdfName("L"); /** A name */ public static final PdfName L2R = new PdfName("L2R"); /** A name */ public static final PdfName LANG = new PdfName("Lang"); /** A name */ public static final PdfName LANGUAGE = new PdfName("Language"); /** A name */ public static final PdfName LAST = new PdfName("Last"); /** A name */ public static final PdfName LASTCHAR = new PdfName("LastChar"); /** A name */ public static final PdfName LASTPAGE = new PdfName("LastPage"); /** A name */ public static final PdfName LAUNCH = new PdfName("Launch"); /** * A name * @since 2.1.6 */ public static final PdfName LBL = new PdfName("Lbl"); /** * A name * @since 2.1.6 */ public static final PdfName LBODY = new PdfName("LBody"); /** A name */ public static final PdfName LENGTH = new PdfName("Length"); /** A name */ public static final PdfName LENGTH1 = new PdfName("Length1"); /** * A name * @since 2.1.6 */ public static final PdfName LI = new PdfName("LI"); /** A name */ public static final PdfName LIMITS = new PdfName("Limits"); /** A name */ public static final PdfName LINE = new PdfName("Line"); /** * A name. * @since 2.1.6 */ public static final PdfName LINEAR = new PdfName("Linear"); /** A name */ public static final PdfName LINK = new PdfName("Link"); /** A name */ public static final PdfName LISTMODE = new PdfName("ListMode"); /** A name */ public static final PdfName LOCATION = new PdfName("Location"); /** A name */ public static final PdfName LOCK = new PdfName("Lock"); /** * A name * @since 2.1.2 */ public static final PdfName LOCKED = new PdfName("Locked"); /** A name */ public static final PdfName LZWDECODE = new PdfName("LZWDecode"); /** A name */ public static final PdfName M = new PdfName("M"); /** * A name * @since 2.1.6 */ public static final PdfName MATERIAL = new PdfName("Material"); /** A name */ public static final PdfName MATRIX = new PdfName("Matrix"); /** A name of an encoding */ public static final PdfName MAC_EXPERT_ENCODING = new PdfName("MacExpertEncoding"); /** A name of an encoding */ public static final PdfName MAC_ROMAN_ENCODING = new PdfName("MacRomanEncoding"); /** A name */ public static final PdfName MARKED = new PdfName("Marked"); /** A name */ public static final PdfName MARKINFO = new PdfName("MarkInfo"); /** A name */ public static final PdfName MASK = new PdfName("Mask"); /** * A name * @since 2.1.6 renamed from MAX */ public static final PdfName MAX_LOWER_CASE = new PdfName("max"); /** * A name * @since 2.1.6 */ public static final PdfName MAX_CAMEL_CASE = new PdfName("Max"); /** A name */ public static final PdfName MAXLEN = new PdfName("MaxLen"); /** A name */ public static final PdfName MEDIABOX = new PdfName("MediaBox"); /** A name */ public static final PdfName MCID = new PdfName("MCID"); /** A name */ public static final PdfName MCR = new PdfName("MCR"); /** A name */ public static final PdfName METADATA = new PdfName("Metadata"); /** * A name * @since 2.1.6 renamed from MIN */ public static final PdfName MIN_LOWER_CASE = new PdfName("min"); /** * A name * @since 2.1.6 */ public static final PdfName MIN_CAMEL_CASE = new PdfName("Min"); /** A name */ public static final PdfName MK = new PdfName("MK"); /** A name */ public static final PdfName MMTYPE1 = new PdfName("MMType1"); /** A name */ public static final PdfName MODDATE = new PdfName("ModDate"); /** A name */ public static final PdfName N = new PdfName("N"); /** A name */ public static final PdfName N0 = new PdfName("n0"); /** A name */ public static final PdfName N1 = new PdfName("n1"); /** A name */ public static final PdfName N2 = new PdfName("n2"); /** A name */ public static final PdfName N3 = new PdfName("n3"); /** A name */ public static final PdfName N4 = new PdfName("n4"); /** A name */ public static final PdfName NAME = new PdfName("Name"); /** A name */ public static final PdfName NAMED = new PdfName("Named"); /** A name */ public static final PdfName NAMES = new PdfName("Names"); /** * A name. * @since 2.1.6 */ public static final PdfName NAVIGATION = new PdfName("Navigation"); /** * A name. * @since 2.1.6 */ public static final PdfName NAVIGATIONPANE = new PdfName("NavigationPane"); /** * A name. * @since 2.1.6 */ public static final PdfName NEAR = new PdfName("Near"); /** A name */ public static final PdfName NEEDAPPEARANCES = new PdfName("NeedAppearances"); /** A name */ public static final PdfName NEWWINDOW = new PdfName("NewWindow"); /** A name */ public static final PdfName NEXT = new PdfName("Next"); /** A name */ public static final PdfName NEXTPAGE = new PdfName("NextPage"); /** A name */ public static final PdfName NM = new PdfName("NM"); /** A name */ public static final PdfName NONE = new PdfName("None"); /** A name */ public static final PdfName NONFULLSCREENPAGEMODE = new PdfName("NonFullScreenPageMode"); /** * A name * @since 2.1.6 */ public static final PdfName NONSTRUCT = new PdfName("NonStruct"); /** * A name * @since 2.1.6 */ public static final PdfName NOTE = new PdfName("Note"); /** A name */ public static final PdfName NUMCOPIES = new PdfName("NumCopies"); /** A name */ public static final PdfName NUMS = new PdfName("Nums"); /** A name */ public static final PdfName O = new PdfName("O"); /** * A name used with Document Structure * @since 2.1.5 */ public static final PdfName OBJ = new PdfName("Obj"); /** * a name used with Doucment Structure * @since 2.1.5 */ public static final PdfName OBJR = new PdfName("OBJR"); /** A name */ public static final PdfName OBJSTM = new PdfName("ObjStm"); /** A name */ public static final PdfName OC = new PdfName("OC"); /** A name */ public static final PdfName OCG = new PdfName("OCG"); /** A name */ public static final PdfName OCGS = new PdfName("OCGs"); /** A name */ public static final PdfName OCMD = new PdfName("OCMD"); /** A name */ public static final PdfName OCPROPERTIES = new PdfName("OCProperties"); /** A name */ public static final PdfName Off = new PdfName("Off"); /** A name */ public static final PdfName OFF = new PdfName("OFF"); /** A name */ public static final PdfName ON = new PdfName("ON"); /** A name */ public static final PdfName ONECOLUMN = new PdfName("OneColumn"); /** A name */ public static final PdfName OPEN = new PdfName("Open"); /** A name */ public static final PdfName OPENACTION = new PdfName("OpenAction"); /** A name */ public static final PdfName OP = new PdfName("OP"); /** A name */ public static final PdfName op = new PdfName("op"); /** A name */ public static final PdfName OPM = new PdfName("OPM"); /** A name */ public static final PdfName OPT = new PdfName("Opt"); /** A name */ public static final PdfName ORDER = new PdfName("Order"); /** A name */ public static final PdfName ORDERING = new PdfName("Ordering"); /** * A name. * @since 2.1.6 */ public static final PdfName OSCILLATING = new PdfName("Oscillating"); /** A name */ public static final PdfName OUTLINES = new PdfName("Outlines"); /** A name */ public static final PdfName OUTPUTCONDITION = new PdfName("OutputCondition"); /** A name */ public static final PdfName OUTPUTCONDITIONIDENTIFIER = new PdfName("OutputConditionIdentifier"); /** A name */ public static final PdfName OUTPUTINTENT = new PdfName("OutputIntent"); /** A name */ public static final PdfName OUTPUTINTENTS = new PdfName("OutputIntents"); /** A name */ public static final PdfName P = new PdfName("P"); /** A name */ public static final PdfName PAGE = new PdfName("Page"); /** A name */ public static final PdfName PAGELABELS = new PdfName("PageLabels"); /** A name */ public static final PdfName PAGELAYOUT = new PdfName("PageLayout"); /** A name */ public static final PdfName PAGEMODE = new PdfName("PageMode"); /** A name */ public static final PdfName PAGES = new PdfName("Pages"); /** A name */ public static final PdfName PAINTTYPE = new PdfName("PaintType"); /** A name */ public static final PdfName PANOSE = new PdfName("Panose"); /** A name */ public static final PdfName PARAMS = new PdfName("Params"); /** A name */ public static final PdfName PARENT = new PdfName("Parent"); /** A name */ public static final PdfName PARENTTREE = new PdfName("ParentTree"); /** * A name used in defining Document Structure. * @since 2.1.5 */ public static final PdfName PARENTTREENEXTKEY = new PdfName( "ParentTreeNextKey" ); /** * A name * @since 2.1.6 */ public static final PdfName PART = new PdfName( "Part" ); /** * A name. * @since 2.1.6 */ public static final PdfName PASSCONTEXTCLICK = new PdfName("PassContextClick"); /** A name */ public static final PdfName PATTERN = new PdfName("Pattern"); /** A name */ public static final PdfName PATTERNTYPE = new PdfName("PatternType"); /** * A name. * @since 2.1.6 */ public static final PdfName PC = new PdfName("PC"); /** A name */ public static final PdfName PDF = new PdfName("PDF"); /** A name */ public static final PdfName PDFDOCENCODING = new PdfName("PDFDocEncoding"); /** A name */ public static final PdfName PERCEPTUAL = new PdfName("Perceptual"); /** A name */ public static final PdfName PERMS = new PdfName("Perms"); /** A name */ public static final PdfName PG = new PdfName("Pg"); /** * A name. * @since 2.1.6 */ public static final PdfName PI = new PdfName("PI"); /** A name */ public static final PdfName PICKTRAYBYPDFSIZE = new PdfName("PickTrayByPDFSize"); /** * A name. * @since 2.1.6 */ public static final PdfName PLAYCOUNT = new PdfName("PlayCount"); /** * A name. * @since 2.1.6 */ public static final PdfName PO = new PdfName("PO"); /** A name */ public static final PdfName POPUP = new PdfName("Popup"); /** * A name. * @since 2.1.6 */ public static final PdfName POSITION = new PdfName("Position"); /** A name */ public static final PdfName PREDICTOR = new PdfName("Predictor"); /** A name */ public static final PdfName PREFERRED = new PdfName("Preferred"); /** * A name. * @since 2.1.6 */ public static final PdfName PRESENTATION = new PdfName("Presentation"); /** A name */ public static final PdfName PRESERVERB = new PdfName("PreserveRB"); /** A name */ public static final PdfName PREV = new PdfName("Prev"); /** A name */ public static final PdfName PREVPAGE = new PdfName("PrevPage"); /** A name */ public static final PdfName PRINT = new PdfName("Print"); /** A name */ public static final PdfName PRINTAREA = new PdfName("PrintArea"); /** A name */ public static final PdfName PRINTCLIP = new PdfName("PrintClip"); /** A name */ public static final PdfName PRINTPAGERANGE = new PdfName("PrintPageRange"); /** A name */ public static final PdfName PRINTSCALING = new PdfName("PrintScaling"); /** A name */ public static final PdfName PRINTSTATE = new PdfName("PrintState"); /** * A name * @since 2.1.6 */ public static final PdfName PRIVATE = new PdfName("Private"); /** A name */ public static final PdfName PROCSET = new PdfName("ProcSet"); /** A name */ public static final PdfName PRODUCER = new PdfName("Producer"); /** A name */ public static final PdfName PROPERTIES = new PdfName("Properties"); /** A name */ public static final PdfName PS = new PdfName("PS"); /** A name */ public static final PdfName PUBSEC = new PdfName("Adobe.PubSec"); /** * A name. * @since 2.1.6 */ public static final PdfName PV = new PdfName("PV"); /** A name */ public static final PdfName Q = new PdfName("Q"); /** A name */ public static final PdfName QUADPOINTS = new PdfName("QuadPoints"); /** * A name * @since 2.1.6 */ public static final PdfName QUOTE = new PdfName("Quote"); /** A name */ public static final PdfName R = new PdfName("R"); /** A name */ public static final PdfName R2L = new PdfName("R2L"); /** A name */ public static final PdfName RANGE = new PdfName("Range"); /** A name */ public static final PdfName RC = new PdfName("RC"); /** A name */ public static final PdfName RBGROUPS = new PdfName("RBGroups"); /** A name */ public static final PdfName REASON = new PdfName("Reason"); /** A name */ public static final PdfName RECIPIENTS = new PdfName("Recipients"); /** A name */ public static final PdfName RECT = new PdfName("Rect"); /** A name */ public static final PdfName REFERENCE = new PdfName("Reference"); /** A name */ public static final PdfName REGISTRY = new PdfName("Registry"); /** A name */ public static final PdfName REGISTRYNAME = new PdfName("RegistryName"); /** * A name * @since 2.1.5 renamed from RELATIVECALORIMETRIC */ public static final PdfName RELATIVECOLORIMETRIC = new PdfName("RelativeColorimetric"); /** A name */ public static final PdfName RENDITION = new PdfName("Rendition"); /** A name */ public static final PdfName RESETFORM = new PdfName("ResetForm"); /** A name */ public static final PdfName RESOURCES = new PdfName("Resources"); /** A name */ public static final PdfName RI = new PdfName("RI"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIA = new PdfName("RichMedia"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAACTIVATION = new PdfName("RichMediaActivation"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAANIMATION = new PdfName("RichMediaAnimation"); /** * A name * @since 2.1.6 */ public static final PdfName RICHMEDIACOMMAND = new PdfName("RichMediaCommand"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIACONFIGURATION = new PdfName("RichMediaConfiguration"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIACONTENT = new PdfName("RichMediaContent"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIADEACTIVATION = new PdfName("RichMediaDeactivation"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAEXECUTE = new PdfName("RichMediaExecute"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAINSTANCE = new PdfName("RichMediaInstance"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAPARAMS = new PdfName("RichMediaParams"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAPOSITION = new PdfName("RichMediaPosition"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAPRESENTATION = new PdfName("RichMediaPresentation"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIASETTINGS = new PdfName("RichMediaSettings"); /** * A name. * @since 2.1.6 */ public static final PdfName RICHMEDIAWINDOW = new PdfName("RichMediaWindow"); /** A name */ public static final PdfName ROLEMAP = new PdfName("RoleMap"); /** A name */ public static final PdfName ROOT = new PdfName("Root"); /** A name */ public static final PdfName ROTATE = new PdfName("Rotate"); /** A name */ public static final PdfName ROWS = new PdfName("Rows"); /** * A name * @since 2.1.6 */ public static final PdfName RUBY = new PdfName( "Ruby" ); /** A name */ public static final PdfName RUNLENGTHDECODE = new PdfName("RunLengthDecode"); /** A name */ public static final PdfName RV = new PdfName("RV"); /** A name */ public static final PdfName S = new PdfName("S"); /** A name */ public static final PdfName SATURATION = new PdfName("Saturation"); /** A name */ public static final PdfName SCHEMA = new PdfName("Schema"); /** A name */ public static final PdfName SCREEN = new PdfName("Screen"); /** * A name. * @since 2.1.6 */ public static final PdfName SCRIPTS = new PdfName("Scripts"); /** A name */ public static final PdfName SECT = new PdfName("Sect"); /** A name */ public static final PdfName SEPARATION = new PdfName("Separation"); /** A name */ public static final PdfName SETOCGSTATE = new PdfName("SetOCGState"); /** * A name. * @since 2.1.6 */ public static final PdfName SETTINGS = new PdfName("Settings"); /** A name */ public static final PdfName SHADING = new PdfName("Shading"); /** A name */ public static final PdfName SHADINGTYPE = new PdfName("ShadingType"); /** A name */ public static final PdfName SHIFT_JIS = new PdfName("Shift-JIS"); /** A name */ public static final PdfName SIG = new PdfName("Sig"); /** A name */ public static final PdfName SIGFLAGS = new PdfName("SigFlags"); /** A name */ public static final PdfName SIGREF = new PdfName("SigRef"); /** A name */ public static final PdfName SIMPLEX = new PdfName("Simplex"); /** A name */ public static final PdfName SINGLEPAGE = new PdfName("SinglePage"); /** A name */ public static final PdfName SIZE = new PdfName("Size"); /** A name */ public static final PdfName SMASK = new PdfName("SMask"); /** A name */ public static final PdfName SORT = new PdfName("Sort"); /** * A name. * @since 2.1.6 */ public static final PdfName SOUND = new PdfName("Sound"); /** A name */ public static final PdfName SPAN = new PdfName("Span"); /** * A name. * @since 2.1.6 */ public static final PdfName SPEED = new PdfName("Speed"); /** A name */ public static final PdfName SPLIT = new PdfName("Split"); /** A name */ public static final PdfName SQUARE = new PdfName("Square"); /** * A name * @since 2.1.3 */ public static final PdfName SQUIGGLY = new PdfName("Squiggly"); /** A name */ public static final PdfName ST = new PdfName("St"); /** A name */ public static final PdfName STAMP = new PdfName("Stamp"); /** A name */ public static final PdfName STANDARD = new PdfName("Standard"); /** A name */ public static final PdfName STATE = new PdfName("State"); /** A name */ public static final PdfName STDCF = new PdfName("StdCF"); /** A name */ public static final PdfName STEMV = new PdfName("StemV"); /** A name */ public static final PdfName STMF = new PdfName("StmF"); /** A name */ public static final PdfName STRF = new PdfName("StrF"); /** A name */ public static final PdfName STRIKEOUT = new PdfName("StrikeOut"); /** A name */ public static final PdfName STRUCTPARENT = new PdfName("StructParent"); /** A name */ public static final PdfName STRUCTPARENTS = new PdfName("StructParents"); /** A name */ public static final PdfName STRUCTTREEROOT = new PdfName("StructTreeRoot"); /** A name */ public static final PdfName STYLE = new PdfName("Style"); /** A name */ public static final PdfName SUBFILTER = new PdfName("SubFilter"); /** A name */ public static final PdfName SUBJECT = new PdfName("Subject"); /** A name */ public static final PdfName SUBMITFORM = new PdfName("SubmitForm"); /** A name */ public static final PdfName SUBTYPE = new PdfName("Subtype"); /** A name */ public static final PdfName SUPPLEMENT = new PdfName("Supplement"); /** A name */ public static final PdfName SV = new PdfName("SV"); /** A name */ public static final PdfName SW = new PdfName("SW"); /** A name of a base 14 type 1 font */ public static final PdfName SYMBOL = new PdfName("Symbol"); /** A name */ public static final PdfName T = new PdfName("T"); /** * A name * @since 2.1.6 */ public static final PdfName TA = new PdfName("TA"); /** * A name * @since 2.1.6 */ public static final PdfName TABLE = new PdfName("Table"); /** * A name * @since 2.1.5 */ public static final PdfName TABS = new PdfName("Tabs"); /** * A name * @since 2.1.6 */ public static final PdfName TBODY = new PdfName("TBody"); /** * A name * @since 2.1.6 */ public static final PdfName TD = new PdfName("TD"); /** A name */ public static final PdfName TEXT = new PdfName("Text"); /** * A name * @since 2.1.6 */ public static final PdfName TFOOT = new PdfName("TFoot"); /** * A name * @since 2.1.6 */ public static final PdfName TH = new PdfName("TH"); /** * A name * @since 2.1.6 */ public static final PdfName THEAD = new PdfName("THead"); /** A name */ public static final PdfName THUMB = new PdfName("Thumb"); /** A name */ public static final PdfName THREADS = new PdfName("Threads"); /** A name */ public static final PdfName TI = new PdfName("TI"); /** * A name * @since 2.1.6 */ public static final PdfName TIME = new PdfName("Time"); /** A name */ public static final PdfName TILINGTYPE = new PdfName("TilingType"); /** A name of a base 14 type 1 font */ public static final PdfName TIMES_ROMAN = new PdfName("Times-Roman"); /** A name of a base 14 type 1 font */ public static final PdfName TIMES_BOLD = new PdfName("Times-Bold"); /** A name of a base 14 type 1 font */ public static final PdfName TIMES_ITALIC = new PdfName("Times-Italic"); /** A name of a base 14 type 1 font */ public static final PdfName TIMES_BOLDITALIC = new PdfName("Times-BoldItalic"); /** A name */ public static final PdfName TITLE = new PdfName("Title"); /** A name */ public static final PdfName TK = new PdfName("TK"); /** A name */ public static final PdfName TM = new PdfName("TM"); /** * A name * @since 2.1.6 */ public static final PdfName TOC = new PdfName("TOC"); /** * A name * @since 2.1.6 */ public static final PdfName TOCI = new PdfName("TOCI"); /** A name */ public static final PdfName TOGGLE = new PdfName("Toggle"); /** * A name. * @since 2.1.6 */ public static final PdfName TOOLBAR = new PdfName("Toolbar"); /** A name */ public static final PdfName TOUNICODE = new PdfName("ToUnicode"); /** A name */ public static final PdfName TP = new PdfName("TP"); /** * A name * @since 2.1.6 */ public static final PdfName TABLEROW = new PdfName( "TR" ); /** A name */ public static final PdfName TRANS = new PdfName("Trans"); /** A name */ public static final PdfName TRANSFORMPARAMS = new PdfName("TransformParams"); /** A name */ public static final PdfName TRANSFORMMETHOD = new PdfName("TransformMethod"); /** A name */ public static final PdfName TRANSPARENCY = new PdfName("Transparency"); /** * A name. * @since 2.1.6 */ public static final PdfName TRANSPARENT = new PdfName("Transparent"); /** A name */ public static final PdfName TRAPPED = new PdfName("Trapped"); /** A name */ public static final PdfName TRIMBOX = new PdfName("TrimBox"); /** A name */ public static final PdfName TRUETYPE = new PdfName("TrueType"); /** A name */ public static final PdfName TU = new PdfName("TU"); /** A name */ public static final PdfName TWOCOLUMNLEFT = new PdfName("TwoColumnLeft"); /** A name */ public static final PdfName TWOCOLUMNRIGHT = new PdfName("TwoColumnRight"); /** A name */ public static final PdfName TWOPAGELEFT = new PdfName("TwoPageLeft"); /** A name */ public static final PdfName TWOPAGERIGHT = new PdfName("TwoPageRight"); /** A name */ public static final PdfName TX = new PdfName("Tx"); /** A name */ public static final PdfName TYPE = new PdfName("Type"); /** A name */ public static final PdfName TYPE0 = new PdfName("Type0"); /** A name */ public static final PdfName TYPE1 = new PdfName("Type1"); /** A name of an attribute. */ public static final PdfName TYPE3 = new PdfName("Type3"); /** A name of an attribute. */ public static final PdfName U = new PdfName("U"); /** A name of an attribute. */ public static final PdfName UF = new PdfName("UF"); /** A name of an attribute. */ public static final PdfName UHC = new PdfName("UHC"); /** A name of an attribute. */ public static final PdfName UNDERLINE = new PdfName("Underline"); /** A name */ public static final PdfName UR = new PdfName("UR"); /** A name */ public static final PdfName UR3 = new PdfName("UR3"); /** A name */ public static final PdfName URI = new PdfName("URI"); /** A name */ public static final PdfName URL = new PdfName("URL"); /** A name */ public static final PdfName USAGE = new PdfName("Usage"); /** A name */ public static final PdfName USEATTACHMENTS = new PdfName("UseAttachments"); /** A name */ public static final PdfName USENONE = new PdfName("UseNone"); /** A name */ public static final PdfName USEOC = new PdfName("UseOC"); /** A name */ public static final PdfName USEOUTLINES = new PdfName("UseOutlines"); /** A name */ public static final PdfName USER = new PdfName("User"); /** A name */ public static final PdfName USERPROPERTIES = new PdfName("UserProperties"); /** A name */ public static final PdfName USERUNIT = new PdfName("UserUnit"); /** A name */ public static final PdfName USETHUMBS = new PdfName("UseThumbs"); /** A name */ public static final PdfName V = new PdfName("V"); /** A name */ public static final PdfName V2 = new PdfName("V2"); /** * A name. * @since 2.1.6 */ public static final PdfName VALIGN = new PdfName("VAlign"); /** A name */ public static final PdfName VERISIGN_PPKVS = new PdfName("VeriSign.PPKVS"); /** A name */ public static final PdfName VERSION = new PdfName("Version"); /** * A name. * @since 2.1.6 */ public static final PdfName VIDEO = new PdfName("Video"); /** A name */ public static final PdfName VIEW = new PdfName("View"); /** * A name. * @since 2.1.6 */ public static final PdfName VIEWS = new PdfName("Views"); /** A name */ public static final PdfName VIEWAREA = new PdfName("ViewArea"); /** A name */ public static final PdfName VIEWCLIP = new PdfName("ViewClip"); /** A name */ public static final PdfName VIEWERPREFERENCES = new PdfName("ViewerPreferences"); /** A name */ public static final PdfName VIEWSTATE = new PdfName("ViewState"); /** A name */ public static final PdfName VISIBLEPAGES = new PdfName("VisiblePages"); /** * A name. * @since 2.1.6 */ public static final PdfName VOFFSET = new PdfName("VOffset"); /** A name of an attribute. */ public static final PdfName W = new PdfName("W"); /** A name of an attribute. */ public static final PdfName W2 = new PdfName("W2"); /** * A name * @since 2.1.6 */ public static final PdfName WARICHU = new PdfName("Warichu"); /** A name of an attribute. */ public static final PdfName WC = new PdfName("WC"); /** A name of an attribute. */ public static final PdfName WIDGET = new PdfName("Widget"); /** A name of an attribute. */ public static final PdfName WIDTH = new PdfName("Width"); /** A name */ public static final PdfName WIDTHS = new PdfName("Widths"); /** A name of an encoding */ public static final PdfName WIN = new PdfName("Win"); /** A name of an encoding */ public static final PdfName WIN_ANSI_ENCODING = new PdfName("WinAnsiEncoding"); /** * A name. * @since 2.1.6 */ public static final PdfName WINDOW = new PdfName("Window"); /** * A name. * @since 2.1.6 */ public static final PdfName WINDOWED = new PdfName("Windowed"); /** A name of an encoding */ public static final PdfName WIPE = new PdfName("Wipe"); /** A name */ public static final PdfName WHITEPOINT = new PdfName("WhitePoint"); /** A name */ public static final PdfName WP = new PdfName("WP"); /** A name of an encoding */ public static final PdfName WS = new PdfName("WS"); /** A name */ public static final PdfName X = new PdfName("X"); /** * A name. * @since 2.1.6 */ public static final PdfName XA = new PdfName("XA"); /** * A name. * @since 2.1.6 */ public static final PdfName XD = new PdfName("XD"); /** A name */ public static final PdfName XFA = new PdfName("XFA"); /** A name */ public static final PdfName XML = new PdfName("XML"); /** A name */ public static final PdfName XOBJECT = new PdfName("XObject"); /** A name */ public static final PdfName XSTEP = new PdfName("XStep"); /** A name */ public static final PdfName XREF = new PdfName("XRef"); /** A name */ public static final PdfName XREFSTM = new PdfName("XRefStm"); /** A name */ public static final PdfName XYZ = new PdfName("XYZ"); /** A name */ public static final PdfName YSTEP = new PdfName("YStep"); /** A name */ public static final PdfName ZADB = new PdfName("ZaDb"); /** A name of a base 14 type 1 font */ public static final PdfName ZAPFDINGBATS = new PdfName("ZapfDingbats"); /** A name */ public static final PdfName ZOOM = new PdfName("Zoom"); /** * map strings to all known static names * @since 2.1.6 */ public static Map staticNames; /** * Use reflection to cache all the static public final names so * future PdfName additions don't have to be "added twice". * A bit less efficient (around 50ms spent here on a 2.2ghz machine), * but Much Less error prone. * @since 2.1.6 */ static { Field fields[] = PdfName.class.getDeclaredFields(); staticNames = new HashMap( fields.length ); final int flags = Modifier.STATIC | Modifier.PUBLIC | Modifier.FINAL; try { for (int fldIdx = 0; fldIdx < fields.length; ++fldIdx) { Field curFld = fields[fldIdx]; if ((curFld.getModifiers() & flags) == flags && curFld.getType().equals( PdfName.class )) { PdfName name = (PdfName)curFld.get( null ); staticNames.put( decodeName( name.toString() ), name ); } } } catch (Exception e) { e.printStackTrace(); } } // CLASS VARIABLES private int hash = 0; // CONSTRUCTORS /** * Constructs a new PdfName. The name length will be checked. * * @param name the new name */ public PdfName(String name) { this(name, true); } /** * Constructs a new PdfName. * @param name the new name * @param lengthCheck if true check the length validity, * if false the name can have any length */ public PdfName(String name, boolean lengthCheck) { super(PdfObject.NAME); // The minimum number of characters in a name is 0, the maximum is 127 (the '/' not included) int length = name.length(); if (lengthCheck && length > 127) throw new IllegalArgumentException("The name '" + name + "' is too long (" + length + " characters)."); bytes = encodeName(name); } /** * Constructs a PdfName. * * @param bytes the byte representation of the name */ public PdfName(byte bytes[]) { super(PdfObject.NAME, bytes); } // CLASS METHODS /** * Compares this object with the specified object for order. * Returns a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object.

* * @param object the Object to be compared. * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. * @throws ClassCastException if the specified object's type prevents it * from being compared to this Object. */ public int compareTo(Object object) { PdfName name = (PdfName) object; byte myBytes[] = bytes; byte objBytes[] = name.bytes; int len = Math.min(myBytes.length, objBytes.length); for(int i = 0; i < len; i++) { if (myBytes[i] > objBytes[i]) return 1; if (myBytes[i] < objBytes[i]) return -1; } if (myBytes.length < objBytes.length) return -1; if (myBytes.length > objBytes.length) return 1; return 0; } /** * Indicates whether some other object is "equal to" this one. * * @param obj the reference object with which to compare. * @return true if this object is the same as the obj * argument; false otherwise. */ public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof PdfName) return compareTo(obj) == 0; return false; } /** * Returns a hash code value for the object. * This method is supported for the benefit of hashtables such as those provided by * java.util.Hashtable. * * @return a hash code value for this object. */ public int hashCode() { int h = hash; if (h == 0) { int ptr = 0; int len = bytes.length; for (int i = 0; i < len; i++) h = 31*h + (bytes[ptr++] & 0xff); hash = h; } return h; } /** * Encodes a plain name given in the unescaped form "AB CD" into "/AB#20CD". * * @param name the name to encode * @return the encoded name * @since 2.1.5 */ public static byte[] encodeName(String name) { int length = name.length(); ByteBuffer buf = new ByteBuffer(length + 20); buf.append('/'); char c; char chars[] = name.toCharArray(); for (int k = 0; k < length; k++) { c = (char)(chars[k] & 0xff); // Escape special characters switch (c) { case ' ': case '%': case '(': case ')': case '<': case '>': case '[': case ']': case '{': case '}': case '/': case '#': buf.append('#'); buf.append(Integer.toString(c, 16)); break; default: if (c >= 32 && c <= 126) buf.append(c); else { buf.append('#'); if (c < 16) buf.append('0'); buf.append(Integer.toString(c, 16)); } break; } } return buf.toByteArray(); } /** * Decodes an escaped name given in the form "/AB#20CD" into "AB CD". * * @param name the name to decode * @return the decoded name */ public static String decodeName(String name) { StringBuffer buf = new StringBuffer(); try { int len = name.length(); for (int k = 1; k < len; ++k) { char c = name.charAt(k); if (c == '#') { char c1 = name.charAt(k + 1); char c2 = name.charAt(k + 2); c = (char)((PRTokeniser.getHex(c1) << 4) + PRTokeniser.getHex(c2)); k += 2; } buf.append(c); } } catch (IndexOutOfBoundsException e) { // empty on purpose } return buf.toString(); } } src/core/com/lowagie/text/pdf/PdfNameTree.java100644 0 0 15615 11161724620 16713 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; /** * Creates a name tree. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfNameTree { private static final int leafSize = 64; /** * Writes a name tree to a PdfWriter. * @param items the item of the name tree. The key is a String * and the value is a PdfObject. Note that although the * keys are strings only the lower byte is used and no check is made for chars * with the same lower byte and different upper byte. This will generate a wrong * tree name. * @param writer the writer * @throws IOException on error * @return the dictionary with the name tree. This dictionary is the one * generally pointed to by the key /Dests, for example */ public static PdfDictionary writeTree(HashMap items, PdfWriter writer) throws IOException { if (items.isEmpty()) return null; String names[] = new String[items.size()]; names = (String[])items.keySet().toArray(names); Arrays.sort(names); if (names.length <= leafSize) { PdfDictionary dic = new PdfDictionary(); PdfArray ar = new PdfArray(); for (int k = 0; k < names.length; ++k) { ar.add(new PdfString(names[k], null)); ar.add((PdfObject)items.get(names[k])); } dic.put(PdfName.NAMES, ar); return dic; } int skip = leafSize; PdfIndirectReference kids[] = new PdfIndirectReference[(names.length + leafSize - 1) / leafSize]; for (int k = 0; k < kids.length; ++k) { int offset = k * leafSize; int end = Math.min(offset + leafSize, names.length); PdfDictionary dic = new PdfDictionary(); PdfArray arr = new PdfArray(); arr.add(new PdfString(names[offset], null)); arr.add(new PdfString(names[end - 1], null)); dic.put(PdfName.LIMITS, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.add(new PdfString(names[offset], null)); arr.add((PdfObject)items.get(names[offset])); } dic.put(PdfName.NAMES, arr); kids[k] = writer.addToBody(dic).getIndirectReference(); } int top = kids.length; while (true) { if (top <= leafSize) { PdfArray arr = new PdfArray(); for (int k = 0; k < top; ++k) arr.add(kids[k]); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.KIDS, arr); return dic; } skip *= leafSize; int tt = (names.length + skip - 1 )/ skip; for (int k = 0; k < tt; ++k) { int offset = k * leafSize; int end = Math.min(offset + leafSize, top); PdfDictionary dic = new PdfDictionary(); PdfArray arr = new PdfArray(); arr.add(new PdfString(names[k * skip], null)); arr.add(new PdfString(names[Math.min((k + 1) * skip, names.length) - 1], null)); dic.put(PdfName.LIMITS, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.add(kids[offset]); } dic.put(PdfName.KIDS, arr); kids[k] = writer.addToBody(dic).getIndirectReference(); } top = tt; } } private static void iterateItems(PdfDictionary dic, HashMap items) { PdfArray nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.NAMES)); if (nn != null) { for (int k = 0; k < nn.size(); ++k) { PdfString s = (PdfString)PdfReader.getPdfObjectRelease(nn.getPdfObject(k++)); items.put(PdfEncodings.convertToString(s.getBytes(), null), nn.getPdfObject(k)); } } else if ((nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.KIDS))) != null) { for (int k = 0; k < nn.size(); ++k) { PdfDictionary kid = (PdfDictionary)PdfReader.getPdfObjectRelease(nn.getPdfObject(k)); iterateItems(kid, items); } } } public static HashMap readTree(PdfDictionary dic) { HashMap items = new HashMap(); if (dic != null) iterateItems(dic, items); return items; } }src/core/com/lowagie/text/pdf/PdfNull.java100644 0 0 6576 11154234212 16106 0ustar 0 0 /* * $Id: PdfNull.java 3759 2009-03-06 16:05:00Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfNull is the Null object represented by the keyword null. *

* This object is described in the 'Portable Document Format Reference Manual version 1.7' * section 3.2.8 (page 63). * * @see PdfObject */ public class PdfNull extends PdfObject { // CLASS CONSTANTS /** An instance of the PdfNull-object. */ public static final PdfNull PDFNULL = new PdfNull(); /** The content of the PdfNull-object. */ private static final String CONTENT = "null"; // CONSTRUCTOR /** * Constructs a PdfNull-object. *

* You never need to do this yourself, you can always use the static final object PDFNULL. */ public PdfNull() { super(NULL, CONTENT); } // CLASS METHOD public String toString() { return "null"; } }src/core/com/lowagie/text/pdf/PdfNumber.java100644 0 0 12425 11154234212 16432 0ustar 0 0 /* * $Id: PdfNumber.java 3759 2009-03-06 16:05:00Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfNumber provides two types of numbers, integer and real. *

* Integers may be specified by signed or unsigned constants. Reals may only be * in decimal format.
* This object is described in the 'Portable Document Format Reference Manual * version 1.7' section 3.3.2 (page 52-53). * * @see PdfObject * @see BadPdfFormatException */ public class PdfNumber extends PdfObject { // CLASS VARIABLES /** * actual value of this PdfNumber, represented as a * double */ private double value; // CONSTRUCTORS /** * Constructs a PdfNumber-object. * * @param content value of the new PdfNumber-object */ public PdfNumber(String content) { super(NUMBER); try { value = Double.parseDouble(content.trim()); setContent(content); } catch (NumberFormatException nfe){ throw new RuntimeException(content + " is not a valid number - " + nfe.toString()); } } /** * Constructs a new PdfNumber-object of type integer. * * @param value value of the new PdfNumber-object */ public PdfNumber(int value) { super(NUMBER); this.value = value; setContent(String.valueOf(value)); } /** * Constructs a new PdfNumber-object of type real. * * @param value value of the new PdfNumber-object */ public PdfNumber(double value) { super(NUMBER); this.value = value; setContent(ByteBuffer.formatDouble(value)); } /** * Constructs a new PdfNumber-object of type real. * * @param value value of the new PdfNumber-object */ public PdfNumber(float value) { this((double)value); } // methods returning the value of this object /** * Returns the primitive int value of this object. * * @return The value as int */ public int intValue() { return (int) value; } /** * Returns the primitive double value of this object. * * @return The value as double */ public double doubleValue() { return value; } /** * Returns the primitive float value of this object. * * @return The value as float */ public float floatValue() { return (float)value; } // other methods /** * Increments the value of the PdfNumber-object by 1. */ public void increment() { value += 1.0; setContent(ByteBuffer.formatDouble(value)); } }src/core/com/lowagie/text/pdf/PdfNumberTree.java100644 0 0 15217 11154165267 17271 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; /** * Creates a number tree. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfNumberTree { private static final int leafSize = 64; /** * Creates a number tree. * @param items the item of the number tree. The key is an Integer * and the value is a PdfObject. * @param writer the writer * @throws IOException on error * @return the dictionary with the number tree. */ public static PdfDictionary writeTree(HashMap items, PdfWriter writer) throws IOException { if (items.isEmpty()) return null; Integer numbers[] = new Integer[items.size()]; numbers = (Integer[])items.keySet().toArray(numbers); Arrays.sort(numbers); if (numbers.length <= leafSize) { PdfDictionary dic = new PdfDictionary(); PdfArray ar = new PdfArray(); for (int k = 0; k < numbers.length; ++k) { ar.add(new PdfNumber(numbers[k].intValue())); ar.add((PdfObject)items.get(numbers[k])); } dic.put(PdfName.NUMS, ar); return dic; } int skip = leafSize; PdfIndirectReference kids[] = new PdfIndirectReference[(numbers.length + leafSize - 1) / leafSize]; for (int k = 0; k < kids.length; ++k) { int offset = k * leafSize; int end = Math.min(offset + leafSize, numbers.length); PdfDictionary dic = new PdfDictionary(); PdfArray arr = new PdfArray(); arr.add(new PdfNumber(numbers[offset].intValue())); arr.add(new PdfNumber(numbers[end - 1].intValue())); dic.put(PdfName.LIMITS, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.add(new PdfNumber(numbers[offset].intValue())); arr.add((PdfObject)items.get(numbers[offset])); } dic.put(PdfName.NUMS, arr); kids[k] = writer.addToBody(dic).getIndirectReference(); } int top = kids.length; while (true) { if (top <= leafSize) { PdfArray arr = new PdfArray(); for (int k = 0; k < top; ++k) arr.add(kids[k]); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.KIDS, arr); return dic; } skip *= leafSize; int tt = (numbers.length + skip - 1 )/ skip; for (int k = 0; k < tt; ++k) { int offset = k * leafSize; int end = Math.min(offset + leafSize, top); PdfDictionary dic = new PdfDictionary(); PdfArray arr = new PdfArray(); arr.add(new PdfNumber(numbers[k * skip].intValue())); arr.add(new PdfNumber(numbers[Math.min((k + 1) * skip, numbers.length) - 1].intValue())); dic.put(PdfName.LIMITS, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.add(kids[offset]); } dic.put(PdfName.KIDS, arr); kids[k] = writer.addToBody(dic).getIndirectReference(); } top = tt; } } private static void iterateItems(PdfDictionary dic, HashMap items) { PdfArray nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.NUMS)); if (nn != null) { for (int k = 0; k < nn.size(); ++k) { PdfNumber s = (PdfNumber)PdfReader.getPdfObjectRelease(nn.getPdfObject(k++)); items.put(new Integer(s.intValue()), nn.getPdfObject(k)); } } else if ((nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.KIDS))) != null) { for (int k = 0; k < nn.size(); ++k) { PdfDictionary kid = (PdfDictionary)PdfReader.getPdfObjectRelease(nn.getPdfObject(k)); iterateItems(kid, items); } } } public static HashMap readTree(PdfDictionary dic) { HashMap items = new HashMap(); if (dic != null) iterateItems(dic, items); return items; } }src/core/com/lowagie/text/pdf/PdfOCG.java100644 0 0 5643 11000354131 15567 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * The interface common to all layer types. * * @author Paulo Soares (psoares@consiste.pt) */ public interface PdfOCG { /** * Gets the PdfIndirectReference that represents this layer. * @return the PdfIndirectReference that represents this layer */ public PdfIndirectReference getRef(); /** * Gets the object representing the layer. * @return the object representing the layer */ public PdfObject getPdfObject(); } src/core/com/lowagie/text/pdf/PdfOCProperties.java100644 0 0 5512 11000354131 17530 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * This class represents the /OCProperties entry in the document catalog * and holds the optional content properties dictionary, which contains * a list of all the optional content groups in the document, as well as information * about the default and alternate configurations for optional content. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfOCProperties extends PdfDictionary { } src/core/com/lowagie/text/pdf/PdfObject.java100644 0 0 30765 11213370070 16416 0ustar 0 0 /* * $Id: PdfObject.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; /** * PdfObject is the abstract superclass of all PDF objects. *

* PDF supports seven basic types of objects: Booleans, numbers, strings, names, * arrays, dictionaries and streams. In addition, PDF provides a null object. * Objects may be labeled so that they can be referred to by other objects.
* All these basic PDF objects are described in the 'Portable Document Format * Reference Manual version 1.3' Chapter 4 (pages 37-54). * * @see PdfNull * @see PdfBoolean * @see PdfNumber * @see PdfString * @see PdfName * @see PdfArray * @see PdfDictionary * @see PdfStream * @see PdfIndirectReference */ public abstract class PdfObject { // CONSTANTS /** A possible type of PdfObject */ public static final int BOOLEAN = 1; /** A possible type of PdfObject */ public static final int NUMBER = 2; /** A possible type of PdfObject */ public static final int STRING = 3; /** A possible type of PdfObject */ public static final int NAME = 4; /** A possible type of PdfObject */ public static final int ARRAY = 5; /** A possible type of PdfObject */ public static final int DICTIONARY = 6; /** A possible type of PdfObject */ public static final int STREAM = 7; /** A possible type of PdfObject */ public static final int NULL = 8; /** A possible type of PdfObject */ public static final int INDIRECT = 10; /** An empty string used for the PdfNull-object and for an empty PdfString-object. */ public static final String NOTHING = ""; /** * This is the default encoding to be used for converting Strings into * bytes and vice versa. The default encoding is PdfDocEncoding. */ public static final String TEXT_PDFDOCENCODING = "PDF"; /** This is the encoding to be used to output text in Unicode. */ public static final String TEXT_UNICODE = "UnicodeBig"; // CLASS VARIABLES /** The content of this PdfObject */ protected byte[] bytes; /** The type of this PdfObject */ protected int type; /** Holds the indirect reference. */ protected PRIndirectReference indRef; // CONSTRUCTORS /** * Constructs a PdfObject of a certain type * without any content. * * @param type type of the new PdfObject */ protected PdfObject(int type) { this.type = type; } /** * Constructs a PdfObject of a certain type * with a certain content. * * @param type type of the new PdfObject * @param content content of the new PdfObject as a * String. */ protected PdfObject(int type, String content) { this.type = type; bytes = PdfEncodings.convertToBytes(content, null); } /** * Constructs a PdfObject of a certain type * with a certain content. * * @param type type of the new PdfObject * @param bytes content of the new PdfObject as an array of * byte. */ protected PdfObject(int type, byte[] bytes) { this.bytes = bytes; this.type = type; } // methods dealing with the content of this object /** * Writes the PDF representation of this PdfObject as an * array of bytes to the writer. * * @param writer for backwards compatibility * @param os The OutputStream to write the bytes to. * @throws IOException */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { if (bytes != null) os.write(bytes); } /** * Returns the String-representation of this * PdfObject. * * @return a String */ public String toString() { if (bytes == null) return super.toString(); return PdfEncodings.convertToString(bytes, null); } /** * Gets the presentation of this object in a byte array * * @return a byte array */ public byte[] getBytes() { return bytes; } /** * Whether this object can be contained in an object stream. * * PdfObjects of type STREAM OR INDIRECT can not be contained in an * object stream. * * @return true if this object can be in an object stream. * Otherwise false */ public boolean canBeInObjStm() { switch (type) { case NULL: case BOOLEAN: case NUMBER: case STRING: case NAME: case ARRAY: case DICTIONARY: return true; case STREAM: case INDIRECT: default: return false; } } /** * Returns the length of the PDF representation of the PdfObject. *

* In some cases, namely for PdfString and PdfStream, * this method differs from the method length because length * returns the length of the actual content of the PdfObject.

*

* Remark: the actual content of an object is in most cases identical to its representation. * The following statement is always true: length() >= pdfLength().

* * @return a length */ // public int pdfLength() { // return toPdf(null).length; // } /** * Returns the length of the actual content of the PdfObject. *

* In some cases, namely for PdfString and PdfStream, * this method differs from the method pdfLength because pdfLength * returns the length of the PDF representation of the object, not of the actual content * as does the method length.

*

* Remark: the actual content of an object is in some cases identical to its representation. * The following statement is always true: length() >= pdfLength().

* * @return The length as int */ public int length() { return toString().length(); } /** * Changes the content of this PdfObject. * * @param content the new content of this PdfObject */ protected void setContent(String content) { bytes = PdfEncodings.convertToBytes(content, null); } // methods dealing with the type of this object /** * Returns the type of this PdfObject. * * May be either of: * - NULL: A PdfNull * - BOOLEAN: A PdfBoolean * - NUMBER: A PdfNumber * - STRING: A PdfString * - NAME: A PdfName * - ARRAY: A PdfArray * - DICTIONARY: A PdfDictionary * - STREAM: A PdfStream * - INDIRECT: >PdfIndirectObject * * @return The type */ public int type() { return type; } /** * Checks if this PdfObject is of the type * PdfNull. * * @return true or false */ public boolean isNull() { return (type == NULL); } /** * Checks if this PdfObject is of the type * PdfBoolean. * * @return true or false */ public boolean isBoolean() { return (type == BOOLEAN); } /** * Checks if this PdfObject is of the type * PdfNumber. * * @return true or false */ public boolean isNumber() { return (type == NUMBER); } /** * Checks if this PdfObject is of the type * PdfString. * * @return true or false */ public boolean isString() { return (type == STRING); } /** * Checks if this PdfObject is of the type * PdfName. * * @return true or false */ public boolean isName() { return (type == NAME); } /** * Checks if this PdfObject is of the type * PdfArray. * * @return true or false */ public boolean isArray() { return (type == ARRAY); } /** * Checks if this PdfObject is of the type * PdfDictionary. * * @return true or false */ public boolean isDictionary() { return (type == DICTIONARY); } /** * Checks if this PdfObject is of the type * PdfStream. * * @return true or false */ public boolean isStream() { return (type == STREAM); } /** * Checks if this PdfObject is of the type * PdfIndirectObject. * * @return true if this is an indirect object, * otherwise false */ public boolean isIndirect() { return (type == INDIRECT); } /** * Get the indirect reference * * @return A PdfIndirectReference */ public PRIndirectReference getIndRef() { return indRef; } /** * Set the indirect reference * * @param indRef New value as a PdfIndirectReference */ public void setIndRef(PRIndirectReference indRef) { this.indRef = indRef; } } src/core/com/lowagie/text/pdf/PdfOutline.java100644 0 0 41035 11012562273 16624 0ustar 0 0 /* * $Id: PdfOutline.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Chunk; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; /** * PdfOutline is an object that represents a PDF outline entry. *

* An outline allows a user to access views of a document by name.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 6.7 (page 104-106) * * @see PdfDictionary */ public class PdfOutline extends PdfDictionary { // membervariables /** the PdfIndirectReference of this object */ private PdfIndirectReference reference; /** value of the Count-key */ private int count = 0; /** value of the Parent-key */ private PdfOutline parent; /** value of the Destination-key */ private PdfDestination destination; /** The PdfAction for this outline. */ private PdfAction action; protected ArrayList kids = new ArrayList(); protected PdfWriter writer; /** Holds value of property tag. */ private String tag; /** Holds value of property open. */ private boolean open; /** Holds value of property color. */ private Color color; /** Holds value of property style. */ private int style = 0; // constructors /** * Constructs a PdfOutline. *

* This is the constructor for the outlines object. * * @param writer The PdfWriter you are adding the outline to */ PdfOutline(PdfWriter writer) { super(OUTLINES); open = true; parent = null; this.writer = writer; } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfAction action, String title) { this(parent, action, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfAction action, String title, boolean open) { super(); this.action = action; initOutline(parent, title, open); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfDestination destination, String title) { this(parent, destination, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfDestination destination, String title, boolean open) { super(); this.destination = destination; initOutline(parent, title, open); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfAction action, PdfString title) { this(parent, action, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfAction action, PdfString title, boolean open) { this(parent, action, title.toString(), open); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title) { this(parent, destination, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title, boolean open) { this(parent, destination, title.toString(), true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title) { this(parent, action, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param action the PdfAction for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title, boolean open) { super(); StringBuffer buf = new StringBuffer(); for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) { Chunk chunk = (Chunk) i.next(); buf.append(chunk.getContent()); } this.action = action; initOutline(parent, buf.toString(), open); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. The open mode is * true. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item */ public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title) { this(parent, destination, title, true); } /** * Constructs a PdfOutline. *

* This is the constructor for an outline entry. * * @param parent the parent of this outline item * @param destination the destination for this outline item * @param title the title of this outline item * @param open true if the children are visible */ public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title, boolean open) { super(); StringBuffer buf = new StringBuffer(); for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) { Chunk chunk = (Chunk) i.next(); buf.append(chunk.getContent()); } this.destination = destination; initOutline(parent, buf.toString(), open); } // methods /** Helper for the constructors. * @param parent the parent outline * @param title the title for this outline * @param open true if the children are visible */ void initOutline(PdfOutline parent, String title, boolean open) { this.open = open; this.parent = parent; writer = parent.writer; put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); parent.addKid(this); if (destination != null && !destination.hasPage()) // bugfix Finn Bock setDestinationPage(writer.getCurrentPage()); } /** * Sets the indirect reference of this PdfOutline. * * @param reference the PdfIndirectReference to this outline. */ public void setIndirectReference(PdfIndirectReference reference) { this.reference = reference; } /** * Gets the indirect reference of this PdfOutline. * * @return the PdfIndirectReference to this outline. */ public PdfIndirectReference indirectReference() { return reference; } /** * Gets the parent of this PdfOutline. * * @return the PdfOutline that is the parent of this outline. */ public PdfOutline parent() { return parent; } /** * Set the page of the PdfDestination-object. * * @param pageReference indirect reference to the page * @return true if this page was set as the PdfDestination-page. */ public boolean setDestinationPage(PdfIndirectReference pageReference) { if (destination == null) { return false; } return destination.addPage(pageReference); } /** * Gets the destination for this outline. * @return the destination */ public PdfDestination getPdfDestination() { return destination; } int getCount() { return count; } void setCount(int count) { this.count = count; } /** * returns the level of this outline. * * @return a level */ public int level() { if (parent == null) { return 0; } return (parent.level() + 1); } /** * Returns the PDF representation of this PdfOutline. * * @param writer the encryption information * @param os * @throws IOException */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { if (color != null && !color.equals(Color.black)) { put(PdfName.C, new PdfArray(new float[]{color.getRed()/255f,color.getGreen()/255f,color.getBlue()/255f})); } int flag = 0; if ((style & Font.BOLD) != 0) flag |= 2; if ((style & Font.ITALIC) != 0) flag |= 1; if (flag != 0) put(PdfName.F, new PdfNumber(flag)); if (parent != null) { put(PdfName.PARENT, parent.indirectReference()); } if (destination != null && destination.hasPage()) { put(PdfName.DEST, destination); } if (action != null) put(PdfName.A, action); if (count != 0) { put(PdfName.COUNT, new PdfNumber(count)); } super.toPdf(writer, os); } /** * Adds a kid to the outline * @param outline */ public void addKid(PdfOutline outline) { kids.add(outline); } /** * Returns the kids of this outline * @return an ArrayList with PdfOutlines */ public ArrayList getKids() { return kids; } /** * Sets the kids of this outline * @param kids */ public void setKids(ArrayList kids) { this.kids = kids; } /** Getter for property tag. * @return Value of property tag. */ public String getTag() { return tag; } /** Setter for property tag. * @param tag New value of property tag. */ public void setTag(String tag) { this.tag = tag; } /** * Gets the title of this outline * @return the title as a String */ public String getTitle() { PdfString title = (PdfString)get(PdfName.TITLE); return title.toString(); } /** * Sets the title of this outline * @param title */ public void setTitle(String title) { put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); } /** Getter for property open. * @return Value of property open. */ public boolean isOpen() { return open; } /** Setter for property open. * @param open New value of property open. */ public void setOpen(boolean open) { this.open = open; } /** Getter for property color. * @return Value of property color. * */ public Color getColor() { return this.color; } /** Setter for property color. * @param color New value of property color. * */ public void setColor(Color color) { this.color = color; } /** Getter for property style. * @return Value of property style. * */ public int getStyle() { return this.style; } /** Setter for property style. * @param style New value of property style. * */ public void setStyle(int style) { this.style = style; } }src/core/com/lowagie/text/pdf/PdfPCell.java100644 0 0 67300 11224570760 16214 0ustar 0 0 /* * $Id: PdfPCell.java 3992 2009-06-19 12:05:06Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.List; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.events.PdfPCellEventForwarder; /** * A cell in a PdfPTable. */ public class PdfPCell extends Rectangle{ private ColumnText column = new ColumnText(null); /** Vertical alignment of the cell. */ private int verticalAlignment = Element.ALIGN_TOP; /** Left padding of the cell. */ private float paddingLeft = 2; /** Right padding of the cell. */ private float paddingRight = 2; /** Top padding of the cell. */ private float paddingTop = 2; /** Bottom padding of the cell. */ private float paddingBottom = 2; /** Fixed height of the cell. */ private float fixedHeight = 0; /** Minimum height of the cell. */ private float minimumHeight; /** Holds value of property noWrap. */ private boolean noWrap = false; /** Holds value of property table. */ private PdfPTable table; /** Holds value of property colspan. */ private int colspan = 1; /** * Holds value of property rowspan. * @since 2.1.6 */ private int rowspan = 1; /** Holds value of property image. */ private Image image; /** Holds value of property cellEvent. */ private PdfPCellEvent cellEvent; /** Holds value of property useDescender. */ private boolean useDescender; /** Increases padding to include border if true */ private boolean useBorderPadding = false; /** The text in the cell. */ protected Phrase phrase; /** * The rotation of the cell. Possible values are * 0, 90, 180 and 270. */ private int rotation; /** * Constructs an empty PdfPCell. * The default padding is 2. */ public PdfPCell() { super(0, 0, 0, 0); borderWidth = 0.5f; border = BOX; column.setLeading(0, 1); } /** * Constructs a PdfPCell with a Phrase. * The default padding is 2. * * @param phrase the text */ public PdfPCell(Phrase phrase) { super(0, 0, 0, 0); borderWidth = 0.5f; border = BOX; column.addText(this.phrase = phrase); column.setLeading(0, 1); } /** * Constructs a PdfPCell with an Image. * The default padding is 0. * * @param image the Image */ public PdfPCell(Image image) { this(image, false); } /** * Constructs a PdfPCell with an Image. * The default padding is 0.25 for a border width of 0.5. * * @param image the Image * @param fit true to fit the image to the cell */ public PdfPCell(Image image, boolean fit) { super(0, 0, 0, 0); borderWidth = 0.5f; border = BOX; if (fit) { this.image = image; column.setLeading(0, 1); setPadding(borderWidth / 2); } else { column.addText(this.phrase = new Phrase(new Chunk(image, 0, 0))); column.setLeading(0, 1); setPadding(0); } } /** * Constructs a PdfPCell with a PdfPtable. * This constructor allows nested tables. * The default padding is 0. * * @param table The PdfPTable */ public PdfPCell(PdfPTable table) { this(table, null); } /** * Constructs a PdfPCell with a PdfPtable. * This constructor allows nested tables. * * @param table The PdfPTable * @param style The style to apply to the cell (you could use getDefaultCell()) * @since 2.1.0 */ public PdfPCell(PdfPTable table, PdfPCell style) { super(0, 0, 0, 0); borderWidth = 0.5f; border = BOX; column.setLeading(0, 1); this.table = table; table.setWidthPercentage(100); table.setExtendLastRow(true); column.addElement(table); if (style != null) { cloneNonPositionParameters(style); verticalAlignment = style.verticalAlignment; paddingLeft = style.paddingLeft; paddingRight = style.paddingRight; paddingTop = style.paddingTop; paddingBottom = style.paddingBottom; colspan = style.colspan; rowspan = style.rowspan; cellEvent = style.cellEvent; useDescender = style.useDescender; useBorderPadding = style.useBorderPadding; rotation = style.rotation; } else setPadding(0); } /** * Constructs a deep copy of a PdfPCell. * * @param cell the PdfPCell to duplicate */ public PdfPCell(PdfPCell cell) { super(cell.llx, cell.lly, cell.urx, cell.ury); cloneNonPositionParameters(cell); verticalAlignment = cell.verticalAlignment; paddingLeft = cell.paddingLeft; paddingRight = cell.paddingRight; paddingTop = cell.paddingTop; paddingBottom = cell.paddingBottom; phrase = cell.phrase; fixedHeight = cell.fixedHeight; minimumHeight = cell.minimumHeight; noWrap = cell.noWrap; colspan = cell.colspan; rowspan = cell.rowspan; if (cell.table != null) table = new PdfPTable(cell.table); image = Image.getInstance(cell.image); cellEvent = cell.cellEvent; useDescender = cell.useDescender; column = ColumnText.duplicate(cell.column); useBorderPadding = cell.useBorderPadding; rotation = cell.rotation; } /** * Adds an iText element to the cell. * * @param element */ public void addElement(Element element) { if (table != null) { table = null; column.setText(null); } column.addElement(element); } /** * Gets the Phrase from this cell. * * @return the Phrase */ public Phrase getPhrase() { return phrase; } /** * Sets the Phrase for this cell. * * @param phrase the Phrase */ public void setPhrase(Phrase phrase) { table = null; image = null; column.setText(this.phrase = phrase); } /** * Gets the horizontal alignment for the cell. * * @return the horizontal alignment for the cell */ public int getHorizontalAlignment() { return column.getAlignment(); } /** * Sets the horizontal alignment for the cell. It could be * Element.ALIGN_CENTER for example. * * @param horizontalAlignment The horizontal alignment */ public void setHorizontalAlignment(int horizontalAlignment) { column.setAlignment(horizontalAlignment); } /** * Gets the vertical alignment for the cell. * * @return the vertical alignment for the cell */ public int getVerticalAlignment() { return verticalAlignment; } /** * Sets the vertical alignment for the cell. It could be * Element.ALIGN_MIDDLE for example. * * @param verticalAlignment The vertical alignment */ public void setVerticalAlignment(int verticalAlignment) { if (table != null) table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); this.verticalAlignment = verticalAlignment; } /** * Gets the effective left padding. * This will include the left border width if * {@link #isUseBorderPadding()} is true. * * @return effective value of property paddingLeft. */ public float getEffectivePaddingLeft() { if (isUseBorderPadding()) { float border = getBorderWidthLeft() / (isUseVariableBorders() ? 1f : 2f); return paddingLeft + border; } return paddingLeft; } /** * @return Value of property paddingLeft. */ public float getPaddingLeft() { return paddingLeft; } /** * Setter for property paddingLeft. * * @param paddingLeft New value of property paddingLeft. */ public void setPaddingLeft(float paddingLeft) { this.paddingLeft = paddingLeft; } /** * Gets the effective right padding. This will include * the right border width if {@link #isUseBorderPadding()} is true. * * @return effective value of property paddingRight. */ public float getEffectivePaddingRight() { if (isUseBorderPadding()) { float border = getBorderWidthRight() / (isUseVariableBorders() ? 1f : 2f); return paddingRight + border; } return paddingRight; } /** * Getter for property paddingRight. * * @return Value of property paddingRight. */ public float getPaddingRight() { return paddingRight; } /** * Setter for property paddingRight. * * @param paddingRight New value of property paddingRight. */ public void setPaddingRight(float paddingRight) { this.paddingRight = paddingRight; } /** * Gets the effective top padding. This will include * the top border width if {@link #isUseBorderPadding()} is true. * * @return effective value of property paddingTop. */ public float getEffectivePaddingTop() { if (isUseBorderPadding()) { float border = getBorderWidthTop()/(isUseVariableBorders()?1f:2f); return paddingTop + border; } return paddingTop; } /** * Getter for property paddingTop. * * @return Value of property paddingTop. */ public float getPaddingTop() { return paddingTop; } /** * Setter for property paddingTop. * * @param paddingTop New value of property paddingTop. */ public void setPaddingTop(float paddingTop) { this.paddingTop = paddingTop; } /** * Gets the effective bottom padding. * This will include the bottom border width if * {@link #isUseBorderPadding()} is true. * * @return effective value of property paddingBottom. */ public float getEffectivePaddingBottom() { if (isUseBorderPadding()) { float border = getBorderWidthBottom()/(isUseVariableBorders()?1f:2f); return paddingBottom + border; } return paddingBottom; } /** * Getter for property paddingBottom. * * @return Value of property paddingBottom. */ public float getPaddingBottom() { return paddingBottom; } /** * Setter for property paddingBottom. * * @param paddingBottom New value of property paddingBottom. */ public void setPaddingBottom(float paddingBottom) { this.paddingBottom = paddingBottom; } /** * Sets the padding of the contents in the cell (space between content and border). * * @param padding */ public void setPadding(float padding) { paddingBottom = padding; paddingTop = padding; paddingLeft = padding; paddingRight = padding; } /** * If true, then effective padding will include border widths * * @return true if effective padding includes border widths */ public boolean isUseBorderPadding() { return useBorderPadding; } /** * Adjusts effective padding to include border widths. * * @param use adjust effective padding if true */ public void setUseBorderPadding(boolean use) { useBorderPadding = use; } /** * Sets the leading fixed and variable. * The resultant leading will be: * fixedLeading+multipliedLeading*maxFontSize * where maxFontSize is the size of the biggest font in the line. * * @param fixedLeading the fixed leading * @param multipliedLeading the variable leading */ public void setLeading(float fixedLeading, float multipliedLeading) { column.setLeading(fixedLeading, multipliedLeading); } /** * Gets the fixed leading. * * @return the leading */ public float getLeading() { return column.getLeading(); } /** * Gets the variable leading. * * @return the leading */ public float getMultipliedLeading() { return column.getMultipliedLeading(); } /** * Sets the first paragraph line indent. * * @param indent the indent */ public void setIndent(float indent) { column.setIndent(indent); } /** * Gets the first paragraph line indent. * * @return the indent */ public float getIndent() { return column.getIndent(); } /** * Gets the extra space between paragraphs. * * @return the extra space between paragraphs */ public float getExtraParagraphSpace() { return column.getExtraParagraphSpace(); } /** * Sets the extra space between paragraphs. * * @param extraParagraphSpace the extra space between paragraphs */ public void setExtraParagraphSpace(float extraParagraphSpace) { column.setExtraParagraphSpace(extraParagraphSpace); } /** * Set a fixed height for the cell. * This will automatically unset minimumHeight, if set. * * @param fixedHeight New value of property fixedHeight. */ public void setFixedHeight(float fixedHeight) { this.fixedHeight = fixedHeight; minimumHeight = 0; } /** * Get the fixed height of the cell. * * @return Value of property fixedHeight. */ public float getFixedHeight() { return fixedHeight; } /** * Tells you whether the cell has a fixed height. * * @return true is a fixed height was set. * @since 2.1.5 */ public boolean hasFixedHeight() { return getFixedHeight() > 0; } /** * Set a minimum height for the cell. * This will automatically unset fixedHeight, if set. * * @param minimumHeight New value of property minimumHeight. */ public void setMinimumHeight(float minimumHeight) { this.minimumHeight = minimumHeight; fixedHeight = 0; } /** * Get the minimum height of the cell. * * @return Value of property minimumHeight. */ public float getMinimumHeight() { return minimumHeight; } /** * Tells you whether the cell has a minimum height. * * @return true if a minimum height was set. * @since 2.1.5 */ public boolean hasMinimumHeight() { return getMinimumHeight() > 0; } /** * Getter for property noWrap. * * @return Value of property noWrap. */ public boolean isNoWrap() { return noWrap; } /** * Setter for property noWrap. * * @param noWrap New value of property noWrap. */ public void setNoWrap(boolean noWrap) { this.noWrap = noWrap; } /** * Getter for property table. * * @return Value of property table. * @since 2.x */ public PdfPTable getTable() { return table; } void setTable(PdfPTable table) { this.table = table; column.setText(null); image = null; if (table != null) { table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); column.addElement(table); table.setWidthPercentage(100); } } /** * Getter for property colspan. * * @return Value of property colspan. */ public int getColspan() { return colspan; } /** * Setter for property colspan. * * @param colspan New value of property colspan. */ public void setColspan(int colspan) { this.colspan = colspan; } /** * Getter for property rowspan. * * @return Value of property rowspan. * @since 2.1.6 */ public int getRowspan() { return rowspan; } /** * Setter for property rowspan. * * @param rowspan New value of property rowspan. * @since 2.1.6 */ public void setRowspan(int rowspan) { this.rowspan = rowspan; } /** * Sets the following paragraph lines indent. * * @param indent the indent */ public void setFollowingIndent(float indent) { column.setFollowingIndent(indent); } /** * Gets the following paragraph lines indent. * * @return the indent */ public float getFollowingIndent() { return column.getFollowingIndent(); } /** * Sets the right paragraph lines indent. * * @param indent the indent */ public void setRightIndent(float indent) { column.setRightIndent(indent); } /** * Gets the right paragraph lines indent. * * @return the indent */ public float getRightIndent() { return column.getRightIndent(); } /** * Gets the space/character extra spacing ratio for fully justified text. * * @return the space/character extra spacing ratio */ public float getSpaceCharRatio() { return column.getSpaceCharRatio(); } /** Sets the ratio between the extra word spacing and the * extra character spacing when the text is fully justified. * Extra word spacing will grow spaceCharRatio times more * than extra character spacing. * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the * extra character spacing will be zero. * * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing */ public void setSpaceCharRatio(float spaceCharRatio) { column.setSpaceCharRatio(spaceCharRatio); } /** * Sets the run direction of the text content in the cell. * May be either of: * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. * @param runDirection */ public void setRunDirection(int runDirection) { column.setRunDirection(runDirection); } /** * Gets the run direction of the text content in the cell * * @return One of the following values: * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. */ public int getRunDirection() { return column.getRunDirection(); } /** * Getter for property image. * * @return Value of property image. */ public Image getImage() { return image; } /** * Setter for property image. * * @param image New value of property image. */ public void setImage(Image image) { column.setText(null); table = null; this.image = image; } /** * Gets the cell event for this cell. * * @return the cell event */ public PdfPCellEvent getCellEvent() { return cellEvent; } /** * Sets the cell event for this cell. * * @param cellEvent the cell event */ public void setCellEvent(PdfPCellEvent cellEvent) { if (cellEvent == null) this.cellEvent = null; else if (this.cellEvent == null) this.cellEvent = cellEvent; else if (this.cellEvent instanceof PdfPCellEventForwarder) ((PdfPCellEventForwarder)this.cellEvent).addCellEvent(cellEvent); else { PdfPCellEventForwarder forward = new PdfPCellEventForwarder(); forward.addCellEvent(this.cellEvent); forward.addCellEvent(cellEvent); this.cellEvent = forward; } } /** * Gets the arabic shaping options. * * @return the arabic shaping options */ public int getArabicOptions() { return column.getArabicOptions(); } /** * Sets the arabic shaping options. * The option can be AR_NOVOWEL, AR_COMPOSEDTASHKEEL and AR_LIG. * * @param arabicOptions the arabic shaping options */ public void setArabicOptions(int arabicOptions) { column.setArabicOptions(arabicOptions); } /** * Gets state of first line height based on max ascender * * @return true if an ascender is to be used. */ public boolean isUseAscender() { return column.isUseAscender(); } /** * Enables/ Disables adjustment of first line height based on max ascender. * * @param useAscender adjust height if true */ public void setUseAscender(boolean useAscender) { column.setUseAscender(useAscender); } /** * Getter for property useDescender. * * @return Value of property useDescender. */ public boolean isUseDescender() { return useDescender; } /** * Setter for property useDescender. * * @param useDescender New value of property useDescender. */ public void setUseDescender(boolean useDescender) { this.useDescender = useDescender; } /** * Gets the ColumnText with the content of the cell. * * @return a columntext object */ public ColumnText getColumn() { return column; } /** * Returns the list of composite elements of the column. * * @return a List object. * @since 2.1.1 */ public List getCompositeElements() { return getColumn().compositeElements; } /** * Sets the columntext in the cell. * * @param column */ public void setColumn(ColumnText column) { this.column = column; } /** * Gets the rotation of the cell. * * @return the rotation of the cell. */ public int getRotation() { return rotation; } /** * Sets the rotation of the cell. * Possible values are 0, 90, 180 and 270. * * @param rotation the rotation of the cell */ public void setRotation(int rotation) { rotation %= 360; if (rotation < 0) rotation += 360; if ((rotation % 90) != 0) throw new IllegalArgumentException("Rotation must be a multiple of 90."); this.rotation = rotation; } /** * Consumes part of the content of the cell. * @param height the hight of the part that has to be consumed * @since 2.1.6 */ void consumeHeight(float height) { float rightLimit = getRight() - getEffectivePaddingRight(); float leftLimit = getLeft() + getEffectivePaddingLeft(); float bry = height - getEffectivePaddingTop() - getEffectivePaddingBottom(); if (getRotation() != 90 && getRotation() != 270) { column.setSimpleColumn(leftLimit, bry + 0.001f, rightLimit, 0); } else { column.setSimpleColumn(0, leftLimit, bry + 0.001f, rightLimit); } try { column.go(true); } catch (DocumentException e) { // do nothing } } /** * Returns the height of the cell. * @return the height of the cell * @since 3.0.0 */ public float getMaxHeight() { boolean pivoted = (getRotation() == 90 || getRotation() == 270); Image img = getImage(); if (img != null) { img.scalePercent(100); float refWidth = pivoted ? img.getScaledHeight() : img.getScaledWidth(); float scale = (getRight() - getEffectivePaddingRight() - getEffectivePaddingLeft() - getLeft()) / refWidth; img.scalePercent(scale * 100); float refHeight = pivoted ? img.getScaledWidth() : img.getScaledHeight(); setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - refHeight); } else { if (pivoted && hasFixedHeight()) setBottom(getTop() - getFixedHeight()); else { ColumnText ct = ColumnText.duplicate(getColumn()); float right, top, left, bottom; if (pivoted) { right = PdfPRow.RIGHT_LIMIT; top = getRight() - getEffectivePaddingRight(); left = 0; bottom = getLeft() + getEffectivePaddingLeft(); } else { right = isNoWrap() ? PdfPRow.RIGHT_LIMIT : getRight() - getEffectivePaddingRight(); top = getTop() - getEffectivePaddingTop(); left = getLeft() + getEffectivePaddingLeft(); bottom = hasFixedHeight() ? top + getEffectivePaddingBottom() - getFixedHeight() : PdfPRow.BOTTOM_LIMIT; } PdfPRow.setColumn(ct, left, bottom, right, top); try { ct.go(true); } catch (DocumentException e) { throw new ExceptionConverter(e); } if (pivoted) setBottom(getTop() - getEffectivePaddingTop() - getEffectivePaddingBottom() - ct.getFilledWidth()); else { float yLine = ct.getYLine(); if (isUseDescender()) yLine += ct.getDescender(); setBottom(yLine - getEffectivePaddingBottom()); } } } float height = getHeight(); if (height < getFixedHeight()) height = getFixedHeight(); else if (height < getMinimumHeight()) height = getMinimumHeight(); return height; } }src/core/com/lowagie/text/pdf/PdfPCellEvent.java100644 0 0 7113 11000354131 17152 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.Rectangle; /** An event called for a single cell. * @author Paulo Soares (psoares@consiste.pt) */ public interface PdfPCellEvent { /** This method is called at the end of the cell rendering. The text or graphics are added to * one of the 4 PdfContentByte contained in * canvases.
* The indexes to canvases are:

*

    *
  • PdfPTable.BASECANVAS - the original PdfContentByte. Anything placed here * will be under the cell. *
  • PdfPTable.BACKGROUNDCANVAS - the layer where the background goes to. *
  • PdfPTable.LINECANVAS - the layer where the lines go to. *
  • PdfPTable.TEXTCANVAS - the layer where the text go to. Anything placed here * will be over the cell. *
* The layers are placed in sequence on top of each other. *

* @param cell the cell * @param position the coordinates of the cell * @param canvases an array of PdfContentByte */ public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases); } src/core/com/lowagie/text/pdf/PdfPKCS7.java100644 0 0 204416 11224570760 16065 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyStore; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Signature; import java.security.SignatureException; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Enumeration; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.jce.provider.X509CRLParser; import org.bouncycastle.jce.provider.X509CertParser; import com.lowagie.text.ExceptionConverter; import java.security.cert.CertificateParsingException; import java.util.Date; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.ocsp.BasicOCSPResp; import org.bouncycastle.ocsp.CertificateID; import org.bouncycastle.ocsp.SingleResp; import org.bouncycastle.tsp.TimeStampToken; /** * This class does all the processing related to signing and verifying a PKCS#7 * signature. *

* It's based in code found at org.bouncycastle. */ public class PdfPKCS7 { private byte sigAttr[]; private byte digestAttr[]; private int version, signerversion; private Set digestalgos; private Collection certs, crls, signCerts; private X509Certificate signCert; private byte[] digest; private MessageDigest messageDigest; private String digestAlgorithm, digestEncryptionAlgorithm; private Signature sig; private transient PrivateKey privKey; private byte RSAdata[]; private boolean verified; private boolean verifyResult; private byte externalDigest[]; private byte externalRSAdata[]; private String provider; private static final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1"; private static final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2"; private static final String ID_RSA = "1.2.840.113549.1.1.1"; private static final String ID_DSA = "1.2.840.10040.4.1"; private static final String ID_CONTENT_TYPE = "1.2.840.113549.1.9.3"; private static final String ID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4"; private static final String ID_SIGNING_TIME = "1.2.840.113549.1.9.5"; private static final String ID_ADBE_REVOCATION = "1.2.840.113583.1.1.8"; /** * Holds value of property reason. */ private String reason; /** * Holds value of property location. */ private String location; /** * Holds value of property signDate. */ private Calendar signDate; /** * Holds value of property signName. */ private String signName; private TimeStampToken timeStampToken; private static final HashMap digestNames = new HashMap(); private static final HashMap algorithmNames = new HashMap(); private static final HashMap allowedDigests = new HashMap(); static { digestNames.put("1.2.840.113549.2.5", "MD5"); digestNames.put("1.2.840.113549.2.2", "MD2"); digestNames.put("1.3.14.3.2.26", "SHA1"); digestNames.put("2.16.840.1.101.3.4.2.4", "SHA224"); digestNames.put("2.16.840.1.101.3.4.2.1", "SHA256"); digestNames.put("2.16.840.1.101.3.4.2.2", "SHA384"); digestNames.put("2.16.840.1.101.3.4.2.3", "SHA512"); digestNames.put("1.3.36.3.2.2", "RIPEMD128"); digestNames.put("1.3.36.3.2.1", "RIPEMD160"); digestNames.put("1.3.36.3.2.3", "RIPEMD256"); digestNames.put("1.2.840.113549.1.1.4", "MD5"); digestNames.put("1.2.840.113549.1.1.2", "MD2"); digestNames.put("1.2.840.113549.1.1.5", "SHA1"); digestNames.put("1.2.840.113549.1.1.14", "SHA224"); digestNames.put("1.2.840.113549.1.1.11", "SHA256"); digestNames.put("1.2.840.113549.1.1.12", "SHA384"); digestNames.put("1.2.840.113549.1.1.13", "SHA512"); digestNames.put("1.2.840.113549.2.5", "MD5"); digestNames.put("1.2.840.113549.2.2", "MD2"); digestNames.put("1.2.840.10040.4.3", "SHA1"); digestNames.put("2.16.840.1.101.3.4.3.1", "SHA224"); digestNames.put("2.16.840.1.101.3.4.3.2", "SHA256"); digestNames.put("2.16.840.1.101.3.4.3.3", "SHA384"); digestNames.put("2.16.840.1.101.3.4.3.4", "SHA512"); digestNames.put("1.3.36.3.3.1.3", "RIPEMD128"); digestNames.put("1.3.36.3.3.1.2", "RIPEMD160"); digestNames.put("1.3.36.3.3.1.4", "RIPEMD256"); algorithmNames.put("1.2.840.113549.1.1.1", "RSA"); algorithmNames.put("1.2.840.10040.4.1", "DSA"); algorithmNames.put("1.2.840.113549.1.1.2", "RSA"); algorithmNames.put("1.2.840.113549.1.1.4", "RSA"); algorithmNames.put("1.2.840.113549.1.1.5", "RSA"); algorithmNames.put("1.2.840.113549.1.1.14", "RSA"); algorithmNames.put("1.2.840.113549.1.1.11", "RSA"); algorithmNames.put("1.2.840.113549.1.1.12", "RSA"); algorithmNames.put("1.2.840.113549.1.1.13", "RSA"); algorithmNames.put("1.2.840.10040.4.3", "DSA"); algorithmNames.put("2.16.840.1.101.3.4.3.1", "DSA"); algorithmNames.put("2.16.840.1.101.3.4.3.2", "DSA"); algorithmNames.put("1.3.36.3.3.1.3", "RSA"); algorithmNames.put("1.3.36.3.3.1.2", "RSA"); algorithmNames.put("1.3.36.3.3.1.4", "RSA"); allowedDigests.put("MD5", "1.2.840.113549.2.5"); allowedDigests.put("MD2", "1.2.840.113549.2.2"); allowedDigests.put("SHA1", "1.3.14.3.2.26"); allowedDigests.put("SHA224", "2.16.840.1.101.3.4.2.4"); allowedDigests.put("SHA256", "2.16.840.1.101.3.4.2.1"); allowedDigests.put("SHA384", "2.16.840.1.101.3.4.2.2"); allowedDigests.put("SHA512", "2.16.840.1.101.3.4.2.3"); allowedDigests.put("MD-5", "1.2.840.113549.2.5"); allowedDigests.put("MD-2", "1.2.840.113549.2.2"); allowedDigests.put("SHA-1", "1.3.14.3.2.26"); allowedDigests.put("SHA-224", "2.16.840.1.101.3.4.2.4"); allowedDigests.put("SHA-256", "2.16.840.1.101.3.4.2.1"); allowedDigests.put("SHA-384", "2.16.840.1.101.3.4.2.2"); allowedDigests.put("SHA-512", "2.16.840.1.101.3.4.2.3"); allowedDigests.put("RIPEMD128", "1.3.36.3.2.2"); allowedDigests.put("RIPEMD-128", "1.3.36.3.2.2"); allowedDigests.put("RIPEMD160", "1.3.36.3.2.1"); allowedDigests.put("RIPEMD-160", "1.3.36.3.2.1"); allowedDigests.put("RIPEMD256", "1.3.36.3.2.3"); allowedDigests.put("RIPEMD-256", "1.3.36.3.2.3"); } /** * Gets the digest name for a certain id * @param oid an id (for instance "1.2.840.113549.2.5") * @return a digest name (for instance "MD5") * @since 2.1.6 */ public static String getDigest(String oid) { String ret = (String)digestNames.get(oid); if (ret == null) return oid; else return ret; } /** * Gets the algorithm name for a certain id. * @param oid an id (for instance "1.2.840.113549.1.1.1") * @return an algorithm name (for instance "RSA") * @since 2.1.6 */ public static String getAlgorithm(String oid) { String ret = (String)algorithmNames.get(oid); if (ret == null) return oid; else return ret; } /** * Gets the timestamp token if there is one. * @return the timestamp token or null * @since 2.1.6 */ public TimeStampToken getTimeStampToken() { return timeStampToken; } /** * Gets the timestamp date * @return a date * @since 2.1.6 */ public Calendar getTimeStampDate() { if (timeStampToken == null) return null; Calendar cal = new GregorianCalendar(); Date date = timeStampToken.getTimeStampInfo().getGenTime(); cal.setTime(date); return cal; } /** * Verifies a signature using the sub-filter adbe.x509.rsa_sha1. * @param contentsKey the /Contents key * @param certsKey the /Cert key * @param provider the provider or null for the default provider */ public PdfPKCS7(byte[] contentsKey, byte[] certsKey, String provider) { try { this.provider = provider; X509CertParser cr = new X509CertParser(); cr.engineInit(new ByteArrayInputStream(certsKey)); certs = cr.engineReadAll(); signCerts = certs; signCert = (X509Certificate)certs.iterator().next(); crls = new ArrayList(); ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); digest = ((DEROctetString)in.readObject()).getOctets(); if (provider == null) sig = Signature.getInstance("SHA1withRSA"); else sig = Signature.getInstance("SHA1withRSA", provider); sig.initVerify(signCert.getPublicKey()); } catch (Exception e) { throw new ExceptionConverter(e); } } private BasicOCSPResp basicResp; /** * Gets the OCSP basic response if there is one. * @return the OCSP basic response or null * @since 2.1.6 */ public BasicOCSPResp getOcsp() { return basicResp; } private void findOcsp(ASN1Sequence seq) throws IOException { basicResp = null; boolean ret = false; while (true) { if ((seq.getObjectAt(0) instanceof DERObjectIdentifier) && ((DERObjectIdentifier)seq.getObjectAt(0)).getId().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic.getId())) { break; } ret = true; for (int k = 0; k < seq.size(); ++k) { if (seq.getObjectAt(k) instanceof ASN1Sequence) { seq = (ASN1Sequence)seq.getObjectAt(0); ret = false; break; } if (seq.getObjectAt(k) instanceof ASN1TaggedObject) { ASN1TaggedObject tag = (ASN1TaggedObject)seq.getObjectAt(k); if (tag.getObject() instanceof ASN1Sequence) { seq = (ASN1Sequence)tag.getObject(); ret = false; break; } else return; } } if (ret) return; } DEROctetString os = (DEROctetString)seq.getObjectAt(1); ASN1InputStream inp = new ASN1InputStream(os.getOctets()); BasicOCSPResponse resp = BasicOCSPResponse.getInstance(inp.readObject()); basicResp = new BasicOCSPResp(resp); } /** * Verifies a signature using the sub-filter adbe.pkcs7.detached or * adbe.pkcs7.sha1. * @param contentsKey the /Contents key * @param provider the provider or null for the default provider */ public PdfPKCS7(byte[] contentsKey, String provider) { try { this.provider = provider; ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); // // Basic checks to make sure it's a PKCS#7 SignedData Object // DERObject pkcs; try { pkcs = din.readObject(); } catch (IOException e) { throw new IllegalArgumentException("can't decode PKCS7SignedData object"); } if (!(pkcs instanceof ASN1Sequence)) { throw new IllegalArgumentException("Not a valid PKCS#7 object - not a sequence"); } ASN1Sequence signedData = (ASN1Sequence)pkcs; DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); if (!objId.getId().equals(ID_PKCS7_SIGNED_DATA)) throw new IllegalArgumentException("Not a valid PKCS#7 object - not signed data"); ASN1Sequence content = (ASN1Sequence)((DERTaggedObject)signedData.getObjectAt(1)).getObject(); // the positions that we care are: // 0 - version // 1 - digestAlgorithms // 2 - possible ID_PKCS7_DATA // (the certificates and crls are taken out by other means) // last - signerInfos // the version version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); // the digestAlgorithms digestalgos = new HashSet(); Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects(); while (e.hasMoreElements()) { ASN1Sequence s = (ASN1Sequence)e.nextElement(); DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); digestalgos.add(o.getId()); } // the certificates and crls X509CertParser cr = new X509CertParser(); cr.engineInit(new ByteArrayInputStream(contentsKey)); certs = cr.engineReadAll(); X509CRLParser cl = new X509CRLParser(); cl.engineInit(new ByteArrayInputStream(contentsKey)); crls = cl.engineReadAll(); // the possible ID_PKCS7_DATA ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2); if (rsaData.size() > 1) { DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject(); RSAdata = rsaDataContent.getOctets(); } // the signerInfos int next = 3; while (content.getObjectAt(next) instanceof DERTaggedObject) ++next; ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next); if (signerInfos.size() != 1) throw new IllegalArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0); // the positions that we care are // 0 - version // 1 - the signing certificate serial number // 2 - the digest algorithm // 3 or 4 - digestEncryptionAlgorithm // 4 or 5 - encryptedDigest signerversion = ((DERInteger)signerInfo.getObjectAt(0)).getValue().intValue(); // Get the signing certificate ASN1Sequence issuerAndSerialNumber = (ASN1Sequence)signerInfo.getObjectAt(1); BigInteger serialNumber = ((DERInteger)issuerAndSerialNumber.getObjectAt(1)).getValue(); for (Iterator i = certs.iterator(); i.hasNext();) { X509Certificate cert = (X509Certificate)i.next(); if (serialNumber.equals(cert.getSerialNumber())) { signCert = cert; break; } } if (signCert == null) { throw new IllegalArgumentException("Can't find signing certificate with serial " + serialNumber.toString(16)); } signCertificateChain(); digestAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId(); next = 3; if (signerInfo.getObjectAt(next) instanceof ASN1TaggedObject) { ASN1TaggedObject tagsig = (ASN1TaggedObject)signerInfo.getObjectAt(next); ASN1Set sseq = ASN1Set.getInstance(tagsig, false); sigAttr = sseq.getEncoded(ASN1Encodable.DER); for (int k = 0; k < sseq.size(); ++k) { ASN1Sequence seq2 = (ASN1Sequence)sseq.getObjectAt(k); if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { ASN1Set set = (ASN1Set)seq2.getObjectAt(1); digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); } else if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOCATION)) { ASN1Set setout = (ASN1Set)seq2.getObjectAt(1); ASN1Sequence seqout = (ASN1Sequence)setout.getObjectAt(0); for (int j = 0; j < seqout.size(); ++j) { ASN1TaggedObject tg = (ASN1TaggedObject)seqout.getObjectAt(j); if (tg.getTagNo() != 1) continue; ASN1Sequence seqin = (ASN1Sequence)tg.getObject(); findOcsp(seqin); } } } if (digestAttr == null) throw new IllegalArgumentException("Authenticated attribute is missing the digest."); ++next; } digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); digest = ((DEROctetString)signerInfo.getObjectAt(next++)).getOctets(); if (next < signerInfo.size() && (signerInfo.getObjectAt(next) instanceof DERTaggedObject)) { DERTaggedObject taggedObject = (DERTaggedObject) signerInfo.getObjectAt(next); ASN1Set unat = ASN1Set.getInstance(taggedObject, false); AttributeTable attble = new AttributeTable(unat); Attribute ts = attble.get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken); if (ts != null) { ASN1Set attributeValues = ts.getAttrValues(); ASN1Sequence tokenSequence = ASN1Sequence.getInstance(attributeValues.getObjectAt(0)); ContentInfo contentInfo = new ContentInfo(tokenSequence); this.timeStampToken = new TimeStampToken(contentInfo); } } if (RSAdata != null || digestAttr != null) { if (provider == null || provider.startsWith("SunPKCS11")) messageDigest = MessageDigest.getInstance(getHashAlgorithm()); else messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); } if (provider == null) sig = Signature.getInstance(getDigestAlgorithm()); else sig = Signature.getInstance(getDigestAlgorithm(), provider); sig.initVerify(signCert.getPublicKey()); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Generates a signature. * @param privKey the private key * @param certChain the certificate chain * @param crlList the certificate revocation list * @param hashAlgorithm the hash algorithm * @param provider the provider or null for the default provider * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 * @throws InvalidKeyException on error * @throws NoSuchProviderException on error * @throws NoSuchAlgorithmException on error */ public PdfPKCS7(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, String hashAlgorithm, String provider, boolean hasRSAdata) throws InvalidKeyException, NoSuchProviderException, NoSuchAlgorithmException { this.privKey = privKey; this.provider = provider; digestAlgorithm = (String)allowedDigests.get(hashAlgorithm.toUpperCase()); if (digestAlgorithm == null) throw new NoSuchAlgorithmException("Unknown Hash Algorithm "+hashAlgorithm); version = signerversion = 1; certs = new ArrayList(); crls = new ArrayList(); digestalgos = new HashSet(); digestalgos.add(digestAlgorithm); // // Copy in the certificates and crls used to sign the private key. // signCert = (X509Certificate)certChain[0]; for (int i = 0;i < certChain.length;i++) { certs.add(certChain[i]); } if (crlList != null) { for (int i = 0;i < crlList.length;i++) { crls.add(crlList[i]); } } if (privKey != null) { // // Now we have private key, find out what the digestEncryptionAlgorithm is. // digestEncryptionAlgorithm = privKey.getAlgorithm(); if (digestEncryptionAlgorithm.equals("RSA")) { digestEncryptionAlgorithm = ID_RSA; } else if (digestEncryptionAlgorithm.equals("DSA")) { digestEncryptionAlgorithm = ID_DSA; } else { throw new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm); } } if (hasRSAdata) { RSAdata = new byte[0]; if (provider == null || provider.startsWith("SunPKCS11")) messageDigest = MessageDigest.getInstance(getHashAlgorithm()); else messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); } if (privKey != null) { if (provider == null) sig = Signature.getInstance(getDigestAlgorithm()); else sig = Signature.getInstance(getDigestAlgorithm(), provider); sig.initSign(privKey); } } /** * Update the digest with the specified bytes. This method is used both for signing and verifying * @param buf the data buffer * @param off the offset in the data buffer * @param len the data length * @throws SignatureException on error */ public void update(byte[] buf, int off, int len) throws SignatureException { if (RSAdata != null || digestAttr != null) messageDigest.update(buf, off, len); else sig.update(buf, off, len); } /** * Verify the digest. * @throws SignatureException on error * @return true if the signature checks out, false otherwise */ public boolean verify() throws SignatureException { if (verified) return verifyResult; if (sigAttr != null) { sig.update(sigAttr); if (RSAdata != null) { byte msd[] = messageDigest.digest(); messageDigest.update(msd); } verifyResult = (Arrays.equals(messageDigest.digest(), digestAttr) && sig.verify(digest)); } else { if (RSAdata != null) sig.update(messageDigest.digest()); verifyResult = sig.verify(digest); } verified = true; return verifyResult; } /** * Checks if the timestamp refers to this document. * @throws java.security.NoSuchAlgorithmException on error * @return true if it checks false otherwise * @since 2.1.6 */ public boolean verifyTimestampImprint() throws NoSuchAlgorithmException { if (timeStampToken == null) return false; MessageImprint imprint = timeStampToken.getTimeStampInfo().toTSTInfo().getMessageImprint(); byte[] md = MessageDigest.getInstance("SHA-1").digest(digest); byte[] imphashed = imprint.getHashedMessage(); boolean res = Arrays.equals(md, imphashed); return res; } /** * Get all the X.509 certificates associated with this PKCS#7 object in no particular order. * Other certificates, from OCSP for example, will also be included. * @return the X.509 certificates associated with this PKCS#7 object */ public Certificate[] getCertificates() { return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); } /** * Get the X.509 sign certificate chain associated with this PKCS#7 object. * Only the certificates used for the main signature will be returned, with * the signing certificate first. * @return the X.509 certificates associated with this PKCS#7 object * @since 2.1.6 */ public Certificate[] getSignCertificateChain() { return (X509Certificate[])signCerts.toArray(new X509Certificate[signCerts.size()]); } private void signCertificateChain() { ArrayList cc = new ArrayList(); cc.add(signCert); ArrayList oc = new ArrayList(certs); for (int k = 0; k < oc.size(); ++k) { if (signCert.getSerialNumber().equals(((X509Certificate)oc.get(k)).getSerialNumber())) { oc.remove(k); --k; continue; } } boolean found = true; while (found) { X509Certificate v = (X509Certificate)cc.get(cc.size() - 1); found = false; for (int k = 0; k < oc.size(); ++k) { try { if (provider == null) v.verify(((X509Certificate)oc.get(k)).getPublicKey()); else v.verify(((X509Certificate)oc.get(k)).getPublicKey(), provider); found = true; cc.add(oc.get(k)); oc.remove(k); break; } catch (Exception e) { } } } signCerts = cc; } /** * Get the X.509 certificate revocation lists associated with this PKCS#7 object * @return the X.509 certificate revocation lists associated with this PKCS#7 object */ public Collection getCRLs() { return crls; } /** * Get the X.509 certificate actually used to sign the digest. * @return the X.509 certificate actually used to sign the digest */ public X509Certificate getSigningCertificate() { return signCert; } /** * Get the version of the PKCS#7 object. Always 1 * @return the version of the PKCS#7 object. Always 1 */ public int getVersion() { return version; } /** * Get the version of the PKCS#7 "SignerInfo" object. Always 1 * @return the version of the PKCS#7 "SignerInfo" object. Always 1 */ public int getSigningInfoVersion() { return signerversion; } /** * Get the algorithm used to calculate the message digest * @return the algorithm used to calculate the message digest */ public String getDigestAlgorithm() { String dea = getAlgorithm(digestEncryptionAlgorithm); if (dea == null) dea = digestEncryptionAlgorithm; return getHashAlgorithm() + "with" + dea; } /** * Returns the algorithm. * @return the digest algorithm */ public String getHashAlgorithm() { return getDigest(digestAlgorithm); } /** * Loads the default root certificates at <java.home>/lib/security/cacerts * with the default provider. * @return a KeyStore */ public static KeyStore loadCacertsKeyStore() { return loadCacertsKeyStore(null); } /** * Loads the default root certificates at <java.home>/lib/security/cacerts. * @param provider the provider or null for the default provider * @return a KeyStore */ public static KeyStore loadCacertsKeyStore(String provider) { File file = new File(System.getProperty("java.home"), "lib"); file = new File(file, "security"); file = new File(file, "cacerts"); FileInputStream fin = null; try { fin = new FileInputStream(file); KeyStore k; if (provider == null) k = KeyStore.getInstance("JKS"); else k = KeyStore.getInstance("JKS", provider); k.load(fin, null); return k; } catch (Exception e) { throw new ExceptionConverter(e); } finally { try{if (fin != null) {fin.close();}}catch(Exception ex){} } } /** * Verifies a single certificate. * @param cert the certificate to verify * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return a String with the error description or null * if no error */ public static String verifyCertificate(X509Certificate cert, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); if (cert.hasUnsupportedCriticalExtension()) return "Has unsupported critical extension"; try { cert.checkValidity(calendar.getTime()); } catch (Exception e) { return e.getMessage(); } if (crls != null) { for (Iterator it = crls.iterator(); it.hasNext();) { if (((CRL)it.next()).isRevoked(cert)) return "Certificate revoked"; } } return null; } /** * Verifies a certificate chain against a KeyStore. * @param certs the certificate chain * @param keystore the KeyStore * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return null if the certificate chain could be validated or a * Object[]{cert,error} where cert is the * failed certificate and error is the error message */ public static Object[] verifyCertificates(Certificate certs[], KeyStore keystore, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); for (int k = 0; k < certs.length; ++k) { X509Certificate cert = (X509Certificate)certs[k]; String err = verifyCertificate(cert, crls, calendar); if (err != null) return new Object[]{cert, err}; try { for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { try { String alias = (String)aliases.nextElement(); if (!keystore.isCertificateEntry(alias)) continue; X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); if (verifyCertificate(certStoreX509, crls, calendar) != null) continue; try { cert.verify(certStoreX509.getPublicKey()); return null; } catch (Exception e) { continue; } } catch (Exception ex) { } } } catch (Exception e) { } int j; for (j = 0; j < certs.length; ++j) { if (j == k) continue; X509Certificate certNext = (X509Certificate)certs[j]; try { cert.verify(certNext.getPublicKey()); break; } catch (Exception e) { } } if (j == certs.length) return new Object[]{cert, "Cannot be verified against the KeyStore or the certificate chain"}; } return new Object[]{null, "Invalid state. Possible circular certificate chain"}; } /** * Verifies an OCSP response against a KeyStore. * @param ocsp the OCSP response * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found * @since 2.1.6 */ public static boolean verifyOcspCertificates(BasicOCSPResp ocsp, KeyStore keystore, String provider) { if (provider == null) provider = "BC"; try { for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { try { String alias = (String)aliases.nextElement(); if (!keystore.isCertificateEntry(alias)) continue; X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); if (ocsp.verify(certStoreX509.getPublicKey(), provider)) return true; } catch (Exception ex) { } } } catch (Exception e) { } return false; } /** * Verifies a timestamp against a KeyStore. * @param ts the timestamp * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found * @since 2.1.6 */ public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore keystore, String provider) { if (provider == null) provider = "BC"; try { for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { try { String alias = (String)aliases.nextElement(); if (!keystore.isCertificateEntry(alias)) continue; X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); ts.validate(certStoreX509, provider); return true; } catch (Exception ex) { } } } catch (Exception e) { } return false; } /** * Retrieves the OCSP URL from the given certificate. * @param certificate the certificate * @return the URL or null * @throws CertificateParsingException on error * @since 2.1.6 */ public static String getOCSPURL(X509Certificate certificate) throws CertificateParsingException { try { DERObject obj = getExtensionValue(certificate, X509Extensions.AuthorityInfoAccess.getId()); if (obj == null) { return null; } ASN1Sequence AccessDescriptions = (ASN1Sequence) obj; for (int i = 0; i < AccessDescriptions.size(); i++) { ASN1Sequence AccessDescription = (ASN1Sequence) AccessDescriptions.getObjectAt(i); if ( AccessDescription.size() != 2 ) { continue; } else { if ((AccessDescription.getObjectAt(0) instanceof DERObjectIdentifier) && ((DERObjectIdentifier)AccessDescription.getObjectAt(0)).getId().equals("1.3.6.1.5.5.7.48.1")) { String AccessLocation = getStringFromGeneralName((DERObject)AccessDescription.getObjectAt(1)); if ( AccessLocation == null ) { return "" ; } else { return AccessLocation ; } } } } } catch (Exception e) { } return null; } /** * Checks if OCSP revocation refers to the document signing certificate. * @return true if it checks false otherwise * @since 2.1.6 */ public boolean isRevocationValid() { if (basicResp == null) return false; if (signCerts.size() < 2) return false; try { X509Certificate[] cs = (X509Certificate[])getSignCertificateChain(); SingleResp sr = basicResp.getResponses()[0]; CertificateID cid = sr.getCertID(); X509Certificate sigcer = getSigningCertificate(); X509Certificate isscer = cs[1]; CertificateID tis = new CertificateID(CertificateID.HASH_SHA1, isscer, sigcer.getSerialNumber()); return tis.equals(cid); } catch (Exception ex) { } return false; } private static DERObject getExtensionValue(X509Certificate cert, String oid) throws IOException { byte[] bytes = cert.getExtensionValue(oid); if (bytes == null) { return null; } ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes)); ASN1OctetString octs = (ASN1OctetString) aIn.readObject(); aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); return aIn.readObject(); } private static String getStringFromGeneralName(DERObject names) throws IOException { DERTaggedObject taggedObject = (DERTaggedObject) names ; return new String(ASN1OctetString.getInstance(taggedObject, false).getOctets(), "ISO-8859-1"); } /** * Get the "issuer" from the TBSCertificate bytes that are passed in * @param enc a TBSCertificate in a byte array * @return a DERObject */ private static DERObject getIssuer(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); ASN1Sequence seq = (ASN1Sequence)in.readObject(); return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the "subject" from the TBSCertificate bytes that are passed in * @param enc A TBSCertificate in a byte array * @return a DERObject */ private static DERObject getSubject(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); ASN1Sequence seq = (ASN1Sequence)in.readObject(); return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the issuer fields from an X509 Certificate * @param cert an X509Certificate * @return an X509Name */ public static X509Name getIssuerFields(X509Certificate cert) { try { return new X509Name((ASN1Sequence)getIssuer(cert.getTBSCertificate())); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Get the subject fields from an X509 Certificate * @param cert an X509Certificate * @return an X509Name */ public static X509Name getSubjectFields(X509Certificate cert) { try { return new X509Name((ASN1Sequence)getSubject(cert.getTBSCertificate())); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Gets the bytes for the PKCS#1 object. * @return a byte array */ public byte[] getEncodedPKCS1() { try { if (externalDigest != null) digest = externalDigest; else digest = sig.sign(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DEROctetString(digest)); dout.close(); return bOut.toByteArray(); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Sets the digest/signature to an external calculated value. * @param digest the digest. This is the actual signature * @param RSAdata the extra data that goes into the data tag in PKCS#7 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest * is also null. If the digest is not null * then it may be "RSA" or "DSA" */ public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { externalDigest = digest; externalRSAdata = RSAdata; if (digestEncryptionAlgorithm != null) { if (digestEncryptionAlgorithm.equals("RSA")) { this.digestEncryptionAlgorithm = ID_RSA; } else if (digestEncryptionAlgorithm.equals("DSA")) { this.digestEncryptionAlgorithm = ID_DSA; } else throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm)); } } /** * Gets the bytes for the PKCS7SignedData object. * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7() { return getEncodedPKCS7(null, null, null, null); } /** * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set. If either of the parameters is null, none will be used. * @param secondDigest the digest in the authenticatedAttributes * @param signingTime the signing time in the authenticatedAttributes * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime) { return getEncodedPKCS7(secondDigest, signingTime, null, null); } /** * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set, OR a time-stamp-authority client * may be provided. * @param secondDigest the digest in the authenticatedAttributes * @param signingTime the signing time in the authenticatedAttributes * @param tsaClient TSAClient - null or an optional time stamp authority client * @return byte[] the bytes for the PKCS7SignedData object * @since 2.1.6 */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime, TSAClient tsaClient, byte[] ocsp) { try { if (externalDigest != null) { digest = externalDigest; if (RSAdata != null) RSAdata = externalRSAdata; } else if (externalRSAdata != null && RSAdata != null) { RSAdata = externalRSAdata; sig.update(RSAdata); digest = sig.sign(); } else { if (RSAdata != null) { RSAdata = messageDigest.digest(); sig.update(RSAdata); } digest = sig.sign(); } // Create the set of Hash algorithms ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector(); for(Iterator it = digestalgos.iterator(); it.hasNext();) { ASN1EncodableVector algos = new ASN1EncodableVector(); algos.add(new DERObjectIdentifier((String)it.next())); algos.add(DERNull.INSTANCE); digestAlgorithms.add(new DERSequence(algos)); } // Create the contentInfo. ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_PKCS7_DATA)); if (RSAdata != null) v.add(new DERTaggedObject(0, new DEROctetString(RSAdata))); DERSequence contentinfo = new DERSequence(v); // Get all the certificates // v = new ASN1EncodableVector(); for (Iterator i = certs.iterator(); i.hasNext();) { ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate)i.next()).getEncoded())); v.add(tempstream.readObject()); } DERSet dercertificates = new DERSet(v); // Create signerinfo structure. // ASN1EncodableVector signerinfo = new ASN1EncodableVector(); // Add the signerInfo version // signerinfo.add(new DERInteger(signerversion)); v = new ASN1EncodableVector(); v.add(getIssuer(signCert.getTBSCertificate())); v.add(new DERInteger(signCert.getSerialNumber())); signerinfo.add(new DERSequence(v)); // Add the digestAlgorithm v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(digestAlgorithm)); v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // add the authenticated attribute if present if (secondDigest != null && signingTime != null) { signerinfo.add(new DERTaggedObject(false, 0, getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp))); } // Add the digestEncryptionAlgorithm v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(digestEncryptionAlgorithm)); v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // Add the digest signerinfo.add(new DEROctetString(digest)); // When requested, go get and add the timestamp. May throw an exception. // Added by Martin Brunecky, 07/12/2007 folowing Aiken Sam, 2006-11-15 // Sam found Adobe expects time-stamped SHA1-1 of the encrypted digest if (tsaClient != null) { byte[] tsImprint = MessageDigest.getInstance("SHA-1").digest(digest); byte[] tsToken = tsaClient.getTimeStampToken(this, tsImprint); if (tsToken != null) { ASN1EncodableVector unauthAttributes = buildUnauthenticatedAttributes(tsToken); if (unauthAttributes != null) { signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unauthAttributes))); } } } // Finally build the body out of all the components above ASN1EncodableVector body = new ASN1EncodableVector(); body.add(new DERInteger(version)); body.add(new DERSet(digestAlgorithms)); body.add(contentinfo); body.add(new DERTaggedObject(false, 0, dercertificates)); if (!crls.isEmpty()) { v = new ASN1EncodableVector(); for (Iterator i = crls.iterator();i.hasNext();) { ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL)i.next()).getEncoded())); v.add(t.readObject()); } DERSet dercrls = new DERSet(v); body.add(new DERTaggedObject(false, 1, dercrls)); } // Only allow one signerInfo body.add(new DERSet(new DERSequence(signerinfo))); // Now we have the body, wrap it in it's PKCS7Signed shell // and return it // ASN1EncodableVector whole = new ASN1EncodableVector(); whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA)); whole.add(new DERTaggedObject(0, new DERSequence(body))); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DERSequence(whole)); dout.close(); return bOut.toByteArray(); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Added by Aiken Sam, 2006-11-15, modifed by Martin Brunecky 07/12/2007 * to start with the timeStampToken (signedData 1.2.840.113549.1.7.2). * Token is the TSA response without response status, which is usually * handled by the (vendor supplied) TSA request/response interface). * @param timeStampToken byte[] - time stamp token, DER encoded signedData * @return ASN1EncodableVector * @throws IOException */ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { if (timeStampToken == null) return null; // @todo: move this together with the rest of the defintions String ID_TIME_STAMP_TOKEN = "1.2.840.113549.1.9.16.2.14"; // RFC 3161 id-aa-timeStampToken ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(timeStampToken)); ASN1EncodableVector unauthAttributes = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_TIME_STAMP_TOKEN)); // id-aa-timeStampToken ASN1Sequence seq = (ASN1Sequence) tempstream.readObject(); v.add(new DERSet(seq)); unauthAttributes.add(new DERSequence(v)); return unauthAttributes; } /** * When using authenticatedAttributes the authentication process is different. * The document digest is generated and put inside the attribute. The signing is done over the DER encoded * authenticatedAttributes. This method provides that encoding and the parameters must be * exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}. *

* A simple example: *

*

     * Calendar cal = Calendar.getInstance();
     * PdfPKCS7 pk7 = new PdfPKCS7(key, chain, null, "SHA1", null, false);
     * MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
     * byte buf[] = new byte[8192];
     * int n;
     * InputStream inp = sap.getRangeStream();
     * while ((n = inp.read(buf)) > 0) {
     *    messageDigest.update(buf, 0, n);
     * }
     * byte hash[] = messageDigest.digest();
     * byte sh[] = pk7.getAuthenticatedAttributeBytes(hash, cal);
     * pk7.update(sh, 0, sh.length);
     * byte sg[] = pk7.getEncodedPKCS7(hash, cal);
     * 
* @param secondDigest the content digest * @param signingTime the signing time * @return the byte array representation of the authenticatedAttributes ready to be signed */ public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime, byte[] ocsp) { try { return getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp).getEncoded(ASN1Encodable.DER); } catch (Exception e) { throw new ExceptionConverter(e); } } private DERSet getAuthenticatedAttributeSet(byte secondDigest[], Calendar signingTime, byte[] ocsp) { try { ASN1EncodableVector attribute = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); attribute.add(new DERSequence(v)); v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); attribute.add(new DERSequence(v)); v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); v.add(new DERSet(new DEROctetString(secondDigest))); attribute.add(new DERSequence(v)); if (ocsp != null) { v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); DEROctetString doctet = new DEROctetString(ocsp); ASN1EncodableVector vo1 = new ASN1EncodableVector(); ASN1EncodableVector v2 = new ASN1EncodableVector(); v2.add(OCSPObjectIdentifiers.id_pkix_ocsp_basic); v2.add(doctet); DEREnumerated den = new DEREnumerated(0); ASN1EncodableVector v3 = new ASN1EncodableVector(); v3.add(den); v3.add(new DERTaggedObject(true, 0, new DERSequence(v2))); vo1.add(new DERSequence(v3)); v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 1, new DERSequence(vo1))))); attribute.add(new DERSequence(v)); } else if (!crls.isEmpty()) { v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); ASN1EncodableVector v2 = new ASN1EncodableVector(); for (Iterator i = crls.iterator();i.hasNext();) { ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL)i.next()).getEncoded())); v2.add(t.readObject()); } v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 0, new DERSequence(v2))))); attribute.add(new DERSequence(v)); } return new DERSet(attribute); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Getter for property reason. * @return Value of property reason. */ public String getReason() { return this.reason; } /** * Setter for property reason. * @param reason New value of property reason. */ public void setReason(String reason) { this.reason = reason; } /** * Getter for property location. * @return Value of property location. */ public String getLocation() { return this.location; } /** * Setter for property location. * @param location New value of property location. */ public void setLocation(String location) { this.location = location; } /** * Getter for property signDate. * @return Value of property signDate. */ public Calendar getSignDate() { return this.signDate; } /** * Setter for property signDate. * @param signDate New value of property signDate. */ public void setSignDate(Calendar signDate) { this.signDate = signDate; } /** * Getter for property sigName. * @return Value of property sigName. */ public String getSignName() { return this.signName; } /** * Setter for property sigName. * @param signName New value of property sigName. */ public void setSignName(String signName) { this.signName = signName; } /** * a class that holds an X509 name */ public static class X509Name { /** * country code - StringType(SIZE(2)) */ public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6"); /** * organization - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10"); /** * organizational unit name - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11"); /** * Title */ public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12"); /** * common name - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3"); /** * device serial number name - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5"); /** * locality name - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7"); /** * state, or province name - StringType(SIZE(1..64)) */ public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8"); /** Naming attribute of type X520name */ public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); /** Naming attribute of type X520name */ public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); /** Naming attribute of type X520name */ public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); /** Naming attribute of type X520name */ public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44"); /** Naming attribute of type X520name */ public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45"); /** * Email address (RSA PKCS#9 extension) - IA5String. *

Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. */ public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1"); /** * email address in Verisign certificates */ public static final DERObjectIdentifier E = EmailAddress; /** object identifier */ public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25"); /** LDAP User id. */ public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1"); /** A HashMap with default symbols */ public static HashMap DefaultSymbols = new HashMap(); static { DefaultSymbols.put(C, "C"); DefaultSymbols.put(O, "O"); DefaultSymbols.put(T, "T"); DefaultSymbols.put(OU, "OU"); DefaultSymbols.put(CN, "CN"); DefaultSymbols.put(L, "L"); DefaultSymbols.put(ST, "ST"); DefaultSymbols.put(SN, "SN"); DefaultSymbols.put(EmailAddress, "E"); DefaultSymbols.put(DC, "DC"); DefaultSymbols.put(UID, "UID"); DefaultSymbols.put(SURNAME, "SURNAME"); DefaultSymbols.put(GIVENNAME, "GIVENNAME"); DefaultSymbols.put(INITIALS, "INITIALS"); DefaultSymbols.put(GENERATION, "GENERATION"); } /** A HashMap with values */ public HashMap values = new HashMap(); /** * Constructs an X509 name * @param seq an ASN1 Sequence */ public X509Name(ASN1Sequence seq) { Enumeration e = seq.getObjects(); while (e.hasMoreElements()) { ASN1Set set = (ASN1Set)e.nextElement(); for (int i = 0; i < set.size(); i++) { ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); String id = (String)DefaultSymbols.get(s.getObjectAt(0)); if (id == null) continue; ArrayList vs = (ArrayList)values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } vs.add(((DERString)s.getObjectAt(1)).getString()); } } } /** * Constructs an X509 name * @param dirName a directory name */ public X509Name(String dirName) { X509NameTokenizer nTok = new X509NameTokenizer(dirName); while (nTok.hasMoreTokens()) { String token = nTok.nextToken(); int index = token.indexOf('='); if (index == -1) { throw new IllegalArgumentException("badly formated directory string"); } String id = token.substring(0, index).toUpperCase(); String value = token.substring(index + 1); ArrayList vs = (ArrayList)values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } vs.add(value); } } public String getField(String name) { ArrayList vs = (ArrayList)values.get(name); return vs == null ? null : (String)vs.get(0); } /** * gets a field array from the values Hashmap * @param name * @return an ArrayList */ public ArrayList getFieldArray(String name) { ArrayList vs = (ArrayList)values.get(name); return vs == null ? null : vs; } /** * getter for values * @return a HashMap with the fields of the X509 name */ public HashMap getFields() { return values; } /** * @see java.lang.Object#toString() */ public String toString() { return values.toString(); } } /** * class for breaking up an X500 Name into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the * lightweight Java environment don't support classes like * StringTokenizer. */ public static class X509NameTokenizer { private String oid; private int index; private StringBuffer buf = new StringBuffer(); public X509NameTokenizer( String oid) { this.oid = oid; this.index = -1; } public boolean hasMoreTokens() { return (index != oid.length()); } public String nextToken() { if (index == oid.length()) { return null; } int end = index + 1; boolean quoted = false; boolean escaped = false; buf.setLength(0); while (end != oid.length()) { char c = oid.charAt(end); if (c == '"') { if (!escaped) { quoted = !quoted; } else { buf.append(c); } escaped = false; } else { if (escaped || quoted) { buf.append(c); escaped = false; } else if (c == '\\') { escaped = true; } else if (c == ',') { break; } else { buf.append(c); } } end++; } index = end; return buf.toString().trim(); } } } src/core/com/lowagie/text/pdf/PdfPRow.java100644 0 0 55675 11224570760 16120 0ustar 0 0 /* * $Id: PdfPRow.java 3999 2009-06-30 11:52:55Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; /** * A row in a PdfPTable. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfPRow { /** the bottom limit (bottom right y) */ public static final float BOTTOM_LIMIT = -(1 << 30); /** * the right limit * @since 2.1.5 */ public static final float RIGHT_LIMIT = 20000; protected PdfPCell cells[]; protected float widths[]; /** * extra heights that needs to be added to a cell because of rowspans. * @since 2.1.6 */ protected float extraHeights[]; protected float maxHeight = 0; protected boolean calculated = false; private int[] canvasesPos; /** * Constructs a new PdfPRow with the cells in the array that was passed * as a parameter. * * @param cells */ public PdfPRow(PdfPCell cells[]) { this.cells = cells; widths = new float[cells.length]; initExtraHeights(); } /** * Makes a copy of an existing row. * * @param row */ public PdfPRow(PdfPRow row) { maxHeight = row.maxHeight; calculated = row.calculated; cells = new PdfPCell[row.cells.length]; for (int k = 0; k < cells.length; ++k) { if (row.cells[k] != null) cells[k] = new PdfPCell(row.cells[k]); } widths = new float[cells.length]; System.arraycopy(row.widths, 0, widths, 0, cells.length); initExtraHeights(); } /** * Sets the widths of the columns in the row. * * @param widths * @return true if everything went right */ public boolean setWidths(float widths[]) { if (widths.length != cells.length) return false; System.arraycopy(widths, 0, this.widths, 0, cells.length); float total = 0; calculated = false; for (int k = 0; k < widths.length; ++k) { PdfPCell cell = cells[k]; if (cell == null) { total += widths[k]; continue; } cell.setLeft(total); int last = k + cell.getColspan(); for (; k < last; ++k) total += widths[k]; --k; cell.setRight(total); cell.setTop(0); } return true; } /** * Initializes the extra heights array. * @since 2.1.6 */ public void initExtraHeights() { extraHeights = new float[cells.length]; for (int i = 0; i < extraHeights.length; i++) { extraHeights[i] = 0; } } /** * Sets an extra height for a cell. * @param cell the index of the cell that needs an extra height * @param height the extra height * @since 2.1.6 */ public void setExtraHeight(int cell, float height) { if (cell < 0 || cell >= cells.length) return; extraHeights[cell] = height; } /** * Calculates the heights of each cell in the row. * * @return the maximum height of the row. */ public float calculateHeights() { maxHeight = 0; for (int k = 0; k < cells.length; ++k) { PdfPCell cell = cells[k]; float height = 0; if (cell == null) { continue; } else { height = cell.getMaxHeight(); if ((height > maxHeight) && (cell.getRowspan() == 1)) maxHeight = height; } } calculated = true; return maxHeight; } /** * Writes the border and background of one cell in the row. * * @param xPos The x-coordinate where the table starts on the canvas * @param yPos The y-coordinate where the table starts on the canvas * @param currentMaxHeight The height of the cell to be drawn. * @param cell * @param canvases * @since 2.1.6 extra parameter currentMaxHeight */ public void writeBorderAndBackground(float xPos, float yPos, float currentMaxHeight, PdfPCell cell, PdfContentByte[] canvases) { Color background = cell.getBackgroundColor(); if (background != null || cell.hasBorders()) { // Add xPos resp. yPos to the cell's coordinates for absolute coordinates float right = cell.getRight() + xPos; float top = cell.getTop() + yPos; float left = cell.getLeft() + xPos; float bottom = top - currentMaxHeight; if (background != null) { PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS]; backgr.setColorFill(background); backgr.rectangle(left, bottom, right - left, top - bottom); backgr.fill(); } if (cell.hasBorders()) { Rectangle newRect = new Rectangle(left, bottom, right, top); // Clone non-position parameters except for the background color newRect.cloneNonPositionParameters(cell); newRect.setBackgroundColor(null); // Write the borders on the line canvas PdfContentByte lineCanvas = canvases[PdfPTable.LINECANVAS]; lineCanvas.rectangle(newRect); } } } /** * @since 2.1.6 private is now protected */ protected void saveAndRotateCanvases(PdfContentByte[] canvases, float a, float b, float c, float d, float e, float f) { int last = PdfPTable.TEXTCANVAS + 1; if (canvasesPos == null) canvasesPos = new int[last * 2]; for (int k = 0; k < last; ++k) { ByteBuffer bb = canvases[k].getInternalBuffer(); canvasesPos[k * 2] = bb.size(); canvases[k].saveState(); canvases[k].concatCTM(a, b, c, d, e, f); canvasesPos[k * 2 + 1] = bb.size(); } } /** * @since 2.1.6 private is now protected */ protected void restoreCanvases(PdfContentByte[] canvases) { int last = PdfPTable.TEXTCANVAS + 1; for (int k = 0; k < last; ++k) { ByteBuffer bb = canvases[k].getInternalBuffer(); int p1 = bb.size(); canvases[k].restoreState(); if (p1 == canvasesPos[k * 2 + 1]) bb.setSize(canvasesPos[k * 2]); } } /** * @since 3.0.0 protected is now public static */ public static float setColumn(ColumnText ct, float left, float bottom, float right, float top) { if (left > right) right = left; if (bottom > top) top = bottom; ct.setSimpleColumn(left, bottom, right, top); return top; } /** * Writes a number of cells (not necessarily all cells). * * @param colStart The first column to be written. * Remember that the column index starts with 0. * @param colEnd The last column to be written. * Remember that the column index starts with 0. * If -1, all the columns to the end are written. * @param xPos The x-coordinate where the table starts on the canvas * @param yPos The y-coordinate where the table starts on the canvas */ public void writeCells(int colStart, int colEnd, float xPos, float yPos, PdfContentByte[] canvases) { if (!calculated) calculateHeights(); if (colEnd < 0) colEnd = cells.length; else colEnd = Math.min(colEnd, cells.length); if (colStart < 0) colStart = 0; if (colStart >= colEnd) return; int newStart; for (newStart = colStart; newStart >= 0; --newStart) { if (cells[newStart] != null) break; if (newStart > 0) xPos -= widths[newStart - 1]; } if (newStart < 0) newStart = 0; if (cells[newStart] != null) xPos -= cells[newStart].getLeft(); for (int k = newStart; k < colEnd; ++k) { PdfPCell cell = cells[k]; if (cell == null) continue; float currentMaxHeight = maxHeight + extraHeights[k]; writeBorderAndBackground(xPos, yPos, currentMaxHeight, cell, canvases); Image img = cell.getImage(); float tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); if (cell.getHeight() <= currentMaxHeight) { switch (cell.getVerticalAlignment()) { case Element.ALIGN_BOTTOM: tly = cell.getTop() + yPos - currentMaxHeight + cell.getHeight() - cell.getEffectivePaddingTop(); break; case Element.ALIGN_MIDDLE: tly = cell.getTop() + yPos + (cell.getHeight() - currentMaxHeight) / 2 - cell.getEffectivePaddingTop(); break; default: break; } } if (img != null) { if (cell.getRotation() != 0) { img = Image.getInstance(img); img.setRotation(img.getImageRotation() + (float)(cell.getRotation() * Math.PI / 180.0)); } boolean vf = false; if (cell.getHeight() > currentMaxHeight) { img.scalePercent(100); float scale = (currentMaxHeight - cell.getEffectivePaddingTop() - cell .getEffectivePaddingBottom()) / img.getScaledHeight(); img.scalePercent(scale * 100); vf = true; } float left = cell.getLeft() + xPos + cell.getEffectivePaddingLeft(); if (vf) { switch (cell.getHorizontalAlignment()) { case Element.ALIGN_CENTER: left = xPos + (cell.getLeft() + cell.getEffectivePaddingLeft() + cell.getRight() - cell.getEffectivePaddingRight() - img .getScaledWidth()) / 2; break; case Element.ALIGN_RIGHT: left = xPos + cell.getRight() - cell.getEffectivePaddingRight() - img.getScaledWidth(); break; default: break; } tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); } img.setAbsolutePosition(left, tly - img.getScaledHeight()); try { canvases[PdfPTable.TEXTCANVAS].addImage(img); } catch (DocumentException e) { throw new ExceptionConverter(e); } } else { // rotation sponsored by Connection GmbH if (cell.getRotation() == 90 || cell.getRotation() == 270) { float netWidth = currentMaxHeight - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom(); float netHeight = cell.getWidth() - cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight(); ColumnText ct = ColumnText.duplicate(cell.getColumn()); ct.setCanvases(canvases); ct.setSimpleColumn(0, 0, netWidth + 0.001f, -netHeight); try { ct.go(true); } catch (DocumentException e) { throw new ExceptionConverter(e); } float calcHeight = -ct.getYLine(); if (netWidth <= 0 || netHeight <= 0) calcHeight = 0; if (calcHeight > 0) { if (cell.isUseDescender()) calcHeight -= ct.getDescender(); ct = ColumnText.duplicate(cell.getColumn()); ct.setCanvases(canvases); ct.setSimpleColumn(-0.003f, -0.001f, netWidth + 0.003f, calcHeight); float pivotX; float pivotY; if (cell.getRotation() == 90) { pivotY = cell.getTop() + yPos - currentMaxHeight + cell.getEffectivePaddingBottom(); switch (cell.getVerticalAlignment()) { case Element.ALIGN_BOTTOM: pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight(); break; case Element.ALIGN_MIDDLE: pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() + calcHeight) / 2; break; default: //top pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft() + calcHeight; break; } saveAndRotateCanvases(canvases, 0,1,-1,0,pivotX,pivotY); } else { pivotY = cell.getTop() + yPos - cell.getEffectivePaddingTop(); switch (cell.getVerticalAlignment()) { case Element.ALIGN_BOTTOM: pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft(); break; case Element.ALIGN_MIDDLE: pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() - calcHeight) / 2; break; default: //top pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight() - calcHeight; break; } saveAndRotateCanvases(canvases, 0,-1,1,0,pivotX,pivotY); } try { ct.go(); } catch (DocumentException e) { throw new ExceptionConverter(e); } finally { restoreCanvases(canvases); } } } else { float fixedHeight = cell.getFixedHeight(); float rightLimit = cell.getRight() + xPos - cell.getEffectivePaddingRight(); float leftLimit = cell.getLeft() + xPos + cell.getEffectivePaddingLeft(); if (cell.isNoWrap()) { switch (cell.getHorizontalAlignment()) { case Element.ALIGN_CENTER: rightLimit += 10000; leftLimit -= 10000; break; case Element.ALIGN_RIGHT: if (cell.getRotation() == 180) { rightLimit += RIGHT_LIMIT; } else { leftLimit -= RIGHT_LIMIT; } break; default: if (cell.getRotation() == 180) { leftLimit -= RIGHT_LIMIT; } else { rightLimit += RIGHT_LIMIT; } break; } } ColumnText ct = ColumnText.duplicate(cell.getColumn()); ct.setCanvases(canvases); float bry = tly - (currentMaxHeight - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom()); if (fixedHeight > 0) { if (cell.getHeight() > currentMaxHeight) { tly = cell.getTop() + yPos - cell.getEffectivePaddingTop(); bry = cell.getTop() + yPos - currentMaxHeight + cell.getEffectivePaddingBottom(); } } if ((tly > bry || ct.zeroHeightElement()) && leftLimit < rightLimit) { ct.setSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly); if (cell.getRotation() == 180) { float shx = leftLimit + rightLimit; float shy = yPos + yPos - currentMaxHeight + cell.getEffectivePaddingBottom() - cell.getEffectivePaddingTop(); saveAndRotateCanvases(canvases, -1,0,0,-1,shx,shy); } try { ct.go(); } catch (DocumentException e) { throw new ExceptionConverter(e); } finally { if (cell.getRotation() == 180) { restoreCanvases(canvases); } } } } } PdfPCellEvent evt = cell.getCellEvent(); if (evt != null) { Rectangle rect = new Rectangle(cell.getLeft() + xPos, cell.getTop() + yPos - currentMaxHeight, cell.getRight() + xPos, cell.getTop() + yPos); evt.cellLayout(cell, rect, canvases); } } } /** * Checks if the dimensions of the columns were calculated. * * @return true if the dimensions of the columns were calculated */ public boolean isCalculated() { return calculated; } /** * Gets the maximum height of the row (i.e. of the 'highest' cell). * * @return the maximum height of the row */ public float getMaxHeights() { if (calculated) return maxHeight; return calculateHeights(); } /** * Changes the maximum height of the row (to make it higher). * (added by Jin-Hsia Yang) * * @param maxHeight the new maximum height */ public void setMaxHeights(float maxHeight) { this.maxHeight = maxHeight; } //end add float[] getEventWidth(float xPos) { int n = 0; for (int k = 0; k < cells.length; ++k) { if (cells[k] != null) ++n; } float width[] = new float[n + 1]; n = 0; width[n++] = xPos; for (int k = 0; k < cells.length; ++k) { if (cells[k] != null) { width[n] = width[n - 1] + cells[k].getWidth(); ++n; } } return width; } /** * Splits a row to newHeight. * The returned row is the remainder. It will return null if the newHeight * was so small that only an empty row would result. * * @param new_height the new height * @return the remainder row or null if the newHeight was so small that only * an empty row would result */ public PdfPRow splitRow(PdfPTable table, int rowIndex, float new_height) { PdfPCell newCells[] = new PdfPCell[cells.length]; float fixHs[] = new float[cells.length]; float minHs[] = new float[cells.length]; boolean allEmpty = true; for (int k = 0; k < cells.length; ++k) { float newHeight = new_height; PdfPCell cell = cells[k]; if (cell == null) { int index = rowIndex; if (table.rowSpanAbove(index, k)) { newHeight += table.getRowHeight(index); while (table.rowSpanAbove(--index, k)) { newHeight += table.getRowHeight(index); } PdfPRow row = table.getRow(index); if (row != null && row.getCells()[k] != null) { newCells[k] = new PdfPCell(row.getCells()[k]); newCells[k].consumeHeight(newHeight); newCells[k].setRowspan(row.getCells()[k].getRowspan() - rowIndex + index); allEmpty = false; } } continue; } fixHs[k] = cell.getFixedHeight(); minHs[k] = cell.getMinimumHeight(); Image img = cell.getImage(); PdfPCell newCell = new PdfPCell(cell); if (img != null) { if (newHeight > cell.getEffectivePaddingBottom() + cell.getEffectivePaddingTop() + 2) { newCell.setPhrase(null); allEmpty = false; } } else { float y; ColumnText ct = ColumnText.duplicate(cell.getColumn()); float left = cell.getLeft() + cell.getEffectivePaddingLeft(); float bottom = cell.getTop() + cell.getEffectivePaddingBottom() - newHeight; float right = cell.getRight() - cell.getEffectivePaddingRight(); float top = cell.getTop() - cell.getEffectivePaddingTop(); switch (cell.getRotation()) { case 90: case 270: y = setColumn(ct, bottom, left, top, right); break; default: y = setColumn(ct, left, bottom, cell.isNoWrap() ? RIGHT_LIMIT : right, top); break; } int status; try { status = ct.go(true); } catch (DocumentException e) { throw new ExceptionConverter(e); } boolean thisEmpty = (ct.getYLine() == y); if (thisEmpty) { newCell.setColumn(ColumnText.duplicate(cell.getColumn())); ct.setFilledWidth(0); } else if ((status & ColumnText.NO_MORE_TEXT) == 0) { newCell.setColumn(ct); ct.setFilledWidth(0); } else newCell.setPhrase(null); allEmpty = (allEmpty && thisEmpty); } newCells[k] = newCell; cell.setFixedHeight(newHeight); } if (allEmpty) { for (int k = 0; k < cells.length; ++k) { PdfPCell cell = cells[k]; if (cell == null) continue; if (fixHs[k] > 0) cell.setFixedHeight(fixHs[k]); else cell.setMinimumHeight(minHs[k]); } return null; } calculateHeights(); PdfPRow split = new PdfPRow(newCells); split.widths = (float[]) widths.clone(); split.calculateHeights(); return split; } /** * Returns the array of cells in the row. * Please be extremely careful with this method. * Use the cells as read only objects. * * @return an array of cells * @since 2.1.1 */ public PdfPCell[] getCells() { return cells; } } src/core/com/lowagie/text/pdf/PdfPSXObject.java100644 0 0 7520 11036112746 16771 0ustar 0 0 /* * Copyright 2005 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; /** * Implements the PostScript XObject. */ public class PdfPSXObject extends PdfTemplate { /** Creates a new instance of PdfPSXObject */ protected PdfPSXObject() { super(); } /** * Constructs a PSXObject * @param wr */ public PdfPSXObject(PdfWriter wr) { super(wr); } /** * Gets the stream representing this object. * * @param compressionLevel the compressionLevel * @return the stream representing this template * @since 2.1.3 (replacing the method without param compressionLevel) * @throws IOException */ PdfStream getFormXObject(int compressionLevel) throws IOException { PdfStream s = new PdfStream(content.toByteArray()); s.put(PdfName.TYPE, PdfName.XOBJECT); s.put(PdfName.SUBTYPE, PdfName.PS); s.flateCompress(compressionLevel); return s; } /** * Gets a duplicate of this PdfPSXObject. All * the members are copied by reference but the buffer stays different. * @return a copy of this PdfPSXObject */ public PdfContentByte getDuplicate() { PdfPSXObject tpl = new PdfPSXObject(); tpl.writer = writer; tpl.pdf = pdf; tpl.thisReference = thisReference; tpl.pageResources = pageResources; tpl.separator = separator; return tpl; } } src/core/com/lowagie/text/pdf/PdfPTable.java100644 0 0 142251 11224602534 16376 0ustar 0 0 /* * $Id: PdfPTable.java 4010 2009-07-07 11:05:23Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementListener; import com.lowagie.text.Image; import com.lowagie.text.LargeElement; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.events.PdfPTableEventForwarder; /** * This is a table that can be put at an absolute position but can also * be added to the document as the class Table. * In the last case when crossing pages the table always break at full rows; if a * row is bigger than the page it is dropped silently to avoid infinite loops. *

* A PdfPTableEvent can be associated to the table to do custom drawing * when the table is rendered. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfPTable implements LargeElement{ /** * The index of the original PdfcontentByte. */ public static final int BASECANVAS = 0; /** * The index of the duplicate PdfContentByte where the background will be drawn. */ public static final int BACKGROUNDCANVAS = 1; /** * The index of the duplicate PdfContentByte where the border lines will be drawn. */ public static final int LINECANVAS = 2; /** * The index of the duplicate PdfContentByte where the text will be drawn. */ public static final int TEXTCANVAS = 3; protected ArrayList rows = new ArrayList(); protected float totalHeight = 0; protected PdfPCell currentRow[]; protected int currentRowIdx = 0; protected PdfPCell defaultCell = new PdfPCell((Phrase)null); protected float totalWidth = 0; protected float relativeWidths[]; protected float absoluteWidths[]; protected PdfPTableEvent tableEvent; /** * Holds value of property headerRows. */ protected int headerRows; /** * Holds value of property widthPercentage. */ protected float widthPercentage = 80; /** * Holds value of property horizontalAlignment. */ private int horizontalAlignment = Element.ALIGN_CENTER; /** * Holds value of property skipFirstHeader. */ private boolean skipFirstHeader = false; /** * Holds value of property skipLastFooter. * @since 2.1.6 */ private boolean skipLastFooter = false; protected boolean isColspan = false; protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT; /** * Holds value of property lockedWidth. */ private boolean lockedWidth = false; /** * Holds value of property splitRows. */ private boolean splitRows = true; /** * The spacing before the table. */ protected float spacingBefore; /** * The spacing after the table. */ protected float spacingAfter; /** * Holds value of property extendLastRow. */ private boolean extendLastRow; /** * Holds value of property headersInEvent. */ private boolean headersInEvent; /** * Holds value of property splitLate. */ private boolean splitLate = true; /** * Defines if the table should be kept * on one page if possible */ private boolean keepTogether; /** * Indicates if the PdfPTable is complete once added to the document. * * @since iText 2.0.8 */ protected boolean complete = true; /** * Holds value of property footerRows. */ private int footerRows; /** * Keeps track of the completeness of the current row. * @since 2.1.6 */ protected boolean rowCompleted = true; protected PdfPTable() { } /** * Constructs a PdfPTable with the relative column widths. * * @param relativeWidths the relative column widths */ public PdfPTable(float relativeWidths[]) { if (relativeWidths == null) throw new NullPointerException("The widths array in PdfPTable constructor can not be null."); if (relativeWidths.length == 0) throw new IllegalArgumentException("The widths array in PdfPTable constructor can not have zero length."); this.relativeWidths = new float[relativeWidths.length]; System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); absoluteWidths = new float[relativeWidths.length]; calculateWidths(); currentRow = new PdfPCell[absoluteWidths.length]; keepTogether = false; } /** * Constructs a PdfPTable with numColumns columns. * * @param numColumns the number of columns */ public PdfPTable(int numColumns) { if (numColumns <= 0) throw new IllegalArgumentException("The number of columns in PdfPTable constructor must be greater than zero."); relativeWidths = new float[numColumns]; for (int k = 0; k < numColumns; ++k) relativeWidths[k] = 1; absoluteWidths = new float[relativeWidths.length]; calculateWidths(); currentRow = new PdfPCell[absoluteWidths.length]; keepTogether = false; } /** * Constructs a copy of a PdfPTable. * * @param table the PdfPTable to be copied */ public PdfPTable(PdfPTable table) { copyFormat(table); for (int k = 0; k < currentRow.length; ++k) { if (table.currentRow[k] == null) break; currentRow[k] = new PdfPCell(table.currentRow[k]); } for (int k = 0; k < table.rows.size(); ++k) { PdfPRow row = (PdfPRow)(table.rows.get(k)); if (row != null) row = new PdfPRow(row); rows.add(row); } } /** * Makes a shallow copy of a table (format without content). * * @param table * @return a shallow copy of the table */ public static PdfPTable shallowCopy(PdfPTable table) { PdfPTable nt = new PdfPTable(); nt.copyFormat(table); return nt; } /** * Copies the format of the sourceTable without copying the content. * * @param sourceTable * @since 2.1.6 private is now protected */ protected void copyFormat(PdfPTable sourceTable) { relativeWidths = new float[sourceTable.getNumberOfColumns()]; absoluteWidths = new float[sourceTable.getNumberOfColumns()]; System.arraycopy(sourceTable.relativeWidths, 0, relativeWidths, 0, getNumberOfColumns()); System.arraycopy(sourceTable.absoluteWidths, 0, absoluteWidths, 0, getNumberOfColumns()); totalWidth = sourceTable.totalWidth; totalHeight = sourceTable.totalHeight; currentRowIdx = 0; tableEvent = sourceTable.tableEvent; runDirection = sourceTable.runDirection; defaultCell = new PdfPCell(sourceTable.defaultCell); currentRow = new PdfPCell[sourceTable.currentRow.length]; isColspan = sourceTable.isColspan; splitRows = sourceTable.splitRows; spacingAfter = sourceTable.spacingAfter; spacingBefore = sourceTable.spacingBefore; headerRows = sourceTable.headerRows; footerRows = sourceTable.footerRows; lockedWidth = sourceTable.lockedWidth; extendLastRow = sourceTable.extendLastRow; headersInEvent = sourceTable.headersInEvent; widthPercentage = sourceTable.widthPercentage; splitLate = sourceTable.splitLate; skipFirstHeader = sourceTable.skipFirstHeader; skipLastFooter = sourceTable.skipLastFooter; horizontalAlignment = sourceTable.horizontalAlignment; keepTogether = sourceTable.keepTogether; complete = sourceTable.complete; } /** * Sets the relative widths of the table. * * @param relativeWidths the relative widths of the table. * @throws DocumentException if the number of widths is different than the number * of columns */ public void setWidths(float relativeWidths[]) throws DocumentException { if (relativeWidths.length != getNumberOfColumns()) throw new DocumentException("Wrong number of columns."); this.relativeWidths = new float[relativeWidths.length]; System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); absoluteWidths = new float[relativeWidths.length]; totalHeight = 0; calculateWidths(); calculateHeights(true); } /** * Sets the relative widths of the table. * * @param relativeWidths the relative widths of the table. * @throws DocumentException if the number of widths is different than the number * of columns */ public void setWidths(int relativeWidths[]) throws DocumentException { float tb[] = new float[relativeWidths.length]; for (int k = 0; k < relativeWidths.length; ++k) tb[k] = relativeWidths[k]; setWidths(tb); } /** * @since 2.1.6 private is now protected */ protected void calculateWidths() { if (totalWidth <= 0) return; float total = 0; int numCols = getNumberOfColumns(); for (int k = 0; k < numCols; ++k) total += relativeWidths[k]; for (int k = 0; k < numCols; ++k) absoluteWidths[k] = totalWidth * relativeWidths[k] / total; } /** * Sets the full width of the table. * * @param totalWidth the full width of the table. */ public void setTotalWidth(float totalWidth) { if (this.totalWidth == totalWidth) return; this.totalWidth = totalWidth; totalHeight = 0; calculateWidths(); calculateHeights(true); } /** * Sets the full width of the table from the absolute column width. * * @param columnWidth the absolute width of each column * @throws DocumentException if the number of widths is different than the number * of columns */ public void setTotalWidth(float columnWidth[]) throws DocumentException { if (columnWidth.length != getNumberOfColumns()) throw new DocumentException("Wrong number of columns."); totalWidth = 0; for (int k = 0; k < columnWidth.length; ++k) totalWidth += columnWidth[k]; setWidths(columnWidth); } /** * Sets the percentage width of the table from the absolute column width. * * @param columnWidth the absolute width of each column * @param pageSize the page size * @throws DocumentException */ public void setWidthPercentage(float columnWidth[], Rectangle pageSize) throws DocumentException { if (columnWidth.length != getNumberOfColumns()) throw new IllegalArgumentException("Wrong number of columns."); float totalWidth = 0; for (int k = 0; k < columnWidth.length; ++k) totalWidth += columnWidth[k]; widthPercentage = totalWidth / (pageSize.getRight() - pageSize.getLeft()) * 100f; setWidths(columnWidth); } /** * Gets the full width of the table. * * @return the full width of the table */ public float getTotalWidth() { return totalWidth; } /** * Calculates the heights of the table. * * @param firsttime if true, the heights of the rows will be recalculated. * This takes time; normally the heights of the rows are already calcultated, * so in most cases, it's save to use false as parameter. * @return the total height of the table. Note that it will be 0 if you didn't * specify the width of the table with setTotalWidth(). * @since 2.1.5 added a parameter and a return type to an existing method, * and made it public */ public float calculateHeights(boolean firsttime) { if (totalWidth <= 0) return 0; totalHeight = 0; for (int k = 0; k < rows.size(); ++k) { totalHeight += getRowHeight(k, firsttime); } return totalHeight; } /** * Calculates the heights of the table. */ public void calculateHeightsFast() { calculateHeights(false); } /** * Gets the default PdfPCell that will be used as * reference for all the addCell methods except * addCell(PdfPCell). * * @return default PdfPCell */ public PdfPCell getDefaultCell() { return defaultCell; } /** * Adds a cell element. * * @param cell the cell element */ public void addCell(PdfPCell cell) { rowCompleted = false; PdfPCell ncell = new PdfPCell(cell); int colspan = ncell.getColspan(); colspan = Math.max(colspan, 1); colspan = Math.min(colspan, currentRow.length - currentRowIdx); ncell.setColspan(colspan); if (colspan != 1) isColspan = true; int rdir = ncell.getRunDirection(); if (rdir == PdfWriter.RUN_DIRECTION_DEFAULT) ncell.setRunDirection(runDirection); skipColsWithRowspanAbove(); boolean cellAdded = false; if (currentRowIdx < currentRow.length) { currentRow[currentRowIdx] = ncell; currentRowIdx += colspan; cellAdded = true; } skipColsWithRowspanAbove(); if (currentRowIdx >= currentRow.length) { int numCols = getNumberOfColumns(); if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { PdfPCell rtlRow[] = new PdfPCell[numCols]; int rev = currentRow.length; for (int k = 0; k < currentRow.length; ++k) { PdfPCell rcell = currentRow[k]; int cspan = rcell.getColspan(); rev -= cspan; rtlRow[rev] = rcell; k += cspan - 1; } currentRow = rtlRow; } PdfPRow row = new PdfPRow(currentRow); if (totalWidth > 0) { row.setWidths(absoluteWidths); totalHeight += row.getMaxHeights(); } rows.add(row); currentRow = new PdfPCell[numCols]; currentRowIdx = 0; rowCompleted = true; } if (!cellAdded) { currentRow[currentRowIdx] = ncell; currentRowIdx += colspan; } } /** * When updating the row index, cells with rowspan should be taken into account. * This is what happens in this method. * @since 2.1.6 */ private void skipColsWithRowspanAbove() { int direction = 1; if (runDirection == PdfWriter.RUN_DIRECTION_RTL) direction = -1; while (rowSpanAbove(rows.size(), currentRowIdx)) currentRowIdx += direction; } /** * Checks if there are rows above belonging to a rowspan. * @param currRow the current row to check * @param currCol the current column to check * @return true if there's a cell above that belongs to a rowspan * @since 2.1.6 */ boolean rowSpanAbove(int currRow, int currCol) { if ((currCol >= getNumberOfColumns()) || (currCol < 0) || (currRow == 0)) return false; int row = currRow - 1; PdfPRow aboveRow = (PdfPRow)rows.get(row); if (aboveRow == null) return false; PdfPCell aboveCell = (PdfPCell)aboveRow.getCells()[currCol]; while ((aboveCell == null) && (row > 0)) { aboveRow = (PdfPRow)rows.get(--row); if (aboveRow == null) return false; aboveCell = (PdfPCell)aboveRow.getCells()[currCol]; } int distance = currRow - row; if (aboveCell == null) { int col = currCol - 1; aboveCell = (PdfPCell)aboveRow.getCells()[col]; while ((aboveCell == null) && (row > 0)) aboveCell = (PdfPCell)aboveRow.getCells()[--col]; return aboveCell != null && aboveCell.getRowspan() > distance; } if ((aboveCell.getRowspan() == 1) && (distance > 1)) { int col = currCol - 1; aboveRow = (PdfPRow)rows.get(row + 1); distance--; aboveCell = (PdfPCell)aboveRow.getCells()[col]; while ((aboveCell == null) && (col > 0)) aboveCell = (PdfPCell)aboveRow.getCells()[--col]; } return aboveCell != null && aboveCell.getRowspan() > distance; } /** * Adds a cell element. * * @param text the text for the cell */ public void addCell(String text) { addCell(new Phrase(text)); } /** * Adds a nested table. * * @param table the table to be added to the cell */ public void addCell(PdfPTable table) { defaultCell.setTable(table); addCell(defaultCell); defaultCell.setTable(null); } /** * Adds an Image as Cell. * * @param image the Image to add to the table. * This image will fit in the cell */ public void addCell(Image image) { defaultCell.setImage(image); addCell(defaultCell); defaultCell.setImage(null); } /** * Adds a cell element. * * @param phrase the Phrase to be added to the cell */ public void addCell(Phrase phrase) { defaultCell.setPhrase(phrase); addCell(defaultCell); defaultCell.setPhrase(null); } /** * Writes the selected rows to the document. * canvases is obtained from beginWritingRows(). * * @param rowStart the first row to be written, zero index * @param rowEnd the last row to be written + 1. If it is -1 all the * rows to the end are written * @param xPos the x write coordinate * @param yPos the y write coordinate * @param canvases an array of 4 PdfContentByte obtained from * beginWrittingRows() * @return the y coordinate position of the bottom of the last row * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte) */ public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvases); } /** * Writes the selected rows and columns to the document. * This method does not clip the columns; this is only important * if there are columns with colspan at boundaries. * canvases is obtained from beginWritingRows(). * The table event is only fired for complete rows. * * @param colStart the first column to be written, zero index * @param colEnd the last column to be written + 1. If it is -1 all the * columns to the end are written * @param rowStart the first row to be written, zero index * @param rowEnd the last row to be written + 1. If it is -1 all the * rows to the end are written * @param xPos the x write coordinate * @param yPos the y write coordinate * @param canvases an array of 4 PdfContentByte obtained from * beginWritingRows() * @return the y coordinate position of the bottom of the last row * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte) */ public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { if (totalWidth <= 0) throw new RuntimeException("The table width must be greater than zero."); int totalRows = rows.size(); if (rowStart < 0) rowStart = 0; if (rowEnd < 0) rowEnd = totalRows; else rowEnd = Math.min(rowEnd, totalRows); if (rowStart >= rowEnd) return yPos; int totalCols = getNumberOfColumns(); if (colStart < 0) colStart = 0; else colStart = Math.min(colStart, totalCols); if (colEnd < 0) colEnd = totalCols; else colEnd = Math.min(colEnd, totalCols); float yPosStart = yPos; for (int k = rowStart; k < rowEnd; ++k) { PdfPRow row = (PdfPRow)rows.get(k); if (row != null) { row.writeCells(colStart, colEnd, xPos, yPos, canvases); yPos -= row.getMaxHeights(); } } if (tableEvent != null && colStart == 0 && colEnd == totalCols) { float heights[] = new float[rowEnd - rowStart + 1]; heights[0] = yPosStart; for (int k = rowStart; k < rowEnd; ++k) { PdfPRow row = (PdfPRow)rows.get(k); float hr = 0; if (row != null) hr = row.getMaxHeights(); heights[k - rowStart + 1] = heights[k - rowStart] - hr; } tableEvent.tableLayout(this, getEventWidths(xPos, rowStart, rowEnd, headersInEvent), heights, headersInEvent ? headerRows : 0, rowStart, canvases); } return yPos; } /** * Writes the selected rows to the document. * * @param rowStart the first row to be written, zero index * @param rowEnd the last row to be written + 1. If it is -1 all the * rows to the end are written * @param xPos the x write coordinate * @param yPos the y write coordinate * @param canvas the PdfContentByte where the rows will * be written to * @return the y coordinate position of the bottom of the last row */ public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvas); } /** * Writes the selected rows and columns to the document. * This method clips the columns; this is only important * if there are columns with colspan at boundaries. * The table event is only fired for complete rows. * * @param colStart the first column to be written, zero index * @param colEnd the last column to be written + 1. If it is -1 all the * columns to the end are written * @param rowStart the first row to be written, zero index * @param rowEnd the last row to be written + 1. If it is -1 all the * rows to the end are written * @param xPos the x write coordinate * @param yPos the y write coordinate * @param canvas the PdfContentByte where the rows will * be written to * @return the y coordinate position of the bottom of the last row */ public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { int totalCols = getNumberOfColumns(); if (colStart < 0) colStart = 0; else colStart = Math.min(colStart, totalCols); if (colEnd < 0) colEnd = totalCols; else colEnd = Math.min(colEnd, totalCols); boolean clip = (colStart != 0 || colEnd != totalCols); if (clip) { float w = 0; for (int k = colStart; k < colEnd; ++k) w += absoluteWidths[k]; canvas.saveState(); float lx = (colStart == 0) ? 10000 : 0; float rx = (colEnd == totalCols) ? 10000 : 0; canvas.rectangle(xPos - lx, -10000, w + lx + rx, PdfPRow.RIGHT_LIMIT); canvas.clip(); canvas.newPath(); } PdfContentByte[] canvases = beginWritingRows(canvas); float y = writeSelectedRows(colStart, colEnd, rowStart, rowEnd, xPos, yPos, canvases); endWritingRows(canvases); if (clip) canvas.restoreState(); return y; } /** * Gets and initializes the 4 layers where the table is written to. The text or graphics are added to * one of the 4 PdfContentByte returned with the following order:

*

    *
  • PdfPtable.BASECANVAS - the original PdfContentByte. Anything placed here * will be under the table. *
  • PdfPtable.BACKGROUNDCANVAS - the layer where the background goes to. *
  • PdfPtable.LINECANVAS - the layer where the lines go to. *
  • PdfPtable.TEXTCANVAS - the layer where the text go to. Anything placed here * will be over the table. *

* The layers are placed in sequence on top of each other. * * @param canvas the PdfContentByte where the rows will * be written to * @return an array of 4 PdfContentByte * @see #writeSelectedRows(int, int, float, float, PdfContentByte[]) */ public static PdfContentByte[] beginWritingRows(PdfContentByte canvas) { return new PdfContentByte[]{ canvas, canvas.getDuplicate(), canvas.getDuplicate(), canvas.getDuplicate(), }; } /** * Finishes writing the table. * * @param canvases the array returned by beginWritingRows() */ public static void endWritingRows(PdfContentByte[] canvases) { PdfContentByte canvas = canvases[BASECANVAS]; canvas.saveState(); canvas.add(canvases[BACKGROUNDCANVAS]); canvas.restoreState(); canvas.saveState(); canvas.setLineCap(2); canvas.resetRGBColorStroke(); canvas.add(canvases[LINECANVAS]); canvas.restoreState(); canvas.add(canvases[TEXTCANVAS]); } /** * Gets the number of rows in this table. * * @return the number of rows in this table */ public int size() { return rows.size(); } /** * Gets the total height of the table. * * @return the total height of the table */ public float getTotalHeight() { return totalHeight; } /** * Gets the height of a particular row. * * @param idx the row index (starts at 0) * @return the height of a particular row */ public float getRowHeight(int idx) { return getRowHeight(idx, false); } /** * Gets the height of a particular row. * * @param idx the row index (starts at 0) * @param firsttime is this the first time the row heigh is calculated? * @return the height of a particular row * @since 3.0.0 */ public float getRowHeight(int idx, boolean firsttime) { if (totalWidth <= 0 || idx < 0 || idx >= rows.size()) return 0; PdfPRow row = (PdfPRow)rows.get(idx); if (row == null) return 0; if (firsttime) row.setWidths(absoluteWidths); float height = row.getMaxHeights(); PdfPCell cell; PdfPRow tmprow; for (int i = 0; i < relativeWidths.length; i++) { if(!rowSpanAbove(idx, i)) continue; int rs = 1; while (rowSpanAbove(idx - rs, i)) { rs++; } tmprow = (PdfPRow)rows.get(idx - rs); cell = tmprow.getCells()[i]; float tmp = 0; if (cell.getRowspan() == rs + 1) { tmp = cell.getMaxHeight(); while (rs > 0) { tmp -= getRowHeight(idx - rs); rs--; } } if (tmp > height) height = tmp; } row.setMaxHeights(height); return height; } /** * Gets the maximum height of a cell in a particular row (will only be different * from getRowHeight is one of the cells in the row has a rowspan > 1). * * @param rowIndex the row index * @param cellIndex the cell index * @return the height of a particular row including rowspan * @since 2.1.6 */ public float getRowspanHeight(int rowIndex, int cellIndex) { if (totalWidth <= 0 || rowIndex < 0 || rowIndex >= rows.size()) return 0; PdfPRow row = (PdfPRow)rows.get(rowIndex); if (row == null || cellIndex >= row.getCells().length) return 0; PdfPCell cell = row.getCells()[cellIndex]; if (cell == null) return 0; float rowspanHeight = 0; for (int j = 0; j < cell.getRowspan(); j++) { rowspanHeight += getRowHeight(rowIndex + j); } return rowspanHeight; } /** * Gets the height of the rows that constitute the header as defined by * setHeaderRows(). * * @return the height of the rows that constitute the header and footer */ public float getHeaderHeight() { float total = 0; int size = Math.min(rows.size(), headerRows); for (int k = 0; k < size; ++k) { PdfPRow row = (PdfPRow)rows.get(k); if (row != null) total += row.getMaxHeights(); } return total; } /** * Gets the height of the rows that constitute the footer as defined by * setFooterRows(). * * @return the height of the rows that constitute the footer * @since 2.1.1 */ public float getFooterHeight() { float total = 0; int start = Math.max(0, headerRows - footerRows); int size = Math.min(rows.size(), headerRows); for (int k = start; k < size; ++k) { PdfPRow row = (PdfPRow)rows.get(k); if (row != null) total += row.getMaxHeights(); } return total; } /** * Deletes a row from the table. * * @param rowNumber the row to be deleted * @return true if the row was deleted */ public boolean deleteRow(int rowNumber) { if (rowNumber < 0 || rowNumber >= rows.size()) return false; if (totalWidth > 0) { PdfPRow row = (PdfPRow)rows.get(rowNumber); if (row != null) totalHeight -= row.getMaxHeights(); } rows.remove(rowNumber); if (rowNumber < headerRows) { --headerRows; if (rowNumber >= (headerRows - footerRows)) --footerRows; } return true; } /** * Deletes the last row in the table. * * @return true if the last row was deleted */ public boolean deleteLastRow() { return deleteRow(rows.size() - 1); } /** * Removes all of the rows except headers */ public void deleteBodyRows() { ArrayList rows2 = new ArrayList(); for (int k = 0; k < headerRows; ++k) rows2.add(rows.get(k)); rows = rows2; totalHeight = 0; if (totalWidth > 0) totalHeight = getHeaderHeight(); } /** * Returns the number of columns. * * @return the number of columns. * @since 2.1.1 */ public int getNumberOfColumns() { return relativeWidths.length; } /** * Gets the number of the rows that constitute the header. * * @return the number of the rows that constitute the header */ public int getHeaderRows() { return headerRows; } /** * Sets the number of the top rows that constitute the header. * This header has only meaning if the table is added to Document * and the table crosses pages. * * @param headerRows the number of the top rows that constitute the header */ public void setHeaderRows(int headerRows) { if (headerRows < 0) headerRows = 0; this.headerRows = headerRows; } /** * Gets all the chunks in this element. * * @return an ArrayList */ public ArrayList getChunks() { return new ArrayList(); } /** * Gets the type of the text element. * * @return a type */ public int type() { return Element.PTABLE; } /** * @see com.lowagie.text.Element#isContent() * @since iText 2.0.8 */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() * @since iText 2.0.8 */ public boolean isNestable() { return true; } /** * Processes the element by adding it (or the different parts) to an * ElementListener. * * @param listener an ElementListener * @return true if the element was processed successfully */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch(DocumentException de) { return false; } } /** * Gets the width percentage that the table will occupy in the page. * * @return the width percentage that the table will occupy in the page */ public float getWidthPercentage() { return widthPercentage; } /** * Sets the width percentage that the table will occupy in the page. * * @param widthPercentage the width percentage that the table will occupy in the page */ public void setWidthPercentage(float widthPercentage) { this.widthPercentage = widthPercentage; } /** * Gets the horizontal alignment of the table relative to the page. * * @return the horizontal alignment of the table relative to the page */ public int getHorizontalAlignment() { return horizontalAlignment; } /** * Sets the horizontal alignment of the table relative to the page. * It only has meaning if the width percentage is less than 100%. * * @param horizontalAlignment the horizontal alignment of the table * relative to the page */ public void setHorizontalAlignment(int horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } /** * Gets a row with a given index * (added by Jin-Hsia Yang). * * @param idx * @return the row at position idx */ public PdfPRow getRow(int idx) { return (PdfPRow)rows.get(idx); } /** * Gets an arraylist with all the rows in the table. * * @return an arraylist */ public ArrayList getRows() { return rows; } /** * Gets an arraylist with a selection of rows. * @param start the first row in the selection * @param end the first row that isn't part of the selection * @return a selection of rows * @since 2.1.6 */ public ArrayList getRows(int start, int end) { ArrayList list = new ArrayList(); if (start < 0 || end > size()) { return list; } PdfPRow firstRow = adjustCellsInRow(start, end); int colIndex = 0; PdfPCell cell; while (colIndex < getNumberOfColumns()) { int rowIndex = start; while (rowSpanAbove(rowIndex--, colIndex)) { PdfPRow row = getRow(rowIndex); if (row != null) { PdfPCell replaceCell = row.getCells()[colIndex]; if (replaceCell != null) { firstRow.getCells()[colIndex] = new PdfPCell(replaceCell); float extra = 0; int stop = Math.min(rowIndex + replaceCell.getRowspan(), end); for (int j = start + 1; j < stop; j++) { extra += getRowHeight(j); } firstRow.setExtraHeight(colIndex, extra); float diff = getRowspanHeight(rowIndex, colIndex) - getRowHeight(start) - extra; firstRow.getCells()[colIndex].consumeHeight(diff); } } } cell = firstRow.getCells()[colIndex]; if (cell == null) colIndex++; else colIndex += cell.getColspan(); } list.add(firstRow); for (int i = start + 1; i < end; i++) { list.add(adjustCellsInRow(i, end)); } return list; } /** * Calculates the extra height needed in a row because of rowspans. * @param start the index of the start row (the one to adjust) * @param end the index of the end row on the page * @since 2.1.6 */ protected PdfPRow adjustCellsInRow(int start, int end) { PdfPRow row = new PdfPRow(getRow(start)); row.initExtraHeights(); PdfPCell cell; PdfPCell[] cells = row.getCells(); for (int i = 0; i < cells.length; i++) { cell = cells[i]; if (cell == null || cell.getRowspan() == 1) continue; int stop = Math.min(end, start + cell.getRowspan()); float extra = 0; for (int k = start + 1; k < stop; k++) { extra += getRowHeight(k); } row.setExtraHeight(i, extra); } return row; } /** Sets the table event for this table. * @param event the table event for this table */ public void setTableEvent(PdfPTableEvent event) { if (event == null) this.tableEvent = null; else if (this.tableEvent == null) this.tableEvent = event; else if (this.tableEvent instanceof PdfPTableEventForwarder) ((PdfPTableEventForwarder)this.tableEvent).addTableEvent(event); else { PdfPTableEventForwarder forward = new PdfPTableEventForwarder(); forward.addTableEvent(this.tableEvent); forward.addTableEvent(event); this.tableEvent = forward; } } /** * Gets the table event for this page. * * @return the table event for this page */ public PdfPTableEvent getTableEvent() { return tableEvent; } /** * Gets the absolute sizes of each column width. * * @return he absolute sizes of each column width */ public float[] getAbsoluteWidths() { return absoluteWidths; } float [][] getEventWidths(float xPos, int firstRow, int lastRow, boolean includeHeaders) { if (includeHeaders) { firstRow = Math.max(firstRow, headerRows); lastRow = Math.max(lastRow, headerRows); } float widths[][] = new float[(includeHeaders ? headerRows : 0) + lastRow - firstRow][]; if (isColspan) { int n = 0; if (includeHeaders) { for (int k = 0; k < headerRows; ++k) { PdfPRow row = (PdfPRow)rows.get(k); if (row == null) ++n; else widths[n++] = row.getEventWidth(xPos); } } for (; firstRow < lastRow; ++firstRow) { PdfPRow row = (PdfPRow)rows.get(firstRow); if (row == null) ++n; else widths[n++] = row.getEventWidth(xPos); } } else { int numCols = getNumberOfColumns(); float width[] = new float[numCols + 1]; width[0] = xPos; for (int k = 0; k < numCols; ++k) width[k + 1] = width[k] + absoluteWidths[k]; for (int k = 0; k < widths.length; ++k) widths[k] = width; } return widths; } /** * Tells you if the first header needs to be skipped * (for instance if the header says "continued from the previous page"). * * @return Value of property skipFirstHeader. */ public boolean isSkipFirstHeader() { return skipFirstHeader; } /** * Tells you if the last footer needs to be skipped * (for instance if the footer says "continued on the next page") * * @return Value of property skipLastFooter. * @since 2.1.6 */ public boolean isSkipLastFooter() { return skipLastFooter; } /** * Skips the printing of the first header. Used when printing * tables in succession belonging to the same printed table aspect. * * @param skipFirstHeader New value of property skipFirstHeader. */ public void setSkipFirstHeader(boolean skipFirstHeader) { this.skipFirstHeader = skipFirstHeader; } /** * Skips the printing of the last footer. Used when printing * tables in succession belonging to the same printed table aspect. * * @param skipLastFooter New value of property skipLastFooter. * @since 2.1.6 */ public void setSkipLastFooter(boolean skipLastFooter) { this.skipLastFooter = skipLastFooter; } /** * Sets the run direction of the contents of the table. * * @param runDirection One of the following values: * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. */ public void setRunDirection(int runDirection) { switch (runDirection) { case PdfWriter.RUN_DIRECTION_DEFAULT: case PdfWriter.RUN_DIRECTION_NO_BIDI: case PdfWriter.RUN_DIRECTION_LTR: case PdfWriter.RUN_DIRECTION_RTL: this.runDirection = runDirection; break; default: throw new RuntimeException("Invalid run direction: " + runDirection); } } /** * Returns the run direction of the contents in the table. * * @return One of the following values: * PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, * PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. */ public int getRunDirection() { return runDirection; } /** * Getter for property lockedWidth. * * @return Value of property lockedWidth. */ public boolean isLockedWidth() { return this.lockedWidth; } /** * Uses the value in setTotalWidth() in Document.add(). * * @param lockedWidth true to use the value in setTotalWidth() in Document.add() */ public void setLockedWidth(boolean lockedWidth) { this.lockedWidth = lockedWidth; } /** * Gets the split value. * * @return true to split; false otherwise */ public boolean isSplitRows() { return this.splitRows; } /** * When set the rows that won't fit in the page will be split. * Note that it takes at least twice the memory to handle a split table row * than a normal table. true by default. * * @param splitRows true to split; false otherwise */ public void setSplitRows(boolean splitRows) { this.splitRows = splitRows; } /** * Sets the spacing before this table. * * @param spacing the new spacing */ public void setSpacingBefore(float spacing) { this.spacingBefore = spacing; } /** * Sets the spacing after this table. * * @param spacing the new spacing */ public void setSpacingAfter(float spacing) { this.spacingAfter = spacing; } /** * Gets the spacing before this table. * * @return the spacing */ public float spacingBefore() { return spacingBefore; } /** * Gets the spacing after this table. * * @return the spacing */ public float spacingAfter() { return spacingAfter; } /** * Gets the value of the last row extension. * * @return true if the last row will extend; false otherwise */ public boolean isExtendLastRow() { return extendLastRow; } /** * When set the last row will be extended to fill all the remaining space * to the bottom boundary. * * @param extendLastRow true to extend the last row; false otherwise */ public void setExtendLastRow(boolean extendLastRow) { this.extendLastRow = extendLastRow; } /** * Gets the header status inclusion in PdfPTableEvent. * * @return true if the headers are included; false otherwise */ public boolean isHeadersInEvent() { return headersInEvent; } /** * When set the PdfPTableEvent will include the headers. * * @param headersInEvent true to include the headers; false otherwise */ public void setHeadersInEvent(boolean headersInEvent) { this.headersInEvent = headersInEvent; } /** * Gets the property splitLate. * * @return the property splitLate */ public boolean isSplitLate() { return splitLate; } /** * If true the row will only split if it's the first one in an empty page. * It's true by default. * It's only meaningful if setSplitRows(true). * * @param splitLate the property value */ public void setSplitLate(boolean splitLate) { this.splitLate = splitLate; } /** * If true the table will be kept on one page if it fits, by forcing a * new page if it doesn't fit on the current page. The default is to * split the table over multiple pages. * * @param keepTogether whether to try to keep the table on one page */ public void setKeepTogether(boolean keepTogether) { this.keepTogether = keepTogether; } /** * Getter for property keepTogether * * @return true if it is tried to keep the table on one page; * false otherwise */ public boolean getKeepTogether() { return keepTogether; } /** * Gets the number of rows in the footer. * * @return the number of rows in the footer */ public int getFooterRows() { return this.footerRows; } /** * Sets the number of rows to be used for the footer. The number * of footer rows are subtracted from the header rows. For * example, for a table with two header rows and one footer row the * code would be: *

     * table.setHeaderRows(3);
     * table.setFooterRows(1);
     * 
* Row 0 and 1 will be the header rows and row 2 will be the footer row. * * @param footerRows the number of rows to be used for the footer */ public void setFooterRows(int footerRows) { if (footerRows < 0) footerRows = 0; this.footerRows = footerRows; } /** * Completes the current row with the default cell. An incomplete row will * be dropped but calling this method will make sure that it will be * present in the table. */ public void completeRow() { while (!rowCompleted) { addCell(defaultCell); } } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#flushContent() */ public void flushContent() { deleteBodyRows(); setSkipFirstHeader(true); } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#isComplete() */ public boolean isComplete() { return complete; } /** * @since iText 2.0.8 * @see com.lowagie.text.LargeElement#setComplete(boolean) */ public void setComplete(boolean complete) { this.complete = complete; } }src/core/com/lowagie/text/pdf/PdfPTableEvent.java100644 0 0 11324 11012562273 17354 0ustar 0 0 /* * $Id: PdfPTableEvent.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** An interface that can be used to retrieve the position of cells in PdfPTable. * * @author Paulo Soares (psoares@consiste.pt) */ public interface PdfPTableEvent { /** This method is called at the end of the table rendering. The text or graphics are added to * one of the 4 PdfContentByte contained in * canvases.
* The indexes to canvases are:

*

    *
  • PdfPTable.BASECANVAS - the original PdfContentByte. Anything placed here * will be under the table. *
  • PdfPTable.BACKGROUNDCANVAS - the layer where the background goes to. *
  • PdfPTable.LINECANVAS - the layer where the lines go to. *
  • PdfPTable.TEXTCANVAS - the layer where the text go to. Anything placed here * will be over the table. *
* The layers are placed in sequence on top of each other. *

* The widths and heights have the coordinates of the cells.
* The size of the widths array is the number of rows. * Each sub-array in widths corresponds to the x column border positions where * the first element is the x coordinate of the left table border and the last * element is the x coordinate of the right table border. * If colspan is not used all the sub-arrays in widths * are the same.
* For the heights the first element is the y coordinate of the top table border and the last * element is the y coordinate of the bottom table border. * @param table the PdfPTable in use * @param widths an array of arrays with the cells' x positions. It has the length of the number * of rows * @param heights an array with the cells' y positions. It has a length of the number * of rows + 1 * @param headerRows the number of rows defined for the header. * @param rowStart the first row number after the header * @param canvases an array of PdfContentByte */ public void tableLayout(PdfPTable table, float widths[][], float heights[], int headerRows, int rowStart, PdfContentByte[] canvases); } src/core/com/lowagie/text/pdf/PdfPage.java100644 0 0 15463 11012562273 16067 0ustar 0 0 /* * $Id: PdfPage.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.HashMap; /** * PdfPage is the PDF Page-object. *

* A Page object is a dictionary whose keys describe a single page containing text, * graphics, and images. A Page object is a leaf of the Pages tree.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 6.4 (page 73-81) * * @see PdfPages */ public class PdfPage extends PdfDictionary { private static final String boxStrings[] = {"crop", "trim", "art", "bleed"}; private static final PdfName boxNames[] = {PdfName.CROPBOX, PdfName.TRIMBOX, PdfName.ARTBOX, PdfName.BLEEDBOX}; // membervariables /** value of the Rotate key for a page in PORTRAIT */ public static final PdfNumber PORTRAIT = new PdfNumber(0); /** value of the Rotate key for a page in LANDSCAPE */ public static final PdfNumber LANDSCAPE = new PdfNumber(90); /** value of the Rotate key for a page in INVERTEDPORTRAIT */ public static final PdfNumber INVERTEDPORTRAIT = new PdfNumber(180); /** value of the Rotate key for a page in SEASCAPE */ public static final PdfNumber SEASCAPE = new PdfNumber(270); /** value of the MediaBox key */ PdfRectangle mediaBox; // constructors /** * Constructs a PdfPage. * * @param mediaBox a value for the MediaBox key * @param resources an indirect reference to a PdfResources-object * @param rotate a value for the Rotate key */ // PdfPage(PdfRectangle mediaBox, Rectangle cropBox, PdfIndirectReference resources, PdfNumber rotate) { // super(PAGE); // this.mediaBox = mediaBox; // put(PdfName.MEDIABOX, mediaBox); // put(PdfName.RESOURCES, resources); // if (rotate != null) { // put(PdfName.ROTATE, rotate); // } // if (cropBox != null) // put(PdfName.CROPBOX, new PdfRectangle(cropBox)); // } /** * Constructs a PdfPage. * * @param mediaBox a value for the MediaBox key * @param resources an indirect reference to a PdfResources-object * @param rotate a value for the Rotate key */ PdfPage(PdfRectangle mediaBox, HashMap boxSize, PdfDictionary resources, int rotate) { super(PAGE); this.mediaBox = mediaBox; put(PdfName.MEDIABOX, mediaBox); put(PdfName.RESOURCES, resources); if (rotate != 0) { put(PdfName.ROTATE, new PdfNumber(rotate)); } for (int k = 0; k < boxStrings.length; ++k) { PdfObject rect = (PdfObject)boxSize.get(boxStrings[k]); if (rect != null) put(boxNames[k], rect); } } /** * Constructs a PdfPage. * * @param mediaBox a value for the MediaBox key * @param resources an indirect reference to a PdfResources-object */ // PdfPage(PdfRectangle mediaBox, Rectangle cropBox, PdfIndirectReference resources) { // this(mediaBox, cropBox, resources, null); // } /** * Constructs a PdfPage. * * @param mediaBox a value for the MediaBox key * @param resources an indirect reference to a PdfResources-object */ PdfPage(PdfRectangle mediaBox, HashMap boxSize, PdfDictionary resources) { this(mediaBox, boxSize, resources, 0); } /** * Checks if this page element is a tree of pages. *

* This method always returns false. * * @return false because this is a single page */ public boolean isParent() { return false; } // methods /** * Adds an indirect reference pointing to a PdfContents-object. * * @param contents an indirect reference to a PdfContents-object */ void add(PdfIndirectReference contents) { put(PdfName.CONTENTS, contents); } /** * Rotates the mediabox, but not the text in it. * * @return a PdfRectangle */ PdfRectangle rotateMediaBox() { this.mediaBox = mediaBox.rotate(); put(PdfName.MEDIABOX, this.mediaBox); return this.mediaBox; } /** * Returns the MediaBox of this Page. * * @return a PdfRectangle */ PdfRectangle getMediaBox() { return mediaBox; } }src/core/com/lowagie/text/pdf/PdfPageElement.java100644 0 0 6154 11012562273 17356 0ustar 0 0 /* * $Id: PdfPageElement.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * The PdfPageElement interface has to be implemented by PdfPage and PdfPages. * * @see PdfPage * @see PdfPages */ interface PdfPageElement { /** * Set the value for the Parent key in the Page or Pages Dictionary. * * @param reference an indirect reference to a PdfPages-object */ public void setParent(PdfIndirectReference reference); /** * Checks if this page element is a tree of pages. * * @return true if it's a tree of pages; * false if it's a single page */ public boolean isParent(); }src/core/com/lowagie/text/pdf/PdfPageEvent.java100644 0 0 16133 11012562273 17064 0ustar 0 0 /* * $Id: PdfPageEvent.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; /** * Allows a class to catch several document events. *

* Note: do not use Document.add() inside a page event. * * @author Paulo Soares (psoares@consiste.pt) */ public interface PdfPageEvent { /** * Called when the document is opened. * * @param writer the PdfWriter for this document * @param document the document */ public void onOpenDocument(PdfWriter writer, Document document); /** * Called when a page is initialized. *

* Note that if even if a page is not written this method is still * called. It is preferable to use onEndPage to avoid * infinite loops. * * @param writer the PdfWriter for this document * @param document the document */ public void onStartPage(PdfWriter writer, Document document); /** * Called when a page is finished, just before being written to the document. * * @param writer the PdfWriter for this document * @param document the document */ public void onEndPage(PdfWriter writer, Document document); /** * Called when the document is closed. *

* Note that this method is called with the page number equal * to the last page plus one. * * @param writer the PdfWriter for this document * @param document the document */ public void onCloseDocument(PdfWriter writer, Document document); /** * Called when a Paragraph is written. *

* paragraphPosition will hold the height at which the * paragraph will be written to. This is useful to insert bookmarks with * more control. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the paragraph will be written to */ public void onParagraph(PdfWriter writer, Document document, float paragraphPosition); /** * Called when a Paragraph is written. *

* paragraphPosition will hold the height of the end of the paragraph. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position of the end of the paragraph */ public void onParagraphEnd(PdfWriter writer,Document document,float paragraphPosition); /** * Called when a Chapter is written. *

* position will hold the height at which the * chapter will be written to. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the chapter will be written to * @param title the title of the Chapter */ public void onChapter(PdfWriter writer,Document document,float paragraphPosition, Paragraph title); /** * Called when the end of a Chapter is reached. *

* position will hold the height of the end of the chapter. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the chapter will be written to */ public void onChapterEnd(PdfWriter writer,Document document,float paragraphPosition); /** * Called when a Section is written. *

* position will hold the height at which the * section will be written to. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the section will be written to * @param depth the number depth of the section * @param title the title of the section */ public void onSection(PdfWriter writer,Document document,float paragraphPosition, int depth, Paragraph title); /** * Called when the end of a Section is reached. *

* position will hold the height of the section end. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the section will be written to */ public void onSectionEnd(PdfWriter writer,Document document,float paragraphPosition); /** * Called when a Chunk with a generic tag is written. *

* It is useful to pinpoint the Chunk location to generate * bookmarks, for example. * * @param writer the PdfWriter for this document * @param document the document * @param rect the Rectangle containing the Chunk * @param text the text of the tag */ public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text); } src/core/com/lowagie/text/pdf/PdfPageEventHelper.java100644 0 0 16350 11012562273 20225 0ustar 0 0 /* * $Id: PdfPageEventHelper.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; /** * Helps the use of PdfPageEvent by implementing all the interface methods. * A class can extend PdfPageEventHelper and only implement the * needed methods. *

* Note: do not use Document.add() inside a page event. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfPageEventHelper implements PdfPageEvent { /** * Called when the document is opened. * * @param writer the PdfWriter for this document * @param document the document */ public void onOpenDocument(PdfWriter writer,Document document) { } /** * Called when a page is initialized. *

* Note that if even if a page is not written this method is still * called. It is preferable to use onEndPage to avoid * infinite loops. * * @param writer the PdfWriter for this document * @param document the document */ public void onStartPage(PdfWriter writer,Document document) { } /** * Called when a page is finished, just before being written to the document. * * @param writer the PdfWriter for this document * @param document the document */ public void onEndPage(PdfWriter writer,Document document) { } /** * Called when the document is closed. *

* Note that this method is called with the page number equal * to the last page plus one. * * @param writer the PdfWriter for this document * @param document the document */ public void onCloseDocument(PdfWriter writer,Document document) { } /** * Called when a Paragraph is written. *

* paragraphPosition will hold the height at which the * paragraph will be written to. This is useful to insert bookmarks with * more control. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the paragraph will be written to */ public void onParagraph(PdfWriter writer,Document document,float paragraphPosition) { } /** * Called when a Paragraph is written. *

* paragraphPosition will hold the height of the end of the paragraph. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position of the end of the paragraph */ public void onParagraphEnd(PdfWriter writer,Document document,float paragraphPosition) { } /** * Called when a Chapter is written. *

* position will hold the height at which the * chapter will be written to. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the chapter will be written to * @param title the title of the Chapter */ public void onChapter(PdfWriter writer,Document document,float paragraphPosition,Paragraph title) { } /** * Called when the end of a Chapter is reached. *

* position will hold the height of the end of the chapter. * * @param writer the PdfWriter for this document * @param document the document * @param position the position of the end of the chapter. */ public void onChapterEnd(PdfWriter writer,Document document,float position) { } /** * Called when a Section is written. *

* position will hold the height at which the * section will be written to. * * @param writer the PdfWriter for this document * @param document the document * @param paragraphPosition the position the section will be written to * @param depth the number depth of the Section * @param title the title of the section */ public void onSection(PdfWriter writer,Document document,float paragraphPosition,int depth,Paragraph title) { } /** * Called when the end of a Section is reached. *

* position will hold the height of the section end. * * @param writer the PdfWriter for this document * @param document the document * @param position the position of the end of the section */ public void onSectionEnd(PdfWriter writer,Document document,float position) { } /** * Called when a Chunk with a generic tag is written. *

* It is useful to pinpoint the Chunk location to generate * bookmarks, for example. * * @param writer the PdfWriter for this document * @param document the document * @param rect the Rectangle containing the Chunk * @param text the text of the tag */ public void onGenericTag(PdfWriter writer,Document document,Rectangle rect,String text) { } } src/core/com/lowagie/text/pdf/PdfPageLabels.java100644 0 0 27525 11012562273 17214 0ustar 0 0 /* * $Id: PdfPageLabels.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.ExceptionConverter; import java.io.IOException; import java.util.HashMap; import com.lowagie.text.factories.RomanAlphabetFactory; import com.lowagie.text.factories.RomanNumberFactory; import java.util.Arrays; /** Page labels are used to identify each * page visually on the screen or in print. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfPageLabels { /** Logical pages will have the form 1,2,3,... */ public static final int DECIMAL_ARABIC_NUMERALS = 0; /** Logical pages will have the form I,II,III,IV,... */ public static final int UPPERCASE_ROMAN_NUMERALS = 1; /** Logical pages will have the form i,ii,iii,iv,... */ public static final int LOWERCASE_ROMAN_NUMERALS = 2; /** Logical pages will have the form of uppercase letters * (A to Z for the first 26 pages, AA to ZZ for the next 26, and so on) */ public static final int UPPERCASE_LETTERS = 3; /** Logical pages will have the form of uppercase letters * (a to z for the first 26 pages, aa to zz for the next 26, and so on) */ public static final int LOWERCASE_LETTERS = 4; /** No logical page numbers are generated but fixed text may * still exist */ public static final int EMPTY = 5; /** Dictionary values to set the logical page styles */ static PdfName numberingStyle[] = new PdfName[]{PdfName.D, PdfName.R, new PdfName("r"), PdfName.A, new PdfName("a")}; /** The sequence of logical pages. Will contain at least a value for page 1 */ private HashMap map; /** Creates a new PdfPageLabel with a default logical page 1 */ public PdfPageLabels() { map = new HashMap(); addPageLabel(1, DECIMAL_ARABIC_NUMERALS, null, 1); } /** Adds or replaces a page label. * @param page the real page to start the numbering. First page is 1 * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS * @param text the text to prefix the number. Can be null or empty * @param firstPage the first logical page number */ public void addPageLabel(int page, int numberStyle, String text, int firstPage) { if (page < 1 || firstPage < 1) throw new IllegalArgumentException("In a page label the page numbers must be greater or equal to 1."); PdfDictionary dic = new PdfDictionary(); if (numberStyle >= 0 && numberStyle < numberingStyle.length) dic.put(PdfName.S, numberingStyle[numberStyle]); if (text != null) dic.put(PdfName.P, new PdfString(text, PdfObject.TEXT_UNICODE)); if (firstPage != 1) dic.put(PdfName.ST, new PdfNumber(firstPage)); map.put(new Integer(page - 1), dic); } /** Adds or replaces a page label. The first logical page has the default * of 1. * @param page the real page to start the numbering. First page is 1 * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS * @param text the text to prefix the number. Can be null or empty */ public void addPageLabel(int page, int numberStyle, String text) { addPageLabel(page, numberStyle, text, 1); } /** Adds or replaces a page label. There is no text prefix and the first * logical page has the default of 1. * @param page the real page to start the numbering. First page is 1 * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS */ public void addPageLabel(int page, int numberStyle) { addPageLabel(page, numberStyle, null, 1); } /** Adds or replaces a page label. */ public void addPageLabel(PdfPageLabelFormat format) { addPageLabel(format.physicalPage, format.numberStyle, format.prefix, format.logicalPage); } /** Removes a page label. The first page label can not be removed, only changed. * @param page the real page to remove */ public void removePageLabel(int page) { if (page <= 1) return; map.remove(new Integer(page - 1)); } /** Gets the page label dictionary to insert into the document. * @return the page label dictionary */ PdfDictionary getDictionary(PdfWriter writer) { try { return PdfNumberTree.writeTree(map, writer); } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Retrieves the page labels from a PDF as an array of String objects. * @param reader a PdfReader object that has the page labels you want to retrieve * @return a String array or null if no page labels are present */ public static String[] getPageLabels(PdfReader reader) { int n = reader.getNumberOfPages(); PdfDictionary dict = reader.getCatalog(); PdfDictionary labels = (PdfDictionary)PdfReader.getPdfObjectRelease(dict.get(PdfName.PAGELABELS)); if (labels == null) return null; String[] labelstrings = new String[n]; HashMap numberTree = PdfNumberTree.readTree(labels); int pagecount = 1; Integer current; String prefix = ""; char type = 'D'; for (int i = 0; i < n; i++) { current = new Integer(i); if (numberTree.containsKey(current)) { PdfDictionary d = (PdfDictionary)PdfReader.getPdfObjectRelease((PdfObject)numberTree.get(current)); if (d.contains(PdfName.ST)) { pagecount = ((PdfNumber)d.get(PdfName.ST)).intValue(); } else { pagecount = 1; } if (d.contains(PdfName.P)) { prefix = ((PdfString)d.get(PdfName.P)).toUnicodeString(); } if (d.contains(PdfName.S)) { type = ((PdfName)d.get(PdfName.S)).toString().charAt(1); } } switch(type) { default: labelstrings[i] = prefix + pagecount; break; case 'R': labelstrings[i] = prefix + RomanNumberFactory.getUpperCaseString(pagecount); break; case 'r': labelstrings[i] = prefix + RomanNumberFactory.getLowerCaseString(pagecount); break; case 'A': labelstrings[i] = prefix + RomanAlphabetFactory.getUpperCaseString(pagecount); break; case 'a': labelstrings[i] = prefix + RomanAlphabetFactory.getLowerCaseString(pagecount); break; } pagecount++; } return labelstrings; } /** * Retrieves the page labels from a PDF as an array of {@link PdfPageLabelFormat} objects. * @param reader a PdfReader object that has the page labels you want to retrieve * @return a PdfPageLabelEntry array, containing an entry for each format change * or null if no page labels are present */ public static PdfPageLabelFormat[] getPageLabelFormats(PdfReader reader) { PdfDictionary dict = reader.getCatalog(); PdfDictionary labels = (PdfDictionary)PdfReader.getPdfObjectRelease(dict.get(PdfName.PAGELABELS)); if (labels == null) return null; HashMap numberTree = PdfNumberTree.readTree(labels); Integer numbers[] = new Integer[numberTree.size()]; numbers = (Integer[])numberTree.keySet().toArray(numbers); Arrays.sort(numbers); PdfPageLabelFormat[] formats = new PdfPageLabelFormat[numberTree.size()]; String prefix; int numberStyle; int pagecount; for (int k = 0; k < numbers.length; ++k) { Integer key = numbers[k]; PdfDictionary d = (PdfDictionary)PdfReader.getPdfObjectRelease((PdfObject)numberTree.get(key)); if (d.contains(PdfName.ST)) { pagecount = ((PdfNumber)d.get(PdfName.ST)).intValue(); } else { pagecount = 1; } if (d.contains(PdfName.P)) { prefix = ((PdfString)d.get(PdfName.P)).toUnicodeString(); } else { prefix = ""; } if (d.contains(PdfName.S)) { char type = ((PdfName)d.get(PdfName.S)).toString().charAt(1); switch(type) { case 'R': numberStyle = UPPERCASE_ROMAN_NUMERALS; break; case 'r': numberStyle = LOWERCASE_ROMAN_NUMERALS; break; case 'A': numberStyle = UPPERCASE_LETTERS; break; case 'a': numberStyle = LOWERCASE_LETTERS; break; default: numberStyle = DECIMAL_ARABIC_NUMERALS; break; } } else { numberStyle = EMPTY; } formats[k] = new PdfPageLabelFormat(key.intValue()+1, numberStyle, prefix, pagecount); } return formats; } public static class PdfPageLabelFormat { public int physicalPage; public int numberStyle; public String prefix; public int logicalPage; /** Creates a page label format. * @param physicalPage the real page to start the numbering. First page is 1 * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS * @param prefix the text to prefix the number. Can be null or empty * @param logicalPage the first logical page number */ public PdfPageLabelFormat(int physicalPage, int numberStyle, String prefix, int logicalPage) { this.physicalPage = physicalPage; this.numberStyle = numberStyle; this.prefix = prefix; this.logicalPage = logicalPage; } } }src/core/com/lowagie/text/pdf/PdfPages.java100644 0 0 20053 11213370070 16234 0ustar 0 0 /* * $Id: PdfPages.java 3934 2009-05-27 11:23:23Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.ArrayList; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; /** * PdfPages is the PDF Pages-object. *

* The Pages of a document are accessible through a tree of nodes known as the Pages tree. * This tree defines the ordering of the pages in the document.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 6.3 (page 71-73) * * @see PdfPage */ public class PdfPages { private ArrayList pages = new ArrayList(); private ArrayList parents = new ArrayList(); private int leafSize = 10; private PdfWriter writer; private PdfIndirectReference topParent; // constructors /** * Constructs a PdfPages-object. */ PdfPages(PdfWriter writer) { this.writer = writer; } void addPage(PdfDictionary page) { try { if ((pages.size() % leafSize) == 0) parents.add(writer.getPdfIndirectReference()); PdfIndirectReference parent = (PdfIndirectReference)parents.get(parents.size() - 1); page.put(PdfName.PARENT, parent); PdfIndirectReference current = writer.getCurrentPage(); writer.addToBody(page, current); pages.add(current); } catch (Exception e) { throw new ExceptionConverter(e); } } PdfIndirectReference addPageRef(PdfIndirectReference pageRef) { try { if ((pages.size() % leafSize) == 0) parents.add(writer.getPdfIndirectReference()); pages.add(pageRef); return (PdfIndirectReference)parents.get(parents.size() - 1); } catch (Exception e) { throw new ExceptionConverter(e); } } // returns the top parent to include in the catalog PdfIndirectReference writePageTree() throws IOException { if (pages.isEmpty()) throw new IOException("The document has no pages."); int leaf = 1; ArrayList tParents = parents; ArrayList tPages = pages; ArrayList nextParents = new ArrayList(); while (true) { leaf *= leafSize; int stdCount = leafSize; int rightCount = tPages.size() % leafSize; if (rightCount == 0) rightCount = leafSize; for (int p = 0; p < tParents.size(); ++p) { int count; int thisLeaf = leaf; if (p == tParents.size() - 1) { count = rightCount; thisLeaf = pages.size() % leaf; if (thisLeaf == 0) thisLeaf = leaf; } else count = stdCount; PdfDictionary top = new PdfDictionary(PdfName.PAGES); top.put(PdfName.COUNT, new PdfNumber(thisLeaf)); PdfArray kids = new PdfArray(); ArrayList internal = kids.getArrayList(); internal.addAll(tPages.subList(p * stdCount, p * stdCount + count)); top.put(PdfName.KIDS, kids); if (tParents.size() > 1) { if ((p % leafSize) == 0) nextParents.add(writer.getPdfIndirectReference()); top.put(PdfName.PARENT, (PdfIndirectReference)nextParents.get(p / leafSize)); } else { top.put(PdfName.ITXT, new PdfString(Document.getRelease())); } writer.addToBody(top, (PdfIndirectReference)tParents.get(p)); } if (tParents.size() == 1) { topParent = (PdfIndirectReference)tParents.get(0); return topParent; } tPages = tParents; tParents = nextParents; nextParents = new ArrayList(); } } PdfIndirectReference getTopParent() { return topParent; } void setLinearMode(PdfIndirectReference topParent) { if (parents.size() > 1) throw new RuntimeException("Linear page mode can only be called with a single parent."); if (topParent != null) { this.topParent = topParent; parents.clear(); parents.add(topParent); } leafSize = 10000000; } void addPage(PdfIndirectReference page) { pages.add(page); } int reorderPages(int order[]) throws DocumentException { if (order == null) return pages.size(); if (parents.size() > 1) throw new DocumentException("Page reordering requires a single parent in the page tree. Call PdfWriter.setLinearMode() after open."); if (order.length != pages.size()) throw new DocumentException("Page reordering requires an array with the same size as the number of pages."); int max = pages.size(); boolean temp[] = new boolean[max]; for (int k = 0; k < max; ++k) { int p = order[k]; if (p < 1 || p > max) throw new DocumentException("Page reordering requires pages between 1 and " + max + ". Found " + p + "."); if (temp[p - 1]) throw new DocumentException("Page reordering requires no page repetition. Page " + p + " is repeated."); temp[p - 1] = true; } Object copy[] = pages.toArray(); for (int k = 0; k < max; ++k) { pages.set(k, copy[order[k] - 1]); } return max; } }src/core/com/lowagie/text/pdf/PdfPattern.java100644 0 0 7646 11036112746 16616 0ustar 0 0 /* * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.ExceptionConverter; /** * A PdfPattern defines a ColorSpace * * @see PdfStream */ public class PdfPattern extends PdfStream { /** * Creates a PdfPattern object. * @param painter a pattern painter instance */ PdfPattern(PdfPatternPainter painter) { this(painter, DEFAULT_COMPRESSION); } /** * Creates a PdfPattern object. * @param painter a pattern painter instance * @param compressionLevel the compressionLevel for the stream * @since 2.1.3 */ PdfPattern(PdfPatternPainter painter, int compressionLevel) { super(); PdfNumber one = new PdfNumber(1); PdfArray matrix = painter.getMatrix(); if ( matrix != null ) { put(PdfName.MATRIX, matrix); } put(PdfName.TYPE, PdfName.PATTERN); put(PdfName.BBOX, new PdfRectangle(painter.getBoundingBox())); put(PdfName.RESOURCES, painter.getResources()); put(PdfName.TILINGTYPE, one); put(PdfName.PATTERNTYPE, one); if (painter.isStencil()) put(PdfName.PAINTTYPE, new PdfNumber(2)); else put(PdfName.PAINTTYPE, one); put(PdfName.XSTEP, new PdfNumber(painter.getXStep())); put(PdfName.YSTEP, new PdfNumber(painter.getYStep())); bytes = painter.toPdf(null); put(PdfName.LENGTH, new PdfNumber(bytes.length)); try { flateCompress(compressionLevel); } catch (Exception e) { throw new ExceptionConverter(e); } } } src/core/com/lowagie/text/pdf/PdfPatternPainter.java100644 0 0 30122 11036112746 20142 0ustar 0 0 /* * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; /** * Implements the pattern. */ public final class PdfPatternPainter extends PdfTemplate { float xstep, ystep; boolean stencil = false; Color defaultColor; /** *Creates a PdfPattern. */ private PdfPatternPainter() { super(); type = TYPE_PATTERN; } /** * Creates new PdfPattern * * @param wr the PdfWriter */ PdfPatternPainter(PdfWriter wr) { super(wr); type = TYPE_PATTERN; } PdfPatternPainter(PdfWriter wr, Color defaultColor) { this(wr); stencil = true; if (defaultColor == null) this.defaultColor = Color.gray; else this.defaultColor = defaultColor; } /** * Sets the horizontal interval of this pattern. * * @param xstep the xstep in horizontal painting */ public void setXStep(float xstep) { this.xstep = xstep; } /** * Sets the vertical interval of this pattern. * * @param ystep in vertical painting */ public void setYStep(float ystep) { this.ystep = ystep; } /** * Returns the horizontal interval when repeating the pattern. * @return a value */ public float getXStep() { return this.xstep; } /** * Returns the vertical interval when repeating the pattern. * @return a value */ public float getYStep() { return this.ystep; } /** * Tells you if this pattern is colored/uncolored (stencil = uncolored, you need to set a default color). * @return true if the pattern is an uncolored tiling pattern (stencil). */ public boolean isStencil() { return stencil; } /** * Sets the transformation matrix for the pattern. * @param a * @param b * @param c * @param d * @param e * @param f */ public void setPatternMatrix(float a, float b, float c, float d, float e, float f) { setMatrix(a, b, c, d, e, f); } /** * Gets the stream representing this pattern * @return the stream representing this pattern */ PdfPattern getPattern() { return new PdfPattern(this); } /** * Gets the stream representing this pattern * @param compressionLevel the compression level of the stream * @return the stream representing this pattern * @since 2.1.3 */ PdfPattern getPattern(int compressionLevel) { return new PdfPattern(this, compressionLevel); } /** * Gets a duplicate of this PdfPatternPainter. All * the members are copied by reference but the buffer stays different. * @return a copy of this PdfPatternPainter */ public PdfContentByte getDuplicate() { PdfPatternPainter tpl = new PdfPatternPainter(); tpl.writer = writer; tpl.pdf = pdf; tpl.thisReference = thisReference; tpl.pageResources = pageResources; tpl.bBox = new Rectangle(bBox); tpl.xstep = xstep; tpl.ystep = ystep; tpl.matrix = matrix; tpl.stencil = stencil; tpl.defaultColor = defaultColor; return tpl; } /** * Returns the default color of the pattern. * @return a Color */ public Color getDefaultColor() { return defaultColor; } /** * @see com.lowagie.text.pdf.PdfContentByte#setGrayFill(float) */ public void setGrayFill(float gray) { checkNoColor(); super.setGrayFill(gray); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetGrayFill() */ public void resetGrayFill() { checkNoColor(); super.resetGrayFill(); } /** * @see com.lowagie.text.pdf.PdfContentByte#setGrayStroke(float) */ public void setGrayStroke(float gray) { checkNoColor(); super.setGrayStroke(gray); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetGrayStroke() */ public void resetGrayStroke() { checkNoColor(); super.resetGrayStroke(); } /** * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFillF(float, float, float) */ public void setRGBColorFillF(float red, float green, float blue) { checkNoColor(); super.setRGBColorFillF(red, green, blue); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorFill() */ public void resetRGBColorFill() { checkNoColor(); super.resetRGBColorFill(); } /** * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStrokeF(float, float, float) */ public void setRGBColorStrokeF(float red, float green, float blue) { checkNoColor(); super.setRGBColorStrokeF(red, green, blue); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorStroke() */ public void resetRGBColorStroke() { checkNoColor(); super.resetRGBColorStroke(); } /** * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFillF(float, float, float, float) */ public void setCMYKColorFillF(float cyan, float magenta, float yellow, float black) { checkNoColor(); super.setCMYKColorFillF(cyan, magenta, yellow, black); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorFill() */ public void resetCMYKColorFill() { checkNoColor(); super.resetCMYKColorFill(); } /** * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStrokeF(float, float, float, float) */ public void setCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) { checkNoColor(); super.setCMYKColorStrokeF(cyan, magenta, yellow, black); } /** * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorStroke() */ public void resetCMYKColorStroke() { checkNoColor(); super.resetCMYKColorStroke(); } /** * @see com.lowagie.text.pdf.PdfContentByte#addImage(com.lowagie.text.Image, float, float, float, float, float, float) */ public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { if (stencil && !image.isMask()) checkNoColor(); super.addImage(image, a, b, c, d, e, f); } /** * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFill(int, int, int, int) */ public void setCMYKColorFill(int cyan, int magenta, int yellow, int black) { checkNoColor(); super.setCMYKColorFill(cyan, magenta, yellow, black); } /** * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStroke(int, int, int, int) */ public void setCMYKColorStroke(int cyan, int magenta, int yellow, int black) { checkNoColor(); super.setCMYKColorStroke(cyan, magenta, yellow, black); } /** * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFill(int, int, int) */ public void setRGBColorFill(int red, int green, int blue) { checkNoColor(); super.setRGBColorFill(red, green, blue); } /** * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStroke(int, int, int) */ public void setRGBColorStroke(int red, int green, int blue) { checkNoColor(); super.setRGBColorStroke(red, green, blue); } /** * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(java.awt.Color) */ public void setColorStroke(Color color) { checkNoColor(); super.setColorStroke(color); } /** * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(java.awt.Color) */ public void setColorFill(Color color) { checkNoColor(); super.setColorFill(color); } /** * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(com.lowagie.text.pdf.PdfSpotColor, float) */ public void setColorFill(PdfSpotColor sp, float tint) { checkNoColor(); super.setColorFill(sp, tint); } /** * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(com.lowagie.text.pdf.PdfSpotColor, float) */ public void setColorStroke(PdfSpotColor sp, float tint) { checkNoColor(); super.setColorStroke(sp, tint); } /** * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter) */ public void setPatternFill(PdfPatternPainter p) { checkNoColor(); super.setPatternFill(p); } /** * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float) */ public void setPatternFill(PdfPatternPainter p, Color color, float tint) { checkNoColor(); super.setPatternFill(p, color, tint); } /** * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float) */ public void setPatternStroke(PdfPatternPainter p, Color color, float tint) { checkNoColor(); super.setPatternStroke(p, color, tint); } /** * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter) */ public void setPatternStroke(PdfPatternPainter p) { checkNoColor(); super.setPatternStroke(p); } void checkNoColor() { if (stencil) throw new RuntimeException("Colors are not allowed in uncolored tile patterns."); } } src/core/com/lowagie/text/pdf/PdfPrinterGraphics2D.java100644 0 0 6264 11012562273 20464 0ustar 0 0 /* * $Id: PdfPrinterGraphics2D.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2004 Paulo Soares and Alexandru Carstoiu * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.print.PrinterGraphics; import java.awt.print.PrinterJob; /** * This is an extension class for the sole purpose of implementing the * {@link java.awt.print.PrinterGraphics PrinterGraphics} interface. */ public class PdfPrinterGraphics2D extends PdfGraphics2D implements PrinterGraphics { private PrinterJob printerJob; public PdfPrinterGraphics2D(PdfContentByte cb, float width, float height, FontMapper fontMapper, boolean onlyShapes, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { super(cb, width, height, fontMapper, onlyShapes, convertImagesToJPEG, quality); this.printerJob = printerJob; } public PrinterJob getPrinterJob() { return printerJob; } } src/core/com/lowagie/text/pdf/PdfPublicKeyRecipient.java100644 0 0 6075 11012562273 20724 0ustar 0 0 /* * $Id: PdfPublicKeyRecipient.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.security.cert.Certificate; public class PdfPublicKeyRecipient { private Certificate certificate = null; private int permission = 0; protected byte[] cms = null; public PdfPublicKeyRecipient(Certificate certificate, int permission) { this.certificate = certificate; this.permission = permission; } public Certificate getCertificate() { return certificate; } public int getPermission() { return permission; } protected void setCms(byte[] cms) { this.cms = cms; } protected byte[] getCms() { return cms; } } src/core/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java100644 0 0 32551 11012562273 22125 0ustar 0 0 /* * $Id: PdfPublicKeySecurityHandler.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ /** * The below 2 methods are from pdfbox. * * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); * * 2006-11-22 Aiken Sam. */ /** * Copyright (c) 2003-2006, www.pdfbox.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of pdfbox; nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * http://www.pdfbox.org * */ package com.lowagie.text.pdf; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.ArrayList; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; import org.bouncycastle.asn1.cms.EnvelopedData; import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; import org.bouncycastle.asn1.cms.RecipientIdentifier; import org.bouncycastle.asn1.cms.RecipientInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.TBSCertificateStructure; /** * @author Aiken Sam (aikensam@ieee.org) */ public class PdfPublicKeySecurityHandler { static final int SEED_LENGTH = 20; private ArrayList recipients = null; private byte[] seed = new byte[SEED_LENGTH]; public PdfPublicKeySecurityHandler() { KeyGenerator key; try { key = KeyGenerator.getInstance("AES"); key.init(192, new SecureRandom()); SecretKey sk = key.generateKey(); System.arraycopy(sk.getEncoded(), 0, seed, 0, SEED_LENGTH); // create the 20 bytes seed } catch (NoSuchAlgorithmException e) { seed = SecureRandom.getSeed(SEED_LENGTH); } recipients = new ArrayList(); } /* * Routine for decode output of PdfContentByte.escapeString(byte[] bytes). * It should be moved to PdfContentByte. */ static public byte[] unescapedString(byte[] bytes) throws BadPdfFormatException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int index = 0; if (bytes[0] != '(' && bytes[bytes.length-1] != ')') throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); while (index < bytes.length) { if (bytes[index] == '\\') { index++; switch (bytes[index]) { case 'b': baos.write('\b'); break; case 'f': baos.write('\f'); break; case 't': baos.write('\t'); break; case 'n': baos.write('\n'); break; case 'r': baos.write('\r'); break; case '(': baos.write('('); break; case ')': baos.write(')'); break; case '\\': baos.write('\\'); break; } } else baos.write(bytes[index]); index++; } return baos.toByteArray(); } public void addRecipient(PdfPublicKeyRecipient recipient) { recipients.add(recipient); } protected byte[] getSeed() { return (byte[])seed.clone(); } /* public PdfPublicKeyRecipient[] getRecipients() { recipients.toArray(); return (PdfPublicKeyRecipient[])recipients.toArray(); }*/ public int getRecipientsSize() { return recipients.size(); } public byte[] getEncodedRecipient(int index) throws IOException, GeneralSecurityException { //Certificate certificate = recipient.getX509(); PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient)recipients.get(index); byte[] cms = recipient.getCms(); if (cms != null) return cms; Certificate certificate = recipient.getCertificate(); int permission = recipient.getPermission();//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly; int revision = 3; permission |= revision==3 ? 0xfffff0c0 : 0xffffffc0; permission &= 0xfffffffc; permission += 1; byte[] pkcs7input = new byte[24]; byte one = (byte)(permission); byte two = (byte)(permission >> 8); byte three = (byte)(permission >> 16); byte four = (byte)(permission >> 24); System.arraycopy(seed, 0, pkcs7input, 0, 20); // put this seed in the pkcs7 input pkcs7input[20] = four; pkcs7input[21] = three; pkcs7input[22] = two; pkcs7input[23] = one; DERObject obj = createDERForRecipient(pkcs7input, (X509Certificate)certificate); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DEROutputStream k = new DEROutputStream(baos); k.writeObject(obj); cms = baos.toByteArray(); recipient.setCms(cms); return cms; } public PdfArray getEncodedRecipients() throws IOException, GeneralSecurityException { PdfArray EncodedRecipients = new PdfArray(); byte[] cms = null; for (int i=0; i -1, 0 // type 1 -> offset, 0 // type 2 -> index, obj num protected int xref[]; protected HashMap objStmMark; protected IntHashtable objStmToOffset; protected boolean newXrefType; private ArrayList xrefObj; PdfDictionary rootPages; protected PdfDictionary trailer; protected PdfDictionary catalog; protected PageRefs pageRefs; protected PRAcroForm acroForm = null; protected boolean acroFormParsed = false; protected boolean encrypted = false; protected boolean rebuilt = false; protected int freeXref; protected boolean tampered = false; protected int lastXref; protected int eofPos; protected char pdfVersion; protected PdfEncryption decrypt; protected byte password[] = null; //added by ujihara for decryption protected Key certificateKey = null; //added by Aiken Sam for certificate decryption protected Certificate certificate = null; //added by Aiken Sam for certificate decryption protected String certificateKeyProvider = null; //added by Aiken Sam for certificate decryption private boolean ownerPasswordUsed; protected ArrayList strings = new ArrayList(); protected boolean sharedStreams = true; protected boolean consolidateNamedDestinations = false; protected int rValue; protected int pValue; private int objNum; private int objGen; private int fileLength; private boolean hybridXref; private int lastXrefPartial = -1; private boolean partial; private PRIndirectReference cryptoRef; private PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp(); private boolean encryptionError; /** * Holds value of property appendable. */ private boolean appendable; protected PdfReader() { } /** Reads and parses a PDF document. * @param filename the file name of the document * @throws IOException on error */ public PdfReader(String filename) throws IOException { this(filename, null); } /** Reads and parses a PDF document. * @param filename the file name of the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(String filename, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(filename); readPdf(); } /** Reads and parses a PDF document. * @param pdfIn the byte array with the document * @throws IOException on error */ public PdfReader(byte pdfIn[]) throws IOException { this(pdfIn, null); } /** Reads and parses a PDF document. * @param pdfIn the byte array with the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(byte pdfIn[], byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(pdfIn); readPdf(); } /** Reads and parses a PDF document. * @param filename the file name of the document * @param certificate the certificate to read the document * @param certificateKey the private key of the certificate * @param certificateKeyProvider the security provider for certificateKey * @throws IOException on error */ public PdfReader(String filename, Certificate certificate, Key certificateKey, String certificateKeyProvider) throws IOException { this.certificate = certificate; this.certificateKey = certificateKey; this.certificateKeyProvider = certificateKeyProvider; tokens = new PRTokeniser(filename); readPdf(); } /** Reads and parses a PDF document. * @param url the URL of the document * @throws IOException on error */ public PdfReader(URL url) throws IOException { this(url, null); } /** Reads and parses a PDF document. * @param url the URL of the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(URL url, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(new RandomAccessFileOrArray(url)); readPdf(); } /** * Reads and parses a PDF document. * @param is the InputStream containing the document. The stream is read to the * end but is not closed * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(InputStream is, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(new RandomAccessFileOrArray(is)); readPdf(); } /** * Reads and parses a PDF document. * @param is the InputStream containing the document. The stream is read to the * end but is not closed * @throws IOException on error */ public PdfReader(InputStream is) throws IOException { this(is, null); } /** * Reads and parses a pdf document. Contrary to the other constructors only the xref is read * into memory. The reader is said to be working in "partial" mode as only parts of the pdf * are read as needed. The pdf is left open but may be closed at any time with * PdfReader.close(), reopen is automatic. * @param raf the document location * @param ownerPassword the password or null for no password * @throws IOException on error */ public PdfReader(RandomAccessFileOrArray raf, byte ownerPassword[]) throws IOException { password = ownerPassword; partial = true; tokens = new PRTokeniser(raf); readPdfPartial(); } /** Creates an independent duplicate. * @param reader the PdfReader to duplicate */ public PdfReader(PdfReader reader) { this.appendable = reader.appendable; this.consolidateNamedDestinations = reader.consolidateNamedDestinations; this.encrypted = reader.encrypted; this.rebuilt = reader.rebuilt; this.sharedStreams = reader.sharedStreams; this.tampered = reader.tampered; this.password = reader.password; this.pdfVersion = reader.pdfVersion; this.eofPos = reader.eofPos; this.freeXref = reader.freeXref; this.lastXref = reader.lastXref; this.tokens = new PRTokeniser(reader.tokens.getSafeFile()); if (reader.decrypt != null) this.decrypt = new PdfEncryption(reader.decrypt); this.pValue = reader.pValue; this.rValue = reader.rValue; this.xrefObj = new ArrayList(reader.xrefObj); for (int k = 0; k < reader.xrefObj.size(); ++k) { this.xrefObj.set(k, duplicatePdfObject((PdfObject)reader.xrefObj.get(k), this)); } this.pageRefs = new PageRefs(reader.pageRefs, this); this.trailer = (PdfDictionary)duplicatePdfObject(reader.trailer, this); this.catalog = trailer.getAsDict(PdfName.ROOT); this.rootPages = catalog.getAsDict(PdfName.PAGES); this.fileLength = reader.fileLength; this.partial = reader.partial; this.hybridXref = reader.hybridXref; this.objStmToOffset = reader.objStmToOffset; this.xref = reader.xref; this.cryptoRef = (PRIndirectReference)duplicatePdfObject(reader.cryptoRef, this); this.ownerPasswordUsed = reader.ownerPasswordUsed; } /** Gets a new file instance of the original PDF * document. * @return a new file instance of the original PDF document */ public RandomAccessFileOrArray getSafeFile() { return tokens.getSafeFile(); } protected PdfReaderInstance getPdfReaderInstance(PdfWriter writer) { return new PdfReaderInstance(this, writer); } /** Gets the number of pages in the document. * @return the number of pages in the document */ public int getNumberOfPages() { return pageRefs.size(); } /** Returns the document's catalog. This dictionary is not a copy, * any changes will be reflected in the catalog. * @return the document's catalog */ public PdfDictionary getCatalog() { return catalog; } /** Returns the document's acroform, if it has one. * @return the document's acroform */ public PRAcroForm getAcroForm() { if (!acroFormParsed) { acroFormParsed = true; PdfObject form = catalog.get(PdfName.ACROFORM); if (form != null) { try { acroForm = new PRAcroForm(this); acroForm.readAcroForm((PdfDictionary)getPdfObject(form)); } catch (Exception e) { acroForm = null; } } } return acroForm; } /** * Gets the page rotation. This value can be 0, 90, 180 or 270. * @param index the page number. The first page is 1 * @return the page rotation */ public int getPageRotation(int index) { return getPageRotation(pageRefs.getPageNRelease(index)); } int getPageRotation(PdfDictionary page) { PdfNumber rotate = page.getAsNumber(PdfName.ROTATE); if (rotate == null) return 0; else { int n = rotate.intValue(); n %= 360; return n < 0 ? n + 360 : n; } } /** Gets the page size, taking rotation into account. This * is a Rectangle with the value of the /MediaBox and the /Rotate key. * @param index the page number. The first page is 1 * @return a Rectangle */ public Rectangle getPageSizeWithRotation(int index) { return getPageSizeWithRotation(pageRefs.getPageNRelease(index)); } /** * Gets the rotated page from a page dictionary. * @param page the page dictionary * @return the rotated page */ public Rectangle getPageSizeWithRotation(PdfDictionary page) { Rectangle rect = getPageSize(page); int rotation = getPageRotation(page); while (rotation > 0) { rect = rect.rotate(); rotation -= 90; } return rect; } /** Gets the page size without taking rotation into account. This * is the value of the /MediaBox key. * @param index the page number. The first page is 1 * @return the page size */ public Rectangle getPageSize(int index) { return getPageSize(pageRefs.getPageNRelease(index)); } /** * Gets the page from a page dictionary * @param page the page dictionary * @return the page */ public Rectangle getPageSize(PdfDictionary page) { PdfArray mediaBox = page.getAsArray(PdfName.MEDIABOX); return getNormalizedRectangle(mediaBox); } /** Gets the crop box without taking rotation into account. This * is the value of the /CropBox key. The crop box is the part * of the document to be displayed or printed. It usually is the same * as the media box but may be smaller. If the page doesn't have a crop * box the page size will be returned. * @param index the page number. The first page is 1 * @return the crop box */ public Rectangle getCropBox(int index) { PdfDictionary page = pageRefs.getPageNRelease(index); PdfArray cropBox = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX)); if (cropBox == null) return getPageSize(page); return getNormalizedRectangle(cropBox); } /** Gets the box size. Allowed names are: "crop", "trim", "art", "bleed" and "media". * @param index the page number. The first page is 1 * @param boxName the box name * @return the box rectangle or null */ public Rectangle getBoxSize(int index, String boxName) { PdfDictionary page = pageRefs.getPageNRelease(index); PdfArray box = null; if (boxName.equals("trim")) box = (PdfArray)getPdfObjectRelease(page.get(PdfName.TRIMBOX)); else if (boxName.equals("art")) box = (PdfArray)getPdfObjectRelease(page.get(PdfName.ARTBOX)); else if (boxName.equals("bleed")) box = (PdfArray)getPdfObjectRelease(page.get(PdfName.BLEEDBOX)); else if (boxName.equals("crop")) box = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX)); else if (boxName.equals("media")) box = (PdfArray)getPdfObjectRelease(page.get(PdfName.MEDIABOX)); if (box == null) return null; return getNormalizedRectangle(box); } /** Returns the content of the document information dictionary as a HashMap * of String. * @return content of the document information dictionary */ public HashMap getInfo() { HashMap map = new HashMap(); PdfDictionary info = trailer.getAsDict(PdfName.INFO); if (info == null) return map; for (Iterator it = info.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); PdfObject obj = getPdfObject(info.get(key)); if (obj == null) continue; String value = obj.toString(); switch (obj.type()) { case PdfObject.STRING: { value = ((PdfString)obj).toUnicodeString(); break; } case PdfObject.NAME: { value = PdfName.decodeName(value); break; } } map.put(PdfName.decodeName(key.toString()), value); } return map; } /** Normalizes a Rectangle so that llx and lly are smaller than urx and ury. * @param box the original rectangle * @return a normalized Rectangle */ public static Rectangle getNormalizedRectangle(PdfArray box) { float llx = ((PdfNumber)getPdfObjectRelease(box.getPdfObject(0))).floatValue(); float lly = ((PdfNumber)getPdfObjectRelease(box.getPdfObject(1))).floatValue(); float urx = ((PdfNumber)getPdfObjectRelease(box.getPdfObject(2))).floatValue(); float ury = ((PdfNumber)getPdfObjectRelease(box.getPdfObject(3))).floatValue(); return new Rectangle(Math.min(llx, urx), Math.min(lly, ury), Math.max(llx, urx), Math.max(lly, ury)); } protected void readPdf() throws IOException { try { fileLength = tokens.getFile().length(); pdfVersion = tokens.checkPdfHeader(); try { readXref(); } catch (Exception e) { try { rebuilt = true; rebuildXref(); lastXref = -1; } catch (Exception ne) { throw new InvalidPdfException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage()); } } try { readDocObj(); } catch (Exception e) { if (e instanceof BadPasswordException) throw new BadPasswordException(e.getMessage()); if (rebuilt || encryptionError) throw new InvalidPdfException(e.getMessage()); rebuilt = true; encrypted = false; rebuildXref(); lastXref = -1; readDocObj(); } strings.clear(); readPages(); eliminateSharedStreams(); removeUnusedObjects(); } finally { try { tokens.close(); } catch (Exception e) { // empty on purpose } } } protected void readPdfPartial() throws IOException { try { fileLength = tokens.getFile().length(); pdfVersion = tokens.checkPdfHeader(); try { readXref(); } catch (Exception e) { try { rebuilt = true; rebuildXref(); lastXref = -1; } catch (Exception ne) { throw new InvalidPdfException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage()); } } readDocObjPartial(); readPages(); } catch (IOException e) { try{tokens.close();}catch(Exception ee){} throw e; } } private boolean equalsArray(byte ar1[], byte ar2[], int size) { for (int k = 0; k < size; ++k) { if (ar1[k] != ar2[k]) return false; } return true; } /** * @throws IOException */ private void readDecryptedDocObj() throws IOException { if (encrypted) return; PdfObject encDic = trailer.get(PdfName.ENCRYPT); if (encDic == null || encDic.toString().equals("null")) return; encryptionError = true; byte[] encryptionKey = null; encrypted = true; PdfDictionary enc = (PdfDictionary)getPdfObject(encDic); String s; PdfObject o; PdfArray documentIDs = trailer.getAsArray(PdfName.ID); byte documentID[] = null; if (documentIDs != null) { o = documentIDs.getPdfObject(0); strings.remove(o); s = o.toString(); documentID = com.lowagie.text.DocWriter.getISOBytes(s); if (documentIDs.size() > 1) strings.remove(documentIDs.getPdfObject(1)); } // just in case we have a broken producer if (documentID == null) documentID = new byte[0]; byte uValue[] = null; byte oValue[] = null; int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; int lengthValue = 0; PdfObject filter = getPdfObjectRelease(enc.get(PdfName.FILTER)); if (filter.equals(PdfName.STANDARD)) { s = enc.get(PdfName.U).toString(); strings.remove(enc.get(PdfName.U)); uValue = com.lowagie.text.DocWriter.getISOBytes(s); s = enc.get(PdfName.O).toString(); strings.remove(enc.get(PdfName.O)); oValue = com.lowagie.text.DocWriter.getISOBytes(s); o = enc.get(PdfName.P); if (!o.isNumber()) throw new InvalidPdfException("Illegal P value."); pValue = ((PdfNumber)o).intValue(); o = enc.get(PdfName.R); if (!o.isNumber()) throw new InvalidPdfException("Illegal R value."); rValue = ((PdfNumber)o).intValue(); switch (rValue) { case 2: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; break; case 3: o = enc.get(PdfName.LENGTH); if (!o.isNumber()) throw new InvalidPdfException("Illegal Length value."); lengthValue = ( (PdfNumber) o).intValue(); if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException("Illegal Length value."); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; break; case 4: PdfDictionary dic = (PdfDictionary)enc.get(PdfName.CF); if (dic == null) throw new InvalidPdfException("/CF not found (encryption)"); dic = (PdfDictionary)dic.get(PdfName.STDCF); if (dic == null) throw new InvalidPdfException("/StdCF not found (encryption)"); if (PdfName.V2.equals(dic.get(PdfName.CFM))) cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; else if (PdfName.AESV2.equals(dic.get(PdfName.CFM))) cryptoMode = PdfWriter.ENCRYPTION_AES_128; else throw new UnsupportedPdfException("No compatible encryption found"); PdfObject em = enc.get(PdfName.ENCRYPTMETADATA); if (em != null && em.toString().equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; default: throw new UnsupportedPdfException("Unknown encryption type R = " + rValue); } } else if (filter.equals(PdfName.PUBSEC)) { boolean foundRecipient = false; byte[] envelopedData = null; PdfArray recipients = null; o = enc.get(PdfName.V); if (!o.isNumber()) throw new InvalidPdfException("Illegal V value."); int vValue = ((PdfNumber)o).intValue(); switch(vValue) { case 1: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; lengthValue = 40; recipients = (PdfArray)enc.get(PdfName.RECIPIENTS); break; case 2: o = enc.get(PdfName.LENGTH); if (!o.isNumber()) throw new InvalidPdfException("Illegal Length value."); lengthValue = ( (PdfNumber) o).intValue(); if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException("Illegal Length value."); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; recipients = (PdfArray)enc.get(PdfName.RECIPIENTS); break; case 4: PdfDictionary dic = (PdfDictionary)enc.get(PdfName.CF); if (dic == null) throw new InvalidPdfException("/CF not found (encryption)"); dic = (PdfDictionary)dic.get(PdfName.DEFAULTCRYPTFILTER); if (dic == null) throw new InvalidPdfException("/DefaultCryptFilter not found (encryption)"); if (PdfName.V2.equals(dic.get(PdfName.CFM))) { cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; lengthValue = 128; } else if (PdfName.AESV2.equals(dic.get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_128; lengthValue = 128; } else throw new UnsupportedPdfException("No compatible encryption found"); PdfObject em = dic.get(PdfName.ENCRYPTMETADATA); if (em != null && em.toString().equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; recipients = (PdfArray)dic.get(PdfName.RECIPIENTS); break; default: throw new UnsupportedPdfException("Unknown encryption type V = " + rValue); } for (int i = 0; iPdfObject resolving an indirect reference * if needed. * @param obj the PdfObject to read * @return the resolved PdfObject */ public static PdfObject getPdfObject(PdfObject obj) { if (obj == null) return null; if (!obj.isIndirect()) return obj; try { PRIndirectReference ref = (PRIndirectReference)obj; int idx = ref.getNumber(); boolean appendable = ref.getReader().appendable; obj = ref.getReader().getPdfObject(idx); if (obj == null) { return null; } else { if (appendable) { switch (obj.type()) { case PdfObject.NULL: obj = new PdfNull(); break; case PdfObject.BOOLEAN: obj = new PdfBoolean(((PdfBoolean)obj).booleanValue()); break; case PdfObject.NAME: obj = new PdfName(obj.getBytes()); break; } obj.setIndRef(ref); } return obj; } } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Reads a PdfObject resolving an indirect reference * if needed. If the reader was opened in partial mode the object will be released * to save memory. * @param obj the PdfObject to read * @param parent * @return a PdfObject */ public static PdfObject getPdfObjectRelease(PdfObject obj, PdfObject parent) { PdfObject obj2 = getPdfObject(obj, parent); releaseLastXrefPartial(obj); return obj2; } /** * @param obj * @param parent * @return a PdfObject */ public static PdfObject getPdfObject(PdfObject obj, PdfObject parent) { if (obj == null) return null; if (!obj.isIndirect()) { PRIndirectReference ref = null; if (parent != null && (ref = parent.getIndRef()) != null && ref.getReader().isAppendable()) { switch (obj.type()) { case PdfObject.NULL: obj = new PdfNull(); break; case PdfObject.BOOLEAN: obj = new PdfBoolean(((PdfBoolean)obj).booleanValue()); break; case PdfObject.NAME: obj = new PdfName(obj.getBytes()); break; } obj.setIndRef(ref); } return obj; } return getPdfObject(obj); } /** * @param idx * @return a PdfObject */ public PdfObject getPdfObjectRelease(int idx) { PdfObject obj = getPdfObject(idx); releaseLastXrefPartial(); return obj; } /** * @param idx * @return aPdfObject */ public PdfObject getPdfObject(int idx) { try { lastXrefPartial = -1; if (idx < 0 || idx >= xrefObj.size()) return null; PdfObject obj = (PdfObject)xrefObj.get(idx); if (!partial || obj != null) return obj; if (idx * 2 >= xref.length) return null; obj = readSingleObject(idx); lastXrefPartial = -1; if (obj != null) lastXrefPartial = idx; return obj; } catch (Exception e) { throw new ExceptionConverter(e); } } /** * */ public void resetLastXrefPartial() { lastXrefPartial = -1; } /** * */ public void releaseLastXrefPartial() { if (partial && lastXrefPartial != -1) { xrefObj.set(lastXrefPartial, null); lastXrefPartial = -1; } } /** * @param obj */ public static void releaseLastXrefPartial(PdfObject obj) { if (obj == null) return; if (!obj.isIndirect()) return; if (!(obj instanceof PRIndirectReference)) return; PRIndirectReference ref = (PRIndirectReference)obj; PdfReader reader = ref.getReader(); if (reader.partial && reader.lastXrefPartial != -1 && reader.lastXrefPartial == ref.getNumber()) { reader.xrefObj.set(reader.lastXrefPartial, null); } reader.lastXrefPartial = -1; } private void setXrefPartialObject(int idx, PdfObject obj) { if (!partial || idx < 0) return; xrefObj.set(idx, obj); } /** * @param obj * @return an indirect reference */ public PRIndirectReference addPdfObject(PdfObject obj) { xrefObj.add(obj); return new PRIndirectReference(this, xrefObj.size() - 1); } protected void readPages() throws IOException { catalog = trailer.getAsDict(PdfName.ROOT); rootPages = catalog.getAsDict(PdfName.PAGES); pageRefs = new PageRefs(this); } protected void readDocObjPartial() throws IOException { xrefObj = new ArrayList(xref.length / 2); xrefObj.addAll(Collections.nCopies(xref.length / 2, null)); readDecryptedDocObj(); if (objStmToOffset != null) { int keys[] = objStmToOffset.getKeys(); for (int k = 0; k < keys.length; ++k) { int n = keys[k]; objStmToOffset.put(n, xref[n * 2]); xref[n * 2] = -1; } } } protected PdfObject readSingleObject(int k) throws IOException { strings.clear(); int k2 = k * 2; int pos = xref[k2]; if (pos < 0) return null; if (xref[k2 + 1] > 0) pos = objStmToOffset.get(xref[k2 + 1]); if (pos == 0) return null; tokens.seek(pos); tokens.nextValidToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Invalid object number."); objNum = tokens.intValue(); tokens.nextValidToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Invalid generation number."); objGen = tokens.intValue(); tokens.nextValidToken(); if (!tokens.getStringValue().equals("obj")) tokens.throwError("Token 'obj' expected."); PdfObject obj; try { obj = readPRObject(); for (int j = 0; j < strings.size(); ++j) { PdfString str = (PdfString)strings.get(j); str.decrypt(this); } if (obj.isStream()) { checkPRStreamLength((PRStream)obj); } } catch (Exception e) { obj = null; } if (xref[k2 + 1] > 0) { obj = readOneObjStm((PRStream)obj, xref[k2]); } xrefObj.set(k, obj); return obj; } protected PdfObject readOneObjStm(PRStream stream, int idx) throws IOException { int first = stream.getAsNumber(PdfName.FIRST).intValue(); byte b[] = getStreamBytes(stream, tokens.getFile()); PRTokeniser saveTokens = tokens; tokens = new PRTokeniser(b); try { int address = 0; boolean ok = true; ++idx; for (int k = 0; k < idx; ++k) { ok = tokens.nextToken(); if (!ok) break; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { ok = false; break; } ok = tokens.nextToken(); if (!ok) break; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { ok = false; break; } address = tokens.intValue() + first; } if (!ok) throw new InvalidPdfException("Error reading ObjStm"); tokens.seek(address); return readPRObject(); } finally { tokens = saveTokens; } } /** * @return the percentage of the cross reference table that has been read */ public double dumpPerc() { int total = 0; for (int k = 0; k < xrefObj.size(); ++k) { if (xrefObj.get(k) != null) ++total; } return (total * 100.0 / xrefObj.size()); } protected void readDocObj() throws IOException { ArrayList streams = new ArrayList(); xrefObj = new ArrayList(xref.length / 2); xrefObj.addAll(Collections.nCopies(xref.length / 2, null)); for (int k = 2; k < xref.length; k += 2) { int pos = xref[k]; if (pos <= 0 || xref[k + 1] > 0) continue; tokens.seek(pos); tokens.nextValidToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Invalid object number."); objNum = tokens.intValue(); tokens.nextValidToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Invalid generation number."); objGen = tokens.intValue(); tokens.nextValidToken(); if (!tokens.getStringValue().equals("obj")) tokens.throwError("Token 'obj' expected."); PdfObject obj; try { obj = readPRObject(); if (obj.isStream()) { streams.add(obj); } } catch (Exception e) { obj = null; } xrefObj.set(k / 2, obj); } for (int k = 0; k < streams.size(); ++k) { checkPRStreamLength((PRStream)streams.get(k)); } readDecryptedDocObj(); if (objStmMark != null) { for (Iterator i = objStmMark.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry)i.next(); int n = ((Integer)entry.getKey()).intValue(); IntHashtable h = (IntHashtable)entry.getValue(); readObjStm((PRStream)xrefObj.get(n), h); xrefObj.set(n, null); } objStmMark = null; } xref = null; } private void checkPRStreamLength(PRStream stream) throws IOException { int fileLength = tokens.length(); int start = stream.getOffset(); boolean calc = false; int streamLength = 0; PdfObject obj = getPdfObjectRelease(stream.get(PdfName.LENGTH)); if (obj != null && obj.type() == PdfObject.NUMBER) { streamLength = ((PdfNumber)obj).intValue(); if (streamLength + start > fileLength - 20) calc = true; else { tokens.seek(start + streamLength); String line = tokens.readString(20); if (!line.startsWith("\nendstream") && !line.startsWith("\r\nendstream") && !line.startsWith("\rendstream") && !line.startsWith("endstream")) calc = true; } } else calc = true; if (calc) { byte tline[] = new byte[16]; tokens.seek(start); while (true) { int pos = tokens.getFilePointer(); if (!tokens.readLineSegment(tline)) break; if (equalsn(tline, endstream)) { streamLength = pos - start; break; } if (equalsn(tline, endobj)) { tokens.seek(pos - 16); String s = tokens.readString(16); int index = s.indexOf("endstream"); if (index >= 0) pos = pos - 16 + index; streamLength = pos - start; break; } } } stream.setLength(streamLength); } protected void readObjStm(PRStream stream, IntHashtable map) throws IOException { int first = stream.getAsNumber(PdfName.FIRST).intValue(); int n = stream.getAsNumber(PdfName.N).intValue(); byte b[] = getStreamBytes(stream, tokens.getFile()); PRTokeniser saveTokens = tokens; tokens = new PRTokeniser(b); try { int address[] = new int[n]; int objNumber[] = new int[n]; boolean ok = true; for (int k = 0; k < n; ++k) { ok = tokens.nextToken(); if (!ok) break; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { ok = false; break; } objNumber[k] = tokens.intValue(); ok = tokens.nextToken(); if (!ok) break; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { ok = false; break; } address[k] = tokens.intValue() + first; } if (!ok) throw new InvalidPdfException("Error reading ObjStm"); for (int k = 0; k < n; ++k) { if (map.containsKey(k)) { tokens.seek(address[k]); PdfObject obj = readPRObject(); xrefObj.set(objNumber[k], obj); } } } finally { tokens = saveTokens; } } /** * Eliminates the reference to the object freeing the memory used by it and clearing * the xref entry. * @param obj the object. If it's an indirect reference it will be eliminated * @return the object or the already erased dereferenced object */ public static PdfObject killIndirect(PdfObject obj) { if (obj == null || obj.isNull()) return null; PdfObject ret = getPdfObjectRelease(obj); if (obj.isIndirect()) { PRIndirectReference ref = (PRIndirectReference)obj; PdfReader reader = ref.getReader(); int n = ref.getNumber(); reader.xrefObj.set(n, null); if (reader.partial) reader.xref[n * 2] = -1; } return ret; } private void ensureXrefSize(int size) { if (size == 0) return; if (xref == null) xref = new int[size]; else { if (xref.length < size) { int xref2[] = new int[size]; System.arraycopy(xref, 0, xref2, 0, xref.length); xref = xref2; } } } protected void readXref() throws IOException { hybridXref = false; newXrefType = false; tokens.seek(tokens.getStartxref()); tokens.nextToken(); if (!tokens.getStringValue().equals("startxref")) throw new InvalidPdfException("startxref not found."); tokens.nextToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) throw new InvalidPdfException("startxref is not followed by a number."); int startxref = tokens.intValue(); lastXref = startxref; eofPos = tokens.getFilePointer(); try { if (readXRefStream(startxref)) { newXrefType = true; return; } } catch (Exception e) {} xref = null; tokens.seek(startxref); trailer = readXrefSection(); PdfDictionary trailer2 = trailer; while (true) { PdfNumber prev = (PdfNumber)trailer2.get(PdfName.PREV); if (prev == null) break; tokens.seek(prev.intValue()); trailer2 = readXrefSection(); } } protected PdfDictionary readXrefSection() throws IOException { tokens.nextValidToken(); if (!tokens.getStringValue().equals("xref")) tokens.throwError("xref subsection not found"); int start = 0; int end = 0; int pos = 0; int gen = 0; while (true) { tokens.nextValidToken(); if (tokens.getStringValue().equals("trailer")) break; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Object number of the first object in this xref subsection not found"); start = tokens.intValue(); tokens.nextValidToken(); if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) tokens.throwError("Number of entries in this xref subsection not found"); end = tokens.intValue() + start; if (start == 1) { // fix incorrect start number int back = tokens.getFilePointer(); tokens.nextValidToken(); pos = tokens.intValue(); tokens.nextValidToken(); gen = tokens.intValue(); if (pos == 0 && gen == PdfWriter.GENERATION_MAX) { --start; --end; } tokens.seek(back); } ensureXrefSize(end * 2); for (int k = start; k < end; ++k) { tokens.nextValidToken(); pos = tokens.intValue(); tokens.nextValidToken(); gen = tokens.intValue(); tokens.nextValidToken(); int p = k * 2; if (tokens.getStringValue().equals("n")) { if (xref[p] == 0 && xref[p + 1] == 0) { // if (pos == 0) // tokens.throwError("File position 0 cross-reference entry in this xref subsection"); xref[p] = pos; } } else if (tokens.getStringValue().equals("f")) { if (xref[p] == 0 && xref[p + 1] == 0) xref[p] = -1; } else tokens.throwError("Invalid cross-reference entry in this xref subsection"); } } PdfDictionary trailer = (PdfDictionary)readPRObject(); PdfNumber xrefSize = (PdfNumber)trailer.get(PdfName.SIZE); ensureXrefSize(xrefSize.intValue() * 2); PdfObject xrs = trailer.get(PdfName.XREFSTM); if (xrs != null && xrs.isNumber()) { int loc = ((PdfNumber)xrs).intValue(); try { readXRefStream(loc); newXrefType = true; hybridXref = true; } catch (IOException e) { xref = null; throw e; } } return trailer; } protected boolean readXRefStream(int ptr) throws IOException { tokens.seek(ptr); int thisStream = 0; if (!tokens.nextToken()) return false; if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) return false; thisStream = tokens.intValue(); if (!tokens.nextToken() || tokens.getTokenType() != PRTokeniser.TK_NUMBER) return false; if (!tokens.nextToken() || !tokens.getStringValue().equals("obj")) return false; PdfObject object = readPRObject(); PRStream stm = null; if (object.isStream()) { stm = (PRStream)object; if (!PdfName.XREF.equals(stm.get(PdfName.TYPE))) return false; } else return false; if (trailer == null) { trailer = new PdfDictionary(); trailer.putAll(stm); } stm.setLength(((PdfNumber)stm.get(PdfName.LENGTH)).intValue()); int size = ((PdfNumber)stm.get(PdfName.SIZE)).intValue(); PdfArray index; PdfObject obj = stm.get(PdfName.INDEX); if (obj == null) { index = new PdfArray(); index.add(new int[]{0, size}); } else index = (PdfArray)obj; PdfArray w = (PdfArray)stm.get(PdfName.W); int prev = -1; obj = stm.get(PdfName.PREV); if (obj != null) prev = ((PdfNumber)obj).intValue(); // Each xref pair is a position // type 0 -> -1, 0 // type 1 -> offset, 0 // type 2 -> index, obj num ensureXrefSize(size * 2); if (objStmMark == null && !partial) objStmMark = new HashMap(); if (objStmToOffset == null && partial) objStmToOffset = new IntHashtable(); byte b[] = getStreamBytes(stm, tokens.getFile()); int bptr = 0; int wc[] = new int[3]; for (int k = 0; k < 3; ++k) wc[k] = w.getAsNumber(k).intValue(); for (int idx = 0; idx < index.size(); idx += 2) { int start = index.getAsNumber(idx).intValue(); int length = index.getAsNumber(idx + 1).intValue(); ensureXrefSize((start + length) * 2); while (length-- > 0) { int type = 1; if (wc[0] > 0) { type = 0; for (int k = 0; k < wc[0]; ++k) type = (type << 8) + (b[bptr++] & 0xff); } int field2 = 0; for (int k = 0; k < wc[1]; ++k) field2 = (field2 << 8) + (b[bptr++] & 0xff); int field3 = 0; for (int k = 0; k < wc[2]; ++k) field3 = (field3 << 8) + (b[bptr++] & 0xff); int base = start * 2; if (xref[base] == 0 && xref[base + 1] == 0) { switch (type) { case 0: xref[base] = -1; break; case 1: xref[base] = field2; break; case 2: xref[base] = field3; xref[base + 1] = field2; if (partial) { objStmToOffset.put(field2, 0); } else { Integer on = new Integer(field2); IntHashtable seq = (IntHashtable)objStmMark.get(on); if (seq == null) { seq = new IntHashtable(); seq.put(field3, 1); objStmMark.put(on, seq); } else seq.put(field3, 1); } break; } } ++start; } } thisStream *= 2; if (thisStream < xref.length) xref[thisStream] = -1; if (prev == -1) return true; return readXRefStream(prev); } protected void rebuildXref() throws IOException { hybridXref = false; newXrefType = false; tokens.seek(0); int xr[][] = new int[1024][]; int top = 0; trailer = null; byte line[] = new byte[64]; for (;;) { int pos = tokens.getFilePointer(); if (!tokens.readLineSegment(line)) break; if (line[0] == 't') { if (!PdfEncodings.convertToString(line, null).startsWith("trailer")) continue; tokens.seek(pos); tokens.nextToken(); pos = tokens.getFilePointer(); try { PdfDictionary dic = (PdfDictionary)readPRObject(); if (dic.get(PdfName.ROOT) != null) trailer = dic; else tokens.seek(pos); } catch (Exception e) { tokens.seek(pos); } } else if (line[0] >= '0' && line[0] <= '9') { int obj[] = PRTokeniser.checkObjectStart(line); if (obj == null) continue; int num = obj[0]; int gen = obj[1]; if (num >= xr.length) { int newLength = num * 2; int xr2[][] = new int[newLength][]; System.arraycopy(xr, 0, xr2, 0, top); xr = xr2; } if (num >= top) top = num + 1; if (xr[num] == null || gen >= xr[num][1]) { obj[0] = pos; xr[num] = obj; } } } if (trailer == null) throw new InvalidPdfException("trailer not found."); xref = new int[top * 2]; for (int k = 0; k < top; ++k) { int obj[] = xr[k]; if (obj != null) xref[k * 2] = obj[0]; } } protected PdfDictionary readDictionary() throws IOException { PdfDictionary dic = new PdfDictionary(); while (true) { tokens.nextValidToken(); if (tokens.getTokenType() == PRTokeniser.TK_END_DIC) break; if (tokens.getTokenType() != PRTokeniser.TK_NAME) tokens.throwError("Dictionary key is not a name."); PdfName name = new PdfName(tokens.getStringValue(), false); PdfObject obj = readPRObject(); int type = obj.type(); if (-type == PRTokeniser.TK_END_DIC) tokens.throwError("Unexpected '>>'"); if (-type == PRTokeniser.TK_END_ARRAY) tokens.throwError("Unexpected ']'"); dic.put(name, obj); } return dic; } protected PdfArray readArray() throws IOException { PdfArray array = new PdfArray(); while (true) { PdfObject obj = readPRObject(); int type = obj.type(); if (-type == PRTokeniser.TK_END_ARRAY) break; if (-type == PRTokeniser.TK_END_DIC) tokens.throwError("Unexpected '>>'"); array.add(obj); } return array; } // Track how deeply nested the current object is, so // we know when to return an individual null or boolean, or // reuse one of the static ones. private int readDepth = 0; protected PdfObject readPRObject() throws IOException { tokens.nextValidToken(); int type = tokens.getTokenType(); switch (type) { case PRTokeniser.TK_START_DIC: { ++readDepth; PdfDictionary dic = readDictionary(); --readDepth; int pos = tokens.getFilePointer(); // be careful in the trailer. May not be a "next" token. boolean hasNext; do { hasNext = tokens.nextToken(); } while (hasNext && tokens.getTokenType() == PRTokeniser.TK_COMMENT); if (hasNext && tokens.getStringValue().equals("stream")) { //skip whitespaces int ch; do { ch = tokens.read(); } while (ch == 32 || ch == 9 || ch == 0 || ch == 12); if (ch != '\n') ch = tokens.read(); if (ch != '\n') tokens.backOnePosition(ch); PRStream stream = new PRStream(this, tokens.getFilePointer()); stream.putAll(dic); // crypto handling stream.setObjNum(objNum, objGen); return stream; } else { tokens.seek(pos); return dic; } } case PRTokeniser.TK_START_ARRAY: { ++readDepth; PdfArray arr = readArray(); --readDepth; return arr; } case PRTokeniser.TK_NUMBER: return new PdfNumber(tokens.getStringValue()); case PRTokeniser.TK_STRING: PdfString str = new PdfString(tokens.getStringValue(), null).setHexWriting(tokens.isHexString()); // crypto handling str.setObjNum(objNum, objGen); if (strings != null) strings.add(str); return str; case PRTokeniser.TK_NAME: { PdfName cachedName = (PdfName)PdfName.staticNames.get( tokens.getStringValue() ); if (readDepth > 0 && cachedName != null) { return cachedName; } else { // an indirect name (how odd...), or a non-standard one return new PdfName(tokens.getStringValue(), false); } } case PRTokeniser.TK_REF: int num = tokens.getReference(); PRIndirectReference ref = new PRIndirectReference(this, num, tokens.getGeneration()); return ref; default: String sv = tokens.getStringValue(); if ("null".equals(sv)) { if (readDepth == 0) { return new PdfNull(); } //else return PdfNull.PDFNULL; } else if ("true".equals(sv)) { if (readDepth == 0) { return new PdfBoolean( true ); } //else return PdfBoolean.PDFTRUE; } else if ("false".equals(sv)) { if (readDepth == 0) { return new PdfBoolean( false ); } //else return PdfBoolean.PDFFALSE; } return new PdfLiteral(-type, tokens.getStringValue()); } } /** Decodes a stream that has the FlateDecode filter. * @param in the input data * @return the decoded data */ public static byte[] FlateDecode(byte in[]) { byte b[] = FlateDecode(in, true); if (b == null) return FlateDecode(in, false); return b; } /** * @param in * @param dicPar * @return a byte array */ public static byte[] decodePredictor(byte in[], PdfObject dicPar) { if (dicPar == null || !dicPar.isDictionary()) return in; PdfDictionary dic = (PdfDictionary)dicPar; PdfObject obj = getPdfObject(dic.get(PdfName.PREDICTOR)); if (obj == null || !obj.isNumber()) return in; int predictor = ((PdfNumber)obj).intValue(); if (predictor < 10) return in; int width = 1; obj = getPdfObject(dic.get(PdfName.COLUMNS)); if (obj != null && obj.isNumber()) width = ((PdfNumber)obj).intValue(); int colors = 1; obj = getPdfObject(dic.get(PdfName.COLORS)); if (obj != null && obj.isNumber()) colors = ((PdfNumber)obj).intValue(); int bpc = 8; obj = getPdfObject(dic.get(PdfName.BITSPERCOMPONENT)); if (obj != null && obj.isNumber()) bpc = ((PdfNumber)obj).intValue(); DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(in)); ByteArrayOutputStream fout = new ByteArrayOutputStream(in.length); int bytesPerPixel = colors * bpc / 8; int bytesPerRow = (colors*width*bpc + 7)/8; byte[] curr = new byte[bytesPerRow]; byte[] prior = new byte[bytesPerRow]; // Decode the (sub)image row-by-row while (true) { // Read the filter type byte and a row of data int filter = 0; try { filter = dataStream.read(); if (filter < 0) { return fout.toByteArray(); } dataStream.readFully(curr, 0, bytesPerRow); } catch (Exception e) { return fout.toByteArray(); } switch (filter) { case 0: //PNG_FILTER_NONE break; case 1: //PNG_FILTER_SUB for (int i = bytesPerPixel; i < bytesPerRow; i++) { curr[i] += curr[i - bytesPerPixel]; } break; case 2: //PNG_FILTER_UP for (int i = 0; i < bytesPerRow; i++) { curr[i] += prior[i]; } break; case 3: //PNG_FILTER_AVERAGE for (int i = 0; i < bytesPerPixel; i++) { curr[i] += prior[i] / 2; } for (int i = bytesPerPixel; i < bytesPerRow; i++) { curr[i] += ((curr[i - bytesPerPixel] & 0xff) + (prior[i] & 0xff))/2; } break; case 4: //PNG_FILTER_PAETH for (int i = 0; i < bytesPerPixel; i++) { curr[i] += prior[i]; } for (int i = bytesPerPixel; i < bytesPerRow; i++) { int a = curr[i - bytesPerPixel] & 0xff; int b = prior[i] & 0xff; int c = prior[i - bytesPerPixel] & 0xff; int p = a + b - c; int pa = Math.abs(p - a); int pb = Math.abs(p - b); int pc = Math.abs(p - c); int ret; if ((pa <= pb) && (pa <= pc)) { ret = a; } else if (pb <= pc) { ret = b; } else { ret = c; } curr[i] += (byte)(ret); } break; default: // Error -- unknown filter type throw new RuntimeException("PNG filter unknown."); } try { fout.write(curr); } catch (IOException ioe) { // Never happens } // Swap curr and prior byte[] tmp = prior; prior = curr; curr = tmp; } } /** A helper to FlateDecode. * @param in the input data * @param strict true to read a correct stream. false * to try to read a corrupted stream * @return the decoded data */ public static byte[] FlateDecode(byte in[], boolean strict) { ByteArrayInputStream stream = new ByteArrayInputStream(in); InflaterInputStream zip = new InflaterInputStream(stream); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte b[] = new byte[strict ? 4092 : 1]; try { int n; while ((n = zip.read(b)) >= 0) { out.write(b, 0, n); } zip.close(); out.close(); return out.toByteArray(); } catch (Exception e) { if (strict) return null; return out.toByteArray(); } } /** Decodes a stream that has the ASCIIHexDecode filter. * @param in the input data * @return the decoded data */ public static byte[] ASCIIHexDecode(byte in[]) { ByteArrayOutputStream out = new ByteArrayOutputStream(); boolean first = true; int n1 = 0; for (int k = 0; k < in.length; ++k) { int ch = in[k] & 0xff; if (ch == '>') break; if (PRTokeniser.isWhitespace(ch)) continue; int n = PRTokeniser.getHex(ch); if (n == -1) throw new RuntimeException("Illegal character in ASCIIHexDecode."); if (first) n1 = n; else out.write((byte)((n1 << 4) + n)); first = !first; } if (!first) out.write((byte)(n1 << 4)); return out.toByteArray(); } /** Decodes a stream that has the ASCII85Decode filter. * @param in the input data * @return the decoded data */ public static byte[] ASCII85Decode(byte in[]) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int state = 0; int chn[] = new int[5]; for (int k = 0; k < in.length; ++k) { int ch = in[k] & 0xff; if (ch == '~') break; if (PRTokeniser.isWhitespace(ch)) continue; if (ch == 'z' && state == 0) { out.write(0); out.write(0); out.write(0); out.write(0); continue; } if (ch < '!' || ch > 'u') throw new RuntimeException("Illegal character in ASCII85Decode."); chn[state] = ch - '!'; ++state; if (state == 5) { state = 0; int r = 0; for (int j = 0; j < 5; ++j) r = r * 85 + chn[j]; out.write((byte)(r >> 24)); out.write((byte)(r >> 16)); out.write((byte)(r >> 8)); out.write((byte)r); } } int r = 0; // We'll ignore the next two lines for the sake of perpetuating broken PDFs // if (state == 1) // throw new RuntimeException("Illegal length in ASCII85Decode."); if (state == 2) { r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + 85 * 85 * 85 + 85 * 85 + 85; out.write((byte)(r >> 24)); } else if (state == 3) { r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85 + 85 * 85 + 85; out.write((byte)(r >> 24)); out.write((byte)(r >> 16)); } else if (state == 4) { r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85 + chn[3] * 85 + 85; out.write((byte)(r >> 24)); out.write((byte)(r >> 16)); out.write((byte)(r >> 8)); } return out.toByteArray(); } /** Decodes a stream that has the LZWDecode filter. * @param in the input data * @return the decoded data */ public static byte[] LZWDecode(byte in[]) { ByteArrayOutputStream out = new ByteArrayOutputStream(); LZWDecoder lzw = new LZWDecoder(); lzw.decode(in, out); return out.toByteArray(); } /** Checks if the document had errors and was rebuilt. * @return true if rebuilt. * */ public boolean isRebuilt() { return this.rebuilt; } /** Gets the dictionary that represents a page. * @param pageNum the page number. 1 is the first * @return the page dictionary */ public PdfDictionary getPageN(int pageNum) { PdfDictionary dic = pageRefs.getPageN(pageNum); if (dic == null) return null; if (appendable) dic.setIndRef(pageRefs.getPageOrigRef(pageNum)); return dic; } /** * @param pageNum * @return a Dictionary object */ public PdfDictionary getPageNRelease(int pageNum) { PdfDictionary dic = getPageN(pageNum); pageRefs.releasePage(pageNum); return dic; } /** * @param pageNum */ public void releasePage(int pageNum) { pageRefs.releasePage(pageNum); } /** * */ public void resetReleasePage() { pageRefs.resetReleasePage(); } /** Gets the page reference to this page. * @param pageNum the page number. 1 is the first * @return the page reference */ public PRIndirectReference getPageOrigRef(int pageNum) { return pageRefs.getPageOrigRef(pageNum); } /** Gets the contents of the page. * @param pageNum the page number. 1 is the first * @param file the location of the PDF document * @throws IOException on error * @return the content */ public byte[] getPageContent(int pageNum, RandomAccessFileOrArray file) throws IOException{ PdfDictionary page = getPageNRelease(pageNum); if (page == null) return null; PdfObject contents = getPdfObjectRelease(page.get(PdfName.CONTENTS)); if (contents == null) return new byte[0]; ByteArrayOutputStream bout = null; if (contents.isStream()) { return getStreamBytes((PRStream)contents, file); } else if (contents.isArray()) { PdfArray array = (PdfArray)contents; bout = new ByteArrayOutputStream(); for (int k = 0; k < array.size(); ++k) { PdfObject item = getPdfObjectRelease(array.getPdfObject(k)); if (item == null || !item.isStream()) continue; byte[] b = getStreamBytes((PRStream)item, file); bout.write(b); if (k != array.size() - 1) bout.write('\n'); } return bout.toByteArray(); } else return new byte[0]; } /** Gets the contents of the page. * @param pageNum the page number. 1 is the first * @throws IOException on error * @return the content */ public byte[] getPageContent(int pageNum) throws IOException{ RandomAccessFileOrArray rf = getSafeFile(); try { rf.reOpen(); return getPageContent(pageNum, rf); } finally { try{rf.close();}catch(Exception e){} } } protected void killXref(PdfObject obj) { if (obj == null) return; if ((obj instanceof PdfIndirectReference) && !obj.isIndirect()) return; switch (obj.type()) { case PdfObject.INDIRECT: { int xr = ((PRIndirectReference)obj).getNumber(); obj = (PdfObject)xrefObj.get(xr); xrefObj.set(xr, null); freeXref = xr; killXref(obj); break; } case PdfObject.ARRAY: { PdfArray t = (PdfArray)obj; for (int i = 0; i < t.size(); ++i) killXref(t.getPdfObject(i)); break; } case PdfObject.STREAM: case PdfObject.DICTIONARY: { PdfDictionary dic = (PdfDictionary)obj; for (Iterator i = dic.getKeys().iterator(); i.hasNext();){ killXref(dic.get((PdfName)i.next())); } break; } } } /** Sets the contents of the page. * @param content the new page content * @param pageNum the page number. 1 is the first */ public void setPageContent(int pageNum, byte content[]) { setPageContent(pageNum, content, PdfStream.DEFAULT_COMPRESSION); } /** Sets the contents of the page. * @param content the new page content * @param pageNum the page number. 1 is the first * @since 2.1.3 (the method already existed without param compressionLevel) */ public void setPageContent(int pageNum, byte content[], int compressionLevel) { PdfDictionary page = getPageN(pageNum); if (page == null) return; PdfObject contents = page.get(PdfName.CONTENTS); freeXref = -1; killXref(contents); if (freeXref == -1) { xrefObj.add(null); freeXref = xrefObj.size() - 1; } page.put(PdfName.CONTENTS, new PRIndirectReference(this, freeXref)); xrefObj.set(freeXref, new PRStream(this, content, compressionLevel)); } /** Get the content from a stream applying the required filters. * @param stream the stream * @param file the location where the stream is * @throws IOException on error * @return the stream content */ public static byte[] getStreamBytes(PRStream stream, RandomAccessFileOrArray file) throws IOException { PdfObject filter = getPdfObjectRelease(stream.get(PdfName.FILTER)); byte[] b = getStreamBytesRaw(stream, file); ArrayList filters = new ArrayList(); if (filter != null) { if (filter.isName()) filters.add(filter); else if (filter.isArray()) filters = ((PdfArray)filter).getArrayList(); } ArrayList dp = new ArrayList(); PdfObject dpo = getPdfObjectRelease(stream.get(PdfName.DECODEPARMS)); if (dpo == null || (!dpo.isDictionary() && !dpo.isArray())) dpo = getPdfObjectRelease(stream.get(PdfName.DP)); if (dpo != null) { if (dpo.isDictionary()) dp.add(dpo); else if (dpo.isArray()) dp = ((PdfArray)dpo).getArrayList(); } String name; for (int j = 0; j < filters.size(); ++j) { name = ((PdfName)getPdfObjectRelease((PdfObject)filters.get(j))).toString(); if (name.equals("/FlateDecode") || name.equals("/Fl")) { b = FlateDecode(b); PdfObject dicParam = null; if (j < dp.size()) { dicParam = (PdfObject)dp.get(j); b = decodePredictor(b, dicParam); } } else if (name.equals("/ASCIIHexDecode") || name.equals("/AHx")) b = ASCIIHexDecode(b); else if (name.equals("/ASCII85Decode") || name.equals("/A85")) b = ASCII85Decode(b); else if (name.equals("/LZWDecode")) { b = LZWDecode(b); PdfObject dicParam = null; if (j < dp.size()) { dicParam = (PdfObject)dp.get(j); b = decodePredictor(b, dicParam); } } else if (name.equals("/Crypt")) { } else throw new UnsupportedPdfException("The filter " + name + " is not supported."); } return b; } /** Get the content from a stream applying the required filters. * @param stream the stream * @throws IOException on error * @return the stream content */ public static byte[] getStreamBytes(PRStream stream) throws IOException { RandomAccessFileOrArray rf = stream.getReader().getSafeFile(); try { rf.reOpen(); return getStreamBytes(stream, rf); } finally { try{rf.close();}catch(Exception e){} } } /** Get the content from a stream as it is without applying any filter. * @param stream the stream * @param file the location where the stream is * @throws IOException on error * @return the stream content */ public static byte[] getStreamBytesRaw(PRStream stream, RandomAccessFileOrArray file) throws IOException { PdfReader reader = stream.getReader(); byte b[]; if (stream.getOffset() < 0) b = stream.getBytes(); else { b = new byte[stream.getLength()]; file.seek(stream.getOffset()); file.readFully(b); PdfEncryption decrypt = reader.getDecrypt(); if (decrypt != null) { PdfObject filter = getPdfObjectRelease(stream.get(PdfName.FILTER)); ArrayList filters = new ArrayList(); if (filter != null) { if (filter.isName()) filters.add(filter); else if (filter.isArray()) filters = ((PdfArray)filter).getArrayList(); } boolean skip = false; for (int k = 0; k < filters.size(); ++k) { PdfObject obj = getPdfObjectRelease((PdfObject)filters.get(k)); if (obj != null && obj.toString().equals("/Crypt")) { skip = true; break; } } if (!skip) { decrypt.setHashKey(stream.getObjNum(), stream.getObjGen()); b = decrypt.decryptByteArray(b); } } } return b; } /** Get the content from a stream as it is without applying any filter. * @param stream the stream * @throws IOException on error * @return the stream content */ public static byte[] getStreamBytesRaw(PRStream stream) throws IOException { RandomAccessFileOrArray rf = stream.getReader().getSafeFile(); try { rf.reOpen(); return getStreamBytesRaw(stream, rf); } finally { try{rf.close();}catch(Exception e){} } } /** Eliminates shared streams if they exist. */ public void eliminateSharedStreams() { if (!sharedStreams) return; sharedStreams = false; if (pageRefs.size() == 1) return; ArrayList newRefs = new ArrayList(); ArrayList newStreams = new ArrayList(); IntHashtable visited = new IntHashtable(); for (int k = 1; k <= pageRefs.size(); ++k) { PdfDictionary page = pageRefs.getPageN(k); if (page == null) continue; PdfObject contents = getPdfObject(page.get(PdfName.CONTENTS)); if (contents == null) continue; if (contents.isStream()) { PRIndirectReference ref = (PRIndirectReference)page.get(PdfName.CONTENTS); if (visited.containsKey(ref.getNumber())) { // need to duplicate newRefs.add(ref); newStreams.add(new PRStream((PRStream)contents, null)); } else visited.put(ref.getNumber(), 1); } else if (contents.isArray()) { PdfArray array = (PdfArray)contents; for (int j = 0; j < array.size(); ++j) { PRIndirectReference ref = (PRIndirectReference)array.getPdfObject(j); if (visited.containsKey(ref.getNumber())) { // need to duplicate newRefs.add(ref); newStreams.add(new PRStream((PRStream)getPdfObject(ref), null)); } else visited.put(ref.getNumber(), 1); } } } if (newStreams.isEmpty()) return; for (int k = 0; k < newStreams.size(); ++k) { xrefObj.add(newStreams.get(k)); PRIndirectReference ref = (PRIndirectReference)newRefs.get(k); ref.setNumber(xrefObj.size() - 1, 0); } } /** Checks if the document was changed. * @return true if the document was changed, * false otherwise */ public boolean isTampered() { return tampered; } /** * Sets the tampered state. A tampered PdfReader cannot be reused in PdfStamper. * @param tampered the tampered state */ public void setTampered(boolean tampered) { this.tampered = tampered; pageRefs.keepPages(); } /** Gets the XML metadata. * @throws IOException on error * @return the XML metadata */ public byte[] getMetadata() throws IOException { PdfObject obj = getPdfObject(catalog.get(PdfName.METADATA)); if (!(obj instanceof PRStream)) return null; RandomAccessFileOrArray rf = getSafeFile(); byte b[] = null; try { rf.reOpen(); b = getStreamBytes((PRStream)obj, rf); } finally { try { rf.close(); } catch (Exception e) { // empty on purpose } } return b; } /** * Gets the byte address of the last xref table. * @return the byte address of the last xref table */ public int getLastXref() { return lastXref; } /** * Gets the number of xref objects. * @return the number of xref objects */ public int getXrefSize() { return xrefObj.size(); } /** * Gets the byte address of the %%EOF marker. * @return the byte address of the %%EOF marker */ public int getEofPos() { return eofPos; } /** * Gets the PDF version. Only the last version char is returned. For example * version 1.4 is returned as '4'. * @return the PDF version */ public char getPdfVersion() { return pdfVersion; } /** * Returns true if the PDF is encrypted. * @return true if the PDF is encrypted */ public boolean isEncrypted() { return encrypted; } /** * Gets the encryption permissions. It can be used directly in * PdfWriter.setEncryption(). * @return the encryption permissions */ public int getPermissions() { return pValue; } /** * Returns true if the PDF has a 128 bit key encryption. * @return true if the PDF has a 128 bit key encryption */ public boolean is128Key() { return rValue == 3; } /** * Gets the trailer dictionary * @return the trailer dictionary */ public PdfDictionary getTrailer() { return trailer; } PdfEncryption getDecrypt() { return decrypt; } static boolean equalsn(byte a1[], byte a2[]) { int length = a2.length; for (int k = 0; k < length; ++k) { if (a1[k] != a2[k]) return false; } return true; } static boolean existsName(PdfDictionary dic, PdfName key, PdfName value) { PdfObject type = getPdfObjectRelease(dic.get(key)); if (type == null || !type.isName()) return false; PdfName name = (PdfName)type; return name.equals(value); } static String getFontName(PdfDictionary dic) { if (dic == null) return null; PdfObject type = getPdfObjectRelease(dic.get(PdfName.BASEFONT)); if (type == null || !type.isName()) return null; return PdfName.decodeName(type.toString()); } static String getSubsetPrefix(PdfDictionary dic) { if (dic == null) return null; String s = getFontName(dic); if (s == null) return null; if (s.length() < 8 || s.charAt(6) != '+') return null; for (int k = 0; k < 6; ++k) { char c = s.charAt(k); if (c < 'A' || c > 'Z') return null; } return s; } /** Finds all the font subsets and changes the prefixes to some * random values. * @return the number of font subsets altered */ public int shuffleSubsetNames() { int total = 0; for (int k = 1; k < xrefObj.size(); ++k) { PdfObject obj = getPdfObjectRelease(k); if (obj == null || !obj.isDictionary()) continue; PdfDictionary dic = (PdfDictionary)obj; if (!existsName(dic, PdfName.TYPE, PdfName.FONT)) continue; if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE1) || existsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1) || existsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) { String s = getSubsetPrefix(dic); if (s == null) continue; String ns = BaseFont.createSubsetPrefix() + s.substring(7); PdfName newName = new PdfName(ns); dic.put(PdfName.BASEFONT, newName); setXrefPartialObject(k, dic); ++total; PdfDictionary fd = dic.getAsDict(PdfName.FONTDESCRIPTOR); if (fd == null) continue; fd.put(PdfName.FONTNAME, newName); } else if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE0)) { String s = getSubsetPrefix(dic); PdfArray arr = dic.getAsArray(PdfName.DESCENDANTFONTS); if (arr == null) continue; if (arr.isEmpty()) continue; PdfDictionary desc = arr.getAsDict(0); String sde = getSubsetPrefix(desc); if (sde == null) continue; String ns = BaseFont.createSubsetPrefix(); if (s != null) dic.put(PdfName.BASEFONT, new PdfName(ns + s.substring(7))); setXrefPartialObject(k, dic); PdfName newName = new PdfName(ns + sde.substring(7)); desc.put(PdfName.BASEFONT, newName); ++total; PdfDictionary fd = desc.getAsDict(PdfName.FONTDESCRIPTOR); if (fd == null) continue; fd.put(PdfName.FONTNAME, newName); } } return total; } /** Finds all the fonts not subset but embedded and marks them as subset. * @return the number of fonts altered */ public int createFakeFontSubsets() { int total = 0; for (int k = 1; k < xrefObj.size(); ++k) { PdfObject obj = getPdfObjectRelease(k); if (obj == null || !obj.isDictionary()) continue; PdfDictionary dic = (PdfDictionary)obj; if (!existsName(dic, PdfName.TYPE, PdfName.FONT)) continue; if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE1) || existsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1) || existsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) { String s = getSubsetPrefix(dic); if (s != null) continue; s = getFontName(dic); if (s == null) continue; String ns = BaseFont.createSubsetPrefix() + s; PdfDictionary fd = (PdfDictionary)getPdfObjectRelease(dic.get(PdfName.FONTDESCRIPTOR)); if (fd == null) continue; if (fd.get(PdfName.FONTFILE) == null && fd.get(PdfName.FONTFILE2) == null && fd.get(PdfName.FONTFILE3) == null) continue; fd = dic.getAsDict(PdfName.FONTDESCRIPTOR); PdfName newName = new PdfName(ns); dic.put(PdfName.BASEFONT, newName); fd.put(PdfName.FONTNAME, newName); setXrefPartialObject(k, dic); ++total; } } return total; } private static PdfArray getNameArray(PdfObject obj) { if (obj == null) return null; obj = getPdfObjectRelease(obj); if (obj == null) return null; if (obj.isArray()) return (PdfArray)obj; else if (obj.isDictionary()) { PdfObject arr2 = getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.D)); if (arr2 != null && arr2.isArray()) return (PdfArray)arr2; } return null; } /** * Gets all the named destinations as an HashMap. The key is the name * and the value is the destinations array. * @return gets all the named destinations */ public HashMap getNamedDestination() { return getNamedDestination(false); } /** * Gets all the named destinations as an HashMap. The key is the name * and the value is the destinations array. * @param keepNames true if you want the keys to be real PdfNames instead of Strings * @return gets all the named destinations * @since 2.1.6 */ public HashMap getNamedDestination(boolean keepNames) { HashMap names = getNamedDestinationFromNames(keepNames); names.putAll(getNamedDestinationFromStrings()); return names; } /** * Gets the named destinations from the /Dests key in the catalog as an HashMap. The key is the name * and the value is the destinations array. * @return gets the named destinations */ public HashMap getNamedDestinationFromNames() { return getNamedDestinationFromNames(false); } /** * Gets the named destinations from the /Dests key in the catalog as an HashMap. The key is the name * and the value is the destinations array. * @param keepNames true if you want the keys to be real PdfNames instead of Strings * @return gets the named destinations * @since 2.1.6 */ public HashMap getNamedDestinationFromNames(boolean keepNames) { HashMap names = new HashMap(); if (catalog.get(PdfName.DESTS) != null) { PdfDictionary dic = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.DESTS)); if (dic == null) return names; Set keys = dic.getKeys(); for (Iterator it = keys.iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); PdfArray arr = getNameArray(dic.get(key)); if (arr == null) continue; if (keepNames) { names.put(key, arr); } else { String name = PdfName.decodeName(key.toString()); names.put(name, arr); } } } return names; } /** * Gets the named destinations from the /Names key in the catalog as an HashMap. The key is the name * and the value is the destinations array. * @return gets the named destinations */ public HashMap getNamedDestinationFromStrings() { if (catalog.get(PdfName.NAMES) != null) { PdfDictionary dic = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.NAMES)); if (dic != null) { dic = (PdfDictionary)getPdfObjectRelease(dic.get(PdfName.DESTS)); if (dic != null) { HashMap names = PdfNameTree.readTree(dic); for (Iterator it = names.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); PdfArray arr = getNameArray((PdfObject)entry.getValue()); if (arr != null) entry.setValue(arr); else it.remove(); } return names; } } } return new HashMap(); } private boolean replaceNamedDestination(PdfObject obj, HashMap names) { obj = getPdfObject(obj); int objIdx = lastXrefPartial; releaseLastXrefPartial(); if (obj != null && obj.isDictionary()) { PdfObject ob2 = getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.DEST)); Object name = null; if (ob2 != null) { if (ob2.isName()) name = ob2; else if (ob2.isString()) name = ob2.toString(); PdfArray dest = (PdfArray)names.get(name); if (dest != null) { ((PdfDictionary)obj).put(PdfName.DEST, dest); setXrefPartialObject(objIdx, obj); return true; } } else if ((ob2 = getPdfObject(((PdfDictionary)obj).get(PdfName.A))) != null) { int obj2Idx = lastXrefPartial; releaseLastXrefPartial(); PdfDictionary dic = (PdfDictionary)ob2; PdfName type = (PdfName)getPdfObjectRelease(dic.get(PdfName.S)); if (PdfName.GOTO.equals(type)) { PdfObject ob3 = getPdfObjectRelease(dic.get(PdfName.D)); if (ob3 != null) { if (ob3.isName()) name = ob3; else if (ob3.isString()) name = ob3.toString(); } PdfArray dest = (PdfArray)names.get(name); if (dest != null) { dic.put(PdfName.D, dest); setXrefPartialObject(obj2Idx, ob2); setXrefPartialObject(objIdx, obj); return true; } } } } return false; } /** * Removes all the fields from the document. */ public void removeFields() { pageRefs.resetReleasePage(); for (int k = 1; k <= pageRefs.size(); ++k) { PdfDictionary page = pageRefs.getPageN(k); PdfArray annots = page.getAsArray(PdfName.ANNOTS); if (annots == null) { pageRefs.releasePage(k); continue; } for (int j = 0; j < annots.size(); ++j) { PdfObject obj = getPdfObjectRelease(annots.getPdfObject(j)); if (obj == null || !obj.isDictionary()) continue; PdfDictionary annot = (PdfDictionary)obj; if (PdfName.WIDGET.equals(annot.get(PdfName.SUBTYPE))) annots.remove(j--); } if (annots.isEmpty()) page.remove(PdfName.ANNOTS); else pageRefs.releasePage(k); } catalog.remove(PdfName.ACROFORM); pageRefs.resetReleasePage(); } /** * Removes all the annotations and fields from the document. */ public void removeAnnotations() { pageRefs.resetReleasePage(); for (int k = 1; k <= pageRefs.size(); ++k) { PdfDictionary page = pageRefs.getPageN(k); if (page.get(PdfName.ANNOTS) == null) pageRefs.releasePage(k); else page.remove(PdfName.ANNOTS); } catalog.remove(PdfName.ACROFORM); pageRefs.resetReleasePage(); } public ArrayList getLinks(int page) { pageRefs.resetReleasePage(); ArrayList result = new ArrayList(); PdfDictionary pageDic = pageRefs.getPageN(page); if (pageDic.get(PdfName.ANNOTS) != null) { PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); for (int j = 0; j < annots.size(); ++j) { PdfDictionary annot = (PdfDictionary)getPdfObjectRelease(annots.getPdfObject(j)); if (PdfName.LINK.equals(annot.get(PdfName.SUBTYPE))) { result.add(new PdfAnnotation.PdfImportedLink(annot)); } } } pageRefs.releasePage(page); pageRefs.resetReleasePage(); return result; } private void iterateBookmarks(PdfObject outlineRef, HashMap names) { while (outlineRef != null) { replaceNamedDestination(outlineRef, names); PdfDictionary outline = (PdfDictionary)getPdfObjectRelease(outlineRef); PdfObject first = outline.get(PdfName.FIRST); if (first != null) { iterateBookmarks(first, names); } outlineRef = outline.get(PdfName.NEXT); } } /** Replaces all the local named links with the actual destinations. */ public void consolidateNamedDestinations() { if (consolidateNamedDestinations) return; consolidateNamedDestinations = true; HashMap names = getNamedDestination(true); if (names.isEmpty()) return; for (int k = 1; k <= pageRefs.size(); ++k) { PdfDictionary page = pageRefs.getPageN(k); PdfObject annotsRef; PdfArray annots = (PdfArray)getPdfObject(annotsRef = page.get(PdfName.ANNOTS)); int annotIdx = lastXrefPartial; releaseLastXrefPartial(); if (annots == null) { pageRefs.releasePage(k); continue; } boolean commitAnnots = false; for (int an = 0; an < annots.size(); ++an) { PdfObject objRef = annots.getPdfObject(an); if (replaceNamedDestination(objRef, names) && !objRef.isIndirect()) commitAnnots = true; } if (commitAnnots) setXrefPartialObject(annotIdx, annots); if (!commitAnnots || annotsRef.isIndirect()) pageRefs.releasePage(k); } PdfDictionary outlines = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.OUTLINES)); if (outlines == null) return; iterateBookmarks(outlines.get(PdfName.FIRST), names); } protected static PdfDictionary duplicatePdfDictionary(PdfDictionary original, PdfDictionary copy, PdfReader newReader) { if (copy == null) copy = new PdfDictionary(); for (Iterator it = original.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); copy.put(key, duplicatePdfObject(original.get(key), newReader)); } return copy; } protected static PdfObject duplicatePdfObject(PdfObject original, PdfReader newReader) { if (original == null) return null; switch (original.type()) { case PdfObject.DICTIONARY: { return duplicatePdfDictionary((PdfDictionary)original, null, newReader); } case PdfObject.STREAM: { PRStream org = (PRStream)original; PRStream stream = new PRStream(org, null, newReader); duplicatePdfDictionary(org, stream, newReader); return stream; } case PdfObject.ARRAY: { PdfArray arr = new PdfArray(); for (Iterator it = ((PdfArray)original).listIterator(); it.hasNext();) { arr.add(duplicatePdfObject((PdfObject)it.next(), newReader)); } return arr; } case PdfObject.INDIRECT: { PRIndirectReference org = (PRIndirectReference)original; return new PRIndirectReference(newReader, org.getNumber(), org.getGeneration()); } default: return original; } } /** * Closes the reader */ public void close() { if (!partial) return; try { tokens.close(); } catch (IOException e) { throw new ExceptionConverter(e); } } protected void removeUnusedNode(PdfObject obj, boolean hits[]) { Stack state = new Stack(); state.push(obj); while (!state.empty()) { Object current = state.pop(); if (current == null) continue; ArrayList ar = null; PdfDictionary dic = null; PdfName[] keys = null; Object[] objs = null; int idx = 0; if (current instanceof PdfObject) { obj = (PdfObject)current; switch (obj.type()) { case PdfObject.DICTIONARY: case PdfObject.STREAM: dic = (PdfDictionary)obj; keys = new PdfName[dic.size()]; dic.getKeys().toArray(keys); break; case PdfObject.ARRAY: ar = ((PdfArray)obj).getArrayList(); break; case PdfObject.INDIRECT: PRIndirectReference ref = (PRIndirectReference)obj; int num = ref.getNumber(); if (!hits[num]) { hits[num] = true; state.push(getPdfObjectRelease(ref)); } continue; default: continue; } } else { objs = (Object[])current; if (objs[0] instanceof ArrayList) { ar = (ArrayList)objs[0]; idx = ((Integer)objs[1]).intValue(); } else { keys = (PdfName[])objs[0]; dic = (PdfDictionary)objs[1]; idx = ((Integer)objs[2]).intValue(); } } if (ar != null) { for (int k = idx; k < ar.size(); ++k) { PdfObject v = (PdfObject)ar.get(k); if (v.isIndirect()) { int num = ((PRIndirectReference)v).getNumber(); if (num >= xrefObj.size() || (!partial && xrefObj.get(num) == null)) { ar.set(k, PdfNull.PDFNULL); continue; } } if (objs == null) state.push(new Object[]{ar, new Integer(k + 1)}); else { objs[1] = new Integer(k + 1); state.push(objs); } state.push(v); break; } } else { for (int k = idx; k < keys.length; ++k) { PdfName key = keys[k]; PdfObject v = dic.get(key); if (v.isIndirect()) { int num = ((PRIndirectReference)v).getNumber(); if (num >= xrefObj.size() || (!partial && xrefObj.get(num) == null)) { dic.put(key, PdfNull.PDFNULL); continue; } } if (objs == null) state.push(new Object[]{keys, dic, new Integer(k + 1)}); else { objs[2] = new Integer(k + 1); state.push(objs); } state.push(v); break; } } } } /** Removes all the unreachable objects. * @return the number of indirect objects removed */ public int removeUnusedObjects() { boolean hits[] = new boolean[xrefObj.size()]; removeUnusedNode(trailer, hits); int total = 0; if (partial) { for (int k = 1; k < hits.length; ++k) { if (!hits[k]) { xref[k * 2] = -1; xref[k * 2 + 1] = 0; xrefObj.set(k, null); ++total; } } } else { for (int k = 1; k < hits.length; ++k) { if (!hits[k]) { xrefObj.set(k, null); ++total; } } } return total; } /** Gets a read-only version of AcroFields. * @return a read-only version of AcroFields */ public AcroFields getAcroFields() { return new AcroFields(this, null); } /** * Gets the global document JavaScript. * @param file the document file * @throws IOException on error * @return the global document JavaScript */ public String getJavaScript(RandomAccessFileOrArray file) throws IOException { PdfDictionary names = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.NAMES)); if (names == null) return null; PdfDictionary js = (PdfDictionary)getPdfObjectRelease(names.get(PdfName.JAVASCRIPT)); if (js == null) return null; HashMap jscript = PdfNameTree.readTree(js); String sortedNames[] = new String[jscript.size()]; sortedNames = (String[])jscript.keySet().toArray(sortedNames); Arrays.sort(sortedNames); StringBuffer buf = new StringBuffer(); for (int k = 0; k < sortedNames.length; ++k) { PdfDictionary j = (PdfDictionary)getPdfObjectRelease((PdfIndirectReference)jscript.get(sortedNames[k])); if (j == null) continue; PdfObject obj = getPdfObjectRelease(j.get(PdfName.JS)); if (obj != null) { if (obj.isString()) buf.append(((PdfString)obj).toUnicodeString()).append('\n'); else if (obj.isStream()) { byte bytes[] = getStreamBytes((PRStream)obj, file); if (bytes.length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255) buf.append(PdfEncodings.convertToString(bytes, PdfObject.TEXT_UNICODE)); else buf.append(PdfEncodings.convertToString(bytes, PdfObject.TEXT_PDFDOCENCODING)); buf.append('\n'); } } } return buf.toString(); } /** * Gets the global document JavaScript. * @throws IOException on error * @return the global document JavaScript */ public String getJavaScript() throws IOException { RandomAccessFileOrArray rf = getSafeFile(); try { rf.reOpen(); return getJavaScript(rf); } finally { try{rf.close();}catch(Exception e){} } } /** * Selects the pages to keep in the document. The pages are described as * ranges. The page ordering can be changed but * no page repetitions are allowed. Note that it may be very slow in partial mode. * @param ranges the comma separated ranges as described in {@link SequenceList} */ public void selectPages(String ranges) { selectPages(SequenceList.expand(ranges, getNumberOfPages())); } /** * Selects the pages to keep in the document. The pages are described as a * List of Integer. The page ordering can be changed but * no page repetitions are allowed. Note that it may be very slow in partial mode. * @param pagesToKeep the pages to keep in the document */ public void selectPages(List pagesToKeep) { pageRefs.selectPages(pagesToKeep); removeUnusedObjects(); } /** Sets the viewer preferences as the sum of several constants. * @param preferences the viewer preferences * @see PdfViewerPreferences#setViewerPreferences */ public void setViewerPreferences(int preferences) { this.viewerPreferences.setViewerPreferences(preferences); setViewerPreferences(this.viewerPreferences); } /** Adds a viewer preference * @param key a key for a viewer preference * @param value a value for the viewer preference * @see PdfViewerPreferences#addViewerPreference */ public void addViewerPreference(PdfName key, PdfObject value) { this.viewerPreferences.addViewerPreference(key, value); setViewerPreferences(this.viewerPreferences); } void setViewerPreferences(PdfViewerPreferencesImp vp) { vp.addToCatalog(catalog); } /** * Returns a bitset representing the PageMode and PageLayout viewer preferences. * Doesn't return any information about the ViewerPreferences dictionary. * @return an int that contains the Viewer Preferences. */ public int getSimpleViewerPreferences() { return PdfViewerPreferencesImp.getViewerPreferences(catalog).getPageLayoutAndMode(); } /** * Getter for property appendable. * @return Value of property appendable. */ public boolean isAppendable() { return this.appendable; } /** * Setter for property appendable. * @param appendable New value of property appendable. */ public void setAppendable(boolean appendable) { this.appendable = appendable; if (appendable) getPdfObject(trailer.get(PdfName.ROOT)); } /** * Getter for property newXrefType. * @return Value of property newXrefType. */ public boolean isNewXrefType() { return newXrefType; } /** * Getter for property fileLength. * @return Value of property fileLength. */ public int getFileLength() { return fileLength; } /** * Getter for property hybridXref. * @return Value of property hybridXref. */ public boolean isHybridXref() { return hybridXref; } static class PageRefs { private PdfReader reader; private IntHashtable refsp; private ArrayList refsn; private ArrayList pageInh; private int lastPageRead = -1; private int sizep; private boolean keepPages; private PageRefs(PdfReader reader) throws IOException { this.reader = reader; if (reader.partial) { refsp = new IntHashtable(); PdfNumber npages = (PdfNumber)PdfReader.getPdfObjectRelease(reader.rootPages.get(PdfName.COUNT)); sizep = npages.intValue(); } else { readPages(); } } PageRefs(PageRefs other, PdfReader reader) { this.reader = reader; this.sizep = other.sizep; if (other.refsn != null) { refsn = new ArrayList(other.refsn); for (int k = 0; k < refsn.size(); ++k) { refsn.set(k, duplicatePdfObject((PdfObject)refsn.get(k), reader)); } } else this.refsp = (IntHashtable)other.refsp.clone(); } int size() { if (refsn != null) return refsn.size(); else return sizep; } void readPages() throws IOException { if (refsn != null) return; refsp = null; refsn = new ArrayList(); pageInh = new ArrayList(); iteratePages((PRIndirectReference)reader.catalog.get(PdfName.PAGES)); pageInh = null; reader.rootPages.put(PdfName.COUNT, new PdfNumber(refsn.size())); } void reReadPages() throws IOException { refsn = null; readPages(); } /** Gets the dictionary that represents a page. * @param pageNum the page number. 1 is the first * @return the page dictionary */ public PdfDictionary getPageN(int pageNum) { PRIndirectReference ref = getPageOrigRef(pageNum); return (PdfDictionary)PdfReader.getPdfObject(ref); } /** * @param pageNum * @return a dictionary object */ public PdfDictionary getPageNRelease(int pageNum) { PdfDictionary page = getPageN(pageNum); releasePage(pageNum); return page; } /** * @param pageNum * @return an indirect reference */ public PRIndirectReference getPageOrigRefRelease(int pageNum) { PRIndirectReference ref = getPageOrigRef(pageNum); releasePage(pageNum); return ref; } /** Gets the page reference to this page. * @param pageNum the page number. 1 is the first * @return the page reference */ public PRIndirectReference getPageOrigRef(int pageNum) { try { --pageNum; if (pageNum < 0 || pageNum >= size()) return null; if (refsn != null) return (PRIndirectReference)refsn.get(pageNum); else { int n = refsp.get(pageNum); if (n == 0) { PRIndirectReference ref = getSinglePage(pageNum); if (reader.lastXrefPartial == -1) lastPageRead = -1; else lastPageRead = pageNum; reader.lastXrefPartial = -1; refsp.put(pageNum, ref.getNumber()); if (keepPages) lastPageRead = -1; return ref; } else { if (lastPageRead != pageNum) lastPageRead = -1; if (keepPages) lastPageRead = -1; return new PRIndirectReference(reader, n); } } } catch (Exception e) { throw new ExceptionConverter(e); } } void keepPages() { if (refsp == null || keepPages) return; keepPages = true; refsp.clear(); } /** * @param pageNum */ public void releasePage(int pageNum) { if (refsp == null) return; --pageNum; if (pageNum < 0 || pageNum >= size()) return; if (pageNum != lastPageRead) return; lastPageRead = -1; reader.lastXrefPartial = refsp.get(pageNum); reader.releaseLastXrefPartial(); refsp.remove(pageNum); } /** * */ public void resetReleasePage() { if (refsp == null) return; lastPageRead = -1; } void insertPage(int pageNum, PRIndirectReference ref) { --pageNum; if (refsn != null) { if (pageNum >= refsn.size()) refsn.add(ref); else refsn.add(pageNum, ref); } else { ++sizep; lastPageRead = -1; if (pageNum >= size()) { refsp.put(size(), ref.getNumber()); } else { IntHashtable refs2 = new IntHashtable((refsp.size() + 1) * 2); for (Iterator it = refsp.getEntryIterator(); it.hasNext();) { IntHashtable.Entry entry = (IntHashtable.Entry)it.next(); int p = entry.getKey(); refs2.put(p >= pageNum ? p + 1 : p, entry.getValue()); } refs2.put(pageNum, ref.getNumber()); refsp = refs2; } } } private void pushPageAttributes(PdfDictionary nodePages) { PdfDictionary dic = new PdfDictionary(); if (!pageInh.isEmpty()) { dic.putAll((PdfDictionary)pageInh.get(pageInh.size() - 1)); } for (int k = 0; k < pageInhCandidates.length; ++k) { PdfObject obj = nodePages.get(pageInhCandidates[k]); if (obj != null) dic.put(pageInhCandidates[k], obj); } pageInh.add(dic); } private void popPageAttributes() { pageInh.remove(pageInh.size() - 1); } private void iteratePages(PRIndirectReference rpage) throws IOException { PdfDictionary page = (PdfDictionary)getPdfObject(rpage); PdfArray kidsPR = page.getAsArray(PdfName.KIDS); if (kidsPR == null) { page.put(PdfName.TYPE, PdfName.PAGE); PdfDictionary dic = (PdfDictionary)pageInh.get(pageInh.size() - 1); PdfName key; for (Iterator i = dic.getKeys().iterator(); i.hasNext();) { key = (PdfName)i.next(); if (page.get(key) == null) page.put(key, dic.get(key)); } if (page.get(PdfName.MEDIABOX) == null) { PdfArray arr = new PdfArray(new float[]{0,0,PageSize.LETTER.getRight(),PageSize.LETTER.getTop()}); page.put(PdfName.MEDIABOX, arr); } refsn.add(rpage); } else { page.put(PdfName.TYPE, PdfName.PAGES); pushPageAttributes(page); for (int k = 0; k < kidsPR.size(); ++k){ PdfObject obj = kidsPR.getPdfObject(k); if (!obj.isIndirect()) { while (k < kidsPR.size()) kidsPR.remove(k); break; } iteratePages((PRIndirectReference)obj); } popPageAttributes(); } } protected PRIndirectReference getSinglePage(int n) { PdfDictionary acc = new PdfDictionary(); PdfDictionary top = reader.rootPages; int base = 0; while (true) { for (int k = 0; k < pageInhCandidates.length; ++k) { PdfObject obj = top.get(pageInhCandidates[k]); if (obj != null) acc.put(pageInhCandidates[k], obj); } PdfArray kids = (PdfArray)PdfReader.getPdfObjectRelease(top.get(PdfName.KIDS)); for (Iterator it = kids.listIterator(); it.hasNext();) { PRIndirectReference ref = (PRIndirectReference)it.next(); PdfDictionary dic = (PdfDictionary)getPdfObject(ref); int last = reader.lastXrefPartial; PdfObject count = getPdfObjectRelease(dic.get(PdfName.COUNT)); reader.lastXrefPartial = last; int acn = 1; if (count != null && count.type() == PdfObject.NUMBER) acn = ((PdfNumber)count).intValue(); if (n < base + acn) { if (count == null) { dic.mergeDifferent(acc); return ref; } reader.releaseLastXrefPartial(); top = dic; break; } reader.releaseLastXrefPartial(); base += acn; } } } private void selectPages(List pagesToKeep) { IntHashtable pg = new IntHashtable(); ArrayList finalPages = new ArrayList(); int psize = size(); for (Iterator it = pagesToKeep.iterator(); it.hasNext();) { Integer pi = (Integer)it.next(); int p = pi.intValue(); if (p >= 1 && p <= psize && pg.put(p, 1) == 0) finalPages.add(pi); } if (reader.partial) { for (int k = 1; k <= psize; ++k) { getPageOrigRef(k); resetReleasePage(); } } PRIndirectReference parent = (PRIndirectReference)reader.catalog.get(PdfName.PAGES); PdfDictionary topPages = (PdfDictionary)PdfReader.getPdfObject(parent); ArrayList newPageRefs = new ArrayList(finalPages.size()); PdfArray kids = new PdfArray(); for (int k = 0; k < finalPages.size(); ++k) { int p = ((Integer)finalPages.get(k)).intValue(); PRIndirectReference pref = getPageOrigRef(p); resetReleasePage(); kids.add(pref); newPageRefs.add(pref); getPageN(p).put(PdfName.PARENT, parent); } AcroFields af = reader.getAcroFields(); boolean removeFields = (af.getFields().size() > 0); for (int k = 1; k <= psize; ++k) { if (!pg.containsKey(k)) { if (removeFields) af.removeFieldsFromPage(k); PRIndirectReference pref = getPageOrigRef(k); int nref = pref.getNumber(); reader.xrefObj.set(nref, null); if (reader.partial) { reader.xref[nref * 2] = -1; reader.xref[nref * 2 + 1] = 0; } } } topPages.put(PdfName.COUNT, new PdfNumber(finalPages.size())); topPages.put(PdfName.KIDS, kids); refsp = null; refsn = newPageRefs; } } PdfIndirectReference getCryptoRef() { if (cryptoRef == null) return null; return new PdfIndirectReference(0, cryptoRef.getNumber(), cryptoRef.getGeneration()); } /** * Removes any usage rights that this PDF may have. Only Adobe can grant usage rights * and any PDF modification with iText will invalidate them. Invalidated usage rights may * confuse Acrobat and it's advisable to remove them altogether. */ public void removeUsageRights() { PdfDictionary perms = catalog.getAsDict(PdfName.PERMS); if (perms == null) return; perms.remove(PdfName.UR); perms.remove(PdfName.UR3); if (perms.size() == 0) catalog.remove(PdfName.PERMS); } /** * Gets the certification level for this document. The return values can be PdfSignatureAppearance.NOT_CERTIFIED, * PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED, * PdfSignatureAppearance.CERTIFIED_FORM_FILLING and * PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS. *

* No signature validation is made, use the methods available for that in AcroFields. *

* @return gets the certification level for this document */ public int getCertificationLevel() { PdfDictionary dic = catalog.getAsDict(PdfName.PERMS); if (dic == null) return PdfSignatureAppearance.NOT_CERTIFIED; dic = dic.getAsDict(PdfName.DOCMDP); if (dic == null) return PdfSignatureAppearance.NOT_CERTIFIED; PdfArray arr = dic.getAsArray(PdfName.REFERENCE); if (arr == null || arr.size() == 0) return PdfSignatureAppearance.NOT_CERTIFIED; dic = arr.getAsDict(0); if (dic == null) return PdfSignatureAppearance.NOT_CERTIFIED; dic = dic.getAsDict(PdfName.TRANSFORMPARAMS); if (dic == null) return PdfSignatureAppearance.NOT_CERTIFIED; PdfNumber p = dic.getAsNumber(PdfName.P); if (p == null) return PdfSignatureAppearance.NOT_CERTIFIED; return p.intValue(); } /** * Checks if the document was opened with the owner password so that the end application * can decide what level of access restrictions to apply. If the document is not encrypted * it will return true. * @return true if the document was opened with the owner password or if it's not encrypted, * false if the document was opened with the user password */ public final boolean isOpenedWithFullPermissions() { return !encrypted || ownerPasswordUsed; } public int getCryptoMode() { if (decrypt == null) return -1; else return decrypt.getCryptoMode(); } public boolean isMetadataEncrypted() { if (decrypt == null) return false; else return decrypt.isMetadataEncrypted(); } public byte[] computeUserPassword() { if (!encrypted || !ownerPasswordUsed) return null; return decrypt.computeUserPassword(password); } }src/core/com/lowagie/text/pdf/PdfReaderInstance.java100644 0 0 16540 11036112746 20101 0ustar 0 0 /* * $Id: PdfReaderInstance.java 3527 2008-07-06 15:34:38Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; /** * Instance of PdfReader in each output document. * * @author Paulo Soares (psoares@consiste.pt) */ class PdfReaderInstance { static final PdfLiteral IDENTITYMATRIX = new PdfLiteral("[1 0 0 1 0 0]"); static final PdfNumber ONE = new PdfNumber(1); int myXref[]; PdfReader reader; RandomAccessFileOrArray file; HashMap importedPages = new HashMap(); PdfWriter writer; HashMap visited = new HashMap(); ArrayList nextRound = new ArrayList(); PdfReaderInstance(PdfReader reader, PdfWriter writer) { this.reader = reader; this.writer = writer; file = reader.getSafeFile(); myXref = new int[reader.getXrefSize()]; } PdfReader getReader() { return reader; } PdfImportedPage getImportedPage(int pageNumber) { if (!reader.isOpenedWithFullPermissions()) throw new IllegalArgumentException("PdfReader not opened with owner password"); if (pageNumber < 1 || pageNumber > reader.getNumberOfPages()) throw new IllegalArgumentException("Invalid page number: " + pageNumber); Integer i = new Integer(pageNumber); PdfImportedPage pageT = (PdfImportedPage)importedPages.get(i); if (pageT == null) { pageT = new PdfImportedPage(this, writer, pageNumber); importedPages.put(i, pageT); } return pageT; } int getNewObjectNumber(int number, int generation) { if (myXref[number] == 0) { myXref[number] = writer.getIndirectReferenceNumber(); nextRound.add(new Integer(number)); } return myXref[number]; } RandomAccessFileOrArray getReaderFile() { return file; } PdfObject getResources(int pageNumber) { PdfObject obj = PdfReader.getPdfObjectRelease(reader.getPageNRelease(pageNumber).get(PdfName.RESOURCES)); return obj; } /** * Gets the content stream of a page as a PdfStream object. * @param pageNumber the page of which you want the stream * @param compressionLevel the compression level you want to apply to the stream * @return a PdfStream object * @since 2.1.3 (the method already existed without param compressionLevel) */ PdfStream getFormXObject(int pageNumber, int compressionLevel) throws IOException { PdfDictionary page = reader.getPageNRelease(pageNumber); PdfObject contents = PdfReader.getPdfObjectRelease(page.get(PdfName.CONTENTS)); PdfDictionary dic = new PdfDictionary(); byte bout[] = null; if (contents != null) { if (contents.isStream()) dic.putAll((PRStream)contents); else bout = reader.getPageContent(pageNumber, file); } else bout = new byte[0]; dic.put(PdfName.RESOURCES, PdfReader.getPdfObjectRelease(page.get(PdfName.RESOURCES))); dic.put(PdfName.TYPE, PdfName.XOBJECT); dic.put(PdfName.SUBTYPE, PdfName.FORM); PdfImportedPage impPage = (PdfImportedPage)importedPages.get(new Integer(pageNumber)); dic.put(PdfName.BBOX, new PdfRectangle(impPage.getBoundingBox())); PdfArray matrix = impPage.getMatrix(); if (matrix == null) dic.put(PdfName.MATRIX, IDENTITYMATRIX); else dic.put(PdfName.MATRIX, matrix); dic.put(PdfName.FORMTYPE, ONE); PRStream stream; if (bout == null) { stream = new PRStream((PRStream)contents, dic); } else { stream = new PRStream(reader, bout, compressionLevel); stream.putAll(dic); } return stream; } void writeAllVisited() throws IOException { while (!nextRound.isEmpty()) { ArrayList vec = nextRound; nextRound = new ArrayList(); for (int k = 0; k < vec.size(); ++k) { Integer i = (Integer)vec.get(k); if (!visited.containsKey(i)) { visited.put(i, null); int n = i.intValue(); writer.addToBody(reader.getPdfObjectRelease(n), myXref[n]); } } } } void writeAllPages() throws IOException { try { file.reOpen(); for (Iterator it = importedPages.values().iterator(); it.hasNext();) { PdfImportedPage ip = (PdfImportedPage)it.next(); writer.addToBody(ip.getFormXObject(writer.getCompressionLevel()), ip.getIndirectReference()); } writeAllVisited(); } finally { try { reader.close(); file.close(); } catch (Exception e) { //Empty on purpose } } } } src/core/com/lowagie/text/pdf/PdfRectangle.java100644 0 0 20426 11154165266 17122 0ustar 0 0 /* * $Id: PdfRectangle.java 3694 2009-02-17 19:29:05Z mstorer $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.Rectangle; /** * PdfRectangle is the PDF Rectangle object. *

* Rectangles are used to describe locations on the page and bounding boxes for several * objects in PDF, such as fonts. A rectangle is represented as an array of * four numbers, specifying the lower left x, lower left y, upper right x, * and upper right y coordinates of the rectangle, in that order.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 7.1 (page 183). * * @see com.lowagie.text.Rectangle * @see PdfArray */ public class PdfRectangle extends PdfArray { // membervariables /** lower left x */ private float llx = 0; /** lower left y */ private float lly = 0; /** upper right x */ private float urx = 0; /** upper right y */ private float ury = 0; // constructors /** * Constructs a PdfRectangle-object. * * @param llx lower left x * @param lly lower left y * @param urx upper right x * @param ury upper right y * * @since rugPdf0.10 */ public PdfRectangle(float llx, float lly, float urx, float ury, int rotation) { super(); if (rotation == 90 || rotation == 270) { this.llx = lly; this.lly = llx; this.urx = ury; this.ury = urx; } else { this.llx = llx; this.lly = lly; this.urx = urx; this.ury = ury; } super.add(new PdfNumber(this.llx)); super.add(new PdfNumber(this.lly)); super.add(new PdfNumber(this.urx)); super.add(new PdfNumber(this.ury)); } public PdfRectangle(float llx, float lly, float urx, float ury) { this(llx, lly, urx, ury, 0); } /** * Constructs a PdfRectangle-object starting from the origin (0, 0). * * @param urx upper right x * @param ury upper right y */ public PdfRectangle(float urx, float ury, int rotation) { this(0, 0, urx, ury, rotation); } public PdfRectangle(float urx, float ury) { this(0, 0, urx, ury, 0); } /** * Constructs a PdfRectangle-object with a Rectangle-object. * * @param rectangle a Rectangle */ public PdfRectangle(Rectangle rectangle, int rotation) { this(rectangle.getLeft(), rectangle.getBottom(), rectangle.getRight(), rectangle.getTop(), rotation); } public PdfRectangle(Rectangle rectangle) { this(rectangle.getLeft(), rectangle.getBottom(), rectangle.getRight(), rectangle.getTop(), 0); } // methods /** * Returns the high level version of this PdfRectangle * @return this PdfRectangle translated to class Rectangle */ public Rectangle getRectangle() { return new Rectangle(left(), bottom(), right(), top()); } /** * Overrides the add-method in PdfArray in order to prevent the adding of extra object to the array. * * @param object PdfObject to add (will not be added here) * @return false */ public boolean add(PdfObject object) { return false; } /** * Block changes to the underlying PdfArray * @param values stuff we'll ignore. Ha! * @return false. You can't add anything to a PdfRectangle * @since 2.1.5 */ public boolean add( float values[] ) { return false; } /** * Block changes to the underlying PdfArray * @param values stuff we'll ignore. Ha! * @return false. You can't add anything to a PdfRectangle * @since 2.1.5 */ public boolean add( int values[] ) { return false; } /** * Block changes to the underlying PdfArray * @param object Ignored. * @since 2.1.5 */ public void addFirst( PdfObject object ) { } /** * Returns the lower left x-coordinate. * * @return the lower left x-coordinate */ public float left() { return llx; } /** * Returns the upper right x-coordinate. * * @return the upper right x-coordinate */ public float right() { return urx; } /** * Returns the upper right y-coordinate. * * @return the upper right y-coordinate */ public float top() { return ury; } /** * Returns the lower left y-coordinate. * * @return the lower left y-coordinate */ public float bottom() { return lly; } /** * Returns the lower left x-coordinate, considering a given margin. * * @param margin a margin * @return the lower left x-coordinate */ public float left(int margin) { return llx + margin; } /** * Returns the upper right x-coordinate, considering a given margin. * * @param margin a margin * @return the upper right x-coordinate */ public float right(int margin) { return urx - margin; } /** * Returns the upper right y-coordinate, considering a given margin. * * @param margin a margin * @return the upper right y-coordinate */ public float top(int margin) { return ury - margin; } /** * Returns the lower left y-coordinate, considering a given margin. * * @param margin a margin * @return the lower left y-coordinate */ public float bottom(int margin) { return lly + margin; } /** * Returns the width of the rectangle. * * @return a width */ public float width() { return urx - llx; } /** * Returns the height of the rectangle. * * @return a height */ public float height() { return ury - lly; } /** * Swaps the values of urx and ury and of lly and llx in order to rotate the rectangle. * * @return a PdfRectangle */ public PdfRectangle rotate() { return new PdfRectangle(lly, llx, ury, urx, 0); } }src/core/com/lowagie/text/pdf/PdfRendition.java100644 0 0 5470 11000354131 17110 0ustar 0 0 /* * Copyright 2003 Galo Gimenez * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; /** * A Rendition dictionary (pdf spec 1.5) */ public class PdfRendition extends PdfDictionary { PdfRendition(String file, PdfFileSpecification fs, String mimeType) throws IOException{ put(PdfName.S, new PdfName("MR")); put(PdfName.N, new PdfString("Rendition for "+file)); put(PdfName.C, new PdfMediaClipData(file, fs, mimeType)); } } src/core/com/lowagie/text/pdf/PdfResources.java100644 0 0 7230 11154165267 17147 0ustar 0 0 /* * $Id: PdfResources.java 3712 2009-02-20 20:11:31Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * PdfResources is the PDF Resources-object. *

* The marking operations for drawing a page are stored in a stream that is the value of the * Contents key in the Page object's dictionary. Each marking context includes a list * of the named resources it uses. This resource list is stored as a dictionary that is the * value of the context's Resources key, and it serves two functions: it enumerates * the named resources in the contents stream, and it established the mapping from the names * to the objects used by the marking operations.
* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 7.5 (page 195-197). * * @see PdfPage */ class PdfResources extends PdfDictionary { // constructor /** * Constructs a PDF ResourcesDictionary. */ PdfResources() { super(); } // methods void add(PdfName key, PdfDictionary resource) { if (resource.size() == 0) return; PdfDictionary dic = getAsDict(key); if (dic == null) put(key, resource); else dic.putAll(resource); } }src/core/com/lowagie/text/pdf/PdfShading.java100644 0 0 24656 11000354131 16561 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; /** Implements the shading dictionary (or stream). * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfShading { protected PdfDictionary shading; protected PdfWriter writer; protected int shadingType; protected ColorDetails colorDetails; protected PdfName shadingName; protected PdfIndirectReference shadingReference; private Color cspace; /** Holds value of property bBox. */ protected float[] bBox; /** Holds value of property antiAlias. */ protected boolean antiAlias = false; /** Creates new PdfShading */ protected PdfShading(PdfWriter writer) { this.writer = writer; } protected void setColorSpace(Color color) { cspace = color; int type = ExtendedColor.getType(color); PdfObject colorSpace = null; switch (type) { case ExtendedColor.TYPE_GRAY: { colorSpace = PdfName.DEVICEGRAY; break; } case ExtendedColor.TYPE_CMYK: { colorSpace = PdfName.DEVICECMYK; break; } case ExtendedColor.TYPE_SEPARATION: { SpotColor spot = (SpotColor)color; colorDetails = writer.addSimple(spot.getPdfSpotColor()); colorSpace = colorDetails.getIndirectReference(); break; } case ExtendedColor.TYPE_PATTERN: case ExtendedColor.TYPE_SHADING: { throwColorSpaceError(); } default: colorSpace = PdfName.DEVICERGB; break; } shading.put(PdfName.COLORSPACE, colorSpace); } public Color getColorSpace() { return cspace; } public static void throwColorSpaceError() { throw new IllegalArgumentException("A tiling or shading pattern cannot be used as a color space in a shading pattern"); } public static void checkCompatibleColors(Color c1, Color c2) { int type1 = ExtendedColor.getType(c1); int type2 = ExtendedColor.getType(c2); if (type1 != type2) throw new IllegalArgumentException("Both colors must be of the same type."); if (type1 == ExtendedColor.TYPE_SEPARATION && ((SpotColor)c1).getPdfSpotColor() != ((SpotColor)c2).getPdfSpotColor()) throw new IllegalArgumentException("The spot color must be the same, only the tint can vary."); if (type1 == ExtendedColor.TYPE_PATTERN || type1 == ExtendedColor.TYPE_SHADING) throwColorSpaceError(); } public static float[] getColorArray(Color color) { int type = ExtendedColor.getType(color); switch (type) { case ExtendedColor.TYPE_GRAY: { return new float[]{((GrayColor)color).getGray()}; } case ExtendedColor.TYPE_CMYK: { CMYKColor cmyk = (CMYKColor)color; return new float[]{cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()}; } case ExtendedColor.TYPE_SEPARATION: { return new float[]{((SpotColor)color).getTint()}; } case ExtendedColor.TYPE_RGB: { return new float[]{color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f}; } } throwColorSpaceError(); return null; } public static PdfShading type1(PdfWriter writer, Color colorSpace, float domain[], float tMatrix[], PdfFunction function) { PdfShading sp = new PdfShading(writer); sp.shading = new PdfDictionary(); sp.shadingType = 1; sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); sp.setColorSpace(colorSpace); if (domain != null) sp.shading.put(PdfName.DOMAIN, new PdfArray(domain)); if (tMatrix != null) sp.shading.put(PdfName.MATRIX, new PdfArray(tMatrix)); sp.shading.put(PdfName.FUNCTION, function.getReference()); return sp; } public static PdfShading type2(PdfWriter writer, Color colorSpace, float coords[], float domain[], PdfFunction function, boolean extend[]) { PdfShading sp = new PdfShading(writer); sp.shading = new PdfDictionary(); sp.shadingType = 2; sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); sp.setColorSpace(colorSpace); sp.shading.put(PdfName.COORDS, new PdfArray(coords)); if (domain != null) sp.shading.put(PdfName.DOMAIN, new PdfArray(domain)); sp.shading.put(PdfName.FUNCTION, function.getReference()); if (extend != null && (extend[0] || extend[1])) { PdfArray array = new PdfArray(extend[0] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); array.add(extend[1] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); sp.shading.put(PdfName.EXTEND, array); } return sp; } public static PdfShading type3(PdfWriter writer, Color colorSpace, float coords[], float domain[], PdfFunction function, boolean extend[]) { PdfShading sp = type2(writer, colorSpace, coords, domain, function, extend); sp.shadingType = 3; sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); return sp; } public static PdfShading simpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor, boolean extendStart, boolean extendEnd) { checkCompatibleColors(startColor, endColor); PdfFunction function = PdfFunction.type2(writer, new float[]{0, 1}, null, getColorArray(startColor), getColorArray(endColor), 1); return type2(writer, startColor, new float[]{x0, y0, x1, y1}, null, function, new boolean[]{extendStart, extendEnd}); } public static PdfShading simpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor) { return simpleAxial(writer, x0, y0, x1, y1, startColor, endColor, true, true); } public static PdfShading simpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor, boolean extendStart, boolean extendEnd) { checkCompatibleColors(startColor, endColor); PdfFunction function = PdfFunction.type2(writer, new float[]{0, 1}, null, getColorArray(startColor), getColorArray(endColor), 1); return type3(writer, startColor, new float[]{x0, y0, r0, x1, y1, r1}, null, function, new boolean[]{extendStart, extendEnd}); } public static PdfShading simpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor) { return simpleRadial(writer, x0, y0, r0, x1, y1, r1, startColor, endColor, true, true); } PdfName getShadingName() { return shadingName; } PdfIndirectReference getShadingReference() { if (shadingReference == null) shadingReference = writer.getPdfIndirectReference(); return shadingReference; } void setName(int number) { shadingName = new PdfName("Sh" + number); } void addToBody() throws IOException { if (bBox != null) shading.put(PdfName.BBOX, new PdfArray(bBox)); if (antiAlias) shading.put(PdfName.ANTIALIAS, PdfBoolean.PDFTRUE); writer.addToBody(shading, getShadingReference()); } PdfWriter getWriter() { return writer; } ColorDetails getColorDetails() { return colorDetails; } public float[] getBBox() { return bBox; } public void setBBox(float[] bBox) { if (bBox.length != 4) throw new IllegalArgumentException("BBox must be a 4 element array."); this.bBox = bBox; } public boolean isAntiAlias() { return antiAlias; } public void setAntiAlias(boolean antiAlias) { this.antiAlias = antiAlias; } } src/core/com/lowagie/text/pdf/PdfShadingPattern.java100644 0 0 10256 11000354131 20106 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; /** Implements the shading pattern dictionary. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfShadingPattern extends PdfDictionary { protected PdfShading shading; protected PdfWriter writer; protected float matrix[] = {1, 0, 0, 1, 0, 0}; protected PdfName patternName; protected PdfIndirectReference patternReference; /** Creates new PdfShadingPattern */ public PdfShadingPattern(PdfShading shading) { writer = shading.getWriter(); put(PdfName.PATTERNTYPE, new PdfNumber(2)); this.shading = shading; } PdfName getPatternName() { return patternName; } PdfName getShadingName() { return shading.getShadingName(); } PdfIndirectReference getPatternReference() { if (patternReference == null) patternReference = writer.getPdfIndirectReference(); return patternReference; } PdfIndirectReference getShadingReference() { return shading.getShadingReference(); } void setName(int number) { patternName = new PdfName("P" + number); } void addToBody() throws IOException { put(PdfName.SHADING, getShadingReference()); put(PdfName.MATRIX, new PdfArray(matrix)); writer.addToBody(this, getPatternReference()); } public void setMatrix(float matrix[]) { if (matrix.length != 6) throw new RuntimeException("The matrix size must be 6."); this.matrix = matrix; } public float[] getMatrix() { return matrix; } public PdfShading getShading() { return shading; } ColorDetails getColorDetails() { return shading.getColorDetails(); } } src/core/com/lowagie/text/pdf/PdfSigGenericPKCS.java100644 0 0 20760 11000354131 17674 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.security.PrivateKey; import java.security.cert.CRL; import java.security.cert.Certificate; import com.lowagie.text.ExceptionConverter; /** * A signature dictionary representation for the standard filters. */ public abstract class PdfSigGenericPKCS extends PdfSignature { /** * The hash algorithm, for example "SHA1" */ protected String hashAlgorithm; /** * The crypto provider */ protected String provider = null; /** * The class instance that calculates the PKCS#1 and PKCS#7 */ protected PdfPKCS7 pkcs; /** * The subject name in the signing certificate (the element "CN") */ protected String name; private byte externalDigest[]; private byte externalRSAdata[]; private String digestEncryptionAlgorithm; /** * Creates a generic standard filter. * @param filter the filter name * @param subFilter the sub-filter name */ public PdfSigGenericPKCS(PdfName filter, PdfName subFilter) { super(filter, subFilter); } /** * Sets the crypto information to sign. * @param privKey the private key * @param certChain the certificate chain * @param crlList the certificate revocation list. It can be null */ public void setSignInfo(PrivateKey privKey, Certificate[] certChain, CRL[] crlList) { try { pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) { ByteArrayOutputStream bout = new ByteArrayOutputStream(); for (int k = 0; k < certChain.length; ++k) { bout.write(certChain[k].getEncoded()); } bout.close(); setCert(bout.toByteArray()); setContents(pkcs.getEncodedPKCS1()); } else setContents(pkcs.getEncodedPKCS7()); name = PdfPKCS7.getSubjectFields(pkcs.getSigningCertificate()).getField("CN"); if (name != null) put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Sets the digest/signature to an external calculated value. * @param digest the digest. This is the actual signature * @param RSAdata the extra data that goes into the data tag in PKCS#7 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest * is also null. If the digest is not null * then it may be "RSA" or "DSA" */ public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { externalDigest = digest; externalRSAdata = RSAdata; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; } /** * Gets the subject name in the signing certificate (the element "CN") * @return the subject name in the signing certificate (the element "CN") */ public String getName() { return name; } /** * Gets the class instance that does the actual signing. * @return the class instance that does the actual signing */ public PdfPKCS7 getSigner() { return pkcs; } /** * Gets the signature content. This can be a PKCS#1 or a PKCS#7. It corresponds to * the /Contents key. * @return the signature content */ public byte[] getSignerContents() { if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) return pkcs.getEncodedPKCS1(); else return pkcs.getEncodedPKCS7(); } /** * Creates a standard filter of the type VeriSign. */ public static class VeriSign extends PdfSigGenericPKCS { /** * The constructor for the default provider. */ public VeriSign() { super(PdfName.VERISIGN_PPKVS, PdfName.ADBE_PKCS7_DETACHED); hashAlgorithm = "MD5"; put(PdfName.R, new PdfNumber(65537)); } /** * The constructor for an explicit provider. * @param provider the crypto provider */ public VeriSign(String provider) { this(); this.provider = provider; } } /** * Creates a standard filter of the type self signed. */ public static class PPKLite extends PdfSigGenericPKCS { /** * The constructor for the default provider. */ public PPKLite() { super(PdfName.ADOBE_PPKLITE, PdfName.ADBE_X509_RSA_SHA1); hashAlgorithm = "SHA1"; put(PdfName.R, new PdfNumber(65541)); } /** * The constructor for an explicit provider. * @param provider the crypto provider */ public PPKLite(String provider) { this(); this.provider = provider; } } /** * Creates a standard filter of the type Windows Certificate. */ public static class PPKMS extends PdfSigGenericPKCS { /** * The constructor for the default provider. */ public PPKMS() { super(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); hashAlgorithm = "SHA1"; } /** * The constructor for an explicit provider. * @param provider the crypto provider */ public PPKMS(String provider) { this(); this.provider = provider; } } } src/core/com/lowagie/text/pdf/PdfSignature.java100644 0 0 7436 11000354131 17122 0ustar 0 0 /* * Copyright 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** Implements the signature dictionary. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfSignature extends PdfDictionary { /** Creates new PdfSignature */ public PdfSignature(PdfName filter, PdfName subFilter) { super(PdfName.SIG); put(PdfName.FILTER, filter); put(PdfName.SUBFILTER, subFilter); } public void setByteRange(int range[]) { PdfArray array = new PdfArray(); for (int k = 0; k < range.length; ++k) array.add(new PdfNumber(range[k])); put(PdfName.BYTERANGE, array); } public void setContents(byte contents[]) { put(PdfName.CONTENTS, new PdfString(contents).setHexWriting(true)); } public void setCert(byte cert[]) { put(PdfName.CERT, new PdfString(cert)); } public void setName(String name) { put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); } public void setDate(PdfDate date) { put(PdfName.M, date); } public void setLocation(String name) { put(PdfName.LOCATION, new PdfString(name, PdfObject.TEXT_UNICODE)); } public void setReason(String name) { put(PdfName.REASON, new PdfString(name, PdfObject.TEXT_UNICODE)); } public void setContact(String name) { put(PdfName.CONTACTINFO, new PdfString(name, PdfObject.TEXT_UNICODE)); } }src/core/com/lowagie/text/pdf/PdfSignatureAppearance.java100644 0 0 153447 11213370070 21154 0ustar 0 0 /* * $Id: PdfSignatureAppearance.java 3905 2009-04-24 10:40:24Z blowagie $ * * Copyright 2004-2006 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.EOFException; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.security.PrivateKey; import java.security.cert.CRL; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Font; import com.lowagie.text.Image; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; /** * This class takes care of the cryptographic options and appearances that form a signature. */ public class PdfSignatureAppearance { /** * The rendering mode is just the description */ public static final int SignatureRenderDescription = 0; /** * The rendering mode is the name of the signer and the description */ public static final int SignatureRenderNameAndDescription = 1; /** * The rendering mode is an image and the description */ public static final int SignatureRenderGraphicAndDescription = 2; /** * The self signed filter. */ public static final PdfName SELF_SIGNED = PdfName.ADOBE_PPKLITE; /** * The VeriSign filter. */ public static final PdfName VERISIGN_SIGNED = PdfName.VERISIGN_PPKVS; /** * The Windows Certificate Security. */ public static final PdfName WINCER_SIGNED = PdfName.ADOBE_PPKMS; public static final int NOT_CERTIFIED = 0; public static final int CERTIFIED_NO_CHANGES_ALLOWED = 1; public static final int CERTIFIED_FORM_FILLING = 2; public static final int CERTIFIED_FORM_FILLING_AND_ANNOTATIONS = 3; private static final float TOP_SECTION = 0.3f; private static final float MARGIN = 2; private Rectangle rect; private Rectangle pageRect; private PdfTemplate app[] = new PdfTemplate[5]; private PdfTemplate frm; private PdfStamperImp writer; private String layer2Text; private String reason; private String location; private Calendar signDate; private String provider; private int page = 1; private String fieldName; private PrivateKey privKey; private Certificate[] certChain; private CRL[] crlList; private PdfName filter; private boolean newField; private ByteBuffer sigout; private OutputStream originalout; private File tempFile; private PdfDictionary cryptoDictionary; private PdfStamper stamper; private boolean preClosed = false; private PdfSigGenericPKCS sigStandard; private int range[]; private RandomAccessFile raf; private byte bout[]; private int boutLen; private byte externalDigest[]; private byte externalRSAdata[]; private String digestEncryptionAlgorithm; private HashMap exclusionLocations; PdfSignatureAppearance(PdfStamperImp writer) { this.writer = writer; signDate = new GregorianCalendar(); fieldName = getNewSigName(); } private int render = SignatureRenderDescription; /** * Gets the rendering mode for this signature. * @return the rendering mode for this signature */ public int getRender() { return render; } /** * Sets the rendering mode for this signature. * The rendering modes can be the constants SignatureRenderDescription, * SignatureRenderNameAndDescription or SignatureRenderGraphicAndDescription. * The two last modes should be used with Acrobat 6 layer type. * @param render the render mode */ public void setRender(int render) { this.render = render; } private Image signatureGraphic = null; /** * Gets the Image object to render. * @return the image */ public Image getSignatureGraphic() { return signatureGraphic; } /** * Sets the Image object to render when Render is set to SignatureRenderGraphicAndDescription * @param signatureGraphic image rendered. If null the mode is defaulted * to SignatureRenderDescription */ public void setSignatureGraphic(Image signatureGraphic) { this.signatureGraphic = signatureGraphic; } /** * Sets the signature text identifying the signer. * @param text the signature text identifying the signer. If null or not set * a standard description will be used */ public void setLayer2Text(String text) { layer2Text = text; } /** * Gets the signature text identifying the signer if set by setLayer2Text(). * @return the signature text identifying the signer */ public String getLayer2Text() { return layer2Text; } /** * Sets the text identifying the signature status. * @param text the text identifying the signature status. If null or not set * the description "Signature Not Verified" will be used */ public void setLayer4Text(String text) { layer4Text = text; } /** * Gets the text identifying the signature status if set by setLayer4Text(). * @return the text identifying the signature status */ public String getLayer4Text() { return layer4Text; } /** * Gets the rectangle representing the signature dimensions. * @return the rectangle representing the signature dimensions. It may be null * or have zero width or height for invisible signatures */ public Rectangle getRect() { return rect; } /** * Gets the visibility status of the signature. * @return the visibility status of the signature */ public boolean isInvisible() { return (rect == null || rect.getWidth() == 0 || rect.getHeight() == 0); } /** * Sets the cryptographic parameters. * @param privKey the private key * @param certChain the certificate chain * @param crlList the certificate revocation list. It may be null * @param filter the crytographic filter type. It can be SELF_SIGNED, VERISIGN_SIGNED or WINCER_SIGNED */ public void setCrypto(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, PdfName filter) { this.privKey = privKey; this.certChain = certChain; this.crlList = crlList; this.filter = filter; } /** * Sets the signature to be visible. It creates a new visible signature field. * @param pageRect the position and dimension of the field in the page * @param page the page to place the field. The fist page is 1 * @param fieldName the field name or null to generate automatically a new field name */ public void setVisibleSignature(Rectangle pageRect, int page, String fieldName) { if (fieldName != null) { if (fieldName.indexOf('.') >= 0) throw new IllegalArgumentException("Field names cannot contain a dot."); AcroFields af = writer.getAcroFields(); AcroFields.Item item = af.getFieldItem(fieldName); if (item != null) throw new IllegalArgumentException("The field " + fieldName + " already exists."); this.fieldName = fieldName; } if (page < 1 || page > writer.reader.getNumberOfPages()) throw new IllegalArgumentException("Invalid page number: " + page); this.pageRect = new Rectangle(pageRect); this.pageRect.normalize(); rect = new Rectangle(this.pageRect.getWidth(), this.pageRect.getHeight()); this.page = page; newField = true; } /** * Sets the signature to be visible. An empty signature field with the same name must already exist. * @param fieldName the existing empty signature field name */ public void setVisibleSignature(String fieldName) { AcroFields af = writer.getAcroFields(); AcroFields.Item item = af.getFieldItem(fieldName); if (item == null) throw new IllegalArgumentException("The field " + fieldName + " does not exist."); PdfDictionary merged = item.getMerged(0); if (!PdfName.SIG.equals(PdfReader.getPdfObject(merged.get(PdfName.FT)))) throw new IllegalArgumentException("The field " + fieldName + " is not a signature field."); this.fieldName = fieldName; PdfArray r = merged.getAsArray(PdfName.RECT); float llx = r.getAsNumber(0).floatValue(); float lly = r.getAsNumber(1).floatValue(); float urx = r.getAsNumber(2).floatValue(); float ury = r.getAsNumber(3).floatValue(); pageRect = new Rectangle(llx, lly, urx, ury); pageRect.normalize(); page = item.getPage(0).intValue(); int rotation = writer.reader.getPageRotation(page); Rectangle pageSize = writer.reader.getPageSizeWithRotation(page); switch (rotation) { case 90: pageRect = new Rectangle( pageRect.getBottom(), pageSize.getTop() - pageRect.getLeft(), pageRect.getTop(), pageSize.getTop() - pageRect.getRight()); break; case 180: pageRect = new Rectangle( pageSize.getRight() - pageRect.getLeft(), pageSize.getTop() - pageRect.getBottom(), pageSize.getRight() - pageRect.getRight(), pageSize.getTop() - pageRect.getTop()); break; case 270: pageRect = new Rectangle( pageSize.getRight() - pageRect.getBottom(), pageRect.getLeft(), pageSize.getRight() - pageRect.getTop(), pageRect.getRight()); break; } if (rotation != 0) pageRect.normalize(); rect = new Rectangle(this.pageRect.getWidth(), this.pageRect.getHeight()); } /** * Gets a template layer to create a signature appearance. The layers can go from 0 to 4. *

* Consult PPKAppearances.pdf * for further details. * @param layer the layer * @return a template */ public PdfTemplate getLayer(int layer) { if (layer < 0 || layer >= app.length) return null; PdfTemplate t = app[layer]; if (t == null) { t = app[layer] = new PdfTemplate(writer); t.setBoundingBox(rect); writer.addDirectTemplateSimple(t, new PdfName("n" + layer)); } return t; } /** * Gets the template that aggregates all appearance layers. This corresponds to the /FRM resource. *

* Consult PPKAppearances.pdf * for further details. * @return the template that aggregates all appearance layers */ public PdfTemplate getTopLayer() { if (frm == null) { frm = new PdfTemplate(writer); frm.setBoundingBox(rect); writer.addDirectTemplateSimple(frm, new PdfName("FRM")); } return frm; } /** * Gets the main appearance layer. *

* Consult PPKAppearances.pdf * for further details. * @return the main appearance layer * @throws DocumentException on error */ public PdfTemplate getAppearance() throws DocumentException { if (isInvisible()) { PdfTemplate t = new PdfTemplate(writer); t.setBoundingBox(new Rectangle(0, 0)); writer.addDirectTemplateSimple(t, null); return t; } if (app[0] == null) { PdfTemplate t = app[0] = new PdfTemplate(writer); t.setBoundingBox(new Rectangle(100, 100)); writer.addDirectTemplateSimple(t, new PdfName("n0")); t.setLiteral("% DSBlank\n"); } if (app[1] == null && !acro6Layers) { PdfTemplate t = app[1] = new PdfTemplate(writer); t.setBoundingBox(new Rectangle(100, 100)); writer.addDirectTemplateSimple(t, new PdfName("n1")); t.setLiteral(questionMark); } if (app[2] == null) { String text; if (layer2Text == null) { StringBuffer buf = new StringBuffer(); buf.append("Digitally signed by ").append(PdfPKCS7.getSubjectFields((X509Certificate)certChain[0]).getField("CN")).append('\n'); SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z"); buf.append("Date: ").append(sd.format(signDate.getTime())); if (reason != null) buf.append('\n').append("Reason: ").append(reason); if (location != null) buf.append('\n').append("Location: ").append(location); text = buf.toString(); } else text = layer2Text; PdfTemplate t = app[2] = new PdfTemplate(writer); t.setBoundingBox(rect); writer.addDirectTemplateSimple(t, new PdfName("n2")); if (image != null) { if (imageScale == 0) { t.addImage(image, rect.getWidth(), 0, 0, rect.getHeight(), 0, 0); } else { float usableScale = imageScale; if (imageScale < 0) usableScale = Math.min(rect.getWidth() / image.getWidth(), rect.getHeight() / image.getHeight()); float w = image.getWidth() * usableScale; float h = image.getHeight() * usableScale; float x = (rect.getWidth() - w) / 2; float y = (rect.getHeight() - h) / 2; t.addImage(image, w, 0, 0, h, x, y); } } Font font; if (layer2Font == null) font = new Font(); else font = new Font(layer2Font); float size = font.getSize(); Rectangle dataRect = null; Rectangle signatureRect = null; if (render == SignatureRenderNameAndDescription || (render == SignatureRenderGraphicAndDescription && this.signatureGraphic != null)) { // origin is the bottom-left signatureRect = new Rectangle( MARGIN, MARGIN, rect.getWidth() / 2 - MARGIN, rect.getHeight() - MARGIN); dataRect = new Rectangle( rect.getWidth() / 2 + MARGIN / 2, MARGIN, rect.getWidth() - MARGIN / 2, rect.getHeight() - MARGIN); if (rect.getHeight() > rect.getWidth()) { signatureRect = new Rectangle( MARGIN, rect.getHeight() / 2, rect.getWidth() - MARGIN, rect.getHeight()); dataRect = new Rectangle( MARGIN, MARGIN, rect.getWidth() - MARGIN, rect.getHeight() / 2 - MARGIN); } } else { dataRect = new Rectangle( MARGIN, MARGIN, rect.getWidth() - MARGIN, rect.getHeight() * (1 - TOP_SECTION) - MARGIN); } if (render == SignatureRenderNameAndDescription) { String signedBy = PdfPKCS7.getSubjectFields((X509Certificate)certChain[0]).getField("CN"); Rectangle sr2 = new Rectangle(signatureRect.getWidth() - MARGIN, signatureRect.getHeight() - MARGIN ); float signedSize = fitText(font, signedBy, sr2, -1, runDirection); ColumnText ct2 = new ColumnText(t); ct2.setRunDirection(runDirection); ct2.setSimpleColumn(new Phrase(signedBy, font), signatureRect.getLeft(), signatureRect.getBottom(), signatureRect.getRight(), signatureRect.getTop(), signedSize, Element.ALIGN_LEFT); ct2.go(); } else if (render == SignatureRenderGraphicAndDescription) { ColumnText ct2 = new ColumnText(t); ct2.setRunDirection(runDirection); ct2.setSimpleColumn(signatureRect.getLeft(), signatureRect.getBottom(), signatureRect.getRight(), signatureRect.getTop(), 0, Element.ALIGN_RIGHT); Image im = Image.getInstance(signatureGraphic); im.scaleToFit(signatureRect.getWidth(), signatureRect.getHeight()); Paragraph p = new Paragraph(); // must calculate the point to draw from to make image appear in middle of column float x = 0; // experimentation found this magic number to counteract Adobe's signature graphic, which // offsets the y co-ordinate by 15 units float y = -im.getScaledHeight() + 15; x = x + (signatureRect.getWidth() - im.getScaledWidth()) / 2; y = y - (signatureRect.getHeight() - im.getScaledHeight()) / 2; p.add(new Chunk(im, x + (signatureRect.getWidth() - im.getScaledWidth()) / 2, y, false)); ct2.addElement(p); ct2.go(); } if (size <= 0) { Rectangle sr = new Rectangle(dataRect.getWidth(), dataRect.getHeight()); size = fitText(font, text, sr, 12, runDirection); } ColumnText ct = new ColumnText(t); ct.setRunDirection(runDirection); ct.setSimpleColumn(new Phrase(text, font), dataRect.getLeft(), dataRect.getBottom(), dataRect.getRight(), dataRect.getTop(), size, Element.ALIGN_LEFT); ct.go(); } if (app[3] == null && !acro6Layers) { PdfTemplate t = app[3] = new PdfTemplate(writer); t.setBoundingBox(new Rectangle(100, 100)); writer.addDirectTemplateSimple(t, new PdfName("n3")); t.setLiteral("% DSBlank\n"); } if (app[4] == null && !acro6Layers) { PdfTemplate t = app[4] = new PdfTemplate(writer); t.setBoundingBox(new Rectangle(0, rect.getHeight() * (1 - TOP_SECTION), rect.getRight(), rect.getTop())); writer.addDirectTemplateSimple(t, new PdfName("n4")); Font font; if (layer2Font == null) font = new Font(); else font = new Font(layer2Font); float size = font.getSize(); String text = "Signature Not Verified"; if (layer4Text != null) text = layer4Text; Rectangle sr = new Rectangle(rect.getWidth() - 2 * MARGIN, rect.getHeight() * TOP_SECTION - 2 * MARGIN); size = fitText(font, text, sr, 15, runDirection); ColumnText ct = new ColumnText(t); ct.setRunDirection(runDirection); ct.setSimpleColumn(new Phrase(text, font), MARGIN, 0, rect.getWidth() - MARGIN, rect.getHeight() - MARGIN, size, Element.ALIGN_LEFT); ct.go(); } int rotation = writer.reader.getPageRotation(page); Rectangle rotated = new Rectangle(rect); int n = rotation; while (n > 0) { rotated = rotated.rotate(); n -= 90; } if (frm == null) { frm = new PdfTemplate(writer); frm.setBoundingBox(rotated); writer.addDirectTemplateSimple(frm, new PdfName("FRM")); float scale = Math.min(rect.getWidth(), rect.getHeight()) * 0.9f; float x = (rect.getWidth() - scale) / 2; float y = (rect.getHeight() - scale) / 2; scale /= 100; if (rotation == 90) frm.concatCTM(0, 1, -1, 0, rect.getHeight(), 0); else if (rotation == 180) frm.concatCTM(-1, 0, 0, -1, rect.getWidth(), rect.getHeight()); else if (rotation == 270) frm.concatCTM(0, -1, 1, 0, 0, rect.getWidth()); frm.addTemplate(app[0], 0, 0); if (!acro6Layers) frm.addTemplate(app[1], scale, 0, 0, scale, x, y); frm.addTemplate(app[2], 0, 0); if (!acro6Layers) { frm.addTemplate(app[3], scale, 0, 0, scale, x, y); frm.addTemplate(app[4], 0, 0); } } PdfTemplate napp = new PdfTemplate(writer); napp.setBoundingBox(rotated); writer.addDirectTemplateSimple(napp, null); napp.addTemplate(frm, 0, 0); return napp; } /** * Fits the text to some rectangle adjusting the font size as needed. * @param font the font to use * @param text the text * @param rect the rectangle where the text must fit * @param maxFontSize the maximum font size * @param runDirection the run direction * @return the calculated font size that makes the text fit */ public static float fitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection) { try { ColumnText ct = null; int status = 0; if (maxFontSize <= 0) { int cr = 0; int lf = 0; char t[] = text.toCharArray(); for (int k = 0; k < t.length; ++k) { if (t[k] == '\n') ++lf; else if (t[k] == '\r') ++cr; } int minLines = Math.max(cr, lf) + 1; maxFontSize = Math.abs(rect.getHeight()) / minLines - 0.001f; } font.setSize(maxFontSize); Phrase ph = new Phrase(text, font); ct = new ColumnText(null); ct.setSimpleColumn(ph, rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop(), maxFontSize, Element.ALIGN_LEFT); ct.setRunDirection(runDirection); status = ct.go(true); if ((status & ColumnText.NO_MORE_TEXT) != 0) return maxFontSize; float precision = 0.1f; float min = 0; float max = maxFontSize; float size = maxFontSize; for (int k = 0; k < 50; ++k) { //just in case it doesn't converge size = (min + max) / 2; ct = new ColumnText(null); font.setSize(size); ct.setSimpleColumn(new Phrase(text, font), rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop(), size, Element.ALIGN_LEFT); ct.setRunDirection(runDirection); status = ct.go(true); if ((status & ColumnText.NO_MORE_TEXT) != 0) { if (max - min < size * precision) return size; min = size; } else max = size; } return size; } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Sets the digest/signature to an external calculated value. * @param digest the digest. This is the actual signature * @param RSAdata the extra data that goes into the data tag in PKCS#7 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest * is also null. If the digest is not null * then it may be "RSA" or "DSA" */ public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { externalDigest = digest; externalRSAdata = RSAdata; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; } /** * Gets the signing reason. * @return the signing reason */ public String getReason() { return this.reason; } /** * Sets the signing reason. * @param reason the signing reason */ public void setReason(String reason) { this.reason = reason; } /** * Gets the signing location. * @return the signing location */ public String getLocation() { return this.location; } /** * Sets the signing location. * @param location the signing location */ public void setLocation(String location) { this.location = location; } /** * Returns the Cryptographic Service Provider that will sign the document. * @return provider the name of the provider, for example "SUN", * or null to use the default provider. */ public String getProvider() { return this.provider; } /** * Sets the Cryptographic Service Provider that will sign the document. * * @param provider the name of the provider, for example "SUN", or * null to use the default provider. */ public void setProvider(String provider) { this.provider = provider; } /** * Gets the private key. * @return the private key */ public java.security.PrivateKey getPrivKey() { return privKey; } /** * Gets the certificate chain. * @return the certificate chain */ public java.security.cert.Certificate[] getCertChain() { return this.certChain; } /** * Gets the certificate revocation list. * @return the certificate revocation list */ public java.security.cert.CRL[] getCrlList() { return this.crlList; } /** * Gets the filter used to sign the document. * @return the filter used to sign the document */ public com.lowagie.text.pdf.PdfName getFilter() { return filter; } /** * Checks if a new field was created. * @return true if a new field was created, false if signing * an existing field or if the signature is invisible */ public boolean isNewField() { return this.newField; } /** * Gets the page number of the field. * @return the page number of the field */ public int getPage() { return page; } /** * Gets the field name. * @return the field name */ public java.lang.String getFieldName() { return fieldName; } /** * Gets the rectangle that represent the position and dimension of the signature in the page. * @return the rectangle that represent the position and dimension of the signature in the page */ public com.lowagie.text.Rectangle getPageRect() { return pageRect; } /** * Gets the signature date. * @return the signature date */ public java.util.Calendar getSignDate() { return signDate; } /** * Sets the signature date. * @param signDate the signature date */ public void setSignDate(java.util.Calendar signDate) { this.signDate = signDate; } com.lowagie.text.pdf.ByteBuffer getSigout() { return sigout; } void setSigout(com.lowagie.text.pdf.ByteBuffer sigout) { this.sigout = sigout; } java.io.OutputStream getOriginalout() { return originalout; } void setOriginalout(java.io.OutputStream originalout) { this.originalout = originalout; } /** * Gets the temporary file. * @return the temporary file or null is the document is created in memory */ public java.io.File getTempFile() { return tempFile; } void setTempFile(java.io.File tempFile) { this.tempFile = tempFile; } /** * Gets a new signature fied name that doesn't clash with any existing name. * @return a new signature fied name */ public String getNewSigName() { AcroFields af = writer.getAcroFields(); String name = "Signature"; int step = 0; boolean found = false; while (!found) { ++step; String n1 = name + step; if (af.getFieldItem(n1) != null) continue; n1 += "."; found = true; for (Iterator it = af.getFields().keySet().iterator(); it.hasNext();) { String fn = (String)it.next(); if (fn.startsWith(n1)) { found = false; break; } } } name += step; return name; } /** * This is the first method to be called when using external signatures. The general sequence is: * preClose(), getDocumentBytes() and close(). *

* If calling preClose() dont't call PdfStamper.close(). *

* No external signatures are allowed if this method is called. * @throws IOException on error * @throws DocumentException on error */ public void preClose() throws IOException, DocumentException { preClose(null); } /** * This is the first method to be called when using external signatures. The general sequence is: * preClose(), getDocumentBytes() and close(). *

* If calling preClose() dont't call PdfStamper.close(). *

* If using an external signature exclusionSizes must contain at least * the PdfName.CONTENTS key with the size that it will take in the * document. Note that due to the hex string coding this size should be * byte_size*2+2. * @param exclusionSizes a HashMap with names and sizes to be excluded in the signature * calculation. The key is a PdfName and the value an * Integer. At least the PdfName.CONTENTS must be present * @throws IOException on error * @throws DocumentException on error */ public void preClose(HashMap exclusionSizes) throws IOException, DocumentException { if (preClosed) throw new DocumentException("Document already pre closed."); preClosed = true; AcroFields af = writer.getAcroFields(); String name = getFieldName(); boolean fieldExists = !(isInvisible() || isNewField()); PdfIndirectReference refSig = writer.getPdfIndirectReference(); writer.setSigFlags(3); if (fieldExists) { PdfDictionary widget = af.getFieldItem(name).getWidget(0); writer.markUsed(widget); widget.put(PdfName.P, writer.getPageReference(getPage())); widget.put(PdfName.V, refSig); PdfObject obj = PdfReader.getPdfObjectRelease(widget.get(PdfName.F)); int flags = 0; if (obj != null && obj.isNumber()) flags = ((PdfNumber)obj).intValue(); flags |= PdfAnnotation.FLAGS_LOCKED; widget.put(PdfName.F, new PdfNumber(flags)); PdfDictionary ap = new PdfDictionary(); ap.put(PdfName.N, getAppearance().getIndirectReference()); widget.put(PdfName.AP, ap); } else { PdfFormField sigField = PdfFormField.createSignature(writer); sigField.setFieldName(name); sigField.put(PdfName.V, refSig); sigField.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_LOCKED); int pagen = getPage(); if (!isInvisible()) sigField.setWidget(getPageRect(), null); else sigField.setWidget(new Rectangle(0, 0), null); sigField.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, getAppearance()); sigField.setPage(pagen); writer.addAnnotation(sigField, pagen); } exclusionLocations = new HashMap(); if (cryptoDictionary == null) { if (PdfName.ADOBE_PPKLITE.equals(getFilter())) sigStandard = new PdfSigGenericPKCS.PPKLite(getProvider()); else if (PdfName.ADOBE_PPKMS.equals(getFilter())) sigStandard = new PdfSigGenericPKCS.PPKMS(getProvider()); else if (PdfName.VERISIGN_PPKVS.equals(getFilter())) sigStandard = new PdfSigGenericPKCS.VeriSign(getProvider()); else throw new IllegalArgumentException("Unknown filter: " + getFilter()); sigStandard.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); if (getReason() != null) sigStandard.setReason(getReason()); if (getLocation() != null) sigStandard.setLocation(getLocation()); if (getContact() != null) sigStandard.setContact(getContact()); sigStandard.put(PdfName.M, new PdfDate(getSignDate())); sigStandard.setSignInfo(getPrivKey(), getCertChain(), getCrlList()); PdfString contents = (PdfString)sigStandard.get(PdfName.CONTENTS); PdfLiteral lit = new PdfLiteral((contents.toString().length() + (PdfName.ADOBE_PPKLITE.equals(getFilter())?0:64)) * 2 + 2); exclusionLocations.put(PdfName.CONTENTS, lit); sigStandard.put(PdfName.CONTENTS, lit); lit = new PdfLiteral(80); exclusionLocations.put(PdfName.BYTERANGE, lit); sigStandard.put(PdfName.BYTERANGE, lit); if (certificationLevel > 0) { addDocMDP(sigStandard); } if (signatureEvent != null) signatureEvent.getSignatureDictionary(sigStandard); writer.addToBody(sigStandard, refSig, false); } else { PdfLiteral lit = new PdfLiteral(80); exclusionLocations.put(PdfName.BYTERANGE, lit); cryptoDictionary.put(PdfName.BYTERANGE, lit); for (Iterator it = exclusionSizes.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); PdfName key = (PdfName)entry.getKey(); Integer v = (Integer)entry.getValue(); lit = new PdfLiteral(v.intValue()); exclusionLocations.put(key, lit); cryptoDictionary.put(key, lit); } if (certificationLevel > 0) addDocMDP(cryptoDictionary); if (signatureEvent != null) signatureEvent.getSignatureDictionary(cryptoDictionary); writer.addToBody(cryptoDictionary, refSig, false); } if (certificationLevel > 0) { // add DocMDP entry to root PdfDictionary docmdp = new PdfDictionary(); docmdp.put(new PdfName("DocMDP"), refSig); writer.reader.getCatalog().put(new PdfName("Perms"), docmdp); } writer.close(stamper.getMoreInfo()); range = new int[exclusionLocations.size() * 2]; int byteRangePosition = ((PdfLiteral)exclusionLocations.get(PdfName.BYTERANGE)).getPosition(); exclusionLocations.remove(PdfName.BYTERANGE); int idx = 1; for (Iterator it = exclusionLocations.values().iterator(); it.hasNext();) { PdfLiteral lit = (PdfLiteral)it.next(); int n = lit.getPosition(); range[idx++] = n; range[idx++] = lit.getPosLength() + n; } Arrays.sort(range, 1, range.length - 1); for (int k = 3; k < range.length - 2; k += 2) range[k] -= range[k - 1]; if (tempFile == null) { bout = sigout.getBuffer(); boutLen = sigout.size(); range[range.length - 1] = boutLen - range[range.length - 2]; ByteBuffer bf = new ByteBuffer(); bf.append('['); for (int k = 0; k < range.length; ++k) bf.append(range[k]).append(' '); bf.append(']'); System.arraycopy(bf.getBuffer(), 0, bout, byteRangePosition, bf.size()); } else { try { raf = new RandomAccessFile(tempFile, "rw"); int boutLen = (int)raf.length(); range[range.length - 1] = boutLen - range[range.length - 2]; ByteBuffer bf = new ByteBuffer(); bf.append('['); for (int k = 0; k < range.length; ++k) bf.append(range[k]).append(' '); bf.append(']'); raf.seek(byteRangePosition); raf.write(bf.getBuffer(), 0, bf.size()); } catch (IOException e) { try{raf.close();}catch(Exception ee){} try{tempFile.delete();}catch(Exception ee){} throw e; } } } /** * This is the last method to be called when using external signatures. The general sequence is: * preClose(), getDocumentBytes() and close(). *

* update is a PdfDictionary that must have exactly the * same keys as the ones provided in {@link #preClose(HashMap)}. * @param update a PdfDictionary with the key/value that will fill the holes defined * in {@link #preClose(HashMap)} * @throws DocumentException on error * @throws IOException on error */ public void close(PdfDictionary update) throws IOException, DocumentException { try { if (!preClosed) throw new DocumentException("preClose() must be called first."); ByteBuffer bf = new ByteBuffer(); for (Iterator it = update.getKeys().iterator(); it.hasNext();) { PdfName key = (PdfName)it.next(); PdfObject obj = update.get(key); PdfLiteral lit = (PdfLiteral)exclusionLocations.get(key); if (lit == null) throw new IllegalArgumentException("The key " + key.toString() + " didn't reserve space in preClose()."); bf.reset(); obj.toPdf(null, bf); if (bf.size() > lit.getPosLength()) throw new IllegalArgumentException("The key " + key.toString() + " is too big. Is " + bf.size() + ", reserved " + lit.getPosLength()); if (tempFile == null) System.arraycopy(bf.getBuffer(), 0, bout, lit.getPosition(), bf.size()); else { raf.seek(lit.getPosition()); raf.write(bf.getBuffer(), 0, bf.size()); } } if (update.size() != exclusionLocations.size()) throw new IllegalArgumentException("The update dictionary has less keys than required."); if (tempFile == null) { originalout.write(bout, 0, boutLen); } else { if (originalout != null) { raf.seek(0); int length = (int)raf.length(); byte buf[] = new byte[8192]; while (length > 0) { int r = raf.read(buf, 0, Math.min(buf.length, length)); if (r < 0) throw new EOFException("Unexpected EOF"); originalout.write(buf, 0, r); length -= r; } } } } finally { if (tempFile != null) { try{raf.close();}catch(Exception ee){} if (originalout != null) try{tempFile.delete();}catch(Exception ee){} } if (originalout != null) try{originalout.close();}catch(Exception e){} } } private void addDocMDP(PdfDictionary crypto) { PdfDictionary reference = new PdfDictionary(); PdfDictionary transformParams = new PdfDictionary(); transformParams.put(PdfName.P, new PdfNumber(certificationLevel)); transformParams.put(PdfName.V, new PdfName("1.2")); transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS); reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP); reference.put(PdfName.TYPE, PdfName.SIGREF); reference.put(PdfName.TRANSFORMPARAMS, transformParams); reference.put(new PdfName("DigestValue"), new PdfString("aa")); PdfArray loc = new PdfArray(); loc.add(new PdfNumber(0)); loc.add(new PdfNumber(0)); reference.put(new PdfName("DigestLocation"), loc); reference.put(new PdfName("DigestMethod"), new PdfName("MD5")); reference.put(PdfName.DATA, writer.reader.getTrailer().get(PdfName.ROOT)); PdfArray types = new PdfArray(); types.add(reference); crypto.put(PdfName.REFERENCE, types); } /** * Gets the document bytes that are hashable when using external signatures. The general sequence is: * preClose(), getRangeStream() and close(). *

* @return the document bytes that are hashable */ public InputStream getRangeStream() { return new PdfSignatureAppearance.RangeStream(raf, bout, range); } /** * Gets the user made signature dictionary. This is the dictionary at the /V key. * @return the user made signature dictionary */ public com.lowagie.text.pdf.PdfDictionary getCryptoDictionary() { return cryptoDictionary; } /** * Sets a user made signature dictionary. This is the dictionary at the /V key. * @param cryptoDictionary a user made signature dictionary */ public void setCryptoDictionary(com.lowagie.text.pdf.PdfDictionary cryptoDictionary) { this.cryptoDictionary = cryptoDictionary; } /** * Gets the PdfStamper associated with this instance. * @return the PdfStamper associated with this instance */ public com.lowagie.text.pdf.PdfStamper getStamper() { return stamper; } void setStamper(com.lowagie.text.pdf.PdfStamper stamper) { this.stamper = stamper; } /** * Checks if the document is in the process of closing. * @return true if the document is in the process of closing, * false otherwise */ public boolean isPreClosed() { return preClosed; } /** * Gets the instance of the standard signature dictionary. This instance * is only available after pre close. *

* The main use is to insert external signatures. * @return the instance of the standard signature dictionary */ public com.lowagie.text.pdf.PdfSigGenericPKCS getSigStandard() { return sigStandard; } /** * Gets the signing contact. * @return the signing contact */ public String getContact() { return this.contact; } /** * Sets the signing contact. * @param contact the signing contact */ public void setContact(String contact) { this.contact = contact; } /** * Gets the n2 and n4 layer font. * @return the n2 and n4 layer font */ public Font getLayer2Font() { return this.layer2Font; } /** * Sets the n2 and n4 layer font. If the font size is zero, auto-fit will be used. * @param layer2Font the n2 and n4 font */ public void setLayer2Font(Font layer2Font) { this.layer2Font = layer2Font; } /** * Gets the Acrobat 6.0 layer mode. * @return the Acrobat 6.0 layer mode */ public boolean isAcro6Layers() { return this.acro6Layers; } /** * Acrobat 6.0 and higher recommends that only layer n2 and n4 be present. This method sets that mode. * @param acro6Layers if true only the layers n2 and n4 will be present */ public void setAcro6Layers(boolean acro6Layers) { this.acro6Layers = acro6Layers; } /** Sets the run direction in the n2 and n4 layer. * @param runDirection the run direction */ public void setRunDirection(int runDirection) { if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) throw new RuntimeException("Invalid run direction: " + runDirection); this.runDirection = runDirection; } /** Gets the run direction. * @return the run direction */ public int getRunDirection() { return runDirection; } /** * Getter for property signatureEvent. * @return Value of property signatureEvent. */ public SignatureEvent getSignatureEvent() { return this.signatureEvent; } /** * Sets the signature event to allow modification of the signature dictionary. * @param signatureEvent the signature event */ public void setSignatureEvent(SignatureEvent signatureEvent) { this.signatureEvent = signatureEvent; } /** * Gets the background image for the layer 2. * @return the background image for the layer 2 */ public Image getImage() { return this.image; } /** * Sets the background image for the layer 2. * @param image the background image for the layer 2 */ public void setImage(Image image) { this.image = image; } /** * Gets the scaling to be applied to the background image. * @return the scaling to be applied to the background image */ public float getImageScale() { return this.imageScale; } /** * Sets the scaling to be applied to the background image. If it's zero the image * will fully fill the rectangle. If it's less than zero the image will fill the rectangle but * will keep the proportions. If it's greater than zero that scaling will be applied. * In any of the cases the image will always be centered. It's zero by default. * @param imageScale the scaling to be applied to the background image */ public void setImageScale(float imageScale) { this.imageScale = imageScale; } /** * Commands to draw a yellow question mark in a stream content */ public static final String questionMark = "% DSUnknown\n" + "q\n" + "1 G\n" + "1 g\n" + "0.1 0 0 0.1 9 0 cm\n" + "0 J 0 j 4 M []0 d\n" + "1 i \n" + "0 g\n" + "313 292 m\n" + "313 404 325 453 432 529 c\n" + "478 561 504 597 504 645 c\n" + "504 736 440 760 391 760 c\n" + "286 760 271 681 265 626 c\n" + "265 625 l\n" + "100 625 l\n" + "100 828 253 898 381 898 c\n" + "451 898 679 878 679 650 c\n" + "679 555 628 499 538 435 c\n" + "488 399 467 376 467 292 c\n" + "313 292 l\n" + "h\n" + "308 214 170 -164 re\n" + "f\n" + "0.44 G\n" + "1.2 w\n" + "1 1 0.4 rg\n" + "287 318 m\n" + "287 430 299 479 406 555 c\n" + "451 587 478 623 478 671 c\n" + "478 762 414 786 365 786 c\n" + "260 786 245 707 239 652 c\n" + "239 651 l\n" + "74 651 l\n" + "74 854 227 924 355 924 c\n" + "425 924 653 904 653 676 c\n" + "653 581 602 525 512 461 c\n" + "462 425 441 402 441 318 c\n" + "287 318 l\n" + "h\n" + "282 240 170 -164 re\n" + "B\n" + "Q\n"; /** * Holds value of property contact. */ private String contact; /** * Holds value of property layer2Font. */ private Font layer2Font; /** * Holds value of property layer4Text. */ private String layer4Text; /** * Holds value of property acro6Layers. */ private boolean acro6Layers; /** * Holds value of property runDirection. */ private int runDirection = PdfWriter.RUN_DIRECTION_NO_BIDI; /** * Holds value of property signatureEvent. */ private SignatureEvent signatureEvent; /** * Holds value of property image. */ private Image image; /** * Holds value of property imageScale. */ private float imageScale; /** * */ private static class RangeStream extends InputStream { private byte b[] = new byte[1]; private RandomAccessFile raf; private byte bout[]; private int range[]; private int rangePosition = 0; private RangeStream(RandomAccessFile raf, byte bout[], int range[]) { this.raf = raf; this.bout = bout; this.range = range; } /** * @see java.io.InputStream#read() */ public int read() throws IOException { int n = read(b); if (n != 1) return -1; return b[0] & 0xff; } /** * @see java.io.InputStream#read(byte[], int, int) */ public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } if (rangePosition >= range[range.length - 2] + range[range.length - 1]) { return -1; } for (int k = 0; k < range.length; k += 2) { int start = range[k]; int end = start + range[k + 1]; if (rangePosition < start) rangePosition = start; if (rangePosition >= start && rangePosition < end) { int lenf = Math.min(len, end - rangePosition); if (raf == null) System.arraycopy(bout, rangePosition, b, off, lenf); else { raf.seek(rangePosition); raf.readFully(b, off, lenf); } rangePosition += lenf; return lenf; } } return -1; } } /** * An interface to retrieve the signature dictionary for modification. */ public interface SignatureEvent { /** * Allows modification of the signature dictionary. * @param sig the signature dictionary */ public void getSignatureDictionary(PdfDictionary sig); } private int certificationLevel = NOT_CERTIFIED; /** * Gets the certified status of this document. * @return the certified status */ public int getCertificationLevel() { return this.certificationLevel; } /** * Sets the document type to certified instead of simply signed. * @param certificationLevel the values can be: NOT_CERTIFIED, CERTIFIED_NO_CHANGES_ALLOWED, * CERTIFIED_FORM_FILLING and CERTIFIED_FORM_FILLING_AND_ANNOTATIONS */ public void setCertificationLevel(int certificationLevel) { this.certificationLevel = certificationLevel; } }src/core/com/lowagie/text/pdf/PdfSmartCopy.java100644 0 0 20757 11224570760 17143 0ustar 0 0 /* * $Id: PdfSmartCopy.java 3991 2009-06-18 21:21:09Z psoares33 $ * * Copyright 2007 Michael Neuweiler and Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * This class was written by Michael Neuweiler based on hints given by Bruno Lowagie * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; import java.util.Arrays; import java.util.HashMap; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; /** * PdfSmartCopy has the same functionality as PdfCopy, * but when resources (such as fonts, images,...) are * encountered, a reference to these resources is saved * in a cache, so that they can be reused. * This requires more memory, but reduces the file size * of the resulting PDF document. */ public class PdfSmartCopy extends PdfCopy { /** the cache with the streams and references. */ private HashMap streamMap = null; /** Creates a PdfSmartCopy instance. */ public PdfSmartCopy(Document document, OutputStream os) throws DocumentException { super(document, os); this.streamMap = new HashMap(); } /** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected PdfIndirectReference copyIndirect(PRIndirectReference in) throws IOException, BadPdfFormatException { PdfObject srcObj = PdfReader.getPdfObjectRelease(in); ByteStore streamKey = null; boolean validStream = false; if (srcObj.isStream()) { streamKey = new ByteStore((PRStream)srcObj); validStream = true; PdfIndirectReference streamRef = (PdfIndirectReference) streamMap.get(streamKey); if (streamRef != null) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(in); IndirectReferences iRef = (IndirectReferences) indirects.get(key); if (iRef != null) { theRef = iRef.getRef(); if (iRef.getCopied()) { return theRef; } } else { theRef = body.getPdfIndirectReference(); iRef = new IndirectReferences(theRef); indirects.put(key, iRef); } if (srcObj.isDictionary()) { PdfObject type = PdfReader.getPdfObjectRelease(((PdfDictionary)srcObj).get(PdfName.TYPE)); if (type != null && PdfName.PAGE.equals(type)) { return theRef; } } iRef.setCopied(); if (validStream) { streamMap.put(streamKey, theRef); } PdfObject obj = copyObject(srcObj); addToBody(obj, theRef); return theRef; } static class ByteStore { private byte[] b; private int hash; private MessageDigest md5; private void serObject(PdfObject obj, int level, ByteBuffer bb) throws IOException { if (level <= 0) return; if (obj == null) { bb.append("$Lnull"); return; } obj = PdfReader.getPdfObject(obj); if (obj.isStream()) { bb.append("$B"); serDic((PdfDictionary)obj, level - 1, bb); if (level > 0) { md5.reset(); bb.append(md5.digest(PdfReader.getStreamBytesRaw((PRStream)obj))); } } else if (obj.isDictionary()) { serDic((PdfDictionary)obj, level - 1, bb); } else if (obj.isArray()) { serArray((PdfArray)obj, level - 1, bb); } else if (obj.isString()) { bb.append("$S").append(obj.toString()); } else if (obj.isName()) { bb.append("$N").append(obj.toString()); } else bb.append("$L").append(obj.toString()); } private void serDic(PdfDictionary dic, int level, ByteBuffer bb) throws IOException { bb.append("$D"); if (level <= 0) return; Object[] keys = dic.getKeys().toArray(); Arrays.sort(keys); for (int k = 0; k < keys.length; ++k) { serObject((PdfObject)keys[k], level, bb); serObject(dic.get((PdfName)keys[k]), level, bb); } } private void serArray(PdfArray array, int level, ByteBuffer bb) throws IOException { bb.append("$A"); if (level <= 0) return; for (int k = 0; k < array.size(); ++k) { serObject(array.getPdfObject(k), level, bb); } } ByteStore(PRStream str) throws IOException { try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { throw new ExceptionConverter(e); } ByteBuffer bb = new ByteBuffer(); int level = 100; serObject(str, level, bb); this.b = bb.toByteArray(); md5 = null; } public boolean equals(Object obj) { if (!(obj instanceof ByteStore)) return false; if (hashCode() != obj.hashCode()) return false; return Arrays.equals(b, ((ByteStore)obj).b); } public int hashCode() { if (hash == 0) { int len = b.length; for (int k = 0; k < len; ++k) { hash = hash * 31 + (b[k] & 0xff); } } return hash; } } }src/core/com/lowagie/text/pdf/PdfSpotColor.java100644 0 0 11635 11036112746 17136 0ustar 0 0 /* * $Id: PdfSpotColor.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; /** * A PdfSpotColor defines a ColorSpace * * @see PdfDictionary */ public class PdfSpotColor{ /* The tint value */ protected float tint; /** The color name */ public PdfName name; /** The alternative color space */ public Color altcs; // constructors /** * Constructs a new PdfSpotColor. * * @param name a String value * @param tint a tint value between 0 and 1 * @param altcs an alternative colorspace value */ public PdfSpotColor(String name, float tint, Color altcs) { this.name = new PdfName(name); this.tint = tint; this.altcs = altcs; } /** * Gets the tint of the SpotColor. * @return a float */ public float getTint() { return tint; } /** * Gets the alternative ColorSpace. * @return a Color */ public Color getAlternativeCS() { return altcs; } protected PdfObject getSpotObject(PdfWriter writer) { PdfArray array = new PdfArray(PdfName.SEPARATION); array.add(name); PdfFunction func = null; if (altcs instanceof ExtendedColor) { int type = ((ExtendedColor)altcs).type; switch (type) { case ExtendedColor.TYPE_GRAY: array.add(PdfName.DEVICEGRAY); func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{0}, new float[]{((GrayColor)altcs).getGray()}, 1); break; case ExtendedColor.TYPE_CMYK: array.add(PdfName.DEVICECMYK); CMYKColor cmyk = (CMYKColor)altcs; func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{0, 0, 0, 0}, new float[]{cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()}, 1); break; default: throw new RuntimeException("Only RGB, Gray and CMYK are supported as alternative color spaces."); } } else { array.add(PdfName.DEVICERGB); func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{1, 1, 1}, new float[]{(float)altcs.getRed() / 255, (float)altcs.getGreen() / 255, (float)altcs.getBlue() / 255}, 1); } array.add(func.getReference()); return array; } } src/core/com/lowagie/text/pdf/PdfStamper.java100644 0 0 103053 11106243445 16640 0ustar 0 0 /* * Copyright 2003, 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SignatureException; import java.util.HashMap; import java.util.List; import java.util.Map; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.collection.PdfCollection; import com.lowagie.text.pdf.interfaces.PdfEncryptionSettings; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; import java.security.cert.Certificate; /** Applies extra content to the pages of a PDF document. * This extra content can be all the objects allowed in PdfContentByte * including pages from other Pdfs. The original PDF will keep * all the interactive elements including bookmarks, links and form fields. *

* It is also possible to change the field values and to * flatten them. New fields can be added but not flattened. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfStamper implements PdfViewerPreferences, PdfEncryptionSettings { /** * The writer */ protected PdfStamperImp stamper; private HashMap moreInfo; private boolean hasSignature; private PdfSignatureAppearance sigApp; /** Starts the process of adding extra content to an existing PDF * document. * @param reader the original document. It cannot be reused * @param os the output stream * @throws DocumentException on error * @throws IOException on error */ public PdfStamper(PdfReader reader, OutputStream os) throws DocumentException, IOException { stamper = new PdfStamperImp(reader, os, '\0', false); } /** * Starts the process of adding extra content to an existing PDF * document. * @param reader the original document. It cannot be reused * @param os the output stream * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @throws DocumentException on error * @throws IOException on error */ public PdfStamper(PdfReader reader, OutputStream os, char pdfVersion) throws DocumentException, IOException { stamper = new PdfStamperImp(reader, os, pdfVersion, false); } /** * Starts the process of adding extra content to an existing PDF * document, possibly as a new revision. * @param reader the original document. It cannot be reused * @param os the output stream * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @param append if true appends the document changes as a new revision. This is * only useful for multiple signatures as nothing is gained in speed or memory * @throws DocumentException on error * @throws IOException on error */ public PdfStamper(PdfReader reader, OutputStream os, char pdfVersion, boolean append) throws DocumentException, IOException { stamper = new PdfStamperImp(reader, os, pdfVersion, append); } /** Gets the optional String map to add or change values in * the info dictionary. * @return the map or null * */ public HashMap getMoreInfo() { return this.moreInfo; } /** An optional String map to add or change values in * the info dictionary. Entries with null * values delete the key in the original info dictionary * @param moreInfo additional entries to the info dictionary * */ public void setMoreInfo(HashMap moreInfo) { this.moreInfo = moreInfo; } /** * Replaces a page from this document with a page from other document. Only the content * is replaced not the fields and annotations. This method must be called before * getOverContent() or getUndercontent() are called for the same page. * @param r the PdfReader from where the new page will be imported * @param pageImported the page number of the imported page * @param pageReplaced the page to replace in this document * @since iText 2.1.1 */ public void replacePage(PdfReader r, int pageImported, int pageReplaced) { stamper.replacePage(r, pageImported, pageReplaced); } /** * Inserts a blank page. All the pages above and including pageNumber will * be shifted up. If pageNumber is bigger than the total number of pages * the new page will be the last one. * @param pageNumber the page number position where the new page will be inserted * @param mediabox the size of the new page */ public void insertPage(int pageNumber, Rectangle mediabox) { stamper.insertPage(pageNumber, mediabox); } /** * Gets the signing instance. The appearances and other parameters can the be set. * @return the signing instance */ public PdfSignatureAppearance getSignatureAppearance() { return sigApp; } /** * Closes the document. No more content can be written after the * document is closed. *

* If closing a signed document with an external signature the closing must be done * in the PdfSignatureAppearance instance. * @throws DocumentException on error * @throws IOException on error */ public void close() throws DocumentException, IOException { if (!hasSignature) { stamper.close(moreInfo); return; } sigApp.preClose(); PdfSigGenericPKCS sig = sigApp.getSigStandard(); PdfLiteral lit = (PdfLiteral)sig.get(PdfName.CONTENTS); int totalBuf = (lit.getPosLength() - 2) / 2; byte buf[] = new byte[8192]; int n; InputStream inp = sigApp.getRangeStream(); try { while ((n = inp.read(buf)) > 0) { sig.getSigner().update(buf, 0, n); } } catch (SignatureException se) { throw new ExceptionConverter(se); } buf = new byte[totalBuf]; byte[] bsig = sig.getSignerContents(); System.arraycopy(bsig, 0, buf, 0, bsig.length); PdfString str = new PdfString(buf); str.setHexWriting(true); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.CONTENTS, str); sigApp.close(dic); stamper.reader.close(); } /** Gets a PdfContentByte to write under the page of * the original document. * @param pageNum the page number where the extra content is written * @return a PdfContentByte to write under the page of * the original document */ public PdfContentByte getUnderContent(int pageNum) { return stamper.getUnderContent(pageNum); } /** Gets a PdfContentByte to write over the page of * the original document. * @param pageNum the page number where the extra content is written * @return a PdfContentByte to write over the page of * the original document */ public PdfContentByte getOverContent(int pageNum) { return stamper.getOverContent(pageNum); } /** Checks if the content is automatically adjusted to compensate * the original page rotation. * @return the auto-rotation status */ public boolean isRotateContents() { return stamper.isRotateContents(); } /** Flags the content to be automatically adjusted to compensate * the original page rotation. The default is true. * @param rotateContents true to set auto-rotation, false * otherwise */ public void setRotateContents(boolean rotateContents) { stamper.setRotateContents(rotateContents); } /** Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @throws DocumentException if anything was already written to the output */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { if (stamper.isAppend()) throw new DocumentException("Append mode does not support changing the encryption status."); if (stamper.isContentWritten()) throw new DocumentException("Content was already written to the output."); stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40); } /** Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @throws DocumentException if the document is already open */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, int encryptionType) throws DocumentException { if (stamper.isAppend()) throw new DocumentException("Append mode does not support changing the encryption status."); if (stamper.isContentWritten()) throw new DocumentException("Content was already written to the output."); stamper.setEncryption(userPassword, ownerPassword, permissions, encryptionType); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param strength true for 128 bit key length, false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if anything was already written to the output */ public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if anything was already written to the output */ public void setEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, encryptionType); } /** * Sets the certificate encryption options for this document. An array of one or more public certificates * must be provided together with an array of the same size for the permissions for each certificate. * The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param certs the public certificates to be used for the encryption * @param permissions the user permissions for each of the certificates * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * @throws DocumentException if the encryption was set too late */ public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException { if (stamper.isAppend()) throw new DocumentException("Append mode does not support changing the encryption status."); if (stamper.isContentWritten()) throw new DocumentException("Content was already written to the output."); stamper.setEncryption(certs, permissions, encryptionType); } /** Gets a page from other PDF document. Note that calling this method more than * once with the same parameters will retrieve the same object. * @param reader the PDF document where the page is * @param pageNumber the page number. The first page is 1 * @return the template representing the imported page */ public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { return stamper.getImportedPage(reader, pageNumber); } /** Gets the underlying PdfWriter. * @return the underlying PdfWriter */ public PdfWriter getWriter() { return stamper; } /** Gets the underlying PdfReader. * @return the underlying PdfReader */ public PdfReader getReader() { return stamper.reader; } /** Gets the AcroFields object that allows to get and set field values * and to merge FDF forms. * @return the AcroFields object */ public AcroFields getAcroFields() { return stamper.getAcroFields(); } /** Determines if the fields are flattened on close. The fields added with * {@link #addAnnotation(PdfAnnotation,int)} will never be flattened. * @param flat true to flatten the fields, false * to keep the fields */ public void setFormFlattening(boolean flat) { stamper.setFormFlattening(flat); } /** Determines if the FreeText annotations are flattened on close. * @param flat true to flatten the FreeText annotations, false * (the default) to keep the FreeText annotations as active content. */ public void setFreeTextFlattening(boolean flat) { stamper.setFreeTextFlattening(flat); } /** * Adds an annotation of form field in a specific page. This page number * can be overridden with {@link PdfAnnotation#setPlaceInPage(int)}. * @param annot the annotation * @param page the page */ public void addAnnotation(PdfAnnotation annot, int page) { stamper.addAnnotation(annot, page); } /** * Adds an empty signature. * @param name the name of the signature * @param page the page number * @param llx lower left x coordinate of the signature's position * @param lly lower left y coordinate of the signature's position * @param urx upper right x coordinate of the signature's position * @param ury upper right y coordinate of the signature's position * @return a signature form field * @since 2.1.4 */ public PdfFormField addSignature(String name, int page, float llx, float lly, float urx, float ury) { PdfAcroForm acroForm = stamper.getAcroForm(); PdfFormField signature = PdfFormField.createSignature(stamper); acroForm.setSignatureParams(signature, name, llx, lly, urx, ury); acroForm.drawSignatureAppearences(signature, llx, lly, urx, ury); addAnnotation(signature, page); return signature; } /** * Adds the comments present in an FDF file. * @param fdf the FDF file * @throws IOException on error */ public void addComments(FdfReader fdf) throws IOException { stamper.addComments(fdf); } /** * Sets the bookmarks. The list structure is defined in * {@link SimpleBookmark}. * @param outlines the bookmarks or null to remove any */ public void setOutlines(List outlines) { stamper.setOutlines(outlines); } /** * Sets the thumbnail image for a page. * @param image the image * @param page the page * @throws PdfException on error * @throws DocumentException on error */ public void setThumbnail(Image image, int page) throws PdfException, DocumentException { stamper.setThumbnail(image, page); } /** * Adds name to the list of fields that will be flattened on close, * all the other fields will remain. If this method is never called or is called * with invalid field names, all the fields will be flattened. *

* Calling setFormFlattening(true) is needed to have any kind of * flattening. * @param name the field name * @return true if the field exists, false otherwise */ public boolean partialFormFlattening(String name) { return stamper.partialFormFlattening(name); } /** Adds a JavaScript action at the document level. When the document * opens all this JavaScript runs. The existing JavaScript will be replaced. * @param js the JavaScript code */ public void addJavaScript(String js) { stamper.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js)); } /** Adds a file attachment at the document level. Existing attachments will be kept. * @param description the file description * @param fileStore an array with the file. If it's null * the file will be read from the disk * @param file the path to the file. It will only be used if * fileStore is not null * @param fileDisplay the actual file name stored in the pdf * @throws IOException on error */ public void addFileAttachment(String description, byte fileStore[], String file, String fileDisplay) throws IOException { addFileAttachment(description, PdfFileSpecification.fileEmbedded(stamper, file, fileDisplay, fileStore)); } /** Adds a file attachment at the document level. Existing attachments will be kept. * @param description the file description * @param fs the file specification */ public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { stamper.addFileAttachment(description, fs); } /** * This is the most simple way to change a PDF into a * portable collection. Choose one of the following names: *

    *
  • PdfName.D (detailed view) *
  • PdfName.T (tiled view) *
  • PdfName.H (hidden) *
* Pass this name as a parameter and your PDF will be * a portable collection with all the embedded and * attached files as entries. * @param initialView can be PdfName.D, PdfName.T or PdfName.H */ public void makePackage( PdfName initialView ) { PdfCollection collection = new PdfCollection(0); collection.put(PdfName.VIEW, initialView); stamper.makePackage( collection ); } /** * Adds or replaces the Collection Dictionary in the Catalog. * @param collection the new collection dictionary. */ public void makePackage(PdfCollection collection) { stamper.makePackage(collection); } /** * Sets the viewer preferences. * @param preferences the viewer preferences * @see PdfViewerPreferences#setViewerPreferences(int) */ public void setViewerPreferences(int preferences) { stamper.setViewerPreferences(preferences); } /** Adds a viewer preference * @param key a key for a viewer preference * @param value the value for the viewer preference * @see PdfViewerPreferences#addViewerPreference */ public void addViewerPreference(PdfName key, PdfObject value) { stamper.addViewerPreference(key, value); } /** * Sets the XMP metadata. * @param xmp * @see PdfWriter#setXmpMetadata(byte[]) */ public void setXmpMetadata(byte[] xmp) { stamper.setXmpMetadata(xmp); } /** * Gets the 1.5 compression status. * @return true if the 1.5 compression is on */ public boolean isFullCompression() { return stamper.isFullCompression(); } /** * Sets the document's compression to the new 1.5 mode with object streams and xref * streams. It can be set at any time but once set it can't be unset. */ public void setFullCompression() { if (stamper.isAppend()) return; stamper.setFullCompression(); } /** * Sets the open and close page additional action. * @param actionType the action type. It can be PdfWriter.PAGE_OPEN * or PdfWriter.PAGE_CLOSE * @param action the action to perform * @param page the page where the action will be applied. The first page is 1 * @throws PdfException if the action type is invalid */ public void setPageAction(PdfName actionType, PdfAction action, int page) throws PdfException { stamper.setPageAction(actionType, action, page); } /** * Sets the display duration for the page (for presentations) * @param seconds the number of seconds to display the page. A negative value removes the entry * @param page the page where the duration will be applied. The first page is 1 */ public void setDuration(int seconds, int page) { stamper.setDuration(seconds, page); } /** * Sets the transition for the page * @param transition the transition object. A null removes the transition * @param page the page where the transition will be applied. The first page is 1 */ public void setTransition(PdfTransition transition, int page) { stamper.setTransition(transition, page); } /** * Applies a digital signature to a document, possibly as a new revision, making * possible multiple signatures. The returned PdfStamper * can be used normally as the signature is only applied when closing. *

* A possible use for adding a signature without invalidating an existing one is: *

*

     * KeyStore ks = KeyStore.getInstance("pkcs12");
     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
     * String alias = (String)ks.aliases().nextElement();
     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
     * Certificate[] chain = ks.getCertificateChain(alias);
     * PdfReader reader = new PdfReader("original.pdf");
     * FileOutputStream fout = new FileOutputStream("signed.pdf");
     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new
     * File("/temp"), true);
     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
     * sap.setReason("I'm the author");
     * sap.setLocation("Lisbon");
     * // comment next line to have an invisible signature
     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
     * stp.close();
     * 
* @param reader the original document * @param os the output stream or null to keep the document in the temporary file * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there. * If it's a file it will be used directly. The file will be deleted on exit unless os is null. * In that case the document can be retrieved directly from the temporary file. If it's null * no temporary file will be created and memory will be used * @param append if true the signature and all the other content will be added as a * new revision thus not invalidating existing signatures * @return a PdfStamper * @throws DocumentException on error * @throws IOException on error */ public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion, File tempFile, boolean append) throws DocumentException, IOException { PdfStamper stp; if (tempFile == null) { ByteBuffer bout = new ByteBuffer(); stp = new PdfStamper(reader, bout, pdfVersion, append); stp.sigApp = new PdfSignatureAppearance(stp.stamper); stp.sigApp.setSigout(bout); } else { if (tempFile.isDirectory()) tempFile = File.createTempFile("pdf", null, tempFile); FileOutputStream fout = new FileOutputStream(tempFile); stp = new PdfStamper(reader, fout, pdfVersion, append); stp.sigApp = new PdfSignatureAppearance(stp.stamper); stp.sigApp.setTempFile(tempFile); } stp.sigApp.setOriginalout(os); stp.sigApp.setStamper(stp); stp.hasSignature = true; PdfDictionary catalog = reader.getCatalog(); PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), catalog); if (acroForm != null) { acroForm.remove(PdfName.NEEDAPPEARANCES); stp.stamper.markUsed(acroForm); } return stp; } /** * Applies a digital signature to a document. The returned PdfStamper * can be used normally as the signature is only applied when closing. *

* Note that the pdf is created in memory. *

* A possible use is: *

*

     * KeyStore ks = KeyStore.getInstance("pkcs12");
     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
     * String alias = (String)ks.aliases().nextElement();
     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
     * Certificate[] chain = ks.getCertificateChain(alias);
     * PdfReader reader = new PdfReader("original.pdf");
     * FileOutputStream fout = new FileOutputStream("signed.pdf");
     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
     * sap.setReason("I'm the author");
     * sap.setLocation("Lisbon");
     * // comment next line to have an invisible signature
     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
     * stp.close();
     * 
* @param reader the original document * @param os the output stream * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @throws DocumentException on error * @throws IOException on error * @return a PdfStamper */ public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion) throws DocumentException, IOException { return createSignature(reader, os, pdfVersion, null, false); } /** * Applies a digital signature to a document. The returned PdfStamper * can be used normally as the signature is only applied when closing. *

* A possible use is: *

*

     * KeyStore ks = KeyStore.getInstance("pkcs12");
     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
     * String alias = (String)ks.aliases().nextElement();
     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
     * Certificate[] chain = ks.getCertificateChain(alias);
     * PdfReader reader = new PdfReader("original.pdf");
     * FileOutputStream fout = new FileOutputStream("signed.pdf");
     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new File("/temp"));
     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
     * sap.setReason("I'm the author");
     * sap.setLocation("Lisbon");
     * // comment next line to have an invisible signature
     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
     * stp.close();
     * 
* @param reader the original document * @param os the output stream or null to keep the document in the temporary file * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there. * If it's a file it will be used directly. The file will be deleted on exit unless os is null. * In that case the document can be retrieved directly from the temporary file. If it's null * no temporary file will be created and memory will be used * @return a PdfStamper * @throws DocumentException on error * @throws IOException on error */ public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion, File tempFile) throws DocumentException, IOException { return createSignature(reader, os, pdfVersion, tempFile, false); } /** * Gets the PdfLayer objects in an existing document as a Map * with the names/titles of the layers as keys. * @return a Map with all the PdfLayers in the document (and the name/title of the layer as key) * @since 2.1.2 */ public Map getPdfLayers() { return stamper.getPdfLayers(); } }src/core/com/lowagie/text/pdf/PdfStamperImp.java100644 0 0 202611 11224570760 17312 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import org.xml.sax.SAXException; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.exceptions.BadPasswordException; import com.lowagie.text.pdf.collection.PdfCollection; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; import com.lowagie.text.pdf.internal.PdfViewerPreferencesImp; import com.lowagie.text.xml.xmp.XmpReader; class PdfStamperImp extends PdfWriter { HashMap readers2intrefs = new HashMap(); HashMap readers2file = new HashMap(); RandomAccessFileOrArray file; PdfReader reader; IntHashtable myXref = new IntHashtable(); /** Integer(page number) -> PageStamp */ HashMap pagesToContent = new HashMap(); boolean closed = false; /** Holds value of property rotateContents. */ private boolean rotateContents = true; protected AcroFields acroFields; protected boolean flat = false; protected boolean flatFreeText = false; protected int namePtr[] = {0}; protected HashSet partialFlattening = new HashSet(); protected boolean useVp = false; protected PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp(); protected HashMap fieldTemplates = new HashMap(); protected boolean fieldsAdded = false; protected int sigFlags = 0; protected boolean append; protected IntHashtable marked; protected int initialXrefSize; protected PdfAction openAction; /** Creates new PdfStamperImp. * @param reader the read PDF * @param os the output destination * @param pdfVersion the new pdf version or '\0' to keep the same version as the original * document * @param append * @throws DocumentException on error * @throws IOException */ PdfStamperImp(PdfReader reader, OutputStream os, char pdfVersion, boolean append) throws DocumentException, IOException { super(new PdfDocument(), os); if (!reader.isOpenedWithFullPermissions()) throw new BadPasswordException("PdfReader not opened with owner password"); if (reader.isTampered()) throw new DocumentException("The original document was reused. Read it again from file."); reader.setTampered(true); this.reader = reader; file = reader.getSafeFile(); this.append = append; if (append) { if (reader.isRebuilt()) throw new DocumentException("Append mode requires a document without errors even if recovery was possible."); if (reader.isEncrypted()) crypto = new PdfEncryption(reader.getDecrypt()); pdf_version.setAppendmode(true); file.reOpen(); byte buf[] = new byte[8192]; int n; while ((n = file.read(buf)) > 0) this.os.write(buf, 0, n); file.close(); prevxref = reader.getLastXref(); reader.setAppendable(true); } else { if (pdfVersion == 0) super.setPdfVersion(reader.getPdfVersion()); else super.setPdfVersion(pdfVersion); } super.open(); pdf.addWriter(this); if (append) { body.setRefnum(reader.getXrefSize()); marked = new IntHashtable(); if (reader.isNewXrefType()) fullCompression = true; if (reader.isHybridXref()) fullCompression = false; } initialXrefSize = reader.getXrefSize(); } void close(HashMap moreInfo) throws IOException { if (closed) return; if (useVp) { reader.setViewerPreferences(viewerPreferences); markUsed(reader.getTrailer().get(PdfName.ROOT)); } if (flat) flatFields(); if (flatFreeText) flatFreeTextFields(); addFieldResources(); PdfDictionary catalog = reader.getCatalog(); PdfDictionary pages = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.PAGES)); pages.put(PdfName.ITXT, new PdfString(Document.getRelease())); markUsed(pages); PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), reader.getCatalog()); if (acroFields != null && acroFields.getXfa().isChanged()) { markUsed(acroForm); if (!flat) acroFields.getXfa().setXfa(this); } if (sigFlags != 0) { if (acroForm != null) { acroForm.put(PdfName.SIGFLAGS, new PdfNumber(sigFlags)); markUsed(acroForm); markUsed(catalog); } } closed = true; addSharedObjectsToBody(); setOutlines(); setJavaScript(); addFileAttachments(); if (openAction != null) { catalog.put(PdfName.OPENACTION, openAction); } if (pdf.pageLabels != null) catalog.put(PdfName.PAGELABELS, pdf.pageLabels.getDictionary(this)); // OCG if (!documentOCG.isEmpty()) { fillOCProperties(false); PdfDictionary ocdict = catalog.getAsDict(PdfName.OCPROPERTIES); if (ocdict == null) { reader.getCatalog().put(PdfName.OCPROPERTIES, OCProperties); } else { ocdict.put(PdfName.OCGS, OCProperties.get(PdfName.OCGS)); PdfDictionary ddict = ocdict.getAsDict(PdfName.D); if (ddict == null) { ddict = new PdfDictionary(); ocdict.put(PdfName.D, ddict); } ddict.put(PdfName.ORDER, OCProperties.getAsDict(PdfName.D).get(PdfName.ORDER)); ddict.put(PdfName.RBGROUPS, OCProperties.getAsDict(PdfName.D).get(PdfName.RBGROUPS)); ddict.put(PdfName.OFF, OCProperties.getAsDict(PdfName.D).get(PdfName.OFF)); ddict.put(PdfName.AS, OCProperties.getAsDict(PdfName.D).get(PdfName.AS)); } } // metadata int skipInfo = -1; PRIndirectReference iInfo = (PRIndirectReference)reader.getTrailer().get(PdfName.INFO); PdfDictionary oldInfo = (PdfDictionary)PdfReader.getPdfObject(iInfo); String producer = null; if (iInfo != null) skipInfo = iInfo.getNumber(); if (oldInfo != null && oldInfo.get(PdfName.PRODUCER) != null) producer = oldInfo.getAsString(PdfName.PRODUCER).toString(); if (producer == null) { producer = Document.getVersion(); } else if (producer.indexOf(Document.getProduct()) == -1) { StringBuffer buf = new StringBuffer(producer); buf.append("; modified using "); buf.append(Document.getVersion()); producer = buf.toString(); } // XMP byte[] altMetadata = null; PdfObject xmpo = PdfReader.getPdfObject(catalog.get(PdfName.METADATA)); if (xmpo != null && xmpo.isStream()) { altMetadata = PdfReader.getStreamBytesRaw((PRStream)xmpo); PdfReader.killIndirect(catalog.get(PdfName.METADATA)); } if (xmpMetadata != null) { altMetadata = xmpMetadata; } // if there is XMP data to add: add it PdfDate date = new PdfDate(); if (altMetadata != null) { PdfStream xmp; try { XmpReader xmpr = new XmpReader(altMetadata); if (!xmpr.replace("http://ns.adobe.com/pdf/1.3/", "Producer", producer)) xmpr.add("rdf:Description", "http://ns.adobe.com/pdf/1.3/", "pdf:Producer", producer); if (!xmpr.replace("http://ns.adobe.com/xap/1.0/", "ModifyDate", date.getW3CDate())) xmpr.add("rdf:Description", "http://ns.adobe.com/xap/1.0/", "xmp:ModifyDate", date.getW3CDate()); xmpr.replace("http://ns.adobe.com/xap/1.0/", "MetadataDate", date.getW3CDate()); xmp = new PdfStream(xmpr.serializeDoc()); } catch(SAXException e) { xmp = new PdfStream(altMetadata); } catch(IOException e) { xmp = new PdfStream(altMetadata); } xmp.put(PdfName.TYPE, PdfName.METADATA); xmp.put(PdfName.SUBTYPE, PdfName.XML); if (crypto != null && !crypto.isMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.add(PdfName.CRYPT); xmp.put(PdfName.FILTER, ar); } if (append && xmpo != null) { body.add(xmp, xmpo.getIndRef()); } else { catalog.put(PdfName.METADATA, body.add(xmp).getIndirectReference()); markUsed(catalog); } } try { file.reOpen(); alterContents(); int rootN = ((PRIndirectReference)reader.trailer.get(PdfName.ROOT)).getNumber(); if (append) { int keys[] = marked.getKeys(); for (int k = 0; k < keys.length; ++k) { int j = keys[k]; PdfObject obj = reader.getPdfObjectRelease(j); if (obj != null && skipInfo != j && j < initialXrefSize) { addToBody(obj, j, j != rootN); } } for (int k = initialXrefSize; k < reader.getXrefSize(); ++k) { PdfObject obj = reader.getPdfObject(k); if (obj != null) { addToBody(obj, getNewObjectNumber(reader, k, 0)); } } } else { for (int k = 1; k < reader.getXrefSize(); ++k) { PdfObject obj = reader.getPdfObjectRelease(k); if (obj != null && skipInfo != k) { addToBody(obj, getNewObjectNumber(reader, k, 0), k != rootN); } } } } finally { try { file.close(); } catch (Exception e) { // empty on purpose } } PdfIndirectReference encryption = null; PdfObject fileID = null; if (crypto != null) { if (append) { encryption = reader.getCryptoRef(); } else { PdfIndirectObject encryptionObject = addToBody(crypto.getEncryptionDictionary(), false); encryption = encryptionObject.getIndirectReference(); } fileID = crypto.getFileID(); } else fileID = PdfEncryption.createInfoId(PdfEncryption.createDocumentId()); PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.get(PdfName.ROOT); PdfIndirectReference root = new PdfIndirectReference(0, getNewObjectNumber(reader, iRoot.getNumber(), 0)); PdfIndirectReference info = null; PdfDictionary newInfo = new PdfDictionary(); if (oldInfo != null) { for (Iterator i = oldInfo.getKeys().iterator(); i.hasNext();) { PdfName key = (PdfName)i.next(); PdfObject value = PdfReader.getPdfObject(oldInfo.get(key)); newInfo.put(key, value); } } if (moreInfo != null) { for (Iterator i = moreInfo.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String key = (String) entry.getKey(); PdfName keyName = new PdfName(key); String value = (String) entry.getValue(); if (value == null) newInfo.remove(keyName); else newInfo.put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE)); } } newInfo.put(PdfName.MODDATE, date); newInfo.put(PdfName.PRODUCER, new PdfString(producer)); if (append) { if (iInfo == null) info = addToBody(newInfo, false).getIndirectReference(); else info = addToBody(newInfo, iInfo.getNumber(), false).getIndirectReference(); } else { info = addToBody(newInfo, false).getIndirectReference(); } // write the cross-reference table of the body body.writeCrossReferenceTable(os, root, info, encryption, fileID, prevxref); if (fullCompression) { os.write(getISOBytes("startxref\n")); os.write(getISOBytes(String.valueOf(body.offset()))); os.write(getISOBytes("\n%%EOF\n")); } else { PdfTrailer trailer = new PdfTrailer(body.size(), body.offset(), root, info, encryption, fileID, prevxref); trailer.toPdf(this, os); } os.flush(); if (isCloseStream()) os.close(); reader.close(); } void applyRotation(PdfDictionary pageN, ByteBuffer out) { if (!rotateContents) return; Rectangle page = reader.getPageSizeWithRotation(pageN); int rotation = page.getRotation(); switch (rotation) { case 90: out.append(PdfContents.ROTATE90); out.append(page.getTop()); out.append(' ').append('0').append(PdfContents.ROTATEFINAL); break; case 180: out.append(PdfContents.ROTATE180); out.append(page.getRight()); out.append(' '); out.append(page.getTop()); out.append(PdfContents.ROTATEFINAL); break; case 270: out.append(PdfContents.ROTATE270); out.append('0').append(' '); out.append(page.getRight()); out.append(PdfContents.ROTATEFINAL); break; } } void alterContents() throws IOException { for (Iterator i = pagesToContent.values().iterator(); i.hasNext();) { PageStamp ps = (PageStamp)i.next(); PdfDictionary pageN = ps.pageN; markUsed(pageN); PdfArray ar = null; PdfObject content = PdfReader.getPdfObject(pageN.get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } else if (content.isArray()) { ar = (PdfArray)content; markUsed(ar); } else if (content.isStream()) { ar = new PdfArray(); ar.add(pageN.get(PdfName.CONTENTS)); pageN.put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } ByteBuffer out = new ByteBuffer(); if (ps.under != null) { out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(ps.under.getInternalBuffer()); out.append(PdfContents.RESTORESTATE); } if (ps.over != null) out.append(PdfContents.SAVESTATE); PdfStream stream = new PdfStream(out.toByteArray()); stream.flateCompress(compressionLevel); ar.addFirst(addToBody(stream).getIndirectReference()); out.reset(); if (ps.over != null) { out.append(' '); out.append(PdfContents.RESTORESTATE); ByteBuffer buf = ps.over.getInternalBuffer(); out.append(buf.getBuffer(), 0, ps.replacePoint); out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(buf.getBuffer(), ps.replacePoint, buf.size() - ps.replacePoint); out.append(PdfContents.RESTORESTATE); stream = new PdfStream(out.toByteArray()); stream.flateCompress(compressionLevel); ar.add(addToBody(stream).getIndirectReference()); } alterResources(ps); } } void alterResources(PageStamp ps) { ps.pageN.put(PdfName.RESOURCES, ps.pageResources.getResources()); } protected int getNewObjectNumber(PdfReader reader, int number, int generation) { IntHashtable ref = (IntHashtable)readers2intrefs.get(reader); if (ref != null) { int n = ref.get(number); if (n == 0) { n = getIndirectReferenceNumber(); ref.put(number, n); } return n; } if (currentPdfReaderInstance == null) { if (append && number < initialXrefSize) return number; int n = myXref.get(number); if (n == 0) { n = getIndirectReferenceNumber(); myXref.put(number, n); } return n; } else return currentPdfReaderInstance.getNewObjectNumber(number, generation); } RandomAccessFileOrArray getReaderFile(PdfReader reader) { if (readers2intrefs.containsKey(reader)) { RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file.get(reader); if (raf != null) return raf; return reader.getSafeFile(); } if (currentPdfReaderInstance == null) return file; else return currentPdfReaderInstance.getReaderFile(); } /** * @param reader * @param openFile * @throws IOException */ public void registerReader(PdfReader reader, boolean openFile) throws IOException { if (readers2intrefs.containsKey(reader)) return; readers2intrefs.put(reader, new IntHashtable()); if (openFile) { RandomAccessFileOrArray raf = reader.getSafeFile(); readers2file.put(reader, raf); raf.reOpen(); } } /** * @param reader */ public void unRegisterReader(PdfReader reader) { if (!readers2intrefs.containsKey(reader)) return; readers2intrefs.remove(reader); RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file.get(reader); if (raf == null) return; readers2file.remove(reader); try{raf.close();}catch(Exception e){} } static void findAllObjects(PdfReader reader, PdfObject obj, IntHashtable hits) { if (obj == null) return; switch (obj.type()) { case PdfObject.INDIRECT: PRIndirectReference iref = (PRIndirectReference)obj; if (reader != iref.getReader()) return; if (hits.containsKey(iref.getNumber())) return; hits.put(iref.getNumber(), 1); findAllObjects(reader, PdfReader.getPdfObject(obj), hits); return; case PdfObject.ARRAY: PdfArray a = (PdfArray)obj; for (int k = 0; k < a.size(); ++k) { findAllObjects(reader, a.getPdfObject(k), hits); } return; case PdfObject.DICTIONARY: case PdfObject.STREAM: PdfDictionary dic = (PdfDictionary)obj; for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { PdfName name = (PdfName)it.next(); findAllObjects(reader, dic.get(name), hits); } return; } } /** * @param fdf * @throws IOException */ public void addComments(FdfReader fdf) throws IOException{ if (readers2intrefs.containsKey(fdf)) return; PdfDictionary catalog = fdf.getCatalog(); catalog = catalog.getAsDict(PdfName.FDF); if (catalog == null) return; PdfArray annots = catalog.getAsArray(PdfName.ANNOTS); if (annots == null || annots.size() == 0) return; registerReader(fdf, false); IntHashtable hits = new IntHashtable(); HashMap irt = new HashMap(); ArrayList an = new ArrayList(); for (int k = 0; k < annots.size(); ++k) { PdfObject obj = annots.getPdfObject(k); PdfDictionary annot = (PdfDictionary)PdfReader.getPdfObject(obj); PdfNumber page = annot.getAsNumber(PdfName.PAGE); if (page == null || page.intValue() >= reader.getNumberOfPages()) continue; findAllObjects(fdf, obj, hits); an.add(obj); if (obj.type() == PdfObject.INDIRECT) { PdfObject nm = PdfReader.getPdfObject(annot.get(PdfName.NM)); if (nm != null && nm.type() == PdfObject.STRING) irt.put(nm.toString(), obj); } } int arhits[] = hits.getKeys(); for (int k = 0; k < arhits.length; ++k) { int n = arhits[k]; PdfObject obj = fdf.getPdfObject(n); if (obj.type() == PdfObject.DICTIONARY) { PdfObject str = PdfReader.getPdfObject(((PdfDictionary)obj).get(PdfName.IRT)); if (str != null && str.type() == PdfObject.STRING) { PdfObject i = (PdfObject)irt.get(str.toString()); if (i != null) { PdfDictionary dic2 = new PdfDictionary(); dic2.merge((PdfDictionary)obj); dic2.put(PdfName.IRT, i); obj = dic2; } } } addToBody(obj, getNewObjectNumber(fdf, n, 0)); } for (int k = 0; k < an.size(); ++k) { PdfObject obj = (PdfObject)an.get(k); PdfDictionary annot = (PdfDictionary)PdfReader.getPdfObject(obj); PdfNumber page = annot.getAsNumber(PdfName.PAGE); PdfDictionary dic = reader.getPageN(page.intValue() + 1); PdfArray annotsp = (PdfArray)PdfReader.getPdfObject(dic.get(PdfName.ANNOTS), dic); if (annotsp == null) { annotsp = new PdfArray(); dic.put(PdfName.ANNOTS, annotsp); markUsed(dic); } markUsed(annotsp); annotsp.add(obj); } } PageStamp getPageStamp(int pageNum) { PdfDictionary pageN = reader.getPageN(pageNum); PageStamp ps = (PageStamp)pagesToContent.get(pageN); if (ps == null) { ps = new PageStamp(this, reader, pageN); pagesToContent.put(pageN, ps); } return ps; } PdfContentByte getUnderContent(int pageNum) { if (pageNum < 1 || pageNum > reader.getNumberOfPages()) return null; PageStamp ps = getPageStamp(pageNum); if (ps.under == null) ps.under = new StampContent(this, ps); return ps.under; } PdfContentByte getOverContent(int pageNum) { if (pageNum < 1 || pageNum > reader.getNumberOfPages()) return null; PageStamp ps = getPageStamp(pageNum); if (ps.over == null) ps.over = new StampContent(this, ps); return ps.over; } void correctAcroFieldPages(int page) { if (acroFields == null) return; if (page > reader.getNumberOfPages()) return; HashMap fields = acroFields.getFields(); for (Iterator it = fields.values().iterator(); it.hasNext();) { AcroFields.Item item = (AcroFields.Item)it.next(); for (int k = 0; k < item.size(); ++k) { int p = item.getPage(k).intValue(); if (p >= page) item.forcePage(k, p + 1); } } } private static void moveRectangle(PdfDictionary dic2, PdfReader r, int pageImported, PdfName key, String name) { Rectangle m = r.getBoxSize(pageImported, name); if (m == null) dic2.remove(key); else dic2.put(key, new PdfRectangle(m)); } void replacePage(PdfReader r, int pageImported, int pageReplaced) { PdfDictionary pageN = reader.getPageN(pageReplaced); if (pagesToContent.containsKey(pageN)) throw new IllegalStateException("This page cannot be replaced: new content was already added"); PdfImportedPage p = getImportedPage(r, pageImported); PdfDictionary dic2 = reader.getPageNRelease(pageReplaced); dic2.remove(PdfName.RESOURCES); dic2.remove(PdfName.CONTENTS); moveRectangle(dic2, r, pageImported, PdfName.MEDIABOX, "media"); moveRectangle(dic2, r, pageImported, PdfName.CROPBOX, "crop"); moveRectangle(dic2, r, pageImported, PdfName.TRIMBOX, "trim"); moveRectangle(dic2, r, pageImported, PdfName.ARTBOX, "art"); moveRectangle(dic2, r, pageImported, PdfName.BLEEDBOX, "bleed"); dic2.put(PdfName.ROTATE, new PdfNumber(r.getPageRotation(pageImported))); PdfContentByte cb = getOverContent(pageReplaced); cb.addTemplate(p, 0, 0); PageStamp ps = (PageStamp)pagesToContent.get(pageN); ps.replacePoint = ps.over.getInternalBuffer().size(); } void insertPage(int pageNumber, Rectangle mediabox) { Rectangle media = new Rectangle(mediabox); int rotation = media.getRotation() % 360; PdfDictionary page = new PdfDictionary(PdfName.PAGE); PdfDictionary resources = new PdfDictionary(); PdfArray procset = new PdfArray(); procset.add(PdfName.PDF); procset.add(PdfName.TEXT); procset.add(PdfName.IMAGEB); procset.add(PdfName.IMAGEC); procset.add(PdfName.IMAGEI); resources.put(PdfName.PROCSET, procset); page.put(PdfName.RESOURCES, resources); page.put(PdfName.ROTATE, new PdfNumber(rotation)); page.put(PdfName.MEDIABOX, new PdfRectangle(media, rotation)); PRIndirectReference pref = reader.addPdfObject(page); PdfDictionary parent; PRIndirectReference parentRef; if (pageNumber > reader.getNumberOfPages()) { PdfDictionary lastPage = reader.getPageNRelease(reader.getNumberOfPages()); parentRef = (PRIndirectReference)lastPage.get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.getNumber()); parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.getPdfObject(parent.get(PdfName.KIDS), parent); kids.add(pref); markUsed(kids); reader.pageRefs.insertPage(pageNumber, pref); } else { if (pageNumber < 1) pageNumber = 1; PdfDictionary firstPage = reader.getPageN(pageNumber); PRIndirectReference firstPageRef = reader.getPageOrigRef(pageNumber); reader.releasePage(pageNumber); parentRef = (PRIndirectReference)firstPage.get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.getNumber()); parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.getPdfObject(parent.get(PdfName.KIDS), parent); int len = kids.size(); int num = firstPageRef.getNumber(); for (int k = 0; k < len; ++k) { PRIndirectReference cur = (PRIndirectReference)kids.getPdfObject(k); if (num == cur.getNumber()) { kids.add(k, pref); break; } } if (len == kids.size()) throw new RuntimeException("Internal inconsistence."); markUsed(kids); reader.pageRefs.insertPage(pageNumber, pref); correctAcroFieldPages(pageNumber); } page.put(PdfName.PARENT, parentRef); while (parent != null) { markUsed(parent); PdfNumber count = (PdfNumber)PdfReader.getPdfObjectRelease(parent.get(PdfName.COUNT)); parent.put(PdfName.COUNT, new PdfNumber(count.intValue() + 1)); parent = parent.getAsDict(PdfName.PARENT); } } /** Getter for property rotateContents. * @return Value of property rotateContents. * */ boolean isRotateContents() { return this.rotateContents; } /** Setter for property rotateContents. * @param rotateContents New value of property rotateContents. * */ void setRotateContents(boolean rotateContents) { this.rotateContents = rotateContents; } boolean isContentWritten() { return body.size() > 1; } AcroFields getAcroFields() { if (acroFields == null) { acroFields = new AcroFields(reader, this); } return acroFields; } void setFormFlattening(boolean flat) { this.flat = flat; } void setFreeTextFlattening(boolean flat) { this.flatFreeText = flat; } boolean partialFormFlattening(String name) { getAcroFields(); if (acroFields.getXfa().isXfaPresent()) throw new UnsupportedOperationException("Partial form flattening is not supported with XFA forms."); if (!acroFields.getFields().containsKey(name)) return false; partialFlattening.add(name); return true; } void flatFields() { if (append) throw new IllegalArgumentException("Field flattening is not supported in append mode."); getAcroFields(); HashMap fields = acroFields.getFields(); if (fieldsAdded && partialFlattening.isEmpty()) { for (Iterator i = fields.keySet().iterator(); i.hasNext();) { partialFlattening.add(i.next()); } } PdfDictionary acroForm = reader.getCatalog().getAsDict(PdfName.ACROFORM); PdfArray acroFds = null; if (acroForm != null) { acroFds = (PdfArray)PdfReader.getPdfObject(acroForm.get(PdfName.FIELDS), acroForm); } for (Iterator i = fields.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String name = (String) entry.getKey(); if (!partialFlattening.isEmpty() && !partialFlattening.contains(name)) continue; AcroFields.Item item = (AcroFields.Item) entry.getValue(); for (int k = 0; k < item.size(); ++k) { PdfDictionary merged = item.getMerged(k); PdfNumber ff = merged.getAsNumber(PdfName.F); int flags = 0; if (ff != null) flags = ff.intValue(); int page = item.getPage(k).intValue(); PdfDictionary appDic = merged.getAsDict(PdfName.AP); if (appDic != null && (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) { PdfObject obj = appDic.get(PdfName.N); PdfAppearance app = null; if (obj != null) { PdfObject objReal = PdfReader.getPdfObject(obj); if (obj instanceof PdfIndirectReference && !obj.isIndirect()) app = new PdfAppearance((PdfIndirectReference)obj); else if (objReal instanceof PdfStream) { ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); app = new PdfAppearance((PdfIndirectReference)obj); } else { if (objReal != null && objReal.isDictionary()) { PdfName as = merged.getAsName(PdfName.AS); if (as != null) { PdfIndirectReference iref = (PdfIndirectReference)((PdfDictionary)objReal).get(as); if (iref != null) { app = new PdfAppearance(iref); if (iref.isIndirect()) { objReal = PdfReader.getPdfObject(iref); ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); } } } } } } if (app != null) { Rectangle box = PdfReader.getNormalizedRectangle(merged.getAsArray(PdfName.RECT)); PdfContentByte cb = getOverContent(page); cb.setLiteral("Q "); cb.addTemplate(app, box.getLeft(), box.getBottom()); cb.setLiteral("q "); } } if (partialFlattening.isEmpty()) continue; PdfDictionary pageDic = reader.getPageN(page); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots == null) continue; for (int idx = 0; idx < annots.size(); ++idx) { PdfObject ran = annots.getPdfObject(idx); if (!ran.isIndirect()) continue; PdfObject ran2 = item.getWidgetRef(k); if (!ran2.isIndirect()) continue; if (((PRIndirectReference)ran).getNumber() == ((PRIndirectReference)ran2).getNumber()) { annots.remove(idx--); PRIndirectReference wdref = (PRIndirectReference)ran2; while (true) { PdfDictionary wd = (PdfDictionary)PdfReader.getPdfObject(wdref); PRIndirectReference parentRef = (PRIndirectReference)wd.get(PdfName.PARENT); PdfReader.killIndirect(wdref); if (parentRef == null) { // reached AcroForm for (int fr = 0; fr < acroFds.size(); ++fr) { PdfObject h = acroFds.getPdfObject(fr); if (h.isIndirect() && ((PRIndirectReference)h).getNumber() == wdref.getNumber()) { acroFds.remove(fr); --fr; } } break; } PdfDictionary parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); PdfArray kids = parent.getAsArray(PdfName.KIDS); for (int fr = 0; fr < kids.size(); ++fr) { PdfObject h = kids.getPdfObject(fr); if (h.isIndirect() && ((PRIndirectReference)h).getNumber() == wdref.getNumber()) { kids.remove(fr); --fr; } } if (!kids.isEmpty()) break; wdref = parentRef; } } } if (annots.isEmpty()) { PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); pageDic.remove(PdfName.ANNOTS); } } } if (!fieldsAdded && partialFlattening.isEmpty()) { for (int page = 1; page <= reader.getNumberOfPages(); ++page) { PdfDictionary pageDic = reader.getPageN(page); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots == null) continue; for (int idx = 0; idx < annots.size(); ++idx) { PdfObject annoto = annots.getDirectObject(idx); if ((annoto instanceof PdfIndirectReference) && !annoto.isIndirect()) continue; if (!annoto.isDictionary() || PdfName.WIDGET.equals(((PdfDictionary)annoto).get(PdfName.SUBTYPE))) { annots.remove(idx); --idx; } } if (annots.isEmpty()) { PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); pageDic.remove(PdfName.ANNOTS); } } eliminateAcroformObjects(); } } void eliminateAcroformObjects() { PdfObject acro = reader.getCatalog().get(PdfName.ACROFORM); if (acro == null) return; PdfDictionary acrodic = (PdfDictionary)PdfReader.getPdfObject(acro); reader.killXref(acrodic.get(PdfName.XFA)); acrodic.remove(PdfName.XFA); PdfObject iFields = acrodic.get(PdfName.FIELDS); if (iFields != null) { PdfDictionary kids = new PdfDictionary(); kids.put(PdfName.KIDS, iFields); sweepKids(kids); PdfReader.killIndirect(iFields); acrodic.put(PdfName.FIELDS, new PdfArray()); } // PdfReader.killIndirect(acro); // reader.getCatalog().remove(PdfName.ACROFORM); } void sweepKids(PdfObject obj) { PdfObject oo = PdfReader.killIndirect(obj); if (oo == null || !oo.isDictionary()) return; PdfDictionary dic = (PdfDictionary)oo; PdfArray kids = (PdfArray)PdfReader.killIndirect(dic.get(PdfName.KIDS)); if (kids == null) return; for (int k = 0; k < kids.size(); ++k) { sweepKids(kids.getPdfObject(k)); } } private void flatFreeTextFields() { if (append) throw new IllegalArgumentException("FreeText flattening is not supported in append mode."); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { PdfDictionary pageDic = reader.getPageN(page); PdfArray annots = pageDic.getAsArray(PdfName.ANNOTS); if (annots == null) continue; for (int idx = 0; idx < annots.size(); ++idx) { PdfObject annoto = annots.getDirectObject(idx); if ((annoto instanceof PdfIndirectReference) && !annoto.isIndirect()) continue; PdfDictionary annDic = (PdfDictionary)annoto; if (!((PdfName)annDic.get(PdfName.SUBTYPE)).equals(PdfName.FREETEXT)) continue; PdfNumber ff = annDic.getAsNumber(PdfName.F); int flags = (ff != null) ? ff.intValue() : 0; if ( (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) { PdfObject obj1 = annDic.get(PdfName.AP); if (obj1 == null) continue; PdfDictionary appDic = (obj1 instanceof PdfIndirectReference) ? (PdfDictionary) PdfReader.getPdfObject(obj1) : (PdfDictionary) obj1; PdfObject obj = appDic.get(PdfName.N); PdfAppearance app = null; PdfObject objReal = PdfReader.getPdfObject(obj); if (obj instanceof PdfIndirectReference && !obj.isIndirect()) app = new PdfAppearance((PdfIndirectReference)obj); else if (objReal instanceof PdfStream) { ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); app = new PdfAppearance((PdfIndirectReference)obj); } else { if (objReal.isDictionary()) { PdfName as_p = appDic.getAsName(PdfName.AS); if (as_p != null) { PdfIndirectReference iref = (PdfIndirectReference)((PdfDictionary)objReal).get(as_p); if (iref != null) { app = new PdfAppearance(iref); if (iref.isIndirect()) { objReal = PdfReader.getPdfObject(iref); ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); } } } } } if (app != null) { Rectangle box = PdfReader.getNormalizedRectangle(annDic.getAsArray(PdfName.RECT)); PdfContentByte cb = getOverContent(page); cb.setLiteral("Q "); cb.addTemplate(app, box.getLeft(), box.getBottom()); cb.setLiteral("q "); } } } for (int idx = 0; idx < annots.size(); ++idx) { PdfDictionary annot = annots.getAsDict(idx); if (annot != null) { if (PdfName.FREETEXT.equals(annot.get(PdfName.SUBTYPE))) { annots.remove(idx); --idx; } } } if (annots.isEmpty()) { PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); pageDic.remove(PdfName.ANNOTS); } } } /** * @see com.lowagie.text.pdf.PdfWriter#getPageReference(int) */ public PdfIndirectReference getPageReference(int page) { PdfIndirectReference ref = reader.getPageOrigRef(page); if (ref == null) throw new IllegalArgumentException("Invalid page number " + page); return ref; } /** * @see com.lowagie.text.pdf.PdfWriter#addAnnotation(com.lowagie.text.pdf.PdfAnnotation) */ public void addAnnotation(PdfAnnotation annot) { throw new RuntimeException("Unsupported in this context. Use PdfStamper.addAnnotation()"); } void addDocumentField(PdfIndirectReference ref) { PdfDictionary catalog = reader.getCatalog(); PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), catalog); if (acroForm == null) { acroForm = new PdfDictionary(); catalog.put(PdfName.ACROFORM, acroForm); markUsed(catalog); } PdfArray fields = (PdfArray)PdfReader.getPdfObject(acroForm.get(PdfName.FIELDS), acroForm); if (fields == null) { fields = new PdfArray(); acroForm.put(PdfName.FIELDS, fields); markUsed(acroForm); } if (!acroForm.contains(PdfName.DA)) { acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); markUsed(acroForm); } fields.add(ref); markUsed(fields); } void addFieldResources() throws IOException { if (fieldTemplates.isEmpty()) return; PdfDictionary catalog = reader.getCatalog(); PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), catalog); if (acroForm == null) { acroForm = new PdfDictionary(); catalog.put(PdfName.ACROFORM, acroForm); markUsed(catalog); } PdfDictionary dr = (PdfDictionary)PdfReader.getPdfObject(acroForm.get(PdfName.DR), acroForm); if (dr == null) { dr = new PdfDictionary(); acroForm.put(PdfName.DR, dr); markUsed(acroForm); } markUsed(dr); for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) { PdfTemplate template = (PdfTemplate)it.next(); PdfFormField.mergeResources(dr, (PdfDictionary)template.getResources(), this); } // if (dr.get(PdfName.ENCODING) == null) dr.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING); PdfDictionary fonts = dr.getAsDict(PdfName.FONT); if (fonts == null) { fonts = new PdfDictionary(); dr.put(PdfName.FONT, fonts); } if (!fonts.contains(PdfName.HELV)) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.BASEFONT, PdfName.HELVETICA); dic.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING); dic.put(PdfName.NAME, PdfName.HELV); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); fonts.put(PdfName.HELV, addToBody(dic).getIndirectReference()); } if (!fonts.contains(PdfName.ZADB)) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS); dic.put(PdfName.NAME, PdfName.ZADB); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); fonts.put(PdfName.ZADB, addToBody(dic).getIndirectReference()); } if (acroForm.get(PdfName.DA) == null) { acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); markUsed(acroForm); } } void expandFields(PdfFormField field, ArrayList allAnnots) { allAnnots.add(field); ArrayList kids = field.getKids(); if (kids != null) { for (int k = 0; k < kids.size(); ++k) expandFields((PdfFormField)kids.get(k), allAnnots); } } void addAnnotation(PdfAnnotation annot, PdfDictionary pageN) { try { ArrayList allAnnots = new ArrayList(); if (annot.isForm()) { fieldsAdded = true; getAcroFields(); PdfFormField field = (PdfFormField)annot; if (field.getParent() != null) return; expandFields(field, allAnnots); } else allAnnots.add(annot); for (int k = 0; k < allAnnots.size(); ++k) { annot = (PdfAnnotation)allAnnots.get(k); if (annot.getPlaceInPage() > 0) pageN = reader.getPageN(annot.getPlaceInPage()); if (annot.isForm()) { if (!annot.isUsed()) { HashMap templates = annot.getTemplates(); if (templates != null) fieldTemplates.putAll(templates); } PdfFormField field = (PdfFormField)annot; if (field.getParent() == null) addDocumentField(field.getIndirectReference()); } if (annot.isAnnotation()) { PdfObject pdfobj = PdfReader.getPdfObject(pageN.get(PdfName.ANNOTS), pageN); PdfArray annots = null; if (pdfobj == null || !pdfobj.isArray()) { annots = new PdfArray(); pageN.put(PdfName.ANNOTS, annots); markUsed(pageN); } else annots = (PdfArray)pdfobj; annots.add(annot.getIndirectReference()); markUsed(annots); if (!annot.isUsed()) { PdfRectangle rect = (PdfRectangle)annot.get(PdfName.RECT); if (rect != null && (rect.left() != 0 || rect.right() != 0 || rect.top() != 0 || rect.bottom() != 0)) { int rotation = reader.getPageRotation(pageN); Rectangle pageSize = reader.getPageSizeWithRotation(pageN); switch (rotation) { case 90: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getTop() - rect.bottom(), rect.left(), pageSize.getTop() - rect.top(), rect.right())); break; case 180: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getRight() - rect.left(), pageSize.getTop() - rect.bottom(), pageSize.getRight() - rect.right(), pageSize.getTop() - rect.top())); break; case 270: annot.put(PdfName.RECT, new PdfRectangle( rect.bottom(), pageSize.getRight() - rect.left(), rect.top(), pageSize.getRight() - rect.right())); break; } } } } if (!annot.isUsed()) { annot.setUsed(); addToBody(annot, annot.getIndirectReference()); } } } catch (IOException e) { throw new ExceptionConverter(e); } } void addAnnotation(PdfAnnotation annot, int page) { annot.setPage(page); addAnnotation(annot, reader.getPageN(page)); } private void outlineTravel(PRIndirectReference outline) { while (outline != null) { PdfDictionary outlineR = (PdfDictionary)PdfReader.getPdfObjectRelease(outline); PRIndirectReference first = (PRIndirectReference)outlineR.get(PdfName.FIRST); if (first != null) { outlineTravel(first); } PdfReader.killIndirect(outlineR.get(PdfName.DEST)); PdfReader.killIndirect(outlineR.get(PdfName.A)); PdfReader.killIndirect(outline); outline = (PRIndirectReference)outlineR.get(PdfName.NEXT); } } void deleteOutlines() { PdfDictionary catalog = reader.getCatalog(); PRIndirectReference outlines = (PRIndirectReference)catalog.get(PdfName.OUTLINES); if (outlines == null) return; outlineTravel(outlines); PdfReader.killIndirect(outlines); catalog.remove(PdfName.OUTLINES); markUsed(catalog); } void setJavaScript() throws IOException { HashMap djs = pdf.getDocumentLevelJS(); if (djs.isEmpty()) return; PdfDictionary catalog = reader.getCatalog(); PdfDictionary names = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.NAMES), catalog); if (names == null) { names = new PdfDictionary(); catalog.put(PdfName.NAMES, names); markUsed(catalog); } markUsed(names); PdfDictionary tree = PdfNameTree.writeTree(djs, this); names.put(PdfName.JAVASCRIPT, addToBody(tree).getIndirectReference()); } void addFileAttachments() throws IOException { HashMap fs = pdf.getDocumentFileAttachment(); if (fs.isEmpty()) return; PdfDictionary catalog = reader.getCatalog(); PdfDictionary names = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.NAMES), catalog); if (names == null) { names = new PdfDictionary(); catalog.put(PdfName.NAMES, names); markUsed(catalog); } markUsed(names); HashMap old = PdfNameTree.readTree((PdfDictionary)PdfReader.getPdfObjectRelease(names.get(PdfName.EMBEDDEDFILES))); for (Iterator it = fs.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String name = (String) entry.getKey(); int k = 0; String nn = name; while (old.containsKey(nn)) { ++k; nn += " " + k; } old.put(nn, entry.getValue()); } PdfDictionary tree = PdfNameTree.writeTree(old, this); names.put(PdfName.EMBEDDEDFILES, addToBody(tree).getIndirectReference()); } /** * Adds or replaces the Collection Dictionary in the Catalog. * @param collection the new collection dictionary. */ void makePackage( PdfCollection collection ) { PdfDictionary catalog = reader.getCatalog(); catalog.put( PdfName.COLLECTION, collection ); } void setOutlines() throws IOException { if (newBookmarks == null) return; deleteOutlines(); if (newBookmarks.isEmpty()) return; PdfDictionary catalog = reader.getCatalog(); boolean namedAsNames = (catalog.get(PdfName.DESTS) != null); writeOutlines(catalog, namedAsNames); markUsed(catalog); } /** * Sets the viewer preferences. * @param preferences the viewer preferences * @see PdfWriter#setViewerPreferences(int) */ public void setViewerPreferences(int preferences) { useVp = true; this.viewerPreferences.setViewerPreferences(preferences); } /** Adds a viewer preference * @param key a key for a viewer preference * @param value the value for the viewer preference * @see PdfViewerPreferences#addViewerPreference */ public void addViewerPreference(PdfName key, PdfObject value) { useVp = true; this.viewerPreferences.addViewerPreference(key, value); } /** * Set the signature flags. * @param f the flags. This flags are ORed with current ones */ public void setSigFlags(int f) { sigFlags |= f; } /** Always throws an UnsupportedOperationException. * @param actionType ignore * @param action ignore * @throws PdfException ignore * @see PdfStamper#setPageAction(PdfName, PdfAction, int) */ public void setPageAction(PdfName actionType, PdfAction action) throws PdfException { throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); } /** * Sets the open and close page additional action. * @param actionType the action type. It can be PdfWriter.PAGE_OPEN * or PdfWriter.PAGE_CLOSE * @param action the action to perform * @param page the page where the action will be applied. The first page is 1 * @throws PdfException if the action type is invalid */ void setPageAction(PdfName actionType, PdfAction action, int page) throws PdfException { if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) throw new PdfException("Invalid page additional action type: " + actionType.toString()); PdfDictionary pg = reader.getPageN(page); PdfDictionary aa = (PdfDictionary)PdfReader.getPdfObject(pg.get(PdfName.AA), pg); if (aa == null) { aa = new PdfDictionary(); pg.put(PdfName.AA, aa); markUsed(pg); } aa.put(actionType, action); markUsed(aa); } /** * Always throws an UnsupportedOperationException. * @param seconds ignore */ public void setDuration(int seconds) { throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); } /** * Always throws an UnsupportedOperationException. * @param transition ignore */ public void setTransition(PdfTransition transition) { throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); } /** * Sets the display duration for the page (for presentations) * @param seconds the number of seconds to display the page. A negative value removes the entry * @param page the page where the duration will be applied. The first page is 1 */ void setDuration(int seconds, int page) { PdfDictionary pg = reader.getPageN(page); if (seconds < 0) pg.remove(PdfName.DUR); else pg.put(PdfName.DUR, new PdfNumber(seconds)); markUsed(pg); } /** * Sets the transition for the page * @param transition the transition object. A null removes the transition * @param page the page where the transition will be applied. The first page is 1 */ void setTransition(PdfTransition transition, int page) { PdfDictionary pg = reader.getPageN(page); if (transition == null) pg.remove(PdfName.TRANS); else pg.put(PdfName.TRANS, transition.getTransitionDictionary()); markUsed(pg); } protected void markUsed(PdfObject obj) { if (append && obj != null) { PRIndirectReference ref = null; if (obj.type() == PdfObject.INDIRECT) ref = (PRIndirectReference)obj; else ref = obj.getIndRef(); if (ref != null) marked.put(ref.getNumber(), 1); } } protected void markUsed(int num) { if (append) marked.put(num, 1); } /** * Getter for property append. * @return Value of property append. */ boolean isAppend() { return append; } /** Additional-actions defining the actions to be taken in * response to various trigger events affecting the document * as a whole. The actions types allowed are: DOCUMENT_CLOSE, * WILL_SAVE, DID_SAVE, WILL_PRINT * and DID_PRINT. * * @param actionType the action type * @param action the action to execute in response to the trigger * @throws PdfException on invalid action type */ public void setAdditionalAction(PdfName actionType, PdfAction action) throws PdfException { if (!(actionType.equals(DOCUMENT_CLOSE) || actionType.equals(WILL_SAVE) || actionType.equals(DID_SAVE) || actionType.equals(WILL_PRINT) || actionType.equals(DID_PRINT))) { throw new PdfException("Invalid additional action type: " + actionType.toString()); } PdfDictionary aa = reader.getCatalog().getAsDict(PdfName.AA); if (aa == null) { if (action == null) return; aa = new PdfDictionary(); reader.getCatalog().put(PdfName.AA, aa); } markUsed(aa); if (action == null) aa.remove(actionType); else aa.put(actionType, action); } /** * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(com.lowagie.text.pdf.PdfAction) */ public void setOpenAction(PdfAction action) { openAction = action; } /** * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(java.lang.String) */ public void setOpenAction(String name) { throw new UnsupportedOperationException("Open actions by name are not supported."); } /** * @see com.lowagie.text.pdf.PdfWriter#setThumbnail(com.lowagie.text.Image) */ public void setThumbnail(com.lowagie.text.Image image) { throw new UnsupportedOperationException("Use PdfStamper.setThumbnail()."); } void setThumbnail(Image image, int page) throws PdfException, DocumentException { PdfIndirectReference thumb = getImageReference(addDirectImageSimple(image)); reader.resetReleasePage(); PdfDictionary dic = reader.getPageN(page); dic.put(PdfName.THUMB, thumb); reader.resetReleasePage(); } public PdfContentByte getDirectContentUnder() { throw new UnsupportedOperationException("Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()"); } public PdfContentByte getDirectContent() { throw new UnsupportedOperationException("Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()"); } /** * Reads the OCProperties dictionary from the catalog of the existing document * and fills the documentOCG, documentOCGorder and OCGRadioGroup variables in PdfWriter. * Note that the original OCProperties of the existing document can contain more information. * @since 2.1.2 */ protected void readOCProperties() { if (!documentOCG.isEmpty()) { return; } PdfDictionary dict = reader.getCatalog().getAsDict(PdfName.OCPROPERTIES); if (dict == null) { return; } PdfArray ocgs = dict.getAsArray(PdfName.OCGS); PdfIndirectReference ref; PdfLayer layer; HashMap ocgmap = new HashMap(); for (Iterator i = ocgs.listIterator(); i.hasNext(); ) { ref = (PdfIndirectReference)i.next(); layer = new PdfLayer(null); layer.setRef(ref); layer.setOnPanel(false); layer.merge((PdfDictionary)PdfReader.getPdfObject(ref)); ocgmap.put(ref.toString(), layer); } PdfDictionary d = dict.getAsDict(PdfName.D); PdfArray off = d.getAsArray(PdfName.OFF); if (off != null) { for (Iterator i = off.listIterator(); i.hasNext(); ) { ref = (PdfIndirectReference)i.next(); layer = (PdfLayer)ocgmap.get(ref.toString()); layer.setOn(false); } } PdfArray order = d.getAsArray(PdfName.ORDER); if (order != null) { addOrder(null, order, ocgmap); } documentOCG.addAll(ocgmap.values()); OCGRadioGroup = d.getAsArray(PdfName.RBGROUPS); OCGLocked = d.getAsArray(PdfName.LOCKED); if (OCGLocked == null) OCGLocked = new PdfArray(); } /** * Recursive method to reconstruct the documentOCGorder variable in the writer. * @param parent a parent PdfLayer (can be null) * @param arr an array possibly containing children for the parent PdfLayer * @param ocgmap a HashMap with indirect reference Strings as keys and PdfLayer objects as values. * @since 2.1.2 */ private void addOrder(PdfLayer parent, PdfArray arr, Map ocgmap) { PdfObject obj; PdfLayer layer; for (int i = 0; i < arr.size(); i++) { obj = arr.getPdfObject(i); if (obj.isIndirect()) { layer = (PdfLayer)ocgmap.get(obj.toString()); layer.setOnPanel(true); registerLayer(layer); if (parent != null) { parent.addChild(layer); } if (arr.size() > i + 1 && arr.getPdfObject(i + 1).isArray()) { i++; addOrder(layer, (PdfArray)arr.getPdfObject(i), ocgmap); } } else if (obj.isArray()) { PdfArray sub = (PdfArray)obj; if (sub.isEmpty()) return; obj = sub.getPdfObject(0); if (obj.isString()) { layer = new PdfLayer(obj.toString()); layer.setOnPanel(true); registerLayer(layer); if (parent != null) { parent.addChild(layer); } PdfArray array = new PdfArray(); for (Iterator j = sub.listIterator(); j.hasNext(); ) { array.add((PdfObject)j.next()); } addOrder(layer, array, ocgmap); } else { addOrder(parent, (PdfArray)obj, ocgmap); } } } } /** * Gets the PdfLayer objects in an existing document as a Map * with the names/titles of the layers as keys. * @return a Map with all the PdfLayers in the document (and the name/title of the layer as key) * @since 2.1.2 */ public Map getPdfLayers() { if (documentOCG.isEmpty()) { readOCProperties(); } HashMap map = new HashMap(); PdfLayer layer; String key; for (Iterator i = documentOCG.iterator(); i.hasNext(); ) { layer = (PdfLayer)i.next(); if (layer.getTitle() == null) { key = layer.getAsString(PdfName.NAME).toString(); } else { key = layer.getTitle(); } if (map.containsKey(key)) { int seq = 2; String tmp = key + "(" + seq + ")"; while (map.containsKey(tmp)) { seq++; tmp = key + "(" + seq + ")"; } key = tmp; } map.put(key, layer); } return map; } static class PageStamp { PdfDictionary pageN; StampContent under; StampContent over; PageResources pageResources; int replacePoint = 0; PageStamp(PdfStamperImp stamper, PdfReader reader, PdfDictionary pageN) { this.pageN = pageN; pageResources = new PageResources(); PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES); pageResources.setOriginalResources(resources, stamper.namePtr); } } } src/core/com/lowagie/text/pdf/PdfStream.java100644 0 0 32610 11154165267 16450 0ustar 0 0 /* * $Id: PdfStream.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.ExceptionConverter; /** * PdfStream is the Pdf stream object. *

* A stream, like a string, is a sequence of characters. However, an application can * read a small portion of a stream at a time, while a string must be read in its entirety. * For this reason, objects with potentially large amounts of data, such as images and * page descriptions, are represented as streams.
* A stream consists of a dictionary that describes a sequence of characters, followed by * the keyword stream, followed by zero or more lines of characters, followed by * the keyword endstream.
* All streams must be PdfIndirectObjects. The stream dictionary must be a direct * object. The keyword stream that follows the stream dictionary should be followed by * a carriage return and linefeed or just a linefeed.
* Remark: In this version only the FLATEDECODE-filter is supported.
* This object is described in the 'Portable Document Format Reference Manual version 1.7' * section 3.2.7 (page 60-63).
* * @see PdfObject * @see PdfDictionary */ public class PdfStream extends PdfDictionary { // membervariables /** * A possible compression level. * @since 2.1.3 */ public static final int DEFAULT_COMPRESSION = -1; /** * A possible compression level. * @since 2.1.3 */ public static final int NO_COMPRESSION = 0; /** * A possible compression level. * @since 2.1.3 */ public static final int BEST_SPEED = 1; /** * A possible compression level. * @since 2.1.3 */ public static final int BEST_COMPRESSION = 9; /** is the stream compressed? */ protected boolean compressed = false; /** * The level of compression. * @since 2.1.3 */ protected int compressionLevel = NO_COMPRESSION; protected ByteArrayOutputStream streamBytes = null; protected InputStream inputStream; protected PdfIndirectReference ref; protected int inputStreamLength = -1; protected PdfWriter writer; protected int rawLength; static final byte STARTSTREAM[] = DocWriter.getISOBytes("stream\n"); static final byte ENDSTREAM[] = DocWriter.getISOBytes("\nendstream"); static final int SIZESTREAM = STARTSTREAM.length + ENDSTREAM.length; // constructors /** * Constructs a PdfStream-object. * * @param bytes content of the new PdfObject as an array of byte. */ public PdfStream(byte[] bytes) { super(); type = STREAM; this.bytes = bytes; rawLength = bytes.length; put(PdfName.LENGTH, new PdfNumber(bytes.length)); } /** * Creates an efficient stream. No temporary array is ever created. The InputStream * is totally consumed but is not closed. The general usage is: *

*

     * InputStream in = ...;
     * PdfStream stream = new PdfStream(in, writer);
     * stream.flateCompress();
     * writer.addToBody(stream);
     * stream.writeLength();
     * in.close();
     * 
* @param inputStream the data to write to this stream * @param writer the PdfWriter for this stream */ public PdfStream(InputStream inputStream, PdfWriter writer) { super(); type = STREAM; this.inputStream = inputStream; this.writer = writer; ref = writer.getPdfIndirectReference(); put(PdfName.LENGTH, ref); } /** * Constructs a PdfStream-object. */ protected PdfStream() { super(); type = STREAM; } /** * Writes the stream length to the PdfWriter. *

* This method must be called and can only be called if the constructor {@link #PdfStream(InputStream,PdfWriter)} * is used to create the stream. * @throws IOException on error * @see #PdfStream(InputStream,PdfWriter) */ public void writeLength() throws IOException { if (inputStream == null) throw new UnsupportedOperationException("writeLength() can only be called in a contructed PdfStream(InputStream,PdfWriter)."); if (inputStreamLength == -1) throw new IOException("writeLength() can only be called after output of the stream body."); writer.addToBody(new PdfNumber(inputStreamLength), ref, false); } /** * Gets the raw length of the stream. * @return the raw length of the stream */ public int getRawLength() { return rawLength; } /** * Compresses the stream. */ public void flateCompress() { flateCompress(DEFAULT_COMPRESSION); } /** * Compresses the stream. * @param compressionLevel the compression level (0 = best speed, 9 = best compression, -1 is default) * @since 2.1.3 */ public void flateCompress(int compressionLevel) { if (!Document.compress) return; // check if the flateCompress-method has already been if (compressed) { return; } this.compressionLevel = compressionLevel; if (inputStream != null) { compressed = true; return; } // check if a filter already exists PdfObject filter = PdfReader.getPdfObject(get(PdfName.FILTER)); if (filter != null) { if (filter.isName()) { if (PdfName.FLATEDECODE.equals(filter)) return; } else if (filter.isArray()) { if (((PdfArray) filter).contains(PdfName.FLATEDECODE)) return; } else { throw new RuntimeException("Stream could not be compressed: filter is not a name or array."); } } try { // compress ByteArrayOutputStream stream = new ByteArrayOutputStream(); Deflater deflater = new Deflater(compressionLevel); DeflaterOutputStream zip = new DeflaterOutputStream(stream, deflater); if (streamBytes != null) streamBytes.writeTo(zip); else zip.write(bytes); zip.close(); deflater.end(); // update the object streamBytes = stream; bytes = null; put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); if (filter == null) { put(PdfName.FILTER, PdfName.FLATEDECODE); } else { PdfArray filters = new PdfArray(filter); filters.add(PdfName.FLATEDECODE); put(PdfName.FILTER, filters); } compressed = true; } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } // public int getStreamLength(PdfWriter writer) { // if (dicBytes == null) // toPdf(writer); // if (streamBytes != null) // return streamBytes.size() + dicBytes.length + SIZESTREAM; // else // return bytes.length + dicBytes.length + SIZESTREAM; // } protected void superToPdf(PdfWriter writer, OutputStream os) throws IOException { super.toPdf(writer, os); } /** * @see com.lowagie.text.pdf.PdfDictionary#toPdf(com.lowagie.text.pdf.PdfWriter, java.io.OutputStream) */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { if (inputStream != null && compressed) put(PdfName.FILTER, PdfName.FLATEDECODE); PdfEncryption crypto = null; if (writer != null) crypto = writer.getEncryption(); if (crypto != null) { PdfObject filter = get(PdfName.FILTER); if (filter != null) { if (PdfName.CRYPT.equals(filter)) crypto = null; else if (filter.isArray()) { PdfArray a = (PdfArray)filter; if (!a.isEmpty() && PdfName.CRYPT.equals(a.getPdfObject(0))) crypto = null; } } } PdfObject nn = get(PdfName.LENGTH); if (crypto != null && nn != null && nn.isNumber()) { int sz = ((PdfNumber)nn).intValue(); put(PdfName.LENGTH, new PdfNumber(crypto.calculateStreamSize(sz))); superToPdf(writer, os); put(PdfName.LENGTH, nn); } else superToPdf(writer, os); os.write(STARTSTREAM); if (inputStream != null) { rawLength = 0; DeflaterOutputStream def = null; OutputStreamCounter osc = new OutputStreamCounter(os); OutputStreamEncryption ose = null; OutputStream fout = osc; if (crypto != null && !crypto.isEmbeddedFilesOnly()) fout = ose = crypto.getEncryptionStream(fout); Deflater deflater = null; if (compressed) { deflater = new Deflater(compressionLevel); fout = def = new DeflaterOutputStream(fout, deflater, 0x8000); } byte buf[] = new byte[4192]; while (true) { int n = inputStream.read(buf); if (n <= 0) break; fout.write(buf, 0, n); rawLength += n; } if (def != null) { def.finish(); deflater.end(); } if (ose != null) ose.finish(); inputStreamLength = osc.getCounter(); } else { if (crypto != null && !crypto.isEmbeddedFilesOnly()) { byte b[]; if (streamBytes != null) { b = crypto.encryptByteArray(streamBytes.toByteArray()); } else { b = crypto.encryptByteArray(bytes); } os.write(b); } else { if (streamBytes != null) streamBytes.writeTo(os); else os.write(bytes); } } os.write(ENDSTREAM); } /** * Writes the data content to an OutputStream. * @param os the destination to write to * @throws IOException on error */ public void writeContent(OutputStream os) throws IOException { if (streamBytes != null) streamBytes.writeTo(os); else if (bytes != null) os.write(bytes); } /** * @see com.lowagie.text.pdf.PdfObject#toString() */ public String toString() { if (get(PdfName.TYPE) == null) return "Stream"; return "Stream of type: " + get(PdfName.TYPE); } } src/core/com/lowagie/text/pdf/PdfString.java100644 0 0 20267 11154234212 16453 0ustar 0 0 /* * $Id: PdfString.java 3759 2009-03-06 16:05:00Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.io.OutputStream; /** * A PdfString-class is the PDF-equivalent of a * JAVA-String-object. *

* A string is a sequence of characters delimited by parenthesis. * If a string is too long to be conveniently placed on a single line, it may * be split across multiple lines by using the backslash character (\) at the * end of a line to indicate that the string continues on the following line. * Within a string, the backslash character is used as an escape to specify * unbalanced parenthesis, non-printing ASCII characters, and the backslash * character itself. Use of the \ddd escape sequence is the preferred * way to represent characters outside the printable ASCII character set.
* This object is described in the 'Portable Document Format Reference Manual * version 1.7' section 3.2.3 (page 53-56). * * @see PdfObject * @see BadPdfFormatException */ public class PdfString extends PdfObject { // CLASS VARIABLES /** The value of this object. */ protected String value = NOTHING; protected String originalValue = null; /** The encoding. */ protected String encoding = TEXT_PDFDOCENCODING; protected int objNum = 0; protected int objGen = 0; protected boolean hexWriting = false; // CONSTRUCTORS /** * Constructs an empty PdfString-object. */ public PdfString() { super(STRING); } /** * Constructs a PdfString-object containing a string in the * standard encoding TEXT_PDFDOCENCODING. * * @param value the content of the string */ public PdfString(String value) { super(STRING); this.value = value; } /** * Constructs a PdfString-object containing a string in the * specified encoding. * * @param value the content of the string * @param encoding an encoding */ public PdfString(String value, String encoding) { super(STRING); this.value = value; this.encoding = encoding; } /** * Constructs a PdfString-object. * * @param bytes an array of byte */ public PdfString(byte[] bytes) { super(STRING); value = PdfEncodings.convertToString(bytes, null); encoding = NOTHING; } // methods overriding some methods in PdfObject /** * Writes the PDF representation of this PdfString as an array * of byte to the specified OutputStream. * * @param writer for backwards compatibility * @param os The OutputStream to write the bytes to. */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { byte b[] = getBytes(); PdfEncryption crypto = null; if (writer != null) crypto = writer.getEncryption(); if (crypto != null && !crypto.isEmbeddedFilesOnly()) b = crypto.encryptByteArray(b); if (hexWriting) { ByteBuffer buf = new ByteBuffer(); buf.append('<'); int len = b.length; for (int k = 0; k < len; ++k) buf.appendHex(b[k]); buf.append('>'); os.write(buf.toByteArray()); } else os.write(PdfContentByte.escapeString(b)); } /** * Returns the String value of this PdfString-object. * * @return A String */ public String toString() { return value; } public byte[] getBytes() { if (bytes == null) { if (encoding != null && encoding.equals(TEXT_UNICODE) && PdfEncodings.isPdfDocEncoding(value)) bytes = PdfEncodings.convertToBytes(value, TEXT_PDFDOCENCODING); else bytes = PdfEncodings.convertToBytes(value, encoding); } return bytes; } // other methods /** * Returns the Unicode String value of this * PdfString-object. * * @return A String */ public String toUnicodeString() { if (encoding != null && encoding.length() != 0) return value; getBytes(); if (bytes.length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255) return PdfEncodings.convertToString(bytes, PdfObject.TEXT_UNICODE); else return PdfEncodings.convertToString(bytes, PdfObject.TEXT_PDFDOCENCODING); } /** * Gets the encoding of this string. * * @return a String */ public String getEncoding() { return encoding; } void setObjNum(int objNum, int objGen) { this.objNum = objNum; this.objGen = objGen; } /** * Decrypt an encrypted PdfString */ void decrypt(PdfReader reader) { PdfEncryption decrypt = reader.getDecrypt(); if (decrypt != null) { originalValue = value; decrypt.setHashKey(objNum, objGen); bytes = PdfEncodings.convertToBytes(value, null); bytes = decrypt.decryptByteArray(bytes); value = PdfEncodings.convertToString(bytes, null); } } public byte[] getOriginalBytes() { if (originalValue == null) return getBytes(); return PdfEncodings.convertToBytes(originalValue, null); } public PdfString setHexWriting(boolean hexWriting) { this.hexWriting = hexWriting; return this; } public boolean isHexWriting() { return hexWriting; } }src/core/com/lowagie/text/pdf/PdfStructureElement.java100644 0 0 12006 11213370070 20506 0ustar 0 0 /* * $Id: PdfStructureElement.java 3914 2009-04-26 09:16:47Z blowagie $ * * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * This is a node in a document logical structure. It may contain a mark point or it may contain * other nodes. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfStructureElement extends PdfDictionary { /** * Holds value of property kids. */ private PdfStructureElement parent; private PdfStructureTreeRoot top; /** * Holds value of property reference. */ private PdfIndirectReference reference; /** * Creates a new instance of PdfStructureElement. * @param parent the parent of this node * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map */ public PdfStructureElement(PdfStructureElement parent, PdfName structureType) { top = parent.top; init(parent, structureType); this.parent = parent; put(PdfName.P, parent.reference); } /** * Creates a new instance of PdfStructureElement. * @param parent the parent of this node * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map */ public PdfStructureElement(PdfStructureTreeRoot parent, PdfName structureType) { top = parent; init(parent, structureType); put(PdfName.P, parent.getReference()); } private void init(PdfDictionary parent, PdfName structureType) { PdfObject kido = parent.get(PdfName.K); PdfArray kids = null; if (kido != null && !kido.isArray()) throw new IllegalArgumentException("The parent has already another function."); if (kido == null) { kids = new PdfArray(); parent.put(PdfName.K, kids); } else kids = (PdfArray)kido; kids.add(this); put(PdfName.S, structureType); reference = top.getWriter().getPdfIndirectReference(); } /** * Gets the parent of this node. * @return the parent of this node */ public PdfDictionary getParent() { return parent; } void setPageMark(int page, int mark) { if (mark >= 0) put(PdfName.K, new PdfNumber(mark)); top.setPageMark(page, reference); } /** * Gets the reference this object will be written to. * @return the reference this object will be written to * @since 2.1.6 method removed in 2.1.5, but restored in 2.1.6 */ public PdfIndirectReference getReference() { return this.reference; } } src/core/com/lowagie/text/pdf/PdfStructureTreeRoot.java100644 0 0 13252 11213370070 20664 0ustar 0 0 /* * $Id: PdfStructureTreeRoot.java 3914 2009-04-26 09:16:47Z blowagie $ * * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; /** * The structure tree root corresponds to the highest hierarchy level in a tagged PDF. * @author Paulo Soares (psoares@consiste.pt) */ public class PdfStructureTreeRoot extends PdfDictionary { private HashMap parentTree = new HashMap(); private PdfIndirectReference reference; /** * Holds value of property writer. */ private PdfWriter writer; /** Creates a new instance of PdfStructureTreeRoot */ PdfStructureTreeRoot(PdfWriter writer) { super(PdfName.STRUCTTREEROOT); this.writer = writer; reference = writer.getPdfIndirectReference(); } /** * Maps the user tags to the standard tags. The mapping will allow a standard application to make some sense of the tagged * document whatever the user tags may be. * @param used the user tag * @param standard the standard tag */ public void mapRole(PdfName used, PdfName standard) { PdfDictionary rm = (PdfDictionary)get(PdfName.ROLEMAP); if (rm == null) { rm = new PdfDictionary(); put(PdfName.ROLEMAP, rm); } rm.put(used, standard); } /** * Gets the writer. * @return the writer */ public PdfWriter getWriter() { return this.writer; } /** * Gets the reference this object will be written to. * @return the reference this object will be written to * @since 2.1.6 method removed in 2.1.5, but restored in 2.1.6 */ public PdfIndirectReference getReference() { return this.reference; } void setPageMark(int page, PdfIndirectReference struc) { Integer i = new Integer(page); PdfArray ar = (PdfArray)parentTree.get(i); if (ar == null) { ar = new PdfArray(); parentTree.put(i, ar); } ar.add(struc); } private void nodeProcess(PdfDictionary struc, PdfIndirectReference reference) throws IOException { PdfObject obj = struc.get(PdfName.K); if (obj != null && obj.isArray() && !((PdfObject)((PdfArray)obj).getArrayList().get(0)).isNumber()) { PdfArray ar = (PdfArray)obj; ArrayList a = ar.getArrayList(); for (int k = 0; k < a.size(); ++k) { PdfStructureElement e = (PdfStructureElement)a.get(k); a.set(k, e.getReference()); nodeProcess(e, e.getReference()); } } if (reference != null) writer.addToBody(struc, reference); } void buildTree() throws IOException { HashMap numTree = new HashMap(); for (Iterator it = parentTree.keySet().iterator(); it.hasNext();) { Integer i = (Integer)it.next(); PdfArray ar = (PdfArray)parentTree.get(i); numTree.put(i, writer.addToBody(ar).getIndirectReference()); } PdfDictionary dicTree = PdfNumberTree.writeTree(numTree, writer); if (dicTree != null) put(PdfName.PARENTTREE, writer.addToBody(dicTree).getIndirectReference()); nodeProcess(this, reference); } } src/core/com/lowagie/text/pdf/PdfTable.java100644 0 0 21535 11012562273 16237 0ustar 0 0 /* * $Id: PdfTable.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Cell; import com.lowagie.text.Element; import com.lowagie.text.Rectangle; import com.lowagie.text.Row; import com.lowagie.text.Table; /** * PdfTable is an object that contains the graphics and text of a table. * * @see com.lowagie.text.Table * @see com.lowagie.text.Row * @see com.lowagie.text.Cell * @see PdfCell */ public class PdfTable extends Rectangle { // membervariables /** this is the number of columns in the table. */ private int columns; /** this is the ArrayList with all the cell of the table header. */ private ArrayList headercells; /** this is the ArrayList with all the cells in the table. */ private ArrayList cells; /** Original table used to build this object*/ protected Table table; /** Cached column widths. */ protected float[] positions; // constructors /** * Constructs a PdfTable-object. * * @param table a Table * @param left the left border on the page * @param right the right border on the page * @param top the start position of the top of the table * @since a parameter of this method has been removed in iText 2.0.8 */ PdfTable(Table table, float left, float right, float top) { // constructs a Rectangle (the bottom value will be changed afterwards) super(left, top, right, top); this.table = table; table.complete(); // copying the attributes from class Table cloneNonPositionParameters(table); this.columns = table.getColumns(); positions = table.getWidths(left, right - left); // initialization of some parameters setLeft(positions[0]); setRight(positions[positions.length - 1]); headercells = new ArrayList(); cells = new ArrayList(); updateRowAdditionsInternal(); } // methods /** * Updates the table row additions in the underlying table object and deletes all table rows, * in order to preserve memory and detect future row additions. *

Pre-requisite: the object must have been built with the parameter supportUpdateRowAdditions equals to true. */ void updateRowAdditions() { table.complete(); updateRowAdditionsInternal(); table.deleteAllRows(); } /** * Updates the table row additions in the underlying table object */ private void updateRowAdditionsInternal() { // correct table : fill empty cells/ parse table in table Row row; int prevRows = rows(); int rowNumber = 0; int groupNumber = 0; boolean groupChange; int firstDataRow = table.getLastHeaderRow() + 1; Cell cell; PdfCell currentCell; ArrayList newCells = new ArrayList(); int rows = table.size() + 1; float[] offsets = new float[rows]; for (int i = 0; i < rows; i++) { offsets[i] = getBottom(); } // loop over all the rows for (Iterator rowIterator = table.iterator(); rowIterator.hasNext(); ) { groupChange = false; row = (Row) rowIterator.next(); if (row.isEmpty()) { if (rowNumber < rows - 1 && offsets[rowNumber + 1] > offsets[rowNumber]) offsets[rowNumber + 1] = offsets[rowNumber]; } else { for(int i = 0; i < row.getColumns(); i++) { cell = (Cell) row.getCell(i); if (cell != null) { currentCell = new PdfCell(cell, rowNumber+prevRows, positions[i], positions[i + cell.getColspan()], offsets[rowNumber], cellspacing(), cellpadding()); if (rowNumber < firstDataRow) { currentCell.setHeader(); headercells.add(currentCell); if (!table.isNotAddedYet()) continue; } try { if (offsets[rowNumber] - currentCell.getHeight() - cellpadding() < offsets[rowNumber + currentCell.rowspan()]) { offsets[rowNumber + currentCell.rowspan()] = offsets[rowNumber] - currentCell.getHeight() - cellpadding(); } } catch(ArrayIndexOutOfBoundsException aioobe) { if (offsets[rowNumber] - currentCell.getHeight() < offsets[rows - 1]) { offsets[rows - 1] = offsets[rowNumber] - currentCell.getHeight(); } } currentCell.setGroupNumber(groupNumber); groupChange |= cell.getGroupChange(); newCells.add(currentCell); } } } rowNumber++; if( groupChange ) groupNumber++; } // loop over all the cells int n = newCells.size(); for (int i = 0; i < n; i++) { currentCell = (PdfCell) newCells.get(i); try { currentCell.setBottom(offsets[currentCell.rownumber()-prevRows + currentCell.rowspan()]); } catch(ArrayIndexOutOfBoundsException aioobe) { currentCell.setBottom(offsets[rows - 1]); } } cells.addAll(newCells); setBottom(offsets[rows - 1]); } /** * Get the number of rows */ int rows() { return cells.isEmpty() ? 0 : ((PdfCell)cells.get(cells.size()-1)).rownumber()+1; } /** @see com.lowagie.text.Element#type() */ public int type() { return Element.TABLE; } /** * Returns the arraylist with the cells of the table header. * * @return an ArrayList */ ArrayList getHeaderCells() { return headercells; } /** * Checks if there is a table header. * * @return an ArrayList */ boolean hasHeader() { return !headercells.isEmpty(); } /** * Returns the arraylist with the cells of the table. * * @return an ArrayList */ ArrayList getCells() { return cells; } /** * Returns the number of columns of the table. * * @return the number of columns */ int columns() { return columns; } /** * Returns the cellpadding of the table. * * @return the cellpadding */ final float cellpadding() { return table.getPadding(); } /** * Returns the cellspacing of the table. * * @return the cellspacing */ final float cellspacing() { return table.getSpacing(); } /** * Checks if this Table has to fit a page. * * @return true if the table may not be split */ public final boolean hasToFitPageTable() { return table.isTableFitsPage(); } /** * Checks if the cells of this Table have to fit a page. * * @return true if the cells may not be split */ public final boolean hasToFitPageCells() { return table.isCellsFitPage(); } /** * Gets the offset of this table. * * @return the space between this table and the previous element. */ public float getOffset() { return table.getOffset(); } } src/core/com/lowagie/text/pdf/PdfTemplate.java100644 0 0 21502 11213370070 16750 0ustar 0 0 /* * $Id: PdfTemplate.java 3929 2009-05-22 13:26:41Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import com.lowagie.text.Rectangle; /** * Implements the form XObject. */ public class PdfTemplate extends PdfContentByte { public static final int TYPE_TEMPLATE = 1; public static final int TYPE_IMPORTED = 2; public static final int TYPE_PATTERN = 3; protected int type; /** The indirect reference to this template */ protected PdfIndirectReference thisReference; /** The resources used by this template */ protected PageResources pageResources; /** The bounding box of this template */ protected Rectangle bBox = new Rectangle(0, 0); protected PdfArray matrix; protected PdfTransparencyGroup group; protected PdfOCG layer; /** *Creates a PdfTemplate. */ protected PdfTemplate() { super(null); type = TYPE_TEMPLATE; } /** * Creates new PdfTemplate * * @param wr the PdfWriter */ PdfTemplate(PdfWriter wr) { super(wr); type = TYPE_TEMPLATE; pageResources = new PageResources(); pageResources.addDefaultColor(wr.getDefaultColorspace()); thisReference = writer.getPdfIndirectReference(); } /** * Creates a new template. *

* Creates a new template that is nothing more than a form XObject. This template can be included * in this template or in another template. Templates are only written * to the output when the document is closed permitting things like showing text in the first page * that is only defined in the last page. * * @param writer the PdfWriter to use * @param width the bounding box width * @param height the bounding box height * @return the created template */ public static PdfTemplate createTemplate(PdfWriter writer, float width, float height) { return createTemplate(writer, width, height, null); } static PdfTemplate createTemplate(PdfWriter writer, float width, float height, PdfName forcedName) { PdfTemplate template = new PdfTemplate(writer); template.setWidth(width); template.setHeight(height); writer.addDirectTemplateSimple(template, forcedName); return template; } /** * Sets the bounding width of this template. * * @param width the bounding width */ public void setWidth(float width) { bBox.setLeft(0); bBox.setRight(width); } /** * Sets the bounding height of this template. * * @param height the bounding height */ public void setHeight(float height) { bBox.setBottom(0); bBox.setTop(height); } /** * Gets the bounding width of this template. * * @return width the bounding width */ public float getWidth() { return bBox.getWidth(); } /** * Gets the bounding height of this template. * * @return height the bounding height */ public float getHeight() { return bBox.getHeight(); } public Rectangle getBoundingBox() { return bBox; } public void setBoundingBox(Rectangle bBox) { this.bBox = bBox; } /** * Sets the layer this template belongs to. * @param layer the layer this template belongs to */ public void setLayer(PdfOCG layer) { this.layer = layer; } /** * Gets the layer this template belongs to. * @return the layer this template belongs to or null for no layer defined */ public PdfOCG getLayer() { return layer; } public void setMatrix(float a, float b, float c, float d, float e, float f) { matrix = new PdfArray(); matrix.add(new PdfNumber(a)); matrix.add(new PdfNumber(b)); matrix.add(new PdfNumber(c)); matrix.add(new PdfNumber(d)); matrix.add(new PdfNumber(e)); matrix.add(new PdfNumber(f)); } PdfArray getMatrix() { return matrix; } /** * Gets the indirect reference to this template. * * @return the indirect reference to this template */ public PdfIndirectReference getIndirectReference() { // uncomment the null check as soon as we're sure all examples still work if (thisReference == null /* && writer != null */) { thisReference = writer.getPdfIndirectReference(); } return thisReference; } public void beginVariableText() { content.append("/Tx BMC "); } public void endVariableText() { content.append("EMC "); } /** * Constructs the resources used by this template. * * @return the resources used by this template */ PdfObject getResources() { return getPageResources().getResources(); } /** * Gets the stream representing this template. * * @param compressionLevel the compressionLevel * @return the stream representing this template * @since 2.1.3 (replacing the method without param compressionLevel) */ PdfStream getFormXObject(int compressionLevel) throws IOException { return new PdfFormXObject(this, compressionLevel); } /** * Gets a duplicate of this PdfTemplate. All * the members are copied by reference but the buffer stays different. * @return a copy of this PdfTemplate */ public PdfContentByte getDuplicate() { PdfTemplate tpl = new PdfTemplate(); tpl.writer = writer; tpl.pdf = pdf; tpl.thisReference = thisReference; tpl.pageResources = pageResources; tpl.bBox = new Rectangle(bBox); tpl.group = group; tpl.layer = layer; if (matrix != null) { tpl.matrix = new PdfArray(matrix); } tpl.separator = separator; return tpl; } public int getType() { return type; } PageResources getPageResources() { return pageResources; } /** Getter for property group. * @return Value of property group. * */ public PdfTransparencyGroup getGroup() { return this.group; } /** Setter for property group. * @param group New value of property group. * */ public void setGroup(PdfTransparencyGroup group) { this.group = group; } }src/core/com/lowagie/text/pdf/PdfTextArray.java100644 0 0 11670 11013321346 17125 0ustar 0 0 /* * $Id: PdfTextArray.java 3382 2008-05-15 10:18:45Z psoares33 $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.ArrayList; /** * PdfTextArray defines an array with displacements and PdfString-objects. *

* A TextArray is used with the operator TJ in PdfText. * The first object in this array has to be a PdfString; * see reference manual version 1.3 section 8.7.5, pages 346-347. * OR * see reference manual version 1.6 section 5.3.2, pages 378-379. */ public class PdfTextArray{ ArrayList arrayList = new ArrayList(); // To emit a more efficient array, we consolidate // repeated numbers or strings into single array entries. // "add( 50 ); add( -50 );" will REMOVE the combined zero from the array. // the alternative (leaving a zero in there) was Just Weird. // --Mark Storer, May 12, 2008 private String lastStr; private Float lastNum; // constructors public PdfTextArray(String str) { add(str); } public PdfTextArray() { } /** * Adds a PdfNumber to the PdfArray. * * @param number displacement of the string */ public void add(PdfNumber number) { add((float) number.doubleValue()); } public void add(float number) { if (number != 0) { if (lastNum != null) { lastNum = new Float(number + lastNum.floatValue()); if (lastNum.floatValue() != 0) { replaceLast(lastNum); } else { arrayList.remove(arrayList.size() - 1); } } else { lastNum = new Float(number); arrayList.add(lastNum); } lastStr = null; } // adding zero doesn't modify the TextArray at all } public void add(String str) { if (str.length() > 0) { if (lastStr != null) { lastStr = lastStr + str; replaceLast(lastStr); } else { lastStr = str; arrayList.add(lastStr); } lastNum = null; } // adding an empty string doesn't modify the TextArray at all } ArrayList getArrayList() { return arrayList; } private void replaceLast(Object obj) { // deliberately throw the IndexOutOfBoundsException if we screw up. arrayList.set(arrayList.size() - 1, obj); } } src/core/com/lowagie/text/pdf/PdfTransition.java100644 0 0 20622 11000354131 17323 0ustar 0 0 /* * Copyright 2002 by Josselin PUJO. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; public class PdfTransition { /** * Out Vertical Split */ public static final int SPLITVOUT = 1; /** * Out Horizontal Split */ public static final int SPLITHOUT = 2; /** * In Vertical Split */ public static final int SPLITVIN = 3; /** * IN Horizontal Split */ public static final int SPLITHIN = 4; /** * Vertical Blinds */ public static final int BLINDV = 5; /** * Vertical Blinds */ public static final int BLINDH = 6; /** * Inward Box */ public static final int INBOX = 7; /** * Outward Box */ public static final int OUTBOX = 8; /** * Left-Right Wipe */ public static final int LRWIPE = 9; /** * Right-Left Wipe */ public static final int RLWIPE = 10; /** * Bottom-Top Wipe */ public static final int BTWIPE = 11; /** * Top-Bottom Wipe */ public static final int TBWIPE = 12; /** * Dissolve */ public static final int DISSOLVE = 13; /** * Left-Right Glitter */ public static final int LRGLITTER = 14; /** * Top-Bottom Glitter */ public static final int TBGLITTER = 15; /** * Diagonal Glitter */ public static final int DGLITTER = 16; /** * duration of the transition effect */ protected int duration; /** * type of the transition effect */ protected int type; /** * Constructs a Transition. * */ public PdfTransition() { this(BLINDH); } /** * Constructs a Transition. * *@param type type of the transition effect */ public PdfTransition(int type) { this(type,1); } /** * Constructs a Transition. * *@param type type of the transition effect *@param duration duration of the transition effect */ public PdfTransition(int type, int duration) { this.duration = duration; this.type = type; } public int getDuration() { return duration; } public int getType() { return type; } public PdfDictionary getTransitionDictionary() { PdfDictionary trans = new PdfDictionary(PdfName.TRANS); switch (type) { case SPLITVOUT: trans.put(PdfName.S,PdfName.SPLIT); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.V); trans.put(PdfName.M,PdfName.O); break; case SPLITHOUT: trans.put(PdfName.S,PdfName.SPLIT); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.H); trans.put(PdfName.M,PdfName.O); break; case SPLITVIN: trans.put(PdfName.S,PdfName.SPLIT); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.V); trans.put(PdfName.M,PdfName.I); break; case SPLITHIN: trans.put(PdfName.S,PdfName.SPLIT); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.H); trans.put(PdfName.M,PdfName.I); break; case BLINDV: trans.put(PdfName.S,PdfName.BLINDS); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.V); break; case BLINDH: trans.put(PdfName.S,PdfName.BLINDS); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DM,PdfName.H); break; case INBOX: trans.put(PdfName.S,PdfName.BOX); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.M,PdfName.I); break; case OUTBOX: trans.put(PdfName.S,PdfName.BOX); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.M,PdfName.O); break; case LRWIPE: trans.put(PdfName.S,PdfName.WIPE); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(0)); break; case RLWIPE: trans.put(PdfName.S,PdfName.WIPE); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(180)); break; case BTWIPE: trans.put(PdfName.S,PdfName.WIPE); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(90)); break; case TBWIPE: trans.put(PdfName.S,PdfName.WIPE); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(270)); break; case DISSOLVE: trans.put(PdfName.S,PdfName.DISSOLVE); trans.put(PdfName.D,new PdfNumber(duration)); break; case LRGLITTER: trans.put(PdfName.S,PdfName.GLITTER); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(0)); break; case TBGLITTER: trans.put(PdfName.S,PdfName.GLITTER); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(270)); break; case DGLITTER: trans.put(PdfName.S,PdfName.GLITTER); trans.put(PdfName.D,new PdfNumber(duration)); trans.put(PdfName.DI,new PdfNumber(315)); break; } return trans; } } src/core/com/lowagie/text/pdf/PdfTransparencyGroup.java100644 0 0 6520 11000354131 20640 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** The transparency group dictionary. * * @author Paulo Soares (psoares@consiste.pt) */ public class PdfTransparencyGroup extends PdfDictionary { /** * Constructs a transparencyGroup. */ public PdfTransparencyGroup() { super(); put(PdfName.S, PdfName.TRANSPARENCY); } /** * Determining the initial backdrop against which its stack is composited. * @param isolated */ public void setIsolated(boolean isolated) { if (isolated) put(PdfName.I, PdfBoolean.PDFTRUE); else remove(PdfName.I); } /** * Determining whether the objects within the stack are composited with one another or only with the group's backdrop. * @param knockout */ public void setKnockout(boolean knockout) { if (knockout) put(PdfName.K, PdfBoolean.PDFTRUE); else remove(PdfName.K); } } src/core/com/lowagie/text/pdf/PdfWriter.java100644 0 0 352651 11213370070 16505 0ustar 0 0 /* * $Id: PdfWriter.java 3948 2009-06-03 15:17:22Z blowagie $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.awt.color.ICC_Profile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; import java.security.cert.Certificate; import com.lowagie.text.DocListener; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgJBIG2; import com.lowagie.text.ImgWMF; import com.lowagie.text.Rectangle; import com.lowagie.text.Table; import com.lowagie.text.pdf.collection.PdfCollection; import com.lowagie.text.pdf.events.PdfPageEventForwarder; import com.lowagie.text.pdf.interfaces.PdfAnnotations; import com.lowagie.text.pdf.interfaces.PdfDocumentActions; import com.lowagie.text.pdf.interfaces.PdfEncryptionSettings; import com.lowagie.text.pdf.interfaces.PdfPageActions; import com.lowagie.text.pdf.interfaces.PdfVersion; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; import com.lowagie.text.pdf.interfaces.PdfXConformance; import com.lowagie.text.pdf.interfaces.PdfRunDirection; import com.lowagie.text.pdf.internal.PdfVersionImp; import com.lowagie.text.pdf.internal.PdfXConformanceImp; import com.lowagie.text.xml.xmp.XmpWriter; /** * A DocWriter class for PDF. *

* When this PdfWriter is added * to a certain PdfDocument, the PDF representation of every Element * added to this Document will be written to the outputstream.

*/ public class PdfWriter extends DocWriter implements PdfViewerPreferences, PdfEncryptionSettings, PdfVersion, PdfDocumentActions, PdfPageActions, PdfXConformance, PdfRunDirection, PdfAnnotations { /** * The highest generation number possible. * @since iText 2.1.6 */ public static final int GENERATION_MAX = 65535; // INNER CLASSES /** * This class generates the structure of a PDF document. *

* This class covers the third section of Chapter 5 in the 'Portable Document Format * Reference Manual version 1.3' (page 55-60). It contains the body of a PDF document * (section 5.14) and it can also generate a Cross-reference Table (section 5.15). * * @see PdfWriter * @see PdfObject * @see PdfIndirectObject */ public static class PdfBody { // inner classes /** * PdfCrossReference is an entry in the PDF Cross-Reference table. */ static class PdfCrossReference implements Comparable { // membervariables private int type; /** Byte offset in the PDF file. */ private int offset; private int refnum; /** generation of the object. */ private int generation; // constructors /** * Constructs a cross-reference element for a PdfIndirectObject. * @param refnum * @param offset byte offset of the object * @param generation generation number of the object */ PdfCrossReference(int refnum, int offset, int generation) { type = 0; this.offset = offset; this.refnum = refnum; this.generation = generation; } /** * Constructs a cross-reference element for a PdfIndirectObject. * @param refnum * @param offset byte offset of the object */ PdfCrossReference(int refnum, int offset) { type = 1; this.offset = offset; this.refnum = refnum; this.generation = 0; } PdfCrossReference(int type, int refnum, int offset, int generation) { this.type = type; this.offset = offset; this.refnum = refnum; this.generation = generation; } int getRefnum() { return refnum; } /** * Returns the PDF representation of this PdfObject. * @param os * @throws IOException */ public void toPdf(OutputStream os) throws IOException { StringBuffer off = new StringBuffer("0000000000").append(offset); off.delete(0, off.length() - 10); StringBuffer gen = new StringBuffer("00000").append(generation); gen.delete(0, gen.length() - 5); off.append(' ').append(gen).append(generation == GENERATION_MAX ? " f \n" : " n \n"); os.write(getISOBytes(off.toString())); } /** * Writes PDF syntax to the OutputStream * @param midSize * @param os * @throws IOException */ public void toPdf(int midSize, OutputStream os) throws IOException { os.write((byte)type); while (--midSize >= 0) os.write((byte)((offset >>> (8 * midSize)) & 0xff)); os.write((byte)((generation >>> 8) & 0xff)); os.write((byte)(generation & 0xff)); } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object o) { PdfCrossReference other = (PdfCrossReference)o; return (refnum < other.refnum ? -1 : (refnum==other.refnum ? 0 : 1)); } /** * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (obj instanceof PdfCrossReference) { PdfCrossReference other = (PdfCrossReference)obj; return (refnum == other.refnum); } else return false; } /** * @see java.lang.Object#hashCode() */ public int hashCode() { return refnum; } } private static final int OBJSINSTREAM = 200; // membervariables /** array containing the cross-reference table of the normal objects. */ private TreeSet xrefs; private int refnum; /** the current byte position in the body. */ private int position; private PdfWriter writer; private ByteBuffer index; private ByteBuffer streamObjects; private int currentObjNum; private int numObj = 0; // constructors /** * Constructs a new PdfBody. * @param writer */ PdfBody(PdfWriter writer) { xrefs = new TreeSet(); xrefs.add(new PdfCrossReference(0, 0, GENERATION_MAX)); position = writer.getOs().getCounter(); refnum = 1; this.writer = writer; } // methods void setRefnum(int refnum) { this.refnum = refnum; } private PdfWriter.PdfBody.PdfCrossReference addToObjStm(PdfObject obj, int nObj) throws IOException { if (numObj >= OBJSINSTREAM) flushObjStm(); if (index == null) { index = new ByteBuffer(); streamObjects = new ByteBuffer(); currentObjNum = getIndirectReferenceNumber(); numObj = 0; } int p = streamObjects.size(); int idx = numObj++; PdfEncryption enc = writer.crypto; writer.crypto = null; obj.toPdf(writer, streamObjects); writer.crypto = enc; streamObjects.append(' '); index.append(nObj).append(' ').append(p).append(' '); return new PdfWriter.PdfBody.PdfCrossReference(2, nObj, currentObjNum, idx); } private void flushObjStm() throws IOException { if (numObj == 0) return; int first = index.size(); index.append(streamObjects); PdfStream stream = new PdfStream(index.toByteArray()); stream.flateCompress(writer.getCompressionLevel()); stream.put(PdfName.TYPE, PdfName.OBJSTM); stream.put(PdfName.N, new PdfNumber(numObj)); stream.put(PdfName.FIRST, new PdfNumber(first)); add(stream, currentObjNum); index = null; streamObjects = null; numObj = 0; } /** * Adds a PdfObject to the body. *

* This methods creates a PdfIndirectObject with a * certain number, containing the given PdfObject. * It also adds a PdfCrossReference for this object * to an ArrayList that will be used to build the * Cross-reference Table. * * @param object a PdfObject * @return a PdfIndirectObject * @throws IOException */ PdfIndirectObject add(PdfObject object) throws IOException { return add(object, getIndirectReferenceNumber()); } PdfIndirectObject add(PdfObject object, boolean inObjStm) throws IOException { return add(object, getIndirectReferenceNumber(), inObjStm); } /** * Gets a PdfIndirectReference for an object that will be created in the future. * @return a PdfIndirectReference */ PdfIndirectReference getPdfIndirectReference() { return new PdfIndirectReference(0, getIndirectReferenceNumber()); } int getIndirectReferenceNumber() { int n = refnum++; xrefs.add(new PdfCrossReference(n, 0, GENERATION_MAX)); return n; } /** * Adds a PdfObject to the body given an already existing * PdfIndirectReference. *

* This methods creates a PdfIndirectObject with the number given by * ref, containing the given PdfObject. * It also adds a PdfCrossReference for this object * to an ArrayList that will be used to build the * Cross-reference Table. * * @param object a PdfObject * @param ref a PdfIndirectReference * @return a PdfIndirectObject * @throws IOException */ PdfIndirectObject add(PdfObject object, PdfIndirectReference ref) throws IOException { return add(object, ref.getNumber()); } PdfIndirectObject add(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { return add(object, ref.getNumber(), inObjStm); } PdfIndirectObject add(PdfObject object, int refNumber) throws IOException { return add(object, refNumber, true); // to false } PdfIndirectObject add(PdfObject object, int refNumber, boolean inObjStm) throws IOException { if (inObjStm && object.canBeInObjStm() && writer.isFullCompression()) { PdfCrossReference pxref = addToObjStm(object, refNumber); PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); if (!xrefs.add(pxref)) { xrefs.remove(pxref); xrefs.add(pxref); } return indirect; } else { PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); PdfCrossReference pxref = new PdfCrossReference(refNumber, position); if (!xrefs.add(pxref)) { xrefs.remove(pxref); xrefs.add(pxref); } indirect.writeTo(writer.getOs()); position = writer.getOs().getCounter(); return indirect; } } /** * Returns the offset of the Cross-Reference table. * * @return an offset */ int offset() { return position; } /** * Returns the total number of objects contained in the CrossReferenceTable of this Body. * * @return a number of objects */ int size() { return Math.max(((PdfCrossReference)xrefs.last()).getRefnum() + 1, refnum); } /** * Returns the CrossReferenceTable of the Body. * @param os * @param root * @param info * @param encryption * @param fileID * @param prevxref * @throws IOException */ void writeCrossReferenceTable(OutputStream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) throws IOException { int refNumber = 0; if (writer.isFullCompression()) { flushObjStm(); refNumber = getIndirectReferenceNumber(); xrefs.add(new PdfCrossReference(refNumber, position)); } PdfCrossReference entry = (PdfCrossReference)xrefs.first(); int first = entry.getRefnum(); int len = 0; ArrayList sections = new ArrayList(); for (Iterator i = xrefs.iterator(); i.hasNext(); ) { entry = (PdfCrossReference)i.next(); if (first + len == entry.getRefnum()) ++len; else { sections.add(new Integer(first)); sections.add(new Integer(len)); first = entry.getRefnum(); len = 1; } } sections.add(new Integer(first)); sections.add(new Integer(len)); if (writer.isFullCompression()) { int mid = 4; int mask = 0xff000000; for (; mid > 1; --mid) { if ((mask & position) != 0) break; mask >>>= 8; } ByteBuffer buf = new ByteBuffer(); for (Iterator i = xrefs.iterator(); i.hasNext(); ) { entry = (PdfCrossReference) i.next(); entry.toPdf(mid, buf); } PdfStream xr = new PdfStream(buf.toByteArray()); buf = null; xr.flateCompress(writer.getCompressionLevel()); xr.put(PdfName.SIZE, new PdfNumber(size())); xr.put(PdfName.ROOT, root); if (info != null) { xr.put(PdfName.INFO, info); } if (encryption != null) xr.put(PdfName.ENCRYPT, encryption); if (fileID != null) xr.put(PdfName.ID, fileID); xr.put(PdfName.W, new PdfArray(new int[]{1, mid, 2})); xr.put(PdfName.TYPE, PdfName.XREF); PdfArray idx = new PdfArray(); for (int k = 0; k < sections.size(); ++k) idx.add(new PdfNumber(((Integer)sections.get(k)).intValue())); xr.put(PdfName.INDEX, idx); if (prevxref > 0) xr.put(PdfName.PREV, new PdfNumber(prevxref)); PdfEncryption enc = writer.crypto; writer.crypto = null; PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer); indirect.writeTo(writer.getOs()); writer.crypto = enc; } else { os.write(getISOBytes("xref\n")); Iterator i = xrefs.iterator(); for (int k = 0; k < sections.size(); k += 2) { first = ((Integer)sections.get(k)).intValue(); len = ((Integer)sections.get(k + 1)).intValue(); os.write(getISOBytes(String.valueOf(first))); os.write(getISOBytes(" ")); os.write(getISOBytes(String.valueOf(len))); os.write('\n'); while (len-- > 0) { entry = (PdfCrossReference) i.next(); entry.toPdf(os); } } } } } /** * PdfTrailer is the PDF Trailer object. *

* This object is described in the 'Portable Document Format Reference Manual version 1.3' * section 5.16 (page 59-60). */ static class PdfTrailer extends PdfDictionary { // membervariables int offset; // constructors /** * Constructs a PDF-Trailer. * * @param size the number of entries in the PdfCrossReferenceTable * @param offset offset of the PdfCrossReferenceTable * @param root an indirect reference to the root of the PDF document * @param info an indirect reference to the info object of the PDF document * @param encryption * @param fileID * @param prevxref */ PdfTrailer(int size, int offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) { this.offset = offset; put(PdfName.SIZE, new PdfNumber(size)); put(PdfName.ROOT, root); if (info != null) { put(PdfName.INFO, info); } if (encryption != null) put(PdfName.ENCRYPT, encryption); if (fileID != null) put(PdfName.ID, fileID); if (prevxref > 0) put(PdfName.PREV, new PdfNumber(prevxref)); } /** * Returns the PDF representation of this PdfObject. * @param writer * @param os * @throws IOException */ public void toPdf(PdfWriter writer, OutputStream os) throws IOException { os.write(getISOBytes("trailer\n")); super.toPdf(null, os); os.write(getISOBytes("\nstartxref\n")); os.write(getISOBytes(String.valueOf(offset))); os.write(getISOBytes("\n%%EOF\n")); } } // ESSENTIALS // Construct a PdfWriter instance /** * Constructs a PdfWriter. */ protected PdfWriter() { } /** * Constructs a PdfWriter. *

* Remark: a PdfWriter can only be constructed by calling the method * getInstance(Document document, OutputStream os). * * @param document The PdfDocument that has to be written * @param os The OutputStream the writer has to write to. */ protected PdfWriter(PdfDocument document, OutputStream os) { super(document, os); pdf = document; directContent = new PdfContentByte(this); directContentUnder = new PdfContentByte(this); } /** * Use this method to get an instance of the PdfWriter. * * @param document The Document that has to be written * @param os The OutputStream the writer has to write to. * @return a new PdfWriter * * @throws DocumentException on error */ public static PdfWriter getInstance(Document document, OutputStream os) throws DocumentException { PdfDocument pdf = new PdfDocument(); document.addDocListener(pdf); PdfWriter writer = new PdfWriter(pdf, os); pdf.addWriter(writer); return writer; } /** * Use this method to get an instance of the PdfWriter. * * @return a new PdfWriter * @param document The Document that has to be written * @param os The OutputStream the writer has to write to. * @param listener A DocListener to pass to the PdfDocument. * @throws DocumentException on error */ public static PdfWriter getInstance(Document document, OutputStream os, DocListener listener) throws DocumentException { PdfDocument pdf = new PdfDocument(); pdf.addDocListener(listener); document.addDocListener(pdf); PdfWriter writer = new PdfWriter(pdf, os); pdf.addWriter(writer); return writer; } // the PdfDocument instance /** the pdfdocument object. */ protected PdfDocument pdf; /** * Gets the PdfDocument associated with this writer. * @return the PdfDocument */ PdfDocument getPdfDocument() { return pdf; } /** * Use this method to get the info dictionary if you want to * change it directly (add keys and values to the info dictionary). * @return the info dictionary */ public PdfDictionary getInfo() { return pdf.getInfo(); } /** * Use this method to get the current vertical page position. * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects * for elements that do not terminate the lines they've started because those lines will get * terminated. * @return The current vertical page position. */ public float getVerticalPosition(boolean ensureNewLine) { return pdf.getVerticalPosition(ensureNewLine); } /** * Sets the initial leading for the PDF document. * This has to be done before the document is opened. * @param leading the initial leading * @since 2.1.6 * @throws DocumentException if you try setting the leading after the document was opened. */ public void setInitialLeading(float leading) throws DocumentException { if (open) throw new DocumentException("You can't set the initial leading if the document is already open."); pdf.setLeading(leading); } // the PdfDirectContentByte instances /* * You should see Direct Content as a canvas on which you can draw * graphics and text. One canvas goes on top of the page (getDirectContent), * the other goes underneath (getDirectContentUnder). * You can always the same object throughout your document, * even if you have moved to a new page. Whatever you add on * the canvas will be displayed on top or under the current page. */ /** The direct content in this document. */ protected PdfContentByte directContent; /** The direct content under in this document. */ protected PdfContentByte directContentUnder; /** * Use this method to get the direct content for this document. * There is only one direct content, multiple calls to this method * will allways retrieve the same object. * @return the direct content */ public PdfContentByte getDirectContent() { if (!open) throw new RuntimeException("The document is not open."); return directContent; } /** * Use this method to get the direct content under for this document. * There is only one direct content, multiple calls to this method * will always retrieve the same object. * @return the direct content */ public PdfContentByte getDirectContentUnder() { if (!open) throw new RuntimeException("The document is not open."); return directContentUnder; } /** * Resets all the direct contents to empty. * This happens when a new page is started. */ void resetContent() { directContent.reset(); directContentUnder.reset(); } // PDF body /* * A PDF file has 4 parts: a header, a body, a cross-reference table, and a trailer. * The body contains all the PDF objects that make up the PDF document. * Each element gets a reference (a set of numbers) and the byte position of * every object is stored in the cross-reference table. * Use these methods only if you know what you're doing. */ /** body of the PDF document */ protected PdfBody body; /** * Adds the local destinations to the body of the document. * @param dest the HashMap containing the destinations * @throws IOException on error */ void addLocalDestinations(TreeMap dest) throws IOException { for (Iterator i = dest.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); String name = (String) entry.getKey(); Object obj[] = (Object[]) entry.getValue(); PdfDestination destination = (PdfDestination)obj[2]; if (obj[1] == null) obj[1] = getPdfIndirectReference(); if (destination == null) addToBody(new PdfString("invalid_" + name), (PdfIndirectReference)obj[1]); else addToBody(destination, (PdfIndirectReference)obj[1]); } } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object) throws IOException { PdfIndirectObject iobj = body.add(object); return iobj; } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @param inObjStm * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object, boolean inObjStm) throws IOException { PdfIndirectObject iobj = body.add(object, inObjStm); return iobj; } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @param ref * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref) throws IOException { PdfIndirectObject iobj = body.add(object, ref); return iobj; } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @param ref * @param inObjStm * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { PdfIndirectObject iobj = body.add(object, ref, inObjStm); return iobj; } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @param refNumber * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object, int refNumber) throws IOException { PdfIndirectObject iobj = body.add(object, refNumber); return iobj; } /** * Use this method to add a PDF object to the PDF body. * Use this method only if you know what you're doing! * @param object * @param refNumber * @param inObjStm * @return a PdfIndirectObject * @throws IOException */ public PdfIndirectObject addToBody(PdfObject object, int refNumber, boolean inObjStm) throws IOException { PdfIndirectObject iobj = body.add(object, refNumber, inObjStm); return iobj; } /** * Use this to get an PdfIndirectReference for an object that * will be created in the future. * Use this method only if you know what you're doing! * @return the PdfIndirectReference */ public PdfIndirectReference getPdfIndirectReference() { return body.getPdfIndirectReference(); } int getIndirectReferenceNumber() { return body.getIndirectReferenceNumber(); } /** * Returns the outputStreamCounter. * @return the outputStreamCounter */ OutputStreamCounter getOs() { return os; } // PDF Catalog /* * The Catalog is also called the root object of the document. * Whereas the Cross-Reference maps the objects number with the * byte offset so that the viewer can find the objects, the * Catalog tells the viewer the numbers of the objects needed * to render the document. */ protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { PdfDictionary catalog = pdf.getCatalog(rootObj); // [F12] tagged PDF if (tagged) { try { getStructureTreeRoot().buildTree(); } catch (Exception e) { throw new ExceptionConverter(e); } catalog.put(PdfName.STRUCTTREEROOT, structureTreeRoot.getReference()); PdfDictionary mi = new PdfDictionary(); mi.put(PdfName.MARKED, PdfBoolean.PDFTRUE); if (userProperties) mi.put(PdfName.USERPROPERTIES, PdfBoolean.PDFTRUE); catalog.put(PdfName.MARKINFO, mi); } // [F13] OCG if (!documentOCG.isEmpty()) { fillOCProperties(false); catalog.put(PdfName.OCPROPERTIES, OCProperties); } return catalog; } /** Holds value of property extraCatalog this is used for Output Intents. */ protected PdfDictionary extraCatalog; /** * Sets extra keys to the catalog. * @return the catalog to change */ public PdfDictionary getExtraCatalog() { if (extraCatalog == null) extraCatalog = new PdfDictionary(); return this.extraCatalog; } // PdfPages /* * The page root keeps the complete page tree of the document. * There's an entry in the Catalog that refers to the root * of the page tree, the page tree contains the references * to pages and other page trees. */ /** The root of the page tree. */ protected PdfPages root = new PdfPages(this); /** The PdfIndirectReference to the pages. */ protected ArrayList pageReferences = new ArrayList(); /** The current page number. */ protected int currentPageNumber = 1; /** * The value of the Tabs entry in the page dictionary. * @since 2.1.5 */ protected PdfName tabs = null; /** * Use this method to make sure the page tree has a linear structure * (every leave is attached directly to the root). * Use this method to allow page reordering with method reorderPages. */ public void setLinearPageMode() { root.setLinearMode(null); } /** * Use this method to reorder the pages in the document. * A null argument value only returns the number of pages to process. * It is advisable to issue a Document.newPage() before using this method. * @return the total number of pages * @param order an array with the new page sequence. It must have the * same size as the number of pages. * @throws DocumentException if all the pages are not present in the array */ public int reorderPages(int order[]) throws DocumentException { return root.reorderPages(order); } /** * Use this method to get a reference to a page existing or not. * If the page does not exist yet the reference will be created * in advance. If on closing the document, a page number greater * than the total number of pages was requested, an exception * is thrown. * @param page the page number. The first page is 1 * @return the reference to the page */ public PdfIndirectReference getPageReference(int page) { --page; if (page < 0) throw new IndexOutOfBoundsException("The page numbers start at 1."); PdfIndirectReference ref; if (page < pageReferences.size()) { ref = (PdfIndirectReference)pageReferences.get(page); if (ref == null) { ref = body.getPdfIndirectReference(); pageReferences.set(page, ref); } } else { int empty = page - pageReferences.size(); for (int k = 0; k < empty; ++k) pageReferences.add(null); ref = body.getPdfIndirectReference(); pageReferences.add(ref); } return ref; } /** * Gets the pagenumber of this document. * This number can be different from the real pagenumber, * if you have (re)set the page number previously. * @return a page number */ public int getPageNumber() { return pdf.getPageNumber(); } PdfIndirectReference getCurrentPage() { return getPageReference(currentPageNumber); } public int getCurrentPageNumber() { return currentPageNumber; } /** * Sets the value for the Tabs entry in the page tree. * @param tabs Can be PdfName.R, PdfName.C or PdfName.S. * Since the Adobe Extensions Level 3, it can also be PdfName.A * or PdfName.W * @since 2.1.5 */ public void setTabs(PdfName tabs) { this.tabs = tabs; } /** * Returns the value to be used for the Tabs entry in the page tree. * @since 2.1.5 */ public PdfName getTabs() { return tabs; } /** * Adds some PdfContents to this Writer. *

* The document has to be open before you can begin to add content * to the body of the document. * * @return a PdfIndirectReference * @param page the PdfPage to add * @param contents the PdfContents of the page * @throws PdfException on error */ PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { if (!open) { throw new PdfException("The document isn't open."); } PdfIndirectObject object; try { object = addToBody(contents); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } page.add(object.getIndirectReference()); // [U5] if (group != null) { page.put(PdfName.GROUP, group); group = null; } else if (rgbTransparencyBlending) { PdfDictionary pp = new PdfDictionary(); pp.put(PdfName.TYPE, PdfName.GROUP); pp.put(PdfName.S, PdfName.TRANSPARENCY); pp.put(PdfName.CS, PdfName.DEVICERGB); page.put(PdfName.GROUP, pp); } root.addPage(page); currentPageNumber++; return null; } // page events /* * Page events are specific for iText, not for PDF. * Upon specific events (for instance when a page starts * or ends), the corresponding method in the page event * implementation that is added to the writer is invoked. */ /** The PdfPageEvent for this document. */ private PdfPageEvent pageEvent; /** * Sets the PdfPageEvent for this document. * @param event the PdfPageEvent for this document */ public void setPageEvent(PdfPageEvent event) { if (event == null) this.pageEvent = null; else if (this.pageEvent == null) this.pageEvent = event; else if (this.pageEvent instanceof PdfPageEventForwarder) ((PdfPageEventForwarder)this.pageEvent).addPageEvent(event); else { PdfPageEventForwarder forward = new PdfPageEventForwarder(); forward.addPageEvent(this.pageEvent); forward.addPageEvent(event); this.pageEvent = forward; } } /** * Gets the PdfPageEvent for this document or null * if none is set. * @return the PdfPageEvent for this document or null * if none is set */ public PdfPageEvent getPageEvent() { return pageEvent; } // Open and Close methods + method that create the PDF /** A number referring to the previous Cross-Reference Table. */ protected int prevxref = 0; /** * Signals that the Document has been opened and that * Elements can be added. *

* When this method is called, the PDF-document header is * written to the outputstream. * @see com.lowagie.text.DocWriter#open() */ public void open() { super.open(); try { pdf_version.writeHeader(os); body = new PdfBody(this); if (pdfxConformance.isPdfX32002()) { PdfDictionary sec = new PdfDictionary(); sec.put(PdfName.GAMMA, new PdfArray(new float[]{2.2f,2.2f,2.2f})); sec.put(PdfName.MATRIX, new PdfArray(new float[]{0.4124f,0.2126f,0.0193f,0.3576f,0.7152f,0.1192f,0.1805f,0.0722f,0.9505f})); sec.put(PdfName.WHITEPOINT, new PdfArray(new float[]{0.9505f,1f,1.089f})); PdfArray arr = new PdfArray(PdfName.CALRGB); arr.add(sec); setDefaultColorspace(PdfName.DEFAULTRGB, addToBody(arr).getIndirectReference()); } } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Signals that the Document was closed and that no other * Elements will be added. *

* The pages-tree is built and written to the outputstream. * A Catalog is constructed, as well as an Info-object, * the reference table is composed and everything is written * to the outputstream embedded in a Trailer. * @see com.lowagie.text.DocWriter#close() */ public void close() { if (open) { if ((currentPageNumber - 1) != pageReferences.size()) throw new RuntimeException("The page " + pageReferences.size() + " was requested but the document has only " + (currentPageNumber - 1) + " pages."); pdf.close(); try { addSharedObjectsToBody(); // add the root to the body PdfIndirectReference rootRef = root.writePageTree(); // make the catalog-object and add it to the body PdfDictionary catalog = getCatalog(rootRef); // [C9] if there is XMP data to add: add it if (xmpMetadata != null) { PdfStream xmp = new PdfStream(xmpMetadata); xmp.put(PdfName.TYPE, PdfName.METADATA); xmp.put(PdfName.SUBTYPE, PdfName.XML); if (crypto != null && !crypto.isMetadataEncrypted()) { PdfArray ar = new PdfArray(); ar.add(PdfName.CRYPT); xmp.put(PdfName.FILTER, ar); } catalog.put(PdfName.METADATA, body.add(xmp).getIndirectReference()); } // [C10] make pdfx conformant if (isPdfX()) { pdfxConformance.completeInfoDictionary(getInfo()); pdfxConformance.completeExtraCatalog(getExtraCatalog()); } // [C11] Output Intents if (extraCatalog != null) { catalog.mergeDifferent(extraCatalog); } writeOutlines(catalog, false); // add the Catalog to the body PdfIndirectObject indirectCatalog = addToBody(catalog, false); // add the info-object to the body PdfIndirectObject infoObj = addToBody(getInfo(), false); // [F1] encryption PdfIndirectReference encryption = null; PdfObject fileID = null; body.flushObjStm(); if (crypto != null) { PdfIndirectObject encryptionObject = addToBody(crypto.getEncryptionDictionary(), false); encryption = encryptionObject.getIndirectReference(); fileID = crypto.getFileID(); } else fileID = PdfEncryption.createInfoId(PdfEncryption.createDocumentId()); // write the cross-reference table of the body body.writeCrossReferenceTable(os, indirectCatalog.getIndirectReference(), infoObj.getIndirectReference(), encryption, fileID, prevxref); // make the trailer // [F2] full compression if (fullCompression) { os.write(getISOBytes("startxref\n")); os.write(getISOBytes(String.valueOf(body.offset()))); os.write(getISOBytes("\n%%EOF\n")); } else { PdfTrailer trailer = new PdfTrailer(body.size(), body.offset(), indirectCatalog.getIndirectReference(), infoObj.getIndirectReference(), encryption, fileID, prevxref); trailer.toPdf(this, os); } super.close(); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } } protected void addSharedObjectsToBody() throws IOException { // [F3] add the fonts for (Iterator it = documentFonts.values().iterator(); it.hasNext();) { FontDetails details = (FontDetails)it.next(); details.writeFont(this); } // [F4] add the form XObjects for (Iterator it = formXObjects.values().iterator(); it.hasNext();) { Object objs[] = (Object[])it.next(); PdfTemplate template = (PdfTemplate)objs[1]; if (template != null && template.getIndirectReference() instanceof PRIndirectReference) continue; if (template != null && template.getType() == PdfTemplate.TYPE_TEMPLATE) { addToBody(template.getFormXObject(compressionLevel), template.getIndirectReference()); } } // [F5] add all the dependencies in the imported pages for (Iterator it = importedPages.values().iterator(); it.hasNext();) { currentPdfReaderInstance = (PdfReaderInstance)it.next(); currentPdfReaderInstance.writeAllPages(); } currentPdfReaderInstance = null; // [F6] add the spotcolors for (Iterator it = documentColors.values().iterator(); it.hasNext();) { ColorDetails color = (ColorDetails)it.next(); addToBody(color.getSpotColor(this), color.getIndirectReference()); } // [F7] add the pattern for (Iterator it = documentPatterns.keySet().iterator(); it.hasNext();) { PdfPatternPainter pat = (PdfPatternPainter)it.next(); addToBody(pat.getPattern(compressionLevel), pat.getIndirectReference()); } // [F8] add the shading patterns for (Iterator it = documentShadingPatterns.keySet().iterator(); it.hasNext();) { PdfShadingPattern shadingPattern = (PdfShadingPattern)it.next(); shadingPattern.addToBody(); } // [F9] add the shadings for (Iterator it = documentShadings.keySet().iterator(); it.hasNext();) { PdfShading shading = (PdfShading)it.next(); shading.addToBody(); } // [F10] add the extgstate for (Iterator it = documentExtGState.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); PdfDictionary gstate = (PdfDictionary) entry.getKey(); PdfObject obj[] = (PdfObject[]) entry.getValue(); addToBody(gstate, (PdfIndirectReference)obj[1]); } // [F11] add the properties for (Iterator it = documentProperties.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); Object prop = entry.getKey(); PdfObject[] obj = (PdfObject[]) entry.getValue(); if (prop instanceof PdfLayerMembership){ PdfLayerMembership layer = (PdfLayerMembership)prop; addToBody(layer.getPdfObject(), layer.getRef()); } else if ((prop instanceof PdfDictionary) && !(prop instanceof PdfLayer)){ addToBody((PdfDictionary)prop, (PdfIndirectReference)obj[1]); } } // [F13] add the OCG layers for (Iterator it = documentOCG.iterator(); it.hasNext();) { PdfOCG layer = (PdfOCG)it.next(); addToBody(layer.getPdfObject(), layer.getRef()); } } // Root data for the PDF document (used when composing the Catalog) // [C1] Outlines (bookmarks) /** * Use this method to get the root outline * and construct bookmarks. * @return the root outline */ public PdfOutline getRootOutline() { return directContent.getRootOutline(); } protected java.util.List newBookmarks; /** * Sets the bookmarks. The list structure is defined in * {@link SimpleBookmark}. * @param outlines the bookmarks or null to remove any */ public void setOutlines(java.util.List outlines) { newBookmarks = outlines; } protected void writeOutlines(PdfDictionary catalog, boolean namedAsNames) throws IOException { if (newBookmarks == null || newBookmarks.isEmpty()) return; PdfDictionary top = new PdfDictionary(); PdfIndirectReference topRef = getPdfIndirectReference(); Object kids[] = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, namedAsNames); top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); top.put(PdfName.COUNT, new PdfNumber(((Integer)kids[2]).intValue())); addToBody(top, topRef); catalog.put(PdfName.OUTLINES, topRef); } // [C2] PdfVersion interface /** possible PDF version (header) */ public static final char VERSION_1_2 = '2'; /** possible PDF version (header) */ public static final char VERSION_1_3 = '3'; /** possible PDF version (header) */ public static final char VERSION_1_4 = '4'; /** possible PDF version (header) */ public static final char VERSION_1_5 = '5'; /** possible PDF version (header) */ public static final char VERSION_1_6 = '6'; /** possible PDF version (header) */ public static final char VERSION_1_7 = '7'; /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_2 = new PdfName("1.2"); /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_3 = new PdfName("1.3"); /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_4 = new PdfName("1.4"); /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_5 = new PdfName("1.5"); /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_6 = new PdfName("1.6"); /** possible PDF version (catalog) */ public static final PdfName PDF_VERSION_1_7 = new PdfName("1.7"); /** Stores the version information for the header and the catalog. */ protected PdfVersionImp pdf_version = new PdfVersionImp(); /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(char) */ public void setPdfVersion(char version) { pdf_version.setPdfVersion(version); } /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setAtLeastPdfVersion(char) */ public void setAtLeastPdfVersion(char version) { pdf_version.setAtLeastPdfVersion(version); } /** @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(com.lowagie.text.pdf.PdfName) */ public void setPdfVersion(PdfName version) { pdf_version.setPdfVersion(version); } /** * @see com.lowagie.text.pdf.interfaces.PdfVersion#addDeveloperExtension(com.lowagie.text.pdf.PdfDeveloperExtension) * @since 2.1.6 */ public void addDeveloperExtension(PdfDeveloperExtension de) { pdf_version.addDeveloperExtension(de); } /** * Returns the version information. */ PdfVersionImp getPdfVersion() { return pdf_version; } // [C3] PdfViewerPreferences interface // page layout (section 13.1.1 of "iText in Action") /** A viewer preference */ public static final int PageLayoutSinglePage = 1; /** A viewer preference */ public static final int PageLayoutOneColumn = 2; /** A viewer preference */ public static final int PageLayoutTwoColumnLeft = 4; /** A viewer preference */ public static final int PageLayoutTwoColumnRight = 8; /** A viewer preference */ public static final int PageLayoutTwoPageLeft = 16; /** A viewer preference */ public static final int PageLayoutTwoPageRight = 32; // page mode (section 13.1.2 of "iText in Action") /** A viewer preference */ public static final int PageModeUseNone = 64; /** A viewer preference */ public static final int PageModeUseOutlines = 128; /** A viewer preference */ public static final int PageModeUseThumbs = 256; /** A viewer preference */ public static final int PageModeFullScreen = 512; /** A viewer preference */ public static final int PageModeUseOC = 1024; /** A viewer preference */ public static final int PageModeUseAttachments = 2048; // values for setting viewer preferences in iText versions older than 2.x /** A viewer preference */ public static final int HideToolbar = 1 << 12; /** A viewer preference */ public static final int HideMenubar = 1 << 13; /** A viewer preference */ public static final int HideWindowUI = 1 << 14; /** A viewer preference */ public static final int FitWindow = 1 << 15; /** A viewer preference */ public static final int CenterWindow = 1 << 16; /** A viewer preference */ public static final int DisplayDocTitle = 1 << 17; /** A viewer preference */ public static final int NonFullScreenPageModeUseNone = 1 << 18; /** A viewer preference */ public static final int NonFullScreenPageModeUseOutlines = 1 << 19; /** A viewer preference */ public static final int NonFullScreenPageModeUseThumbs = 1 << 20; /** A viewer preference */ public static final int NonFullScreenPageModeUseOC = 1 << 21; /** A viewer preference */ public static final int DirectionL2R = 1 << 22; /** A viewer preference */ public static final int DirectionR2L = 1 << 23; /** A viewer preference */ public static final int PrintScalingNone = 1 << 24; /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int) */ public void setViewerPreferences(int preferences) { pdf.setViewerPreferences(preferences); } /** @see com.lowagie.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfObject) */ public void addViewerPreference(PdfName key, PdfObject value) { pdf.addViewerPreference(key, value); } // [C4] Page labels /** * Use this method to add page labels * @param pageLabels the page labels */ public void setPageLabels(PdfPageLabels pageLabels) { pdf.setPageLabels(pageLabels); } // [C5] named objects: named destinations, javascript, embedded files /** * Use this method to add a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param js The JavaScript action */ public void addJavaScript(PdfAction js) { pdf.addJavaScript(js); } /** * Use this method to add a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param code the JavaScript code * @param unicode select JavaScript unicode. Note that the internal * Acrobat JavaScript engine does not support unicode, * so this may or may not work for you */ public void addJavaScript(String code, boolean unicode) { addJavaScript(PdfAction.javaScript(code, this, unicode)); } /** * Use this method to adds a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param code the JavaScript code */ public void addJavaScript(String code) { addJavaScript(code, false); } /** * Use this method to add a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param name The name of the JS Action in the name tree * @param js The JavaScript action */ public void addJavaScript(String name, PdfAction js) { pdf.addJavaScript(name, js); } /** * Use this method to add a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param name The name of the JS Action in the name tree * @param code the JavaScript code * @param unicode select JavaScript unicode. Note that the internal * Acrobat JavaScript engine does not support unicode, * so this may or may not work for you */ public void addJavaScript(String name, String code, boolean unicode) { addJavaScript(name, PdfAction.javaScript(code, this, unicode)); } /** * Use this method to adds a JavaScript action at the document level. * When the document opens, all this JavaScript runs. * @param name The name of the JS Action in the name tree * @param code the JavaScript code */ public void addJavaScript(String name, String code) { addJavaScript(name, code, false); } /** * Use this method to add a file attachment at the document level. * @param description the file description * @param fileStore an array with the file. If it's null * the file will be read from the disk * @param file the path to the file. It will only be used if * fileStore is not null * @param fileDisplay the actual file name stored in the pdf * @throws IOException on error */ public void addFileAttachment(String description, byte fileStore[], String file, String fileDisplay) throws IOException { addFileAttachment(description, PdfFileSpecification.fileEmbedded(this, file, fileDisplay, fileStore)); } /** * Use this method to add a file attachment at the document level. * @param description the file description * @param fs the file specification */ public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { pdf.addFileAttachment(description, fs); } /** * Use this method to add a file attachment at the document level. * @param fs the file specification */ public void addFileAttachment(PdfFileSpecification fs) throws IOException { addFileAttachment(null, fs); } // [C6] Actions (open and additional) /** action value */ public static final PdfName DOCUMENT_CLOSE = PdfName.WC; /** action value */ public static final PdfName WILL_SAVE = PdfName.WS; /** action value */ public static final PdfName DID_SAVE = PdfName.DS; /** action value */ public static final PdfName WILL_PRINT = PdfName.WP; /** action value */ public static final PdfName DID_PRINT = PdfName.DP; /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setOpenAction(java.lang.String) */ public void setOpenAction(String name) { pdf.setOpenAction(name); } /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setOpenAction(com.lowagie.text.pdf.PdfAction) */ public void setOpenAction(PdfAction action) { pdf.setOpenAction(action); } /** @see com.lowagie.text.pdf.interfaces.PdfDocumentActions#setAdditionalAction(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfAction) */ public void setAdditionalAction(PdfName actionType, PdfAction action) throws DocumentException { if (!(actionType.equals(DOCUMENT_CLOSE) || actionType.equals(WILL_SAVE) || actionType.equals(DID_SAVE) || actionType.equals(WILL_PRINT) || actionType.equals(DID_PRINT))) { throw new DocumentException("Invalid additional action type: " + actionType.toString()); } pdf.addAdditionalAction(actionType, action); } // [C7] portable collections /** * Use this method to add the Collection dictionary. * @param collection a dictionary of type PdfCollection */ public void setCollection(PdfCollection collection) { setAtLeastPdfVersion(VERSION_1_7); pdf.setCollection(collection); } // [C8] AcroForm /** signature value */ public static final int SIGNATURE_EXISTS = 1; /** signature value */ public static final int SIGNATURE_APPEND_ONLY = 2; /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#getAcroForm() */ public PdfAcroForm getAcroForm() { return pdf.getAcroForm(); } /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#addAnnotation(com.lowagie.text.pdf.PdfAnnotation) */ public void addAnnotation(PdfAnnotation annot) { pdf.addAnnotation(annot); } void addAnnotation(PdfAnnotation annot, int page) { addAnnotation(annot); } /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#addCalculationOrder(com.lowagie.text.pdf.PdfFormField) */ public void addCalculationOrder(PdfFormField annot) { pdf.addCalculationOrder(annot); } /** @see com.lowagie.text.pdf.interfaces.PdfAnnotations#setSigFlags(int) */ public void setSigFlags(int f) { pdf.setSigFlags(f); } // [C9] Metadata /** XMP Metadata for the document. */ protected byte[] xmpMetadata = null; /** * Use this method to set the XMP Metadata. * @param xmpMetadata The xmpMetadata to set. */ public void setXmpMetadata(byte[] xmpMetadata) { this.xmpMetadata = xmpMetadata; } /** * Use this method to set the XMP Metadata for each page. * @param xmpMetadata The xmpMetadata to set. */ public void setPageXmpMetadata(byte[] xmpMetadata) { pdf.setXmpMetadata(xmpMetadata); } /** * Use this method to creates XMP Metadata based * on the metadata in the PdfDocument. */ public void createXmpMetadata() { setXmpMetadata(createXmpMetadataBytes()); } /** * @return an XmpMetadata byte array */ private byte[] createXmpMetadataBytes() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { XmpWriter xmp = new XmpWriter(baos, pdf.getInfo(), pdfxConformance.getPDFXConformance()); xmp.close(); } catch (IOException ioe) { ioe.printStackTrace(); } return baos.toByteArray(); } // [C10] PDFX Conformance /** A PDF/X level. */ public static final int PDFXNONE = 0; /** A PDF/X level. */ public static final int PDFX1A2001 = 1; /** A PDF/X level. */ public static final int PDFX32002 = 2; /** PDFA-1A level. */ public static final int PDFA1A = 3; /** PDFA-1B level. */ public static final int PDFA1B = 4; /** Stores the PDF/X level. */ private PdfXConformanceImp pdfxConformance = new PdfXConformanceImp(); /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#setPDFXConformance(int) */ public void setPDFXConformance(int pdfx) { if (pdfxConformance.getPDFXConformance() == pdfx) return; if (pdf.isOpen()) throw new PdfXConformanceException("PDFX conformance can only be set before opening the document."); if (crypto != null) throw new PdfXConformanceException("A PDFX conforming document cannot be encrypted."); if (pdfx == PDFA1A || pdfx == PDFA1B) setPdfVersion(VERSION_1_4); else if (pdfx != PDFXNONE) setPdfVersion(VERSION_1_3); pdfxConformance.setPDFXConformance(pdfx); } /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#getPDFXConformance() */ public int getPDFXConformance() { return pdfxConformance.getPDFXConformance(); } /** @see com.lowagie.text.pdf.interfaces.PdfXConformance#isPdfX() */ public boolean isPdfX() { return pdfxConformance.isPdfX(); } // [C11] Output intents /** * Sets the values of the output intent dictionary. Null values are allowed to * suppress any key. * * @param outputConditionIdentifier a value * @param outputCondition a value, "PDFA/A" to force GTS_PDFA1, otherwise cued by pdfxConformance. * @param registryName a value * @param info a value * @param colorProfile a value * @since 2.1.5 * @throws IOException on error */ public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, ICC_Profile colorProfile) throws IOException { getExtraCatalog(); PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT); if (outputCondition != null) out.put(PdfName.OUTPUTCONDITION, new PdfString(outputCondition, PdfObject.TEXT_UNICODE)); if (outputConditionIdentifier != null) out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString(outputConditionIdentifier, PdfObject.TEXT_UNICODE)); if (registryName != null) out.put(PdfName.REGISTRYNAME, new PdfString(registryName, PdfObject.TEXT_UNICODE)); if (info != null) out.put(PdfName.INFO, new PdfString(info, PdfObject.TEXT_UNICODE)); if (colorProfile != null) { PdfStream stream = new PdfICCBased(colorProfile, compressionLevel); out.put(PdfName.DESTOUTPUTPROFILE, addToBody(stream).getIndirectReference()); } PdfName intentSubtype; if (pdfxConformance.isPdfA1() || "PDFA/1".equals(outputCondition)) { intentSubtype = PdfName.GTS_PDFA1; } else { intentSubtype = PdfName.GTS_PDFX; } out.put(PdfName.S, intentSubtype); extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out)); } /** * Sets the values of the output intent dictionary. Null values are allowed to * suppress any key. * * Prefer the ICC_Profile-based version of this method. * @param outputConditionIdentifier a value * @param outputCondition a value, "PDFA/A" to force GTS_PDFA1, otherwise cued by pdfxConformance. * @param registryName a value * @param info a value * @param destOutputProfile a value * @since 1.x * * @throws IOException */ public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, byte destOutputProfile[]) throws IOException { ICC_Profile colorProfile = (destOutputProfile == null) ? null : ICC_Profile.getInstance(destOutputProfile); setOutputIntents(outputConditionIdentifier, outputCondition, registryName, info, colorProfile); } /** * Use this method to copy the output intent dictionary * from another document to this one. * @param reader the other document * @param checkExistence true to just check for the existence of a valid output intent * dictionary, false to insert the dictionary if it exists * @throws IOException on error * @return true if the output intent dictionary exists, false * otherwise */ public boolean setOutputIntents(PdfReader reader, boolean checkExistence) throws IOException { PdfDictionary catalog = reader.getCatalog(); PdfArray outs = catalog.getAsArray(PdfName.OUTPUTINTENTS); if (outs == null) return false; if (outs.isEmpty()) return false; PdfDictionary out = outs.getAsDict(0); PdfObject obj = PdfReader.getPdfObject(out.get(PdfName.S)); if (obj == null || !PdfName.GTS_PDFX.equals(obj)) return false; if (checkExistence) return true; PRStream stream = (PRStream)PdfReader.getPdfObject(out.get(PdfName.DESTOUTPUTPROFILE)); byte destProfile[] = null; if (stream != null) { destProfile = PdfReader.getStreamBytes(stream); } setOutputIntents(getNameString(out, PdfName.OUTPUTCONDITIONIDENTIFIER), getNameString(out, PdfName.OUTPUTCONDITION), getNameString(out, PdfName.REGISTRYNAME), getNameString(out, PdfName.INFO), destProfile); return true; } private static String getNameString(PdfDictionary dic, PdfName key) { PdfObject obj = PdfReader.getPdfObject(dic.get(key)); if (obj == null || !obj.isString()) return null; return ((PdfString)obj).toUnicodeString(); } // PDF Objects that have an impact on the PDF body // [F1] PdfEncryptionSettings interface // types of encryption /** Type of encryption */ public static final int STANDARD_ENCRYPTION_40 = 0; /** Type of encryption */ public static final int STANDARD_ENCRYPTION_128 = 1; /** Type of encryption */ public static final int ENCRYPTION_AES_128 = 2; /** Mask to separate the encryption type from the encryption mode. */ static final int ENCRYPTION_MASK = 7; /** Add this to the mode to keep the metadata in clear text */ public static final int DO_NOT_ENCRYPT_METADATA = 8; /** * Add this to the mode to keep encrypt only the embedded files. * @since 2.1.3 */ public static final int EMBEDDED_FILES_ONLY = 24; // permissions /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_PRINTING = 4 + 2048; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_MODIFY_CONTENTS = 8; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_COPY = 16; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_MODIFY_ANNOTATIONS = 32; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_FILL_IN = 256; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_SCREENREADERS = 512; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_ASSEMBLY = 1024; /** The operation permitted when the document is opened with the user password * * @since 2.0.7 */ public static final int ALLOW_DEGRADED_PRINTING = 4; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_PRINTING} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowPrinting = ALLOW_PRINTING; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_CONTENTS} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowModifyContents = ALLOW_MODIFY_CONTENTS; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_COPY} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowCopy = ALLOW_COPY; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_MODIFY_ANNOTATIONS} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowModifyAnnotations = ALLOW_MODIFY_ANNOTATIONS; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_FILL_IN} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowFillIn = ALLOW_FILL_IN; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_SCREENREADERS} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowScreenReaders = ALLOW_SCREENREADERS; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_ASSEMBLY} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowAssembly = ALLOW_ASSEMBLY; /** @deprecated As of iText 2.0.7, use {@link #ALLOW_DEGRADED_PRINTING} instead. Scheduled for removal at or after 2.2.0 */ public static final int AllowDegradedPrinting = ALLOW_DEGRADED_PRINTING; // Strength of the encryption (kept for historical reasons) /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_40} instead. Scheduled for removal at or after 2.2.0 */ public static final boolean STRENGTH40BITS = false; /** @deprecated As of iText 2.0.7, use {@link #STANDARD_ENCRYPTION_128} instead. Scheduled for removal at or after 2.2.0 */ public static final boolean STRENGTH128BITS = true; /** Contains the business logic for cryptography. */ protected PdfEncryption crypto; PdfEncryption getEncryption() { return crypto; } /** @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int) */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, int encryptionType) throws DocumentException { if (pdf.isOpen()) throw new DocumentException("Encryption can only be added before opening the document."); crypto = new PdfEncryption(); crypto.setCryptoMode(encryptionType, 0); crypto.setupAllKeys(userPassword, ownerPassword, permissions); } /** @see com.lowagie.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int) */ public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException { if (pdf.isOpen()) throw new DocumentException("Encryption can only be added before opening the document."); crypto = new PdfEncryption(); if (certs != null) { for (int i=0; i < certs.length; i++) { crypto.addRecipient(certs[i], permissions[i]); } } crypto.setCryptoMode(encryptionType, 0); crypto.getEncryptionDictionary(); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param strength128Bits true for 128 bit key length, false for 40 bit key length * @throws DocumentException if the document is already open * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? STANDARD_ENCRYPTION_128 : STANDARD_ENCRYPTION_40); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param strength true for 128 bit key length, false for 40 bit key length * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if the document is already open * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 */ public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, strength ? STANDARD_ENCRYPTION_128 : STANDARD_ENCRYPTION_40); } /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @throws DocumentException if the document is already open * @deprecated As of iText 2.0.3, replaced by (@link #setEncryption(byte[], byte[], int, int)}. Scheduled for removal at or after 2.2.0 */ public void setEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) throws DocumentException { setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, encryptionType); } // [F2] compression /** Holds value of property fullCompression. */ protected boolean fullCompression = false; /** * Use this method to find out if 1.5 compression is on. * @return the 1.5 compression status */ public boolean isFullCompression() { return this.fullCompression; } /** * Use this method to set the document's compression to the * PDF 1.5 mode with object streams and xref streams. * It can be set at any time but once set it can't be unset. *

* If set before opening the document it will also set the pdf version to 1.5. */ public void setFullCompression() { this.fullCompression = true; setAtLeastPdfVersion(VERSION_1_5); } /** * The compression level of the content streams. * @since 2.1.3 */ protected int compressionLevel = PdfStream.DEFAULT_COMPRESSION; /** * Returns the compression level used for streams written by this writer. * @return the compression level (0 = best speed, 9 = best compression, -1 is default) * @since 2.1.3 */ public int getCompressionLevel() { return compressionLevel; } /** * Sets the compression level to be used for streams written by this writer. * @param compressionLevel a value between 0 (best speed) and 9 (best compression) * @since 2.1.3 */ public void setCompressionLevel(int compressionLevel) { if (compressionLevel < PdfStream.NO_COMPRESSION || compressionLevel > PdfStream.BEST_COMPRESSION) this.compressionLevel = PdfStream.DEFAULT_COMPRESSION; else this.compressionLevel = compressionLevel; } // [F3] adding fonts /** The fonts of this document */ protected LinkedHashMap documentFonts = new LinkedHashMap(); /** The font number counter for the fonts in the document. */ protected int fontNumber = 1; /** * Adds a BaseFont to the document but not to the page resources. * It is used for templates. * @param bf the BaseFont to add * @return an Object[] where position 0 is a PdfName * and position 1 is an PdfIndirectReference */ FontDetails addSimple(BaseFont bf) { if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { return new FontDetails(new PdfName("F" + (fontNumber++)), ((DocumentFont)bf).getIndirectReference(), bf); } FontDetails ret = (FontDetails)documentFonts.get(bf); if (ret == null) { PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_FONT, bf); ret = new FontDetails(new PdfName("F" + (fontNumber++)), body.getPdfIndirectReference(), bf); documentFonts.put(bf, ret); } return ret; } void eliminateFontSubset(PdfDictionary fonts) { for (Iterator it = documentFonts.values().iterator(); it.hasNext();) { FontDetails ft = (FontDetails)it.next(); if (fonts.get(ft.getFontName()) != null) ft.setSubset(false); } } // [F4] adding (and releasing) form XObjects /** The form XObjects in this document. The key is the xref and the value is Object[]{PdfName, template}.*/ protected HashMap formXObjects = new HashMap(); /** The name counter for the form XObjects name. */ protected int formXObjectsCounter = 1; /** * Adds a template to the document but not to the page resources. * @param template the template to add * @param forcedName the template name, rather than a generated one. Can be null * @return the PdfName for this template */ PdfName addDirectTemplateSimple(PdfTemplate template, PdfName forcedName) { PdfIndirectReference ref = template.getIndirectReference(); Object obj[] = (Object[])formXObjects.get(ref); PdfName name = null; try { if (obj == null) { if (forcedName == null) { name = new PdfName("Xf" + formXObjectsCounter); ++formXObjectsCounter; } else name = forcedName; if (template.getType() == PdfTemplate.TYPE_IMPORTED) { // If we got here from PdfCopy we'll have to fill importedPages PdfImportedPage ip = (PdfImportedPage)template; PdfReader r = ip.getPdfReaderInstance().getReader(); if (!importedPages.containsKey(r)) { importedPages.put(r, ip.getPdfReaderInstance()); } template = null; } formXObjects.put(ref, new Object[]{name, template}); } else name = (PdfName)obj[0]; } catch (Exception e) { throw new ExceptionConverter(e); } return name; } /** * Use this method to releases the memory used by a template. * This method writes the template to the output. * The template can still be added to any content * but changes to the template itself won't have any effect. * @param tp the template to release * @throws IOException on error */ public void releaseTemplate(PdfTemplate tp) throws IOException { PdfIndirectReference ref = tp.getIndirectReference(); Object[] objs = (Object[])formXObjects.get(ref); if (objs == null || objs[1] == null) return; PdfTemplate template = (PdfTemplate)objs[1]; if (template.getIndirectReference() instanceof PRIndirectReference) return; if (template.getType() == PdfTemplate.TYPE_TEMPLATE) { addToBody(template.getFormXObject(compressionLevel), template.getIndirectReference()); objs[1] = null; } } // [F5] adding pages imported form other PDF documents protected HashMap importedPages = new HashMap(); /** * Use this method to get a page from other PDF document. * The page can be used as any other PdfTemplate. * Note that calling this method more than once with the same parameters * will retrieve the same object. * @param reader the PDF document where the page is * @param pageNumber the page number. The first page is 1 * @return the template representing the imported page */ public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { PdfReaderInstance inst = (PdfReaderInstance)importedPages.get(reader); if (inst == null) { inst = reader.getPdfReaderInstance(this); importedPages.put(reader, inst); } return inst.getImportedPage(pageNumber); } /** * Use this method to writes the reader to the document * and free the memory used by it. * The main use is when concatenating multiple documents * to keep the memory usage restricted to the current * appending document. * @param reader the PdfReader to free * @throws IOException on error */ public void freeReader(PdfReader reader) throws IOException { currentPdfReaderInstance = (PdfReaderInstance)importedPages.get(reader); if (currentPdfReaderInstance == null) return; currentPdfReaderInstance.writeAllPages(); currentPdfReaderInstance = null; importedPages.remove(reader); } /** * Use this method to gets the current document size. * This size only includes the data already written * to the output stream, it does not include templates or fonts. * It is useful if used with freeReader() * when concatenating many documents and an idea of * the current size is needed. * @return the approximate size without fonts or templates */ public int getCurrentDocumentSize() { return body.offset() + body.size() * 20 + 0x48; } protected PdfReaderInstance currentPdfReaderInstance; protected int getNewObjectNumber(PdfReader reader, int number, int generation) { return currentPdfReaderInstance.getNewObjectNumber(number, generation); } RandomAccessFileOrArray getReaderFile(PdfReader reader) { return currentPdfReaderInstance.getReaderFile(); } // [F6] spot colors /** The colors of this document */ protected HashMap documentColors = new HashMap(); /** The color number counter for the colors in the document. */ protected int colorNumber = 1; PdfName getColorspaceName() { return new PdfName("CS" + (colorNumber++)); } /** * Adds a SpotColor to the document but not to the page resources. * @param spc the SpotColor to add * @return an Object[] where position 0 is a PdfName * and position 1 is an PdfIndirectReference */ ColorDetails addSimple(PdfSpotColor spc) { ColorDetails ret = (ColorDetails)documentColors.get(spc); if (ret == null) { ret = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), spc); documentColors.put(spc, ret); } return ret; } // [F7] document patterns /** The patterns of this document */ protected HashMap documentPatterns = new HashMap(); /** The pattern number counter for the colors in the document. */ protected int patternNumber = 1; PdfName addSimplePattern(PdfPatternPainter painter) { PdfName name = (PdfName)documentPatterns.get(painter); try { if ( name == null ) { name = new PdfName("P" + patternNumber); ++patternNumber; documentPatterns.put(painter, name); } } catch (Exception e) { throw new ExceptionConverter(e); } return name; } // [F8] shading patterns protected HashMap documentShadingPatterns = new HashMap(); void addSimpleShadingPattern(PdfShadingPattern shading) { if (!documentShadingPatterns.containsKey(shading)) { shading.setName(patternNumber); ++patternNumber; documentShadingPatterns.put(shading, null); addSimpleShading(shading.getShading()); } } // [F9] document shadings protected HashMap documentShadings = new HashMap(); void addSimpleShading(PdfShading shading) { if (!documentShadings.containsKey(shading)) { documentShadings.put(shading, null); shading.setName(documentShadings.size()); } } // [F10] extended graphics state (for instance for transparency) protected HashMap documentExtGState = new HashMap(); PdfObject[] addSimpleExtGState(PdfDictionary gstate) { if (!documentExtGState.containsKey(gstate)) { PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_GSTATE, gstate); documentExtGState.put(gstate, new PdfObject[]{new PdfName("GS" + (documentExtGState.size() + 1)), getPdfIndirectReference()}); } return (PdfObject[])documentExtGState.get(gstate); } // [F11] adding properties (OCG, marked content) protected HashMap documentProperties = new HashMap(); PdfObject[] addSimpleProperty(Object prop, PdfIndirectReference refi) { if (!documentProperties.containsKey(prop)) { if (prop instanceof PdfOCG) PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null); documentProperties.put(prop, new PdfObject[]{new PdfName("Pr" + (documentProperties.size() + 1)), refi}); } return (PdfObject[])documentProperties.get(prop); } boolean propertyExists(Object prop) { return documentProperties.containsKey(prop); } // [F12] tagged PDF protected boolean tagged = false; protected PdfStructureTreeRoot structureTreeRoot; /** * Mark this document for tagging. It must be called before open. */ public void setTagged() { if (open) throw new IllegalArgumentException("Tagging must be set before opening the document."); tagged = true; } /** * Check if the document is marked for tagging. * @return true if the document is marked for tagging */ public boolean isTagged() { return tagged; } /** * Gets the structure tree root. If the document is not marked for tagging it will return null. * @return the structure tree root */ public PdfStructureTreeRoot getStructureTreeRoot() { if (tagged && structureTreeRoot == null) structureTreeRoot = new PdfStructureTreeRoot(this); return structureTreeRoot; } // [F13] Optional Content Groups /** A hashSet containing all the PdfLayer objects. */ protected HashSet documentOCG = new HashSet(); /** An array list used to define the order of an OCG tree. */ protected ArrayList documentOCGorder = new ArrayList(); /** The OCProperties in a catalog dictionary. */ protected PdfOCProperties OCProperties; /** The RBGroups array in an OCG dictionary */ protected PdfArray OCGRadioGroup = new PdfArray(); /** * The locked array in an OCG dictionary * @since 2.1.2 */ protected PdfArray OCGLocked = new PdfArray(); /** * Use this method to get the Optional Content Properties Dictionary. * Each call fills the dictionary with the current layer state. * It's advisable to only call this method right before close * and do any modifications at that time. * @return the Optional Content Properties Dictionary */ public PdfOCProperties getOCProperties() { fillOCProperties(true); return OCProperties; } /** * Use this method to set a collection of optional content groups * whose states are intended to follow a "radio button" paradigm. * That is, the state of at most one optional content group * in the array should be ON at a time: if one group is turned * ON, all others must be turned OFF. * @param group the radio group */ public void addOCGRadioGroup(ArrayList group) { PdfArray ar = new PdfArray(); for (int k = 0; k < group.size(); ++k) { PdfLayer layer = (PdfLayer)group.get(k); if (layer.getTitle() == null) ar.add(layer.getRef()); } if (ar.size() == 0) return; OCGRadioGroup.add(ar); } /** * Use this method to lock an optional content group. * The state of a locked group cannot be changed through the user interface * of a viewer application. Producers can use this entry to prevent the visibility * of content that depends on these groups from being changed by users. * @param layer the layer that needs to be added to the array of locked OCGs * @since 2.1.2 */ public void lockLayer(PdfLayer layer) { OCGLocked.add(layer.getRef()); } private static void getOCGOrder(PdfArray order, PdfLayer layer) { if (!layer.isOnPanel()) return; if (layer.getTitle() == null) order.add(layer.getRef()); ArrayList children = layer.getChildren(); if (children == null) return; PdfArray kids = new PdfArray(); if (layer.getTitle() != null) kids.add(new PdfString(layer.getTitle(), PdfObject.TEXT_UNICODE)); for (int k = 0; k < children.size(); ++k) { getOCGOrder(kids, (PdfLayer)children.get(k)); } if (kids.size() > 0) order.add(kids); } private void addASEvent(PdfName event, PdfName category) { PdfArray arr = new PdfArray(); for (Iterator it = documentOCG.iterator(); it.hasNext();) { PdfLayer layer = (PdfLayer)it.next(); PdfDictionary usage = (PdfDictionary)layer.get(PdfName.USAGE); if (usage != null && usage.get(category) != null) arr.add(layer.getRef()); } if (arr.size() == 0) return; PdfDictionary d = (PdfDictionary)OCProperties.get(PdfName.D); PdfArray arras = (PdfArray)d.get(PdfName.AS); if (arras == null) { arras = new PdfArray(); d.put(PdfName.AS, arras); } PdfDictionary as = new PdfDictionary(); as.put(PdfName.EVENT, event); as.put(PdfName.CATEGORY, new PdfArray(category)); as.put(PdfName.OCGS, arr); arras.add(as); } /** * @since 2.1.2 */ protected void fillOCProperties(boolean erase) { if (OCProperties == null) OCProperties = new PdfOCProperties(); if (erase) { OCProperties.remove(PdfName.OCGS); OCProperties.remove(PdfName.D); } if (OCProperties.get(PdfName.OCGS) == null) { PdfArray gr = new PdfArray(); for (Iterator it = documentOCG.iterator(); it.hasNext();) { PdfLayer layer = (PdfLayer)it.next(); gr.add(layer.getRef()); } OCProperties.put(PdfName.OCGS, gr); } if (OCProperties.get(PdfName.D) != null) return; ArrayList docOrder = new ArrayList(documentOCGorder); for (Iterator it = docOrder.iterator(); it.hasNext();) { PdfLayer layer = (PdfLayer)it.next(); if (layer.getParent() != null) it.remove(); } PdfArray order = new PdfArray(); for (Iterator it = docOrder.iterator(); it.hasNext();) { PdfLayer layer = (PdfLayer)it.next(); getOCGOrder(order, layer); } PdfDictionary d = new PdfDictionary(); OCProperties.put(PdfName.D, d); d.put(PdfName.ORDER, order); PdfArray gr = new PdfArray(); for (Iterator it = documentOCG.iterator(); it.hasNext();) { PdfLayer layer = (PdfLayer)it.next(); if (!layer.isOn()) gr.add(layer.getRef()); } if (gr.size() > 0) d.put(PdfName.OFF, gr); if (OCGRadioGroup.size() > 0) d.put(PdfName.RBGROUPS, OCGRadioGroup); if (OCGLocked.size() > 0) d.put(PdfName.LOCKED, OCGLocked); addASEvent(PdfName.VIEW, PdfName.ZOOM); addASEvent(PdfName.VIEW, PdfName.VIEW); addASEvent(PdfName.PRINT, PdfName.PRINT); addASEvent(PdfName.EXPORT, PdfName.EXPORT); d.put(PdfName.LISTMODE, PdfName.VISIBLEPAGES); } void registerLayer(PdfOCG layer) { PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_LAYER, null); if (layer instanceof PdfLayer) { PdfLayer la = (PdfLayer)layer; if (la.getTitle() == null) { if (!documentOCG.contains(layer)) { documentOCG.add(layer); documentOCGorder.add(layer); } } else { documentOCGorder.add(layer); } } else throw new IllegalArgumentException("Only PdfLayer is accepted."); } // User methods to change aspects of the page // [U1] page size /** * Use this method to get the size of the media box. * @return a Rectangle */ public Rectangle getPageSize() { return pdf.getPageSize(); } /** * Use this method to set the crop box. * The crop box should not be rotated even if the page is rotated. * This change only takes effect in the next page. * @param crop the crop box */ public void setCropBoxSize(Rectangle crop) { pdf.setCropBoxSize(crop); } /** * Use this method to set the page box sizes. * Allowed names are: "crop", "trim", "art" and "bleed". * @param boxName the box size * @param size the size */ public void setBoxSize(String boxName, Rectangle size) { pdf.setBoxSize(boxName, size); } /** * Use this method to get the size of a trim, art, crop or bleed box, * or null if not defined. * @param boxName crop, trim, art or bleed */ public Rectangle getBoxSize(String boxName) { return pdf.getBoxSize(boxName); } // [U2] take care of empty pages /** * Use this method to make sure a page is added, * even if it's empty. If you use setPageEmpty(false), * invoking newPage() after a blank page will add a newPage. * @param pageEmpty the state */ public void setPageEmpty(boolean pageEmpty) { pdf.setPageEmpty(pageEmpty); } // [U3] page actions (open and close) /** action value */ public static final PdfName PAGE_OPEN = PdfName.O; /** action value */ public static final PdfName PAGE_CLOSE = PdfName.C; /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setPageAction(com.lowagie.text.pdf.PdfName, com.lowagie.text.pdf.PdfAction) */ public void setPageAction(PdfName actionType, PdfAction action) throws DocumentException { if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) throw new DocumentException("Invalid page additional action type: " + actionType.toString()); pdf.setPageAction(actionType, action); } /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setDuration(int) */ public void setDuration(int seconds) { pdf.setDuration(seconds); } /** @see com.lowagie.text.pdf.interfaces.PdfPageActions#setTransition(com.lowagie.text.pdf.PdfTransition) */ public void setTransition(PdfTransition transition) { pdf.setTransition(transition); } // [U4] Thumbnail image /** * Use this method to set the thumbnail image for the current page. * @param image the image * @throws PdfException on error * @throws DocumentException or error */ public void setThumbnail(Image image) throws PdfException, DocumentException { pdf.setThumbnail(image); } // [U5] Transparency groups /** * A group attributes dictionary specifying the attributes * of the page's page group for use in the transparent * imaging model */ protected PdfDictionary group; /** * Use this method to get the group dictionary. * @return Value of property group. */ public PdfDictionary getGroup() { return this.group; } /** * Use this method to set the group dictionary. * @param group New value of property group. */ public void setGroup(PdfDictionary group) { this.group = group; } // [U6] space char ratio /** The default space-char ratio. */ public static final float SPACE_CHAR_RATIO_DEFAULT = 2.5f; /** Disable the inter-character spacing. */ public static final float NO_SPACE_CHAR_RATIO = 10000000f; /** * The ratio between the extra word spacing and the extra character spacing. * Extra word spacing will grow ratio times more than extra character spacing. */ private float spaceCharRatio = SPACE_CHAR_RATIO_DEFAULT; /** * Use this method to gets the space/character extra spacing ratio * for fully justified text. * @return the space/character extra spacing ratio */ public float getSpaceCharRatio() { return spaceCharRatio; } /** * Use this method to set the ratio between the extra word spacing and * the extra character spacing when the text is fully justified. * Extra word spacing will grow spaceCharRatio times more * than extra character spacing. If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO * then the extra character spacing will be zero. * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing */ public void setSpaceCharRatio(float spaceCharRatio) { if (spaceCharRatio < 0.001f) this.spaceCharRatio = 0.001f; else this.spaceCharRatio = spaceCharRatio; } // [U7] run direction (doesn't actually do anything) /** Use the default run direction. */ public static final int RUN_DIRECTION_DEFAULT = 0; /** Do not use bidirectional reordering. */ public static final int RUN_DIRECTION_NO_BIDI = 1; /** Use bidirectional reordering with left-to-right * preferential run direction. */ public static final int RUN_DIRECTION_LTR = 2; /** Use bidirectional reordering with right-to-left * preferential run direction. */ public static final int RUN_DIRECTION_RTL = 3; protected int runDirection = RUN_DIRECTION_NO_BIDI; /** * Use this method to set the run direction. * This is only used as a placeholder as it does not affect anything. * @param runDirection the run direction */ public void setRunDirection(int runDirection) { if (runDirection < RUN_DIRECTION_NO_BIDI || runDirection > RUN_DIRECTION_RTL) throw new RuntimeException("Invalid run direction: " + runDirection); this.runDirection = runDirection; } /** * Use this method to set the run direction. * @return the run direction */ public int getRunDirection() { return runDirection; } // [U8] user units protected float userunit = 0f; /** * Use this method to get the user unit. * A user unit is a value that defines the default user space unit. * The minimum UserUnit is 1 (1 unit = 1/72 inch). * The maximum UserUnit is 75,000. * Note that this userunit only works starting with PDF1.6! * @return Returns the userunit. */ public float getUserunit() { return userunit; } /** * Use this method to set the user unit. * A UserUnit is a value that defines the default user space unit. * The minimum UserUnit is 1 (1 unit = 1/72 inch). * The maximum UserUnit is 75,000. * Note that this userunit only works starting with PDF1.6! * @param userunit The userunit to set. * @throws DocumentException on error */ public void setUserunit(float userunit) throws DocumentException { if (userunit < 1f || userunit > 75000f) throw new DocumentException("UserUnit should be a value between 1 and 75000."); this.userunit = userunit; setAtLeastPdfVersion(VERSION_1_6); } // Miscellaneous topics // [M1] Color settings protected PdfDictionary defaultColorspace = new PdfDictionary(); /** * Use this method to get the default colorspaces. * @return the default colorspaces */ public PdfDictionary getDefaultColorspace() { return defaultColorspace; } /** * Use this method to sets the default colorspace that will be applied * to all the document. The colorspace is only applied if another colorspace * with the same name is not present in the content. *

* The colorspace is applied immediately when creating templates and * at the page end for the main document content. * @param key the name of the colorspace. It can be PdfName.DEFAULTGRAY, PdfName.DEFAULTRGB * or PdfName.DEFAULTCMYK * @param cs the colorspace. A null or PdfNull removes any colorspace with the same name */ public void setDefaultColorspace(PdfName key, PdfObject cs) { if (cs == null || cs.isNull()) defaultColorspace.remove(key); defaultColorspace.put(key, cs); } // [M2] spot patterns protected HashMap documentSpotPatterns = new HashMap(); protected ColorDetails patternColorspaceRGB; protected ColorDetails patternColorspaceGRAY; protected ColorDetails patternColorspaceCMYK; ColorDetails addSimplePatternColorspace(Color color) { int type = ExtendedColor.getType(color); if (type == ExtendedColor.TYPE_PATTERN || type == ExtendedColor.TYPE_SHADING) throw new RuntimeException("An uncolored tile pattern can not have another pattern or shading as color."); try { switch (type) { case ExtendedColor.TYPE_RGB: if (patternColorspaceRGB == null) { patternColorspaceRGB = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); PdfArray array = new PdfArray(PdfName.PATTERN); array.add(PdfName.DEVICERGB); addToBody(array, patternColorspaceRGB.getIndirectReference()); } return patternColorspaceRGB; case ExtendedColor.TYPE_CMYK: if (patternColorspaceCMYK == null) { patternColorspaceCMYK = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); PdfArray array = new PdfArray(PdfName.PATTERN); array.add(PdfName.DEVICECMYK); addToBody(array, patternColorspaceCMYK.getIndirectReference()); } return patternColorspaceCMYK; case ExtendedColor.TYPE_GRAY: if (patternColorspaceGRAY == null) { patternColorspaceGRAY = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); PdfArray array = new PdfArray(PdfName.PATTERN); array.add(PdfName.DEVICEGRAY); addToBody(array, patternColorspaceGRAY.getIndirectReference()); } return patternColorspaceGRAY; case ExtendedColor.TYPE_SEPARATION: { ColorDetails details = addSimple(((SpotColor)color).getPdfSpotColor()); ColorDetails patternDetails = (ColorDetails)documentSpotPatterns.get(details); if (patternDetails == null) { patternDetails = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); PdfArray array = new PdfArray(PdfName.PATTERN); array.add(details.getIndirectReference()); addToBody(array, patternDetails.getIndirectReference()); documentSpotPatterns.put(details, patternDetails); } return patternDetails; } default: throw new RuntimeException("Invalid color type in PdfWriter.addSimplePatternColorspace()."); } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } // [M3] Images /** * Use this method to get the strictImageSequence status. * @return value of property strictImageSequence */ public boolean isStrictImageSequence() { return pdf.isStrictImageSequence(); } /** * Use this method to set the image sequence, so that it follows * the text in strict order (or not). * @param strictImageSequence new value of property strictImageSequence * */ public void setStrictImageSequence(boolean strictImageSequence) { pdf.setStrictImageSequence(strictImageSequence); } /** * Use this method to clear text wrapping around images (if applicable). * @throws DocumentException */ public void clearTextWrap() throws DocumentException { pdf.clearTextWrap(); } /** Dictionary, containing all the images of the PDF document */ protected PdfDictionary imageDictionary = new PdfDictionary(); /** This is the list with all the images in the document. */ private HashMap images = new HashMap(); /** * Use this method to adds an image to the document * but not to the page resources. It is used with * templates and Document.add(Image). * Use this method only if you know what you're doing! * @param image the Image to add * @return the name of the image added * @throws PdfException on error * @throws DocumentException on error */ public PdfName addDirectImageSimple(Image image) throws PdfException, DocumentException { return addDirectImageSimple(image, null); } /** * Adds an image to the document but not to the page resources. * It is used with templates and Document.add(Image). * Use this method only if you know what you're doing! * @param image the Image to add * @param fixedRef the reference to used. It may be null, * a PdfIndirectReference or a PRIndirectReference. * @return the name of the image added * @throws PdfException on error * @throws DocumentException on error */ public PdfName addDirectImageSimple(Image image, PdfIndirectReference fixedRef) throws PdfException, DocumentException { PdfName name; // if the images is already added, just retrieve the name if (images.containsKey(image.getMySerialId())) { name = (PdfName) images.get(image.getMySerialId()); } // if it's a new image, add it to the document else { if (image.isImgTemplate()) { name = new PdfName("img" + images.size()); if(image instanceof ImgWMF){ try { ImgWMF wmf = (ImgWMF)image; wmf.readWMF(PdfTemplate.createTemplate(this, 0, 0)); } catch (Exception e) { throw new DocumentException(e); } } } else { PdfIndirectReference dref = image.getDirectReference(); if (dref != null) { PdfName rname = new PdfName("img" + images.size()); images.put(image.getMySerialId(), rname); imageDictionary.put(rname, dref); return rname; } Image maskImage = image.getImageMask(); PdfIndirectReference maskRef = null; if (maskImage != null) { PdfName mname = (PdfName)images.get(maskImage.getMySerialId()); maskRef = getImageReference(mname); } PdfImage i = new PdfImage(image, "img" + images.size(), maskRef); if (image instanceof ImgJBIG2) { byte[] globals = ((ImgJBIG2) image).getGlobalBytes(); if (globals != null) { PdfDictionary decodeparms = new PdfDictionary(); decodeparms.put(PdfName.JBIG2GLOBALS, getReferenceJBIG2Globals(globals)); i.put(PdfName.DECODEPARMS, decodeparms); } } if (image.hasICCProfile()) { PdfICCBased icc = new PdfICCBased(image.getICCProfile(), image.getCompressionLevel()); PdfIndirectReference iccRef = add(icc); PdfArray iccArray = new PdfArray(); iccArray.add(PdfName.ICCBASED); iccArray.add(iccRef); PdfArray colorspace = i.getAsArray(PdfName.COLORSPACE); if (colorspace != null) { if (colorspace.size() > 1 && PdfName.INDEXED.equals(colorspace.getPdfObject(0))) colorspace.set(1, iccArray); else i.put(PdfName.COLORSPACE, iccArray); } else i.put(PdfName.COLORSPACE, iccArray); } add(i, fixedRef); name = i.name(); } images.put(image.getMySerialId(), name); } return name; } /** * Writes a PdfImage to the outputstream. * * @param pdfImage the image to be added * @return a PdfIndirectReference to the encapsulated image * @throws PdfException when a document isn't open yet, or has been closed */ PdfIndirectReference add(PdfImage pdfImage, PdfIndirectReference fixedRef) throws PdfException { if (! imageDictionary.contains(pdfImage.name())) { PdfXConformanceImp.checkPDFXConformance(this, PdfXConformanceImp.PDFXKEY_IMAGE, pdfImage); if (fixedRef instanceof PRIndirectReference) { PRIndirectReference r2 = (PRIndirectReference)fixedRef; fixedRef = new PdfIndirectReference(0, getNewObjectNumber(r2.getReader(), r2.getNumber(), r2.getGeneration())); } try { if (fixedRef == null) fixedRef = addToBody(pdfImage).getIndirectReference(); else addToBody(pdfImage, fixedRef); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } imageDictionary.put(pdfImage.name(), fixedRef); return fixedRef; } return (PdfIndirectReference) imageDictionary.get(pdfImage.name()); } /** * return the PdfIndirectReference to the image with a given name. * * @param name the name of the image * @return a PdfIndirectReference */ PdfIndirectReference getImageReference(PdfName name) { return (PdfIndirectReference) imageDictionary.get(name); } protected PdfIndirectReference add(PdfICCBased icc) { PdfIndirectObject object; try { object = addToBody(icc); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } return object.getIndirectReference(); } /** * A HashSet with Stream objects containing JBIG2 Globals * @since 2.1.5 */ protected HashMap JBIG2Globals = new HashMap(); /** * Gets an indirect reference to a JBIG2 Globals stream. * Adds the stream if it hasn't already been added to the writer. * @param content a byte array that may already been added to the writer inside a stream object. * @since 2.1.5 */ protected PdfIndirectReference getReferenceJBIG2Globals(byte[] content) { if (content == null) return null; PdfStream stream; for (Iterator i = JBIG2Globals.keySet().iterator(); i.hasNext(); ) { stream = (PdfStream) i.next(); if (Arrays.equals(content, stream.getBytes())) { return (PdfIndirectReference) JBIG2Globals.get(stream); } } stream = new PdfStream(content); PdfIndirectObject ref; try { ref = addToBody(stream); } catch (IOException e) { return null; } JBIG2Globals.put(stream, ref.getIndirectReference()); return ref.getIndirectReference(); } // [M4] Old table functionality; do we still need it? /** * Checks if a Table fits the current page of the PdfDocument. * * @param table the table that has to be checked * @param margin a certain margin * @return true if the Table fits the page, false otherwise. */ public boolean fitsPage(Table table, float margin) { return pdf.bottom(table) > pdf.indentBottom() + margin; } /** * Checks if a Table fits the current page of the PdfDocument. * * @param table the table that has to be checked * @return true if the Table fits the page, false otherwise. */ public boolean fitsPage(Table table) { return fitsPage(table, 0); } // [F12] tagged PDF /** * A flag indicating the presence of structure elements that contain user properties attributes. */ private boolean userProperties; /** * Gets the flag indicating the presence of structure elements that contain user properties attributes. * @return the user properties flag */ public boolean isUserProperties() { return this.userProperties; } /** * Sets the flag indicating the presence of structure elements that contain user properties attributes. * @param userProperties the user properties flag */ public void setUserProperties(boolean userProperties) { this.userProperties = userProperties; } /** * Holds value of property RGBTranparency. */ private boolean rgbTransparencyBlending; /** * Gets the transparency blending colorspace. * @return true if the transparency blending colorspace is RGB, false * if it is the default blending colorspace * @since 2.1.0 */ public boolean isRgbTransparencyBlending() { return this.rgbTransparencyBlending; } /** * Sets the transparency blending colorspace to RGB. The default blending colorspace is * CMYK and will result in faded colors in the screen and in printing. Calling this method * will return the RGB colors to what is expected. The RGB blending will be applied to all subsequent pages * until other value is set. * Note that this is a generic solution that may not work in all cases. * @param rgbTransparencyBlending true to set the transparency blending colorspace to RGB, false * to use the default blending colorspace * @since 2.1.0 */ public void setRgbTransparencyBlending(boolean rgbTransparencyBlending) { this.rgbTransparencyBlending = rgbTransparencyBlending; } } src/core/com/lowagie/text/pdf/PdfXConformanceException.java100644 0 0 5636 11012562273 21435 0ustar 0 0 /* * $Id: PdfXConformanceException.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2004 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * * @author psoares */ public class PdfXConformanceException extends RuntimeException { private static final long serialVersionUID = 9199144538884293397L; /** Creates a new instance of PdfXConformanceException. */ public PdfXConformanceException() { } /** * Creates a new instance of PdfXConformanceException. * @param s */ public PdfXConformanceException(String s) { super(s); } } src/core/com/lowagie/text/pdf/Pfm2afm.java100644 0 0 102217 11036112746 16065 0ustar 0 0 /* * $Id: Pfm2afm.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 1991 Ken Borgendale * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ /******************************************************************** * * * Title: pfm2afm - Convert Windows .pfm files to .afm files * * * * Author: Ken Borgendale 10/9/91 Version 1.0 * * * * Function: * * Convert a Windows .pfm (Printer Font Metrics) file to a * * .afm (Adobe Font Metrics) file. The purpose of this is * * to allow fonts put out for Windows to be used with OS/2. * * * * Syntax: * * pfm2afm infile [outfile] -a * * * * Copyright: * * pfm2afm - Copyright (C) IBM Corp., 1991 * * * * This code is released for public use as long as the * * copyright remains intact. This code is provided asis * * without any warrenties, express or implied. * * * * Notes: * * 1. Much of the information in the original .afm file is * * lost when the .pfm file is created, and thus cannot be * * reconstructed by this utility. This is especially true * * of data for characters not in the Windows character set. * * * * 2. This module is coded to be compiled by the MSC 6.0. * * For other compilers, be careful of the packing of the * * PFM structure. * * * ********************************************************************/ /******************************************************************** * * * Modifications by Rod Smith, 5/22/96 * * * * These changes look for the strings "italic", "bold", "black", * * and "light" in the font's name and set the weight accordingly * * and adds an ItalicAngle line with a value of "0" or "-12.00". * * This allows OS/2 programs such as DeScribe to handle the bold * * and italic attributes appropriately, which was not the case * * when I used the original version on fonts from the KeyFonts * * Pro 2002 font CD. * * * * I've also increased the size of the buffer used to load the * * .PFM file; the old size was inadequate for most of the fonts * * from the SoftKey collection. * * * * Compiled with Watcom C 10.6 * * * ********************************************************************/ /******************************************************************** * * * Further modifications, 4/21/98, by Rod Smith * * * * Minor changes to get the program to compile with gcc under * * Linux (Red Hat 5.0, to be precise). I had to add an itoa * * function from the net (the function was buggy, so I had to fix * * it, too!). I also made the program more friendly towards * * files with mixed-case filenames. * * * ********************************************************************/ /******************************************************************** * * * 1/31/2005, by Paulo Soares * * * * This code was integrated into iText. * * Note that the itoa function mentioned in the comment by Rod * * Smith is no longer in the code because Java has native support * * in PrintWriter to convert integers to strings * * * ********************************************************************/ /******************************************************************** * * * 7/16/2005, by Bruno Lowagie * * * * I solved an Eclipse Warning. * * * ********************************************************************/ /******************************************************************** * * * 9/14/2006, by Xavier Le Vourch * * * * expand import clauses (import java.io.*) * * the removal of an exception in readString was restored on 9/16 * * * ********************************************************************/ package com.lowagie.text.pdf; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; /** * Converts a PFM file into an AFM file. */ public final class Pfm2afm { private RandomAccessFileOrArray in; private PrintWriter out; /** Creates a new instance of Pfm2afm */ private Pfm2afm(RandomAccessFileOrArray in, OutputStream out) throws IOException { this.in = in; this.out = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1")); } /** * Converts a PFM file into an AFM file. * @param in the PFM file * @param out the AFM file * @throws IOException on error */ public static void convert(RandomAccessFileOrArray in, OutputStream out) throws IOException { Pfm2afm p = new Pfm2afm(in, out); p.openpfm(); p.putheader(); p.putchartab(); p.putkerntab(); p.puttrailer(); p.out.flush(); } public static void main(String[] args) { try { RandomAccessFileOrArray in = new RandomAccessFileOrArray(args[0]); OutputStream out = new FileOutputStream(args[1]); convert(in, out); in.close(); out.close(); } catch (Exception e) { e.printStackTrace(); } } private String readString(int n) throws IOException { byte b[] = new byte[n]; in.readFully(b); int k; for (k = 0; k < b.length; ++k) { if (b[k] == 0) break; } return new String(b, 0, k, "ISO-8859-1"); } private String readString() throws IOException { StringBuffer buf = new StringBuffer(); while (true) { int c = in.read(); if (c <= 0) break; buf.append((char)c); } return buf.toString(); } private void outval(int n) { out.print(' '); out.print(n); } /* * Output a character entry */ private void outchar(int code, int width, String name) { out.print("C "); outval(code); out.print(" ; WX "); outval(width); if (name != null) { out.print(" ; N "); out.print(name); } out.print(" ;\n"); } private void openpfm() throws IOException { in.seek(0); vers = in.readShortLE(); h_len = in.readIntLE(); copyright = readString(60); type = in.readShortLE(); points = in.readShortLE(); verres = in.readShortLE(); horres = in.readShortLE(); ascent = in.readShortLE(); intleading = in.readShortLE(); extleading = in.readShortLE(); italic = (byte)in.read(); uline = (byte)in.read(); overs = (byte)in.read(); weight = in.readShortLE(); charset = (byte)in.read(); pixwidth = in.readShortLE(); pixheight = in.readShortLE(); kind = (byte)in.read(); avgwidth = in.readShortLE(); maxwidth = in.readShortLE(); firstchar = in.read(); lastchar = in.read(); defchar = (byte)in.read(); brkchar = (byte)in.read(); widthby = in.readShortLE(); device = in.readIntLE(); face = in.readIntLE(); bits = in.readIntLE(); bitoff = in.readIntLE(); extlen = in.readShortLE(); psext = in.readIntLE(); chartab = in.readIntLE(); res1 = in.readIntLE(); kernpairs = in.readIntLE(); res2 = in.readIntLE(); fontname = in.readIntLE(); if (h_len != in.length() || extlen != 30 || fontname < 75 || fontname > 512) throw new IOException("Not a valid PFM file."); in.seek(psext + 14); capheight = in.readShortLE(); xheight = in.readShortLE(); ascender = in.readShortLE(); descender = in.readShortLE(); } private void putheader() throws IOException { out.print("StartFontMetrics 2.0\n"); if (copyright.length() > 0) out.print("Comment " + copyright + '\n'); out.print("FontName "); in.seek(fontname); String fname = readString(); out.print(fname); out.print("\nEncodingScheme "); if (charset != 0) out.print("FontSpecific\n"); else out.print("AdobeStandardEncoding\n"); /* * The .pfm is missing full name, so construct from font name by * changing the hyphen to a space. This actually works in a lot * of cases. */ out.print("FullName " + fname.replace('-', ' ')); if (face != 0) { in.seek(face); out.print("\nFamilyName " + readString()); } out.print("\nWeight "); if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0) out.print("Bold"); else if ((weight < 325 && weight != 0) || fname.toLowerCase().indexOf("light") >= 0) out.print("Light"); else if (fname.toLowerCase().indexOf("black") >= 0) out.print("Black"); else out.print("Medium"); out.print("\nItalicAngle "); if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0) out.print("-12.00"); /* this is a typical value; something else may work better for a specific font */ else out.print("0"); /* * The mono flag in the pfm actually indicates whether there is a * table of font widths, not if they are all the same. */ out.print("\nIsFixedPitch "); if ((kind & 1) == 0 || /* Flag for mono */ avgwidth == maxwidth ) { /* Avg width = max width */ out.print("true"); isMono = true; } else { out.print("false"); isMono = false; } /* * The font bounding box is lost, but try to reconstruct it. * Much of this is just guess work. The bounding box is required in * the .afm, but is not used by the PM font installer. */ out.print("\nFontBBox"); if (isMono) outval(-20); /* Just guess at left bounds */ else outval(-100); outval(-(descender+5)); /* Descender is given as positive value */ outval(maxwidth+10); outval(ascent+5); /* * Give other metrics that were kept */ out.print("\nCapHeight"); outval(capheight); out.print("\nXHeight"); outval(xheight); out.print("\nDescender"); outval(descender); out.print("\nAscender"); outval(ascender); out.print('\n'); } private void putchartab() throws IOException { int count = lastchar - firstchar + 1; int ctabs[] = new int[count]; in.seek(chartab); for (int k = 0; k < count; ++k) ctabs[k] = in.readUnsignedShortLE(); int back[] = new int[256]; if (charset == 0) { for (int i = firstchar; i <= lastchar; ++i) { if (Win2PSStd[i] != 0) back[Win2PSStd[i]] = i; } } /* Put out the header */ out.print("StartCharMetrics"); outval(count); out.print('\n'); /* Put out all encoded chars */ if (charset != 0) { /* * If the charset is not the Windows standard, just put out * unnamed entries. */ for (int i = firstchar; i <= lastchar; i++) { if (ctabs[i - firstchar] != 0) { outchar(i, ctabs[i - firstchar], null); } } } else { for (int i = 0; i < 256; i++) { int j = back[i]; if (j != 0) { outchar(i, ctabs[j - firstchar], WinChars[j]); ctabs[j - firstchar] = 0; } } /* Put out all non-encoded chars */ for (int i = firstchar; i <= lastchar; i++) { if (ctabs[i - firstchar] != 0) { outchar(-1, ctabs[i - firstchar], WinChars[i]); } } } /* Put out the trailer */ out.print("EndCharMetrics\n"); } private void putkerntab() throws IOException { if (kernpairs == 0) return; in.seek(kernpairs); int count = in.readUnsignedShortLE(); int nzero = 0; int kerns[] = new int[count * 3]; for (int k = 0; k < kerns.length;) { kerns[k++] = in.read(); kerns[k++] = in.read(); if ((kerns[k++] = in.readShortLE()) != 0) ++nzero; } if (nzero == 0) return; out.print("StartKernData\nStartKernPairs"); outval(nzero); out.print('\n'); for (int k = 0; k < kerns.length; k += 3) { if (kerns[k + 2] != 0) { out.print("KPX "); out.print(WinChars[kerns[k]]); out.print(' '); out.print(WinChars[kerns[k + 1]]); outval(kerns[k + 2]); out.print('\n'); } } /* Put out trailer */ out.print("EndKernPairs\nEndKernData\n"); } private void puttrailer() { out.print("EndFontMetrics\n"); } private short vers; private int h_len; /* Total length of .pfm file */ private String copyright; /* Copyright string [60]*/ private short type; private short points; private short verres; private short horres; private short ascent; private short intleading; private short extleading; private byte italic; private byte uline; private byte overs; private short weight; private byte charset; /* 0=windows, otherwise nomap */ private short pixwidth; /* Width for mono fonts */ private short pixheight; private byte kind; /* Lower bit off in mono */ private short avgwidth; /* Mono if avg=max width */ private short maxwidth; /* Use to compute bounding box */ private int firstchar; /* First char in table */ private int lastchar; /* Last char in table */ private byte defchar; private byte brkchar; private short widthby; private int device; private int face; /* Face name */ private int bits; private int bitoff; private short extlen; private int psext; /* PostScript extension */ private int chartab; /* Character width tables */ private int res1; private int kernpairs; /* Kerning pairs */ private int res2; private int fontname; /* Font name */ /* * Some metrics from the PostScript extension */ private short capheight; /* Cap height */ private short xheight; /* X height */ private short ascender; /* Ascender */ private short descender; /* Descender (positive) */ private boolean isMono; /** * Translate table from 1004 to psstd. 1004 is an extension of the * Windows translate table used in PM. */ private int Win2PSStd[] = { 0, 0, 0, 0, 197, 198, 199, 0, 202, 0, 205, 206, 207, 0, 0, 0, // 00 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42, 43, 44, 45, 46, 47, // 20 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 30 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 40 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 50 193, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 60 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 70 0, 0, 184, 166, 185, 188, 178, 179, 195, 189, 0, 172, 234, 0, 0, 0, // 80 0, 96, 0, 170, 186, 183, 177, 208, 196, 0, 0, 173, 250, 0, 0, 0, // 90 0, 161, 162, 163, 168, 165, 0, 167, 200, 0, 227, 171, 0, 0, 0, 197, // A0 0, 0, 0, 0, 194, 0, 182, 180, 203, 0, 235, 187, 0, 0, 0, 191, // B0 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C0 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 251, // D0 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E0 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0 // F0 }; /** * Character class. This is a minor attempt to overcome the problem that * in the pfm file, all unused characters are given the width of space. * Note that this array isn't used in iText. */ private int WinClass[] = { 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, /* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, /* 70 */ 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 80 */ 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, /* 90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f0 */ }; /** * Windows character names. Give a name to the used locations * for when the all flag is specified. */ private String WinChars[] = { "W00", /* 00 */ "W01", /* 01 */ "W02", /* 02 */ "W03", /* 03 */ "macron", /* 04 */ "breve", /* 05 */ "dotaccent", /* 06 */ "W07", /* 07 */ "ring", /* 08 */ "W09", /* 09 */ "W0a", /* 0a */ "W0b", /* 0b */ "W0c", /* 0c */ "W0d", /* 0d */ "W0e", /* 0e */ "W0f", /* 0f */ "hungarumlaut", /* 10 */ "ogonek", /* 11 */ "caron", /* 12 */ "W13", /* 13 */ "W14", /* 14 */ "W15", /* 15 */ "W16", /* 16 */ "W17", /* 17 */ "W18", /* 18 */ "W19", /* 19 */ "W1a", /* 1a */ "W1b", /* 1b */ "W1c", /* 1c */ "W1d", /* 1d */ "W1e", /* 1e */ "W1f", /* 1f */ "space", /* 20 */ "exclam", /* 21 */ "quotedbl", /* 22 */ "numbersign", /* 23 */ "dollar", /* 24 */ "percent", /* 25 */ "ampersand", /* 26 */ "quotesingle", /* 27 */ "parenleft", /* 28 */ "parenright", /* 29 */ "asterisk", /* 2A */ "plus", /* 2B */ "comma", /* 2C */ "hyphen", /* 2D */ "period", /* 2E */ "slash", /* 2F */ "zero", /* 30 */ "one", /* 31 */ "two", /* 32 */ "three", /* 33 */ "four", /* 34 */ "five", /* 35 */ "six", /* 36 */ "seven", /* 37 */ "eight", /* 38 */ "nine", /* 39 */ "colon", /* 3A */ "semicolon", /* 3B */ "less", /* 3C */ "equal", /* 3D */ "greater", /* 3E */ "question", /* 3F */ "at", /* 40 */ "A", /* 41 */ "B", /* 42 */ "C", /* 43 */ "D", /* 44 */ "E", /* 45 */ "F", /* 46 */ "G", /* 47 */ "H", /* 48 */ "I", /* 49 */ "J", /* 4A */ "K", /* 4B */ "L", /* 4C */ "M", /* 4D */ "N", /* 4E */ "O", /* 4F */ "P", /* 50 */ "Q", /* 51 */ "R", /* 52 */ "S", /* 53 */ "T", /* 54 */ "U", /* 55 */ "V", /* 56 */ "W", /* 57 */ "X", /* 58 */ "Y", /* 59 */ "Z", /* 5A */ "bracketleft", /* 5B */ "backslash", /* 5C */ "bracketright", /* 5D */ "asciicircum", /* 5E */ "underscore", /* 5F */ "grave", /* 60 */ "a", /* 61 */ "b", /* 62 */ "c", /* 63 */ "d", /* 64 */ "e", /* 65 */ "f", /* 66 */ "g", /* 67 */ "h", /* 68 */ "i", /* 69 */ "j", /* 6A */ "k", /* 6B */ "l", /* 6C */ "m", /* 6D */ "n", /* 6E */ "o", /* 6F */ "p", /* 70 */ "q", /* 71 */ "r", /* 72 */ "s", /* 73 */ "t", /* 74 */ "u", /* 75 */ "v", /* 76 */ "w", /* 77 */ "x", /* 78 */ "y", /* 79 */ "z", /* 7A */ "braceleft", /* 7B */ "bar", /* 7C */ "braceright", /* 7D */ "asciitilde", /* 7E */ "W7f", /* 7F */ "euro", /* 80 */ "W81", /* 81 */ "quotesinglbase", /* 82 */ "florin", /* 83 */ "quotedblbase", /* 84 */ "ellipsis", /* 85 */ "dagger", /* 86 */ "daggerdbl", /* 87 */ "circumflex", /* 88 */ "perthousand", /* 89 */ "Scaron", /* 8A */ "guilsinglleft", /* 8B */ "OE", /* 8C */ "W8d", /* 8D */ "Zcaron", /* 8E */ "W8f", /* 8F */ "W90", /* 90 */ "quoteleft", /* 91 */ "quoteright", /* 92 */ "quotedblleft", /* 93 */ "quotedblright", /* 94 */ "bullet", /* 95 */ "endash", /* 96 */ "emdash", /* 97 */ "tilde", /* 98 */ "trademark", /* 99 */ "scaron", /* 9A */ "guilsinglright", /* 9B */ "oe", /* 9C */ "W9d", /* 9D */ "zcaron", /* 9E */ "Ydieresis", /* 9F */ "reqspace", /* A0 */ "exclamdown", /* A1 */ "cent", /* A2 */ "sterling", /* A3 */ "currency", /* A4 */ "yen", /* A5 */ "brokenbar", /* A6 */ "section", /* A7 */ "dieresis", /* A8 */ "copyright", /* A9 */ "ordfeminine", /* AA */ "guillemotleft", /* AB */ "logicalnot", /* AC */ "syllable", /* AD */ "registered", /* AE */ "macron", /* AF */ "degree", /* B0 */ "plusminus", /* B1 */ "twosuperior", /* B2 */ "threesuperior", /* B3 */ "acute", /* B4 */ "mu", /* B5 */ "paragraph", /* B6 */ "periodcentered", /* B7 */ "cedilla", /* B8 */ "onesuperior", /* B9 */ "ordmasculine", /* BA */ "guillemotright", /* BB */ "onequarter", /* BC */ "onehalf", /* BD */ "threequarters", /* BE */ "questiondown", /* BF */ "Agrave", /* C0 */ "Aacute", /* C1 */ "Acircumflex", /* C2 */ "Atilde", /* C3 */ "Adieresis", /* C4 */ "Aring", /* C5 */ "AE", /* C6 */ "Ccedilla", /* C7 */ "Egrave", /* C8 */ "Eacute", /* C9 */ "Ecircumflex", /* CA */ "Edieresis", /* CB */ "Igrave", /* CC */ "Iacute", /* CD */ "Icircumflex", /* CE */ "Idieresis", /* CF */ "Eth", /* D0 */ "Ntilde", /* D1 */ "Ograve", /* D2 */ "Oacute", /* D3 */ "Ocircumflex", /* D4 */ "Otilde", /* D5 */ "Odieresis", /* D6 */ "multiply", /* D7 */ "Oslash", /* D8 */ "Ugrave", /* D9 */ "Uacute", /* DA */ "Ucircumflex", /* DB */ "Udieresis", /* DC */ "Yacute", /* DD */ "Thorn", /* DE */ "germandbls", /* DF */ "agrave", /* E0 */ "aacute", /* E1 */ "acircumflex", /* E2 */ "atilde", /* E3 */ "adieresis", /* E4 */ "aring", /* E5 */ "ae", /* E6 */ "ccedilla", /* E7 */ "egrave", /* E8 */ "eacute", /* E9 */ "ecircumflex", /* EA */ "edieresis", /* EB */ "igrave", /* EC */ "iacute", /* ED */ "icircumflex", /* EE */ "idieresis", /* EF */ "eth", /* F0 */ "ntilde", /* F1 */ "ograve", /* F2 */ "oacute", /* F3 */ "ocircumflex", /* F4 */ "otilde", /* F5 */ "odieresis", /* F6 */ "divide", /* F7 */ "oslash", /* F8 */ "ugrave", /* F9 */ "uacute", /* FA */ "ucircumflex", /* FB */ "udieresis", /* FC */ "yacute", /* FD */ "thorn", /* FE */ "ydieresis" /* FF */ }; }src/core/com/lowagie/text/pdf/PushbuttonField.java100644 0 0 63707 11154165266 17714 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; /** * Creates a pushbutton field. It supports all the text and icon alignments. * The icon may be an image or a template. *

* Example usage: *

*

 * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
 * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
 * document.open();
 * PdfContentByte cb = writer.getDirectContent();
 * Image img = Image.getInstance("image.png");
 * PushbuttonField bt = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1");
 * bt.setText("My Caption");
 * bt.setFontSize(0);
 * bt.setImage(img);
 * bt.setLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM);
 * bt.setBackgroundColor(Color.cyan);
 * bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
 * bt.setBorderColor(Color.red);
 * bt.setBorderWidth(3);
 * PdfFormField ff = bt.getField();
 * PdfAction ac = PdfAction.createSubmitForm("http://www.submit-site.com", null, 0);
 * ff.setAction(ac);
 * writer.addAnnotation(ff);
 * document.close();
 * 
* @author Paulo Soares (psoares@consiste.pt) */ public class PushbuttonField extends BaseField { /** A layout option */ public static final int LAYOUT_LABEL_ONLY = 1; /** A layout option */ public static final int LAYOUT_ICON_ONLY = 2; /** A layout option */ public static final int LAYOUT_ICON_TOP_LABEL_BOTTOM = 3; /** A layout option */ public static final int LAYOUT_LABEL_TOP_ICON_BOTTOM = 4; /** A layout option */ public static final int LAYOUT_ICON_LEFT_LABEL_RIGHT = 5; /** A layout option */ public static final int LAYOUT_LABEL_LEFT_ICON_RIGHT = 6; /** A layout option */ public static final int LAYOUT_LABEL_OVER_ICON = 7; /** An icon scaling option */ public static final int SCALE_ICON_ALWAYS = 1; /** An icon scaling option */ public static final int SCALE_ICON_NEVER = 2; /** An icon scaling option */ public static final int SCALE_ICON_IS_TOO_BIG = 3; /** An icon scaling option */ public static final int SCALE_ICON_IS_TOO_SMALL = 4; /** * Holds value of property layout. */ private int layout = LAYOUT_LABEL_ONLY; /** * Holds value of property image. */ private Image image; /** * Holds value of property template. */ private PdfTemplate template; /** * Holds value of property scaleIcon. */ private int scaleIcon = SCALE_ICON_ALWAYS; /** * Holds value of property proportionalIcon. */ private boolean proportionalIcon = true; /** * Holds value of property iconVerticalAdjustment. */ private float iconVerticalAdjustment = 0.5f; /** * Holds value of property iconHorizontalAdjustment. */ private float iconHorizontalAdjustment = 0.5f; /** * Holds value of property iconFitToBounds. */ private boolean iconFitToBounds; private PdfTemplate tp; /** * Creates a new instance of PushbuttonField * @param writer the document PdfWriter * @param box the field location and dimensions * @param fieldName the field name. If null only the widget keys * will be included in the field allowing it to be used as a kid field. */ public PushbuttonField(PdfWriter writer, Rectangle box, String fieldName) { super(writer, box, fieldName); } /** * Getter for property layout. * @return Value of property layout. */ public int getLayout() { return this.layout; } /** * Sets the icon and label layout. Possible values are LAYOUT_LABEL_ONLY, * LAYOUT_ICON_ONLY, LAYOUT_ICON_TOP_LABEL_BOTTOM, * LAYOUT_LABEL_TOP_ICON_BOTTOM, LAYOUT_ICON_LEFT_LABEL_RIGHT, * LAYOUT_LABEL_LEFT_ICON_RIGHT and LAYOUT_LABEL_OVER_ICON. * The default is LAYOUT_LABEL_ONLY. * @param layout New value of property layout. */ public void setLayout(int layout) { if (layout < LAYOUT_LABEL_ONLY || layout > LAYOUT_LABEL_OVER_ICON) throw new IllegalArgumentException("Layout out of bounds."); this.layout = layout; } /** * Getter for property image. * @return Value of property image. */ public Image getImage() { return this.image; } /** * Sets the icon as an image. * @param image the image */ public void setImage(Image image) { this.image = image; template = null; } /** * Getter for property template. * @return Value of property template. */ public PdfTemplate getTemplate() { return this.template; } /** * Sets the icon as a template. * @param template the template */ public void setTemplate(PdfTemplate template) { this.template = template; image = null; } /** * Getter for property scaleIcon. * @return Value of property scaleIcon. */ public int getScaleIcon() { return this.scaleIcon; } /** * Sets the way the icon will be scaled. Possible values are * SCALE_ICON_ALWAYS, SCALE_ICON_NEVER, * SCALE_ICON_IS_TOO_BIG and SCALE_ICON_IS_TOO_SMALL. * The default is SCALE_ICON_ALWAYS. * @param scaleIcon the way the icon will be scaled */ public void setScaleIcon(int scaleIcon) { if (scaleIcon < SCALE_ICON_ALWAYS || scaleIcon > SCALE_ICON_IS_TOO_SMALL) scaleIcon = SCALE_ICON_ALWAYS; this.scaleIcon = scaleIcon; } /** * Getter for property proportionalIcon. * @return Value of property proportionalIcon. */ public boolean isProportionalIcon() { return this.proportionalIcon; } /** * Sets the way the icon is scaled. If true the icon is scaled proportionally, * if false the scaling is done anamorphicaly. * @param proportionalIcon the way the icon is scaled */ public void setProportionalIcon(boolean proportionalIcon) { this.proportionalIcon = proportionalIcon; } /** * Getter for property iconVerticalAdjustment. * @return Value of property iconVerticalAdjustment. */ public float getIconVerticalAdjustment() { return this.iconVerticalAdjustment; } /** * A number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon. * A value of 0 positions the icon at the bottom of the annotation rectangle. * A value of 0.5 centers it within the rectangle. The default is 0.5. * @param iconVerticalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon */ public void setIconVerticalAdjustment(float iconVerticalAdjustment) { if (iconVerticalAdjustment < 0) iconVerticalAdjustment = 0; else if (iconVerticalAdjustment > 1) iconVerticalAdjustment = 1; this.iconVerticalAdjustment = iconVerticalAdjustment; } /** * Getter for property iconHorizontalAdjustment. * @return Value of property iconHorizontalAdjustment. */ public float getIconHorizontalAdjustment() { return this.iconHorizontalAdjustment; } /** * A number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon. * A value of 0 positions the icon at the left of the annotation rectangle. * A value of 0.5 centers it within the rectangle. The default is 0.5. * @param iconHorizontalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon */ public void setIconHorizontalAdjustment(float iconHorizontalAdjustment) { if (iconHorizontalAdjustment < 0) iconHorizontalAdjustment = 0; else if (iconHorizontalAdjustment > 1) iconHorizontalAdjustment = 1; this.iconHorizontalAdjustment = iconHorizontalAdjustment; } private float calculateFontSize(float w, float h) throws IOException, DocumentException { BaseFont ufont = getRealFont(); float fsize = fontSize; if (fsize == 0) { float bw = ufont.getWidthPoint(text, 1); if (bw == 0) fsize = 12; else fsize = w / bw; float nfsize = h / (1 - ufont.getFontDescriptor(BaseFont.DESCENT, 1)); fsize = Math.min(fsize, nfsize); if (fsize < 4) fsize = 4; } return fsize; } /** * Gets the button appearance. * @throws IOException on error * @throws DocumentException on error * @return the button appearance */ public PdfAppearance getAppearance() throws IOException, DocumentException { PdfAppearance app = getBorderAppearance(); Rectangle box = new Rectangle(app.getBoundingBox()); if ((text == null || text.length() == 0) && (layout == LAYOUT_LABEL_ONLY || (image == null && template == null && iconReference == null))) { return app; } if (layout == LAYOUT_ICON_ONLY && image == null && template == null && iconReference == null) return app; BaseFont ufont = getRealFont(); boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; float h = box.getHeight() - borderWidth * 2; float bw2 = borderWidth; if (borderExtra) { h -= borderWidth * 2; bw2 *= 2; } float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); offsetX = Math.max(offsetX, 1); float offX = Math.min(bw2, offsetX); tp = null; float textX = Float.NaN; float textY = 0; float fsize = fontSize; float wt = box.getWidth() - 2 * offX - 2; float ht = box.getHeight() - 2 * offX; float adj = (iconFitToBounds ? 0 : offX + 1); int nlayout = layout; if (image == null && template == null && iconReference == null) nlayout = LAYOUT_LABEL_ONLY; Rectangle iconBox = null; while (true) { switch (nlayout) { case LAYOUT_LABEL_ONLY: case LAYOUT_LABEL_OVER_ICON: if (text != null && text.length() > 0 && wt > 0 && ht > 0) { fsize = calculateFontSize(wt, ht); textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; } case LAYOUT_ICON_ONLY: if (nlayout == LAYOUT_LABEL_OVER_ICON || nlayout == LAYOUT_ICON_ONLY) iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); break; case LAYOUT_ICON_TOP_LABEL_BOTTOM: if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { nlayout = LAYOUT_ICON_ONLY; continue; } float nht = box.getHeight() * 0.35f - offX; if (nht > 0) fsize = calculateFontSize(wt, nht); else fsize = 4; textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; textY = offX - ufont.getFontDescriptor(BaseFont.DESCENT, fsize); iconBox = new Rectangle(box.getLeft() + adj, textY + fsize, box.getRight() - adj, box.getTop() - adj); break; case LAYOUT_LABEL_TOP_ICON_BOTTOM: if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { nlayout = LAYOUT_ICON_ONLY; continue; } nht = box.getHeight() * 0.35f - offX; if (nht > 0) fsize = calculateFontSize(wt, nht); else fsize = 4; textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; textY = box.getHeight() - offX - fsize; if (textY < offX) textY = offX; iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, textY + ufont.getFontDescriptor(BaseFont.DESCENT, fsize)); break; case LAYOUT_LABEL_LEFT_ICON_RIGHT: if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { nlayout = LAYOUT_ICON_ONLY; continue; } float nw = box.getWidth() * 0.35f - offX; if (nw > 0) fsize = calculateFontSize(wt, nw); else fsize = 4; if (ufont.getWidthPoint(text, fsize) >= wt) { nlayout = LAYOUT_LABEL_ONLY; fsize = fontSize; continue; } textX = offX + 1; textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; iconBox = new Rectangle(textX + ufont.getWidthPoint(text, fsize), box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); break; case LAYOUT_ICON_LEFT_LABEL_RIGHT: if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { nlayout = LAYOUT_ICON_ONLY; continue; } nw = box.getWidth() * 0.35f - offX; if (nw > 0) fsize = calculateFontSize(wt, nw); else fsize = 4; if (ufont.getWidthPoint(text, fsize) >= wt) { nlayout = LAYOUT_LABEL_ONLY; fsize = fontSize; continue; } textX = box.getWidth() - ufont.getWidthPoint(text, fsize) - offX - 1; textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, textX - 1, box.getTop() - adj); break; } break; } if (textY < box.getBottom() + offX) textY = box.getBottom() + offX; if (iconBox != null && (iconBox.getWidth() <= 0 || iconBox.getHeight() <= 0)) iconBox = null; boolean haveIcon = false; float boundingBoxWidth = 0; float boundingBoxHeight = 0; PdfArray matrix = null; if (iconBox != null) { if (image != null) { tp = new PdfTemplate(writer); tp.setBoundingBox(new Rectangle(image)); writer.addDirectTemplateSimple(tp, PdfName.FRM); tp.addImage(image, image.getWidth(), 0, 0, image.getHeight(), 0, 0); haveIcon = true; boundingBoxWidth = tp.getBoundingBox().getWidth(); boundingBoxHeight = tp.getBoundingBox().getHeight(); } else if (template != null) { tp = new PdfTemplate(writer); tp.setBoundingBox(new Rectangle(template.getWidth(), template.getHeight())); writer.addDirectTemplateSimple(tp, PdfName.FRM); tp.addTemplate(template, template.getBoundingBox().getLeft(), template.getBoundingBox().getBottom()); haveIcon = true; boundingBoxWidth = tp.getBoundingBox().getWidth(); boundingBoxHeight = tp.getBoundingBox().getHeight(); } else if (iconReference != null) { PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObject(iconReference); if (dic != null) { Rectangle r2 = PdfReader.getNormalizedRectangle(dic.getAsArray(PdfName.BBOX)); matrix = dic.getAsArray(PdfName.MATRIX); haveIcon = true; boundingBoxWidth = r2.getWidth(); boundingBoxHeight = r2.getHeight(); } } } if (haveIcon) { float icx = iconBox.getWidth() / boundingBoxWidth; float icy = iconBox.getHeight() / boundingBoxHeight; if (proportionalIcon) { switch (scaleIcon) { case SCALE_ICON_IS_TOO_BIG: icx = Math.min(icx, icy); icx = Math.min(icx, 1); break; case SCALE_ICON_IS_TOO_SMALL: icx = Math.min(icx, icy); icx = Math.max(icx, 1); break; case SCALE_ICON_NEVER: icx = 1; break; default: icx = Math.min(icx, icy); break; } icy = icx; } else { switch (scaleIcon) { case SCALE_ICON_IS_TOO_BIG: icx = Math.min(icx, 1); icy = Math.min(icy, 1); break; case SCALE_ICON_IS_TOO_SMALL: icx = Math.max(icx, 1); icy = Math.max(icy, 1); break; case SCALE_ICON_NEVER: icx = icy = 1; break; default: break; } } float xpos = iconBox.getLeft() + (iconBox.getWidth() - (boundingBoxWidth * icx)) * iconHorizontalAdjustment; float ypos = iconBox.getBottom() + (iconBox.getHeight() - (boundingBoxHeight * icy)) * iconVerticalAdjustment; app.saveState(); app.rectangle(iconBox.getLeft(), iconBox.getBottom(), iconBox.getWidth(), iconBox.getHeight()); app.clip(); app.newPath(); if (tp != null) app.addTemplate(tp, icx, 0, 0, icy, xpos, ypos); else { float cox = 0; float coy = 0; if (matrix != null && matrix.size() == 6) { PdfNumber nm = matrix.getAsNumber(4); if (nm != null) cox = nm.floatValue(); nm = matrix.getAsNumber(5); if (nm != null) coy = nm.floatValue(); } app.addTemplateReference(iconReference, PdfName.FRM, icx, 0, 0, icy, xpos - cox * icx, ypos - coy * icy); } app.restoreState(); } if (!Float.isNaN(textX)) { app.saveState(); app.rectangle(offX, offX, box.getWidth() - 2 * offX, box.getHeight() - 2 * offX); app.clip(); app.newPath(); if (textColor == null) app.resetGrayFill(); else app.setColorFill(textColor); app.beginText(); app.setFontAndSize(ufont, fsize); app.setTextMatrix(textX, textY); app.showText(text); app.endText(); app.restoreState(); } return app; } /** * Gets the pushbutton field. * @throws IOException on error * @throws DocumentException on error * @return the pushbutton field */ public PdfFormField getField() throws IOException, DocumentException { PdfFormField field = PdfFormField.createPushButton(writer); field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); if (fieldName != null) { field.setFieldName(fieldName); if ((options & READ_ONLY) != 0) field.setFieldFlags(PdfFormField.FF_READ_ONLY); if ((options & REQUIRED) != 0) field.setFieldFlags(PdfFormField.FF_REQUIRED); } if (text != null) field.setMKNormalCaption(text); if (rotation != 0) field.setMKRotation(rotation); field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); PdfAppearance tpa = getAppearance(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tpa); PdfAppearance da = (PdfAppearance)tpa.getDuplicate(); da.setFontAndSize(getRealFont(), fontSize); if (textColor == null) da.setGrayFill(0); else da.setColorFill(textColor); field.setDefaultAppearanceString(da); if (borderColor != null) field.setMKBorderColor(borderColor); if (backgroundColor != null) field.setMKBackgroundColor(backgroundColor); switch (visibility) { case HIDDEN: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); break; case VISIBLE_BUT_DOES_NOT_PRINT: break; case HIDDEN_BUT_PRINTABLE: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); break; default: field.setFlags(PdfAnnotation.FLAGS_PRINT); break; } if (tp != null) field.setMKNormalIcon(tp); field.setMKTextPosition(layout - 1); PdfName scale = PdfName.A; if (scaleIcon == SCALE_ICON_IS_TOO_BIG) scale = PdfName.B; else if (scaleIcon == SCALE_ICON_IS_TOO_SMALL) scale = PdfName.S; else if (scaleIcon == SCALE_ICON_NEVER) scale = PdfName.N; field.setMKIconFit(scale, proportionalIcon ? PdfName.P : PdfName.A, iconHorizontalAdjustment, iconVerticalAdjustment, iconFitToBounds); return field; } /** * Getter for property iconFitToBounds. * @return Value of property iconFitToBounds. */ public boolean isIconFitToBounds() { return this.iconFitToBounds; } /** * If true the icon will be scaled to fit fully within the bounds of the annotation, * if false the border width will be taken into account. The default * is false. * @param iconFitToBounds if true the icon will be scaled to fit fully within the bounds of the annotation, * if false the border width will be taken into account */ public void setIconFitToBounds(boolean iconFitToBounds) { this.iconFitToBounds = iconFitToBounds; } /** * Holds value of property iconReference. */ private PRIndirectReference iconReference; /** * Gets the reference to an existing icon. * @return the reference to an existing icon. */ public PRIndirectReference getIconReference() { return this.iconReference; } /** * Sets the reference to an existing icon. * @param iconReference the reference to an existing icon */ public void setIconReference(PRIndirectReference iconReference) { this.iconReference = iconReference; } }src/core/com/lowagie/text/pdf/RadioCheckField.java100644 0 0 36722 11000354131 17507 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; /** * Creates a radio or a check field. *

* Example usage: *

*

 * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
 * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
 * document.open();
 * PdfContentByte cb = writer.getDirectContent();
 * RadioCheckField bt = new RadioCheckField(writer, new Rectangle(100, 100, 200, 200), "radio", "v1");
 * bt.setCheckType(RadioCheckField.TYPE_CIRCLE);
 * bt.setBackgroundColor(Color.cyan);
 * bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
 * bt.setBorderColor(Color.red);
 * bt.setTextColor(Color.yellow);
 * bt.setBorderWidth(BaseField.BORDER_WIDTH_THICK);
 * bt.setChecked(false);
 * PdfFormField f1 = bt.getRadioField();
 * bt.setOnValue("v2");
 * bt.setChecked(true);
 * bt.setBox(new Rectangle(100, 300, 200, 400));
 * PdfFormField f2 = bt.getRadioField();
 * bt.setChecked(false);
 * PdfFormField top = bt.getRadioGroup(true, false);
 * bt.setOnValue("v3");
 * bt.setBox(new Rectangle(100, 500, 200, 600));
 * PdfFormField f3 = bt.getRadioField();
 * top.addKid(f1);
 * top.addKid(f2);
 * top.addKid(f3);
 * writer.addAnnotation(top);
 * bt = new RadioCheckField(writer, new Rectangle(300, 300, 400, 400), "check1", "Yes");
 * bt.setCheckType(RadioCheckField.TYPE_CHECK);
 * bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
 * bt.setBorderColor(Color.black);
 * bt.setBackgroundColor(Color.white);
 * PdfFormField ck = bt.getCheckField();
 * writer.addAnnotation(ck);
 * document.close();
 * 
* @author Paulo Soares (psoares@consiste.pt) */ public class RadioCheckField extends BaseField { /** A field with the symbol check */ public static final int TYPE_CHECK = 1; /** A field with the symbol circle */ public static final int TYPE_CIRCLE = 2; /** A field with the symbol cross */ public static final int TYPE_CROSS = 3; /** A field with the symbol diamond */ public static final int TYPE_DIAMOND = 4; /** A field with the symbol square */ public static final int TYPE_SQUARE = 5; /** A field with the symbol star */ public static final int TYPE_STAR = 6; private static String typeChars[] = {"4", "l", "8", "u", "n", "H"}; /** * Holds value of property checkType. */ private int checkType; /** * Holds value of property onValue. */ private String onValue; /** * Holds value of property checked. */ private boolean checked; /** * Creates a new instance of RadioCheckField * @param writer the document PdfWriter * @param box the field location and dimensions * @param fieldName the field name. It must not be null * @param onValue the value when the field is checked */ public RadioCheckField(PdfWriter writer, Rectangle box, String fieldName, String onValue) { super(writer, box, fieldName); setOnValue(onValue); setCheckType(TYPE_CIRCLE); } /** * Getter for property checkType. * @return Value of property checkType. */ public int getCheckType() { return this.checkType; } /** * Sets the checked symbol. It can be * TYPE_CHECK, * TYPE_CIRCLE, * TYPE_CROSS, * TYPE_DIAMOND, * TYPE_SQUARE and * TYPE_STAR. * @param checkType the checked symbol */ public void setCheckType(int checkType) { if (checkType < TYPE_CHECK || checkType > TYPE_STAR) checkType = TYPE_CIRCLE; this.checkType = checkType; setText(typeChars[checkType - 1]); try { setFont(BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, false)); } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Getter for property onValue. * @return Value of property onValue. */ public String getOnValue() { return this.onValue; } /** * Sets the value when the field is checked. * @param onValue the value when the field is checked */ public void setOnValue(String onValue) { this.onValue = onValue; } /** * Getter for property checked. * @return Value of property checked. */ public boolean isChecked() { return this.checked; } /** * Sets the state of the field to checked or unchecked. * @param checked the state of the field, true for checked * and false for unchecked */ public void setChecked(boolean checked) { this.checked = checked; } /** * Gets the field appearance. * @param isRadio true for a radio field and false * for a check field * @param on true for the checked state, false * otherwise * @throws IOException on error * @throws DocumentException on error * @return the appearance */ public PdfAppearance getAppearance(boolean isRadio, boolean on) throws IOException, DocumentException { if (isRadio && checkType == TYPE_CIRCLE) return getAppearanceRadioCircle(on); PdfAppearance app = getBorderAppearance(); if (!on) return app; BaseFont ufont = getRealFont(); boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; float h = box.getHeight() - borderWidth * 2; float bw2 = borderWidth; if (borderExtra) { h -= borderWidth * 2; bw2 *= 2; } float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); offsetX = Math.max(offsetX, 1); float offX = Math.min(bw2, offsetX); float wt = box.getWidth() - 2 * offX; float ht = box.getHeight() - 2 * offX; float fsize = fontSize; if (fsize == 0) { float bw = ufont.getWidthPoint(text, 1); if (bw == 0) fsize = 12; else fsize = wt / bw; float nfsize = h / (ufont.getFontDescriptor(BaseFont.ASCENT, 1)); fsize = Math.min(fsize, nfsize); } app.saveState(); app.rectangle(offX, offX, wt, ht); app.clip(); app.newPath(); if (textColor == null) app.resetGrayFill(); else app.setColorFill(textColor); app.beginText(); app.setFontAndSize(ufont, fsize); app.setTextMatrix((box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2, (box.getHeight() - ufont.getAscentPoint(text, fsize)) / 2); app.showText(text); app.endText(); app.restoreState(); return app; } /** * Gets the special field appearance for the radio circle. * @param on true for the checked state, false * otherwise * @return the appearance */ public PdfAppearance getAppearanceRadioCircle(boolean on) { PdfAppearance app = PdfAppearance.createAppearance(writer, box.getWidth(), box.getHeight()); switch (rotation) { case 90: app.setMatrix(0, 1, -1, 0, box.getHeight(), 0); break; case 180: app.setMatrix(-1, 0, 0, -1, box.getWidth(), box.getHeight()); break; case 270: app.setMatrix(0, -1, 1, 0, 0, box.getWidth()); break; } Rectangle box = new Rectangle(app.getBoundingBox()); float cx = box.getWidth() / 2; float cy = box.getHeight() / 2; float r = (Math.min(box.getWidth(), box.getHeight()) - borderWidth) / 2; if (r <= 0) return app; if (backgroundColor != null) { app.setColorFill(backgroundColor); app.circle(cx, cy, r + borderWidth / 2); app.fill(); } if (borderWidth > 0 && borderColor != null) { app.setLineWidth(borderWidth); app.setColorStroke(borderColor); app.circle(cx, cy, r); app.stroke(); } if (on) { if (textColor == null) app.resetGrayFill(); else app.setColorFill(textColor); app.circle(cx, cy, r / 2); app.fill(); } return app; } /** * Gets a radio group. It's composed of the field specific keys, without the widget * ones. This field is to be used as a field aggregator with {@link PdfFormField#addKid(PdfFormField) addKid()}. * @param noToggleToOff if true, exactly one radio button must be selected at all * times; clicking the currently selected button has no effect. * If false, clicking * the selected button deselects it, leaving no button selected. * @param radiosInUnison if true, a group of radio buttons within a radio button field that * use the same value for the on state will turn on and off in unison; that is if * one is checked, they are all checked. If false, the buttons are mutually exclusive * (the same behavior as HTML radio buttons) * @return the radio group */ public PdfFormField getRadioGroup(boolean noToggleToOff, boolean radiosInUnison) { PdfFormField field = PdfFormField.createRadioButton(writer, noToggleToOff); if (radiosInUnison) field.setFieldFlags(PdfFormField.FF_RADIOSINUNISON); field.setFieldName(fieldName); if ((options & READ_ONLY) != 0) field.setFieldFlags(PdfFormField.FF_READ_ONLY); if ((options & REQUIRED) != 0) field.setFieldFlags(PdfFormField.FF_REQUIRED); field.setValueAsName(checked ? onValue : "Off"); return field; } /** * Gets the radio field. It's only composed of the widget keys and must be used * with {@link #getRadioGroup(boolean,boolean)}. * @return the radio field * @throws IOException on error * @throws DocumentException on error */ public PdfFormField getRadioField() throws IOException, DocumentException { return getField(true); } /** * Gets the check field. * @return the check field * @throws IOException on error * @throws DocumentException on error */ public PdfFormField getCheckField() throws IOException, DocumentException { return getField(false); } /** * Gets a radio or check field. * @param isRadio true to get a radio field, false to get * a check field * @throws IOException on error * @throws DocumentException on error * @return the field */ protected PdfFormField getField(boolean isRadio) throws IOException, DocumentException { PdfFormField field = null; if (isRadio) field = PdfFormField.createEmpty(writer); else field = PdfFormField.createCheckBox(writer); field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); if (!isRadio) { field.setFieldName(fieldName); if ((options & READ_ONLY) != 0) field.setFieldFlags(PdfFormField.FF_READ_ONLY); if ((options & REQUIRED) != 0) field.setFieldFlags(PdfFormField.FF_REQUIRED); field.setValueAsName(checked ? onValue : "Off"); } if (text != null) field.setMKNormalCaption(text); if (rotation != 0) field.setMKRotation(rotation); field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); PdfAppearance tpon = getAppearance(isRadio, true); PdfAppearance tpoff = getAppearance(isRadio, false); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, onValue, tpon); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpoff); field.setAppearanceState(checked ? onValue : "Off"); PdfAppearance da = (PdfAppearance)tpon.getDuplicate(); da.setFontAndSize(getRealFont(), fontSize); if (textColor == null) da.setGrayFill(0); else da.setColorFill(textColor); field.setDefaultAppearanceString(da); if (borderColor != null) field.setMKBorderColor(borderColor); if (backgroundColor != null) field.setMKBackgroundColor(backgroundColor); switch (visibility) { case HIDDEN: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); break; case VISIBLE_BUT_DOES_NOT_PRINT: break; case HIDDEN_BUT_PRINTABLE: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); break; default: field.setFlags(PdfAnnotation.FLAGS_PRINT); break; } return field; } }src/core/com/lowagie/text/pdf/RandomAccessFileOrArray.java100644 0 0 52101 11036112746 21213 0ustar 0 0 /* * $Id: RandomAccessFileOrArray.java 3488 2008-06-02 14:19:26Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.Document; import java.io.ByteArrayOutputStream; import java.io.DataInput; import java.io.DataInputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.URL; import java.nio.channels.FileChannel; /** An implementation of a RandomAccessFile for input only * that accepts a file or a byte array as data source. * * @author Paulo Soares (psoares@consiste.pt) */ public class RandomAccessFileOrArray implements DataInput { MappedRandomAccessFile rf; RandomAccessFile trf; boolean plainRandomAccess; String filename; byte arrayIn[]; int arrayInPtr; byte back; boolean isBack = false; /** Holds value of property startOffset. */ private int startOffset = 0; public RandomAccessFileOrArray(String filename) throws IOException { this(filename, false, Document.plainRandomAccess); } public RandomAccessFileOrArray(String filename, boolean forceRead, boolean plainRandomAccess) throws IOException { this.plainRandomAccess = plainRandomAccess; File file = new File(filename); if (!file.canRead()) { if (filename.startsWith("file:/") || filename.startsWith("http://") || filename.startsWith("https://") || filename.startsWith("jar:")) { InputStream is = new URL(filename).openStream(); try { this.arrayIn = InputStreamToArray(is); return; } finally { try {is.close();}catch(IOException ioe){} } } else { InputStream is = BaseFont.getResourceStream(filename); if (is == null) throw new IOException(filename + " not found as file or resource."); try { this.arrayIn = InputStreamToArray(is); return; } finally { try {is.close();}catch(IOException ioe){} } } } else if (forceRead) { InputStream s = null; try { s = new FileInputStream(file); this.arrayIn = InputStreamToArray(s); } finally { try {if (s != null) {s.close();}}catch(Exception e){} } return; } this.filename = filename; if (plainRandomAccess) trf = new RandomAccessFile(filename, "r"); else rf = new MappedRandomAccessFile(filename, "r"); } public RandomAccessFileOrArray(URL url) throws IOException { InputStream is = url.openStream(); try { this.arrayIn = InputStreamToArray(is); } finally { try {is.close();}catch(IOException ioe){} } } public RandomAccessFileOrArray(InputStream is) throws IOException { this.arrayIn = InputStreamToArray(is); } public static byte[] InputStreamToArray(InputStream is) throws IOException { byte b[] = new byte[8192]; ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { int read = is.read(b); if (read < 1) break; out.write(b, 0, read); } out.close(); return out.toByteArray(); } public RandomAccessFileOrArray(byte arrayIn[]) { this.arrayIn = arrayIn; } public RandomAccessFileOrArray(RandomAccessFileOrArray file) { filename = file.filename; arrayIn = file.arrayIn; startOffset = file.startOffset; plainRandomAccess = file.plainRandomAccess; } public void pushBack(byte b) { back = b; isBack = true; } public int read() throws IOException { if(isBack) { isBack = false; return back & 0xff; } if (arrayIn == null) return plainRandomAccess ? trf.read() : rf.read(); else { if (arrayInPtr >= arrayIn.length) return -1; return arrayIn[arrayInPtr++] & 0xff; } } public int read(byte[] b, int off, int len) throws IOException { if (len == 0) return 0; int n = 0; if (isBack) { isBack = false; if (len == 1) { b[off] = back; return 1; } else { n = 1; b[off++] = back; --len; } } if (arrayIn == null) { return (plainRandomAccess ? trf.read(b, off, len) : rf.read(b, off, len)) + n; } else { if (arrayInPtr >= arrayIn.length) return -1; if (arrayInPtr + len > arrayIn.length) len = arrayIn.length - arrayInPtr; System.arraycopy(arrayIn, arrayInPtr, b, off, len); arrayInPtr += len; return len + n; } } public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public void readFully(byte b[]) throws IOException { readFully(b, 0, b.length); } public void readFully(byte b[], int off, int len) throws IOException { int n = 0; do { int count = read(b, off + n, len - n); if (count < 0) throw new EOFException(); n += count; } while (n < len); } public long skip(long n) throws IOException { return skipBytes((int)n); } public int skipBytes(int n) throws IOException { if (n <= 0) { return 0; } int adj = 0; if (isBack) { isBack = false; if (n == 1) { return 1; } else { --n; adj = 1; } } int pos; int len; int newpos; pos = getFilePointer(); len = length(); newpos = pos + n; if (newpos > len) { newpos = len; } seek(newpos); /* return the actual number of bytes skipped */ return newpos - pos + adj; } public void reOpen() throws IOException { if (filename != null && rf == null && trf == null) { if (plainRandomAccess) trf = new RandomAccessFile(filename, "r"); else rf = new MappedRandomAccessFile(filename, "r"); } seek(0); } protected void insureOpen() throws IOException { if (filename != null && rf == null && trf == null) { reOpen(); } } public boolean isOpen() { return (filename == null || rf != null || trf != null); } public void close() throws IOException { isBack = false; if (rf != null) { rf.close(); rf = null; // it's very expensive to open a memory mapped file and for the usage pattern of this class // in iText it's faster the next re-openings to be done as a plain random access // file plainRandomAccess = true; } else if (trf != null) { trf.close(); trf = null; } } public int length() throws IOException { if (arrayIn == null) { insureOpen(); return (int)(plainRandomAccess ? trf.length() : rf.length()) - startOffset; } else return arrayIn.length - startOffset; } public void seek(int pos) throws IOException { pos += startOffset; isBack = false; if (arrayIn == null) { insureOpen(); if (plainRandomAccess) trf.seek(pos); else rf.seek(pos); } else arrayInPtr = pos; } public void seek(long pos) throws IOException { seek((int)pos); } public int getFilePointer() throws IOException { insureOpen(); int n = isBack ? 1 : 0; if (arrayIn == null) { return (int)(plainRandomAccess ? trf.getFilePointer() : rf.getFilePointer()) - n - startOffset; } else return arrayInPtr - n - startOffset; } public boolean readBoolean() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return (ch != 0); } public byte readByte() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return (byte)(ch); } public int readUnsignedByte() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return ch; } public short readShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (short)((ch1 << 8) + ch2); } /** * Reads a signed 16-bit number from this stream in little-endian order. * The method reads two * bytes from this stream, starting at the current stream pointer. * If the two bytes read, in order, are * b1 and b2, where each of the two values is * between 0 and 255, inclusive, then the * result is equal to: *
     *     (short)((b2 << 8) | b1)
     * 
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as a signed * 16-bit number. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final short readShortLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (short)((ch2 << 8) + (ch1 << 0)); } public int readUnsignedShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (ch1 << 8) + ch2; } /** * Reads an unsigned 16-bit number from this stream in little-endian order. * This method reads * two bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

     *     (b2 << 8) | b1
     * 
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream, interpreted as an * unsigned 16-bit integer. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final int readUnsignedShortLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (ch2 << 8) + (ch1 << 0); } public char readChar() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (char)((ch1 << 8) + ch2); } /** * Reads a Unicode character from this stream in little-endian order. * This method reads two * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

     *     (char)((b2 << 8) | b1)
     * 
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this stream as a Unicode character. * @exception EOFException if this stream reaches the end before reading * two bytes. * @exception IOException if an I/O error occurs. */ public final char readCharLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (char)((ch2 << 8) + (ch1 << 0)); } public int readInt() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4); } /** * Reads a signed 32-bit integer from this stream in little-endian order. * This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

     *     (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
     * 
*

* This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as an * int. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final int readIntLE() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); } /** * Reads an unsigned 32-bit integer from this stream. This method reads 4 * bytes from the stream, starting at the current stream pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

     *     (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
     * 
*

* This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as a * long. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public final long readUnsignedInt() throws IOException { long ch1 = this.read(); long ch2 = this.read(); long ch3 = this.read(); long ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } public final long readUnsignedIntLE() throws IOException { long ch1 = this.read(); long ch2 = this.read(); long ch3 = this.read(); long ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); } public long readLong() throws IOException { return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL); } public final long readLongLE() throws IOException { int i1 = readIntLE(); int i2 = readIntLE(); return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); } public float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } public final float readFloatLE() throws IOException { return Float.intBitsToFloat(readIntLE()); } public double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } public final double readDoubleLE() throws IOException { return Double.longBitsToDouble(readLongLE()); } public String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c = -1; boolean eol = false; while (!eol) { switch (c = read()) { case -1: case '\n': eol = true; break; case '\r': eol = true; int cur = getFilePointer(); if ((read()) != '\n') { seek(cur); } break; default: input.append((char)c); break; } } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); } public String readUTF() throws IOException { return DataInputStream.readUTF(this); } /** Getter for property startOffset. * @return Value of property startOffset. * */ public int getStartOffset() { return this.startOffset; } /** Setter for property startOffset. * @param startOffset New value of property startOffset. * */ public void setStartOffset(int startOffset) { this.startOffset = startOffset; } /** * @since 2.0.8 */ public java.nio.ByteBuffer getNioByteBuffer() throws IOException { if (filename != null) { FileChannel channel; if (plainRandomAccess) channel = trf.getChannel(); else channel = rf.getChannel(); return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); } return java.nio.ByteBuffer.wrap(arrayIn); } } src/core/com/lowagie/text/pdf/SequenceList.java100644 0 0 26437 11000354131 17155 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; /** * This class expands a string into a list of numbers. The main use is to select a * range of pages. *

* The general syntax is:
* [!][o][odd][e][even]start-end *

* You can have multiple ranges separated by commas ','. The '!' modifier removes the * range from what is already selected. The range changes are incremental, that is, * numbers are added or deleted as the range appears. The start or the end, but not both, can be omitted. */ public class SequenceList { protected static final int COMMA = 1; protected static final int MINUS = 2; protected static final int NOT = 3; protected static final int TEXT = 4; protected static final int NUMBER = 5; protected static final int END = 6; protected static final char EOT = '\uffff'; private static final int FIRST = 0; private static final int DIGIT = 1; private static final int OTHER = 2; private static final int DIGIT2 = 3; private static final String NOT_OTHER = "-,!0123456789"; protected char text[]; protected int ptr; protected int number; protected String other; protected int low; protected int high; protected boolean odd; protected boolean even; protected boolean inverse; protected SequenceList(String range) { ptr = 0; text = range.toCharArray(); } protected char nextChar() { while (true) { if (ptr >= text.length) return EOT; char c = text[ptr++]; if (c > ' ') return c; } } protected void putBack() { --ptr; if (ptr < 0) ptr = 0; } protected int getType() { StringBuffer buf = new StringBuffer(); int state = FIRST; while (true) { char c = nextChar(); if (c == EOT) { if (state == DIGIT) { number = Integer.parseInt(other = buf.toString()); return NUMBER; } else if (state == OTHER) { other = buf.toString().toLowerCase(); return TEXT; } return END; } switch (state) { case FIRST: switch (c) { case '!': return NOT; case '-': return MINUS; case ',': return COMMA; } buf.append(c); if (c >= '0' && c <= '9') state = DIGIT; else state = OTHER; break; case DIGIT: if (c >= '0' && c <= '9') buf.append(c); else { putBack(); number = Integer.parseInt(other = buf.toString()); return NUMBER; } break; case OTHER: if (NOT_OTHER.indexOf(c) < 0) buf.append(c); else { putBack(); other = buf.toString().toLowerCase(); return TEXT; } break; } } } private void otherProc() { if (other.equals("odd") || other.equals("o")) { odd = true; even = false; } else if (other.equals("even") || other.equals("e")) { odd = false; even = true; } } protected boolean getAttributes() { low = -1; high = -1; odd = even = inverse = false; int state = OTHER; while (true) { int type = getType(); if (type == END || type == COMMA) { if (state == DIGIT) high = low; return (type == END); } switch (state) { case OTHER: switch (type) { case NOT: inverse = true; break; case MINUS: state = DIGIT2; break; default: if (type == NUMBER) { low = number; state = DIGIT; } else otherProc(); break; } break; case DIGIT: switch (type) { case NOT: inverse = true; state = OTHER; high = low; break; case MINUS: state = DIGIT2; break; default: high = low; state = OTHER; otherProc(); break; } break; case DIGIT2: switch (type) { case NOT: inverse = true; state = OTHER; break; case MINUS: break; case NUMBER: high = number; state = OTHER; break; default: state = OTHER; otherProc(); break; } break; } } } /** * Generates a list of numbers from a string. * @param ranges the comma separated ranges * @param maxNumber the maximum number in the range * @return a list with the numbers as Integer */ public static List expand(String ranges, int maxNumber) { SequenceList parse = new SequenceList(ranges); LinkedList list = new LinkedList(); boolean sair = false; while (!sair) { sair = parse.getAttributes(); if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd) continue; if (parse.low < 1) parse.low = 1; if (parse.high < 1 || parse.high > maxNumber) parse.high = maxNumber; if (parse.low > maxNumber) parse.low = maxNumber; //System.out.println("low="+parse.low+",high="+parse.high+",odd="+parse.odd+",even="+parse.even+",inverse="+parse.inverse); int inc = 1; if (parse.inverse) { if (parse.low > parse.high) { int t = parse.low; parse.low = parse.high; parse.high = t; } for (ListIterator it = list.listIterator(); it.hasNext();) { int n = ((Integer)it.next()).intValue(); if (parse.even && (n & 1) == 1) continue; if (parse.odd && (n & 1) == 0) continue; if (n >= parse.low && n <= parse.high) it.remove(); } } else { if (parse.low > parse.high) { inc = -1; if (parse.odd || parse.even) { --inc; if (parse.even) parse.low &= ~1; else parse.low -= ((parse.low & 1) == 1 ? 0 : 1); } for (int k = parse.low; k >= parse.high; k += inc) list.add(new Integer(k)); } else { if (parse.odd || parse.even) { ++inc; if (parse.odd) parse.low |= 1; else parse.low += ((parse.low & 1) == 1 ? 1 : 0); } for (int k = parse.low; k <= parse.high; k += inc) { list.add(new Integer(k)); } } } // for (int k = 0; k < list.size(); ++k) // System.out.print(((Integer)list.get(k)).intValue() + ","); // System.out.println(); } return list; } }src/core/com/lowagie/text/pdf/ShadingColor.java100644 0 0 6360 11000354131 17076 0ustar 0 0 /* * Copyright 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** Implements a shading pattern as a Color. * * @author Paulo Soares (psoares@consiste.pt) */ public class ShadingColor extends ExtendedColor { private static final long serialVersionUID = 4817929454941328671L; PdfShadingPattern shadingPattern; /** * Creates a shading color. * @param shadingPattern */ public ShadingColor(PdfShadingPattern shadingPattern) { super(TYPE_SHADING, .5f, .5f, .5f); this.shadingPattern = shadingPattern; } /** * Gets the shading pattern. * @return a shading pattern. */ public PdfShadingPattern getPdfShadingPattern() { return shadingPattern; } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return shadingPattern.hashCode(); } } src/core/com/lowagie/text/pdf/SimpleBookmark.java100644 0 0 77755 11154165266 17524 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.StringTokenizer; import com.lowagie.text.xml.simpleparser.IanaEncodings; import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; import com.lowagie.text.xml.simpleparser.SimpleXMLParser; /** * Bookmark processing in a simple way. It has some limitations, mainly the only * action types supported are GoTo, GoToR, URI and Launch. *

* The list structure is composed by a number of HashMap, keyed by strings, one HashMap * for each bookmark. * The element values are all strings with the exception of the key "Kids" that has * another list for the child bookmarks. *

* All the bookmarks have a "Title" with the * bookmark title and optionally a "Style" that can be "bold", "italic" or a * combination of both. They can also have a "Color" key with a value of three * floats separated by spaces. The key "Open" can have the values "true" or "false" and * signals the open status of the children. It's "true" by default. *

* The actions and the parameters can be: *

    *
  • "Action" = "GoTo" - "Page" | "Named" *
      *
    • "Page" = "3 XYZ 70 400 null" - page number followed by a destination (/XYZ is also accepted) *
    • "Named" = "named_destination" *
    *
  • "Action" = "GoToR" - "Page" | "Named" | "NamedN", "File", ["NewWindow"] *
      *
    • "Page" = "3 XYZ 70 400 null" - page number followed by a destination (/XYZ is also accepted) *
    • "Named" = "named_destination_as_a_string" *
    • "NamedN" = "named_destination_as_a_name" *
    • "File" - "the_file_to_open" *
    • "NewWindow" - "true" or "false" *
    *
  • "Action" = "URI" - "URI" *
      *
    • "URI" = "http://sf.net" - URI to jump to *
    *
  • "Action" = "Launch" - "File" *
      *
    • "File" - "the_file_to_open_or_execute" *
    * @author Paulo Soares (psoares@consiste.pt) */ public final class SimpleBookmark implements SimpleXMLDocHandler { private ArrayList topList; private Stack attr = new Stack(); /** Creates a new instance of SimpleBookmark */ private SimpleBookmark() { } private static List bookmarkDepth(PdfReader reader, PdfDictionary outline, IntHashtable pages) { ArrayList list = new ArrayList(); while (outline != null) { HashMap map = new HashMap(); PdfString title = (PdfString)PdfReader.getPdfObjectRelease(outline.get(PdfName.TITLE)); map.put("Title", title.toUnicodeString()); PdfArray color = (PdfArray)PdfReader.getPdfObjectRelease(outline.get(PdfName.C)); if (color != null && color.size() == 3) { ByteBuffer out = new ByteBuffer(); out.append(color.getAsNumber(0).floatValue()).append(' '); out.append(color.getAsNumber(1).floatValue()).append(' '); out.append(color.getAsNumber(2).floatValue()); map.put("Color", PdfEncodings.convertToString(out.toByteArray(), null)); } PdfNumber style = (PdfNumber)PdfReader.getPdfObjectRelease(outline.get(PdfName.F)); if (style != null) { int f = style.intValue(); String s = ""; if ((f & 1) != 0) s += "italic "; if ((f & 2) != 0) s += "bold "; s = s.trim(); if (s.length() != 0) map.put("Style", s); } PdfNumber count = (PdfNumber)PdfReader.getPdfObjectRelease(outline.get(PdfName.COUNT)); if (count != null && count.intValue() < 0) map.put("Open", "false"); try { PdfObject dest = PdfReader.getPdfObjectRelease(outline.get(PdfName.DEST)); if (dest != null) { mapGotoBookmark(map, dest, pages); //changed by ujihara 2004-06-13 } else { PdfDictionary action = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.A)); if (action != null) { if (PdfName.GOTO.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) { dest = PdfReader.getPdfObjectRelease(action.get(PdfName.D)); if (dest != null) { mapGotoBookmark(map, dest, pages); } } else if (PdfName.URI.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) { map.put("Action", "URI"); map.put("URI", ((PdfString)PdfReader.getPdfObjectRelease(action.get(PdfName.URI))).toUnicodeString()); } else if (PdfName.GOTOR.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) { dest = PdfReader.getPdfObjectRelease(action.get(PdfName.D)); if (dest != null) { if (dest.isString()) map.put("Named", dest.toString()); else if (dest.isName()) map.put("NamedN", PdfName.decodeName(dest.toString())); else if (dest.isArray()) { PdfArray arr = (PdfArray)dest; StringBuffer s = new StringBuffer(); s.append(arr.getPdfObject(0).toString()); s.append(' ').append(arr.getPdfObject(1).toString()); for (int k = 2; k < arr.size(); ++k) s.append(' ').append(arr.getPdfObject(k).toString()); map.put("Page", s.toString()); } } map.put("Action", "GoToR"); PdfObject file = PdfReader.getPdfObjectRelease(action.get(PdfName.F)); if (file != null) { if (file.isString()) map.put("File", ((PdfString)file).toUnicodeString()); else if (file.isDictionary()) { file = PdfReader.getPdfObject(((PdfDictionary)file).get(PdfName.F)); if (file.isString()) map.put("File", ((PdfString)file).toUnicodeString()); } } PdfObject newWindow = PdfReader.getPdfObjectRelease(action.get(PdfName.NEWWINDOW)); if (newWindow != null) map.put("NewWindow", newWindow.toString()); } else if (PdfName.LAUNCH.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) { map.put("Action", "Launch"); PdfObject file = PdfReader.getPdfObjectRelease(action.get(PdfName.F)); if (file == null) file = PdfReader.getPdfObjectRelease(action.get(PdfName.WIN)); if (file != null) { if (file.isString()) map.put("File", ((PdfString)file).toUnicodeString()); else if (file.isDictionary()) { file = PdfReader.getPdfObjectRelease(((PdfDictionary)file).get(PdfName.F)); if (file.isString()) map.put("File", ((PdfString)file).toUnicodeString()); } } } } } } catch (Exception e) { //empty on purpose } PdfDictionary first = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.FIRST)); if (first != null) { map.put("Kids", bookmarkDepth(reader, first, pages)); } list.add(map); outline = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.NEXT)); } return list; } private static void mapGotoBookmark(HashMap map, PdfObject dest, IntHashtable pages) { if (dest.isString()) map.put("Named", dest.toString()); else if (dest.isName()) map.put("Named", PdfName.decodeName(dest.toString())); else if (dest.isArray()) map.put("Page", makeBookmarkParam((PdfArray)dest, pages)); //changed by ujihara 2004-06-13 map.put("Action", "GoTo"); } private static String makeBookmarkParam(PdfArray dest, IntHashtable pages) { StringBuffer s = new StringBuffer(); PdfObject obj = dest.getPdfObject(0); if (obj.isNumber()) s.append(((PdfNumber)obj).intValue() + 1); else s.append(pages.get(getNumber((PdfIndirectReference)obj))); //changed by ujihara 2004-06-13 s.append(' ').append(dest.getPdfObject(1).toString().substring(1)); for (int k = 2; k < dest.size(); ++k) s.append(' ').append(dest.getPdfObject(k).toString()); return s.toString(); } /** * Gets number of indirect. If type of directed indirect is PAGES, it refers PAGE object through KIDS. * (Contributed by Kazuya Ujihara) * @param indirect * 2004-06-13 */ private static int getNumber(PdfIndirectReference indirect) { PdfDictionary pdfObj = (PdfDictionary)PdfReader.getPdfObjectRelease(indirect); if (pdfObj.contains(PdfName.TYPE) && pdfObj.get(PdfName.TYPE).equals(PdfName.PAGES) && pdfObj.contains(PdfName.KIDS)) { PdfArray kids = (PdfArray)pdfObj.get(PdfName.KIDS); indirect = (PdfIndirectReference)kids.getPdfObject(0); } return indirect.getNumber(); } /** * Gets a List with the bookmarks. It returns null if * the document doesn't have any bookmarks. * @param reader the document * @return a List with the bookmarks or null if the * document doesn't have any */ public static List getBookmark(PdfReader reader) { PdfDictionary catalog = reader.getCatalog(); PdfObject obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.OUTLINES)); if (obj == null || !obj.isDictionary()) return null; PdfDictionary outlines = (PdfDictionary)obj; IntHashtable pages = new IntHashtable(); int numPages = reader.getNumberOfPages(); for (int k = 1; k <= numPages; ++k) { pages.put(reader.getPageOrigRef(k).getNumber(), k); reader.releasePage(k); } return bookmarkDepth(reader, (PdfDictionary)PdfReader.getPdfObjectRelease(outlines.get(PdfName.FIRST)), pages); } /** * Removes the bookmark entries for a number of page ranges. The page ranges * consists of a number of pairs with the start/end page range. The page numbers * are inclusive. * @param list the bookmarks * @param pageRange the page ranges, always in pairs. */ public static void eliminatePages(List list, int pageRange[]) { if (list == null) return; for (Iterator it = list.listIterator(); it.hasNext();) { HashMap map = (HashMap)it.next(); boolean hit = false; if ("GoTo".equals(map.get("Action"))) { String page = (String)map.get("Page"); if (page != null) { page = page.trim(); int idx = page.indexOf(' '); int pageNum; if (idx < 0) pageNum = Integer.parseInt(page); else pageNum = Integer.parseInt(page.substring(0, idx)); int len = pageRange.length & 0xfffffffe; for (int k = 0; k < len; k += 2) { if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) { hit = true; break; } } } } List kids = (List)map.get("Kids"); if (kids != null) { eliminatePages(kids, pageRange); if (kids.isEmpty()) { map.remove("Kids"); kids = null; } } if (hit) { if (kids == null) it.remove(); else { map.remove("Action"); map.remove("Page"); map.remove("Named"); } } } } /** * For the pages in range add the pageShift to the page number. * The page ranges * consists of a number of pairs with the start/end page range. The page numbers * are inclusive. * @param list the bookmarks * @param pageShift the number to add to the pages in range * @param pageRange the page ranges, always in pairs. It can be null * to include all the pages */ public static void shiftPageNumbers(List list, int pageShift, int pageRange[]) { if (list == null) return; for (Iterator it = list.listIterator(); it.hasNext();) { HashMap map = (HashMap)it.next(); if ("GoTo".equals(map.get("Action"))) { String page = (String)map.get("Page"); if (page != null) { page = page.trim(); int idx = page.indexOf(' '); int pageNum; if (idx < 0) pageNum = Integer.parseInt(page); else pageNum = Integer.parseInt(page.substring(0, idx)); boolean hit = false; if (pageRange == null) hit = true; else { int len = pageRange.length & 0xfffffffe; for (int k = 0; k < len; k += 2) { if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) { hit = true; break; } } } if (hit) { if (idx < 0) page = Integer.toString(pageNum + pageShift); else page = (pageNum + pageShift) + page.substring(idx); } map.put("Page", page); } } List kids = (List)map.get("Kids"); if (kids != null) shiftPageNumbers(kids, pageShift, pageRange); } } static void createOutlineAction(PdfDictionary outline, HashMap map, PdfWriter writer, boolean namedAsNames) { try { String action = (String)map.get("Action"); if ("GoTo".equals(action)) { String p; if ((p = (String)map.get("Named")) != null) { if (namedAsNames) outline.put(PdfName.DEST, new PdfName(p)); else outline.put(PdfName.DEST, new PdfString(p, null)); } else if ((p = (String)map.get("Page")) != null) { PdfArray ar = new PdfArray(); StringTokenizer tk = new StringTokenizer(p); int n = Integer.parseInt(tk.nextToken()); ar.add(writer.getPageReference(n)); if (!tk.hasMoreTokens()) { ar.add(PdfName.XYZ); ar.add(new float[]{0, 10000, 0}); } else { String fn = tk.nextToken(); if (fn.startsWith("/")) fn = fn.substring(1); ar.add(new PdfName(fn)); for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) { fn = tk.nextToken(); if (fn.equals("null")) ar.add(PdfNull.PDFNULL); else ar.add(new PdfNumber(fn)); } } outline.put(PdfName.DEST, ar); } } else if ("GoToR".equals(action)) { String p; PdfDictionary dic = new PdfDictionary(); if ((p = (String)map.get("Named")) != null) dic.put(PdfName.D, new PdfString(p, null)); else if ((p = (String)map.get("NamedN")) != null) dic.put(PdfName.D, new PdfName(p)); else if ((p = (String)map.get("Page")) != null){ PdfArray ar = new PdfArray(); StringTokenizer tk = new StringTokenizer(p); ar.add(new PdfNumber(tk.nextToken())); if (!tk.hasMoreTokens()) { ar.add(PdfName.XYZ); ar.add(new float[]{0, 10000, 0}); } else { String fn = tk.nextToken(); if (fn.startsWith("/")) fn = fn.substring(1); ar.add(new PdfName(fn)); for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) { fn = tk.nextToken(); if (fn.equals("null")) ar.add(PdfNull.PDFNULL); else ar.add(new PdfNumber(fn)); } } dic.put(PdfName.D, ar); } String file = (String)map.get("File"); if (dic.size() > 0 && file != null) { dic.put(PdfName.S, PdfName.GOTOR); dic.put(PdfName.F, new PdfString(file)); String nw = (String)map.get("NewWindow"); if (nw != null) { if (nw.equals("true")) dic.put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE); else if (nw.equals("false")) dic.put(PdfName.NEWWINDOW, PdfBoolean.PDFFALSE); } outline.put(PdfName.A, dic); } } else if ("URI".equals(action)) { String uri = (String)map.get("URI"); if (uri != null) { PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.S, PdfName.URI); dic.put(PdfName.URI, new PdfString(uri)); outline.put(PdfName.A, dic); } } else if ("Launch".equals(action)) { String file = (String)map.get("File"); if (file != null) { PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.S, PdfName.LAUNCH); dic.put(PdfName.F, new PdfString(file)); outline.put(PdfName.A, dic); } } } catch (Exception e) { // empty on purpose } } public static Object[] iterateOutlines(PdfWriter writer, PdfIndirectReference parent, List kids, boolean namedAsNames) throws IOException { PdfIndirectReference refs[] = new PdfIndirectReference[kids.size()]; for (int k = 0; k < refs.length; ++k) refs[k] = writer.getPdfIndirectReference(); int ptr = 0; int count = 0; for (Iterator it = kids.listIterator(); it.hasNext(); ++ptr) { HashMap map = (HashMap)it.next(); Object lower[] = null; List subKid = (List)map.get("Kids"); if (subKid != null && !subKid.isEmpty()) lower = iterateOutlines(writer, refs[ptr], subKid, namedAsNames); PdfDictionary outline = new PdfDictionary(); ++count; if (lower != null) { outline.put(PdfName.FIRST, (PdfIndirectReference)lower[0]); outline.put(PdfName.LAST, (PdfIndirectReference)lower[1]); int n = ((Integer)lower[2]).intValue(); if ("false".equals(map.get("Open"))) { outline.put(PdfName.COUNT, new PdfNumber(-n)); } else { outline.put(PdfName.COUNT, new PdfNumber(n)); count += n; } } outline.put(PdfName.PARENT, parent); if (ptr > 0) outline.put(PdfName.PREV, refs[ptr - 1]); if (ptr < refs.length - 1) outline.put(PdfName.NEXT, refs[ptr + 1]); outline.put(PdfName.TITLE, new PdfString((String)map.get("Title"), PdfObject.TEXT_UNICODE)); String color = (String)map.get("Color"); if (color != null) { try { PdfArray arr = new PdfArray(); StringTokenizer tk = new StringTokenizer(color); for (int k = 0; k < 3; ++k) { float f = Float.parseFloat(tk.nextToken()); if (f < 0) f = 0; if (f > 1) f = 1; arr.add(new PdfNumber(f)); } outline.put(PdfName.C, arr); } catch(Exception e){} //in case it's malformed } String style = (String)map.get("Style"); if (style != null) { style = style.toLowerCase(); int bits = 0; if (style.indexOf("italic") >= 0) bits |= 1; if (style.indexOf("bold") >= 0) bits |= 2; if (bits != 0) outline.put(PdfName.F, new PdfNumber(bits)); } createOutlineAction(outline, map, writer, namedAsNames); writer.addToBody(outline, refs[ptr]); } return new Object[]{refs[0], refs[refs.length - 1], new Integer(count)}; } /** * Exports the bookmarks to XML. Only of use if the generation is to be include in * some other XML document. * @param list the bookmarks * @param out the export destination. The writer is not closed * @param indent the indentation level. Pretty printing significant only * @param onlyASCII codes above 127 will always be escaped with &#nn; if true, * whatever the encoding * @throws IOException on error */ public static void exportToXMLNode(List list, Writer out, int indent, boolean onlyASCII) throws IOException { String dep = ""; for (int k = 0; k < indent; ++k) dep += " "; for (Iterator it = list.iterator(); it.hasNext();) { HashMap map = (HashMap)it.next(); String title = null; out.write(dep); out.write(""); if (title == null) title = ""; out.write(SimpleXMLParser.escapeXML(title, onlyASCII)); if (kids != null) { out.write("\n"); exportToXMLNode(kids, out, indent + 1, onlyASCII); out.write(dep); } out.write("\n"); } } /** * Exports the bookmarks to XML. The DTD for this XML is: *

    *

         * <?xml version='1.0' encoding='UTF-8'?>
         * <!ELEMENT Title (#PCDATA|Title)*>
         * <!ATTLIST Title
         *    Action CDATA #IMPLIED
         *    Open CDATA #IMPLIED
         *    Page CDATA #IMPLIED
         *    URI CDATA #IMPLIED
         *    File CDATA #IMPLIED
         *    Named CDATA #IMPLIED
         *    NamedN CDATA #IMPLIED
         *    NewWindow CDATA #IMPLIED
         *    Style CDATA #IMPLIED
         *    Color CDATA #IMPLIED
         * >
         * <!ELEMENT Bookmark (Title)*>
         * 
    * @param list the bookmarks * @param out the export destination. The stream is not closed * @param encoding the encoding according to IANA conventions * @param onlyASCII codes above 127 will always be escaped with &#nn; if true, * whatever the encoding * @throws IOException on error */ public static void exportToXML(List list, OutputStream out, String encoding, boolean onlyASCII) throws IOException { String jenc = IanaEncodings.getJavaEncoding(encoding); Writer wrt = new BufferedWriter(new OutputStreamWriter(out, jenc)); exportToXML(list, wrt, encoding, onlyASCII); } /** * Exports the bookmarks to XML. * @param list the bookmarks * @param wrt the export destination. The writer is not closed * @param encoding the encoding according to IANA conventions * @param onlyASCII codes above 127 will always be escaped with &#nn; if true, * whatever the encoding * @throws IOException on error */ public static void exportToXML(List list, Writer wrt, String encoding, boolean onlyASCII) throws IOException { wrt.write("\n\n"); exportToXMLNode(list, wrt, 1, onlyASCII); wrt.write("\n"); wrt.flush(); } /** * Import the bookmarks from XML. * @param in the XML source. The stream is not closed * @throws IOException on error * @return the bookmarks */ public static List importFromXML(InputStream in) throws IOException { SimpleBookmark book = new SimpleBookmark(); SimpleXMLParser.parse(book, in); return book.topList; } /** * Import the bookmarks from XML. * @param in the XML source. The reader is not closed * @throws IOException on error * @return the bookmarks */ public static List importFromXML(Reader in) throws IOException { SimpleBookmark book = new SimpleBookmark(); SimpleXMLParser.parse(book, in); return book.topList; } public void endDocument() { } public void endElement(String tag) { if (tag.equals("Bookmark")) { if (attr.isEmpty()) return; else throw new RuntimeException("Bookmark end tag out of place."); } if (!tag.equals("Title")) throw new RuntimeException("Invalid end tag - " + tag); HashMap attributes = (HashMap)attr.pop(); String title = (String)attributes.get("Title"); attributes.put("Title", title.trim()); String named = (String)attributes.get("Named"); if (named != null) attributes.put("Named", SimpleNamedDestination.unEscapeBinaryString(named)); named = (String)attributes.get("NamedN"); if (named != null) attributes.put("NamedN", SimpleNamedDestination.unEscapeBinaryString(named)); if (attr.isEmpty()) topList.add(attributes); else { HashMap parent = (HashMap)attr.peek(); List kids = (List)parent.get("Kids"); if (kids == null) { kids = new ArrayList(); parent.put("Kids", kids); } kids.add(attributes); } } public void startDocument() { } public void startElement(String tag, HashMap h) { if (topList == null) { if (tag.equals("Bookmark")) { topList = new ArrayList(); return; } else throw new RuntimeException("Root element is not Bookmark: " + tag); } if (!tag.equals("Title")) throw new RuntimeException("Tag " + tag + " not allowed."); HashMap attributes = new HashMap(h); attributes.put("Title", ""); attributes.remove("Kids"); attr.push(attributes); } public void text(String str) { if (attr.isEmpty()) return; HashMap attributes = (HashMap)attr.peek(); String title = (String)attributes.get("Title"); title += str; attributes.put("Title", title); } } src/core/com/lowagie/text/pdf/SimpleNamedDestination.java100644 0 0 31176 11154165266 21170 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import com.lowagie.text.xml.simpleparser.IanaEncodings; import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; import com.lowagie.text.xml.simpleparser.SimpleXMLParser; /** * * @author Paulo Soares (psoares@consiste.pt) */ public final class SimpleNamedDestination implements SimpleXMLDocHandler { private HashMap xmlNames; private HashMap xmlLast; private SimpleNamedDestination() { } public static HashMap getNamedDestination(PdfReader reader, boolean fromNames) { IntHashtable pages = new IntHashtable(); int numPages = reader.getNumberOfPages(); for (int k = 1; k <= numPages; ++k) pages.put(reader.getPageOrigRef(k).getNumber(), k); HashMap names = fromNames ? reader.getNamedDestinationFromNames() : reader.getNamedDestinationFromStrings(); for (Iterator it = names.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); PdfArray arr = (PdfArray)entry.getValue(); StringBuffer s = new StringBuffer(); try { s.append(pages.get(arr.getAsIndirectObject(0).getNumber())); s.append(' ').append(arr.getPdfObject(1).toString().substring(1)); for (int k = 2; k < arr.size(); ++k) s.append(' ').append(arr.getPdfObject(k).toString()); entry.setValue(s.toString()); } catch (Exception e) { it.remove(); } } return names; } /** * Exports the destinations to XML. The DTD for this XML is: *

    *

         * <?xml version='1.0' encoding='UTF-8'?>
         * <!ELEMENT Name (#PCDATA)>
         * <!ATTLIST Name
         *    Page CDATA #IMPLIED
         * >
         * <!ELEMENT Destination (Name)*>
         * 
    * @param names the names * @param out the export destination. The stream is not closed * @param encoding the encoding according to IANA conventions * @param onlyASCII codes above 127 will always be escaped with &#nn; if true, * whatever the encoding * @throws IOException on error */ public static void exportToXML(HashMap names, OutputStream out, String encoding, boolean onlyASCII) throws IOException { String jenc = IanaEncodings.getJavaEncoding(encoding); Writer wrt = new BufferedWriter(new OutputStreamWriter(out, jenc)); exportToXML(names, wrt, encoding, onlyASCII); } /** * Exports the destinations to XML. * @param names the names * @param wrt the export destination. The writer is not closed * @param encoding the encoding according to IANA conventions * @param onlyASCII codes above 127 will always be escaped with &#nn; if true, * whatever the encoding * @throws IOException on error */ public static void exportToXML(HashMap names, Writer wrt, String encoding, boolean onlyASCII) throws IOException { wrt.write("\n\n"); for (Iterator it = names.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); String key = (String)entry.getKey(); String value = (String)entry.getValue(); wrt.write(" "); wrt.write(SimpleXMLParser.escapeXML(escapeBinaryString(key), onlyASCII)); wrt.write("\n"); } wrt.write("\n"); wrt.flush(); } /** * Import the names from XML. * @param in the XML source. The stream is not closed * @throws IOException on error * @return the names */ public static HashMap importFromXML(InputStream in) throws IOException { SimpleNamedDestination names = new SimpleNamedDestination(); SimpleXMLParser.parse(names, in); return names.xmlNames; } /** * Import the names from XML. * @param in the XML source. The reader is not closed * @throws IOException on error * @return the names */ public static HashMap importFromXML(Reader in) throws IOException { SimpleNamedDestination names = new SimpleNamedDestination(); SimpleXMLParser.parse(names, in); return names.xmlNames; } static PdfArray createDestinationArray(String value, PdfWriter writer) { PdfArray ar = new PdfArray(); StringTokenizer tk = new StringTokenizer(value); int n = Integer.parseInt(tk.nextToken()); ar.add(writer.getPageReference(n)); if (!tk.hasMoreTokens()) { ar.add(PdfName.XYZ); ar.add(new float[]{0, 10000, 0}); } else { String fn = tk.nextToken(); if (fn.startsWith("/")) fn = fn.substring(1); ar.add(new PdfName(fn)); for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) { fn = tk.nextToken(); if (fn.equals("null")) ar.add(PdfNull.PDFNULL); else ar.add(new PdfNumber(fn)); } } return ar; } public static PdfDictionary outputNamedDestinationAsNames(HashMap names, PdfWriter writer) { PdfDictionary dic = new PdfDictionary(); for (Iterator it = names.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); try { String key = (String)entry.getKey(); String value = (String)entry.getValue(); PdfArray ar = createDestinationArray(value, writer); PdfName kn = new PdfName(key); dic.put(kn, ar); } catch (Exception e) { // empty on purpose } } return dic; } public static PdfDictionary outputNamedDestinationAsStrings(HashMap names, PdfWriter writer) throws IOException { HashMap n2 = new HashMap(names); for (Iterator it = n2.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); try { String value = (String)entry.getValue(); PdfArray ar = createDestinationArray(value, writer); entry.setValue(writer.addToBody(ar).getIndirectReference()); } catch (Exception e) { it.remove(); } } return PdfNameTree.writeTree(n2, writer); } public static String escapeBinaryString(String s) { StringBuffer buf = new StringBuffer(); char cc[] = s.toCharArray(); int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; if (c < ' ') { buf.append('\\'); String octal = "00" + Integer.toOctalString(c); buf.append(octal.substring(octal.length() - 3)); } else if (c == '\\') buf.append("\\\\"); else buf.append(c); } return buf.toString(); } public static String unEscapeBinaryString(String s) { StringBuffer buf = new StringBuffer(); char cc[] = s.toCharArray(); int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; if (c == '\\') { if (++k >= len) { buf.append('\\'); break; } c = cc[k]; if (c >= '0' && c <= '7') { int n = c - '0'; ++k; for (int j = 0; j < 2 && k < len; ++j) { c = cc[k]; if (c >= '0' && c <= '7') { ++k; n = n * 8 + c - '0'; } else { break; } } --k; buf.append((char)n); } else buf.append(c); } else buf.append(c); } return buf.toString(); } public void endDocument() { } public void endElement(String tag) { if (tag.equals("Destination")) { if (xmlLast == null && xmlNames != null) return; else throw new RuntimeException("Destination end tag out of place."); } if (!tag.equals("Name")) throw new RuntimeException("Invalid end tag - " + tag); if (xmlLast == null || xmlNames == null) throw new RuntimeException("Name end tag out of place."); if (!xmlLast.containsKey("Page")) throw new RuntimeException("Page attribute missing."); xmlNames.put(unEscapeBinaryString((String)xmlLast.get("Name")), xmlLast.get("Page")); xmlLast = null; } public void startDocument() { } public void startElement(String tag, HashMap h) { if (xmlNames == null) { if (tag.equals("Destination")) { xmlNames = new HashMap(); return; } else throw new RuntimeException("Root element is not Destination."); } if (!tag.equals("Name")) throw new RuntimeException("Tag " + tag + " not allowed."); if (xmlLast != null) throw new RuntimeException("Nested tags are not allowed."); xmlLast = new HashMap(h); xmlLast.put("Name", ""); } public void text(String str) { if (xmlLast == null) return; String name = (String)xmlLast.get("Name"); name += str; xmlLast.put("Name", name); } }src/core/com/lowagie/text/pdf/SpotColor.java100644 0 0 6634 11036112746 16467 0ustar 0 0 /* * $Id: SpotColor.java 3514 2008-06-27 09:26:36Z blowagie $ * * Copyright 2002 by Phillip Pan * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * * @author psoares */ public class SpotColor extends ExtendedColor { private static final long serialVersionUID = -6257004582113248079L; PdfSpotColor spot; float tint; public SpotColor(PdfSpotColor spot, float tint) { super(TYPE_SEPARATION, (spot.getAlternativeCS().getRed() / 255f - 1f) * tint + 1, (spot.getAlternativeCS().getGreen() / 255f - 1f) * tint + 1, (spot.getAlternativeCS().getBlue() / 255f - 1f) * tint + 1); this.spot = spot; this.tint = tint; } public SpotColor(PdfSpotColor spot) { this(spot, spot.getTint()); } public PdfSpotColor getPdfSpotColor() { return spot; } public float getTint() { return tint; } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return spot.hashCode() ^ Float.floatToIntBits(tint); } } src/core/com/lowagie/text/pdf/StampContent.java100644 0 0 6734 11000354131 17146 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; public class StampContent extends PdfContentByte { PdfStamperImp.PageStamp ps; PageResources pageResources; /** Creates a new instance of StampContent */ StampContent(PdfStamperImp stamper, PdfStamperImp.PageStamp ps) { super(stamper); this.ps = ps; pageResources = ps.pageResources; } public void setAction(PdfAction action, float llx, float lly, float urx, float ury) { ((PdfStamperImp)writer).addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action), ps.pageN); } /** * Gets a duplicate of this PdfContentByte. All * the members are copied by reference but the buffer stays different. * * @return a copy of this PdfContentByte */ public PdfContentByte getDuplicate() { return new StampContent((PdfStamperImp)writer, ps); } PageResources getPageResources() { return pageResources; } void addAnnotation(PdfAnnotation annot) { ((PdfStamperImp)writer).addAnnotation(annot, ps.pageN); } }src/core/com/lowagie/text/pdf/StandardDecryption.java100644 0 0 10354 11000354131 20341 0ustar 0 0 /* * $Id: StandardDecryption.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.pdf.crypto.AESCipher; import com.lowagie.text.pdf.crypto.ARCFOUREncryption; public class StandardDecryption { protected ARCFOUREncryption arcfour; protected AESCipher cipher; private byte[] key; private static final int AES_128 = 4; private boolean aes; private boolean initiated; private byte[] iv = new byte[16]; private int ivptr; /** Creates a new instance of StandardDecryption */ public StandardDecryption(byte key[], int off, int len, int revision) { aes = revision == AES_128; if (aes) { this.key = new byte[len]; System.arraycopy(key, off, this.key, 0, len); } else { arcfour = new ARCFOUREncryption(); arcfour.prepareARCFOURKey(key, off, len); } } public byte[] update(byte[] b, int off, int len) { if (aes) { if (initiated) return cipher.update(b, off, len); else { int left = Math.min(iv.length - ivptr, len); System.arraycopy(b, off, iv, ivptr, left); off += left; len -= left; ivptr += left; if (ivptr == iv.length) { cipher = new AESCipher(false, key, iv); initiated = true; if (len > 0) return cipher.update(b, off, len); } return null; } } else { byte[] b2 = new byte[len]; arcfour.encryptARCFOUR(b, off, len, b2, 0); return b2; } } public byte[] finish() { if (aes) { return cipher.doFinal(); } else return null; } }src/core/com/lowagie/text/pdf/TSAClient.java100644 0 0 7142 11215636056 16330 0ustar 0 0 /* * $Id: TSAClient.java 3959 2009-06-09 08:31:05Z blowagie $ * * Copyright 2009 Martin Brunecky * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; /** * Time Stamp Authority client (caller) interface. *

    * Interface used by the PdfPKCS7 digital signature builder to call * Time Stamp Authority providing RFC 3161 compliant time stamp token. * @author Martin Brunecky, 07/17/2007 * @since 2.1.6 */ public interface TSAClient { /** * Get the time stamp token size estimate. * Implementation must return value large enough to accomodate the entire token * returned by getTimeStampToken() _prior_ to actual getTimeStampToken() call. * @return an estimate of the token size */ public int getTokenSizeEstimate(); /** * Get RFC 3161 timeStampToken. * Method may return null indicating that timestamp should be skipped. * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) * @param imprint byte[] - data imprint to be time-stamped * @return byte[] - encoded, TSA signed data of the timeStampToken * @throws Exception - TSA request failed */ public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception; }src/core/com/lowagie/text/pdf/TSAClientBouncyCastle.java100644 0 0 23765 11215651460 20671 0ustar 0 0 /* * $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $ * * Copyright 2009 Martin Brunecky, Aiken Sam * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.*; import java.math.*; import java.net.*; import org.bouncycastle.asn1.cmp.*; import org.bouncycastle.asn1.x509.*; import org.bouncycastle.tsp.*; import com.lowagie.text.pdf.codec.Base64; /** * Time Stamp Authority Client interface implementation using Bouncy Castle * org.bouncycastle.tsp package. *

    * Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007 * for ease of subclassing. *

    * @since 2.1.6 */ public class TSAClientBouncyCastle implements TSAClient { /** URL of the Time Stamp Authority */ protected String tsaURL; /** TSA Username */ protected String tsaUsername; /** TSA password */ protected String tsaPassword; /** Estimate of the received time stamp token */ protected int tokSzEstimate; /** * Creates an instance of a TSAClient that will use BouncyCastle. * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") */ public TSAClientBouncyCastle(String url) { this(url, null, null, 4096); } /** * Creates an instance of a TSAClient that will use BouncyCastle. * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") * @param username String - user(account) name * @param password String - password */ public TSAClientBouncyCastle(String url, String username, String password) { this(url, username, password, 4096); } /** * Constructor. * Note the token size estimate is updated by each call, as the token * size is not likely to change (as long as we call the same TSA using * the same imprint length). * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") * @param username String - user(account) name * @param password String - password * @param tokSzEstimate int - estimated size of received time stamp token (DER encoded) */ public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) { this.tsaURL = url; this.tsaUsername = username; this.tsaPassword = password; this.tokSzEstimate = tokSzEstimate; } /** * Get the token size estimate. * Returned value reflects the result of the last succesfull call, padded * @return an estimate of the token size */ public int getTokenSizeEstimate() { return tokSzEstimate; } /** * Get RFC 3161 timeStampToken. * Method may return null indicating that timestamp should be skipped. * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) * @param imprint byte[] - data imprint to be time-stamped * @return byte[] - encoded, TSA signed data of the timeStampToken * @throws Exception - TSA request failed * @see com.lowagie.text.pdf.TSAClient#getTimeStampToken(com.lowagie.text.pdf.PdfPKCS7, byte[]) */ public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception { return getTimeStampToken(imprint); } /** * Get timestamp token - Bouncy Castle request encoding / decoding layer */ protected byte[] getTimeStampToken(byte[] imprint) throws Exception { byte[] respBytes = null; try { // Setup the time stamp request TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); tsqGenerator.setCertReq(true); // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1"); BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce); byte[] requestBytes = request.getEncoded(); // Call the communications layer respBytes = getTSAResponse(requestBytes); // Handle the TSA response TimeStampResponse response = new TimeStampResponse(respBytes); // validate communication level attributes (RFC 3161 PKIStatus) response.validate(request); PKIFailureInfo failure = response.getFailInfo(); int value = (failure == null) ? 0 : failure.intValue(); if (value != 0) { // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value); } // @todo: validate the time stap certificate chain (if we want // assure we do not sign using an invalid timestamp). // extract just the time stamp token (removes communication status info) TimeStampToken tsToken = response.getTimeStampToken(); if (tsToken == null) { throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString()); } TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details byte[] encoded = tsToken.getEncoded(); long stop = System.currentTimeMillis(); // Update our token size estimate for the next call (padded to be safe) this.tokSzEstimate = encoded.length + 32; return encoded; } catch (Exception e) { throw e; } catch (Throwable t) { throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t); } } /** * Get timestamp token - communications layer * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded) */ protected byte[] getTSAResponse(byte[] requestBytes) throws Exception { // Setup the TSA connection URL url = new URL(tsaURL); URLConnection tsaConnection; tsaConnection = (URLConnection) url.openConnection(); tsaConnection.setDoInput(true); tsaConnection.setDoOutput(true); tsaConnection.setUseCaches(false); tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query"); //tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64"); tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary"); if ((tsaUsername != null) && !tsaUsername.equals("") ) { String userPassword = tsaUsername + ":" + tsaPassword; tsaConnection.setRequestProperty("Authorization", "Basic " + new String(Base64.encodeBytes(userPassword.getBytes()))); } OutputStream out = tsaConnection.getOutputStream(); out.write(requestBytes); out.close(); // Get TSA response as a byte array InputStream inp = tsaConnection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int bytesRead = 0; while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) { baos.write(buffer, 0, bytesRead); } byte[] respBytes = baos.toByteArray(); String encoding = tsaConnection.getContentEncoding(); if (encoding != null && encoding.equalsIgnoreCase("base64")) { respBytes = Base64.decode(new String(respBytes)); } return respBytes; } }src/core/com/lowagie/text/pdf/TextField.java100644 0 0 65351 11154165267 16463 0ustar 0 0 /* * Copyright 2003-2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; /** * Supports text, combo and list fields generating the correct appearances. * All the option in the Acrobat GUI are supported in an easy to use API. * @author Paulo Soares (psoares@consiste.pt) */ public class TextField extends BaseField { /** Holds value of property defaultText. */ private String defaultText; /** Holds value of property choices. */ private String[] choices; /** Holds value of property choiceExports. */ private String[] choiceExports; /** Holds value of property choiceSelection. */ private int choiceSelection; private int topFirst; private float extraMarginLeft; private float extraMarginTop; /** * Creates a new TextField. * @param writer the document PdfWriter * @param box the field location and dimensions * @param fieldName the field name. If null only the widget keys * will be included in the field allowing it to be used as a kid field. */ public TextField(PdfWriter writer, Rectangle box, String fieldName) { super(writer, box, fieldName); } private static boolean checkRTL(String text) { if (text == null || text.length() == 0) return false; char[] cc = text.toCharArray(); for (int k = 0; k < cc.length; ++k) { int c = cc[k]; if (c >= 0x590 && c < 0x0780) return true; } return false; } private static void changeFontSize(Phrase p, float size) { for (int k = 0; k < p.size(); ++k) ((Chunk)p.get(k)).getFont().setSize(size); } private Phrase composePhrase(String text, BaseFont ufont, Color color, float fontSize) { Phrase phrase = null; if (extensionFont == null && (substitutionFonts == null || substitutionFonts.isEmpty())) phrase = new Phrase(new Chunk(text, new Font(ufont, fontSize, 0, color))); else { FontSelector fs = new FontSelector(); fs.addFont(new Font(ufont, fontSize, 0, color)); if (extensionFont != null) fs.addFont(new Font(extensionFont, fontSize, 0, color)); if (substitutionFonts != null) { for (int k = 0; k < substitutionFonts.size(); ++k) fs.addFont(new Font((BaseFont)substitutionFonts.get(k), fontSize, 0, color)); } phrase = fs.process(text); } return phrase; } /** * Removes CRLF from a String. * * @param text * @return String * @since 2.1.5 */ public static String removeCRLF(String text) { if (text.indexOf('\n') >= 0 || text.indexOf('\r') >= 0) { char[] p = text.toCharArray(); StringBuffer sb = new StringBuffer(p.length); for (int k = 0; k < p.length; ++k) { char c = p[k]; if (c == '\n') sb.append(' '); else if (c == '\r') { sb.append(' '); if (k < p.length - 1 && p[k + 1] == '\n') ++k; } else sb.append(c); } return sb.toString(); } return text; } /** * Obfuscates a password String. * Every character is replaced by an asterisk (*). * * @param text * @return String * @since 2.1.5 */ public static String obfuscatePassword(String text) { char[] pchar = new char[text.length()]; for (int i = 0; i < text.length(); i++) pchar[i] = '*'; return new String(pchar); } /** * Get the PdfAppearance of a text or combo field * @throws IOException on error * @throws DocumentException on error * @return A PdfAppearance */ public PdfAppearance getAppearance() throws IOException, DocumentException { PdfAppearance app = getBorderAppearance(); app.beginVariableText(); if (text == null || text.length() == 0) { app.endVariableText(); return app; } boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; float h = box.getHeight() - borderWidth * 2 - extraMarginTop; float bw2 = borderWidth; if (borderExtra) { h -= borderWidth * 2; bw2 *= 2; } float offsetX = Math.max(bw2, 1); float offX = Math.min(bw2, offsetX); app.saveState(); app.rectangle(offX, offX, box.getWidth() - 2 * offX, box.getHeight() - 2 * offX); app.clip(); app.newPath(); String ptext; if ((options & PASSWORD) != 0) ptext = obfuscatePassword(text); else if ((options & MULTILINE) == 0) ptext = removeCRLF(text); else ptext = text; //fixed by Kazuya Ujihara (ujihara.jp) BaseFont ufont = getRealFont(); Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor; int rtl = checkRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI; float usize = fontSize; Phrase phrase = composePhrase(ptext, ufont, fcolor, usize); if ((options & MULTILINE) != 0) { float width = box.getWidth() - 4 * offsetX - extraMarginLeft; float factor = ufont.getFontDescriptor(BaseFont.BBOXURY, 1) - ufont.getFontDescriptor(BaseFont.BBOXLLY, 1); ColumnText ct = new ColumnText(null); if (usize == 0) { usize = h / factor; if (usize > 4) { if (usize > 12) usize = 12; float step = Math.max((usize - 4) / 10, 0.2f); ct.setSimpleColumn(0, -h, width, 0); ct.setAlignment(alignment); ct.setRunDirection(rtl); for (; usize > 4; usize -= step) { ct.setYLine(0); changeFontSize(phrase, usize); ct.setText(phrase); ct.setLeading(factor * usize); int status = ct.go(true); if ((status & ColumnText.NO_MORE_COLUMN) == 0) break; } } if (usize < 4) usize = 4; } changeFontSize(phrase, usize); ct.setCanvas(app); float leading = usize * factor; float offsetY = offsetX + h - ufont.getFontDescriptor(BaseFont.BBOXURY, usize); ct.setSimpleColumn(extraMarginLeft + 2 * offsetX, -20000, box.getWidth() - 2 * offsetX, offsetY + leading); ct.setLeading(leading); ct.setAlignment(alignment); ct.setRunDirection(rtl); ct.setText(phrase); ct.go(); } else { if (usize == 0) { float maxCalculatedSize = h / (ufont.getFontDescriptor(BaseFont.BBOXURX, 1) - ufont.getFontDescriptor(BaseFont.BBOXLLY, 1)); changeFontSize(phrase, 1); float wd = ColumnText.getWidth(phrase, rtl, 0); if (wd == 0) usize = maxCalculatedSize; else usize = Math.min(maxCalculatedSize, (box.getWidth() - extraMarginLeft - 4 * offsetX) / wd); if (usize < 4) usize = 4; } changeFontSize(phrase, usize); float offsetY = offX + ((box.getHeight() - 2*offX) - ufont.getFontDescriptor(BaseFont.ASCENT, usize)) / 2; if (offsetY < offX) offsetY = offX; if (offsetY - offX < -ufont.getFontDescriptor(BaseFont.DESCENT, usize)) { float ny = -ufont.getFontDescriptor(BaseFont.DESCENT, usize) + offX; float dy = box.getHeight() - offX - ufont.getFontDescriptor(BaseFont.ASCENT, usize); offsetY = Math.min(ny, Math.max(offsetY, dy)); } if ((options & COMB) != 0 && maxCharacterLength > 0) { int textLen = Math.min(maxCharacterLength, ptext.length()); int position = 0; if (alignment == Element.ALIGN_RIGHT) position = maxCharacterLength - textLen; else if (alignment == Element.ALIGN_CENTER) position = (maxCharacterLength - textLen) / 2; float step = (box.getWidth() - extraMarginLeft) / maxCharacterLength; float start = step / 2 + position * step; if (textColor == null) app.setGrayFill(0); else app.setColorFill(textColor); app.beginText(); for (int k = 0; k < phrase.size(); ++k) { Chunk ck = (Chunk)phrase.get(k); BaseFont bf = ck.getFont().getBaseFont(); app.setFontAndSize(bf, usize); StringBuffer sb = ck.append(""); for (int j = 0; j < sb.length(); ++j) { String c = sb.substring(j, j + 1); float wd = bf.getWidthPoint(c, usize); app.setTextMatrix(extraMarginLeft + start - wd / 2, offsetY - extraMarginTop); app.showText(c); start += step; } } app.endText(); } else { float x; switch (alignment) { case Element.ALIGN_RIGHT: x = extraMarginLeft + box.getWidth() - (2 * offsetX); break; case Element.ALIGN_CENTER: x = extraMarginLeft + (box.getWidth() / 2); break; default: x = extraMarginLeft + (2 * offsetX); } ColumnText.showTextAligned(app, alignment, phrase, x, offsetY - extraMarginTop, 0, rtl, 0); } } app.restoreState(); app.endVariableText(); return app; } /** * Get the PdfAppearance of a list field * @throws IOException on error * @throws DocumentException on error * @return A PdfAppearance */ PdfAppearance getListAppearance() throws IOException, DocumentException { PdfAppearance app = getBorderAppearance(); app.beginVariableText(); if (choices == null || choices.length == 0) { app.endVariableText(); return app; } int topChoice = choiceSelection; if (topChoice >= choices.length) topChoice = choices.length - 1; if (topChoice < 0) topChoice = 0; BaseFont ufont = getRealFont(); float usize = fontSize; if (usize == 0) usize = 12; boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; float h = box.getHeight() - borderWidth * 2; float offsetX = borderWidth; if (borderExtra) { h -= borderWidth * 2; offsetX *= 2; } float leading = ufont.getFontDescriptor(BaseFont.BBOXURY, usize) - ufont.getFontDescriptor(BaseFont.BBOXLLY, usize); int maxFit = (int)(h / leading) + 1; int first = 0; int last = 0; last = topChoice + maxFit / 2 + 1; first = last - maxFit; if (first < 0) { last += first; first = 0; } // first = topChoice; last = first + maxFit; if (last > choices.length) last = choices.length; topFirst = first; app.saveState(); app.rectangle(offsetX, offsetX, box.getWidth() - 2 * offsetX, box.getHeight() - 2 * offsetX); app.clip(); app.newPath(); Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor; app.setColorFill(new Color(10, 36, 106)); app.rectangle(offsetX, offsetX + h - (topChoice - first + 1) * leading, box.getWidth() - 2 * offsetX, leading); app.fill(); float xp = offsetX * 2; float yp = offsetX + h - ufont.getFontDescriptor(BaseFont.BBOXURY, usize); for (int idx = first; idx < last; ++idx, yp -= leading) { String ptext = choices[idx]; int rtl = checkRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI; ptext = removeCRLF(ptext); Phrase phrase = composePhrase(ptext, ufont, (idx == topChoice) ? GrayColor.GRAYWHITE : fcolor, usize); ColumnText.showTextAligned(app, Element.ALIGN_LEFT, phrase, xp, yp, 0, rtl, 0); } app.restoreState(); app.endVariableText(); return app; } /** * Gets a new text field. * @throws IOException on error * @throws DocumentException on error * @return a new text field */ public PdfFormField getTextField() throws IOException, DocumentException { if (maxCharacterLength <= 0) options &= ~COMB; if ((options & COMB) != 0) options &= ~MULTILINE; PdfFormField field = PdfFormField.createTextField(writer, false, false, maxCharacterLength); field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); switch (alignment) { case Element.ALIGN_CENTER: field.setQuadding(PdfFormField.Q_CENTER); break; case Element.ALIGN_RIGHT: field.setQuadding(PdfFormField.Q_RIGHT); break; } if (rotation != 0) field.setMKRotation(rotation); if (fieldName != null) { field.setFieldName(fieldName); if (!"".equals(text)) field.setValueAsString(text); if (defaultText != null) field.setDefaultValueAsString(defaultText); if ((options & READ_ONLY) != 0) field.setFieldFlags(PdfFormField.FF_READ_ONLY); if ((options & REQUIRED) != 0) field.setFieldFlags(PdfFormField.FF_REQUIRED); if ((options & MULTILINE) != 0) field.setFieldFlags(PdfFormField.FF_MULTILINE); if ((options & DO_NOT_SCROLL) != 0) field.setFieldFlags(PdfFormField.FF_DONOTSCROLL); if ((options & PASSWORD) != 0) field.setFieldFlags(PdfFormField.FF_PASSWORD); if ((options & FILE_SELECTION) != 0) field.setFieldFlags(PdfFormField.FF_FILESELECT); if ((options & DO_NOT_SPELL_CHECK) != 0) field.setFieldFlags(PdfFormField.FF_DONOTSPELLCHECK); if ((options & COMB) != 0) field.setFieldFlags(PdfFormField.FF_COMB); } field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); PdfAppearance tp = getAppearance(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); PdfAppearance da = (PdfAppearance)tp.getDuplicate(); da.setFontAndSize(getRealFont(), fontSize); if (textColor == null) da.setGrayFill(0); else da.setColorFill(textColor); field.setDefaultAppearanceString(da); if (borderColor != null) field.setMKBorderColor(borderColor); if (backgroundColor != null) field.setMKBackgroundColor(backgroundColor); switch (visibility) { case HIDDEN: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); break; case VISIBLE_BUT_DOES_NOT_PRINT: break; case HIDDEN_BUT_PRINTABLE: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); break; default: field.setFlags(PdfAnnotation.FLAGS_PRINT); break; } return field; } /** * Gets a new combo field. * @throws IOException on error * @throws DocumentException on error * @return a new combo field */ public PdfFormField getComboField() throws IOException, DocumentException { return getChoiceField(false); } /** * Gets a new list field. * @throws IOException on error * @throws DocumentException on error * @return a new list field */ public PdfFormField getListField() throws IOException, DocumentException { return getChoiceField(true); } protected PdfFormField getChoiceField(boolean isList) throws IOException, DocumentException { options &= (~MULTILINE) & (~COMB); String uchoices[] = choices; if (uchoices == null) uchoices = new String[0]; int topChoice = choiceSelection; if (topChoice >= uchoices.length) topChoice = uchoices.length - 1; if (text == null) text = ""; //fixed by Kazuya Ujihara (ujihara.jp) if (topChoice >= 0) text = uchoices[topChoice]; if (topChoice < 0) topChoice = 0; PdfFormField field = null; String mix[][] = null; if (choiceExports == null) { if (isList) field = PdfFormField.createList(writer, uchoices, topChoice); else field = PdfFormField.createCombo(writer, (options & EDIT) != 0, uchoices, topChoice); } else { mix = new String[uchoices.length][2]; for (int k = 0; k < mix.length; ++k) mix[k][0] = mix[k][1] = uchoices[k]; int top = Math.min(uchoices.length, choiceExports.length); for (int k = 0; k < top; ++k) { if (choiceExports[k] != null) mix[k][0] = choiceExports[k]; } if (isList) field = PdfFormField.createList(writer, mix, topChoice); else field = PdfFormField.createCombo(writer, (options & EDIT) != 0, mix, topChoice); } field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); if (rotation != 0) field.setMKRotation(rotation); if (fieldName != null) { field.setFieldName(fieldName); if (uchoices.length > 0) { if (mix != null) { field.setValueAsString(mix[topChoice][0]); field.setDefaultValueAsString(mix[topChoice][0]); } else { field.setValueAsString(text); field.setDefaultValueAsString(text); } } if ((options & READ_ONLY) != 0) field.setFieldFlags(PdfFormField.FF_READ_ONLY); if ((options & REQUIRED) != 0) field.setFieldFlags(PdfFormField.FF_REQUIRED); if ((options & DO_NOT_SPELL_CHECK) != 0) field.setFieldFlags(PdfFormField.FF_DONOTSPELLCHECK); } field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); PdfAppearance tp; if (isList) { tp = getListAppearance(); if (topFirst > 0) field.put(PdfName.TI, new PdfNumber(topFirst)); } else tp = getAppearance(); field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); PdfAppearance da = (PdfAppearance)tp.getDuplicate(); da.setFontAndSize(getRealFont(), fontSize); if (textColor == null) da.setGrayFill(0); else da.setColorFill(textColor); field.setDefaultAppearanceString(da); if (borderColor != null) field.setMKBorderColor(borderColor); if (backgroundColor != null) field.setMKBackgroundColor(backgroundColor); switch (visibility) { case HIDDEN: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); break; case VISIBLE_BUT_DOES_NOT_PRINT: break; case HIDDEN_BUT_PRINTABLE: field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); break; default: field.setFlags(PdfAnnotation.FLAGS_PRINT); break; } return field; } /** * Gets the default text. * @return the default text */ public String getDefaultText() { return this.defaultText; } /** * Sets the default text. It is only meaningful for text fields. * @param defaultText the default text */ public void setDefaultText(String defaultText) { this.defaultText = defaultText; } /** * Gets the choices to be presented to the user in list/combo fields. * @return the choices to be presented to the user */ public String[] getChoices() { return this.choices; } /** * Sets the choices to be presented to the user in list/combo fields. * @param choices the choices to be presented to the user */ public void setChoices(String[] choices) { this.choices = choices; } /** * Gets the export values in list/combo fields. * @return the export values in list/combo fields */ public String[] getChoiceExports() { return this.choiceExports; } /** * Sets the export values in list/combo fields. If this array * is null then the choice values will also be used * as the export values. * @param choiceExports the export values in list/combo fields */ public void setChoiceExports(String[] choiceExports) { this.choiceExports = choiceExports; } /** * Gets the zero based index of the selected item. * @return the zero based index of the selected item */ public int getChoiceSelection() { return this.choiceSelection; } /** * Sets the zero based index of the selected item. * @param choiceSelection the zero based index of the selected item */ public void setChoiceSelection(int choiceSelection) { this.choiceSelection = choiceSelection; } int getTopFirst() { return topFirst; } /** * Sets extra margins in text fields to better mimic the Acrobat layout. * @param extraMarginLeft the extra margin left * @param extraMarginTop the extra margin top */ public void setExtraMargin(float extraMarginLeft, float extraMarginTop) { this.extraMarginLeft = extraMarginLeft; this.extraMarginTop = extraMarginTop; } /** * Holds value of property substitutionFonts. */ private ArrayList substitutionFonts; /** * Gets the list of substitution fonts. The list is composed of BaseFont and can be null. The fonts in this list will be used if the original * font doesn't contain the needed glyphs. * @return the list */ public ArrayList getSubstitutionFonts() { return this.substitutionFonts; } /** * Sets a list of substitution fonts. The list is composed of BaseFont and can also be null. The fonts in this list will be used if the original * font doesn't contain the needed glyphs. * @param substitutionFonts the list */ public void setSubstitutionFonts(ArrayList substitutionFonts) { this.substitutionFonts = substitutionFonts; } /** * Holds value of property extensionFont. */ private BaseFont extensionFont; /** * Gets the extensionFont. This font will be searched before the * substitution fonts. It may be null. * @return the extensionFont */ public BaseFont getExtensionFont() { return this.extensionFont; } /** * Sets the extensionFont. This font will be searched before the * substitution fonts. It may be null. * @param extensionFont New value of property extensionFont. */ public void setExtensionFont(BaseFont extensionFont) { this.extensionFont = extensionFont; } }src/core/com/lowagie/text/pdf/TrueTypeFont.java100644 0 0 161762 11213370070 17210 0ustar 0 0 /* * $Id: TrueTypeFont.java 3854 2009-04-14 08:02:10Z blowagie $ * * Copyright 2001-2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; /** Reads a Truetype font * * @author Paulo Soares (psoares@consiste.pt) */ class TrueTypeFont extends BaseFont { /** The code pages possible for a True Type font. */ static final String codePages[] = { "1252 Latin 1", "1250 Latin 2: Eastern Europe", "1251 Cyrillic", "1253 Greek", "1254 Turkish", "1255 Hebrew", "1256 Arabic", "1257 Windows Baltic", "1258 Vietnamese", null, null, null, null, null, null, null, "874 Thai", "932 JIS/Japan", "936 Chinese: Simplified chars--PRC and Singapore", "949 Korean Wansung", "950 Chinese: Traditional chars--Taiwan and Hong Kong", "1361 Korean Johab", null, null, null, null, null, null, null, "Macintosh Character Set (US Roman)", "OEM Character Set", "Symbol Character Set", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "869 IBM Greek", "866 MS-DOS Russian", "865 MS-DOS Nordic", "864 Arabic", "863 MS-DOS Canadian French", "862 Hebrew", "861 MS-DOS Icelandic", "860 MS-DOS Portuguese", "857 IBM Turkish", "855 IBM Cyrillic; primarily Russian", "852 Latin 2", "775 MS-DOS Baltic", "737 Greek; former 437 G", "708 Arabic; ASMO 708", "850 WE/Latin 1", "437 US"}; protected boolean justNames = false; /** Contains the location of the several tables. The key is the name of * the table and the value is an int[2] where position 0 * is the offset from the start of the file and position 1 is the length * of the table. */ protected HashMap tables; /** The file in use. */ protected RandomAccessFileOrArray rf; /** The file name. */ protected String fileName; protected boolean cff = false; protected int cffOffset; protected int cffLength; /** The offset from the start of the file to the table directory. * It is 0 for TTF and may vary for TTC depending on the chosen font. */ protected int directoryOffset; /** The index for the TTC font. It is an empty String for a * TTF file. */ protected String ttcIndex; /** The style modifier */ protected String style = ""; /** The content of table 'head'. */ protected FontHeader head = new FontHeader(); /** The content of table 'hhea'. */ protected HorizontalHeader hhea = new HorizontalHeader(); /** The content of table 'OS/2'. */ protected WindowsMetrics os_2 = new WindowsMetrics(); /** The width of the glyphs. This is essentially the content of table * 'hmtx' normalized to 1000 units. */ protected int GlyphWidths[]; protected int bboxes[][]; /** The map containing the code information for the table 'cmap', encoding 1.0. * The key is the code and the value is an int[2] where position 0 * is the glyph number and position 1 is the glyph width normalized to 1000 * units. */ protected HashMap cmap10; /** The map containing the code information for the table 'cmap', encoding 3.1 * in Unicode. *

    * The key is the code and the value is an int[2] where position 0 * is the glyph number and position 1 is the glyph width normalized to 1000 * units. */ protected HashMap cmap31; protected HashMap cmapExt; /** The map containing the kerning information. It represents the content of * table 'kern'. The key is an Integer where the top 16 bits * are the glyph number for the first character and the lower 16 bits are the * glyph number for the second character. The value is the amount of kerning in * normalized 1000 units as an Integer. This value is usually negative. */ protected IntHashtable kerning = new IntHashtable(); /** * The font name. * This name is usually extracted from the table 'name' with * the 'Name ID' 6. */ protected String fontName; /** The full name of the font */ protected String fullName[][]; /** All the names of the Names-Table */ protected String allNameEntries[][]; /** The family name of the font */ protected String familyName[][]; /** The italic angle. It is usually extracted from the 'post' table or in it's * absence with the code: *

    *

         * -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI
         * 
    */ protected double italicAngle; /** true if all the glyphs have the same width. */ protected boolean isFixedPitch = false; protected int underlinePosition; protected int underlineThickness; /** The components of table 'head'. */ protected static class FontHeader { /** A variable. */ int flags; /** A variable. */ int unitsPerEm; /** A variable. */ short xMin; /** A variable. */ short yMin; /** A variable. */ short xMax; /** A variable. */ short yMax; /** A variable. */ int macStyle; } /** The components of table 'hhea'. */ protected static class HorizontalHeader { /** A variable. */ short Ascender; /** A variable. */ short Descender; /** A variable. */ short LineGap; /** A variable. */ int advanceWidthMax; /** A variable. */ short minLeftSideBearing; /** A variable. */ short minRightSideBearing; /** A variable. */ short xMaxExtent; /** A variable. */ short caretSlopeRise; /** A variable. */ short caretSlopeRun; /** A variable. */ int numberOfHMetrics; } /** The components of table 'OS/2'. */ protected static class WindowsMetrics { /** A variable. */ short xAvgCharWidth; /** A variable. */ int usWeightClass; /** A variable. */ int usWidthClass; /** A variable. */ short fsType; /** A variable. */ short ySubscriptXSize; /** A variable. */ short ySubscriptYSize; /** A variable. */ short ySubscriptXOffset; /** A variable. */ short ySubscriptYOffset; /** A variable. */ short ySuperscriptXSize; /** A variable. */ short ySuperscriptYSize; /** A variable. */ short ySuperscriptXOffset; /** A variable. */ short ySuperscriptYOffset; /** A variable. */ short yStrikeoutSize; /** A variable. */ short yStrikeoutPosition; /** A variable. */ short sFamilyClass; /** A variable. */ byte panose[] = new byte[10]; /** A variable. */ byte achVendID[] = new byte[4]; /** A variable. */ int fsSelection; /** A variable. */ int usFirstCharIndex; /** A variable. */ int usLastCharIndex; /** A variable. */ short sTypoAscender; /** A variable. */ short sTypoDescender; /** A variable. */ short sTypoLineGap; /** A variable. */ int usWinAscent; /** A variable. */ int usWinDescent; /** A variable. */ int ulCodePageRange1; /** A variable. */ int ulCodePageRange2; /** A variable. */ int sCapHeight; } /** This constructor is present to allow extending the class. */ protected TrueTypeFont() { } /** Creates a new TrueType font. * @param ttFile the location of the font on file. The file must end in '.ttf' or * '.ttc' but can have modifiers after the name * @param enc the encoding to be applied to this font * @param emb true if the font is to be embedded in the PDF * @param ttfAfm the font as a byte array * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since 2.1.5 */ TrueTypeFont(String ttFile, String enc, boolean emb, byte ttfAfm[], boolean justNames, boolean forceRead) throws DocumentException, IOException { this.justNames = justNames; String nameBase = getBaseName(ttFile); String ttcName = getTTCName(nameBase); if (nameBase.length() < ttFile.length()) { style = ttFile.substring(nameBase.length()); } encoding = enc; embedded = emb; fileName = ttcName; fontType = FONT_TYPE_TT; ttcIndex = ""; if (ttcName.length() < nameBase.length()) ttcIndex = nameBase.substring(ttcName.length() + 1); if (fileName.toLowerCase().endsWith(".ttf") || fileName.toLowerCase().endsWith(".otf") || fileName.toLowerCase().endsWith(".ttc")) { process(ttfAfm, forceRead); if (!justNames && embedded && os_2.fsType == 2) throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions."); } else throw new DocumentException(fileName + style + " is not a TTF, OTF or TTC font file."); if (!encoding.startsWith("#")) PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists createEncoding(); } /** Gets the name from a composed TTC file name. * If I have for input "myfont.ttc,2" the return will * be "myfont.ttc". * @param name the full name * @return the simple file name */ protected static String getTTCName(String name) { int idx = name.toLowerCase().indexOf(".ttc,"); if (idx < 0) return name; else return name.substring(0, idx + 4); } /** * Reads the tables 'head', 'hhea', 'OS/2' and 'post' filling several variables. * @throws DocumentException the font is invalid * @throws IOException the font file could not be read */ void fillTables() throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("head"); if (table_location == null) throw new DocumentException("Table 'head' does not exist in " + fileName + style); rf.seek(table_location[0] + 16); head.flags = rf.readUnsignedShort(); head.unitsPerEm = rf.readUnsignedShort(); rf.skipBytes(16); head.xMin = rf.readShort(); head.yMin = rf.readShort(); head.xMax = rf.readShort(); head.yMax = rf.readShort(); head.macStyle = rf.readUnsignedShort(); table_location = (int[])tables.get("hhea"); if (table_location == null) throw new DocumentException("Table 'hhea' does not exist " + fileName + style); rf.seek(table_location[0] + 4); hhea.Ascender = rf.readShort(); hhea.Descender = rf.readShort(); hhea.LineGap = rf.readShort(); hhea.advanceWidthMax = rf.readUnsignedShort(); hhea.minLeftSideBearing = rf.readShort(); hhea.minRightSideBearing = rf.readShort(); hhea.xMaxExtent = rf.readShort(); hhea.caretSlopeRise = rf.readShort(); hhea.caretSlopeRun = rf.readShort(); rf.skipBytes(12); hhea.numberOfHMetrics = rf.readUnsignedShort(); table_location = (int[])tables.get("OS/2"); if (table_location == null) throw new DocumentException("Table 'OS/2' does not exist in " + fileName + style); rf.seek(table_location[0]); int version = rf.readUnsignedShort(); os_2.xAvgCharWidth = rf.readShort(); os_2.usWeightClass = rf.readUnsignedShort(); os_2.usWidthClass = rf.readUnsignedShort(); os_2.fsType = rf.readShort(); os_2.ySubscriptXSize = rf.readShort(); os_2.ySubscriptYSize = rf.readShort(); os_2.ySubscriptXOffset = rf.readShort(); os_2.ySubscriptYOffset = rf.readShort(); os_2.ySuperscriptXSize = rf.readShort(); os_2.ySuperscriptYSize = rf.readShort(); os_2.ySuperscriptXOffset = rf.readShort(); os_2.ySuperscriptYOffset = rf.readShort(); os_2.yStrikeoutSize = rf.readShort(); os_2.yStrikeoutPosition = rf.readShort(); os_2.sFamilyClass = rf.readShort(); rf.readFully(os_2.panose); rf.skipBytes(16); rf.readFully(os_2.achVendID); os_2.fsSelection = rf.readUnsignedShort(); os_2.usFirstCharIndex = rf.readUnsignedShort(); os_2.usLastCharIndex = rf.readUnsignedShort(); os_2.sTypoAscender = rf.readShort(); os_2.sTypoDescender = rf.readShort(); if (os_2.sTypoDescender > 0) os_2.sTypoDescender = (short)(-os_2.sTypoDescender); os_2.sTypoLineGap = rf.readShort(); os_2.usWinAscent = rf.readUnsignedShort(); os_2.usWinDescent = rf.readUnsignedShort(); os_2.ulCodePageRange1 = 0; os_2.ulCodePageRange2 = 0; if (version > 0) { os_2.ulCodePageRange1 = rf.readInt(); os_2.ulCodePageRange2 = rf.readInt(); } if (version > 1) { rf.skipBytes(2); os_2.sCapHeight = rf.readShort(); } else os_2.sCapHeight = (int)(0.7 * head.unitsPerEm); table_location = (int[])tables.get("post"); if (table_location == null) { italicAngle = -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI; return; } rf.seek(table_location[0] + 4); short mantissa = rf.readShort(); int fraction = rf.readUnsignedShort(); italicAngle = mantissa + fraction / 16384.0d; underlinePosition = rf.readShort(); underlineThickness = rf.readShort(); isFixedPitch = rf.readInt() != 0; } /** * Gets the Postscript font name. * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @return the Postscript font name */ String getBaseFont() throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("name"); if (table_location == null) throw new DocumentException("Table 'name' does not exist in " + fileName + style); rf.seek(table_location[0] + 2); int numRecords = rf.readUnsignedShort(); int startOfStorage = rf.readUnsignedShort(); for (int k = 0; k < numRecords; ++k) { int platformID = rf.readUnsignedShort(); int platformEncodingID = rf.readUnsignedShort(); int languageID = rf.readUnsignedShort(); int nameID = rf.readUnsignedShort(); int length = rf.readUnsignedShort(); int offset = rf.readUnsignedShort(); if (nameID == 6) { rf.seek(table_location[0] + startOfStorage + offset); if (platformID == 0 || platformID == 3) return readUnicodeString(length); else return readStandardString(length); } } File file = new File(fileName); return file.getName().replace(' ', '-'); } /** Extracts the names of the font in all the languages available. * @param id the name id to retrieve * @throws DocumentException on error * @throws IOException on error */ String[][] getNames(int id) throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("name"); if (table_location == null) throw new DocumentException("Table 'name' does not exist in " + fileName + style); rf.seek(table_location[0] + 2); int numRecords = rf.readUnsignedShort(); int startOfStorage = rf.readUnsignedShort(); ArrayList names = new ArrayList(); for (int k = 0; k < numRecords; ++k) { int platformID = rf.readUnsignedShort(); int platformEncodingID = rf.readUnsignedShort(); int languageID = rf.readUnsignedShort(); int nameID = rf.readUnsignedShort(); int length = rf.readUnsignedShort(); int offset = rf.readUnsignedShort(); if (nameID == id) { int pos = rf.getFilePointer(); rf.seek(table_location[0] + startOfStorage + offset); String name; if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){ name = readUnicodeString(length); } else { name = readStandardString(length); } names.add(new String[]{String.valueOf(platformID), String.valueOf(platformEncodingID), String.valueOf(languageID), name}); rf.seek(pos); } } String thisName[][] = new String[names.size()][]; for (int k = 0; k < names.size(); ++k) thisName[k] = (String[])names.get(k); return thisName; } /** Extracts all the names of the names-Table * @throws DocumentException on error * @throws IOException on error */ String[][] getAllNames() throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("name"); if (table_location == null) throw new DocumentException("Table 'name' does not exist in " + fileName + style); rf.seek(table_location[0] + 2); int numRecords = rf.readUnsignedShort(); int startOfStorage = rf.readUnsignedShort(); ArrayList names = new ArrayList(); for (int k = 0; k < numRecords; ++k) { int platformID = rf.readUnsignedShort(); int platformEncodingID = rf.readUnsignedShort(); int languageID = rf.readUnsignedShort(); int nameID = rf.readUnsignedShort(); int length = rf.readUnsignedShort(); int offset = rf.readUnsignedShort(); int pos = rf.getFilePointer(); rf.seek(table_location[0] + startOfStorage + offset); String name; if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){ name = readUnicodeString(length); } else { name = readStandardString(length); } names.add(new String[]{String.valueOf(nameID), String.valueOf(platformID), String.valueOf(platformEncodingID), String.valueOf(languageID), name}); rf.seek(pos); } String thisName[][] = new String[names.size()][]; for (int k = 0; k < names.size(); ++k) thisName[k] = (String[])names.get(k); return thisName; } void checkCff() { int table_location[]; table_location = (int[])tables.get("CFF "); if (table_location != null) { cff = true; cffOffset = table_location[0]; cffLength = table_location[1]; } } /** Reads the font data. * @param ttfAfm the font as a byte array, possibly null * @throws DocumentException the font is invalid * @throws IOException the font file could not be read * @since 2.1.5 */ void process(byte ttfAfm[], boolean preload) throws DocumentException, IOException { tables = new HashMap(); try { if (ttfAfm == null) rf = new RandomAccessFileOrArray(fileName, preload, Document.plainRandomAccess); else rf = new RandomAccessFileOrArray(ttfAfm); if (ttcIndex.length() > 0) { int dirIdx = Integer.parseInt(ttcIndex); if (dirIdx < 0) throw new DocumentException("The font index for " + fileName + " must be positive."); String mainTag = readStandardString(4); if (!mainTag.equals("ttcf")) throw new DocumentException(fileName + " is not a valid TTC file."); rf.skipBytes(4); int dirCount = rf.readInt(); if (dirIdx >= dirCount) throw new DocumentException("The font index for " + fileName + " must be between 0 and " + (dirCount - 1) + ". It was " + dirIdx + "."); rf.skipBytes(dirIdx * 4); directoryOffset = rf.readInt(); } rf.seek(directoryOffset); int ttId = rf.readInt(); if (ttId != 0x00010000 && ttId != 0x4F54544F) throw new DocumentException(fileName + " is not a valid TTF or OTF file."); int num_tables = rf.readUnsignedShort(); rf.skipBytes(6); for (int k = 0; k < num_tables; ++k) { String tag = readStandardString(4); rf.skipBytes(4); int table_location[] = new int[2]; table_location[0] = rf.readInt(); table_location[1] = rf.readInt(); tables.put(tag, table_location); } checkCff(); fontName = getBaseFont(); fullName = getNames(4); //full name familyName = getNames(1); //family name allNameEntries = getAllNames(); if (!justNames) { fillTables(); readGlyphWidths(); readCMaps(); readKerning(); readBbox(); GlyphWidths = null; } } finally { if (rf != null) { rf.close(); if (!embedded) rf = null; } } } /** Reads a String from the font file as bytes using the Cp1252 * encoding. * @param length the length of bytes to read * @return the String read * @throws IOException the font file could not be read */ protected String readStandardString(int length) throws IOException { byte buf[] = new byte[length]; rf.readFully(buf); try { return new String(buf, WINANSI); } catch (Exception e) { throw new ExceptionConverter(e); } } /** Reads a Unicode String from the font file. Each character is * represented by two bytes. * @param length the length of bytes to read. The String will have length/2 * characters * @return the String read * @throws IOException the font file could not be read */ protected String readUnicodeString(int length) throws IOException { StringBuffer buf = new StringBuffer(); length /= 2; for (int k = 0; k < length; ++k) { buf.append(rf.readChar()); } return buf.toString(); } /** Reads the glyphs widths. The widths are extracted from the table 'hmtx'. * The glyphs are normalized to 1000 units. * @throws DocumentException the font is invalid * @throws IOException the font file could not be read */ protected void readGlyphWidths() throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("hmtx"); if (table_location == null) throw new DocumentException("Table 'hmtx' does not exist in " + fileName + style); rf.seek(table_location[0]); GlyphWidths = new int[hhea.numberOfHMetrics]; for (int k = 0; k < hhea.numberOfHMetrics; ++k) { GlyphWidths[k] = (rf.readUnsignedShort() * 1000) / head.unitsPerEm; rf.readUnsignedShort(); } } /** Gets a glyph width. * @param glyph the glyph to get the width of * @return the width of the glyph in normalized 1000 units */ protected int getGlyphWidth(int glyph) { if (glyph >= GlyphWidths.length) glyph = GlyphWidths.length - 1; return GlyphWidths[glyph]; } private void readBbox() throws DocumentException, IOException { int tableLocation[]; tableLocation = (int[])tables.get("head"); if (tableLocation == null) throw new DocumentException("Table 'head' does not exist in " + fileName + style); rf.seek(tableLocation[0] + TrueTypeFontSubSet.HEAD_LOCA_FORMAT_OFFSET); boolean locaShortTable = (rf.readUnsignedShort() == 0); tableLocation = (int[])tables.get("loca"); if (tableLocation == null) return; rf.seek(tableLocation[0]); int locaTable[]; if (locaShortTable) { int entries = tableLocation[1] / 2; locaTable = new int[entries]; for (int k = 0; k < entries; ++k) locaTable[k] = rf.readUnsignedShort() * 2; } else { int entries = tableLocation[1] / 4; locaTable = new int[entries]; for (int k = 0; k < entries; ++k) locaTable[k] = rf.readInt(); } tableLocation = (int[])tables.get("glyf"); if (tableLocation == null) throw new DocumentException("Table 'glyf' does not exist in " + fileName + style); int tableGlyphOffset = tableLocation[0]; bboxes = new int[locaTable.length - 1][]; for (int glyph = 0; glyph < locaTable.length - 1; ++glyph) { int start = locaTable[glyph]; if (start != locaTable[glyph + 1]) { rf.seek(tableGlyphOffset + start + 2); bboxes[glyph] = new int[]{ (rf.readShort() * 1000) / head.unitsPerEm, (rf.readShort() * 1000) / head.unitsPerEm, (rf.readShort() * 1000) / head.unitsPerEm, (rf.readShort() * 1000) / head.unitsPerEm}; } } } /** Reads the several maps from the table 'cmap'. The maps of interest are 1.0 for symbolic * fonts and 3.1 for all others. A symbolic font is defined as having the map 3.0. * @throws DocumentException the font is invalid * @throws IOException the font file could not be read */ void readCMaps() throws DocumentException, IOException { int table_location[]; table_location = (int[])tables.get("cmap"); if (table_location == null) throw new DocumentException("Table 'cmap' does not exist in " + fileName + style); rf.seek(table_location[0]); rf.skipBytes(2); int num_tables = rf.readUnsignedShort(); fontSpecific = false; int map10 = 0; int map31 = 0; int map30 = 0; int mapExt = 0; for (int k = 0; k < num_tables; ++k) { int platId = rf.readUnsignedShort(); int platSpecId = rf.readUnsignedShort(); int offset = rf.readInt(); if (platId == 3 && platSpecId == 0) { fontSpecific = true; map30 = offset; } else if (platId == 3 && platSpecId == 1) { map31 = offset; } else if (platId == 3 && platSpecId == 10) { mapExt = offset; } if (platId == 1 && platSpecId == 0) { map10 = offset; } } if (map10 > 0) { rf.seek(table_location[0] + map10); int format = rf.readUnsignedShort(); switch (format) { case 0: cmap10 = readFormat0(); break; case 4: cmap10 = readFormat4(); break; case 6: cmap10 = readFormat6(); break; } } if (map31 > 0) { rf.seek(table_location[0] + map31); int format = rf.readUnsignedShort(); if (format == 4) { cmap31 = readFormat4(); } } if (map30 > 0) { rf.seek(table_location[0] + map30); int format = rf.readUnsignedShort(); if (format == 4) { cmap10 = readFormat4(); } } if (mapExt > 0) { rf.seek(table_location[0] + mapExt); int format = rf.readUnsignedShort(); switch (format) { case 0: cmapExt = readFormat0(); break; case 4: cmapExt = readFormat4(); break; case 6: cmapExt = readFormat6(); break; case 12: cmapExt = readFormat12(); break; } } } HashMap readFormat12() throws IOException { HashMap h = new HashMap(); rf.skipBytes(2); int table_lenght = rf.readInt(); rf.skipBytes(4); int nGroups = rf.readInt(); for (int k = 0; k < nGroups; k++) { int startCharCode = rf.readInt(); int endCharCode = rf.readInt(); int startGlyphID = rf.readInt(); for (int i = startCharCode; i <= endCharCode; i++) { int[] r = new int[2]; r[0] = startGlyphID; r[1] = getGlyphWidth(r[0]); h.put(new Integer(i), r); startGlyphID++; } } return h; } /** The information in the maps of the table 'cmap' is coded in several formats. * Format 0 is the Apple standard character to glyph index mapping table. * @return a HashMap representing this map * @throws IOException the font file could not be read */ HashMap readFormat0() throws IOException { HashMap h = new HashMap(); rf.skipBytes(4); for (int k = 0; k < 256; ++k) { int r[] = new int[2]; r[0] = rf.readUnsignedByte(); r[1] = getGlyphWidth(r[0]); h.put(new Integer(k), r); } return h; } /** The information in the maps of the table 'cmap' is coded in several formats. * Format 4 is the Microsoft standard character to glyph index mapping table. * @return a HashMap representing this map * @throws IOException the font file could not be read */ HashMap readFormat4() throws IOException { HashMap h = new HashMap(); int table_lenght = rf.readUnsignedShort(); rf.skipBytes(2); int segCount = rf.readUnsignedShort() / 2; rf.skipBytes(6); int endCount[] = new int[segCount]; for (int k = 0; k < segCount; ++k) { endCount[k] = rf.readUnsignedShort(); } rf.skipBytes(2); int startCount[] = new int[segCount]; for (int k = 0; k < segCount; ++k) { startCount[k] = rf.readUnsignedShort(); } int idDelta[] = new int[segCount]; for (int k = 0; k < segCount; ++k) { idDelta[k] = rf.readUnsignedShort(); } int idRO[] = new int[segCount]; for (int k = 0; k < segCount; ++k) { idRO[k] = rf.readUnsignedShort(); } int glyphId[] = new int[table_lenght / 2 - 8 - segCount * 4]; for (int k = 0; k < glyphId.length; ++k) { glyphId[k] = rf.readUnsignedShort(); } for (int k = 0; k < segCount; ++k) { int glyph; for (int j = startCount[k]; j <= endCount[k] && j != 0xFFFF; ++j) { if (idRO[k] == 0) { glyph = (j + idDelta[k]) & 0xFFFF; } else { int idx = k + idRO[k] / 2 - segCount + j - startCount[k]; if (idx >= glyphId.length) continue; glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF; } int r[] = new int[2]; r[0] = glyph; r[1] = getGlyphWidth(r[0]); h.put(new Integer(fontSpecific ? ((j & 0xff00) == 0xf000 ? j & 0xff : j) : j), r); } } return h; } /** The information in the maps of the table 'cmap' is coded in several formats. * Format 6 is a trimmed table mapping. It is similar to format 0 but can have * less than 256 entries. * @return a HashMap representing this map * @throws IOException the font file could not be read */ HashMap readFormat6() throws IOException { HashMap h = new HashMap(); rf.skipBytes(4); int start_code = rf.readUnsignedShort(); int code_count = rf.readUnsignedShort(); for (int k = 0; k < code_count; ++k) { int r[] = new int[2]; r[0] = rf.readUnsignedShort(); r[1] = getGlyphWidth(r[0]); h.put(new Integer(k + start_code), r); } return h; } /** Reads the kerning information from the 'kern' table. * @throws IOException the font file could not be read */ void readKerning() throws IOException { int table_location[]; table_location = (int[])tables.get("kern"); if (table_location == null) return; rf.seek(table_location[0] + 2); int nTables = rf.readUnsignedShort(); int checkpoint = table_location[0] + 4; int length = 0; for (int k = 0; k < nTables; ++k) { checkpoint += length; rf.seek(checkpoint); rf.skipBytes(2); length = rf.readUnsignedShort(); int coverage = rf.readUnsignedShort(); if ((coverage & 0xfff7) == 0x0001) { int nPairs = rf.readUnsignedShort(); rf.skipBytes(6); for (int j = 0; j < nPairs; ++j) { int pair = rf.readInt(); int value = rf.readShort() * 1000 / head.unitsPerEm; kerning.put(pair, value); } } } } /** Gets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @return the kerning to be applied */ public int getKerning(int char1, int char2) { int metrics[] = getMetricsTT(char1); if (metrics == null) return 0; int c1 = metrics[0]; metrics = getMetricsTT(char2); if (metrics == null) return 0; int c2 = metrics[0]; return kerning.get((c1 << 16) + c2); } /** Gets the width from the font according to the unicode char c. * If the name is null it's a symbolic font. * @param c the unicode char * @param name the glyph name * @return the width of the char */ int getRawWidth(int c, String name) { int[] metric = getMetricsTT(c); if (metric == null) return 0; return metric[1]; } /** Generates the font descriptor for this font. * @return the PdfDictionary containing the font descriptor or null * @param subsetPrefix the subset prefix * @param fontStream the indirect reference to a PdfStream containing the font or null */ protected PdfDictionary getFontDescriptor(PdfIndirectReference fontStream, String subsetPrefix, PdfIndirectReference cidset) { PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR); dic.put(PdfName.ASCENT, new PdfNumber(os_2.sTypoAscender * 1000 / head.unitsPerEm)); dic.put(PdfName.CAPHEIGHT, new PdfNumber(os_2.sCapHeight * 1000 / head.unitsPerEm)); dic.put(PdfName.DESCENT, new PdfNumber(os_2.sTypoDescender * 1000 / head.unitsPerEm)); dic.put(PdfName.FONTBBOX, new PdfRectangle( head.xMin * 1000 / head.unitsPerEm, head.yMin * 1000 / head.unitsPerEm, head.xMax * 1000 / head.unitsPerEm, head.yMax * 1000 / head.unitsPerEm)); if (cidset != null) dic.put(PdfName.CIDSET, cidset); if (cff) { if (encoding.startsWith("Identity-")) dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName+"-"+encoding)); else dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style)); } else dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style)); dic.put(PdfName.ITALICANGLE, new PdfNumber(italicAngle)); dic.put(PdfName.STEMV, new PdfNumber(80)); if (fontStream != null) { if (cff) dic.put(PdfName.FONTFILE3, fontStream); else dic.put(PdfName.FONTFILE2, fontStream); } int flags = 0; if (isFixedPitch) flags |= 1; flags |= fontSpecific ? 4 : 32; if ((head.macStyle & 2) != 0) flags |= 64; if ((head.macStyle & 1) != 0) flags |= 262144; dic.put(PdfName.FLAGS, new PdfNumber(flags)); return dic; } /** Generates the font dictionary for this font. * @return the PdfDictionary containing the font dictionary * @param subsetPrefix the subset prefix * @param firstChar the first valid character * @param lastChar the last valid character * @param shortTag a 256 bytes long byte array where each unused byte is represented by 0 * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or null */ protected PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, String subsetPrefix, int firstChar, int lastChar, byte shortTag[]) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); if (cff) { dic.put(PdfName.SUBTYPE, PdfName.TYPE1); dic.put(PdfName.BASEFONT, new PdfName(fontName + style)); } else { dic.put(PdfName.SUBTYPE, PdfName.TRUETYPE); dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style)); } dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style)); if (!fontSpecific) { for (int k = firstChar; k <= lastChar; ++k) { if (!differences[k].equals(notdef)) { firstChar = k; break; } } if (encoding.equals("Cp1252") || encoding.equals("MacRoman")) dic.put(PdfName.ENCODING, encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING); else { PdfDictionary enc = new PdfDictionary(PdfName.ENCODING); PdfArray dif = new PdfArray(); boolean gap = true; for (int k = firstChar; k <= lastChar; ++k) { if (shortTag[k] != 0) { if (gap) { dif.add(new PdfNumber(k)); gap = false; } dif.add(new PdfName(differences[k])); } else gap = true; } enc.put(PdfName.DIFFERENCES, dif); dic.put(PdfName.ENCODING, enc); } } dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar)); dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar)); PdfArray wd = new PdfArray(); for (int k = firstChar; k <= lastChar; ++k) { if (shortTag[k] == 0) wd.add(new PdfNumber(0)); else wd.add(new PdfNumber(widths[k])); } dic.put(PdfName.WIDTHS, wd); if (fontDescriptor != null) dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); return dic; } protected byte[] getFullFont() throws IOException { RandomAccessFileOrArray rf2 = null; try { rf2 = new RandomAccessFileOrArray(rf); rf2.reOpen(); byte b[] = new byte[rf2.length()]; rf2.readFully(b); return b; } finally { try {if (rf2 != null) {rf2.close();}} catch (Exception e) {} } } protected static int[] compactRanges(ArrayList ranges) { ArrayList simp = new ArrayList(); for (int k = 0; k < ranges.size(); ++k) { int[] r = (int[])ranges.get(k); for (int j = 0; j < r.length; j += 2) { simp.add(new int[]{Math.max(0, Math.min(r[j], r[j + 1])), Math.min(0xffff, Math.max(r[j], r[j + 1]))}); } } for (int k1 = 0; k1 < simp.size() - 1; ++k1) { for (int k2 = k1 + 1; k2 < simp.size(); ++k2) { int[] r1 = (int[])simp.get(k1); int[] r2 = (int[])simp.get(k2); if ((r1[0] >= r2[0] && r1[0] <= r2[1]) || (r1[1] >= r2[0] && r1[0] <= r2[1])) { r1[0] = Math.min(r1[0], r2[0]); r1[1] = Math.max(r1[1], r2[1]); simp.remove(k2); --k2; } } } int[] s = new int[simp.size() * 2]; for (int k = 0; k < simp.size(); ++k) { int[] r = (int[])simp.get(k); s[k * 2] = r[0]; s[k * 2 + 1] = r[1]; } return s; } protected void addRangeUni(HashMap longTag, boolean includeMetrics, boolean subsetp) { if (!subsetp && (subsetRanges != null || directoryOffset > 0)) { int[] rg = (subsetRanges == null && directoryOffset > 0) ? new int[]{0, 0xffff} : compactRanges(subsetRanges); HashMap usemap; if (!fontSpecific && cmap31 != null) usemap = cmap31; else if (fontSpecific && cmap10 != null) usemap = cmap10; else if (cmap31 != null) usemap = cmap31; else usemap = cmap10; for (Iterator it = usemap.entrySet().iterator(); it.hasNext();) { Map.Entry e = (Map.Entry)it.next(); int[] v = (int[])e.getValue(); Integer gi = new Integer(v[0]); if (longTag.containsKey(gi)) continue; int c = ((Integer)e.getKey()).intValue(); boolean skip = true; for (int k = 0; k < rg.length; k += 2) { if (c >= rg[k] && c <= rg[k + 1]) { skip = false; break; } } if (!skip) longTag.put(gi, includeMetrics ? new int[]{v[0], v[1], c} : null); } } } /** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param params several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException { int firstChar = ((Integer)params[0]).intValue(); int lastChar = ((Integer)params[1]).intValue(); byte shortTag[] = (byte[])params[2]; boolean subsetp = ((Boolean)params[3]).booleanValue() && subset; if (!subsetp) { firstChar = 0; lastChar = shortTag.length - 1; for (int k = 0; k < shortTag.length; ++k) shortTag[k] = 1; } PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; String subsetPrefix = ""; if (embedded) { if (cff) { pobj = new StreamFont(readCffFont(), "Type1C", compressionLevel); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } else { if (subsetp) subsetPrefix = createSubsetPrefix(); HashMap glyphs = new HashMap(); for (int k = firstChar; k <= lastChar; ++k) { if (shortTag[k] != 0) { int[] metrics = null; if (specialMap != null) { int[] cd = GlyphList.nameToUnicode(differences[k]); if (cd != null) metrics = getMetricsTT(cd[0]); } else { if (fontSpecific) metrics = getMetricsTT(k); else metrics = getMetricsTT(unicodeDifferences[k]); } if (metrics != null) glyphs.put(new Integer(metrics[0]), null); } } addRangeUni(glyphs, false, subsetp); byte[] b = null; if (subsetp || directoryOffset != 0 || subsetRanges != null) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), glyphs, directoryOffset, true, !subsetp); b = sb.process(); } else { b = getFullFont(); } int lengths[] = new int[]{b.length}; pobj = new StreamFont(b, lengths, compressionLevel); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } } pobj = getFontDescriptor(ind_font, subsetPrefix, null); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font, subsetPrefix, firstChar, lastChar, shortTag); writer.addToBody(pobj, ref); } /** * If this font file is using the Compact Font File Format, then this method * will return the raw bytes needed for the font stream. If this method is * ever made public: make sure to add a test if (cff == true). * @return a byte array * @since 2.1.3 */ protected byte[] readCffFont() throws IOException { RandomAccessFileOrArray rf2 = new RandomAccessFileOrArray(rf); byte b[] = new byte[cffLength]; try { rf2.reOpen(); rf2.seek(cffOffset); rf2.readFully(b); } finally { try { rf2.close(); } catch (Exception e) { // empty on purpose } } return b; } /** * Returns a PdfStream object with the full font program. * @return a PdfStream with the font program * @since 2.1.3 */ public PdfStream getFullFontStream() throws IOException, DocumentException { if (cff) { return new StreamFont(readCffFont(), "Type1C", compressionLevel); } else { byte[] b = getFullFont(); int lengths[] = new int[]{b.length}; return new StreamFont(b, lengths, compressionLevel); } } /** Gets the font parameter identified by key. Valid values * for key are ASCENT, CAPHEIGHT, DESCENT * and ITALICANGLE. * @param key the parameter to be extracted * @param fontSize the font size in points * @return the parameter in points */ public float getFontDescriptor(int key, float fontSize) { switch (key) { case ASCENT: return os_2.sTypoAscender * fontSize / head.unitsPerEm; case CAPHEIGHT: return os_2.sCapHeight * fontSize / head.unitsPerEm; case DESCENT: return os_2.sTypoDescender * fontSize / head.unitsPerEm; case ITALICANGLE: return (float)italicAngle; case BBOXLLX: return fontSize * head.xMin / head.unitsPerEm; case BBOXLLY: return fontSize * head.yMin / head.unitsPerEm; case BBOXURX: return fontSize * head.xMax / head.unitsPerEm; case BBOXURY: return fontSize * head.yMax / head.unitsPerEm; case AWT_ASCENT: return fontSize * hhea.Ascender / head.unitsPerEm; case AWT_DESCENT: return fontSize * hhea.Descender / head.unitsPerEm; case AWT_LEADING: return fontSize * hhea.LineGap / head.unitsPerEm; case AWT_MAXADVANCE: return fontSize * hhea.advanceWidthMax / head.unitsPerEm; case UNDERLINE_POSITION: return (underlinePosition - underlineThickness / 2) * fontSize / head.unitsPerEm; case UNDERLINE_THICKNESS: return underlineThickness * fontSize / head.unitsPerEm; case STRIKETHROUGH_POSITION: return os_2.yStrikeoutPosition * fontSize / head.unitsPerEm; case STRIKETHROUGH_THICKNESS: return os_2.yStrikeoutSize * fontSize / head.unitsPerEm; case SUBSCRIPT_SIZE: return os_2.ySubscriptYSize * fontSize / head.unitsPerEm; case SUBSCRIPT_OFFSET: return -os_2.ySubscriptYOffset * fontSize / head.unitsPerEm; case SUPERSCRIPT_SIZE: return os_2.ySuperscriptYSize * fontSize / head.unitsPerEm; case SUPERSCRIPT_OFFSET: return os_2.ySuperscriptYOffset * fontSize / head.unitsPerEm; } return 0; } /** Gets the glyph index and metrics for a character. * @param c the character * @return an int array with {glyph index, width} */ public int[] getMetricsTT(int c) { if (cmapExt != null) return (int[])cmapExt.get(new Integer(c)); if (!fontSpecific && cmap31 != null) return (int[])cmap31.get(new Integer(c)); if (fontSpecific && cmap10 != null) return (int[])cmap10.get(new Integer(c)); if (cmap31 != null) return (int[])cmap31.get(new Integer(c)); if (cmap10 != null) return (int[])cmap10.get(new Integer(c)); return null; } /** Gets the postscript font name. * @return the postscript font name */ public String getPostscriptFontName() { return fontName; } /** Gets the code pages supported by the font. * @return the code pages supported by the font */ public String[] getCodePagesSupported() { long cp = (((long)os_2.ulCodePageRange2) << 32) + (os_2.ulCodePageRange1 & 0xffffffffL); int count = 0; long bit = 1; for (int k = 0; k < 64; ++k) { if ((cp & bit) != 0 && codePages[k] != null) ++count; bit <<= 1; } String ret[] = new String[count]; count = 0; bit = 1; for (int k = 0; k < 64; ++k) { if ((cp & bit) != 0 && codePages[k] != null) ret[count++] = codePages[k]; bit <<= 1; } return ret; } /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font */ public String[][] getFullFontName() { return fullName; } /** Gets all the entries of the Names-Table. If it is a True Type font * each array element will have {Name ID, Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font */ public String[][] getAllNameEntries() { return allNameEntries; } /** Gets the family name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"", "", "", * font name}. * @return the family name of the font */ public String[][] getFamilyFontName() { return familyName; } /** Checks if the font has any kerning pairs. * @return true if the font has any kerning pairs */ public boolean hasKernPairs() { return kerning.size() > 0; } /** * Sets the font name that will appear in the pdf font dictionary. * Use with care as it can easily make a font unreadable if not embedded. * @param name the new font name */ public void setPostscriptFontName(String name) { fontName = name; } /** * Sets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @param kern the kerning to apply in normalized 1000 units * @return true if the kerning was applied, false otherwise */ public boolean setKerning(int char1, int char2, int kern) { int metrics[] = getMetricsTT(char1); if (metrics == null) return false; int c1 = metrics[0]; metrics = getMetricsTT(char2); if (metrics == null) return false; int c2 = metrics[0]; kerning.put((c1 << 16) + c2, kern); return true; } protected int[] getRawCharBBox(int c, String name) { HashMap map = null; if (name == null || cmap31 == null) map = cmap10; else map = cmap31; if (map == null) return null; int metric[] = (int[])map.get(new Integer(c)); if (metric == null || bboxes == null) return null; return bboxes[metric[0]]; } }src/core/com/lowagie/text/pdf/TrueTypeFontSubSet.java100644 0 0 40125 11036112746 20312 0ustar 0 0 /* * $Id: TrueTypeFontSubSet.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; /** Subsets a True Type font by removing the unneeded glyphs from * the font. * * @author Paulo Soares (psoares@consiste.pt) */ class TrueTypeFontSubSet { static final String tableNamesSimple[] = {"cvt ", "fpgm", "glyf", "head", "hhea", "hmtx", "loca", "maxp", "prep"}; static final String tableNamesCmap[] = {"cmap", "cvt ", "fpgm", "glyf", "head", "hhea", "hmtx", "loca", "maxp", "prep"}; static final String tableNamesExtra[] = {"OS/2", "cmap", "cvt ", "fpgm", "glyf", "head", "hhea", "hmtx", "loca", "maxp", "name, prep"}; static final int entrySelectors[] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4}; static final int TABLE_CHECKSUM = 0; static final int TABLE_OFFSET = 1; static final int TABLE_LENGTH = 2; static final int HEAD_LOCA_FORMAT_OFFSET = 51; static final int ARG_1_AND_2_ARE_WORDS = 1; static final int WE_HAVE_A_SCALE = 8; static final int MORE_COMPONENTS = 32; static final int WE_HAVE_AN_X_AND_Y_SCALE = 64; static final int WE_HAVE_A_TWO_BY_TWO = 128; /** Contains the location of the several tables. The key is the name of * the table and the value is an int[3] where position 0 * is the checksum, position 1 is the offset from the start of the file * and position 2 is the length of the table. */ protected HashMap tableDirectory; /** The file in use. */ protected RandomAccessFileOrArray rf; /** The file name. */ protected String fileName; protected boolean includeCmap; protected boolean includeExtras; protected boolean locaShortTable; protected int locaTable[]; protected HashMap glyphsUsed; protected ArrayList glyphsInList; protected int tableGlyphOffset; protected int newLocaTable[]; protected byte newLocaTableOut[]; protected byte newGlyfTable[]; protected int glyfTableRealSize; protected int locaTableRealSize; protected byte outFont[]; protected int fontPtr; protected int directoryOffset; /** Creates a new TrueTypeFontSubSet * @param directoryOffset The offset from the start of the file to the table directory * @param fileName the file name of the font * @param glyphsUsed the glyphs used * @param includeCmap true if the table cmap is to be included in the generated font */ TrueTypeFontSubSet(String fileName, RandomAccessFileOrArray rf, HashMap glyphsUsed, int directoryOffset, boolean includeCmap, boolean includeExtras) { this.fileName = fileName; this.rf = rf; this.glyphsUsed = glyphsUsed; this.includeCmap = includeCmap; this.includeExtras = includeExtras; this.directoryOffset = directoryOffset; glyphsInList = new ArrayList(glyphsUsed.keySet()); } /** Does the actual work of subsetting the font. * @throws IOException on error * @throws DocumentException on error * @return the subset font */ byte[] process() throws IOException, DocumentException { try { rf.reOpen(); createTableDirectory(); readLoca(); flatGlyphs(); createNewGlyphTables(); locaTobytes(); assembleFont(); return outFont; } finally { try { rf.close(); } catch (Exception e) { // empty on purpose } } } protected void assembleFont() throws IOException { int tableLocation[]; int fullFontSize = 0; String tableNames[]; if (includeExtras) tableNames = tableNamesExtra; else { if (includeCmap) tableNames = tableNamesCmap; else tableNames = tableNamesSimple; } int tablesUsed = 2; int len = 0; for (int k = 0; k < tableNames.length; ++k) { String name = tableNames[k]; if (name.equals("glyf") || name.equals("loca")) continue; tableLocation = (int[])tableDirectory.get(name); if (tableLocation == null) continue; ++tablesUsed; fullFontSize += (tableLocation[TABLE_LENGTH] + 3) & (~3); } fullFontSize += newLocaTableOut.length; fullFontSize += newGlyfTable.length; int ref = 16 * tablesUsed + 12; fullFontSize += ref; outFont = new byte[fullFontSize]; fontPtr = 0; writeFontInt(0x00010000); writeFontShort(tablesUsed); int selector = entrySelectors[tablesUsed]; writeFontShort((1 << selector) * 16); writeFontShort(selector); writeFontShort((tablesUsed - (1 << selector)) * 16); for (int k = 0; k < tableNames.length; ++k) { String name = tableNames[k]; tableLocation = (int[])tableDirectory.get(name); if (tableLocation == null) continue; writeFontString(name); if (name.equals("glyf")) { writeFontInt(calculateChecksum(newGlyfTable)); len = glyfTableRealSize; } else if (name.equals("loca")) { writeFontInt(calculateChecksum(newLocaTableOut)); len = locaTableRealSize; } else { writeFontInt(tableLocation[TABLE_CHECKSUM]); len = tableLocation[TABLE_LENGTH]; } writeFontInt(ref); writeFontInt(len); ref += (len + 3) & (~3); } for (int k = 0; k < tableNames.length; ++k) { String name = tableNames[k]; tableLocation = (int[])tableDirectory.get(name); if (tableLocation == null) continue; if (name.equals("glyf")) { System.arraycopy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.length); fontPtr += newGlyfTable.length; newGlyfTable = null; } else if (name.equals("loca")) { System.arraycopy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.length); fontPtr += newLocaTableOut.length; newLocaTableOut = null; } else { rf.seek(tableLocation[TABLE_OFFSET]); rf.readFully(outFont, fontPtr, tableLocation[TABLE_LENGTH]); fontPtr += (tableLocation[TABLE_LENGTH] + 3) & (~3); } } } protected void createTableDirectory() throws IOException, DocumentException { tableDirectory = new HashMap(); rf.seek(directoryOffset); int id = rf.readInt(); if (id != 0x00010000) throw new DocumentException(fileName + " is not a true type file."); int num_tables = rf.readUnsignedShort(); rf.skipBytes(6); for (int k = 0; k < num_tables; ++k) { String tag = readStandardString(4); int tableLocation[] = new int[3]; tableLocation[TABLE_CHECKSUM] = rf.readInt(); tableLocation[TABLE_OFFSET] = rf.readInt(); tableLocation[TABLE_LENGTH] = rf.readInt(); tableDirectory.put(tag, tableLocation); } } protected void readLoca() throws IOException, DocumentException { int tableLocation[]; tableLocation = (int[])tableDirectory.get("head"); if (tableLocation == null) throw new DocumentException("Table 'head' does not exist in " + fileName); rf.seek(tableLocation[TABLE_OFFSET] + HEAD_LOCA_FORMAT_OFFSET); locaShortTable = (rf.readUnsignedShort() == 0); tableLocation = (int[])tableDirectory.get("loca"); if (tableLocation == null) throw new DocumentException("Table 'loca' does not exist in " + fileName); rf.seek(tableLocation[TABLE_OFFSET]); if (locaShortTable) { int entries = tableLocation[TABLE_LENGTH] / 2; locaTable = new int[entries]; for (int k = 0; k < entries; ++k) locaTable[k] = rf.readUnsignedShort() * 2; } else { int entries = tableLocation[TABLE_LENGTH] / 4; locaTable = new int[entries]; for (int k = 0; k < entries; ++k) locaTable[k] = rf.readInt(); } } protected void createNewGlyphTables() throws IOException { newLocaTable = new int[locaTable.length]; int activeGlyphs[] = new int[glyphsInList.size()]; for (int k = 0; k < activeGlyphs.length; ++k) activeGlyphs[k] = ((Integer)glyphsInList.get(k)).intValue(); Arrays.sort(activeGlyphs); int glyfSize = 0; for (int k = 0; k < activeGlyphs.length; ++k) { int glyph = activeGlyphs[k]; glyfSize += locaTable[glyph + 1] - locaTable[glyph]; } glyfTableRealSize = glyfSize; glyfSize = (glyfSize + 3) & (~3); newGlyfTable = new byte[glyfSize]; int glyfPtr = 0; int listGlyf = 0; for (int k = 0; k < newLocaTable.length; ++k) { newLocaTable[k] = glyfPtr; if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) { ++listGlyf; newLocaTable[k] = glyfPtr; int start = locaTable[k]; int len = locaTable[k + 1] - start; if (len > 0) { rf.seek(tableGlyphOffset + start); rf.readFully(newGlyfTable, glyfPtr, len); glyfPtr += len; } } } } protected void locaTobytes() { if (locaShortTable) locaTableRealSize = newLocaTable.length * 2; else locaTableRealSize = newLocaTable.length * 4; newLocaTableOut = new byte[(locaTableRealSize + 3) & (~3)]; outFont = newLocaTableOut; fontPtr = 0; for (int k = 0; k < newLocaTable.length; ++k) { if (locaShortTable) writeFontShort(newLocaTable[k] / 2); else writeFontInt(newLocaTable[k]); } } protected void flatGlyphs() throws IOException, DocumentException { int tableLocation[]; tableLocation = (int[])tableDirectory.get("glyf"); if (tableLocation == null) throw new DocumentException("Table 'glyf' does not exist in " + fileName); Integer glyph0 = new Integer(0); if (!glyphsUsed.containsKey(glyph0)) { glyphsUsed.put(glyph0, null); glyphsInList.add(glyph0); } tableGlyphOffset = tableLocation[TABLE_OFFSET]; for (int k = 0; k < glyphsInList.size(); ++k) { int glyph = ((Integer)glyphsInList.get(k)).intValue(); checkGlyphComposite(glyph); } } protected void checkGlyphComposite(int glyph) throws IOException { int start = locaTable[glyph]; if (start == locaTable[glyph + 1]) // no contour return; rf.seek(tableGlyphOffset + start); int numContours = rf.readShort(); if (numContours >= 0) return; rf.skipBytes(8); for(;;) { int flags = rf.readUnsignedShort(); Integer cGlyph = new Integer(rf.readUnsignedShort()); if (!glyphsUsed.containsKey(cGlyph)) { glyphsUsed.put(cGlyph, null); glyphsInList.add(cGlyph); } if ((flags & MORE_COMPONENTS) == 0) return; int skip; if ((flags & ARG_1_AND_2_ARE_WORDS) != 0) skip = 4; else skip = 2; if ((flags & WE_HAVE_A_SCALE) != 0) skip += 2; else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0) skip += 4; if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0) skip += 8; rf.skipBytes(skip); } } /** Reads a String from the font file as bytes using the Cp1252 * encoding. * @param length the length of bytes to read * @return the String read * @throws IOException the font file could not be read */ protected String readStandardString(int length) throws IOException { byte buf[] = new byte[length]; rf.readFully(buf); try { return new String(buf, BaseFont.WINANSI); } catch (Exception e) { throw new ExceptionConverter(e); } } protected void writeFontShort(int n) { outFont[fontPtr++] = (byte)(n >> 8); outFont[fontPtr++] = (byte)(n); } protected void writeFontInt(int n) { outFont[fontPtr++] = (byte)(n >> 24); outFont[fontPtr++] = (byte)(n >> 16); outFont[fontPtr++] = (byte)(n >> 8); outFont[fontPtr++] = (byte)(n); } protected void writeFontString(String s) { byte b[] = PdfEncodings.convertToBytes(s, BaseFont.WINANSI); System.arraycopy(b, 0, outFont, fontPtr, b.length); fontPtr += b.length; } protected int calculateChecksum(byte b[]) { int len = b.length / 4; int v0 = 0; int v1 = 0; int v2 = 0; int v3 = 0; int ptr = 0; for (int k = 0; k < len; ++k) { v3 += b[ptr++] & 0xff; v2 += b[ptr++] & 0xff; v1 += b[ptr++] & 0xff; v0 += b[ptr++] & 0xff; } return v0 + (v1 << 8) + (v2 << 16) + (v3 << 24); } } src/core/com/lowagie/text/pdf/TrueTypeFontUnicode.java100644 0 0 44630 11213370070 20471 0ustar 0 0 /* * $Id: TrueTypeFontUnicode.java 3869 2009-04-17 18:03:45Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.IOException; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import com.lowagie.text.DocumentException; import com.lowagie.text.Utilities; /** Represents a True Type font with Unicode encoding. All the character * in the font can be used directly by using the encoding Identity-H or * Identity-V. This is the only way to represent some character sets such * as Thai. * @author Paulo Soares (psoares@consiste.pt) */ class TrueTypeFontUnicode extends TrueTypeFont implements Comparator{ /** * true if the encoding is vertical. */ boolean vertical = false; /** * Creates a new TrueType font addressed by Unicode characters. The font * will always be embedded. * @param ttFile the location of the font on file. The file must end in '.ttf'. * The modifiers after the name are ignored. * @param enc the encoding to be applied to this font * @param emb true if the font is to be embedded in the PDF * @param ttfAfm the font as a byte array * @throws DocumentException the font is invalid * @throws IOException the font file could not be read */ TrueTypeFontUnicode(String ttFile, String enc, boolean emb, byte ttfAfm[], boolean forceRead) throws DocumentException, IOException { String nameBase = getBaseName(ttFile); String ttcName = getTTCName(nameBase); if (nameBase.length() < ttFile.length()) { style = ttFile.substring(nameBase.length()); } encoding = enc; embedded = emb; fileName = ttcName; ttcIndex = ""; if (ttcName.length() < nameBase.length()) ttcIndex = nameBase.substring(ttcName.length() + 1); fontType = FONT_TYPE_TTUNI; if ((fileName.toLowerCase().endsWith(".ttf") || fileName.toLowerCase().endsWith(".otf") || fileName.toLowerCase().endsWith(".ttc")) && ((enc.equals(IDENTITY_H) || enc.equals(IDENTITY_V)) && emb)) { process(ttfAfm, forceRead); if (os_2.fsType == 2) throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions."); // Sivan if ((cmap31 == null && !fontSpecific) || (cmap10 == null && fontSpecific)) directTextToByte=true; //throw new DocumentException(fileName + " " + style + " does not contain an usable cmap."); if (fontSpecific) { fontSpecific = false; String tempEncoding = encoding; encoding = ""; createEncoding(); encoding = tempEncoding; fontSpecific = true; } } else throw new DocumentException(fileName + " " + style + " is not a TTF font file."); vertical = enc.endsWith("V"); } /** * Gets the width of a char in normalized 1000 units. * @param char1 the unicode char to get the width of * @return the width in normalized 1000 units */ public int getWidth(int char1) { if (vertical) return 1000; if (fontSpecific) { if ((char1 & 0xff00) == 0 || (char1 & 0xff00) == 0xf000) return getRawWidth(char1 & 0xff, null); else return 0; } else { return getRawWidth(char1, encoding); } } /** * Gets the width of a String in normalized 1000 units. * @param text the String to get the width of * @return the width in normalized 1000 units */ public int getWidth(String text) { if (vertical) return text.length() * 1000; int total = 0; if (fontSpecific) { char cc[] = text.toCharArray(); int len = cc.length; for (int k = 0; k < len; ++k) { char c = cc[k]; if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000) total += getRawWidth(c & 0xff, null); } } else { int len = text.length(); for (int k = 0; k < len; ++k) { if (Utilities.isSurrogatePair(text, k)) { total += getRawWidth(Utilities.convertToUtf32(text, k), encoding); ++k; } else total += getRawWidth(text.charAt(k), encoding); } } return total; } /** Creates a ToUnicode CMap to allow copy and paste from Acrobat. * @param metrics metrics[0] contains the glyph index and metrics[2] * contains the Unicode code * @return the stream representing this CMap or null */ private PdfStream getToUnicode(Object metrics[]) { if (metrics.length == 0) return null; StringBuffer buf = new StringBuffer( "/CIDInit /ProcSet findresource begin\n" + "12 dict begin\n" + "begincmap\n" + "/CIDSystemInfo\n" + "<< /Registry (TTX+0)\n" + "/Ordering (T42UV)\n" + "/Supplement 0\n" + ">> def\n" + "/CMapName /TTX+0 def\n" + "/CMapType 2 def\n" + "1 begincodespacerange\n" + "<0000>\n" + "endcodespacerange\n"); int size = 0; for (int k = 0; k < metrics.length; ++k) { if (size == 0) { if (k != 0) { buf.append("endbfrange\n"); } size = Math.min(100, metrics.length - k); buf.append(size).append(" beginbfrange\n"); } --size; int metric[] = (int[])metrics[k]; String fromTo = toHex(metric[0]); buf.append(fromTo).append(fromTo).append(toHex(metric[2])).append('\n'); } buf.append( "endbfrange\n" + "endcmap\n" + "CMapName currentdict /CMap defineresource pop\n" + "end end\n"); String s = buf.toString(); PdfStream stream = new PdfStream(PdfEncodings.convertToBytes(s, null)); stream.flateCompress(compressionLevel); return stream; } private static String toHex4(int n) { String s = "0000" + Integer.toHexString(n); return s.substring(s.length() - 4); } /** Gets an hex string in the format "<HHHH>". * @param n the number * @return the hex string */ static String toHex(int n) { if (n < 0x10000) return "<" + toHex4(n) + ">"; n -= 0x10000; int high = (n / 0x400) + 0xd800; int low = (n % 0x400) + 0xdc00; return "[<" + toHex4(high) + toHex4(low) + ">]"; } /** Generates the CIDFontTyte2 dictionary. * @param fontDescriptor the indirect reference to the font descriptor * @param subsetPrefix the subset prefix * @param metrics the horizontal width metrics * @return a stream */ private PdfDictionary getCIDFontType2(PdfIndirectReference fontDescriptor, String subsetPrefix, Object metrics[]) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); // sivan; cff if (cff) { dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0); dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName+"-"+encoding)); } else { dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE2); dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName)); } dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); if (!cff) dic.put(PdfName.CIDTOGIDMAP,PdfName.IDENTITY); PdfDictionary cdic = new PdfDictionary(); cdic.put(PdfName.REGISTRY, new PdfString("Adobe")); cdic.put(PdfName.ORDERING, new PdfString("Identity")); cdic.put(PdfName.SUPPLEMENT, new PdfNumber(0)); dic.put(PdfName.CIDSYSTEMINFO, cdic); if (!vertical) { dic.put(PdfName.DW, new PdfNumber(1000)); StringBuffer buf = new StringBuffer("["); int lastNumber = -10; boolean firstTime = true; for (int k = 0; k < metrics.length; ++k) { int metric[] = (int[])metrics[k]; if (metric[1] == 1000) continue; int m = metric[0]; if (m == lastNumber + 1) { buf.append(' ').append(metric[1]); } else { if (!firstTime) { buf.append(']'); } firstTime = false; buf.append(m).append('[').append(metric[1]); } lastNumber = m; } if (buf.length() > 1) { buf.append("]]"); dic.put(PdfName.W, new PdfLiteral(buf.toString())); } } return dic; } /** Generates the font dictionary. * @param descendant the descendant dictionary * @param subsetPrefix the subset prefix * @param toUnicode the ToUnicode stream * @return the stream */ private PdfDictionary getFontBaseType(PdfIndirectReference descendant, String subsetPrefix, PdfIndirectReference toUnicode) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.TYPE0); // The PDF Reference manual advises to add -encoding to CID font names if (cff) dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName+"-"+encoding)); //dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName)); else dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName)); //dic.put(PdfName.BASEFONT, new PdfName(fontName)); dic.put(PdfName.ENCODING, new PdfName(encoding)); dic.put(PdfName.DESCENDANTFONTS, new PdfArray(descendant)); if (toUnicode != null) dic.put(PdfName.TOUNICODE, toUnicode); return dic; } /** The method used to sort the metrics array. * @param o1 the first element * @param o2 the second element * @return the comparison */ public int compare(Object o1, Object o2) { int m1 = ((int[])o1)[0]; int m2 = ((int[])o2)[0]; if (m1 < m2) return -1; if (m1 == m2) return 0; return 1; } private static final byte[] rotbits = {(byte)0x80,(byte)0x40,(byte)0x20,(byte)0x10,(byte)0x08,(byte)0x04,(byte)0x02,(byte)0x01}; /** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param params several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException { HashMap longTag = (HashMap)params[0]; addRangeUni(longTag, true, subset); Object metrics[] = longTag.values().toArray(); Arrays.sort(metrics, this); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; if (writer.getPDFXConformance() == PdfWriter.PDFA1A || writer.getPDFXConformance() == PdfWriter.PDFA1B) { PdfStream stream; if (metrics.length == 0) { stream = new PdfStream(new byte[]{(byte)0x80}); } else { int top = ((int[])metrics[metrics.length - 1])[0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.length; ++k) { int v = ((int[])metrics[k])[0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.flateCompress(compressionLevel); } cidset = writer.addToBody(stream).getIndirectReference(); } // sivan: cff if (cff) { byte b[] = readCffFont(); if (subset || subsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b),longTag); b = cff.Process(cff.getNames()[0]); } pobj = new StreamFont(b, "CIDFontType0C", compressionLevel); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } else { byte[] b; if (subset || directoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), longTag, directoryOffset, false, false); b = sb.process(); } else { b = getFullFont(); } int lengths[] = new int[]{b.length}; pobj = new StreamFont(b, lengths, compressionLevel); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } String subsetPrefix = ""; if (subset) subsetPrefix = createSubsetPrefix(); PdfDictionary dic = getFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.addToBody(dic); ind_font = obj.getIndirectReference(); pobj = getCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); pobj = getToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.addToBody(pobj); toUnicodeRef = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.addToBody(pobj, ref); } /** * Returns a PdfStream object with the full font program. * @return a PdfStream with the font program * @since 2.1.3 */ public PdfStream getFullFontStream() throws IOException, DocumentException { if (cff) { return new StreamFont(readCffFont(), "CIDFontType0C", compressionLevel); } return super.getFullFontStream(); } /** A forbidden operation. Will throw a null pointer exception. * @param text the text * @return always null */ byte[] convertToBytes(String text) { return null; } byte[] convertToBytes(int char1) { return null; } /** Gets the glyph index and metrics for a character. * @param c the character * @return an int array with {glyph index, width} */ public int[] getMetricsTT(int c) { if (cmapExt != null) return (int[])cmapExt.get(new Integer(c)); HashMap map = null; if (fontSpecific) map = cmap10; else map = cmap31; if (map == null) return null; if (fontSpecific) { if ((c & 0xffffff00) == 0 || (c & 0xffffff00) == 0xf000) return (int[])map.get(new Integer(c & 0xff)); else return null; } else return (int[])map.get(new Integer(c)); } /** * Checks if a character exists in this font. * @param c the character to check * @return true if the character has a glyph, * false otherwise */ public boolean charExists(int c) { return getMetricsTT(c) != null; } /** * Sets the character advance. * @param c the character * @param advance the character advance normalized to 1000 units * @return true if the advance was set, * false otherwise */ public boolean setCharAdvance(int c, int advance) { int[] m = getMetricsTT(c); if (m == null) return false; m[1] = advance; return true; } public int[] getCharBBox(int c) { if (bboxes == null) return null; int[] m = getMetricsTT(c); if (m == null) return null; return bboxes[m[0]]; } } src/core/com/lowagie/text/pdf/Type1Font.java100644 0 0 77136 11154165266 16427 0ustar 0 0 /* * $Id: Type1Font.java 3718 2009-02-23 16:56:55Z blowagie $ * * Copyright 2001-2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.StringTokenizer; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.fonts.FontsResourceAnchor; /** Reads a Type1 font * * @author Paulo Soares (psoares@consiste.pt) */ class Type1Font extends BaseFont { private static FontsResourceAnchor resourceAnchor; /** The PFB file if the input was made with a byte array. */ protected byte pfb[]; /** The Postscript font name. */ private String FontName; /** The full name of the font. */ private String FullName; /** The family name of the font. */ private String FamilyName; /** The weight of the font: normal, bold, etc. */ private String Weight = ""; /** The italic angle of the font, usually 0.0 or negative. */ private float ItalicAngle = 0.0f; /** true if all the characters have the same * width. */ private boolean IsFixedPitch = false; /** The character set of the font. */ private String CharacterSet; /** The llx of the FontBox. */ private int llx = -50; /** The lly of the FontBox. */ private int lly = -200; /** The lurx of the FontBox. */ private int urx = 1000; /** The ury of the FontBox. */ private int ury = 900; /** The underline position. */ private int UnderlinePosition = -100; /** The underline thickness. */ private int UnderlineThickness = 50; /** The font's encoding name. This encoding is 'StandardEncoding' or * 'AdobeStandardEncoding' for a font that can be totally encoded * according to the characters names. For all other names the * font is treated as symbolic. */ private String EncodingScheme = "FontSpecific"; /** A variable. */ private int CapHeight = 700; /** A variable. */ private int XHeight = 480; /** A variable. */ private int Ascender = 800; /** A variable. */ private int Descender = -200; /** A variable. */ private int StdHW; /** A variable. */ private int StdVW = 80; /** Represents the section CharMetrics in the AFM file. Each * value of this array contains a Object[4] with an * Integer, Integer, String and int[]. This is the code, width, name and char bbox. * The key is the name of the char and also an Integer with the char number. */ private HashMap CharMetrics = new HashMap(); /** Represents the section KernPairs in the AFM file. The key is * the name of the first character and the value is a Object[] * with 2 elements for each kern pair. Position 0 is the name of * the second character and position 1 is the kerning distance. This is * repeated for all the pairs. */ private HashMap KernPairs = new HashMap(); /** The file in use. */ private String fileName; /** true if this font is one of the 14 built in fonts. */ private boolean builtinFont = false; /** Types of records in a PFB file. ASCII is 1 and BINARY is 2. * They have to appear in the PFB file in this sequence. */ private static final int PFB_TYPES[] = {1, 2, 1}; /** Creates a new Type1 font. * @param ttfAfm the AFM file if the input is made with a byte array * @param pfb the PFB file if the input is made with a byte array * @param afmFile the name of one of the 14 built-in fonts or the location of an AFM file. The file must end in '.afm' * @param enc the encoding to be applied to this font * @param emb true if the font is to be embedded in the PDF * @throws DocumentException the AFM file is invalid * @throws IOException the AFM file could not be read * @since 2.1.5 */ Type1Font(String afmFile, String enc, boolean emb, byte ttfAfm[], byte pfb[], boolean forceRead) throws DocumentException, IOException { if (emb && ttfAfm != null && pfb == null) throw new DocumentException("Two byte arrays are needed if the Type1 font is embedded."); if (emb && ttfAfm != null) this.pfb = pfb; encoding = enc; embedded = emb; fileName = afmFile; fontType = FONT_TYPE_T1; RandomAccessFileOrArray rf = null; InputStream is = null; if (BuiltinFonts14.containsKey(afmFile)) { embedded = false; builtinFont = true; byte buf[] = new byte[1024]; try { if (resourceAnchor == null) resourceAnchor = new FontsResourceAnchor(); is = getResourceStream(RESOURCE_PATH + afmFile + ".afm", resourceAnchor.getClass().getClassLoader()); if (is == null) { String msg = afmFile + " not found as resource. (The *.afm files must exist as resources in the package com.lowagie.text.pdf.fonts)"; System.err.println(msg); throw new DocumentException(msg); } ByteArrayOutputStream out = new ByteArrayOutputStream(); while (true) { int size = is.read(buf); if (size < 0) break; out.write(buf, 0, size); } buf = out.toByteArray(); } finally { if (is != null) { try { is.close(); } catch (Exception e) { // empty on purpose } } } try { rf = new RandomAccessFileOrArray(buf); process(rf); } finally { if (rf != null) { try { rf.close(); } catch (Exception e) { // empty on purpose } } } } else if (afmFile.toLowerCase().endsWith(".afm")) { try { if (ttfAfm == null) rf = new RandomAccessFileOrArray(afmFile, forceRead, Document.plainRandomAccess); else rf = new RandomAccessFileOrArray(ttfAfm); process(rf); } finally { if (rf != null) { try { rf.close(); } catch (Exception e) { // empty on purpose } } } } else if (afmFile.toLowerCase().endsWith(".pfm")) { try { ByteArrayOutputStream ba = new ByteArrayOutputStream(); if (ttfAfm == null) rf = new RandomAccessFileOrArray(afmFile, forceRead, Document.plainRandomAccess); else rf = new RandomAccessFileOrArray(ttfAfm); Pfm2afm.convert(rf, ba); rf.close(); rf = new RandomAccessFileOrArray(ba.toByteArray()); process(rf); } finally { if (rf != null) { try { rf.close(); } catch (Exception e) { // empty on purpose } } } } else throw new DocumentException(afmFile + " is not an AFM or PFM font file."); EncodingScheme = EncodingScheme.trim(); if (EncodingScheme.equals("AdobeStandardEncoding") || EncodingScheme.equals("StandardEncoding")) { fontSpecific = false; } if (!encoding.startsWith("#")) PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists createEncoding(); } /** Gets the width from the font according to the name or, * if the name is null, meaning it is a symbolic font, * the char c. * @param c the char if the font is symbolic * @param name the glyph name * @return the width of the char */ int getRawWidth(int c, String name) { Object metrics[]; if (name == null) { // font specific metrics = (Object[])CharMetrics.get(new Integer(c)); } else { if (name.equals(".notdef")) return 0; metrics = (Object[])CharMetrics.get(name); } if (metrics != null) return ((Integer)(metrics[1])).intValue(); return 0; } /** Gets the kerning between two Unicode characters. The characters * are converted to names and this names are used to find the kerning * pairs in the HashMap KernPairs. * @param char1 the first char * @param char2 the second char * @return the kerning to be applied */ public int getKerning(int char1, int char2) { String first = GlyphList.unicodeToName(char1); if (first == null) return 0; String second = GlyphList.unicodeToName(char2); if (second == null) return 0; Object obj[] = (Object[])KernPairs.get(first); if (obj == null) return 0; for (int k = 0; k < obj.length; k += 2) { if (second.equals(obj[k])) return ((Integer)obj[k + 1]).intValue(); } return 0; } /** Reads the font metrics * @param rf the AFM file * @throws DocumentException the AFM file is invalid * @throws IOException the AFM file could not be read */ public void process(RandomAccessFileOrArray rf) throws DocumentException, IOException { String line; boolean isMetrics = false; while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line, " ,\n\r\t\f"); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("FontName")) FontName = tok.nextToken("\u00ff").substring(1); else if (ident.equals("FullName")) FullName = tok.nextToken("\u00ff").substring(1); else if (ident.equals("FamilyName")) FamilyName = tok.nextToken("\u00ff").substring(1); else if (ident.equals("Weight")) Weight = tok.nextToken("\u00ff").substring(1); else if (ident.equals("ItalicAngle")) ItalicAngle = Float.parseFloat(tok.nextToken()); else if (ident.equals("IsFixedPitch")) IsFixedPitch = tok.nextToken().equals("true"); else if (ident.equals("CharacterSet")) CharacterSet = tok.nextToken("\u00ff").substring(1); else if (ident.equals("FontBBox")) { llx = (int)Float.parseFloat(tok.nextToken()); lly = (int)Float.parseFloat(tok.nextToken()); urx = (int)Float.parseFloat(tok.nextToken()); ury = (int)Float.parseFloat(tok.nextToken()); } else if (ident.equals("UnderlinePosition")) UnderlinePosition = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("UnderlineThickness")) UnderlineThickness = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("EncodingScheme")) EncodingScheme = tok.nextToken("\u00ff").substring(1); else if (ident.equals("CapHeight")) CapHeight = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("XHeight")) XHeight = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("Ascender")) Ascender = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("Descender")) Descender = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("StdHW")) StdHW = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("StdVW")) StdVW = (int)Float.parseFloat(tok.nextToken()); else if (ident.equals("StartCharMetrics")) { isMetrics = true; break; } } if (!isMetrics) throw new DocumentException("Missing StartCharMetrics in " + fileName); while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("EndCharMetrics")) { isMetrics = false; break; } Integer C = new Integer(-1); Integer WX = new Integer(250); String N = ""; int B[] = null; tok = new StringTokenizer(line, ";"); while (tok.hasMoreTokens()) { StringTokenizer tokc = new StringTokenizer(tok.nextToken()); if (!tokc.hasMoreTokens()) continue; ident = tokc.nextToken(); if (ident.equals("C")) C = Integer.valueOf(tokc.nextToken()); else if (ident.equals("WX")) WX = new Integer((int)Float.parseFloat(tokc.nextToken())); else if (ident.equals("N")) N = tokc.nextToken(); else if (ident.equals("B")) { B = new int[]{Integer.parseInt(tokc.nextToken()), Integer.parseInt(tokc.nextToken()), Integer.parseInt(tokc.nextToken()), Integer.parseInt(tokc.nextToken())}; } } Object metrics[] = new Object[]{C, WX, N, B}; if (C.intValue() >= 0) CharMetrics.put(C, metrics); CharMetrics.put(N, metrics); } if (isMetrics) throw new DocumentException("Missing EndCharMetrics in " + fileName); if (!CharMetrics.containsKey("nonbreakingspace")) { Object[] space = (Object[])CharMetrics.get("space"); if (space != null) CharMetrics.put("nonbreakingspace", space); } while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("EndFontMetrics")) return; if (ident.equals("StartKernPairs")) { isMetrics = true; break; } } if (!isMetrics) throw new DocumentException("Missing EndFontMetrics in " + fileName); while ((line = rf.readLine()) != null) { StringTokenizer tok = new StringTokenizer(line); if (!tok.hasMoreTokens()) continue; String ident = tok.nextToken(); if (ident.equals("KPX")) { String first = tok.nextToken(); String second = tok.nextToken(); Integer width = new Integer((int)Float.parseFloat(tok.nextToken())); Object relates[] = (Object[])KernPairs.get(first); if (relates == null) KernPairs.put(first, new Object[]{second, width}); else { int n = relates.length; Object relates2[] = new Object[n + 2]; System.arraycopy(relates, 0, relates2, 0, n); relates2[n] = second; relates2[n + 1] = width; KernPairs.put(first, relates2); } } else if (ident.equals("EndKernPairs")) { isMetrics = false; break; } } if (isMetrics) throw new DocumentException("Missing EndKernPairs in " + fileName); rf.close(); } /** If the embedded flag is false or if the font is * one of the 14 built in types, it returns null, * otherwise the font is read and output in a PdfStream object. * @return the PdfStream containing the font or null * @throws DocumentException if there is an error reading the font * @since 2.1.3 */ public PdfStream getFullFontStream() throws DocumentException { if (builtinFont || !embedded) return null; RandomAccessFileOrArray rf = null; try { String filePfb = fileName.substring(0, fileName.length() - 3) + "pfb"; if (pfb == null) rf = new RandomAccessFileOrArray(filePfb, true, Document.plainRandomAccess); else rf = new RandomAccessFileOrArray(pfb); int fileLength = rf.length(); byte st[] = new byte[fileLength - 18]; int lengths[] = new int[3]; int bytePtr = 0; for (int k = 0; k < 3; ++k) { if (rf.read() != 0x80) throw new DocumentException("Start marker missing in " + filePfb); if (rf.read() != PFB_TYPES[k]) throw new DocumentException("Incorrect segment type in " + filePfb); int size = rf.read(); size += rf.read() << 8; size += rf.read() << 16; size += rf.read() << 24; lengths[k] = size; while (size != 0) { int got = rf.read(st, bytePtr, size); if (got < 0) throw new DocumentException("Premature end in " + filePfb); bytePtr += got; size -= got; } } return new StreamFont(st, lengths, compressionLevel); } catch (Exception e) { throw new DocumentException(e); } finally { if (rf != null) { try { rf.close(); } catch (Exception e) { // empty on purpose } } } } /** Generates the font descriptor for this font or null if it is * one of the 14 built in fonts. * @param fontStream the indirect reference to a PdfStream containing the font or null * @return the PdfDictionary containing the font descriptor or null */ private PdfDictionary getFontDescriptor(PdfIndirectReference fontStream) { if (builtinFont) return null; PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR); dic.put(PdfName.ASCENT, new PdfNumber(Ascender)); dic.put(PdfName.CAPHEIGHT, new PdfNumber(CapHeight)); dic.put(PdfName.DESCENT, new PdfNumber(Descender)); dic.put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury)); dic.put(PdfName.FONTNAME, new PdfName(FontName)); dic.put(PdfName.ITALICANGLE, new PdfNumber(ItalicAngle)); dic.put(PdfName.STEMV, new PdfNumber(StdVW)); if (fontStream != null) dic.put(PdfName.FONTFILE, fontStream); int flags = 0; if (IsFixedPitch) flags |= 1; flags |= fontSpecific ? 4 : 32; if (ItalicAngle < 0) flags |= 64; if (FontName.indexOf("Caps") >= 0 || FontName.endsWith("SC")) flags |= 131072; if (Weight.equals("Bold")) flags |= 262144; dic.put(PdfName.FLAGS, new PdfNumber(flags)); return dic; } /** Generates the font dictionary for this font. * @return the PdfDictionary containing the font dictionary * @param firstChar the first valid character * @param lastChar the last valid character * @param shortTag a 256 bytes long byte array where each unused byte is represented by 0 * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or null */ private PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, int firstChar, int lastChar, byte shortTag[]) { PdfDictionary dic = new PdfDictionary(PdfName.FONT); dic.put(PdfName.SUBTYPE, PdfName.TYPE1); dic.put(PdfName.BASEFONT, new PdfName(FontName)); boolean stdEncoding = encoding.equals("Cp1252") || encoding.equals("MacRoman"); if (!fontSpecific || specialMap != null) { for (int k = firstChar; k <= lastChar; ++k) { if (!differences[k].equals(notdef)) { firstChar = k; break; } } if (stdEncoding) dic.put(PdfName.ENCODING, encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING); else { PdfDictionary enc = new PdfDictionary(PdfName.ENCODING); PdfArray dif = new PdfArray(); boolean gap = true; for (int k = firstChar; k <= lastChar; ++k) { if (shortTag[k] != 0) { if (gap) { dif.add(new PdfNumber(k)); gap = false; } dif.add(new PdfName(differences[k])); } else gap = true; } enc.put(PdfName.DIFFERENCES, dif); dic.put(PdfName.ENCODING, enc); } } if (specialMap != null || forceWidthsOutput || !(builtinFont && (fontSpecific || stdEncoding))) { dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar)); dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar)); PdfArray wd = new PdfArray(); for (int k = firstChar; k <= lastChar; ++k) { if (shortTag[k] == 0) wd.add(new PdfNumber(0)); else wd.add(new PdfNumber(widths[k])); } dic.put(PdfName.WIDTHS, wd); } if (!builtinFont && fontDescriptor != null) dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); return dic; } /** Outputs to the writer the font dictionaries and streams. * @param writer the writer for this document * @param ref the font indirect reference * @param params several parameters that depend on the font type * @throws IOException on error * @throws DocumentException error in generating the object */ void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException { int firstChar = ((Integer)params[0]).intValue(); int lastChar = ((Integer)params[1]).intValue(); byte shortTag[] = (byte[])params[2]; boolean subsetp = ((Boolean)params[3]).booleanValue() && subset; if (!subsetp) { firstChar = 0; lastChar = shortTag.length - 1; for (int k = 0; k < shortTag.length; ++k) shortTag[k] = 1; } PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; pobj = getFullFontStream(); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontDescriptor(ind_font); if (pobj != null){ obj = writer.addToBody(pobj); ind_font = obj.getIndirectReference(); } pobj = getFontBaseType(ind_font, firstChar, lastChar, shortTag); writer.addToBody(pobj, ref); } /** Gets the font parameter identified by key. Valid values * for key are ASCENT, CAPHEIGHT, DESCENT, * ITALICANGLE, BBOXLLX, BBOXLLY, BBOXURX * and BBOXURY. * @param key the parameter to be extracted * @param fontSize the font size in points * @return the parameter in points */ public float getFontDescriptor(int key, float fontSize) { switch (key) { case AWT_ASCENT: case ASCENT: return Ascender * fontSize / 1000; case CAPHEIGHT: return CapHeight * fontSize / 1000; case AWT_DESCENT: case DESCENT: return Descender * fontSize / 1000; case ITALICANGLE: return ItalicAngle; case BBOXLLX: return llx * fontSize / 1000; case BBOXLLY: return lly * fontSize / 1000; case BBOXURX: return urx * fontSize / 1000; case BBOXURY: return ury * fontSize / 1000; case AWT_LEADING: return 0; case AWT_MAXADVANCE: return (urx - llx) * fontSize / 1000; case UNDERLINE_POSITION: return UnderlinePosition * fontSize / 1000; case UNDERLINE_THICKNESS: return UnderlineThickness * fontSize / 1000; } return 0; } /** Gets the postscript font name. * @return the postscript font name */ public String getPostscriptFontName() { return FontName; } /** Gets the full name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"", "", "", * font name}. * @return the full name of the font */ public String[][] getFullFontName() { return new String[][]{{"", "", "", FullName}}; } /** Gets all the entries of the names-table. If it is a True Type font * each array element will have {Name ID, Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"4", "", "", "", * font name}. * @return the full name of the font */ public String[][] getAllNameEntries() { return new String[][]{{"4", "", "", "", FullName}}; } /** Gets the family name of the font. If it is a True Type font * each array element will have {Platform ID, Platform Encoding ID, * Language ID, font name}. The interpretation of this values can be * found in the Open Type specification, chapter 2, in the 'name' table.
    * For the other fonts the array has a single element with {"", "", "", * font name}. * @return the family name of the font */ public String[][] getFamilyFontName() { return new String[][]{{"", "", "", FamilyName}}; } /** Checks if the font has any kerning pairs. * @return true if the font has any kerning pairs */ public boolean hasKernPairs() { return !KernPairs.isEmpty(); } /** * Sets the font name that will appear in the pdf font dictionary. * Use with care as it can easily make a font unreadable if not embedded. * @param name the new font name */ public void setPostscriptFontName(String name) { FontName = name; } /** * Sets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @param kern the kerning to apply in normalized 1000 units * @return true if the kerning was applied, false otherwise */ public boolean setKerning(int char1, int char2, int kern) { String first = GlyphList.unicodeToName(char1); if (first == null) return false; String second = GlyphList.unicodeToName(char2); if (second == null) return false; Object obj[] = (Object[])KernPairs.get(first); if (obj == null) { obj = new Object[]{second, new Integer(kern)}; KernPairs.put(first, obj); return true; } for (int k = 0; k < obj.length; k += 2) { if (second.equals(obj[k])) { obj[k + 1] = new Integer(kern); return true; } } int size = obj.length; Object obj2[] = new Object[size + 2]; System.arraycopy(obj, 0, obj2, 0, size); obj2[size] = second; obj2[size + 1] = new Integer(kern); KernPairs.put(first, obj2); return true; } protected int[] getRawCharBBox(int c, String name) { Object metrics[]; if (name == null) { // font specific metrics = (Object[])CharMetrics.get(new Integer(c)); } else { if (name.equals(".notdef")) return null; metrics = (Object[])CharMetrics.get(name); } if (metrics != null) return ((int[])(metrics[3])); return null; } } src/core/com/lowagie/text/pdf/Type3Font.java100644 0 0 27662 11036112746 16422 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.util.HashMap; import com.lowagie.text.DocumentException; /** * A class to support Type3 fonts. */ public class Type3Font extends BaseFont { private boolean[] usedSlot; private IntHashtable widths3 = new IntHashtable(); private HashMap char2glyph = new HashMap(); private PdfWriter writer; private float llx = Float.NaN, lly, urx, ury; private PageResources pageResources = new PageResources(); private boolean colorized; /** * Creates a Type3 font. * @param writer the writer * @param chars an array of chars corresponding to the glyphs used (not used, present for compatibility only) * @param colorized if true the font may specify color, if false no color commands are allowed * and only images as masks can be used */ public Type3Font(PdfWriter writer, char[] chars, boolean colorized) { this(writer, colorized); } /** * Creates a Type3 font. This implementation assumes that the /FontMatrix is * [0.001 0 0 0.001 0 0] or a 1000-unit glyph coordinate system. *

    * An example: *

    *

         * Document document = new Document(PageSize.A4);
         * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("type3.pdf"));
         * document.open();
         * Type3Font t3 = new Type3Font(writer, false);
         * PdfContentByte g = t3.defineGlyph('a', 1000, 0, 0, 750, 750);
         * g.rectangle(0, 0, 750, 750);
         * g.fill();
         * g = t3.defineGlyph('b', 1000, 0, 0, 750, 750);
         * g.moveTo(0, 0);
         * g.lineTo(375, 750);
         * g.lineTo(750, 0);
         * g.fill();
         * Font f = new Font(t3, 12);
         * document.add(new Paragraph("ababab", f));
         * document.close();
         * 
    * @param writer the writer * @param colorized if true the font may specify color, if false no color commands are allowed * and only images as masks can be used */ public Type3Font(PdfWriter writer, boolean colorized) { this.writer = writer; this.colorized = colorized; fontType = FONT_TYPE_T3; usedSlot = new boolean[256]; } /** * Defines a glyph. If the character was already defined it will return the same content * @param c the character to match this glyph. * @param wx the advance this character will have * @param llx the X lower left corner of the glyph bounding box. If the colorize option is * true the value is ignored * @param lly the Y lower left corner of the glyph bounding box. If the colorize option is * true the value is ignored * @param urx the X upper right corner of the glyph bounding box. If the colorize option is * true the value is ignored * @param ury the Y upper right corner of the glyph bounding box. If the colorize option is * true the value is ignored * @return a content where the glyph can be defined */ public PdfContentByte defineGlyph(char c, float wx, float llx, float lly, float urx, float ury) { if (c == 0 || c > 255) throw new IllegalArgumentException("The char " + (int)c + " doesn't belong in this Type3 font"); usedSlot[c] = true; Integer ck = new Integer(c); Type3Glyph glyph = (Type3Glyph)char2glyph.get(ck); if (glyph != null) return glyph; widths3.put(c, (int)wx); if (!colorized) { if (Float.isNaN(this.llx)) { this.llx = llx; this.lly = lly; this.urx = urx; this.ury = ury; } else { this.llx = Math.min(this.llx, llx); this.lly = Math.min(this.lly, lly); this.urx = Math.max(this.urx, urx); this.ury = Math.max(this.ury, ury); } } glyph = new Type3Glyph(writer, pageResources, wx, llx, lly, urx, ury, colorized); char2glyph.put(ck, glyph); return glyph; } public String[][] getFamilyFontName() { return getFullFontName(); } public float getFontDescriptor(int key, float fontSize) { return 0; } public String[][] getFullFontName() { return new String[][]{{"", "", "", ""}}; } /** * @since 2.0.8 */ public String[][] getAllNameEntries() { return new String[][]{{"4", "", "", "", ""}}; } public int getKerning(int char1, int char2) { return 0; } public String getPostscriptFontName() { return ""; } protected int[] getRawCharBBox(int c, String name) { return null; } int getRawWidth(int c, String name) { return 0; } public boolean hasKernPairs() { return false; } public boolean setKerning(int char1, int char2, int kern) { return false; } public void setPostscriptFontName(String name) { } void writeFont(PdfWriter writer, PdfIndirectReference ref, Object[] params) throws com.lowagie.text.DocumentException, java.io.IOException { if (this.writer != writer) throw new IllegalArgumentException("Type3 font used with the wrong PdfWriter"); // Get first & lastchar ... int firstChar = 0; while( firstChar < usedSlot.length && !usedSlot[firstChar] ) firstChar++; if ( firstChar == usedSlot.length ) { throw new DocumentException( "No glyphs defined for Type3 font" ); } int lastChar = usedSlot.length - 1; while( lastChar >= firstChar && !usedSlot[lastChar] ) lastChar--; int[] widths = new int[lastChar - firstChar + 1]; int[] invOrd = new int[lastChar - firstChar + 1]; int invOrdIndx = 0, w = 0; for( int u = firstChar; u<=lastChar; u++, w++ ) { if ( usedSlot[u] ) { invOrd[invOrdIndx++] = u; widths[w] = widths3.get(u); } } PdfArray diffs = new PdfArray(); PdfDictionary charprocs = new PdfDictionary(); int last = -1; for (int k = 0; k < invOrdIndx; ++k) { int c = invOrd[k]; if (c > last) { last = c; diffs.add(new PdfNumber(last)); } ++last; int c2 = invOrd[k]; String s = GlyphList.unicodeToName(c2); if (s == null) s = "a" + c2; PdfName n = new PdfName(s); diffs.add(n); Type3Glyph glyph = (Type3Glyph)char2glyph.get(new Integer(c2)); PdfStream stream = new PdfStream(glyph.toPdf(null)); stream.flateCompress(compressionLevel); PdfIndirectReference refp = writer.addToBody(stream).getIndirectReference(); charprocs.put(n, refp); } PdfDictionary font = new PdfDictionary(PdfName.FONT); font.put(PdfName.SUBTYPE, PdfName.TYPE3); if (colorized) font.put(PdfName.FONTBBOX, new PdfRectangle(0, 0, 0, 0)); else font.put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury)); font.put(PdfName.FONTMATRIX, new PdfArray(new float[]{0.001f, 0, 0, 0.001f, 0, 0})); font.put(PdfName.CHARPROCS, writer.addToBody(charprocs).getIndirectReference()); PdfDictionary encoding = new PdfDictionary(); encoding.put(PdfName.DIFFERENCES, diffs); font.put(PdfName.ENCODING, writer.addToBody(encoding).getIndirectReference()); font.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar)); font.put(PdfName.LASTCHAR, new PdfNumber(lastChar)); font.put(PdfName.WIDTHS, writer.addToBody(new PdfArray(widths)).getIndirectReference()); if (pageResources.hasResources()) font.put(PdfName.RESOURCES, writer.addToBody(pageResources.getResources()).getIndirectReference()); writer.addToBody(font, ref); } /** * Always returns null, because you can't get the FontStream of a Type3 font. * @return null * @since 2.1.3 */ public PdfStream getFullFontStream() { return null; } byte[] convertToBytes(String text) { char[] cc = text.toCharArray(); byte[] b = new byte[cc.length]; int p = 0; for (int k = 0; k < cc.length; ++k) { char c = cc[k]; if (charExists(c)) b[p++] = (byte)c; } if (b.length == p) return b; byte[] b2 = new byte[p]; System.arraycopy(b, 0, b2, 0, p); return b2; } byte[] convertToBytes(int char1) { if (charExists(char1)) return new byte[]{(byte)char1}; else return new byte[0]; } public int getWidth(int char1) { if (!widths3.containsKey(char1)) throw new IllegalArgumentException("The char " + char1 + " is not defined in a Type3 font"); return widths3.get(char1); } public int getWidth(String text) { char[] c = text.toCharArray(); int total = 0; for (int k = 0; k < c.length; ++k) total += getWidth(c[k]); return total; } public int[] getCharBBox(int c) { return null; } public boolean charExists(int c) { if (c > 0 && c < 256) { return usedSlot[c]; } else { return false; } } public boolean setCharAdvance(int c, int advance) { return false; } } src/core/com/lowagie/text/pdf/Type3Glyph.java100644 0 0 7677 11000663663 16563 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; /** * The content where Type3 glyphs are written to. */ public final class Type3Glyph extends PdfContentByte { private PageResources pageResources; private boolean colorized; private Type3Glyph() { super(null); } Type3Glyph(PdfWriter writer, PageResources pageResources, float wx, float llx, float lly, float urx, float ury, boolean colorized) { super(writer); this.pageResources = pageResources; this.colorized = colorized; if (colorized) { content.append(wx).append(" 0 d0\n"); } else { content.append(wx).append(" 0 ").append(llx).append(' ').append(lly).append(' ').append(urx).append(' ').append(ury).append(" d1\n"); } } PageResources getPageResources() { return pageResources; } public void addImage(Image image, float a, float b, float c, float d, float e, float f, boolean inlineImage) throws DocumentException { if (!colorized && (!image.isMask() || !(image.getBpc() == 1 || image.getBpc() > 0xff))) throw new DocumentException("Not colorized Typed3 fonts only accept mask images."); super.addImage(image, a, b, c, d, e, f, inlineImage); } public PdfContentByte getDuplicate() { Type3Glyph dup = new Type3Glyph(); dup.writer = writer; dup.pdf = pdf; dup.pageResources = pageResources; dup.colorized = colorized; return dup; } }src/core/com/lowagie/text/pdf/VerticalText.java100644 0 0 26250 11000354131 17160 0ustar 0 0 /* * * Copyright 2002 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.awt.Color; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Chunk; import com.lowagie.text.Element; import com.lowagie.text.Phrase; /** Writes text vertically. Note that the naming is done according * to horizontal text although it refers to vertical text. * A line with the alignment Element.LEFT_ALIGN will actually * be top aligned. */ public class VerticalText { /** Signals that there are no more text available. */ public static final int NO_MORE_TEXT = 1; /** Signals that there is no more column. */ public static final int NO_MORE_COLUMN = 2; /** The chunks that form the text. */ protected ArrayList chunks = new ArrayList(); /** The PdfContent where the text will be written to. */ protected PdfContentByte text; /** The column alignment. Default is left alignment. */ protected int alignment = Element.ALIGN_LEFT; /** Marks the chunks to be eliminated when the line is written. */ protected int currentChunkMarker = -1; /** The chunk created by the splitting. */ protected PdfChunk currentStandbyChunk; /** The chunk created by the splitting. */ protected String splittedChunkText; /** The leading */ protected float leading; /** The X coordinate. */ protected float startX; /** The Y coordinate. */ protected float startY; /** The maximum number of vertical lines. */ protected int maxLines; /** The height of the text. */ protected float height; /** Creates new VerticalText * @param text the place where the text will be written to. Can * be a template. */ public VerticalText(PdfContentByte text) { this.text = text; } /** * Adds a Phrase to the current text array. * @param phrase the text */ public void addText(Phrase phrase) { for (Iterator j = phrase.getChunks().iterator(); j.hasNext();) { chunks.add(new PdfChunk((Chunk)j.next(), null)); } } /** * Adds a Chunk to the current text array. * @param chunk the text */ public void addText(Chunk chunk) { chunks.add(new PdfChunk(chunk, null)); } /** Sets the layout. * @param startX the top right X line position * @param startY the top right Y line position * @param height the height of the lines * @param maxLines the maximum number of lines * @param leading the separation between the lines */ public void setVerticalLayout(float startX, float startY, float height, int maxLines, float leading) { this.startX = startX; this.startY = startY; this.height = height; this.maxLines = maxLines; setLeading(leading); } /** Sets the separation between the vertical lines. * @param leading the vertical line separation */ public void setLeading(float leading) { this.leading = leading; } /** Gets the separation between the vertical lines. * @return the vertical line separation */ public float getLeading() { return leading; } /** * Creates a line from the chunk array. * @param width the width of the line * @return the line or null if no more chunks */ protected PdfLine createLine(float width) { if (chunks.isEmpty()) return null; splittedChunkText = null; currentStandbyChunk = null; PdfLine line = new PdfLine(0, width, alignment, 0); String total; for (currentChunkMarker = 0; currentChunkMarker < chunks.size(); ++currentChunkMarker) { PdfChunk original = (PdfChunk)(chunks.get(currentChunkMarker)); total = original.toString(); currentStandbyChunk = line.add(original); if (currentStandbyChunk != null) { splittedChunkText = original.toString(); original.setValue(total); return line; } } return line; } /** * Normalizes the list of chunks when the line is accepted. */ protected void shortenChunkArray() { if (currentChunkMarker < 0) return; if (currentChunkMarker >= chunks.size()) { chunks.clear(); return; } PdfChunk split = (PdfChunk)(chunks.get(currentChunkMarker)); split.setValue(splittedChunkText); chunks.set(currentChunkMarker, currentStandbyChunk); for (int j = currentChunkMarker - 1; j >= 0; --j) chunks.remove(j); } /** * Outputs the lines to the document. It is equivalent to go(false). * @return returns the result of the operation. It can be NO_MORE_TEXT * and/or NO_MORE_COLUMN */ public int go() { return go(false); } /** * Outputs the lines to the document. The output can be simulated. * @param simulate true to simulate the writing to the document * @return returns the result of the operation. It can be NO_MORE_TEXT * and/or NO_MORE_COLUMN */ public int go(boolean simulate) { boolean dirty = false; PdfContentByte graphics = null; if (text != null) { graphics = text.getDuplicate(); } else if (!simulate) throw new NullPointerException("VerticalText.go with simulate==false and text==null."); int status = 0; for (;;) { if (maxLines <= 0) { status = NO_MORE_COLUMN; if (chunks.isEmpty()) status |= NO_MORE_TEXT; break; } if (chunks.isEmpty()) { status = NO_MORE_TEXT; break; } PdfLine line = createLine(height); if (!simulate && !dirty) { text.beginText(); dirty = true; } shortenChunkArray(); if (!simulate) { text.setTextMatrix(startX, startY - line.indentLeft()); writeLine(line, text, graphics); } --maxLines; startX -= leading; } if (dirty) { text.endText(); text.add(graphics); } return status; } void writeLine(PdfLine line, PdfContentByte text, PdfContentByte graphics) { PdfFont currentFont = null; PdfChunk chunk; for (Iterator j = line.iterator(); j.hasNext(); ) { chunk = (PdfChunk) j.next(); if (chunk.font().compareTo(currentFont) != 0) { currentFont = chunk.font(); text.setFontAndSize(currentFont.getFont(), currentFont.size()); } Color color = chunk.color(); if (color != null) text.setColorFill(color); text.showText(chunk.toString()); if (color != null) text.resetRGBColorFill(); } } /** Sets the new text origin. * @param startX the X coordinate * @param startY the Y coordinate */ public void setOrigin(float startX, float startY) { this.startX = startX; this.startY = startY; } /** Gets the X coordinate where the next line will be written. This value will change * after each call to go(). * @return the X coordinate */ public float getOriginX() { return startX; } /** Gets the Y coordinate where the next line will be written. * @return the Y coordinate */ public float getOriginY() { return startY; } /** Gets the maximum number of available lines. This value will change * after each call to go(). * @return Value of property maxLines. */ public int getMaxLines() { return maxLines; } /** Sets the maximum number of lines. * @param maxLines the maximum number of lines */ public void setMaxLines(int maxLines) { this.maxLines = maxLines; } /** Gets the height of the line * @return the height */ public float getHeight() { return height; } /** Sets the height of the line * @param height the new height */ public void setHeight(float height) { this.height = height; } /** * Sets the alignment. * @param alignment the alignment */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * Gets the alignment. * @return the alignment */ public int getAlignment() { return alignment; } } src/core/com/lowagie/text/pdf/XfaForm.java100644 0 0 115276 11215636056 16154 0ustar 0 0 /* * $Id: XfaForm.java 3961 2009-06-09 10:06:10Z blowagie $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.EmptyStackException; import java.util.HashMap; import java.util.Iterator; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Node; import org.xml.sax.SAXException; import com.lowagie.text.xml.XmlDomWriter; /** * Processes XFA forms. * @author Paulo Soares (psoares@consiste.pt) */ public class XfaForm { private Xml2SomTemplate templateSom; private Node templateNode; private Xml2SomDatasets datasetsSom; private Node datasetsNode; private AcroFieldsSearch acroFieldsSom; private PdfReader reader; private boolean xfaPresent; private org.w3c.dom.Document domDocument; private boolean changed; public static final String XFA_DATA_SCHEMA = "http://www.xfa.org/schema/xfa-data/1.0/"; /** * An empty constructor to build on. */ public XfaForm() { } /** * Return the XFA Object, could be an array, could be a Stream. * Returns null f no XFA Object is present. * @param reader a PdfReader instance * @return the XFA object * @since 2.1.3 */ public static PdfObject getXfaObject(PdfReader reader) { PdfDictionary af = (PdfDictionary)PdfReader.getPdfObjectRelease(reader.getCatalog().get(PdfName.ACROFORM)); if (af == null) { return null; } return PdfReader.getPdfObjectRelease(af.get(PdfName.XFA)); } /** * A constructor from a PdfReader. It basically does everything * from finding the XFA stream to the XML parsing. * @param reader the reader * @throws java.io.IOException on error * @throws javax.xml.parsers.ParserConfigurationException on error * @throws org.xml.sax.SAXException on error */ public XfaForm(PdfReader reader) throws IOException, ParserConfigurationException, SAXException { this.reader = reader; PdfObject xfa = getXfaObject(reader); if (xfa == null) { xfaPresent = false; return; } xfaPresent = true; ByteArrayOutputStream bout = new ByteArrayOutputStream(); if (xfa.isArray()) { PdfArray ar = (PdfArray)xfa; for (int k = 1; k < ar.size(); k += 2) { PdfObject ob = ar.getDirectObject(k); if (ob instanceof PRStream) { byte[] b = PdfReader.getStreamBytes((PRStream)ob); bout.write(b); } } } else if (xfa instanceof PRStream) { byte[] b = PdfReader.getStreamBytes((PRStream)xfa); bout.write(b); } bout.close(); DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); fact.setNamespaceAware(true); DocumentBuilder db = fact.newDocumentBuilder(); domDocument = db.parse(new ByteArrayInputStream(bout.toByteArray())); extractNodes(); } /** * Extracts the nodes from the domDocument. * @since 2.1.5 */ private void extractNodes() { Node n = domDocument.getFirstChild(); while (n.getChildNodes().getLength() == 0) { n = n.getNextSibling(); } n = n.getFirstChild(); while (n != null) { if (n.getNodeType() == Node.ELEMENT_NODE) { String s = n.getLocalName(); if (s.equals("template")) { templateNode = n; templateSom = new Xml2SomTemplate(n); } else if (s.equals("datasets")) { datasetsNode = n; datasetsSom = new Xml2SomDatasets(n.getFirstChild()); } } n = n.getNextSibling(); } } /** * Sets the XFA key from a byte array. The old XFA is erased. * @param form the data * @param reader the reader * @param writer the writer * @throws java.io.IOException on error */ public static void setXfa(XfaForm form, PdfReader reader, PdfWriter writer) throws IOException { PdfDictionary af = (PdfDictionary)PdfReader.getPdfObjectRelease(reader.getCatalog().get(PdfName.ACROFORM)); if (af == null) { return; } PdfObject xfa = getXfaObject(reader); if (xfa.isArray()) { PdfArray ar = (PdfArray)xfa; int t = -1; int d = -1; for (int k = 0; k < ar.size(); k += 2) { PdfString s = ar.getAsString(k); if ("template".equals(s.toString())) { t = k + 1; } if ("datasets".equals(s.toString())) { d = k + 1; } } if (t > -1 && d > -1) { reader.killXref(ar.getAsIndirectObject(t)); reader.killXref(ar.getAsIndirectObject(d)); PdfStream tStream = new PdfStream(serializeDoc(form.templateNode)); tStream.flateCompress(writer.getCompressionLevel()); ar.set(t, writer.addToBody(tStream).getIndirectReference()); PdfStream dStream = new PdfStream(serializeDoc(form.datasetsNode)); dStream.flateCompress(writer.getCompressionLevel()); ar.set(d, writer.addToBody(dStream).getIndirectReference()); af.put(PdfName.XFA, new PdfArray(ar)); return; } } reader.killXref(af.get(PdfName.XFA)); PdfStream str = new PdfStream(serializeDoc(form.domDocument)); str.flateCompress(writer.getCompressionLevel()); PdfIndirectReference ref = writer.addToBody(str).getIndirectReference(); af.put(PdfName.XFA, ref); } /** * Sets the XFA key from the instance data. The old XFA is erased. * @param writer the writer * @throws java.io.IOException on error */ public void setXfa(PdfWriter writer) throws IOException { setXfa(this, reader, writer); } /** * Serializes a XML document to a byte array. * @param n the XML document * @throws java.io.IOException on error * @return the serialized XML document */ public static byte[] serializeDoc(Node n) throws IOException { XmlDomWriter xw = new XmlDomWriter(); ByteArrayOutputStream fout = new ByteArrayOutputStream(); xw.setOutput(fout, null); xw.setCanonical(false); xw.write(n); fout.close(); return fout.toByteArray(); } /** * Returns true if it is a XFA form. * @return true if it is a XFA form */ public boolean isXfaPresent() { return xfaPresent; } /** * Gets the top level DOM document. * @return the top level DOM document */ public org.w3c.dom.Document getDomDocument() { return domDocument; } /** * Finds the complete field name contained in the "classic" forms from a partial * name. * @param name the complete or partial name * @param af the fields * @return the complete name or null if not found */ public String findFieldName(String name, AcroFields af) { HashMap items = af.getFields(); if (items.containsKey(name)) return name; if (acroFieldsSom == null) { if (items.isEmpty() && xfaPresent) acroFieldsSom = new AcroFieldsSearch(datasetsSom.getName2Node().keySet()); else acroFieldsSom = new AcroFieldsSearch(items.keySet()); } if (acroFieldsSom.getAcroShort2LongName().containsKey(name)) return (String)acroFieldsSom.getAcroShort2LongName().get(name); return acroFieldsSom.inverseSearchGlobal(Xml2Som.splitParts(name)); } /** * Finds the complete SOM name contained in the datasets section from a * possibly partial name. * @param name the complete or partial name * @return the complete name or null if not found */ public String findDatasetsName(String name) { if (datasetsSom.getName2Node().containsKey(name)) return name; return datasetsSom.inverseSearchGlobal(Xml2Som.splitParts(name)); } /** * Finds the Node contained in the datasets section from a * possibly partial name. * @param name the complete or partial name * @return the Node or null if not found */ public Node findDatasetsNode(String name) { if (name == null) return null; name = findDatasetsName(name); if (name == null) return null; return (Node)datasetsSom.getName2Node().get(name); } /** * Gets all the text contained in the child nodes of this node. * @param n the Node * @return the text found or "" if no text was found */ public static String getNodeText(Node n) { if (n == null) return ""; return getNodeText(n, ""); } private static String getNodeText(Node n, String name) { Node n2 = n.getFirstChild(); while (n2 != null) { if (n2.getNodeType() == Node.ELEMENT_NODE) { name = getNodeText(n2, name); } else if (n2.getNodeType() == Node.TEXT_NODE) { name += n2.getNodeValue(); } n2 = n2.getNextSibling(); } return name; } /** * Sets the text of this node. All the child's node are deleted and a new * child text node is created. * @param n the Node to add the text to * @param text the text to add */ public void setNodeText(Node n, String text) { if (n == null) return; Node nc = null; while ((nc = n.getFirstChild()) != null) { n.removeChild(nc); } if (n.getAttributes().getNamedItemNS(XFA_DATA_SCHEMA, "dataNode") != null) n.getAttributes().removeNamedItemNS(XFA_DATA_SCHEMA, "dataNode"); n.appendChild(domDocument.createTextNode(text)); changed = true; } /** * Sets the XFA form flag signaling that this is a valid XFA form. * @param xfaPresent the XFA form flag signaling that this is a valid XFA form */ public void setXfaPresent(boolean xfaPresent) { this.xfaPresent = xfaPresent; } /** * Sets the top DOM document. * @param domDocument the top DOM document */ public void setDomDocument(org.w3c.dom.Document domDocument) { this.domDocument = domDocument; extractNodes(); } /** * Gets the PdfReader used by this instance. * @return the PdfReader used by this instance */ public PdfReader getReader() { return reader; } /** * Sets the PdfReader to be used by this instance. * @param reader the PdfReader to be used by this instance */ public void setReader(PdfReader reader) { this.reader = reader; } /** * Checks if this XFA form was changed. * @return true if this XFA form was changed */ public boolean isChanged() { return changed; } /** * Sets the changed status of this XFA instance. * @param changed the changed status of this XFA instance */ public void setChanged(boolean changed) { this.changed = changed; } /** * A structure to store each part of a SOM name and link it to the next part * beginning from the lower hierarchy. */ public static class InverseStore { protected ArrayList part = new ArrayList(); protected ArrayList follow = new ArrayList(); /** * Gets the full name by traversing the hierarchy using only the * index 0. * @return the full name */ public String getDefaultName() { InverseStore store = this; while (true) { Object obj = store.follow.get(0); if (obj instanceof String) return (String)obj; store = (InverseStore)obj; } } /** * Search the current node for a similar name. A similar name starts * with the same name but has a different index. For example, "detail[3]" * is similar to "detail[9]". The main use is to discard names that * correspond to out of bounds records. * @param name the name to search * @return true if a similitude was found */ public boolean isSimilar(String name) { int idx = name.indexOf('['); name = name.substring(0, idx + 1); for (int k = 0; k < part.size(); ++k) { if (((String)part.get(k)).startsWith(name)) return true; } return false; } } /** * Another stack implementation. The main use is to facilitate * the porting to other languages. */ public static class Stack2 extends ArrayList { private static final long serialVersionUID = -7451476576174095212L; /** * Looks at the object at the top of this stack without removing it from the stack. * @return the object at the top of this stack */ public Object peek() { if (size() == 0) throw new EmptyStackException(); return get(size() - 1); } /** * Removes the object at the top of this stack and returns that object as the value of this function. * @return the object at the top of this stack */ public Object pop() { if (size() == 0) throw new EmptyStackException(); Object ret = get(size() - 1); remove(size() - 1); return ret; } /** * Pushes an item onto the top of this stack. * @param item the item to be pushed onto this stack * @return the item argument */ public Object push(Object item) { add(item); return item; } /** * Tests if this stack is empty. * @return true if and only if this stack contains no items; false otherwise */ public boolean empty() { return size() == 0; } } /** * A class for some basic SOM processing. */ public static class Xml2Som { /** * The order the names appear in the XML, depth first. */ protected ArrayList order; /** * The mapping of full names to nodes. */ protected HashMap name2Node; /** * The data to do a search from the bottom hierarchy. */ protected HashMap inverseSearch; /** * A stack to be used when parsing. */ protected Stack2 stack; /** * A temporary store for the repetition count. */ protected int anform; /** * Escapes a SOM string fragment replacing "." with "\.". * @param s the unescaped string * @return the escaped string */ public static String escapeSom(String s) { int idx = s.indexOf('.'); if (idx < 0) return s; StringBuffer sb = new StringBuffer(); int last = 0; while (idx >= 0) { sb.append(s.substring(last, idx)); sb.append('\\'); last = idx; idx = s.indexOf('.', idx + 1); } sb.append(s.substring(last)); return sb.toString(); } /** * Unescapes a SOM string fragment replacing "\." with ".". * @param s the escaped string * @return the unescaped string */ public static String unescapeSom(String s) { int idx = s.indexOf('\\'); if (idx < 0) return s; StringBuffer sb = new StringBuffer(); int last = 0; while (idx >= 0) { sb.append(s.substring(last, idx)); last = idx + 1; idx = s.indexOf('\\', idx + 1); } sb.append(s.substring(last)); return sb.toString(); } /** * Outputs the stack as the sequence of elements separated * by '.'. * @return the stack as the sequence of elements separated by '.' */ protected String printStack() { if (stack.empty()) return ""; StringBuffer s = new StringBuffer(); for (int k = 0; k < stack.size(); ++k) s.append('.').append((String)stack.get(k)); return s.substring(1); } /** * Gets the name with the #subform removed. * @param s the long name * @return the short name */ public static String getShortName(String s) { int idx = s.indexOf(".#subform["); if (idx < 0) return s; int last = 0; StringBuffer sb = new StringBuffer(); while (idx >= 0) { sb.append(s.substring(last, idx)); idx = s.indexOf("]", idx + 10); if (idx < 0) return sb.toString(); last = idx + 1; idx = s.indexOf(".#subform[", last); } sb.append(s.substring(last)); return sb.toString(); } /** * Adds a SOM name to the search node chain. * @param unstack the SOM name */ public void inverseSearchAdd(String unstack) { inverseSearchAdd(inverseSearch, stack, unstack); } /** * Adds a SOM name to the search node chain. * @param inverseSearch the start point * @param stack the stack with the separated SOM parts * @param unstack the full name */ public static void inverseSearchAdd(HashMap inverseSearch, Stack2 stack, String unstack) { String last = (String)stack.peek(); InverseStore store = (InverseStore)inverseSearch.get(last); if (store == null) { store = new InverseStore(); inverseSearch.put(last, store); } for (int k = stack.size() - 2; k >= 0; --k) { last = (String)stack.get(k); InverseStore store2; int idx = store.part.indexOf(last); if (idx < 0) { store.part.add(last); store2 = new InverseStore(); store.follow.add(store2); } else store2 = (InverseStore)store.follow.get(idx); store = store2; } store.part.add(""); store.follow.add(unstack); } /** * Searches the SOM hierarchy from the bottom. * @param parts the SOM parts * @return the full name or null if not found */ public String inverseSearchGlobal(ArrayList parts) { if (parts.isEmpty()) return null; InverseStore store = (InverseStore)inverseSearch.get(parts.get(parts.size() - 1)); if (store == null) return null; for (int k = parts.size() - 2; k >= 0; --k) { String part = (String)parts.get(k); int idx = store.part.indexOf(part); if (idx < 0) { if (store.isSimilar(part)) return null; return store.getDefaultName(); } store = (InverseStore)store.follow.get(idx); } return store.getDefaultName(); } /** * Splits a SOM name in the individual parts. * @param name the full SOM name * @return the split name */ public static Stack2 splitParts(String name) { while (name.startsWith(".")) name = name.substring(1); Stack2 parts = new Stack2(); int last = 0; int pos = 0; String part; while (true) { pos = last; while (true) { pos = name.indexOf('.', pos); if (pos < 0) break; if (name.charAt(pos - 1) == '\\') ++pos; else break; } if (pos < 0) break; part = name.substring(last, pos); if (!part.endsWith("]")) part += "[0]"; parts.add(part); last = pos + 1; } part = name.substring(last); if (!part.endsWith("]")) part += "[0]"; parts.add(part); return parts; } /** * Gets the order the names appear in the XML, depth first. * @return the order the names appear in the XML, depth first */ public ArrayList getOrder() { return order; } /** * Sets the order the names appear in the XML, depth first * @param order the order the names appear in the XML, depth first */ public void setOrder(ArrayList order) { this.order = order; } /** * Gets the mapping of full names to nodes. * @return the mapping of full names to nodes */ public HashMap getName2Node() { return name2Node; } /** * Sets the mapping of full names to nodes. * @param name2Node the mapping of full names to nodes */ public void setName2Node(HashMap name2Node) { this.name2Node = name2Node; } /** * Gets the data to do a search from the bottom hierarchy. * @return the data to do a search from the bottom hierarchy */ public HashMap getInverseSearch() { return inverseSearch; } /** * Sets the data to do a search from the bottom hierarchy. * @param inverseSearch the data to do a search from the bottom hierarchy */ public void setInverseSearch(HashMap inverseSearch) { this.inverseSearch = inverseSearch; } } /** * Processes the datasets section in the XFA form. */ public static class Xml2SomDatasets extends Xml2Som { /** * Creates a new instance from the datasets node. This expects * not the datasets but the data node that comes below. * @param n the datasets node */ public Xml2SomDatasets(Node n) { order = new ArrayList(); name2Node = new HashMap(); stack = new Stack2(); anform = 0; inverseSearch = new HashMap(); processDatasetsInternal(n); } /** * Inserts a new Node that will match the short name. * @param n the datasets top Node * @param shortName the short name * @return the new Node of the inserted name */ public Node insertNode(Node n, String shortName) { Stack2 stack = splitParts(shortName); org.w3c.dom.Document doc = n.getOwnerDocument(); Node n2 = null; n = n.getFirstChild(); for (int k = 0; k < stack.size(); ++k) { String part = (String)stack.get(k); int idx = part.lastIndexOf('['); String name = part.substring(0, idx); idx = Integer.parseInt(part.substring(idx + 1, part.length() - 1)); int found = -1; for (n2 = n.getFirstChild(); n2 != null; n2 = n2.getNextSibling()) { if (n2.getNodeType() == Node.ELEMENT_NODE) { String s = escapeSom(n2.getLocalName()); if (s.equals(name)) { ++found; if (found == idx) break; } } } for (; found < idx; ++found) { n2 = doc.createElementNS(null, name); n2 = n.appendChild(n2); Node attr = doc.createAttributeNS(XFA_DATA_SCHEMA, "dataNode"); attr.setNodeValue("dataGroup"); n2.getAttributes().setNamedItemNS(attr); } n = n2; } inverseSearchAdd(inverseSearch, stack, shortName); name2Node.put(shortName, n2); order.add(shortName); return n2; } private static boolean hasChildren(Node n) { Node dataNodeN = n.getAttributes().getNamedItemNS(XFA_DATA_SCHEMA, "dataNode"); if (dataNodeN != null) { String dataNode = dataNodeN.getNodeValue(); if ("dataGroup".equals(dataNode)) return true; else if ("dataValue".equals(dataNode)) return false; } if (!n.hasChildNodes()) return false; Node n2 = n.getFirstChild(); while (n2 != null) { if (n2.getNodeType() == Node.ELEMENT_NODE) { return true; } n2 = n2.getNextSibling(); } return false; } private void processDatasetsInternal(Node n) { HashMap ss = new HashMap(); Node n2 = n.getFirstChild(); while (n2 != null) { if (n2.getNodeType() == Node.ELEMENT_NODE) { String s = escapeSom(n2.getLocalName()); Integer i = (Integer)ss.get(s); if (i == null) i = new Integer(0); else i = new Integer(i.intValue() + 1); ss.put(s, i); if (hasChildren(n2)) { stack.push(s + "[" + i.toString() + "]"); processDatasetsInternal(n2); stack.pop(); } else { stack.push(s + "[" + i.toString() + "]"); String unstack = printStack(); order.add(unstack); inverseSearchAdd(unstack); name2Node.put(unstack, n2); stack.pop(); } } n2 = n2.getNextSibling(); } } } /** * A class to process "classic" fields. */ public static class AcroFieldsSearch extends Xml2Som { private HashMap acroShort2LongName; /** * Creates a new instance from a Collection with the full names. * @param items the Collection */ public AcroFieldsSearch(Collection items) { inverseSearch = new HashMap(); acroShort2LongName = new HashMap(); for (Iterator it = items.iterator(); it.hasNext();) { String itemName = (String)it.next(); String itemShort = getShortName(itemName); acroShort2LongName.put(itemShort, itemName); inverseSearchAdd(inverseSearch, splitParts(itemShort), itemName); } } /** * Gets the mapping from short names to long names. A long * name may contain the #subform name part. * @return the mapping from short names to long names */ public HashMap getAcroShort2LongName() { return acroShort2LongName; } /** * Sets the mapping from short names to long names. A long * name may contain the #subform name part. * @param acroShort2LongName the mapping from short names to long names */ public void setAcroShort2LongName(HashMap acroShort2LongName) { this.acroShort2LongName = acroShort2LongName; } } /** * Processes the template section in the XFA form. */ public static class Xml2SomTemplate extends Xml2Som { private boolean dynamicForm; private int templateLevel; /** * Creates a new instance from the datasets node. * @param n the template node */ public Xml2SomTemplate(Node n) { order = new ArrayList(); name2Node = new HashMap(); stack = new Stack2(); anform = 0; templateLevel = 0; inverseSearch = new HashMap(); processTemplate(n, null); } /** * Gets the field type as described in the template section of the XFA. * @param s the exact template name * @return the field type or null if not found */ public String getFieldType(String s) { Node n = (Node)name2Node.get(s); if (n == null) return null; if (n.getLocalName().equals("exclGroup")) return "exclGroup"; Node ui = n.getFirstChild(); while (ui != null) { if (ui.getNodeType() == Node.ELEMENT_NODE && ui.getLocalName().equals("ui")) { break; } ui = ui.getNextSibling(); } if (ui == null) return null; Node type = ui.getFirstChild(); while (type != null) { if (type.getNodeType() == Node.ELEMENT_NODE && !(type.getLocalName().equals("extras") && type.getLocalName().equals("picture"))) { return type.getLocalName(); } type = type.getNextSibling(); } return null; } private void processTemplate(Node n, HashMap ff) { if (ff == null) ff = new HashMap(); HashMap ss = new HashMap(); Node n2 = n.getFirstChild(); while (n2 != null) { if (n2.getNodeType() == Node.ELEMENT_NODE) { String s = n2.getLocalName(); if (s.equals("subform")) { Node name = n2.getAttributes().getNamedItem("name"); String nn = "#subform"; boolean annon = true; if (name != null) { nn = escapeSom(name.getNodeValue()); annon = false; } Integer i; if (annon) { i = new Integer(anform); ++anform; } else { i = (Integer)ss.get(nn); if (i == null) i = new Integer(0); else i = new Integer(i.intValue() + 1); ss.put(nn, i); } stack.push(nn + "[" + i.toString() + "]"); ++templateLevel; if (annon) processTemplate(n2, ff); else processTemplate(n2, null); --templateLevel; stack.pop(); } else if (s.equals("field") || s.equals("exclGroup")) { Node name = n2.getAttributes().getNamedItem("name"); if (name != null) { String nn = escapeSom(name.getNodeValue()); Integer i = (Integer)ff.get(nn); if (i == null) i = new Integer(0); else i = new Integer(i.intValue() + 1); ff.put(nn, i); stack.push(nn + "[" + i.toString() + "]"); String unstack = printStack(); order.add(unstack); inverseSearchAdd(unstack); name2Node.put(unstack, n2); stack.pop(); } } else if (!dynamicForm && templateLevel > 0 && s.equals("occur")) { int initial = 1; int min = 1; int max = 1; Node a = n2.getAttributes().getNamedItem("initial"); if (a != null) try{initial = Integer.parseInt(a.getNodeValue().trim());}catch(Exception e){} a = n2.getAttributes().getNamedItem("min"); if (a != null) try{min = Integer.parseInt(a.getNodeValue().trim());}catch(Exception e){} a = n2.getAttributes().getNamedItem("max"); if (a != null) try{max = Integer.parseInt(a.getNodeValue().trim());}catch(Exception e){} if (initial != min || min != max) dynamicForm = true; } } n2 = n2.getNextSibling(); } } /** * true if it's a dynamic form; false * if it's a static form. * @return true if it's a dynamic form; false * if it's a static form */ public boolean isDynamicForm() { return dynamicForm; } /** * Sets the dynamic form flag. It doesn't change the template. * @param dynamicForm the dynamic form flag */ public void setDynamicForm(boolean dynamicForm) { this.dynamicForm = dynamicForm; } } /** * Gets the class that contains the template processing section of the XFA. * @return the class that contains the template processing section of the XFA */ public Xml2SomTemplate getTemplateSom() { return templateSom; } /** * Sets the class that contains the template processing section of the XFA * @param templateSom the class that contains the template processing section of the XFA */ public void setTemplateSom(Xml2SomTemplate templateSom) { this.templateSom = templateSom; } /** * Gets the class that contains the datasets processing section of the XFA. * @return the class that contains the datasets processing section of the XFA */ public Xml2SomDatasets getDatasetsSom() { return datasetsSom; } /** * Sets the class that contains the datasets processing section of the XFA. * @param datasetsSom the class that contains the datasets processing section of the XFA */ public void setDatasetsSom(Xml2SomDatasets datasetsSom) { this.datasetsSom = datasetsSom; } /** * Gets the class that contains the "classic" fields processing. * @return the class that contains the "classic" fields processing */ public AcroFieldsSearch getAcroFieldsSom() { return acroFieldsSom; } /** * Sets the class that contains the "classic" fields processing. * @param acroFieldsSom the class that contains the "classic" fields processing */ public void setAcroFieldsSom(AcroFieldsSearch acroFieldsSom) { this.acroFieldsSom = acroFieldsSom; } /** * Gets the Node that corresponds to the datasets part. * @return the Node that corresponds to the datasets part */ public Node getDatasetsNode() { return datasetsNode; } } src/core/com/lowagie/text/pdf/XfdfReader.java100644 0 0 17440 11106243445 16571 0ustar 0 0 /* * * Copyright 2004 by Leonard Rosenthol. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; import com.lowagie.text.xml.simpleparser.SimpleXMLParser; /** * Reads a XFDF. * @author Leonard Rosenthol (leonardr@pdfsages.com) */ public class XfdfReader implements SimpleXMLDocHandler { // stuff used during parsing to handle state private boolean foundRoot = false; private Stack fieldNames = new Stack(); private Stack fieldValues = new Stack(); // storage for the field list and their values HashMap fields; /** * Storage for field values if there's more than one value for a field. * @since 2.1.4 */ protected HashMap listFields; // storage for the path to referenced PDF, if any String fileSpec; /** Reads an XFDF form. * @param filename the file name of the form * @throws IOException on error */ public XfdfReader(String filename) throws IOException { FileInputStream fin = null; try { fin = new FileInputStream(filename); SimpleXMLParser.parse(this, fin); } finally { try{if (fin != null) {fin.close();}}catch(Exception e){} } } /** Reads an XFDF form. * @param xfdfIn the byte array with the form * @throws IOException on error */ public XfdfReader(byte xfdfIn[]) throws IOException { SimpleXMLParser.parse( this, new ByteArrayInputStream(xfdfIn)); } /** Gets all the fields. The map is keyed by the fully qualified * field name and the value is a merged PdfDictionary * with the field content. * @return all the fields */ public HashMap getFields() { return fields; } /** Gets the field value. * @param name the fully qualified field name * @return the field's value */ public String getField(String name) { return (String)fields.get(name); } /** Gets the field value or null if the field does not * exist or has no value defined. * @param name the fully qualified field name * @return the field value or null */ public String getFieldValue(String name) { String field = (String)fields.get(name); if (field == null) return null; else return field; } /** * Gets the field values for a list or null if the field does not * exist or has no value defined. * @param name the fully qualified field name * @return the field values or null * @since 2.1.4 */ public List getListValues(String name) { return (List)listFields.get(name); } /** Gets the PDF file specification contained in the FDF. * @return the PDF file specification contained in the FDF */ public String getFileSpec() { return fileSpec; } /** * Called when a start tag is found. * @param tag the tag name * @param h the tag's attributes */ public void startElement(String tag, HashMap h) { if ( !foundRoot ) { if (!tag.equals("xfdf")) throw new RuntimeException("Root element is not Bookmark."); else foundRoot = true; } if ( tag.equals("xfdf") ){ } else if ( tag.equals("f") ) { fileSpec = (String)h.get( "href" ); } else if ( tag.equals("fields") ) { fields = new HashMap(); // init it! listFields = new HashMap(); } else if ( tag.equals("field") ) { String fName = (String) h.get( "name" ); fieldNames.push( fName ); } else if ( tag.equals("value") ) { fieldValues.push( "" ); } } /** * Called when an end tag is found. * @param tag the tag name */ public void endElement(String tag) { if ( tag.equals("value") ) { String fName = ""; for (int k = 0; k < fieldNames.size(); ++k) { fName += "." + (String)fieldNames.elementAt(k); } if (fName.startsWith(".")) fName = fName.substring(1); String fVal = (String) fieldValues.pop(); String old = (String) fields.put( fName, fVal ); if (old != null) { List l = (List) listFields.get(fName); if (l == null) { l = new ArrayList(); l.add(old); } l.add(fVal); listFields.put(fName, l); } } else if (tag.equals("field") ) { if (!fieldNames.isEmpty()) fieldNames.pop(); } } /** * Called when the document starts to be parsed. */ public void startDocument() { fileSpec = ""; } /** * Called after the document is parsed. */ public void endDocument() { } /** * Called when a text element is found. * @param str the text element, probably a fragment. */ public void text(String str) { if (fieldNames.isEmpty() || fieldValues.isEmpty()) return; String val = (String)fieldValues.pop(); val += str; fieldValues.push(val); } }src/core/com/lowagie/text/pdf/codec/Base64.java100644 0 0 204316 11036112746 16701 0ustar 0 0 package com.lowagie.text.pdf.codec; /** *

    Encodes and decodes to and from Base64 notation.

    *

    Homepage: http://iharder.net/base64.

    * *

    * Change Log: *

    *
      *
    • v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug * when using very small files (~< 40 bytes).
    • *
    • v2.2 - Added some helper methods for encoding/decoding directly from * one file to the next. Also added a main() method to support command line * encoding/decoding from one file to the next. Also added these Base64 dialects: *
        *
      1. The default is RFC3548 format.
      2. *
      3. Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates * URL and file name friendly format as described in Section 4 of RFC3548. * http://www.faqs.org/rfcs/rfc3548.html
      4. *
      5. Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates * URL and file name friendly format that preserves lexical ordering as described * in http://www.faqs.org/qa/rfcc-1940.html
      6. *
      * Special thanks to Jim Kellerman at http://www.powerset.com/ * for contributing the new Base64 dialects. *
    • * *
    • v2.1 - Cleaned up javadoc comments and unused variables and methods. Added * some convenience methods for reading and writing to and from files.
    • *
    • v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems * with other encodings (like EBCDIC).
    • *
    • v2.0.1 - Fixed an error when decoding a single byte, that is, when the * encoded data was a single byte.
    • *
    • v2.0 - I got rid of methods that used booleans to set options. * Now everything is more consolidated and cleaner. The code now detects * when data that's being decoded is gzip-compressed and will decompress it * automatically. Generally things are cleaner. You'll probably have to * change some method calls that you were making to support the new * options format (ints that you "OR" together).
    • *
    • v1.5.1 - Fixed bug when decompressing and decoding to a * byte[] using decode( String s, boolean gzipCompressed ). * Added the ability to "suspend" encoding in the Output Stream so * you can turn on and off the encoding if you need to embed base64 * data in an otherwise "normal" stream (like an XML file).
    • *
    • v1.5 - Output stream pases on flush() command but doesn't do anything itself. * This helps when using GZIP streams. * Added the ability to GZip-compress objects before encoding them.
    • *
    • v1.4 - Added helper methods to read/write files.
    • *
    • v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.
    • *
    • v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream * where last buffer being read, if not completely full, was not returned.
    • *
    • v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.
    • *
    • v1.3.3 - Fixed I/O streams which were totally messed up.
    • *
    * *

    * I am placing this code in the Public Domain. Do with it as you will. * This software comes with no guarantees or warranties but with * plenty of well-wishing instead! * Please visit http://iharder.net/base64 * periodically to check for updates or to contribute improvements. *

    * * @author Robert Harder * @author rob@iharder.net * @version 2.2.1 */ public class Base64 { /* ******** P U B L I C F I E L D S ******** */ /** No options specified. Value is zero. */ public final static int NO_OPTIONS = 0; /** Specify encoding. */ public final static int ENCODE = 1; /** Specify decoding. */ public final static int DECODE = 0; /** Specify that data should be gzip-compressed. */ public final static int GZIP = 2; /** Don't break lines when encoding (violates strict Base64 specification) */ public final static int DONT_BREAK_LINES = 8; /** * Encode using Base64-like encoding that is URL- and Filename-safe as described * in Section 4 of RFC3548: * http://www.faqs.org/rfcs/rfc3548.html. * It is important to note that data encoded this way is not officially valid Base64, * or at the very least should not be called Base64 without also specifying that is * was encoded using the URL- and Filename-safe dialect. */ public final static int URL_SAFE = 16; /** * Encode using the special "ordered" dialect of Base64 described here: * http://www.faqs.org/qa/rfcc-1940.html. */ public final static int ORDERED = 32; /* ******** P R I V A T E F I E L D S ******** */ /** Maximum line length (76) of Base64 output. */ private final static int MAX_LINE_LENGTH = 76; /** The equals sign (=) as a byte. */ private final static byte EQUALS_SIGN = (byte)'='; /** The new line character (\n) as a byte. */ private final static byte NEW_LINE = (byte)'\n'; /** Preferred encoding. */ private final static String PREFERRED_ENCODING = "UTF-8"; // I think I end up not using the BAD_ENCODING indicator. //private final static byte BAD_ENCODING = -9; // Indicates error in encoding private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ /** The 64 valid Base64 values. */ //private final static byte[] ALPHABET; /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ private final static byte[] _STANDARD_ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' }; /** * Translates a Base64 value to either its 6-bit reconstruction value * or a negative number indicating some other meaning. **/ private final static byte[] _STANDARD_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 62, // Plus sign at decimal 43 -9,-9,-9, // Decimal 44 - 46 63, // Slash at decimal 47 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' -9,-9,-9,-9 // Decimal 123 - 126 /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ }; /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ /** * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: * http://www.faqs.org/rfcs/rfc3548.html. * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash." */ private final static byte[] _URL_SAFE_ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_' }; /** * Used in decoding URL- and Filename-safe dialects of Base64. */ private final static byte[] _URL_SAFE_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 -9, // Plus sign at decimal 43 -9, // Decimal 44 62, // Minus sign at decimal 45 -9, // Decimal 46 -9, // Slash at decimal 47 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' -9,-9,-9,-9, // Decimal 91 - 94 63, // Underscore at decimal 95 -9, // Decimal 96 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' -9,-9,-9,-9 // Decimal 123 - 126 /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ }; /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ /** * I don't get the point of this technique, but it is described here: * http://www.faqs.org/qa/rfcc-1940.html. */ private final static byte[] _ORDERED_ALPHABET = { (byte)'-', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'_', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z' }; /** * Used in decoding the "ordered" dialect of Base64. */ private final static byte[] _ORDERED_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 -9, // Plus sign at decimal 43 -9, // Decimal 44 0, // Minus sign at decimal 45 -9, // Decimal 46 -9, // Slash at decimal 47 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' -9,-9,-9,-9, // Decimal 91 - 94 37, // Underscore at decimal 95 -9, // Decimal 96 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' -9,-9,-9,-9 // Decimal 123 - 126 /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ }; /* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ /** * Returns one of the _SOMETHING_ALPHABET byte arrays depending on * the options specified. * It's possible, though silly, to specify ORDERED and URLSAFE * in which case one of them will be picked, though there is * no guarantee as to which one will be picked. */ private final static byte[] getAlphabet( int options ) { if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_ALPHABET; else if( (options & ORDERED) == ORDERED ) return _ORDERED_ALPHABET; else return _STANDARD_ALPHABET; } // end getAlphabet /** * Returns one of the _SOMETHING_DECODABET byte arrays depending on * the options specified. * It's possible, though silly, to specify ORDERED and URL_SAFE * in which case one of them will be picked, though there is * no guarantee as to which one will be picked. */ private final static byte[] getDecodabet( int options ) { if( (options & URL_SAFE) == URL_SAFE ) return _URL_SAFE_DECODABET; else if( (options & ORDERED) == ORDERED ) return _ORDERED_DECODABET; else return _STANDARD_DECODABET; } // end getAlphabet /** Defeats instantiation. */ private Base64(){} /** * Encodes or decodes two files from the command line; * feel free to delete this method (in fact you probably should) * if you're embedding this code into a larger program. */ public final static void main( String[] args ) { if( args.length < 3 ){ usage("Not enough arguments."); } // end if: args.length < 3 else { String flag = args[0]; String infile = args[1]; String outfile = args[2]; if( flag.equals( "-e" ) ){ Base64.encodeFileToFile( infile, outfile ); } // end if: encode else if( flag.equals( "-d" ) ) { Base64.decodeFileToFile( infile, outfile ); } // end else if: decode else { usage( "Unknown flag: " + flag ); } // end else } // end else } // end main /** * Prints command line usage. * * @param msg A message to include with usage info. */ private final static void usage( String msg ) { System.err.println( msg ); System.err.println( "Usage: java Base64 -e|-d inputfile outputfile" ); } // end usage /* ******** E N C O D I N G M E T H O D S ******** */ /** * Encodes up to the first three bytes of array threeBytes * and returns a four-byte array in Base64 notation. * The actual number of significant bytes in your array is * given by numSigBytes. * The array threeBytes needs only be as big as * numSigBytes. * Code can reuse a byte array by passing a four-byte array as b4. * * @param b4 A reusable byte array to reduce array instantiation * @param threeBytes the array to convert * @param numSigBytes the number of significant bytes in your array * @return four byte array in Base64 notation. * @since 1.5.1 */ private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) { encode3to4( threeBytes, 0, numSigBytes, b4, 0, options ); return b4; } // end encode3to4 /** *

    Encodes up to three bytes of the array source * and writes the resulting four Base64 bytes to destination. * The source and destination arrays can be manipulated * anywhere along their length by specifying * srcOffset and destOffset. * This method does not check to make sure your arrays * are large enough to accomodate srcOffset + 3 for * the source array or destOffset + 4 for * the destination array. * The actual number of significant bytes in your array is * given by numSigBytes.

    *

    This is the lowest level of the encoding methods with * all possible parameters.

    * * @param source the array to convert * @param srcOffset the index where conversion begins * @param numSigBytes the number of significant bytes in your array * @param destination the array to hold the conversion * @param destOffset the index where output will be put * @return the destination array * @since 1.3 */ private static byte[] encode3to4( byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset, int options ) { byte[] ALPHABET = getAlphabet( options ); // 1 2 3 // 01234567890123456789012345678901 Bit position // --------000000001111111122222222 Array position from threeBytes // --------| || || || | Six bit groups to index ALPHABET // >>18 >>12 >> 6 >> 0 Right shift necessary // 0x3f 0x3f 0x3f Additional AND // Create buffer with zero-padding if there are only one or two // significant bytes passed in the array. // We have to shift left 24 in order to flush out the 1's that appear // when Java treats a value as negative that is cast from a byte to an int. int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); switch( numSigBytes ) { case 3: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; return destination; case 2: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; destination[ destOffset + 3 ] = EQUALS_SIGN; return destination; case 1: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = EQUALS_SIGN; destination[ destOffset + 3 ] = EQUALS_SIGN; return destination; default: return destination; } // end switch } // end encode3to4 /** * Serializes an object and returns the Base64-encoded * version of that serialized object. If the object * cannot be serialized or there is another error, * the method will return null. * The object is not GZip-compressed before being encoded. * * @param serializableObject The object to encode * @return The Base64-encoded object * @since 1.4 */ public static String encodeObject( java.io.Serializable serializableObject ) { return encodeObject( serializableObject, NO_OPTIONS ); } // end encodeObject /** * Serializes an object and returns the Base64-encoded * version of that serialized object. If the object * cannot be serialized or there is another error, * the method will return null. *

    * Valid options:

         *   GZIP: gzip-compresses object before encoding it.
         *   DONT_BREAK_LINES: don't break lines at 76 characters
         *     Note: Technically, this makes your encoding non-compliant.
         * 
    *

    * Example: encodeObject( myObj, Base64.GZIP ) or *

    * Example: encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES ) * * @param serializableObject The object to encode * @param options Specified options * @return The Base64-encoded object * @see Base64#GZIP * @see Base64#DONT_BREAK_LINES * @since 2.0 */ public static String encodeObject( java.io.Serializable serializableObject, int options ) { // Streams java.io.ByteArrayOutputStream baos = null; java.io.OutputStream b64os = null; java.io.ObjectOutputStream oos = null; java.util.zip.GZIPOutputStream gzos = null; // Isolate options int gzip = (options & GZIP); int dontBreakLines = (options & DONT_BREAK_LINES); try { // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); b64os = new Base64.OutputStream( baos, ENCODE | options ); // GZip? if( gzip == GZIP ) { gzos = new java.util.zip.GZIPOutputStream( b64os ); oos = new java.io.ObjectOutputStream( gzos ); } // end if: gzip else oos = new java.io.ObjectOutputStream( b64os ); oos.writeObject( serializableObject ); } // end try catch( java.io.IOException e ) { e.printStackTrace(); return null; } // end catch finally { try{ oos.close(); } catch( Exception e ){} try{ gzos.close(); } catch( Exception e ){} try{ b64os.close(); } catch( Exception e ){} try{ baos.close(); } catch( Exception e ){} } // end finally // Return value according to relevant encoding. try { return new String( baos.toByteArray(), PREFERRED_ENCODING ); } // end try catch (java.io.UnsupportedEncodingException uue) { return new String( baos.toByteArray() ); } // end catch } // end encode /** * Encodes a byte array into Base64 notation. * Does not GZip-compress data. * * @param source The data to convert * @since 1.4 */ public static String encodeBytes( byte[] source ) { return encodeBytes( source, 0, source.length, NO_OPTIONS ); } // end encodeBytes /** * Encodes a byte array into Base64 notation. *

    * Valid options:

         *   GZIP: gzip-compresses object before encoding it.
         *   DONT_BREAK_LINES: don't break lines at 76 characters
         *     Note: Technically, this makes your encoding non-compliant.
         * 
    *

    * Example: encodeBytes( myData, Base64.GZIP ) or *

    * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) * * * @param source The data to convert * @param options Specified options * @see Base64#GZIP * @see Base64#DONT_BREAK_LINES * @since 2.0 */ public static String encodeBytes( byte[] source, int options ) { return encodeBytes( source, 0, source.length, options ); } // end encodeBytes /** * Encodes a byte array into Base64 notation. * Does not GZip-compress data. * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @since 1.4 */ public static String encodeBytes( byte[] source, int off, int len ) { return encodeBytes( source, off, len, NO_OPTIONS ); } // end encodeBytes /** * Encodes a byte array into Base64 notation. *

    * Valid options:

         *   GZIP: gzip-compresses object before encoding it.
         *   DONT_BREAK_LINES: don't break lines at 76 characters
         *     Note: Technically, this makes your encoding non-compliant.
         * 
    *

    * Example: encodeBytes( myData, Base64.GZIP ) or *

    * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) * * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @param options Specified options * alphabet type is pulled from this (standard, url-safe, ordered) * @see Base64#GZIP * @see Base64#DONT_BREAK_LINES * @since 2.0 */ public static String encodeBytes( byte[] source, int off, int len, int options ) { // Isolate options int dontBreakLines = ( options & DONT_BREAK_LINES ); int gzip = ( options & GZIP ); // Compress? if( gzip == GZIP ) { java.io.ByteArrayOutputStream baos = null; java.util.zip.GZIPOutputStream gzos = null; Base64.OutputStream b64os = null; try { // GZip -> Base64 -> ByteArray baos = new java.io.ByteArrayOutputStream(); b64os = new Base64.OutputStream( baos, ENCODE | options ); gzos = new java.util.zip.GZIPOutputStream( b64os ); gzos.write( source, off, len ); gzos.close(); } // end try catch( java.io.IOException e ) { e.printStackTrace(); return null; } // end catch finally { try{ gzos.close(); } catch( Exception e ){} try{ b64os.close(); } catch( Exception e ){} try{ baos.close(); } catch( Exception e ){} } // end finally // Return value according to relevant encoding. try { return new String( baos.toByteArray(), PREFERRED_ENCODING ); } // end try catch (java.io.UnsupportedEncodingException uue) { return new String( baos.toByteArray() ); } // end catch } // end if: compress // Else, don't compress. Better not to use streams at all then. else { // Convert option to boolean in way that code likes it. boolean breakLines = dontBreakLines == 0; int len43 = len * 4 / 3; byte[] outBuff = new byte[ ( len43 ) // Main 4:3 + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines int d = 0; int e = 0; int len2 = len - 2; int lineLength = 0; for( ; d < len2; d+=3, e+=4 ) { encode3to4( source, d+off, 3, outBuff, e, options ); lineLength += 4; if( breakLines && lineLength == MAX_LINE_LENGTH ) { outBuff[e+4] = NEW_LINE; e++; lineLength = 0; } // end if: end of line } // en dfor: each piece of array if( d < len ) { encode3to4( source, d+off, len - d, outBuff, e, options ); e += 4; } // end if: some padding needed // Return value according to relevant encoding. try { return new String( outBuff, 0, e, PREFERRED_ENCODING ); } // end try catch (java.io.UnsupportedEncodingException uue) { return new String( outBuff, 0, e ); } // end catch } // end else: don't compress } // end encodeBytes /* ******** D E C O D I N G M E T H O D S ******** */ /** * Decodes four bytes from array source * and writes the resulting bytes (up to three of them) * to destination. * The source and destination arrays can be manipulated * anywhere along their length by specifying * srcOffset and destOffset. * This method does not check to make sure your arrays * are large enough to accomodate srcOffset + 4 for * the source array or destOffset + 3 for * the destination array. * This method returns the actual number of bytes that * were converted from the Base64 encoding. *

    This is the lowest level of the decoding methods with * all possible parameters.

    * * * @param source the array to convert * @param srcOffset the index where conversion begins * @param destination the array to hold the conversion * @param destOffset the index where output will be put * @param options alphabet type is pulled from this (standard, url-safe, ordered) * @return the number of decoded bytes converted * @since 1.3 */ private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options ) { byte[] DECODABET = getDecodabet( options ); // Example: Dk== if( source[ srcOffset + 2] == EQUALS_SIGN ) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); return 1; } // Example: DkL= else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); return 2; } // Example: DkLE else { try{ // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); destination[ destOffset ] = (byte)( outBuff >> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); destination[ destOffset + 2 ] = (byte)( outBuff ); return 3; }catch( Exception e){ System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); return -1; } // end catch } } // end decodeToBytes /** * Very low-level access to decoding ASCII characters in * the form of a byte array. Does not support automatically * gunzipping or any other "fancy" features. * * @param source The Base64 encoded data * @param off The offset of where to begin decoding * @param len The length of characters to decode * @return decoded data * @since 1.3 */ public static byte[] decode( byte[] source, int off, int len, int options ) { byte[] DECODABET = getDecodabet( options ); int len34 = len * 3 / 4; byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output int outBuffPosn = 0; byte[] b4 = new byte[4]; int b4Posn = 0; int i = 0; byte sbiCrop = 0; byte sbiDecode = 0; for( i = off; i < off+len; i++ ) { sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits sbiDecode = DECODABET[ sbiCrop ]; if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better { if( sbiDecode >= EQUALS_SIGN_ENC ) { b4[ b4Posn++ ] = sbiCrop; if( b4Posn > 3 ) { outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); b4Posn = 0; // If that was the equals sign, break out of 'for' loop if( sbiCrop == EQUALS_SIGN ) break; } // end if: quartet built } // end if: equals sign or better } // end if: white space, equals sign or better else { System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); return null; } // end else: } // each input character byte[] out = new byte[ outBuffPosn ]; System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); return out; } // end decode /** * Decodes data from Base64 notation, automatically * detecting gzip-compressed data and decompressing it. * * @param s the string to decode * @return the decoded data * @since 1.4 */ public static byte[] decode( String s ) { return decode( s, NO_OPTIONS ); } /** * Decodes data from Base64 notation, automatically * detecting gzip-compressed data and decompressing it. * * @param s the string to decode * @param options encode options such as URL_SAFE * @return the decoded data * @since 1.4 */ public static byte[] decode( String s, int options ) { byte[] bytes; try { bytes = s.getBytes( PREFERRED_ENCODING ); } // end try catch( java.io.UnsupportedEncodingException uee ) { bytes = s.getBytes(); } // end catch // // Decode bytes = decode( bytes, 0, bytes.length, options ); // Check to see if it's gzip-compressed // GZIP Magic Two-Byte Number: 0x8b1f (35615) if( bytes != null && bytes.length >= 4 ) { int head = (bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) { java.io.ByteArrayInputStream bais = null; java.util.zip.GZIPInputStream gzis = null; java.io.ByteArrayOutputStream baos = null; byte[] buffer = new byte[2048]; int length = 0; try { baos = new java.io.ByteArrayOutputStream(); bais = new java.io.ByteArrayInputStream( bytes ); gzis = new java.util.zip.GZIPInputStream( bais ); while( ( length = gzis.read( buffer ) ) >= 0 ) { baos.write(buffer,0,length); } // end while: reading input // No error? Get new bytes. bytes = baos.toByteArray(); } // end try catch( java.io.IOException e ) { // Just return originally-decoded bytes } // end catch finally { try{ baos.close(); } catch( Exception e ){} try{ gzis.close(); } catch( Exception e ){} try{ bais.close(); } catch( Exception e ){} } // end finally } // end if: gzipped } // end if: bytes.length >= 2 return bytes; } // end decode /** * Attempts to decode Base64 data and deserialize a Java * Object within. Returns null if there was an error. * * @param encodedObject The Base64 data to decode * @return The decoded and deserialized object * @since 1.5 */ public static Object decodeToObject( String encodedObject ) { // Decode and gunzip if necessary byte[] objBytes = decode( encodedObject ); java.io.ByteArrayInputStream bais = null; java.io.ObjectInputStream ois = null; Object obj = null; try { bais = new java.io.ByteArrayInputStream( objBytes ); ois = new java.io.ObjectInputStream( bais ); obj = ois.readObject(); } // end try catch( java.io.IOException e ) { e.printStackTrace(); } // end catch catch( java.lang.ClassNotFoundException e ) { e.printStackTrace(); } // end catch finally { try{ bais.close(); } catch( Exception e ){} try{ ois.close(); } catch( Exception e ){} } // end finally return obj; } // end decodeObject /** * Convenience method for encoding data to a file. * * @param dataToEncode byte array of data to encode in base64 form * @param filename Filename for saving encoded data * @return true if successful, false otherwise * * @since 2.1 */ public static boolean encodeToFile( byte[] dataToEncode, String filename ) { boolean success = false; Base64.OutputStream bos = null; try { bos = new Base64.OutputStream( new java.io.FileOutputStream( filename ), Base64.ENCODE ); bos.write( dataToEncode ); success = true; } // end try catch( java.io.IOException e ) { success = false; } // end catch: IOException finally { try{ bos.close(); } catch( Exception e ){} } // end finally return success; } // end encodeToFile /** * Convenience method for decoding data to a file. * * @param dataToDecode Base64-encoded data as a string * @param filename Filename for saving decoded data * @return true if successful, false otherwise * * @since 2.1 */ public static boolean decodeToFile( String dataToDecode, String filename ) { boolean success = false; Base64.OutputStream bos = null; try { bos = new Base64.OutputStream( new java.io.FileOutputStream( filename ), Base64.DECODE ); bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); success = true; } // end try catch( java.io.IOException e ) { success = false; } // end catch: IOException finally { try{ bos.close(); } catch( Exception e ){} } // end finally return success; } // end decodeToFile /** * Convenience method for reading a base64-encoded * file and decoding it. * * @param filename Filename for reading encoded data * @return decoded byte array or null if unsuccessful * * @since 2.1 */ public static byte[] decodeFromFile( String filename ) { byte[] decodedData = null; Base64.InputStream bis = null; try { // Set up some useful variables java.io.File file = new java.io.File( filename ); byte[] buffer = null; int length = 0; int numBytes = 0; // Check for size of file if( file.length() > Integer.MAX_VALUE ) { System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." ); return null; } // end if: file too big for int index buffer = new byte[ (int)file.length() ]; // Open a stream bis = new Base64.InputStream( new java.io.BufferedInputStream( new java.io.FileInputStream( file ) ), Base64.DECODE ); // Read until done while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) length += numBytes; // Save in a variable to return decodedData = new byte[ length ]; System.arraycopy( buffer, 0, decodedData, 0, length ); } // end try catch( java.io.IOException e ) { System.err.println( "Error decoding from file " + filename ); } // end catch: IOException finally { try{ bis.close(); } catch( Exception e) {} } // end finally return decodedData; } // end decodeFromFile /** * Convenience method for reading a binary file * and base64-encoding it. * * @param filename Filename for reading binary data * @return base64-encoded string or null if unsuccessful * * @since 2.1 */ public static String encodeFromFile( String filename ) { String encodedData = null; Base64.InputStream bis = null; try { // Set up some useful variables java.io.File file = new java.io.File( filename ); byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4),40) ]; // Need max() for math on small files (v2.2.1) int length = 0; int numBytes = 0; // Open a stream bis = new Base64.InputStream( new java.io.BufferedInputStream( new java.io.FileInputStream( file ) ), Base64.ENCODE ); // Read until done while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) length += numBytes; // Save in a variable to return encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); } // end try catch( java.io.IOException e ) { System.err.println( "Error encoding from file " + filename ); } // end catch: IOException finally { try{ bis.close(); } catch( Exception e) {} } // end finally return encodedData; } // end encodeFromFile /** * Reads infile and encodes it to outfile. * * @param infile Input file * @param outfile Output file * @since 2.2 */ public static void encodeFileToFile( String infile, String outfile ) { String encoded = Base64.encodeFromFile( infile ); java.io.OutputStream out = null; try{ out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output. } // end try catch( java.io.IOException ex ) { ex.printStackTrace(); } // end catch finally { try { out.close(); } catch( Exception ex ){} } // end finally } // end encodeFileToFile /** * Reads infile and decodes it to outfile. * * @param infile Input file * @param outfile Output file * @since 2.2 */ public static void decodeFileToFile( String infile, String outfile ) { byte[] decoded = Base64.decodeFromFile( infile ); java.io.OutputStream out = null; try{ out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); out.write( decoded ); } // end try catch( java.io.IOException ex ) { ex.printStackTrace(); } // end catch finally { try { out.close(); } catch( Exception ex ){} } // end finally } // end decodeFileToFile /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ /** * A {@link Base64.InputStream} will read data from another * java.io.InputStream, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 * @since 1.3 */ public static class InputStream extends java.io.FilterInputStream { private boolean encode; // Encoding or decoding private int position; // Current position in the buffer private byte[] buffer; // Small buffer holding converted data private int bufferLength; // Length of buffer (3 or 4) private int numSigBytes; // Number of meaningful bytes in the buffer private int lineLength; private boolean breakLines; // Break lines at less than 80 characters private int options; // Record options used to create the stream. private byte[] alphabet; // Local copies to avoid extra method calls private byte[] decodabet; // Local copies to avoid extra method calls /** * Constructs a {@link Base64.InputStream} in DECODE mode. * * @param in the java.io.InputStream from which to read data. * @since 1.3 */ public InputStream( java.io.InputStream in ) { this( in, DECODE ); } // end constructor /** * Constructs a {@link Base64.InputStream} in * either ENCODE or DECODE mode. *

    * Valid options:

             *   ENCODE or DECODE: Encode or Decode as data is read.
             *   DONT_BREAK_LINES: don't break lines at 76 characters
             *     (only meaningful when encoding)
             *     Note: Technically, this makes your encoding non-compliant.
             * 
    *

    * Example: new Base64.InputStream( in, Base64.DECODE ) * * * @param in the java.io.InputStream from which to read data. * @param options Specified options * @see Base64#ENCODE * @see Base64#DECODE * @see Base64#DONT_BREAK_LINES * @since 2.0 */ public InputStream( java.io.InputStream in, int options ) { super( in ); this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; this.encode = (options & ENCODE) == ENCODE; this.bufferLength = encode ? 4 : 3; this.buffer = new byte[ bufferLength ]; this.position = -1; this.lineLength = 0; this.options = options; // Record for later, mostly to determine which alphabet to use this.alphabet = getAlphabet(options); this.decodabet = getDecodabet(options); } // end constructor /** * Reads enough of the input stream to convert * to/from Base64 and returns the next byte. * * @return next byte * @since 1.3 */ public int read() throws java.io.IOException { // Do we need to get data? if( position < 0 ) { if( encode ) { byte[] b3 = new byte[3]; int numBinaryBytes = 0; for( int i = 0; i < 3; i++ ) { try { int b = in.read(); // If end of stream, b is -1. if( b >= 0 ) { b3[i] = (byte)b; numBinaryBytes++; } // end if: not end of stream } // end try: read catch( java.io.IOException e ) { // Only a problem if we got no data at all. if( i == 0 ) throw e; } // end catch } // end for: each needed input byte if( numBinaryBytes > 0 ) { encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); position = 0; numSigBytes = 4; } // end if: got data else { return -1; } // end else } // end if: encoding // Else decoding else { byte[] b4 = new byte[4]; int i = 0; for( i = 0; i < 4; i++ ) { // Read four "meaningful" bytes: int b = 0; do{ b = in.read(); } while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); if( b < 0 ) break; // Reads a -1 if end of stream b4[i] = (byte)b; } // end for: each needed input byte if( i == 4 ) { numSigBytes = decode4to3( b4, 0, buffer, 0, options ); position = 0; } // end if: got four characters else if( i == 0 ){ return -1; } // end else if: also padded correctly else { // Must have broken out from above. throw new java.io.IOException( "Improperly padded Base64 input." ); } // end } // end else: decode } // end else: get data // Got data? if( position >= 0 ) { // End of relevant data? if( /*!encode &&*/ position >= numSigBytes ) return -1; if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) { lineLength = 0; return '\n'; } // end if else { lineLength++; // This isn't important when decoding // but throwing an extra "if" seems // just as wasteful. int b = buffer[ position++ ]; if( position >= bufferLength ) position = -1; return b & 0xFF; // This is how you "cast" a byte that's // intended to be unsigned. } // end else } // end if: position >= 0 // Else error else { // When JDK1.4 is more accepted, use an assertion here. throw new java.io.IOException( "Error in Base64 code reading stream." ); } // end else } // end read /** * Calls {@link #read()} repeatedly until the end of stream * is reached or len bytes are read. * Returns number of bytes read into array or -1 if * end of stream is encountered. * * @param dest array to hold values * @param off offset for array * @param len max number of bytes to read into array * @return bytes read into array or -1 if end of stream is encountered. * @since 1.3 */ public int read( byte[] dest, int off, int len ) throws java.io.IOException { int i; int b; for( i = 0; i < len; i++ ) { b = read(); //if( b < 0 && i == 0 ) // return -1; if( b >= 0 ) dest[off + i] = (byte)b; else if( i == 0 ) return -1; else break; // Out of 'for' loop } // end for: each byte read return i; } // end read } // end inner class InputStream /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ /** * A {@link Base64.OutputStream} will write data to another * java.io.OutputStream, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 * @since 1.3 */ public static class OutputStream extends java.io.FilterOutputStream { private boolean encode; private int position; private byte[] buffer; private int bufferLength; private int lineLength; private boolean breakLines; private byte[] b4; // Scratch used in a few places private boolean suspendEncoding; private int options; // Record for later private byte[] alphabet; // Local copies to avoid extra method calls private byte[] decodabet; // Local copies to avoid extra method calls /** * Constructs a {@link Base64.OutputStream} in ENCODE mode. * * @param out the java.io.OutputStream to which data will be written. * @since 1.3 */ public OutputStream( java.io.OutputStream out ) { this( out, ENCODE ); } // end constructor /** * Constructs a {@link Base64.OutputStream} in * either ENCODE or DECODE mode. *

    * Valid options:

             *   ENCODE or DECODE: Encode or Decode as data is read.
             *   DONT_BREAK_LINES: don't break lines at 76 characters
             *     (only meaningful when encoding)
             *     Note: Technically, this makes your encoding non-compliant.
             * 
    *

    * Example: new Base64.OutputStream( out, Base64.ENCODE ) * * @param out the java.io.OutputStream to which data will be written. * @param options Specified options. * @see Base64#ENCODE * @see Base64#DECODE * @see Base64#DONT_BREAK_LINES * @since 1.3 */ public OutputStream( java.io.OutputStream out, int options ) { super( out ); this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; this.encode = (options & ENCODE) == ENCODE; this.bufferLength = encode ? 3 : 4; this.buffer = new byte[ bufferLength ]; this.position = 0; this.lineLength = 0; this.suspendEncoding = false; this.b4 = new byte[4]; this.options = options; this.alphabet = getAlphabet(options); this.decodabet = getDecodabet(options); } // end constructor /** * Writes the byte to the output stream after * converting to/from Base64 notation. * When encoding, bytes are buffered three * at a time before the output stream actually * gets a write() call. * When decoding, bytes are buffered four * at a time. * * @param theByte the byte to write * @since 1.3 */ public void write(int theByte) throws java.io.IOException { // Encoding suspended? if( suspendEncoding ) { super.out.write( theByte ); return; } // end if: supsended // Encode? if( encode ) { buffer[ position++ ] = (byte)theByte; if( position >= bufferLength ) // Enough to encode. { out.write( encode3to4( b4, buffer, bufferLength, options ) ); lineLength += 4; if( breakLines && lineLength >= MAX_LINE_LENGTH ) { out.write( NEW_LINE ); lineLength = 0; } // end if: end of line position = 0; } // end if: enough to output } // end if: encoding // Else, Decoding else { // Meaningful Base64 character? if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) { buffer[ position++ ] = (byte)theByte; if( position >= bufferLength ) // Enough to output. { int len = Base64.decode4to3( buffer, 0, b4, 0, options ); out.write( b4, 0, len ); //out.write( Base64.decode4to3( buffer ) ); position = 0; } // end if: enough to output } // end if: meaningful base64 character else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) { throw new java.io.IOException( "Invalid character in Base64 data." ); } // end else: not white space either } // end else: decoding } // end write /** * Calls {@link #write(int)} repeatedly until len * bytes are written. * * @param theBytes array from which to read bytes * @param off offset for array * @param len max number of bytes to read into array * @since 1.3 */ public void write( byte[] theBytes, int off, int len ) throws java.io.IOException { // Encoding suspended? if( suspendEncoding ) { super.out.write( theBytes, off, len ); return; } // end if: supsended for( int i = 0; i < len; i++ ) { write( theBytes[ off + i ] ); } // end for: each byte written } // end write /** * Method added by PHIL. [Thanks, PHIL. -Rob] * This pads the buffer without closing the stream. */ public void flushBase64() throws java.io.IOException { if( position > 0 ) { if( encode ) { out.write( encode3to4( b4, buffer, position, options ) ); position = 0; } // end if: encoding else { throw new java.io.IOException( "Base64 input not properly padded." ); } // end else: decoding } // end if: buffer partially full } // end flush /** * Flushes and closes (I think, in the superclass) the stream. * * @since 1.3 */ public void close() throws java.io.IOException { // 1. Ensure that pending characters are written flushBase64(); // 2. Actually close the stream // Base class both flushes and closes. super.close(); buffer = null; out = null; } // end close /** * Suspends encoding of the stream. * May be helpful if you need to embed a piece of * base640-encoded data in a stream. * * @since 1.5.1 */ public void suspendEncoding() throws java.io.IOException { flushBase64(); this.suspendEncoding = true; } // end suspendEncoding /** * Resumes encoding of the stream. * May be helpful if you need to embed a piece of * base640-encoded data in a stream. * * @since 1.5.1 */ public void resumeEncoding() { this.suspendEncoding = false; } // end resumeEncoding } // end inner class OutputStream } // end class Base64 src/core/com/lowagie/text/pdf/codec/BmpImage.java100644 0 0 140505 11036112746 17335 0ustar 0 0 /* * Copyright 2003-2008 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageioimpl.plugins.bmp.BMPImageReader.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import com.lowagie.text.BadElementException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgRaw; import com.lowagie.text.Utilities; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfString; /** Reads a BMP image. All types of BMP can be read. *

    * It is based in the JAI codec. * * @author Paulo Soares (psoares@consiste.pt) */ public class BmpImage { // BMP variables private InputStream inputStream; private long bitmapFileSize; private long bitmapOffset; private long compression; private long imageSize; private byte palette[]; private int imageType; private int numBands; private boolean isBottomUp; private int bitsPerPixel; private int redMask, greenMask, blueMask, alphaMask; public HashMap properties = new HashMap(); private long xPelsPerMeter; private long yPelsPerMeter; // BMP Image types private static final int VERSION_2_1_BIT = 0; private static final int VERSION_2_4_BIT = 1; private static final int VERSION_2_8_BIT = 2; private static final int VERSION_2_24_BIT = 3; private static final int VERSION_3_1_BIT = 4; private static final int VERSION_3_4_BIT = 5; private static final int VERSION_3_8_BIT = 6; private static final int VERSION_3_24_BIT = 7; private static final int VERSION_3_NT_16_BIT = 8; private static final int VERSION_3_NT_32_BIT = 9; private static final int VERSION_4_1_BIT = 10; private static final int VERSION_4_4_BIT = 11; private static final int VERSION_4_8_BIT = 12; private static final int VERSION_4_16_BIT = 13; private static final int VERSION_4_24_BIT = 14; private static final int VERSION_4_32_BIT = 15; // Color space types private static final int LCS_CALIBRATED_RGB = 0; private static final int LCS_sRGB = 1; private static final int LCS_CMYK = 2; // Compression Types private static final int BI_RGB = 0; private static final int BI_RLE8 = 1; private static final int BI_RLE4 = 2; private static final int BI_BITFIELDS = 3; int width; int height; BmpImage(InputStream is, boolean noHeader, int size) throws IOException { bitmapFileSize = size; bitmapOffset = 0; process(is, noHeader); } /** Reads a BMP from an url. * @param url the url * @throws IOException on error * @return the image */ public static Image getImage(URL url) throws IOException { InputStream is = null; try { is = url.openStream(); Image img = getImage(is); img.setUrl(url); return img; } finally { if (is != null) { is.close(); } } } /** Reads a BMP from a stream. The stream is not closed. * @param is the stream * @throws IOException on error * @return the image */ public static Image getImage(InputStream is) throws IOException { return getImage(is, false, 0); } /** Reads a BMP from a stream. The stream is not closed. * The BMP may not have a header and be considered as a plain DIB. * @param is the stream * @param noHeader true to process a plain DIB * @param size the size of the DIB. Not used for a BMP * @throws IOException on error * @return the image */ public static Image getImage(InputStream is, boolean noHeader, int size) throws IOException { BmpImage bmp = new BmpImage(is, noHeader, size); try { Image img = bmp.getImage(); img.setDpi((int)(bmp.xPelsPerMeter * 0.0254d + 0.5d), (int)(bmp.yPelsPerMeter * 0.0254d + 0.5d)); img.setOriginalType(Image.ORIGINAL_BMP); return img; } catch (BadElementException be) { throw new ExceptionConverter(be); } } /** Reads a BMP from a file. * @param file the file * @throws IOException on error * @return the image */ public static Image getImage(String file) throws IOException { return getImage(Utilities.toURL(file)); } /** Reads a BMP from a byte array. * @param data the byte array * @throws IOException on error * @return the image */ public static Image getImage(byte data[]) throws IOException { ByteArrayInputStream is = new ByteArrayInputStream(data); Image img = getImage(is); img.setOriginalData(data); return img; } protected void process(InputStream stream, boolean noHeader) throws IOException { if (noHeader || stream instanceof BufferedInputStream) { inputStream = stream; } else { inputStream = new BufferedInputStream(stream); } if (!noHeader) { // Start File Header if (!(readUnsignedByte(inputStream) == 'B' && readUnsignedByte(inputStream) == 'M')) { throw new RuntimeException("Invalid magic value for BMP file."); } // Read file size bitmapFileSize = readDWord(inputStream); // Read the two reserved fields readWord(inputStream); readWord(inputStream); // Offset to the bitmap from the beginning bitmapOffset = readDWord(inputStream); // End File Header } // Start BitmapCoreHeader long size = readDWord(inputStream); if (size == 12) { width = readWord(inputStream); height = readWord(inputStream); } else { width = readLong(inputStream); height = readLong(inputStream); } int planes = readWord(inputStream); bitsPerPixel = readWord(inputStream); properties.put("color_planes", new Integer(planes)); properties.put("bits_per_pixel", new Integer(bitsPerPixel)); // As BMP always has 3 rgb bands, except for Version 5, // which is bgra numBands = 3; if (bitmapOffset == 0) bitmapOffset = size; if (size == 12) { // Windows 2.x and OS/2 1.x properties.put("bmp_version", "BMP v. 2.x"); // Classify the image type if (bitsPerPixel == 1) { imageType = VERSION_2_1_BIT; } else if (bitsPerPixel == 4) { imageType = VERSION_2_4_BIT; } else if (bitsPerPixel == 8) { imageType = VERSION_2_8_BIT; } else if (bitsPerPixel == 24) { imageType = VERSION_2_24_BIT; } // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 3); int sizeOfPalette = numberOfEntries*3; if (bitmapOffset == size) { switch (imageType) { case VERSION_2_1_BIT: sizeOfPalette = 2 * 3; break; case VERSION_2_4_BIT: sizeOfPalette = 16 * 3; break; case VERSION_2_8_BIT: sizeOfPalette = 256 * 3; break; case VERSION_2_24_BIT: sizeOfPalette = 0; break; } bitmapOffset = size + sizeOfPalette; } readPalette(sizeOfPalette); } else { compression = readDWord(inputStream); imageSize = readDWord(inputStream); xPelsPerMeter = readLong(inputStream); yPelsPerMeter = readLong(inputStream); long colorsUsed = readDWord(inputStream); long colorsImportant = readDWord(inputStream); switch((int)compression) { case BI_RGB: properties.put("compression", "BI_RGB"); break; case BI_RLE8: properties.put("compression", "BI_RLE8"); break; case BI_RLE4: properties.put("compression", "BI_RLE4"); break; case BI_BITFIELDS: properties.put("compression", "BI_BITFIELDS"); break; } properties.put("x_pixels_per_meter", new Long(xPelsPerMeter)); properties.put("y_pixels_per_meter", new Long(yPelsPerMeter)); properties.put("colors_used", new Long(colorsUsed)); properties.put("colors_important", new Long(colorsImportant)); if (size == 40) { // Windows 3.x and Windows NT switch((int)compression) { case BI_RGB: // No compression case BI_RLE8: // 8-bit RLE compression case BI_RLE4: // 4-bit RLE compression if (bitsPerPixel == 1) { imageType = VERSION_3_1_BIT; } else if (bitsPerPixel == 4) { imageType = VERSION_3_4_BIT; } else if (bitsPerPixel == 8) { imageType = VERSION_3_8_BIT; } else if (bitsPerPixel == 24) { imageType = VERSION_3_24_BIT; } else if (bitsPerPixel == 16) { imageType = VERSION_3_NT_16_BIT; redMask = 0x7C00; greenMask = 0x3E0; blueMask = 0x1F; properties.put("red_mask", new Integer(redMask)); properties.put("green_mask", new Integer(greenMask)); properties.put("blue_mask", new Integer(blueMask)); } else if (bitsPerPixel == 32) { imageType = VERSION_3_NT_32_BIT; redMask = 0x00FF0000; greenMask = 0x0000FF00; blueMask = 0x000000FF; properties.put("red_mask", new Integer(redMask)); properties.put("green_mask", new Integer(greenMask)); properties.put("blue_mask", new Integer(blueMask)); } // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; if (bitmapOffset == size) { switch (imageType) { case VERSION_3_1_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4; break; case VERSION_3_4_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4; break; case VERSION_3_8_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4; break; default: sizeOfPalette = 0; break; } bitmapOffset = size + sizeOfPalette; } readPalette(sizeOfPalette); properties.put("bmp_version", "BMP v. 3.x"); break; case BI_BITFIELDS: if (bitsPerPixel == 16) { imageType = VERSION_3_NT_16_BIT; } else if (bitsPerPixel == 32) { imageType = VERSION_3_NT_32_BIT; } // BitsField encoding redMask = (int)readDWord(inputStream); greenMask = (int)readDWord(inputStream); blueMask = (int)readDWord(inputStream); properties.put("red_mask", new Integer(redMask)); properties.put("green_mask", new Integer(greenMask)); properties.put("blue_mask", new Integer(blueMask)); if (colorsUsed != 0) { // there is a palette sizeOfPalette = (int)colorsUsed*4; readPalette(sizeOfPalette); } properties.put("bmp_version", "BMP v. 3.x NT"); break; default: throw new RuntimeException("Invalid compression specified in BMP file."); } } else if (size == 108) { // Windows 4.x BMP properties.put("bmp_version", "BMP v. 4.x"); // rgb masks, valid only if comp is BI_BITFIELDS redMask = (int)readDWord(inputStream); greenMask = (int)readDWord(inputStream); blueMask = (int)readDWord(inputStream); // Only supported for 32bpp BI_RGB argb alphaMask = (int)readDWord(inputStream); long csType = readDWord(inputStream); int redX = readLong(inputStream); int redY = readLong(inputStream); int redZ = readLong(inputStream); int greenX = readLong(inputStream); int greenY = readLong(inputStream); int greenZ = readLong(inputStream); int blueX = readLong(inputStream); int blueY = readLong(inputStream); int blueZ = readLong(inputStream); long gammaRed = readDWord(inputStream); long gammaGreen = readDWord(inputStream); long gammaBlue = readDWord(inputStream); if (bitsPerPixel == 1) { imageType = VERSION_4_1_BIT; } else if (bitsPerPixel == 4) { imageType = VERSION_4_4_BIT; } else if (bitsPerPixel == 8) { imageType = VERSION_4_8_BIT; } else if (bitsPerPixel == 16) { imageType = VERSION_4_16_BIT; if ((int)compression == BI_RGB) { redMask = 0x7C00; greenMask = 0x3E0; blueMask = 0x1F; } } else if (bitsPerPixel == 24) { imageType = VERSION_4_24_BIT; } else if (bitsPerPixel == 32) { imageType = VERSION_4_32_BIT; if ((int)compression == BI_RGB) { redMask = 0x00FF0000; greenMask = 0x0000FF00; blueMask = 0x000000FF; } } properties.put("red_mask", new Integer(redMask)); properties.put("green_mask", new Integer(greenMask)); properties.put("blue_mask", new Integer(blueMask)); properties.put("alpha_mask", new Integer(alphaMask)); // Read in the palette int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int sizeOfPalette = numberOfEntries*4; if (bitmapOffset == size) { switch (imageType) { case VERSION_4_1_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4; break; case VERSION_4_4_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4; break; case VERSION_4_8_BIT: sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4; break; default: sizeOfPalette = 0; break; } bitmapOffset = size + sizeOfPalette; } readPalette(sizeOfPalette); switch((int)csType) { case LCS_CALIBRATED_RGB: // All the new fields are valid only for this case properties.put("color_space", "LCS_CALIBRATED_RGB"); properties.put("redX", new Integer(redX)); properties.put("redY", new Integer(redY)); properties.put("redZ", new Integer(redZ)); properties.put("greenX", new Integer(greenX)); properties.put("greenY", new Integer(greenY)); properties.put("greenZ", new Integer(greenZ)); properties.put("blueX", new Integer(blueX)); properties.put("blueY", new Integer(blueY)); properties.put("blueZ", new Integer(blueZ)); properties.put("gamma_red", new Long(gammaRed)); properties.put("gamma_green", new Long(gammaGreen)); properties.put("gamma_blue", new Long(gammaBlue)); // break; throw new RuntimeException("Not implemented yet."); case LCS_sRGB: // Default Windows color space properties.put("color_space", "LCS_sRGB"); break; case LCS_CMYK: properties.put("color_space", "LCS_CMYK"); // break; throw new RuntimeException("Not implemented yet."); } } else { properties.put("bmp_version", "BMP v. 5.x"); throw new RuntimeException("BMP version 5 not implemented yet."); } } if (height > 0) { // bottom up image isBottomUp = true; } else { // top down image isBottomUp = false; height = Math.abs(height); } // When number of bitsPerPixel is <= 8, we use IndexColorModel. if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) { numBands = 1; // Create IndexColorModel from the palette. byte r[], g[], b[]; int sizep; if (imageType == VERSION_2_1_BIT || imageType == VERSION_2_4_BIT || imageType == VERSION_2_8_BIT) { sizep = palette.length/3; if (sizep > 256) { sizep = 256; } int off; r = new byte[sizep]; g = new byte[sizep]; b = new byte[sizep]; for (int i=0; i 256) { sizep = 256; } int off; r = new byte[sizep]; g = new byte[sizep]; b = new byte[sizep]; for (int i=0; i>>= 1; } return mask; } private int findShift(int mask) { int k = 0; for (; k < 32; ++k) { if ((mask & 1) == 1) break; mask >>>= 1; } return k; } private Image read1632Bit(boolean is32) throws IOException, BadElementException { int red_mask = findMask(redMask); int red_shift = findShift(redMask); int red_factor = red_mask + 1; int green_mask = findMask(greenMask); int green_shift = findShift(greenMask); int green_factor = green_mask + 1; int blue_mask = findMask(blueMask); int blue_shift = findShift(blueMask); int blue_factor = blue_mask + 1; byte bdata[] = new byte[width * height * 3]; // Padding bytes at the end of each scanline int padding = 0; if (!is32) { // width * bitsPerPixel should be divisible by 32 int bitsPerScanline = width * 16; if ( bitsPerScanline%32 != 0) { padding = (bitsPerScanline/32 + 1)*32 - bitsPerScanline; padding = (int)Math.ceil(padding/8.0); } } int imSize = (int)imageSize; if (imSize == 0) { imSize = (int)(bitmapFileSize - bitmapOffset); } int l=0; int v; if (isBottomUp) { for (int i=height - 1; i >= 0; --i) { l = width * 3 * i; for (int j=0; j>> red_shift) & red_mask) * 256 / red_factor); bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor); bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor); } for (int m=0; m>> red_shift) & red_mask) * 256 / red_factor); bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor); bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor); } for (int m=0; m= 0; i--) { index = i * width; lineEnd = l + width; while(l != lineEnd) { val[l++] = inverted[index++]; } } } int stride = ((width + 1) / 2); byte bdata[] = new byte[stride * height]; int ptr = 0; int sh = 0; for (int h = 0; h < height; ++h) { for (int w = 0; w < width; ++w) { if ((w & 1) == 0) bdata[sh + w / 2] = (byte)(val[ptr++] << 4); else bdata[sh + w / 2] |= (byte)(val[ptr++] & 0x0f); } sh += stride; } return indexedModel(bdata, 4, 4); } private byte[] decodeRLE(boolean is8, byte values[]) { byte val[] = new byte[width * height]; try { int ptr = 0; int x = 0; int q = 0; for (int y = 0; y < height && ptr < values.length;) { int count = values[ptr++] & 0xff; if (count != 0) { // encoded mode int bt = values[ptr++] & 0xff; if (is8) { for (int i = count; i != 0; --i) { val[q++] = (byte)bt; } } else { for (int i = 0; i < count; ++i) { val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f)); } } x += count; } else { // escape mode count = values[ptr++] & 0xff; if (count == 1) break; switch (count) { case 0: x = 0; ++y; q = y * width; break; case 2: // delta mode x += values[ptr++] & 0xff; y += values[ptr++] & 0xff; q = y * width + x; break; default: // absolute mode if (is8) { for (int i = count; i != 0; --i) val[q++] = (byte)(values[ptr++] & 0xff); } else { int bt = 0; for (int i = 0; i < count; ++i) { if ((i & 1) == 0) bt = values[ptr++] & 0xff; val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f)); } } x += count; // read pad byte if (is8) { if ((count & 1) == 1) ++ptr; } else { if ((count & 3) == 1 || (count & 3) == 2) ++ptr; } break; } } } } catch (RuntimeException e) { //empty on purpose } return val; } // Windows defined data type reading methods - everything is little endian // Unsigned 8 bits private int readUnsignedByte(InputStream stream) throws IOException { return (stream.read() & 0xff); } // Unsigned 2 bytes private int readUnsignedShort(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); return ((b2 << 8) | b1) & 0xffff; } // Signed 16 bits private int readShort(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); return (b2 << 8) | b1; } // Unsigned 16 bits private int readWord(InputStream stream) throws IOException { return readUnsignedShort(stream); } // Unsigned 4 bytes private long readUnsignedInt(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); int b3 = readUnsignedByte(stream); int b4 = readUnsignedByte(stream); long l = (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; return l & 0xffffffff; } // Signed 4 bytes private int readInt(InputStream stream) throws IOException { int b1 = readUnsignedByte(stream); int b2 = readUnsignedByte(stream); int b3 = readUnsignedByte(stream); int b4 = readUnsignedByte(stream); return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1; } // Unsigned 4 bytes private long readDWord(InputStream stream) throws IOException { return readUnsignedInt(stream); } // 32 bit signed value private int readLong(InputStream stream) throws IOException { return readInt(stream); } } src/core/com/lowagie/text/pdf/codec/CCITTG4Encoder.java100644 0 0 56546 11036112746 20210 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * This code is base in the libtiff encoder */ package com.lowagie.text.pdf.codec; import com.lowagie.text.pdf.ByteBuffer; /** * Encodes data in the CCITT G4 FAX format. */ public class CCITTG4Encoder { private int rowbytes; private int rowpixels; private int bit = 8; private int data; private byte[] refline; private ByteBuffer outBuf = new ByteBuffer(1024); private byte[] dataBp; private int offsetData; private int sizeData; /** * Creates a new encoder. * @param width the line width */ public CCITTG4Encoder(int width) { rowpixels = width; rowbytes = (rowpixels + 7) / 8; refline = new byte[rowbytes]; } /** * Encodes a number of lines. * @param data the data to be encoded * @param offset the offset into the data * @param size the size of the data to be encoded */ public void fax4Encode(byte[] data, int offset, int size) { dataBp = data; offsetData = offset; sizeData = size; while (sizeData > 0) { Fax3Encode2DRow(); System.arraycopy(dataBp, offsetData, refline, 0, rowbytes); offsetData += rowbytes; sizeData -= rowbytes; } } /** * Encodes a full image. * @param data the data to encode * @param width the image width * @param height the image height * @return the encoded image */ public static byte[] compress(byte[] data, int width, int height) { CCITTG4Encoder g4 = new CCITTG4Encoder(width); g4.fax4Encode(data, 0, g4.rowbytes * height); return g4.close(); } /** * Encodes a number of lines. * @param data the data to be encoded * @param height the number of lines to encode */ public void fax4Encode(byte[] data, int height) { fax4Encode(data, 0, rowbytes * height); } private void putcode(int[] table) { putBits(table[CODE], table[LENGTH]); } private void putspan(int span, int[][] tab) { int code, length; while (span >= 2624) { int[] te = tab[63 + (2560>>6)]; code = te[CODE]; length = te[LENGTH]; putBits(code, length); span -= te[RUNLEN]; } if (span >= 64) { int[] te = tab[63 + (span>>6)]; code = te[CODE]; length = te[LENGTH]; putBits(code, length); span -= te[RUNLEN]; } code = tab[span][CODE]; length = tab[span][LENGTH]; putBits(code, length); } private void putBits(int bits, int length) { while (length > bit) { data |= bits >> (length - bit); length -= bit; outBuf.append((byte)data); data = 0; bit = 8; } data |= (bits & msbmask[length]) << (bit - length); bit -= length; if (bit == 0) { outBuf.append((byte)data); data = 0; bit = 8; } } private void Fax3Encode2DRow() { int a0 = 0; int a1 = (pixel(dataBp, offsetData, 0) != 0 ? 0 : finddiff(dataBp, offsetData, 0, rowpixels, 0)); int b1 = (pixel(refline, 0, 0) != 0 ? 0 : finddiff(refline, 0, 0, rowpixels, 0)); int a2, b2; for (;;) { b2 = finddiff2(refline, 0, b1, rowpixels, pixel(refline, 0,b1)); if (b2 >= a1) { int d = b1 - a1; if (!(-3 <= d && d <= 3)) { /* horizontal mode */ a2 = finddiff2(dataBp, offsetData, a1, rowpixels, pixel(dataBp, offsetData,a1)); putcode(horizcode); if (a0+a1 == 0 || pixel(dataBp, offsetData, a0) == 0) { putspan(a1-a0, TIFFFaxWhiteCodes); putspan(a2-a1, TIFFFaxBlackCodes); } else { putspan(a1-a0, TIFFFaxBlackCodes); putspan(a2-a1, TIFFFaxWhiteCodes); } a0 = a2; } else { /* vertical mode */ putcode(vcodes[d+3]); a0 = a1; } } else { /* pass mode */ putcode(passcode); a0 = b2; } if (a0 >= rowpixels) break; a1 = finddiff(dataBp, offsetData, a0, rowpixels, pixel(dataBp, offsetData,a0)); b1 = finddiff(refline, 0, a0, rowpixels, pixel(dataBp, offsetData,a0) ^ 1); b1 = finddiff(refline, 0, b1, rowpixels, pixel(dataBp, offsetData,a0)); } } private void Fax4PostEncode() { putBits(EOL, 12); putBits(EOL, 12); if (bit != 8) { outBuf.append((byte)data); data = 0; bit = 8; } } /** * Closes the encoder and returns the encoded data. * @return the encoded data */ public byte[] close() { Fax4PostEncode(); return outBuf.toByteArray(); } private int pixel(byte[] data, int offset, int bit) { if (bit >= rowpixels) return 0; return ((data[offset + (bit >> 3)] & 0xff) >> (7-((bit)&7))) & 1; } private static int find1span(byte[] bp, int offset, int bs, int be) { int bits = be - bs; int n, span; int pos = offset + (bs >> 3); /* * Check partial byte on lhs. */ if (bits > 0 && (n = (bs & 7)) != 0) { span = oneruns[(bp[pos] << n) & 0xff]; if (span > 8-n) /* table value too generous */ span = 8-n; if (span > bits) /* constrain span to bit range */ span = bits; if (n+span < 8) /* doesn't extend to edge of byte */ return span; bits -= span; pos++; } else span = 0; /* * Scan full bytes for all 1's. */ while (bits >= 8) { if (bp[pos] != -1) /* end of run */ return (span + oneruns[bp[pos] & 0xff]); span += 8; bits -= 8; pos++; } /* * Check partial byte on rhs. */ if (bits > 0) { n = oneruns[bp[pos] & 0xff]; span += (n > bits ? bits : n); } return span; } private static int find0span(byte[] bp, int offset, int bs, int be) { int bits = be - bs; int n, span; int pos = offset + (bs >> 3); /* * Check partial byte on lhs. */ if (bits > 0 && (n = (bs & 7)) != 0) { span = zeroruns[(bp[pos] << n) & 0xff]; if (span > 8-n) /* table value too generous */ span = 8-n; if (span > bits) /* constrain span to bit range */ span = bits; if (n+span < 8) /* doesn't extend to edge of byte */ return span; bits -= span; pos++; } else span = 0; /* * Scan full bytes for all 1's. */ while (bits >= 8) { if (bp[pos] != 0) /* end of run */ return (span + zeroruns[bp[pos] & 0xff]); span += 8; bits -= 8; pos++; } /* * Check partial byte on rhs. */ if (bits > 0) { n = zeroruns[bp[pos] & 0xff]; span += (n > bits ? bits : n); } return span; } private static int finddiff(byte[] bp, int offset, int bs, int be, int color) { return bs + (color != 0 ? find1span(bp, offset, bs, be) : find0span(bp, offset, bs, be)); } private static int finddiff2(byte[] bp, int offset, int bs, int be, int color) { return bs < be ? finddiff(bp, offset, bs, be, color) : be; } private static byte zeroruns[] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ }; private static byte oneruns[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8 /* 0xf0 - 0xff */ }; private static final int LENGTH = 0; /* bit length of g3 code */ private static final int CODE = 1; /* g3 code */ private static final int RUNLEN = 2; /* run length in bits */ private static final int EOL = 0x001; /* EOL code value - 0000 0000 0000 1 */ /* status values returned instead of a run length */ private static final int G3CODE_EOL = -1; /* NB: ACT_EOL - ACT_WRUNT */ private static final int G3CODE_INVALID = -2; /* NB: ACT_INVALID - ACT_WRUNT */ private static final int G3CODE_EOF = -3; /* end of input data */ private static final int G3CODE_INCOMP = -4; /* incomplete run code */ private int[][] TIFFFaxWhiteCodes = { { 8, 0x35, 0 }, /* 0011 0101 */ { 6, 0x7, 1 }, /* 0001 11 */ { 4, 0x7, 2 }, /* 0111 */ { 4, 0x8, 3 }, /* 1000 */ { 4, 0xB, 4 }, /* 1011 */ { 4, 0xC, 5 }, /* 1100 */ { 4, 0xE, 6 }, /* 1110 */ { 4, 0xF, 7 }, /* 1111 */ { 5, 0x13, 8 }, /* 1001 1 */ { 5, 0x14, 9 }, /* 1010 0 */ { 5, 0x7, 10 }, /* 0011 1 */ { 5, 0x8, 11 }, /* 0100 0 */ { 6, 0x8, 12 }, /* 0010 00 */ { 6, 0x3, 13 }, /* 0000 11 */ { 6, 0x34, 14 }, /* 1101 00 */ { 6, 0x35, 15 }, /* 1101 01 */ { 6, 0x2A, 16 }, /* 1010 10 */ { 6, 0x2B, 17 }, /* 1010 11 */ { 7, 0x27, 18 }, /* 0100 111 */ { 7, 0xC, 19 }, /* 0001 100 */ { 7, 0x8, 20 }, /* 0001 000 */ { 7, 0x17, 21 }, /* 0010 111 */ { 7, 0x3, 22 }, /* 0000 011 */ { 7, 0x4, 23 }, /* 0000 100 */ { 7, 0x28, 24 }, /* 0101 000 */ { 7, 0x2B, 25 }, /* 0101 011 */ { 7, 0x13, 26 }, /* 0010 011 */ { 7, 0x24, 27 }, /* 0100 100 */ { 7, 0x18, 28 }, /* 0011 000 */ { 8, 0x2, 29 }, /* 0000 0010 */ { 8, 0x3, 30 }, /* 0000 0011 */ { 8, 0x1A, 31 }, /* 0001 1010 */ { 8, 0x1B, 32 }, /* 0001 1011 */ { 8, 0x12, 33 }, /* 0001 0010 */ { 8, 0x13, 34 }, /* 0001 0011 */ { 8, 0x14, 35 }, /* 0001 0100 */ { 8, 0x15, 36 }, /* 0001 0101 */ { 8, 0x16, 37 }, /* 0001 0110 */ { 8, 0x17, 38 }, /* 0001 0111 */ { 8, 0x28, 39 }, /* 0010 1000 */ { 8, 0x29, 40 }, /* 0010 1001 */ { 8, 0x2A, 41 }, /* 0010 1010 */ { 8, 0x2B, 42 }, /* 0010 1011 */ { 8, 0x2C, 43 }, /* 0010 1100 */ { 8, 0x2D, 44 }, /* 0010 1101 */ { 8, 0x4, 45 }, /* 0000 0100 */ { 8, 0x5, 46 }, /* 0000 0101 */ { 8, 0xA, 47 }, /* 0000 1010 */ { 8, 0xB, 48 }, /* 0000 1011 */ { 8, 0x52, 49 }, /* 0101 0010 */ { 8, 0x53, 50 }, /* 0101 0011 */ { 8, 0x54, 51 }, /* 0101 0100 */ { 8, 0x55, 52 }, /* 0101 0101 */ { 8, 0x24, 53 }, /* 0010 0100 */ { 8, 0x25, 54 }, /* 0010 0101 */ { 8, 0x58, 55 }, /* 0101 1000 */ { 8, 0x59, 56 }, /* 0101 1001 */ { 8, 0x5A, 57 }, /* 0101 1010 */ { 8, 0x5B, 58 }, /* 0101 1011 */ { 8, 0x4A, 59 }, /* 0100 1010 */ { 8, 0x4B, 60 }, /* 0100 1011 */ { 8, 0x32, 61 }, /* 0011 0010 */ { 8, 0x33, 62 }, /* 0011 0011 */ { 8, 0x34, 63 }, /* 0011 0100 */ { 5, 0x1B, 64 }, /* 1101 1 */ { 5, 0x12, 128 }, /* 1001 0 */ { 6, 0x17, 192 }, /* 0101 11 */ { 7, 0x37, 256 }, /* 0110 111 */ { 8, 0x36, 320 }, /* 0011 0110 */ { 8, 0x37, 384 }, /* 0011 0111 */ { 8, 0x64, 448 }, /* 0110 0100 */ { 8, 0x65, 512 }, /* 0110 0101 */ { 8, 0x68, 576 }, /* 0110 1000 */ { 8, 0x67, 640 }, /* 0110 0111 */ { 9, 0xCC, 704 }, /* 0110 0110 0 */ { 9, 0xCD, 768 }, /* 0110 0110 1 */ { 9, 0xD2, 832 }, /* 0110 1001 0 */ { 9, 0xD3, 896 }, /* 0110 1001 1 */ { 9, 0xD4, 960 }, /* 0110 1010 0 */ { 9, 0xD5, 1024 }, /* 0110 1010 1 */ { 9, 0xD6, 1088 }, /* 0110 1011 0 */ { 9, 0xD7, 1152 }, /* 0110 1011 1 */ { 9, 0xD8, 1216 }, /* 0110 1100 0 */ { 9, 0xD9, 1280 }, /* 0110 1100 1 */ { 9, 0xDA, 1344 }, /* 0110 1101 0 */ { 9, 0xDB, 1408 }, /* 0110 1101 1 */ { 9, 0x98, 1472 }, /* 0100 1100 0 */ { 9, 0x99, 1536 }, /* 0100 1100 1 */ { 9, 0x9A, 1600 }, /* 0100 1101 0 */ { 6, 0x18, 1664 }, /* 0110 00 */ { 9, 0x9B, 1728 }, /* 0100 1101 1 */ { 11, 0x8, 1792 }, /* 0000 0001 000 */ { 11, 0xC, 1856 }, /* 0000 0001 100 */ { 11, 0xD, 1920 }, /* 0000 0001 101 */ { 12, 0x12, 1984 }, /* 0000 0001 0010 */ { 12, 0x13, 2048 }, /* 0000 0001 0011 */ { 12, 0x14, 2112 }, /* 0000 0001 0100 */ { 12, 0x15, 2176 }, /* 0000 0001 0101 */ { 12, 0x16, 2240 }, /* 0000 0001 0110 */ { 12, 0x17, 2304 }, /* 0000 0001 0111 */ { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ { 12, 0x0, G3CODE_INVALID } /* 0000 0000 0000 */ }; private int[][] TIFFFaxBlackCodes = { { 10, 0x37, 0 }, /* 0000 1101 11 */ { 3, 0x2, 1 }, /* 010 */ { 2, 0x3, 2 }, /* 11 */ { 2, 0x2, 3 }, /* 10 */ { 3, 0x3, 4 }, /* 011 */ { 4, 0x3, 5 }, /* 0011 */ { 4, 0x2, 6 }, /* 0010 */ { 5, 0x3, 7 }, /* 0001 1 */ { 6, 0x5, 8 }, /* 0001 01 */ { 6, 0x4, 9 }, /* 0001 00 */ { 7, 0x4, 10 }, /* 0000 100 */ { 7, 0x5, 11 }, /* 0000 101 */ { 7, 0x7, 12 }, /* 0000 111 */ { 8, 0x4, 13 }, /* 0000 0100 */ { 8, 0x7, 14 }, /* 0000 0111 */ { 9, 0x18, 15 }, /* 0000 1100 0 */ { 10, 0x17, 16 }, /* 0000 0101 11 */ { 10, 0x18, 17 }, /* 0000 0110 00 */ { 10, 0x8, 18 }, /* 0000 0010 00 */ { 11, 0x67, 19 }, /* 0000 1100 111 */ { 11, 0x68, 20 }, /* 0000 1101 000 */ { 11, 0x6C, 21 }, /* 0000 1101 100 */ { 11, 0x37, 22 }, /* 0000 0110 111 */ { 11, 0x28, 23 }, /* 0000 0101 000 */ { 11, 0x17, 24 }, /* 0000 0010 111 */ { 11, 0x18, 25 }, /* 0000 0011 000 */ { 12, 0xCA, 26 }, /* 0000 1100 1010 */ { 12, 0xCB, 27 }, /* 0000 1100 1011 */ { 12, 0xCC, 28 }, /* 0000 1100 1100 */ { 12, 0xCD, 29 }, /* 0000 1100 1101 */ { 12, 0x68, 30 }, /* 0000 0110 1000 */ { 12, 0x69, 31 }, /* 0000 0110 1001 */ { 12, 0x6A, 32 }, /* 0000 0110 1010 */ { 12, 0x6B, 33 }, /* 0000 0110 1011 */ { 12, 0xD2, 34 }, /* 0000 1101 0010 */ { 12, 0xD3, 35 }, /* 0000 1101 0011 */ { 12, 0xD4, 36 }, /* 0000 1101 0100 */ { 12, 0xD5, 37 }, /* 0000 1101 0101 */ { 12, 0xD6, 38 }, /* 0000 1101 0110 */ { 12, 0xD7, 39 }, /* 0000 1101 0111 */ { 12, 0x6C, 40 }, /* 0000 0110 1100 */ { 12, 0x6D, 41 }, /* 0000 0110 1101 */ { 12, 0xDA, 42 }, /* 0000 1101 1010 */ { 12, 0xDB, 43 }, /* 0000 1101 1011 */ { 12, 0x54, 44 }, /* 0000 0101 0100 */ { 12, 0x55, 45 }, /* 0000 0101 0101 */ { 12, 0x56, 46 }, /* 0000 0101 0110 */ { 12, 0x57, 47 }, /* 0000 0101 0111 */ { 12, 0x64, 48 }, /* 0000 0110 0100 */ { 12, 0x65, 49 }, /* 0000 0110 0101 */ { 12, 0x52, 50 }, /* 0000 0101 0010 */ { 12, 0x53, 51 }, /* 0000 0101 0011 */ { 12, 0x24, 52 }, /* 0000 0010 0100 */ { 12, 0x37, 53 }, /* 0000 0011 0111 */ { 12, 0x38, 54 }, /* 0000 0011 1000 */ { 12, 0x27, 55 }, /* 0000 0010 0111 */ { 12, 0x28, 56 }, /* 0000 0010 1000 */ { 12, 0x58, 57 }, /* 0000 0101 1000 */ { 12, 0x59, 58 }, /* 0000 0101 1001 */ { 12, 0x2B, 59 }, /* 0000 0010 1011 */ { 12, 0x2C, 60 }, /* 0000 0010 1100 */ { 12, 0x5A, 61 }, /* 0000 0101 1010 */ { 12, 0x66, 62 }, /* 0000 0110 0110 */ { 12, 0x67, 63 }, /* 0000 0110 0111 */ { 10, 0xF, 64 }, /* 0000 0011 11 */ { 12, 0xC8, 128 }, /* 0000 1100 1000 */ { 12, 0xC9, 192 }, /* 0000 1100 1001 */ { 12, 0x5B, 256 }, /* 0000 0101 1011 */ { 12, 0x33, 320 }, /* 0000 0011 0011 */ { 12, 0x34, 384 }, /* 0000 0011 0100 */ { 12, 0x35, 448 }, /* 0000 0011 0101 */ { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */ { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */ { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */ { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */ { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */ { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */ { 13, 0x72, 896 }, /* 0000 0011 1001 0 */ { 13, 0x73, 960 }, /* 0000 0011 1001 1 */ { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */ { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */ { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */ { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */ { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */ { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */ { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */ { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */ { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */ { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */ { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */ { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */ { 11, 0x8, 1792 }, /* 0000 0001 000 */ { 11, 0xC, 1856 }, /* 0000 0001 100 */ { 11, 0xD, 1920 }, /* 0000 0001 101 */ { 12, 0x12, 1984 }, /* 0000 0001 0010 */ { 12, 0x13, 2048 }, /* 0000 0001 0011 */ { 12, 0x14, 2112 }, /* 0000 0001 0100 */ { 12, 0x15, 2176 }, /* 0000 0001 0101 */ { 12, 0x16, 2240 }, /* 0000 0001 0110 */ { 12, 0x17, 2304 }, /* 0000 0001 0111 */ { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ { 12, 0x0, G3CODE_INVALID } /* 0000 0000 0000 */ }; private int[] horizcode = { 3, 0x1, 0 }; /* 001 */ private int[] passcode = { 4, 0x1, 0 }; /* 0001 */ private int[][] vcodes = { { 7, 0x03, 0 }, /* 0000 011 */ { 6, 0x03, 0 }, /* 0000 11 */ { 3, 0x03, 0 }, /* 011 */ { 1, 0x1, 0 }, /* 1 */ { 3, 0x2, 0 }, /* 010 */ { 6, 0x02, 0 }, /* 0000 10 */ { 7, 0x02, 0 } /* 0000 010 */ }; private int[] msbmask = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; } src/core/com/lowagie/text/pdf/codec/GifImage.java100644 0 0 47314 11036112746 17310 0ustar 0 0 /* * Copyright 2003 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgRaw; import com.lowagie.text.Utilities; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfString; /** Reads gif images of all types. All the images in a gif are read in the constructors * and can be retrieved with other methods. * @author Paulo Soares (psoares@consiste.pt) */ public class GifImage { protected DataInputStream in; protected int width; // full image width protected int height; // full image height protected boolean gctFlag; // global color table used protected int bgIndex; // background color index protected int bgColor; // background color protected int pixelAspect; // pixel aspect ratio protected boolean lctFlag; // local color table flag protected boolean interlace; // interlace flag protected int lctSize; // local color table size protected int ix, iy, iw, ih; // current image rectangle protected byte[] block = new byte[256]; // current data block protected int blockSize = 0; // block size // last graphic control extension info protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev protected boolean transparency = false; // use transparent color protected int delay = 0; // delay in milliseconds protected int transIndex; // transparent color index protected static final int MaxStackSize = 4096; // max decoder pixel stack size // LZW decoder working arrays protected short[] prefix; protected byte[] suffix; protected byte[] pixelStack; protected byte[] pixels; protected byte m_out[]; protected int m_bpc; protected int m_gbpc; protected byte m_global_table[]; protected byte m_local_table[]; protected byte m_curr_table[]; protected int m_line_stride; protected byte fromData[]; protected URL fromUrl; protected ArrayList frames = new ArrayList(); // frames read from current file /** Reads gif images from an URL. * @param url the URL * @throws IOException on error */ public GifImage(URL url) throws IOException { fromUrl = url; InputStream is = null; try { is = url.openStream(); process(is); } finally { if (is != null) { is.close(); } } } /** Reads gif images from a file. * @param file the file * @throws IOException on error */ public GifImage(String file) throws IOException { this(Utilities.toURL(file)); } /** Reads gif images from a byte array. * @param data the byte array * @throws IOException on error */ public GifImage(byte data[]) throws IOException { fromData = data; InputStream is = null; try { is = new ByteArrayInputStream(data); process(is); } finally { if (is != null) { is.close(); } } } /** Reads gif images from a stream. The stream is not closed. * @param is the stream * @throws IOException on error */ public GifImage(InputStream is) throws IOException { process(is); } /** Gets the number of frames the gif has. * @return the number of frames the gif has */ public int getFrameCount() { return frames.size(); } /** Gets the image from a frame. The first frame is 1. * @param frame the frame to get the image from * @return the image */ public Image getImage(int frame) { GifFrame gf = (GifFrame)frames.get(frame - 1); return gf.image; } /** Gets the [x,y] position of the frame in reference to the * logical screen. * @param frame the frame * @return the [x,y] position of the frame */ public int[] getFramePosition(int frame) { GifFrame gf = (GifFrame)frames.get(frame - 1); return new int[]{gf.ix, gf.iy}; } /** Gets the logical screen. The images may be smaller and placed * in some position in this screen to playback some animation. * No image will be be bigger that this. * @return the logical screen dimensions as [x,y] */ public int[] getLogicalScreen() { return new int[]{width, height}; } void process(InputStream is) throws IOException { in = new DataInputStream(new BufferedInputStream(is)); readHeader(); readContents(); if (frames.isEmpty()) throw new IOException("The file does not contain any valid image."); } /** * Reads GIF file header information. */ protected void readHeader() throws IOException { String id = ""; for (int i = 0; i < 6; i++) id += (char)in.read(); if (!id.startsWith("GIF8")) { throw new IOException("Gif signature nor found."); } readLSD(); if (gctFlag) { m_global_table = readColorTable(m_gbpc); } } /** * Reads Logical Screen Descriptor */ protected void readLSD() throws IOException { // logical screen size width = readShort(); height = readShort(); // packed fields int packed = in.read(); gctFlag = (packed & 0x80) != 0; // 1 : global color table flag m_gbpc = (packed & 7) + 1; bgIndex = in.read(); // background color index pixelAspect = in.read(); // pixel aspect ratio } /** * Reads next 16-bit value, LSB first */ protected int readShort() throws IOException { // read 16-bit value, LSB first return in.read() | (in.read() << 8); } /** * Reads next variable length block from input. * * @return number of bytes stored in "buffer" */ protected int readBlock() throws IOException { blockSize = in.read(); if (blockSize <= 0) return blockSize = 0; for (int k = 0; k < blockSize; ++k) { int v = in.read(); if (v < 0) { return blockSize = k; } block[k] = (byte)v; } return blockSize; } protected byte[] readColorTable(int bpc) throws IOException { int ncolors = 1 << bpc; int nbytes = 3*ncolors; bpc = newBpc(bpc); byte table[] = new byte[(1 << bpc) * 3]; in.readFully(table, 0, nbytes); return table; } static protected int newBpc(int bpc) { switch (bpc) { case 1: case 2: case 4: break; case 3: return 4; default: return 8; } return bpc; } protected void readContents() throws IOException { // read GIF file content blocks boolean done = false; while (!done) { int code = in.read(); switch (code) { case 0x2C: // image separator readImage(); break; case 0x21: // extension code = in.read(); switch (code) { case 0xf9: // graphics control extension readGraphicControlExt(); break; case 0xff: // application extension readBlock(); skip(); // don't care break; default: // uninteresting extension skip(); } break; default: done = true; break; } } } /** * Reads next frame image */ protected void readImage() throws IOException { ix = readShort(); // (sub)image position & size iy = readShort(); iw = readShort(); ih = readShort(); int packed = in.read(); lctFlag = (packed & 0x80) != 0; // 1 - local color table flag interlace = (packed & 0x40) != 0; // 2 - interlace flag // 3 - sort flag // 4-5 - reserved lctSize = 2 << (packed & 7); // 6-8 - local color table size m_bpc = newBpc(m_gbpc); if (lctFlag) { m_curr_table = readColorTable((packed & 7) + 1); // read table m_bpc = newBpc((packed & 7) + 1); } else { m_curr_table = m_global_table; } if (transparency && transIndex >= m_curr_table.length / 3) transparency = false; if (transparency && m_bpc == 1) { // Acrobat 5.05 doesn't like this combination byte tp[] = new byte[12]; System.arraycopy(m_curr_table, 0, tp, 0, 6); m_curr_table = tp; m_bpc = 2; } boolean skipZero = decodeImageData(); // decode pixel data if (!skipZero) skip(); Image img = null; try { img = new ImgRaw(iw, ih, 1, m_bpc, m_out); PdfArray colorspace = new PdfArray(); colorspace.add(PdfName.INDEXED); colorspace.add(PdfName.DEVICERGB); int len = m_curr_table.length; colorspace.add(new PdfNumber(len / 3 - 1)); colorspace.add(new PdfString(m_curr_table)); PdfDictionary ad = new PdfDictionary(); ad.put(PdfName.COLORSPACE, colorspace); img.setAdditional(ad); if (transparency) { img.setTransparency(new int[]{transIndex, transIndex}); } } catch (Exception e) { throw new ExceptionConverter(e); } img.setOriginalType(Image.ORIGINAL_GIF); img.setOriginalData(fromData); img.setUrl(fromUrl); GifFrame gf = new GifFrame(); gf.image = img; gf.ix = ix; gf.iy = iy; frames.add(gf); // add image to frame list //resetFrame(); } protected boolean decodeImageData() throws IOException { int NullCode = -1; int npix = iw * ih; int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi; boolean skipZero = false; if (prefix == null) prefix = new short[MaxStackSize]; if (suffix == null) suffix = new byte[MaxStackSize]; if (pixelStack == null) pixelStack = new byte[MaxStackSize+1]; m_line_stride = (iw * m_bpc + 7) / 8; m_out = new byte[m_line_stride * ih]; int pass = 1; int inc = interlace ? 8 : 1; int line = 0; int xpos = 0; // Initialize GIF data stream decoder. data_size = in.read(); clear = 1 << data_size; end_of_information = clear + 1; available = clear + 2; old_code = NullCode; code_size = data_size + 1; code_mask = (1 << code_size) - 1; for (code = 0; code < clear; code++) { prefix[code] = 0; suffix[code] = (byte) code; } // Decode GIF pixel stream. datum = bits = count = first = top = bi = 0; for (i = 0; i < npix; ) { if (top == 0) { if (bits < code_size) { // Load bytes until there are enough bits for a code. if (count == 0) { // Read a new data block. count = readBlock(); if (count <= 0) { skipZero = true; break; } bi = 0; } datum += (block[bi] & 0xff) << bits; bits += 8; bi++; count--; continue; } // Get the next code. code = datum & code_mask; datum >>= code_size; bits -= code_size; // Interpret the code if ((code > available) || (code == end_of_information)) break; if (code == clear) { // Reset decoder. code_size = data_size + 1; code_mask = (1 << code_size) - 1; available = clear + 2; old_code = NullCode; continue; } if (old_code == NullCode) { pixelStack[top++] = suffix[code]; old_code = code; first = code; continue; } in_code = code; if (code == available) { pixelStack[top++] = (byte) first; code = old_code; } while (code > clear) { pixelStack[top++] = suffix[code]; code = prefix[code]; } first = suffix[code] & 0xff; // Add a new string to the string table, if (available >= MaxStackSize) break; pixelStack[top++] = (byte) first; prefix[available] = (short) old_code; suffix[available] = (byte) first; available++; if (((available & code_mask) == 0) && (available < MaxStackSize)) { code_size++; code_mask += available; } old_code = in_code; } // Pop a pixel off the pixel stack. top--; i++; setPixel(xpos, line, pixelStack[top]); ++xpos; if (xpos >= iw) { xpos = 0; line += inc; if (line >= ih) { if (interlace) { do { pass++; switch (pass) { case 2: line = 4; break; case 3: line = 2; inc = 4; break; case 4: line = 1; inc = 2; break; default: // this shouldn't happen line = ih - 1; inc = 0; } } while (line >= ih); } else { line = ih - 1; // this shouldn't happen inc = 0; } } } } return skipZero; } protected void setPixel(int x, int y, int v) { if (m_bpc == 8) { int pos = x + iw * y; m_out[pos] = (byte)v; } else { int pos = m_line_stride * y + x / (8 / m_bpc); int vout = v << (8 - m_bpc * (x % (8 / m_bpc))- m_bpc); m_out[pos] |= vout; } } /** * Resets frame state for reading next image. */ protected void resetFrame() { // it does nothing in the pdf context //boolean transparency = false; //int delay = 0; } /** * Reads Graphics Control Extension values */ protected void readGraphicControlExt() throws IOException { in.read(); // block size int packed = in.read(); // packed fields dispose = (packed & 0x1c) >> 2; // disposal method if (dispose == 0) dispose = 1; // elect to keep old image if discretionary transparency = (packed & 1) != 0; delay = readShort() * 10; // delay in milliseconds transIndex = in.read(); // transparent color index in.read(); // block terminator } /** * Skips variable length blocks up to and including * next zero length block. */ protected void skip() throws IOException { do { readBlock(); } while (blockSize > 0); } static class GifFrame { Image image; int ix; int iy; } } src/core/com/lowagie/text/pdf/codec/JBIG2Image.java100644 0 0 10600 11154165266 17372 0ustar 0 0 /* * $Id: JBIG2Image.java 3715 2009-02-23 15:02:23Z blowagie $ * * Copyright 2009 by Nigel Kerr. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgJBIG2; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * Support for JBIG2 Images. * This class assumes that we are always embedding into a pdf. * * @since 2.1.5 */ public class JBIG2Image { /** * Gets a byte array that can be used as a /JBIG2Globals, * or null if not applicable to the given jbig2. * @param ra an random access file or array * @return a byte array */ public static byte[] getGlobalSegment(RandomAccessFileOrArray ra ) { try { JBIG2SegmentReader sr = new JBIG2SegmentReader(ra); sr.read(); return sr.getGlobal(true); } catch (Exception e) { return null; } } /** * returns an Image representing the given page. * @param ra the file or array containing the image * @param page the page number of the image * @return an Image object */ public static Image getJbig2Image(RandomAccessFileOrArray ra, int page) { if (page < 1) throw new IllegalArgumentException("The page number must be >= 1."); try { JBIG2SegmentReader sr = new JBIG2SegmentReader(ra); sr.read(); JBIG2SegmentReader.JBIG2Page p = sr.getPage(page); Image img = new ImgJBIG2(p.pageBitmapWidth, p.pageBitmapHeight, p.getData(true), sr.getGlobal(true)); return img; } catch (Exception e) { throw new ExceptionConverter(e); } } /*** * Gets the number of pages in a JBIG2 image. * @param ra a random acces file array containing a JBIG2 image * @return the number of pages */ public static int getNumberOfPages(RandomAccessFileOrArray ra) { try { JBIG2SegmentReader sr = new JBIG2SegmentReader(ra); sr.read(); return sr.numberOfPages(); } catch (Exception e) { throw new ExceptionConverter(e); } } } src/core/com/lowagie/text/pdf/codec/JBIG2SegmentReader.java100644 0 0 40374 11154165266 21110 0ustar 0 0 /* * $Id: JBIG2SegmentReader.java 3714 2009-02-20 21:04:16Z xlv $ * * Copyright 2009 by Nigel Kerr. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2009 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2009 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * Class to read a JBIG2 file at a basic level: understand all the segments, * understand what segments belong to which pages, how many pages there are, * what the width and height of each page is, and global segments if there * are any. Or: the minimum required to be able to take a normal sequential * or random-access organized file, and be able to embed JBIG2 pages as images * in a PDF. * * TODO: the indeterminate-segment-size value of dataLength, else? * * @since 2.1.5 */ public class JBIG2SegmentReader { public static final int SYMBOL_DICTIONARY = 0; //see 7.4.2. public static final int INTERMEDIATE_TEXT_REGION = 4; //see 7.4.3. public static final int IMMEDIATE_TEXT_REGION = 6; //see 7.4.3. public static final int IMMEDIATE_LOSSLESS_TEXT_REGION = 7; //see 7.4.3. public static final int PATTERN_DICTIONARY = 16; //see 7.4.4. public static final int INTERMEDIATE_HALFTONE_REGION = 20; //see 7.4.5. public static final int IMMEDIATE_HALFTONE_REGION = 22; //see 7.4.5. public static final int IMMEDIATE_LOSSLESS_HALFTONE_REGION = 23; //see 7.4.5. public static final int INTERMEDIATE_GENERIC_REGION = 36; //see 7.4.6. public static final int IMMEDIATE_GENERIC_REGION = 38; //see 7.4.6. public static final int IMMEDIATE_LOSSLESS_GENERIC_REGION = 39; //see 7.4.6. public static final int INTERMEDIATE_GENERIC_REFINEMENT_REGION = 40; //see 7.4.7. public static final int IMMEDIATE_GENERIC_REFINEMENT_REGION = 42; //see 7.4.7. public static final int IMMEDIATE_LOSSLESS_GENERIC_REFINEMENT_REGION = 43; //see 7.4.7. public static final int PAGE_INFORMATION = 48; //see 7.4.8. public static final int END_OF_PAGE = 49; //see 7.4.9. public static final int END_OF_STRIPE = 50; //see 7.4.10. public static final int END_OF_FILE = 51; //see 7.4.11. public static final int PROFILES = 52; //see 7.4.12. public static final int TABLES = 53; //see 7.4.13. public static final int EXTENSION = 62; //see 7.4.14. private final SortedMap segments = new TreeMap(); private final SortedMap pages = new TreeMap(); private final SortedSet globals = new TreeSet(); private RandomAccessFileOrArray ra; private boolean sequential; private boolean number_of_pages_known; private int number_of_pages = -1; private boolean read = false; /** * Inner class that holds information about a JBIG2 segment. * @since 2.1.5 */ public static class JBIG2Segment implements Comparable { public final int segmentNumber; public long dataLength = -1; public int page = -1; public int[] referredToSegmentNumbers = null; public boolean[] segmentRetentionFlags = null; public int type = -1; public boolean deferredNonRetain = false; public int countOfReferredToSegments = -1; public byte[] data = null; public byte[] headerData = null; public boolean page_association_size = false; public int page_association_offset = -1; public JBIG2Segment(int segment_number) { this.segmentNumber = segment_number; } // for the globals treeset public int compareTo(Object o) { return this.compareTo((JBIG2Segment)o); } public int compareTo(JBIG2Segment s) { return this.segmentNumber - s.segmentNumber; } } /** * Inner class that holds information about a JBIG2 page. * @since 2.1.5 */ public static class JBIG2Page { public final int page; private final JBIG2SegmentReader sr; private final SortedMap segs = new TreeMap(); public int pageBitmapWidth = -1; public int pageBitmapHeight = -1; public JBIG2Page(int page, JBIG2SegmentReader sr) { this.page = page; this.sr = sr; } /** * return as a single byte array the header-data for each segment in segment number * order, EMBEDDED organization, but i am putting the needed segments in SEQUENTIAL organization. * if for_embedding, skip the segment types that are known to be not for acrobat. * @param for_embedding * @return a byte array * @throws IOException */ public byte[] getData(boolean for_embedding) throws IOException { ByteArrayOutputStream os = new ByteArrayOutputStream(); for (Iterator i = segs.keySet().iterator(); i.hasNext(); ) { Integer sn = (Integer) i.next(); JBIG2Segment s = (JBIG2Segment) segs.get(sn); // pdf reference 1.4, section 3.3.6 JBIG2Decode Filter // D.3 Embedded organisation if ( for_embedding && ( s.type == END_OF_FILE || s.type == END_OF_PAGE ) ) { continue; } if ( for_embedding ) { // change the page association to page 1 byte[] headerData_emb = copyByteArray(s.headerData); if ( s.page_association_size ) { headerData_emb[s.page_association_offset] = 0x0; headerData_emb[s.page_association_offset+1] = 0x0; headerData_emb[s.page_association_offset+2] = 0x0; headerData_emb[s.page_association_offset+3] = 0x1; } else { headerData_emb[s.page_association_offset] = 0x1; } os.write(headerData_emb); } else { os.write(s.headerData); } os.write(s.data); } os.close(); return os.toByteArray(); } public void addSegment(JBIG2Segment s) { segs.put(new Integer(s.segmentNumber), s); } } public JBIG2SegmentReader(RandomAccessFileOrArray ra ) throws IOException { this.ra = ra; } public static byte[] copyByteArray(byte[] b) { byte[] bc = new byte[b.length]; System.arraycopy(b, 0, bc, 0, b.length); return bc; } public void read() throws IOException { if ( this.read ) { throw new IllegalStateException("already attempted a read() on this Jbig2 File"); } this.read = true; readFileHeader(); // Annex D if ( this.sequential ) { // D.1 do { JBIG2Segment tmp = readHeader(); readSegment(tmp); segments.put(new Integer(tmp.segmentNumber), tmp); } while ( this.ra.getFilePointer() < this.ra.length() ); } else { // D.2 JBIG2Segment tmp; do { tmp = readHeader(); segments.put(new Integer(tmp.segmentNumber), tmp); } while ( tmp.type != END_OF_FILE ); Iterator segs = segments.keySet().iterator(); while ( segs.hasNext() ) { readSegment((JBIG2Segment)segments.get(segs.next())); } } } void readSegment(JBIG2Segment s) throws IOException { int ptr = ra.getFilePointer(); if ( s.dataLength == 0xffffffffl ) { // TODO figure this bit out, 7.2.7 return; } byte[] data = new byte[(int)s.dataLength]; ra.read(data); s.data = data; if ( s.type == PAGE_INFORMATION ) { int last = ra.getFilePointer(); ra.seek(ptr); int page_bitmap_width = ra.readInt(); int page_bitmap_height = ra.readInt(); ra.seek(last); JBIG2Page p = (JBIG2Page)pages.get(new Integer(s.page)); if ( p == null ) { throw new IllegalStateException("referring to widht/height of page we havent seen yet? " + s.page); } p.pageBitmapWidth = page_bitmap_width; p.pageBitmapHeight = page_bitmap_height; } } JBIG2Segment readHeader() throws IOException { int ptr = ra.getFilePointer(); // 7.2.1 int segment_number = ra.readInt(); JBIG2Segment s = new JBIG2Segment(segment_number); // 7.2.3 int segment_header_flags = ra.read(); boolean deferred_non_retain = (( segment_header_flags & 0x80 ) == 0x80); s.deferredNonRetain = deferred_non_retain; boolean page_association_size = (( segment_header_flags & 0x40 ) == 0x40); int segment_type = ( segment_header_flags & 0x3f ); s.type = segment_type; //7.2.4 int referred_to_byte0 = ra.read(); int count_of_referred_to_segments = (referred_to_byte0 & 0xE0) >> 5; int[] referred_to_segment_numbers = null; boolean[] segment_retention_flags = null; if ( count_of_referred_to_segments == 7 ) { // at least five bytes ra.seek(ra.getFilePointer() - 1); count_of_referred_to_segments = ( ra.readInt() & 0x1fffffff ); segment_retention_flags = new boolean[count_of_referred_to_segments+1]; int i = 0; int referred_to_current_byte = 0; do { int j = i % 8; if ( j == 0) { referred_to_current_byte = ra.read(); } segment_retention_flags[i] = (((( 0x1 << j ) & referred_to_current_byte) >> j) == 0x1); i++; } while ( i <= count_of_referred_to_segments ); } else if ( count_of_referred_to_segments <= 4 ) { // only one byte segment_retention_flags = new boolean[count_of_referred_to_segments+1]; referred_to_byte0 &= 0x1f; for ( int i = 0; i <= count_of_referred_to_segments; i++ ) { segment_retention_flags[i] = (((( 0x1 << i ) & referred_to_byte0) >> i) == 0x1); } } else if ( count_of_referred_to_segments == 5 || count_of_referred_to_segments == 6 ) { throw new IllegalStateException("count of referred-to segments had bad value in header for segment " + segment_number + " starting at " + ptr); } s.segmentRetentionFlags = segment_retention_flags; s.countOfReferredToSegments = count_of_referred_to_segments; // 7.2.5 referred_to_segment_numbers = new int[count_of_referred_to_segments+1]; for ( int i = 1; i <= count_of_referred_to_segments; i++ ) { if ( segment_number <= 256 ) { referred_to_segment_numbers[i] = ra.read(); } else if ( segment_number <= 65536 ) { referred_to_segment_numbers[i] = ra.readUnsignedShort(); } else { referred_to_segment_numbers[i] = (int)ra.readUnsignedInt(); // TODO wtf ack } } s.referredToSegmentNumbers = referred_to_segment_numbers; // 7.2.6 int segment_page_association; int page_association_offset = ra.getFilePointer() - ptr; if ( page_association_size ) { segment_page_association = ra.readInt(); } else { segment_page_association = ra.read(); } if ( segment_page_association < 0 ) { throw new IllegalStateException("page " + segment_page_association + " invalid for segment " + segment_number + " starting at " + ptr); } s.page = segment_page_association; // so we can change the page association at embedding time. s.page_association_size = page_association_size; s.page_association_offset = page_association_offset; if ( segment_page_association > 0 && ! pages.containsKey(new Integer(segment_page_association)) ) { pages.put(new Integer(segment_page_association), new JBIG2Page(segment_page_association, this)); } if ( segment_page_association > 0 ) { ((JBIG2Page)pages.get(new Integer(segment_page_association))).addSegment(s); } else { globals.add(s); } // 7.2.7 long segment_data_length = ra.readUnsignedInt(); // TODO the 0xffffffff value that might be here, and how to understand those afflicted segments s.dataLength = segment_data_length; int end_ptr = ra.getFilePointer(); ra.seek(ptr); byte[] header_data = new byte[end_ptr - ptr]; ra.read(header_data); s.headerData = header_data; return s; } void readFileHeader() throws IOException { ra.seek(0); byte[] idstring = new byte[8]; ra.read(idstring); byte[] refidstring = {(byte)0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A}; for ( int i = 0; i < idstring.length; i++ ) { if ( idstring[i] != refidstring[i] ) { throw new IllegalStateException("file header idstring not good at byte " + i); } } int fileheaderflags = ra.read(); this.sequential = (( fileheaderflags & 0x1 ) == 0x1); this.number_of_pages_known = (( fileheaderflags & 0x2) == 0x0); if ( (fileheaderflags & 0xfc) != 0x0 ) { throw new IllegalStateException("file header flags bits 2-7 not 0"); } if ( this.number_of_pages_known ) { this.number_of_pages = ra.readInt(); } } public int numberOfPages() { return pages.size(); } public int getPageHeight(int i) { return ((JBIG2Page)pages.get(new Integer(i))).pageBitmapHeight; } public int getPageWidth(int i) { return ((JBIG2Page)pages.get(new Integer(i))).pageBitmapWidth; } public JBIG2Page getPage(int page) { return (JBIG2Page)pages.get(new Integer(page)); } public byte[] getGlobal(boolean for_embedding) { ByteArrayOutputStream os = new ByteArrayOutputStream(); try { for (Iterator gitr = globals.iterator(); gitr.hasNext();) { JBIG2Segment s = (JBIG2Segment)gitr.next(); if ( for_embedding && ( s.type == END_OF_FILE || s.type == END_OF_PAGE ) ) { continue; } os.write(s.headerData); os.write(s.data); } os.close(); } catch (IOException e) { e.printStackTrace(); } if ( os.size() <= 0 ) { return null; } return os.toByteArray(); } public String toString() { if ( this.read ) { return "Jbig2SegmentReader: number of pages: " + this.numberOfPages(); } else { return "Jbig2SegmentReader in indeterminate state."; } } }src/core/com/lowagie/text/pdf/codec/PngImage.java100644 0 0 106061 11154165266 17350 0ustar 0 0 /* * Copyright 2003-2008 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * This code is based on a series of source files originally released * by SUN in the context of the JAI project. The original code was released * under the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; import java.awt.color.ICC_Profile; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.ImgRaw; import com.lowagie.text.Utilities; import com.lowagie.text.pdf.ByteBuffer; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfLiteral; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfString; /** Reads a PNG image. All types of PNG can be read. *

    * It is based in part in the JAI codec. * * @author Paulo Soares (psoares@consiste.pt) */ public class PngImage { /** Some PNG specific values. */ public static final int[] PNGID = {137, 80, 78, 71, 13, 10, 26, 10}; /** A PNG marker. */ public static final String IHDR = "IHDR"; /** A PNG marker. */ public static final String PLTE = "PLTE"; /** A PNG marker. */ public static final String IDAT = "IDAT"; /** A PNG marker. */ public static final String IEND = "IEND"; /** A PNG marker. */ public static final String tRNS = "tRNS"; /** A PNG marker. */ public static final String pHYs = "pHYs"; /** A PNG marker. */ public static final String gAMA = "gAMA"; /** A PNG marker. */ public static final String cHRM = "cHRM"; /** A PNG marker. */ public static final String sRGB = "sRGB"; /** A PNG marker. */ public static final String iCCP = "iCCP"; private static final int TRANSFERSIZE = 4096; private static final int PNG_FILTER_NONE = 0; private static final int PNG_FILTER_SUB = 1; private static final int PNG_FILTER_UP = 2; private static final int PNG_FILTER_AVERAGE = 3; private static final int PNG_FILTER_PAETH = 4; private static final PdfName intents[] = {PdfName.PERCEPTUAL, PdfName.RELATIVECOLORIMETRIC,PdfName.SATURATION,PdfName.ABSOLUTECOLORIMETRIC}; InputStream is; DataInputStream dataStream; int width; int height; int bitDepth; int colorType; int compressionMethod; int filterMethod; int interlaceMethod; PdfDictionary additional = new PdfDictionary(); byte image[]; byte smask[]; byte trans[]; NewByteArrayOutputStream idat = new NewByteArrayOutputStream(); int dpiX; int dpiY; float XYRatio; boolean genBWMask; boolean palShades; int transRedGray = -1; int transGreen = -1; int transBlue = -1; int inputBands; int bytesPerPixel; // number of bytes per input pixel byte colorTable[]; float gamma = 1f; boolean hasCHRM = false; float xW, yW, xR, yR, xG, yG, xB, yB; PdfName intent; ICC_Profile icc_profile; /** Creates a new instance of PngImage */ PngImage(InputStream is) { this.is = is; } /** Reads a PNG from an url. * @param url the url * @throws IOException on error * @return the image */ public static Image getImage(URL url) throws IOException { InputStream is = null; try { is = url.openStream(); Image img = getImage(is); img.setUrl(url); return img; } finally { if (is != null) { is.close(); } } } /** Reads a PNG from a stream. * @param is the stream * @throws IOException on error * @return the image */ public static Image getImage(InputStream is) throws IOException { PngImage png = new PngImage(is); return png.getImage(); } /** Reads a PNG from a file. * @param file the file * @throws IOException on error * @return the image */ public static Image getImage(String file) throws IOException { return getImage(Utilities.toURL(file)); } /** Reads a PNG from a byte array. * @param data the byte array * @throws IOException on error * @return the image */ public static Image getImage(byte data[]) throws IOException { ByteArrayInputStream is = new ByteArrayInputStream(data); Image img = getImage(is); img.setOriginalData(data); return img; } boolean checkMarker(String s) { if (s.length() != 4) return false; for (int k = 0; k < 4; ++k) { char c = s.charAt(k); if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) return false; } return true; } void readPng() throws IOException { for (int i = 0; i < PNGID.length; i++) { if (PNGID[i] != is.read()) { throw new IOException("File is not a valid PNG."); } } byte buffer[] = new byte[TRANSFERSIZE]; while (true) { int len = getInt(is); String marker = getString(is); if (len < 0 || !checkMarker(marker)) throw new IOException("Corrupted PNG file."); if (IDAT.equals(marker)) { int size; while (len != 0) { size = is.read(buffer, 0, Math.min(len, TRANSFERSIZE)); if (size < 0) return; idat.write(buffer, 0, size); len -= size; } } else if (tRNS.equals(marker)) { switch (colorType) { case 0: if (len >= 2) { len -= 2; int gray = getWord(is); if (bitDepth == 16) transRedGray = gray; else additional.put(PdfName.MASK, new PdfLiteral("["+gray+" "+gray+"]")); } break; case 2: if (len >= 6) { len -= 6; int red = getWord(is); int green = getWord(is); int blue = getWord(is); if (bitDepth == 16) { transRedGray = red; transGreen = green; transBlue = blue; } else additional.put(PdfName.MASK, new PdfLiteral("["+red+" "+red+" "+green+" "+green+" "+blue+" "+blue+"]")); } break; case 3: if (len > 0) { trans = new byte[len]; for (int k = 0; k < len; ++k) trans[k] = (byte)is.read(); len = 0; } break; } Utilities.skip(is, len); } else if (IHDR.equals(marker)) { width = getInt(is); height = getInt(is); bitDepth = is.read(); colorType = is.read(); compressionMethod = is.read(); filterMethod = is.read(); interlaceMethod = is.read(); } else if (PLTE.equals(marker)) { if (colorType == 3) { PdfArray colorspace = new PdfArray(); colorspace.add(PdfName.INDEXED); colorspace.add(getColorspace()); colorspace.add(new PdfNumber(len / 3 - 1)); ByteBuffer colortable = new ByteBuffer(); while ((len--) > 0) { colortable.append_i(is.read()); } colorspace.add(new PdfString(colorTable = colortable.toByteArray())); additional.put(PdfName.COLORSPACE, colorspace); } else { Utilities.skip(is, len); } } else if (pHYs.equals(marker)) { int dx = getInt(is); int dy = getInt(is); int unit = is.read(); if (unit == 1) { dpiX = (int)(dx * 0.0254f + 0.5f); dpiY = (int)(dy * 0.0254f + 0.5f); } else { if (dy != 0) XYRatio = (float)dx / (float)dy; } } else if (cHRM.equals(marker)) { xW = getInt(is) / 100000f; yW = getInt(is) / 100000f; xR = getInt(is) / 100000f; yR = getInt(is) / 100000f; xG = getInt(is) / 100000f; yG = getInt(is) / 100000f; xB = getInt(is) / 100000f; yB = getInt(is) / 100000f; hasCHRM = !(Math.abs(xW)<0.0001f||Math.abs(yW)<0.0001f||Math.abs(xR)<0.0001f||Math.abs(yR)<0.0001f||Math.abs(xG)<0.0001f||Math.abs(yG)<0.0001f||Math.abs(xB)<0.0001f||Math.abs(yB)<0.0001f); } else if (sRGB.equals(marker)) { int ri = is.read(); intent = intents[ri]; gamma = 2.2f; xW = 0.3127f; yW = 0.329f; xR = 0.64f; yR = 0.33f; xG = 0.3f; yG = 0.6f; xB = 0.15f; yB = 0.06f; hasCHRM = true; } else if (gAMA.equals(marker)) { int gm = getInt(is); if (gm != 0) { gamma = 100000f / gm; if (!hasCHRM) { xW = 0.3127f; yW = 0.329f; xR = 0.64f; yR = 0.33f; xG = 0.3f; yG = 0.6f; xB = 0.15f; yB = 0.06f; hasCHRM = true; } } } else if (iCCP.equals(marker)) { do { --len; } while (is.read() != 0); is.read(); --len; byte icccom[] = new byte[len]; int p = 0; while (len > 0) { int r = is.read(icccom, p, len); if (r < 0) throw new IOException("Premature end of file."); p += r; len -= r; } byte iccp[] = PdfReader.FlateDecode(icccom, true); icccom = null; try { icc_profile = ICC_Profile.getInstance(iccp); } catch (RuntimeException e) { icc_profile = null; } } else if (IEND.equals(marker)) { break; } else { Utilities.skip(is, len); } Utilities.skip(is, 4); } } PdfObject getColorspace() { if (icc_profile != null) { if ((colorType & 2) == 0) return PdfName.DEVICEGRAY; else return PdfName.DEVICERGB; } if (gamma == 1f && !hasCHRM) { if ((colorType & 2) == 0) return PdfName.DEVICEGRAY; else return PdfName.DEVICERGB; } else { PdfArray array = new PdfArray(); PdfDictionary dic = new PdfDictionary(); if ((colorType & 2) == 0) { if (gamma == 1f) return PdfName.DEVICEGRAY; array.add(PdfName.CALGRAY); dic.put(PdfName.GAMMA, new PdfNumber(gamma)); dic.put(PdfName.WHITEPOINT, new PdfLiteral("[1 1 1]")); array.add(dic); } else { PdfObject wp = new PdfLiteral("[1 1 1]"); array.add(PdfName.CALRGB); if (gamma != 1f) { PdfArray gm = new PdfArray(); PdfNumber n = new PdfNumber(gamma); gm.add(n); gm.add(n); gm.add(n); dic.put(PdfName.GAMMA, gm); } if (hasCHRM) { float z = yW*((xG-xB)*yR-(xR-xB)*yG+(xR-xG)*yB); float YA = yR*((xG-xB)*yW-(xW-xB)*yG+(xW-xG)*yB)/z; float XA = YA*xR/yR; float ZA = YA*((1-xR)/yR-1); float YB = -yG*((xR-xB)*yW-(xW-xB)*yR+(xW-xR)*yB)/z; float XB = YB*xG/yG; float ZB = YB*((1-xG)/yG-1); float YC = yB*((xR-xG)*yW-(xW-xG)*yW+(xW-xR)*yG)/z; float XC = YC*xB/yB; float ZC = YC*((1-xB)/yB-1); float XW = XA+XB+XC; float YW = 1;//YA+YB+YC; float ZW = ZA+ZB+ZC; PdfArray wpa = new PdfArray(); wpa.add(new PdfNumber(XW)); wpa.add(new PdfNumber(YW)); wpa.add(new PdfNumber(ZW)); wp = wpa; PdfArray matrix = new PdfArray(); matrix.add(new PdfNumber(XA)); matrix.add(new PdfNumber(YA)); matrix.add(new PdfNumber(ZA)); matrix.add(new PdfNumber(XB)); matrix.add(new PdfNumber(YB)); matrix.add(new PdfNumber(ZB)); matrix.add(new PdfNumber(XC)); matrix.add(new PdfNumber(YC)); matrix.add(new PdfNumber(ZC)); dic.put(PdfName.MATRIX, matrix); } dic.put(PdfName.WHITEPOINT, wp); array.add(dic); } return array; } } Image getImage() throws IOException { readPng(); try { int pal0 = 0; int palIdx = 0; palShades = false; if (trans != null) { for (int k = 0; k < trans.length; ++k) { int n = trans[k] & 0xff; if (n == 0) { ++pal0; palIdx = k; } if (n != 0 && n != 255) { palShades = true; break; } } } if ((colorType & 4) != 0) palShades = true; genBWMask = (!palShades && (pal0 > 1 || transRedGray >= 0)); if (!palShades && !genBWMask && pal0 == 1) { additional.put(PdfName.MASK, new PdfLiteral("["+palIdx+" "+palIdx+"]")); } boolean needDecode = (interlaceMethod == 1) || (bitDepth == 16) || ((colorType & 4) != 0) || palShades || genBWMask; switch (colorType) { case 0: inputBands = 1; break; case 2: inputBands = 3; break; case 3: inputBands = 1; break; case 4: inputBands = 2; break; case 6: inputBands = 4; break; } if (needDecode) decodeIdat(); int components = inputBands; if ((colorType & 4) != 0) --components; int bpc = bitDepth; if (bpc == 16) bpc = 8; Image img; if (image != null) { if (colorType == 3) img = new ImgRaw(width, height, components, bpc, image); else img = Image.getInstance(width, height, components, bpc, image); } else { img = new ImgRaw(width, height, components, bpc, idat.toByteArray()); img.setDeflated(true); PdfDictionary decodeparms = new PdfDictionary(); decodeparms.put(PdfName.BITSPERCOMPONENT, new PdfNumber(bitDepth)); decodeparms.put(PdfName.PREDICTOR, new PdfNumber(15)); decodeparms.put(PdfName.COLUMNS, new PdfNumber(width)); decodeparms.put(PdfName.COLORS, new PdfNumber((colorType == 3 || (colorType & 2) == 0) ? 1 : 3)); additional.put(PdfName.DECODEPARMS, decodeparms); } if (additional.get(PdfName.COLORSPACE) == null) additional.put(PdfName.COLORSPACE, getColorspace()); if (intent != null) additional.put(PdfName.INTENT, intent); if (additional.size() > 0) img.setAdditional(additional); if (icc_profile != null) img.tagICC(icc_profile); if (palShades) { Image im2 = Image.getInstance(width, height, 1, 8, smask); im2.makeMask(); img.setImageMask(im2); } if (genBWMask) { Image im2 = Image.getInstance(width, height, 1, 1, smask); im2.makeMask(); img.setImageMask(im2); } img.setDpi(dpiX, dpiY); img.setXYRatio(XYRatio); img.setOriginalType(Image.ORIGINAL_PNG); return img; } catch (Exception e) { throw new ExceptionConverter(e); } } void decodeIdat() { int nbitDepth = bitDepth; if (nbitDepth == 16) nbitDepth = 8; int size = -1; bytesPerPixel = (bitDepth == 16) ? 2 : 1; switch (colorType) { case 0: size = (nbitDepth * width + 7) / 8 * height; break; case 2: size = width * 3 * height; bytesPerPixel *= 3; break; case 3: if (interlaceMethod == 1) size = (nbitDepth * width + 7) / 8 * height; bytesPerPixel = 1; break; case 4: size = width * height; bytesPerPixel *= 2; break; case 6: size = width * 3 * height; bytesPerPixel *= 4; break; } if (size >= 0) image = new byte[size]; if (palShades) smask = new byte[width * height]; else if (genBWMask) smask = new byte[(width + 7) / 8 * height]; ByteArrayInputStream bai = new ByteArrayInputStream(idat.getBuf(), 0, idat.size()); InputStream infStream = new InflaterInputStream(bai, new Inflater()); dataStream = new DataInputStream(infStream); if (interlaceMethod != 1) { decodePass(0, 0, 1, 1, width, height); } else { decodePass(0, 0, 8, 8, (width + 7)/8, (height + 7)/8); decodePass(4, 0, 8, 8, (width + 3)/8, (height + 7)/8); decodePass(0, 4, 4, 8, (width + 3)/4, (height + 3)/8); decodePass(2, 0, 4, 4, (width + 1)/4, (height + 3)/4); decodePass(0, 2, 2, 4, (width + 1)/2, (height + 1)/4); decodePass(1, 0, 2, 2, width/2, (height + 1)/2); decodePass(0, 1, 1, 2, width, height/2); } } void decodePass( int xOffset, int yOffset, int xStep, int yStep, int passWidth, int passHeight) { if ((passWidth == 0) || (passHeight == 0)) { return; } int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8; byte[] curr = new byte[bytesPerRow]; byte[] prior = new byte[bytesPerRow]; // Decode the (sub)image row-by-row int srcY, dstY; for (srcY = 0, dstY = yOffset; srcY < passHeight; srcY++, dstY += yStep) { // Read the filter type byte and a row of data int filter = 0; try { filter = dataStream.read(); dataStream.readFully(curr, 0, bytesPerRow); } catch (Exception e) { // empty on purpose } switch (filter) { case PNG_FILTER_NONE: break; case PNG_FILTER_SUB: decodeSubFilter(curr, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_UP: decodeUpFilter(curr, prior, bytesPerRow); break; case PNG_FILTER_AVERAGE: decodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel); break; case PNG_FILTER_PAETH: decodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel); break; default: // Error -- uknown filter type throw new RuntimeException("PNG filter unknown."); } processPixels(curr, xOffset, xStep, dstY, passWidth); // Swap curr and prior byte[] tmp = prior; prior = curr; curr = tmp; } } void processPixels(byte curr[], int xOffset, int step, int y, int width) { int srcX, dstX; int out[] = getPixel(curr); int sizes = 0; switch (colorType) { case 0: case 3: case 4: sizes = 1; break; case 2: case 6: sizes = 3; break; } if (image != null) { dstX = xOffset; int yStride = (sizes*this.width*(bitDepth == 16 ? 8 : bitDepth)+ 7)/8; for (srcX = 0; srcX < width; srcX++) { setPixel(image, out, inputBands * srcX, sizes, dstX, y, bitDepth, yStride); dstX += step; } } if (palShades) { if ((colorType & 4) != 0) { if (bitDepth == 16) { for (int k = 0; k < width; ++k) out[k * inputBands + sizes] >>>= 8; } int yStride = this.width; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { setPixel(smask, out, inputBands * srcX + sizes, 1, dstX, y, 8, yStride); dstX += step; } } else { //colorType 3 int yStride = this.width; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int idx = out[srcX]; if (idx < trans.length) v[0] = trans[idx]; else v[0] = 255; // Patrick Valsecchi setPixel(smask, v, 0, 1, dstX, y, 8, yStride); dstX += step; } } } else if (genBWMask) { switch (colorType) { case 3: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int idx = out[srcX]; v[0] = ((idx < trans.length && trans[idx] == 0) ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } case 0: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int g = out[srcX]; v[0] = (g == transRedGray ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } case 2: { int yStride = (this.width + 7) / 8; int v[] = new int[1]; dstX = xOffset; for (srcX = 0; srcX < width; srcX++) { int markRed = inputBands * srcX; v[0] = (out[markRed] == transRedGray && out[markRed + 1] == transGreen && out[markRed + 2] == transBlue ? 1 : 0); setPixel(smask, v, 0, 1, dstX, y, 1, yStride); dstX += step; } break; } } } } static int getPixel(byte image[], int x, int y, int bitDepth, int bytesPerRow) { if (bitDepth == 8) { int pos = bytesPerRow * y + x; return image[pos] & 0xff; } else { int pos = bytesPerRow * y + x / (8 / bitDepth); int v = image[pos] >> (8 - bitDepth * (x % (8 / bitDepth))- bitDepth); return v & ((1 << bitDepth) - 1); } } static void setPixel(byte image[], int data[], int offset, int size, int x, int y, int bitDepth, int bytesPerRow) { if (bitDepth == 8) { int pos = bytesPerRow * y + size * x; for (int k = 0; k < size; ++k) image[pos + k] = (byte)data[k + offset]; } else if (bitDepth == 16) { int pos = bytesPerRow * y + size * x; for (int k = 0; k < size; ++k) image[pos + k] = (byte)(data[k + offset] >>> 8); } else { int pos = bytesPerRow * y + x / (8 / bitDepth); int v = data[offset] << (8 - bitDepth * (x % (8 / bitDepth))- bitDepth); image[pos] |= v; } } int[] getPixel(byte curr[]) { switch (bitDepth) { case 8: { int out[] = new int[curr.length]; for (int k = 0; k < out.length; ++k) out[k] = curr[k] & 0xff; return out; } case 16: { int out[] = new int[curr.length / 2]; for (int k = 0; k < out.length; ++k) out[k] = ((curr[k * 2] & 0xff) << 8) + (curr[k * 2 + 1] & 0xff); return out; } default: { int out[] = new int[curr.length * 8 / bitDepth]; int idx = 0; int passes = 8 / bitDepth; int mask = (1 << bitDepth) - 1; for (int k = 0; k < curr.length; ++k) { for (int j = passes - 1; j >= 0; --j) { out[idx++] = (curr[k] >>> (bitDepth * j)) & mask; } } return out; } } } private static void decodeSubFilter(byte[] curr, int count, int bpp) { for (int i = bpp; i < count; i++) { int val; val = curr[i] & 0xff; val += curr[i - bpp] & 0xff; curr[i] = (byte)val; } } private static void decodeUpFilter(byte[] curr, byte[] prev, int count) { for (int i = 0; i < count; i++) { int raw = curr[i] & 0xff; int prior = prev[i] & 0xff; curr[i] = (byte)(raw + prior); } } private static void decodeAverageFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw, priorPixel, priorRow; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow/2); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + (priorPixel + priorRow)/2); } } private static int paethPredictor(int a, int b, int c) { int p = a + b - c; int pa = Math.abs(p - a); int pb = Math.abs(p - b); int pc = Math.abs(p - c); if ((pa <= pb) && (pa <= pc)) { return a; } else if (pb <= pc) { return b; } else { return c; } } private static void decodePaethFilter(byte[] curr, byte[] prev, int count, int bpp) { int raw, priorPixel, priorRow, priorRowPixel; for (int i = 0; i < bpp; i++) { raw = curr[i] & 0xff; priorRow = prev[i] & 0xff; curr[i] = (byte)(raw + priorRow); } for (int i = bpp; i < count; i++) { raw = curr[i] & 0xff; priorPixel = curr[i - bpp] & 0xff; priorRow = prev[i] & 0xff; priorRowPixel = prev[i - bpp] & 0xff; curr[i] = (byte)(raw + paethPredictor(priorPixel, priorRow, priorRowPixel)); } } static class NewByteArrayOutputStream extends ByteArrayOutputStream { public byte[] getBuf() { return buf; } } /** * Gets an int from an InputStream. * * @param is an InputStream * @return the value of an int */ public static final int getInt(InputStream is) throws IOException { return (is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read(); } /** * Gets a word from an InputStream. * * @param is an InputStream * @return the value of an int */ public static final int getWord(InputStream is) throws IOException { return (is.read() << 8) + is.read(); } /** * Gets a String from an InputStream. * * @param is an InputStream * @return the value of an int */ public static final String getString(InputStream is) throws IOException { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 4; i++) { buf.append((char)is.read()); } return buf.toString(); } } src/core/com/lowagie/text/pdf/codec/TIFFConstants.java100644 0 0 50720 11000354046 20250 0ustar 0 0 /* * Copyright 2003-2005 by Paulo Soares. * * This list of constants was originally released with libtiff * under the following license: * * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ package com.lowagie.text.pdf.codec; /** * A list of constants used in class TIFFImage. */ public class TIFFConstants { /* * TIFF Tag Definitions (from tifflib). */ public static final int TIFFTAG_SUBFILETYPE = 254; /* subfile data descriptor */ public static final int FILETYPE_REDUCEDIMAGE = 0x1; /* reduced resolution version */ public static final int FILETYPE_PAGE = 0x2; /* one page of many */ public static final int FILETYPE_MASK = 0x4; /* transparency mask */ public static final int TIFFTAG_OSUBFILETYPE = 255; /* +kind of data in subfile */ public static final int OFILETYPE_IMAGE = 1; /* full resolution image data */ public static final int OFILETYPE_REDUCEDIMAGE = 2; /* reduced size image data */ public static final int OFILETYPE_PAGE = 3; /* one page of many */ public static final int TIFFTAG_IMAGEWIDTH = 256; /* image width in pixels */ public static final int TIFFTAG_IMAGELENGTH = 257; /* image height in pixels */ public static final int TIFFTAG_BITSPERSAMPLE = 258; /* bits per channel (sample) */ public static final int TIFFTAG_COMPRESSION = 259; /* data compression technique */ public static final int COMPRESSION_NONE = 1; /* dump mode */ public static final int COMPRESSION_CCITTRLE = 2; /* CCITT modified Huffman RLE */ public static final int COMPRESSION_CCITTFAX3 = 3; /* CCITT Group 3 fax encoding */ public static final int COMPRESSION_CCITTFAX4 = 4; /* CCITT Group 4 fax encoding */ public static final int COMPRESSION_LZW = 5; /* Lempel-Ziv & Welch */ public static final int COMPRESSION_OJPEG = 6; /* !6.0 JPEG */ public static final int COMPRESSION_JPEG = 7; /* %JPEG DCT compression */ public static final int COMPRESSION_NEXT = 32766; /* NeXT 2-bit RLE */ public static final int COMPRESSION_CCITTRLEW = 32771; /* #1 w/ word alignment */ public static final int COMPRESSION_PACKBITS = 32773; /* Macintosh RLE */ public static final int COMPRESSION_THUNDERSCAN = 32809; /* ThunderScan RLE */ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ public static final int COMPRESSION_DCS = 32947; /* Kodak DCS encoding */ public static final int COMPRESSION_JBIG = 34661; /* ISO JBIG */ public static final int COMPRESSION_SGILOG = 34676; /* SGI Log Luminance RLE */ public static final int COMPRESSION_SGILOG24 = 34677; /* SGI Log 24-bit packed */ public static final int TIFFTAG_PHOTOMETRIC = 262; /* photometric interpretation */ public static final int PHOTOMETRIC_MINISWHITE = 0; /* min value is white */ public static final int PHOTOMETRIC_MINISBLACK = 1; /* min value is black */ public static final int PHOTOMETRIC_RGB = 2; /* RGB color model */ public static final int PHOTOMETRIC_PALETTE = 3; /* color map indexed */ public static final int PHOTOMETRIC_MASK = 4; /* $holdout mask */ public static final int PHOTOMETRIC_SEPARATED = 5; /* !color separations */ public static final int PHOTOMETRIC_YCBCR = 6; /* !CCIR 601 */ public static final int PHOTOMETRIC_CIELAB = 8; /* !1976 CIE L*a*b* */ public static final int PHOTOMETRIC_LOGL = 32844; /* CIE Log2(L) */ public static final int PHOTOMETRIC_LOGLUV = 32845; /* CIE Log2(L) (u',v') */ public static final int TIFFTAG_THRESHHOLDING = 263; /* +thresholding used on data */ public static final int THRESHHOLD_BILEVEL = 1; /* b&w art scan */ public static final int THRESHHOLD_HALFTONE = 2; /* or dithered scan */ public static final int THRESHHOLD_ERRORDIFFUSE = 3; /* usually floyd-steinberg */ public static final int TIFFTAG_CELLWIDTH = 264; /* +dithering matrix width */ public static final int TIFFTAG_CELLLENGTH = 265; /* +dithering matrix height */ public static final int TIFFTAG_FILLORDER = 266; /* data order within a byte */ public static final int FILLORDER_MSB2LSB = 1; /* most significant -> least */ public static final int FILLORDER_LSB2MSB = 2; /* least significant -> most */ public static final int TIFFTAG_DOCUMENTNAME = 269; /* name of doc. image is from */ public static final int TIFFTAG_IMAGEDESCRIPTION = 270; /* info about image */ public static final int TIFFTAG_MAKE = 271; /* scanner manufacturer name */ public static final int TIFFTAG_MODEL = 272; /* scanner model name/number */ public static final int TIFFTAG_STRIPOFFSETS = 273; /* offsets to data strips */ public static final int TIFFTAG_ORIENTATION = 274; /* +image orientation */ public static final int ORIENTATION_TOPLEFT = 1; /* row 0 top, col 0 lhs */ public static final int ORIENTATION_TOPRIGHT = 2; /* row 0 top, col 0 rhs */ public static final int ORIENTATION_BOTRIGHT = 3; /* row 0 bottom, col 0 rhs */ public static final int ORIENTATION_BOTLEFT = 4; /* row 0 bottom, col 0 lhs */ public static final int ORIENTATION_LEFTTOP = 5; /* row 0 lhs, col 0 top */ public static final int ORIENTATION_RIGHTTOP = 6; /* row 0 rhs, col 0 top */ public static final int ORIENTATION_RIGHTBOT = 7; /* row 0 rhs, col 0 bottom */ public static final int ORIENTATION_LEFTBOT = 8; /* row 0 lhs, col 0 bottom */ public static final int TIFFTAG_SAMPLESPERPIXEL = 277; /* samples per pixel */ public static final int TIFFTAG_ROWSPERSTRIP = 278; /* rows per strip of data */ public static final int TIFFTAG_STRIPBYTECOUNTS = 279; /* bytes counts for strips */ public static final int TIFFTAG_MINSAMPLEVALUE = 280; /* +minimum sample value */ public static final int TIFFTAG_MAXSAMPLEVALUE = 281; /* +maximum sample value */ public static final int TIFFTAG_XRESOLUTION = 282; /* pixels/resolution in x */ public static final int TIFFTAG_YRESOLUTION = 283; /* pixels/resolution in y */ public static final int TIFFTAG_PLANARCONFIG = 284; /* storage organization */ public static final int PLANARCONFIG_CONTIG = 1; /* single image plane */ public static final int PLANARCONFIG_SEPARATE = 2; /* separate planes of data */ public static final int TIFFTAG_PAGENAME = 285; /* page name image is from */ public static final int TIFFTAG_XPOSITION = 286; /* x page offset of image lhs */ public static final int TIFFTAG_YPOSITION = 287; /* y page offset of image lhs */ public static final int TIFFTAG_FREEOFFSETS = 288; /* +byte offset to free block */ public static final int TIFFTAG_FREEBYTECOUNTS = 289; /* +sizes of free blocks */ public static final int TIFFTAG_GRAYRESPONSEUNIT = 290; /* $gray scale curve accuracy */ public static final int GRAYRESPONSEUNIT_10S = 1; /* tenths of a unit */ public static final int GRAYRESPONSEUNIT_100S = 2; /* hundredths of a unit */ public static final int GRAYRESPONSEUNIT_1000S = 3; /* thousandths of a unit */ public static final int GRAYRESPONSEUNIT_10000S = 4; /* ten-thousandths of a unit */ public static final int GRAYRESPONSEUNIT_100000S = 5; /* hundred-thousandths */ public static final int TIFFTAG_GRAYRESPONSECURVE = 291; /* $gray scale response curve */ public static final int TIFFTAG_GROUP3OPTIONS = 292; /* 32 flag bits */ public static final int GROUP3OPT_2DENCODING = 0x1; /* 2-dimensional coding */ public static final int GROUP3OPT_UNCOMPRESSED = 0x2; /* data not compressed */ public static final int GROUP3OPT_FILLBITS = 0x4; /* fill to byte boundary */ public static final int TIFFTAG_GROUP4OPTIONS = 293; /* 32 flag bits */ public static final int GROUP4OPT_UNCOMPRESSED = 0x2; /* data not compressed */ public static final int TIFFTAG_RESOLUTIONUNIT = 296; /* units of resolutions */ public static final int RESUNIT_NONE = 1; /* no meaningful units */ public static final int RESUNIT_INCH = 2; /* english */ public static final int RESUNIT_CENTIMETER = 3; /* metric */ public static final int TIFFTAG_PAGENUMBER = 297; /* page numbers of multi-page */ public static final int TIFFTAG_COLORRESPONSEUNIT = 300; /* $color curve accuracy */ public static final int COLORRESPONSEUNIT_10S = 1; /* tenths of a unit */ public static final int COLORRESPONSEUNIT_100S = 2; /* hundredths of a unit */ public static final int COLORRESPONSEUNIT_1000S = 3; /* thousandths of a unit */ public static final int COLORRESPONSEUNIT_10000S = 4; /* ten-thousandths of a unit */ public static final int COLORRESPONSEUNIT_100000S = 5; /* hundred-thousandths */ public static final int TIFFTAG_TRANSFERFUNCTION = 301; /* !colorimetry info */ public static final int TIFFTAG_SOFTWARE = 305; /* name & release */ public static final int TIFFTAG_DATETIME = 306; /* creation date and time */ public static final int TIFFTAG_ARTIST = 315; /* creator of image */ public static final int TIFFTAG_HOSTCOMPUTER = 316; /* machine where created */ public static final int TIFFTAG_PREDICTOR = 317; /* prediction scheme w/ LZW */ public static final int TIFFTAG_WHITEPOINT = 318; /* image white point */ public static final int TIFFTAG_PRIMARYCHROMATICITIES = 319; /* !primary chromaticities */ public static final int TIFFTAG_COLORMAP = 320; /* RGB map for pallette image */ public static final int TIFFTAG_HALFTONEHINTS = 321; /* !highlight+shadow info */ public static final int TIFFTAG_TILEWIDTH = 322; /* !rows/data tile */ public static final int TIFFTAG_TILELENGTH = 323; /* !cols/data tile */ public static final int TIFFTAG_TILEOFFSETS = 324; /* !offsets to data tiles */ public static final int TIFFTAG_TILEBYTECOUNTS = 325; /* !byte counts for tiles */ public static final int TIFFTAG_BADFAXLINES = 326; /* lines w/ wrong pixel count */ public static final int TIFFTAG_CLEANFAXDATA = 327; /* regenerated line info */ public static final int CLEANFAXDATA_CLEAN = 0; /* no errors detected */ public static final int CLEANFAXDATA_REGENERATED = 1; /* receiver regenerated lines */ public static final int CLEANFAXDATA_UNCLEAN = 2; /* uncorrected errors exist */ public static final int TIFFTAG_CONSECUTIVEBADFAXLINES = 328; /* max consecutive bad lines */ public static final int TIFFTAG_SUBIFD = 330; /* subimage descriptors */ public static final int TIFFTAG_INKSET = 332; /* !inks in separated image */ public static final int INKSET_CMYK = 1; /* !cyan-magenta-yellow-black */ public static final int TIFFTAG_INKNAMES = 333; /* !ascii names of inks */ public static final int TIFFTAG_NUMBEROFINKS = 334; /* !number of inks */ public static final int TIFFTAG_DOTRANGE = 336; /* !0% and 100% dot codes */ public static final int TIFFTAG_TARGETPRINTER = 337; /* !separation target */ public static final int TIFFTAG_EXTRASAMPLES = 338; /* !info about extra samples */ public static final int EXTRASAMPLE_UNSPECIFIED = 0; /* !unspecified data */ public static final int EXTRASAMPLE_ASSOCALPHA = 1; /* !associated alpha data */ public static final int EXTRASAMPLE_UNASSALPHA = 2; /* !unassociated alpha data */ public static final int TIFFTAG_SAMPLEFORMAT = 339; /* !data sample format */ public static final int SAMPLEFORMAT_UINT = 1; /* !unsigned integer data */ public static final int SAMPLEFORMAT_INT = 2; /* !signed integer data */ public static final int SAMPLEFORMAT_IEEEFP = 3; /* !IEEE floating point data */ public static final int SAMPLEFORMAT_VOID = 4; /* !untyped data */ public static final int SAMPLEFORMAT_COMPLEXINT = 5; /* !complex signed int */ public static final int SAMPLEFORMAT_COMPLEXIEEEFP = 6; /* !complex ieee floating */ public static final int TIFFTAG_SMINSAMPLEVALUE = 340; /* !variable MinSampleValue */ public static final int TIFFTAG_SMAXSAMPLEVALUE = 341; /* !variable MaxSampleValue */ public static final int TIFFTAG_JPEGTABLES = 347; /* %JPEG table stream */ /* * Tags 512-521 are obsoleted by Technical Note #2 * which specifies a revised JPEG-in-TIFF scheme. */ public static final int TIFFTAG_JPEGPROC = 512; /* !JPEG processing algorithm */ public static final int JPEGPROC_BASELINE = 1; /* !baseline sequential */ public static final int JPEGPROC_LOSSLESS = 14; /* !Huffman coded lossless */ public static final int TIFFTAG_JPEGIFOFFSET = 513; /* !pointer to SOI marker */ public static final int TIFFTAG_JPEGIFBYTECOUNT = 514; /* !JFIF stream length */ public static final int TIFFTAG_JPEGRESTARTINTERVAL = 515; /* !restart interval length */ public static final int TIFFTAG_JPEGLOSSLESSPREDICTORS = 517; /* !lossless proc predictor */ public static final int TIFFTAG_JPEGPOINTTRANSFORM = 518; /* !lossless point transform */ public static final int TIFFTAG_JPEGQTABLES = 519; /* !Q matrice offsets */ public static final int TIFFTAG_JPEGDCTABLES = 520; /* !DCT table offsets */ public static final int TIFFTAG_JPEGACTABLES = 521; /* !AC coefficient offsets */ public static final int TIFFTAG_YCBCRCOEFFICIENTS = 529; /* !RGB -> YCbCr transform */ public static final int TIFFTAG_YCBCRSUBSAMPLING = 530; /* !YCbCr subsampling factors */ public static final int TIFFTAG_YCBCRPOSITIONING = 531; /* !subsample positioning */ public static final int YCBCRPOSITION_CENTERED = 1; /* !as in PostScript Level 2 */ public static final int YCBCRPOSITION_COSITED = 2; /* !as in CCIR 601-1 */ public static final int TIFFTAG_REFERENCEBLACKWHITE = 532; /* !colorimetry info */ /* tags 32952-32956 are private tags registered to Island Graphics */ public static final int TIFFTAG_REFPTS = 32953; /* image reference points */ public static final int TIFFTAG_REGIONTACKPOINT = 32954; /* region-xform tack point */ public static final int TIFFTAG_REGIONWARPCORNERS = 32955; /* warp quadrilateral */ public static final int TIFFTAG_REGIONAFFINE = 32956; /* affine transformation mat */ /* tags 32995-32999 are private tags registered to SGI */ public static final int TIFFTAG_MATTEING = 32995; /* $use ExtraSamples */ public static final int TIFFTAG_DATATYPE = 32996; /* $use SampleFormat */ public static final int TIFFTAG_IMAGEDEPTH = 32997; /* z depth of image */ public static final int TIFFTAG_TILEDEPTH = 32998; /* z depth/data tile */ /* tags 33300-33309 are private tags registered to Pixar */ /* * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH * are set when an image has been cropped out of a larger image. * They reflect the size of the original uncropped image. * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used * to determine the position of the smaller image in the larger one. */ public static final int TIFFTAG_PIXAR_IMAGEFULLWIDTH = 33300; /* full image size in x */ public static final int TIFFTAG_PIXAR_IMAGEFULLLENGTH = 33301; /* full image size in y */ /* Tags 33302-33306 are used to identify special image modes and data * used by Pixar's texture formats. */ public static final int TIFFTAG_PIXAR_TEXTUREFORMAT = 33302; /* texture map format */ public static final int TIFFTAG_PIXAR_WRAPMODES = 33303; /* s & t wrap modes */ public static final int TIFFTAG_PIXAR_FOVCOT = 33304; /* cotan(fov) for env. maps */ public static final int TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN = 33305; public static final int TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA = 33306; /* tag 33405 is a private tag registered to Eastman Kodak */ public static final int TIFFTAG_WRITERSERIALNUMBER = 33405; /* device serial number */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ public static final int TIFFTAG_COPYRIGHT = 33432; /* copyright string */ /* IPTC TAG from RichTIFF specifications */ public static final int TIFFTAG_RICHTIFFIPTC = 33723; /* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ public static final int TIFFTAG_STONITS = 37439; /* Sample value to Nits */ /* tag 34929 is a private tag registered to FedEx */ public static final int TIFFTAG_FEDEX_EDR = 34929; /* unknown use */ /* tag 65535 is an undefined tag used by Eastman Kodak */ public static final int TIFFTAG_DCSHUESHIFTVALUES = 65535; /* hue shift correction data */ } src/core/com/lowagie/text/pdf/codec/TIFFDirectory.java100644 0 0 55574 11036112746 20264 0ustar 0 0 /* * Copyright 2003-2008 by Paulo Soares. * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageio.plugins.tiff.TIFFDirectory.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; import java.io.EOFException; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * A class representing an Image File Directory (IFD) from a TIFF 6.0 * stream. The TIFF file format is described in more detail in the * comments for the TIFFDescriptor class. * *

    A TIFF IFD consists of a set of TIFFField tags. Methods are * provided to query the set of tags and to obtain the raw field * array. In addition, convenience methods are provided for acquiring * the values of tags that contain a single value that fits into a * byte, int, long, float, or double. * *

    Every TIFF file is made up of one or more public IFDs that are * joined in a linked list, rooted in the file header. A file may * also contain so-called private IFDs that are referenced from * tag data and do not appear in the main list. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * * @see TIFFField */ public class TIFFDirectory extends Object implements Serializable { private static final long serialVersionUID = -168636766193675380L; /** A boolean storing the endianness of the stream. */ boolean isBigEndian; /** The number of entries in the IFD. */ int numEntries; /** An array of TIFFFields. */ TIFFField[] fields; /** A Hashtable indexing the fields by tag number. */ Hashtable fieldIndex = new Hashtable(); /** The offset of this IFD. */ long IFDOffset = 8; /** The offset of the next IFD. */ long nextIFDOffset = 0; /** The default constructor. */ TIFFDirectory() {} private static boolean isValidEndianTag(int endian) { return ((endian == 0x4949) || (endian == 0x4d4d)); } /** * Constructs a TIFFDirectory from a SeekableStream. * The directory parameter specifies which directory to read from * the linked list present in the stream; directory 0 is normally * read but it is possible to store multiple images in a single * TIFF file by maintaining multiple directories. * * @param stream a SeekableStream to read from. * @param directory the index of the directory to read. */ public TIFFDirectory(RandomAccessFileOrArray stream, int directory) throws IOException { long global_save_offset = stream.getFilePointer(); long ifd_offset; // Read the TIFF header stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } isBigEndian = (endian == 0x4d4d); int magic = readUnsignedShort(stream); if (magic != 42) { throw new IllegalArgumentException("Bad magic number, should be 42."); } // Get the initial ifd offset as an unsigned int (using a long) ifd_offset = readUnsignedInt(stream); for (int i = 0; i < directory; i++) { if (ifd_offset == 0L) { throw new IllegalArgumentException("Directory number too large."); } stream.seek(ifd_offset); int entries = readUnsignedShort(stream); stream.skip(12*entries); ifd_offset = readUnsignedInt(stream); } stream.seek(ifd_offset); initialize(stream); stream.seek(global_save_offset); } /** * Constructs a TIFFDirectory by reading a SeekableStream. * The ifd_offset parameter specifies the stream offset from which * to begin reading; this mechanism is sometimes used to store * private IFDs within a TIFF file that are not part of the normal * sequence of IFDs. * * @param stream a SeekableStream to read from. * @param ifd_offset the long byte offset of the directory. * @param directory the index of the directory to read beyond the * one at the current stream offset; zero indicates the IFD * at the current offset. */ public TIFFDirectory(RandomAccessFileOrArray stream, long ifd_offset, int directory) throws IOException { long global_save_offset = stream.getFilePointer(); stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } isBigEndian = (endian == 0x4d4d); // Seek to the first IFD. stream.seek(ifd_offset); // Seek to desired IFD if necessary. int dirNum = 0; while(dirNum < directory) { // Get the number of fields in the current IFD. int numEntries = readUnsignedShort(stream); // Skip to the next IFD offset value field. stream.seek(ifd_offset + 12*numEntries); // Read the offset to the next IFD beyond this one. ifd_offset = readUnsignedInt(stream); // Seek to the next IFD. stream.seek(ifd_offset); // Increment the directory. dirNum++; } initialize(stream); stream.seek(global_save_offset); } private static final int[] sizeOfType = { 0, // 0 = n/a 1, // 1 = byte 1, // 2 = ascii 2, // 3 = short 4, // 4 = long 8, // 5 = rational 1, // 6 = sbyte 1, // 7 = undefined 2, // 8 = sshort 4, // 9 = slong 8, // 10 = srational 4, // 11 = float 8 // 12 = double }; private void initialize(RandomAccessFileOrArray stream) throws IOException { long nextTagOffset = 0L; long maxOffset = stream.length(); int i, j; IFDOffset = stream.getFilePointer(); numEntries = readUnsignedShort(stream); fields = new TIFFField[numEntries]; for (i = 0; (i < numEntries) && (nextTagOffset < maxOffset); i++) { int tag = readUnsignedShort(stream); int type = readUnsignedShort(stream); int count = (int)(readUnsignedInt(stream)); boolean processTag = true; // The place to return to to read the next tag nextTagOffset = stream.getFilePointer() + 4; try { // If the tag data can't fit in 4 bytes, the next 4 bytes // contain the starting offset of the data if (count*sizeOfType[type] > 4) { long valueOffset = readUnsignedInt(stream); // bounds check offset for EOF if (valueOffset < maxOffset) { stream.seek(valueOffset); } else { // bad offset pointer .. skip tag processTag = false; } } } catch (ArrayIndexOutOfBoundsException ae) { // if the data type is unknown we should skip this TIFF Field processTag = false; } if (processTag) { fieldIndex.put(new Integer(tag), new Integer(i)); Object obj = null; switch (type) { case TIFFField.TIFF_BYTE: case TIFFField.TIFF_SBYTE: case TIFFField.TIFF_UNDEFINED: case TIFFField.TIFF_ASCII: byte[] bvalues = new byte[count]; stream.readFully(bvalues, 0, count); if (type == TIFFField.TIFF_ASCII) { // Can be multiple strings int index = 0, prevIndex = 0; ArrayList v = new ArrayList(); while (index < count) { while ((index < count) && (bvalues[index++] != 0)); // When we encountered zero, means one string has ended v.add(new String(bvalues, prevIndex, (index - prevIndex)) ); prevIndex = index; } count = v.size(); String strings[] = new String[count]; for (int c = 0 ; c < count; c++) { strings[c] = (String)v.get(c); } obj = strings; } else { obj = bvalues; } break; case TIFFField.TIFF_SHORT: char[] cvalues = new char[count]; for (j = 0; j < count; j++) { cvalues[j] = (char)(readUnsignedShort(stream)); } obj = cvalues; break; case TIFFField.TIFF_LONG: long[] lvalues = new long[count]; for (j = 0; j < count; j++) { lvalues[j] = readUnsignedInt(stream); } obj = lvalues; break; case TIFFField.TIFF_RATIONAL: long[][] llvalues = new long[count][2]; for (j = 0; j < count; j++) { llvalues[j][0] = readUnsignedInt(stream); llvalues[j][1] = readUnsignedInt(stream); } obj = llvalues; break; case TIFFField.TIFF_SSHORT: short[] svalues = new short[count]; for (j = 0; j < count; j++) { svalues[j] = readShort(stream); } obj = svalues; break; case TIFFField.TIFF_SLONG: int[] ivalues = new int[count]; for (j = 0; j < count; j++) { ivalues[j] = readInt(stream); } obj = ivalues; break; case TIFFField.TIFF_SRATIONAL: int[][] iivalues = new int[count][2]; for (j = 0; j < count; j++) { iivalues[j][0] = readInt(stream); iivalues[j][1] = readInt(stream); } obj = iivalues; break; case TIFFField.TIFF_FLOAT: float[] fvalues = new float[count]; for (j = 0; j < count; j++) { fvalues[j] = readFloat(stream); } obj = fvalues; break; case TIFFField.TIFF_DOUBLE: double[] dvalues = new double[count]; for (j = 0; j < count; j++) { dvalues[j] = readDouble(stream); } obj = dvalues; break; default: break; } fields[i] = new TIFFField(tag, type, count, obj); } stream.seek(nextTagOffset); } // Read the offset of the next IFD. try { nextIFDOffset = readUnsignedInt(stream); } catch (Exception e) { // broken tiffs may not have this pointer nextIFDOffset = 0; } } /** Returns the number of directory entries. */ public int getNumEntries() { return numEntries; } /** * Returns the value of a given tag as a TIFFField, * or null if the tag is not present. */ public TIFFField getField(int tag) { Integer i = (Integer)fieldIndex.get(new Integer(tag)); if (i == null) { return null; } else { return fields[i.intValue()]; } } /** * Returns true if a tag appears in the directory. */ public boolean isTagPresent(int tag) { return fieldIndex.containsKey(new Integer(tag)); } /** * Returns an ordered array of ints indicating the tag * values. */ public int[] getTags() { int[] tags = new int[fieldIndex.size()]; Enumeration e = fieldIndex.keys(); int i = 0; while (e.hasMoreElements()) { tags[i++] = ((Integer)e.nextElement()).intValue(); } return tags; } /** * Returns an array of TIFFFields containing all the fields * in this directory. */ public TIFFField[] getFields() { return fields; } /** * Returns the value of a particular index of a given tag as a * byte. The caller is responsible for ensuring that the tag is * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or * TIFF_UNDEFINED. */ public byte getFieldAsByte(int tag, int index) { Integer i = (Integer)fieldIndex.get(new Integer(tag)); byte [] b = fields[i.intValue()].getAsBytes(); return b[index]; } /** * Returns the value of index 0 of a given tag as a * byte. The caller is responsible for ensuring that the tag is * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or * TIFF_UNDEFINED. */ public byte getFieldAsByte(int tag) { return getFieldAsByte(tag, 0); } /** * Returns the value of a particular index of a given tag as a * long. The caller is responsible for ensuring that the tag is * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG. */ public long getFieldAsLong(int tag, int index) { Integer i = (Integer)fieldIndex.get(new Integer(tag)); return fields[i.intValue()].getAsLong(index); } /** * Returns the value of index 0 of a given tag as a * long. The caller is responsible for ensuring that the tag is * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG. */ public long getFieldAsLong(int tag) { return getFieldAsLong(tag, 0); } /** * Returns the value of a particular index of a given tag as a * float. The caller is responsible for ensuring that the tag is * present and has numeric type (all but TIFF_UNDEFINED and * TIFF_ASCII). */ public float getFieldAsFloat(int tag, int index) { Integer i = (Integer)fieldIndex.get(new Integer(tag)); return fields[i.intValue()].getAsFloat(index); } /** * Returns the value of index 0 of a given tag as a float. The * caller is responsible for ensuring that the tag is present and * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII). */ public float getFieldAsFloat(int tag) { return getFieldAsFloat(tag, 0); } /** * Returns the value of a particular index of a given tag as a * double. The caller is responsible for ensuring that the tag is * present and has numeric type (all but TIFF_UNDEFINED and * TIFF_ASCII). */ public double getFieldAsDouble(int tag, int index) { Integer i = (Integer)fieldIndex.get(new Integer(tag)); return fields[i.intValue()].getAsDouble(index); } /** * Returns the value of index 0 of a given tag as a double. The * caller is responsible for ensuring that the tag is present and * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII). */ public double getFieldAsDouble(int tag) { return getFieldAsDouble(tag, 0); } // Methods to read primitive data types from the stream private short readShort(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readShort(); } else { return stream.readShortLE(); } } private int readUnsignedShort(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readUnsignedShort(); } else { return stream.readUnsignedShortLE(); } } private int readInt(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readInt(); } else { return stream.readIntLE(); } } private long readUnsignedInt(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readUnsignedInt(); } else { return stream.readUnsignedIntLE(); } } private long readLong(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readLong(); } else { return stream.readLongLE(); } } private float readFloat(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readFloat(); } else { return stream.readFloatLE(); } } private double readDouble(RandomAccessFileOrArray stream) throws IOException { if (isBigEndian) { return stream.readDouble(); } else { return stream.readDoubleLE(); } } private static int readUnsignedShort(RandomAccessFileOrArray stream, boolean isBigEndian) throws IOException { if (isBigEndian) { return stream.readUnsignedShort(); } else { return stream.readUnsignedShortLE(); } } private static long readUnsignedInt(RandomAccessFileOrArray stream, boolean isBigEndian) throws IOException { if (isBigEndian) { return stream.readUnsignedInt(); } else { return stream.readUnsignedIntLE(); } } // Utilities /** * Returns the number of image directories (subimages) stored in a * given TIFF file, represented by a SeekableStream. */ public static int getNumDirectories(RandomAccessFileOrArray stream) throws IOException{ long pointer = stream.getFilePointer(); // Save stream pointer stream.seek(0L); int endian = stream.readUnsignedShort(); if (!isValidEndianTag(endian)) { throw new IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } boolean isBigEndian = (endian == 0x4d4d); int magic = readUnsignedShort(stream, isBigEndian); if (magic != 42) { throw new IllegalArgumentException("Bad magic number, should be 42."); } stream.seek(4L); long offset = readUnsignedInt(stream, isBigEndian); int numDirectories = 0; while (offset != 0L) { ++numDirectories; // EOFException means IFD was probably not properly terminated. try { stream.seek(offset); int entries = readUnsignedShort(stream, isBigEndian); stream.skip(12*entries); offset = readUnsignedInt(stream, isBigEndian); } catch(EOFException eof) { //numDirectories--; break; } } stream.seek(pointer); // Reset stream pointer return numDirectories; } /** * Returns a boolean indicating whether the byte order used in the * the TIFF file is big-endian (i.e. whether the byte order is from * the most significant to the least significant) */ public boolean isBigEndian() { return isBigEndian; } /** * Returns the offset of the IFD corresponding to this * TIFFDirectory. */ public long getIFDOffset() { return IFDOffset; } /** * Returns the offset of the next IFD after the IFD corresponding to this * TIFFDirectory. */ public long getNextIFDOffset() { return nextIFDOffset; } } src/core/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java100644 0 0 164145 11036112746 20337 0ustar 0 0 /* * Copyright 2003-2009 by Paulo Soares. * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageioimpl.plugins.tiff.TIFFFaxDecompressor.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; public class TIFFFaxDecoder { private int bitPointer, bytePointer; private byte[] data; private int w, h; private int fillOrder; // Data structures needed to store changing elements for the previous // and the current scanline private int changingElemSize = 0; private int prevChangingElems[]; private int currChangingElems[]; // Element at which to start search in getNextChangingElement private int lastChangingElement = 0; private int compression = 2; // Variables set by T4Options private int uncompressedMode = 0; private int fillBits = 0; private int oneD; static int table1[] = { 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN 0x01, // 1 bits are left in first byte 0x03, // 2 bits are left in first byte 0x07, // 3 bits are left in first byte 0x0f, // 4 bits are left in first byte 0x1f, // 5 bits are left in first byte 0x3f, // 6 bits are left in first byte 0x7f, // 7 bits are left in first byte 0xff // 8 bits are left in first byte }; static int table2[] = { 0x00, // 0 0x80, // 1 0xc0, // 2 0xe0, // 3 0xf0, // 4 0xf8, // 5 0xfc, // 6 0xfe, // 7 0xff // 8 }; // Table to be used when fillOrder = 2, for flipping bytes. static byte flipTable[] = { 0, -128, 64, -64, 32, -96, 96, -32, 16, -112, 80, -48, 48, -80, 112, -16, 8, -120, 72, -56, 40, -88, 104, -24, 24, -104, 88, -40, 56, -72, 120, -8, 4, -124, 68, -60, 36, -92, 100, -28, 20, -108, 84, -44, 52, -76, 116, -12, 12, -116, 76, -52, 44, -84, 108, -20, 28, -100, 92, -36, 60, -68, 124, -4, 2, -126, 66, -62, 34, -94, 98, -30, 18, -110, 82, -46, 50, -78, 114, -14, 10, -118, 74, -54, 42, -86, 106, -22, 26, -102, 90, -38, 58, -70, 122, -6, 6, -122, 70, -58, 38, -90, 102, -26, 22, -106, 86, -42, 54, -74, 118, -10, 14, -114, 78, -50, 46, -82, 110, -18, 30, -98, 94, -34, 62, -66, 126, -2, 1, -127, 65, -63, 33, -95, 97, -31, 17, -111, 81, -47, 49, -79, 113, -15, 9, -119, 73, -55, 41, -87, 105, -23, 25, -103, 89, -39, 57, -71, 121, -7, 5, -123, 69, -59, 37, -91, 101, -27, 21, -107, 85, -43, 53, -75, 117, -11, 13, -115, 77, -51, 45, -83, 109, -19, 29, -99, 93, -35, 61, -67, 125, -3, 3, -125, 67, -61, 35, -93, 99, -29, 19, -109, 83, -45, 51, -77, 115, -13, 11, -117, 75, -53, 43, -85, 107, -21, 27, -101, 91, -37, 59, -69, 123, -5, 7, -121, 71, -57, 39, -89, 103, -25, 23, -105, 87, -41, 55, -73, 119, -9, 15, -113, 79, -49, 47, -81, 111, -17, 31, -97, 95, -33, 63, -65, 127, -1, }; // The main 10 bit white runs lookup table static short white[] = { // 0 - 7 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225, // 8 - 15 944, 944, 944, 944, 976, 976, 976, 976, // 16 - 23 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488, // 24 - 31 718, 718, 718, 718, 718, 718, 718, 718, // 32 - 39 750, 750, 750, 750, 750, 750, 750, 750, // 40 - 47 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552, // 48 - 55 428, 428, 428, 428, 428, 428, 428, 428, // 56 - 63 428, 428, 428, 428, 428, 428, 428, 428, // 64 - 71 654, 654, 654, 654, 654, 654, 654, 654, // 72 - 79 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104, // 80 - 87 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168, // 88 - 95 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232, // 96 - 103 622, 622, 622, 622, 622, 622, 622, 622, // 104 - 111 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040, // 112 - 119 44, 44, 44, 44, 44, 44, 44, 44, // 120 - 127 44, 44, 44, 44, 44, 44, 44, 44, // 128 - 135 396, 396, 396, 396, 396, 396, 396, 396, // 136 - 143 396, 396, 396, 396, 396, 396, 396, 396, // 144 - 151 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744, // 152 - 159 846, 846, 846, 846, 846, 846, 846, 846, // 160 - 167 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296, // 168 - 175 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360, // 176 - 183 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424, // 184 - 191 686, 686, 686, 686, 686, 686, 686, 686, // 192 - 199 910, 910, 910, 910, 910, 910, 910, 910, // 200 - 207 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000, // 208 - 215 2032, 2032, 2032, 2032, 16, 16, 16, 16, // 216 - 223 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305, // 224 - 231 330, 330, 330, 330, 330, 330, 330, 330, // 232 - 239 330, 330, 330, 330, 330, 330, 330, 330, // 240 - 247 330, 330, 330, 330, 330, 330, 330, 330, // 248 - 255 330, 330, 330, 330, 330, 330, 330, 330, // 256 - 263 362, 362, 362, 362, 362, 362, 362, 362, // 264 - 271 362, 362, 362, 362, 362, 362, 362, 362, // 272 - 279 362, 362, 362, 362, 362, 362, 362, 362, // 280 - 287 362, 362, 362, 362, 362, 362, 362, 362, // 288 - 295 878, 878, 878, 878, 878, 878, 878, 878, // 296 - 303 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936, // 304 - 311 -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221, // 312 - 319 590, 590, 590, 590, 590, 590, 590, 590, // 320 - 327 782, 782, 782, 782, 782, 782, 782, 782, // 328 - 335 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616, // 336 - 343 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680, // 344 - 351 814, 814, 814, 814, 814, 814, 814, 814, // 352 - 359 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808, // 360 - 367 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872, // 368 - 375 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, // 376 - 383 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157, // 384 - 391 -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, // 392 - 399 -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275, // 400 - 407 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401, // 408 - 415 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497, // 416 - 423 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691, // 424 - 431 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653, // 432 - 439 -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461, // 440 - 447 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207, // 448 - 455 72, 72, 72, 72, 72, 72, 72, 72, // 456 - 463 72, 72, 72, 72, 72, 72, 72, 72, // 464 - 471 72, 72, 72, 72, 72, 72, 72, 72, // 472 - 479 72, 72, 72, 72, 72, 72, 72, 72, // 480 - 487 72, 72, 72, 72, 72, 72, 72, 72, // 488 - 495 72, 72, 72, 72, 72, 72, 72, 72, // 496 - 503 72, 72, 72, 72, 72, 72, 72, 72, // 504 - 511 72, 72, 72, 72, 72, 72, 72, 72, // 512 - 519 104, 104, 104, 104, 104, 104, 104, 104, // 520 - 527 104, 104, 104, 104, 104, 104, 104, 104, // 528 - 535 104, 104, 104, 104, 104, 104, 104, 104, // 536 - 543 104, 104, 104, 104, 104, 104, 104, 104, // 544 - 551 104, 104, 104, 104, 104, 104, 104, 104, // 552 - 559 104, 104, 104, 104, 104, 104, 104, 104, // 560 - 567 104, 104, 104, 104, 104, 104, 104, 104, // 568 - 575 104, 104, 104, 104, 104, 104, 104, 104, // 576 - 583 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 584 - 591 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 592 - 599 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 600 - 607 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, // 608 - 615 266, 266, 266, 266, 266, 266, 266, 266, // 616 - 623 266, 266, 266, 266, 266, 266, 266, 266, // 624 - 631 266, 266, 266, 266, 266, 266, 266, 266, // 632 - 639 266, 266, 266, 266, 266, 266, 266, 266, // 640 - 647 298, 298, 298, 298, 298, 298, 298, 298, // 648 - 655 298, 298, 298, 298, 298, 298, 298, 298, // 656 - 663 298, 298, 298, 298, 298, 298, 298, 298, // 664 - 671 298, 298, 298, 298, 298, 298, 298, 298, // 672 - 679 524, 524, 524, 524, 524, 524, 524, 524, // 680 - 687 524, 524, 524, 524, 524, 524, 524, 524, // 688 - 695 556, 556, 556, 556, 556, 556, 556, 556, // 696 - 703 556, 556, 556, 556, 556, 556, 556, 556, // 704 - 711 136, 136, 136, 136, 136, 136, 136, 136, // 712 - 719 136, 136, 136, 136, 136, 136, 136, 136, // 720 - 727 136, 136, 136, 136, 136, 136, 136, 136, // 728 - 735 136, 136, 136, 136, 136, 136, 136, 136, // 736 - 743 136, 136, 136, 136, 136, 136, 136, 136, // 744 - 751 136, 136, 136, 136, 136, 136, 136, 136, // 752 - 759 136, 136, 136, 136, 136, 136, 136, 136, // 760 - 767 136, 136, 136, 136, 136, 136, 136, 136, // 768 - 775 168, 168, 168, 168, 168, 168, 168, 168, // 776 - 783 168, 168, 168, 168, 168, 168, 168, 168, // 784 - 791 168, 168, 168, 168, 168, 168, 168, 168, // 792 - 799 168, 168, 168, 168, 168, 168, 168, 168, // 800 - 807 168, 168, 168, 168, 168, 168, 168, 168, // 808 - 815 168, 168, 168, 168, 168, 168, 168, 168, // 816 - 823 168, 168, 168, 168, 168, 168, 168, 168, // 824 - 831 168, 168, 168, 168, 168, 168, 168, 168, // 832 - 839 460, 460, 460, 460, 460, 460, 460, 460, // 840 - 847 460, 460, 460, 460, 460, 460, 460, 460, // 848 - 855 492, 492, 492, 492, 492, 492, 492, 492, // 856 - 863 492, 492, 492, 492, 492, 492, 492, 492, // 864 - 871 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 872 - 879 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 880 - 887 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 888 - 895 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059, // 896 - 903 200, 200, 200, 200, 200, 200, 200, 200, // 904 - 911 200, 200, 200, 200, 200, 200, 200, 200, // 912 - 919 200, 200, 200, 200, 200, 200, 200, 200, // 920 - 927 200, 200, 200, 200, 200, 200, 200, 200, // 928 - 935 200, 200, 200, 200, 200, 200, 200, 200, // 936 - 943 200, 200, 200, 200, 200, 200, 200, 200, // 944 - 951 200, 200, 200, 200, 200, 200, 200, 200, // 952 - 959 200, 200, 200, 200, 200, 200, 200, 200, // 960 - 967 232, 232, 232, 232, 232, 232, 232, 232, // 968 - 975 232, 232, 232, 232, 232, 232, 232, 232, // 976 - 983 232, 232, 232, 232, 232, 232, 232, 232, // 984 - 991 232, 232, 232, 232, 232, 232, 232, 232, // 992 - 999 232, 232, 232, 232, 232, 232, 232, 232, // 1000 - 1007 232, 232, 232, 232, 232, 232, 232, 232, // 1008 - 1015 232, 232, 232, 232, 232, 232, 232, 232, // 1016 - 1023 232, 232, 232, 232, 232, 232, 232, 232, }; // Additional make up codes for both White and Black runs static short additionalMakeup[] = { 28679, 28679, 31752, (short)32777, (short)33801, (short)34825, (short)35849, (short)36873, (short)29703, (short)29703, (short)30727, (short)30727, (short)37897, (short)38921, (short)39945, (short)40969 }; // Initial black run look up table, uses the first 4 bits of a code static short initBlack[] = { // 0 - 7 3226, 6412, 200, 168, 38, 38, 134, 134, // 8 - 15 100, 100, 100, 100, 68, 68, 68, 68 }; // static short twoBitBlack[] = {292, 260, 226, 226}; // 0 - 3 // Main black run table, using the last 9 bits of possible 13 bit code static short black[] = { // 0 - 7 62, 62, 30, 30, 0, 0, 0, 0, // 8 - 15 0, 0, 0, 0, 0, 0, 0, 0, // 16 - 23 0, 0, 0, 0, 0, 0, 0, 0, // 24 - 31 0, 0, 0, 0, 0, 0, 0, 0, // 32 - 39 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 40 - 47 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 48 - 55 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 56 - 63 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225, // 64 - 71 588, 588, 588, 588, 588, 588, 588, 588, // 72 - 79 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776, // 80 - 87 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904, // 88 - 95 1936, 1936, -16365, -14317, 782, 782, 782, 782, // 96 - 103 814, 814, 814, 814, -12269, -10221, 10257, 10257, // 104 - 111 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712, // 112 - 119 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605, // 120 - 127 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061, // 128 - 135 424, 424, 424, 424, 424, 424, 424, 424, // 136 - 143 424, 424, 424, 424, 424, 424, 424, 424, // 144 - 151 424, 424, 424, 424, 424, 424, 424, 424, // 152 - 159 424, 424, 424, 424, 424, 424, 424, 424, // 160 - 167 750, 750, 750, 750, 1616, 1616, 1648, 1648, // 168 - 175 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520, // 176 - 183 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209, // 184 - 191 524, 524, 524, 524, 524, 524, 524, 524, // 192 - 199 556, 556, 556, 556, 556, 556, 556, 556, // 200 - 207 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032, // 208 - 215 976, 976, 1008, 1008, 1040, 1040, 1072, 1072, // 216 - 223 1296, 1296, 1328, 1328, 718, 718, 718, 718, // 224 - 231 456, 456, 456, 456, 456, 456, 456, 456, // 232 - 239 456, 456, 456, 456, 456, 456, 456, 456, // 240 - 247 456, 456, 456, 456, 456, 456, 456, 456, // 248 - 255 456, 456, 456, 456, 456, 456, 456, 456, // 256 - 263 326, 326, 326, 326, 326, 326, 326, 326, // 264 - 271 326, 326, 326, 326, 326, 326, 326, 326, // 272 - 279 326, 326, 326, 326, 326, 326, 326, 326, // 280 - 287 326, 326, 326, 326, 326, 326, 326, 326, // 288 - 295 326, 326, 326, 326, 326, 326, 326, 326, // 296 - 303 326, 326, 326, 326, 326, 326, 326, 326, // 304 - 311 326, 326, 326, 326, 326, 326, 326, 326, // 312 - 319 326, 326, 326, 326, 326, 326, 326, 326, // 320 - 327 358, 358, 358, 358, 358, 358, 358, 358, // 328 - 335 358, 358, 358, 358, 358, 358, 358, 358, // 336 - 343 358, 358, 358, 358, 358, 358, 358, 358, // 344 - 351 358, 358, 358, 358, 358, 358, 358, 358, // 352 - 359 358, 358, 358, 358, 358, 358, 358, 358, // 360 - 367 358, 358, 358, 358, 358, 358, 358, 358, // 368 - 375 358, 358, 358, 358, 358, 358, 358, 358, // 376 - 383 358, 358, 358, 358, 358, 358, 358, 358, // 384 - 391 490, 490, 490, 490, 490, 490, 490, 490, // 392 - 399 490, 490, 490, 490, 490, 490, 490, 490, // 400 - 407 4113, 4113, 6161, 6161, 848, 848, 880, 880, // 408 - 415 912, 912, 944, 944, 622, 622, 622, 622, // 416 - 423 654, 654, 654, 654, 1104, 1104, 1136, 1136, // 424 - 431 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264, // 432 - 439 686, 686, 686, 686, 1360, 1360, 1392, 1392, // 440 - 447 12, 12, 12, 12, 12, 12, 12, 12, // 448 - 455 390, 390, 390, 390, 390, 390, 390, 390, // 456 - 463 390, 390, 390, 390, 390, 390, 390, 390, // 464 - 471 390, 390, 390, 390, 390, 390, 390, 390, // 472 - 479 390, 390, 390, 390, 390, 390, 390, 390, // 480 - 487 390, 390, 390, 390, 390, 390, 390, 390, // 488 - 495 390, 390, 390, 390, 390, 390, 390, 390, // 496 - 503 390, 390, 390, 390, 390, 390, 390, 390, // 504 - 511 390, 390, 390, 390, 390, 390, 390, 390, }; static byte twoDCodes[] = { // 0 - 7 80, 88, 23, 71, 30, 30, 62, 62, // 8 - 15 4, 4, 4, 4, 4, 4, 4, 4, // 16 - 23 11, 11, 11, 11, 11, 11, 11, 11, // 24 - 31 11, 11, 11, 11, 11, 11, 11, 11, // 32 - 39 35, 35, 35, 35, 35, 35, 35, 35, // 40 - 47 35, 35, 35, 35, 35, 35, 35, 35, // 48 - 55 51, 51, 51, 51, 51, 51, 51, 51, // 56 - 63 51, 51, 51, 51, 51, 51, 51, 51, // 64 - 71 41, 41, 41, 41, 41, 41, 41, 41, // 72 - 79 41, 41, 41, 41, 41, 41, 41, 41, // 80 - 87 41, 41, 41, 41, 41, 41, 41, 41, // 88 - 95 41, 41, 41, 41, 41, 41, 41, 41, // 96 - 103 41, 41, 41, 41, 41, 41, 41, 41, // 104 - 111 41, 41, 41, 41, 41, 41, 41, 41, // 112 - 119 41, 41, 41, 41, 41, 41, 41, 41, // 120 - 127 41, 41, 41, 41, 41, 41, 41, 41, }; /** * @param fillOrder The fill order of the compressed data bytes. * @param w * @param h */ public TIFFFaxDecoder(int fillOrder, int w, int h) { this.fillOrder = fillOrder; this.w = w; this.h = h; this.bitPointer = 0; this.bytePointer = 0; this.prevChangingElems = new int[w]; this.currChangingElems = new int[w]; } /** * Reverses the bits in the array * @param b the bits to reverse * * @since 2.0.7 */ public static void reverseBits(byte[] b) { for (int k = 0; k < b.length; ++k) b[k] = flipTable[b[k] & 0xff]; } // One-dimensional decoding methods public void decode1D(byte[] buffer, byte[] compData, int startX, int height) { this.data = compData; int lineOffset = 0; int scanlineStride = (w + 7)/8; bitPointer = 0; bytePointer = 0; for (int i = 0; i < height; i++) { decodeNextScanline(buffer, lineOffset, startX); lineOffset += scanlineStride; } } public void decodeNextScanline(byte[] buffer, int lineOffset, int bitOffset) { int bits = 0, code = 0, isT = 0; int current, entry, twoBits; boolean isWhite = true; // Initialize starting of the changing elements array changingElemSize = 0; // While scanline not complete while (bitOffset < w) { while (isWhite) { // White run current = nextNBits(10); entry = white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x0f; if (bits == 12) { // Additional Make up code // Get the next 2 bits twoBits = nextLesserThan8Bits(2); // Consolidate the 2 new bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits bitOffset += code; // Skip white run updatePointer(4 - bits); } else if (bits == 0) { // ERROR throw new RuntimeException("Invalid code encountered."); } else if (bits == 15) { // EOL throw new RuntimeException("EOL code word encountered in White run."); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >>> 5) & 0x07ff; bitOffset += code; updatePointer(10 - bits); if (isT == 0) { isWhite = false; currChangingElems[changingElemSize++] = bitOffset; } } } // Check whether this run completed one width, if so // advance to next byte boundary for compression = 2. if (bitOffset == w) { if (compression == 2) { advancePointer(); } break; } while (!isWhite) { // Black run current = nextLesserThan8Bits(4); entry = initBlack[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (code == 100) { current = nextNBits(9); entry = black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (bits == 12) { // Additional makeup codes updatePointer(5); current = nextLesserThan8Bits(4); entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(4 - bits); } else if (bits == 15) { // EOL code throw new RuntimeException("EOL code word encountered in Black run."); } else { setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(9 - bits); if (isT == 0) { isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } } } else if (code == 200) { // Is a Terminating code current = nextLesserThan8Bits(2); entry = twoBitBlack[current]; code = (entry >>> 5) & 0x07ff; bits = (entry >>> 1) & 0x0f; setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(2 - bits); isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } else { // Is a Terminating code setToBlack(buffer, lineOffset, bitOffset, code); bitOffset += code; updatePointer(4 - bits); isWhite = true; currChangingElems[changingElemSize++] = bitOffset; } } // Check whether this run completed one width if (bitOffset == w) { if (compression == 2) { advancePointer(); } break; } } currChangingElems[changingElemSize++] = bitOffset; } // Two-dimensional decoding methods public void decode2D(byte[] buffer, byte compData[], int startX, int height, long tiffT4Options) { this.data = compData; compression = 3; bitPointer = 0; bytePointer = 0; int scanlineStride = (w + 7)/8; int a0, a1, b1, b2; int[] b = new int[2]; int entry, code, bits; boolean isWhite; int currIndex = 0; int temp[]; // fillBits - dealt with this in readEOL // 1D/2D encoding - dealt with this in readEOL // uncompressedMode - haven't dealt with this yet. oneD = (int)(tiffT4Options & 0x01); uncompressedMode = (int)((tiffT4Options & 0x02) >> 1); fillBits = (int)((tiffT4Options & 0x04) >> 2); // The data must start with an EOL code if (readEOL(true) != 1) { throw new RuntimeException("First scanline must be 1D encoded."); } int lineOffset = 0; int bitOffset; // Then the 1D encoded scanline data will occur, changing elements // array gets set. decodeNextScanline(buffer, lineOffset, startX); lineOffset += scanlineStride; for (int lines = 1; lines < height; lines++) { // Every line must begin with an EOL followed by a bit which // indicates whether the following scanline is 1D or 2D encoded. if (readEOL(false) == 0) { // 2D encoded scanline follows // Initialize previous scanlines changing elements, and // initialize current scanline's changing elements array temp = prevChangingElems; prevChangingElems = currChangingElems; currChangingElems = temp; currIndex = 0; // a0 has to be set just before the start of this scanline. a0 = -1; isWhite = true; bitOffset = startX; lastChangingElement = 0; while (bitOffset < w) { // Get the next changing element getNextChangingElement(a0, isWhite, b); b1 = b[0]; b2 = b[1]; // Get the next seven bits entry = nextLesserThan8Bits(7); // Run these through the 2DCodes table entry = twoDCodes[entry] & 0xff; // Get the code and the number of bits used up code = (entry & 0x78) >>> 3; bits = entry & 0x07; if (code == 0) { if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset); } bitOffset = a0 = b2; // Set pointer to consume the correct number of bits. updatePointer(7 - bits); } else if (code == 1) { // Horizontal updatePointer(7 - bits); // identify the next 2 codes. int number; if (isWhite) { number = decodeWhiteCodeWord(); bitOffset += number; currChangingElems[currIndex++] = bitOffset; number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; currChangingElems[currIndex++] = bitOffset; } else { number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; currChangingElems[currIndex++] = bitOffset; number = decodeWhiteCodeWord(); bitOffset += number; currChangingElems[currIndex++] = bitOffset; } a0 = bitOffset; } else if (code <= 8) { // Vertical a1 = b1 + (code - 5); currChangingElems[currIndex++] = a1; // We write the current color till a1 - 1 pos, // since a1 is where the next color starts if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset); } bitOffset = a0 = a1; isWhite = !isWhite; updatePointer(7 - bits); } else { throw new RuntimeException("Invalid code encountered while decoding 2D group 3 compressed data."); } } // Add the changing element beyond the current scanline for the // other color too currChangingElems[currIndex++] = bitOffset; changingElemSize = currIndex; } else { // 1D encoded scanline follows decodeNextScanline(buffer, lineOffset, startX); } lineOffset += scanlineStride; } } public void decodeT6(byte[] buffer, byte[] compData, int startX, int height, long tiffT6Options) { this.data = compData; compression = 4; bitPointer = 0; bytePointer = 0; int scanlineStride = (w + 7)/8; int a0, a1, b1, b2; int entry, code, bits; boolean isWhite; int currIndex; int temp[]; // Return values from getNextChangingElement int[] b = new int[2]; // uncompressedMode - have written some code for this, but this // has not been tested due to lack of test images using this optional uncompressedMode = (int)((tiffT6Options & 0x02) >> 1); // Local cached reference int[] cce = currChangingElems; // Assume invisible preceding row of all white pixels and insert // both black and white changing elements beyond the end of this // imaginary scanline. changingElemSize = 0; cce[changingElemSize++] = w; cce[changingElemSize++] = w; int lineOffset = 0; int bitOffset; for (int lines = 0; lines < height; lines++) { // a0 has to be set just before the start of the scanline. a0 = -1; isWhite = true; // Assign the changing elements of the previous scanline to // prevChangingElems and start putting this new scanline's // changing elements into the currChangingElems. temp = prevChangingElems; prevChangingElems = currChangingElems; cce = currChangingElems = temp; currIndex = 0; // Start decoding the scanline at startX in the raster bitOffset = startX; // Reset search start position for getNextChangingElement lastChangingElement = 0; // Till one whole scanline is decoded while (bitOffset < w) { // Get the next changing element getNextChangingElement(a0, isWhite, b); b1 = b[0]; b2 = b[1]; // Get the next seven bits entry = nextLesserThan8Bits(7); // Run these through the 2DCodes table entry = twoDCodes[entry] & 0xff; // Get the code and the number of bits used up code = (entry & 0x78) >>> 3; bits = entry & 0x07; if (code == 0) { // Pass // We always assume WhiteIsZero format for fax. if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, b2 - bitOffset); } bitOffset = a0 = b2; // Set pointer to only consume the correct number of bits. updatePointer(7 - bits); } else if (code == 1) { // Horizontal // Set pointer to only consume the correct number of bits. updatePointer(7 - bits); // identify the next 2 alternating color codes. int number; if (isWhite) { // Following are white and black runs number = decodeWhiteCodeWord(); bitOffset += number; cce[currIndex++] = bitOffset; number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; cce[currIndex++] = bitOffset; } else { // First a black run and then a white run follows number = decodeBlackCodeWord(); setToBlack(buffer, lineOffset, bitOffset, number); bitOffset += number; cce[currIndex++] = bitOffset; number = decodeWhiteCodeWord(); bitOffset += number; cce[currIndex++] = bitOffset; } a0 = bitOffset; } else if (code <= 8) { // Vertical a1 = b1 + (code - 5); cce[currIndex++] = a1; // We write the current color till a1 - 1 pos, // since a1 is where the next color starts if (!isWhite) { setToBlack(buffer, lineOffset, bitOffset, a1 - bitOffset); } bitOffset = a0 = a1; isWhite = !isWhite; updatePointer(7 - bits); } else if (code == 11) { if (nextLesserThan8Bits(3) != 7) { throw new RuntimeException("Invalid code encountered while decoding 2D group 4 compressed data."); } int zeros = 0; boolean exit = false; while (!exit) { while (nextLesserThan8Bits(1) != 1) { zeros++; } if (zeros > 5) { // Exit code // Zeros before exit code zeros = zeros - 6; if (!isWhite && (zeros > 0)) { cce[currIndex++] = bitOffset; } // Zeros before the exit code bitOffset += zeros; if (zeros > 0) { // Some zeros have been written isWhite = true; } // Read in the bit which specifies the color of // the following run if (nextLesserThan8Bits(1) == 0) { if (!isWhite) { cce[currIndex++] = bitOffset; } isWhite = true; } else { if (isWhite) { cce[currIndex++] = bitOffset; } isWhite = false; } exit = true; } if (zeros == 5) { if (!isWhite) { cce[currIndex++] = bitOffset; } bitOffset += zeros; // Last thing written was white isWhite = true; } else { bitOffset += zeros; cce[currIndex++] = bitOffset; setToBlack(buffer, lineOffset, bitOffset, 1); ++bitOffset; // Last thing written was black isWhite = false; } } } else { //micah_tessler@yahoo.com //Microsoft TIFF renderers seem to treat unknown codes as line-breaks //That is, they give up on the current line and move on to the next one //set bitOffset to w to move on to the next scan line. bitOffset = w; updatePointer(7 - bits); } } // Add the changing element beyond the current scanline for the // other color too //make sure that the index does not exceed the bounds of the array if(currIndex < cce.length) cce[currIndex++] = bitOffset; // Number of changing elements in this scanline. changingElemSize = currIndex; lineOffset += scanlineStride; } } private void setToBlack(byte[] buffer, int lineOffset, int bitOffset, int numBits) { int bitNum = 8*lineOffset + bitOffset; int lastBit = bitNum + numBits; int byteNum = bitNum >> 3; // Handle bits in first byte int shift = bitNum & 0x7; if (shift > 0) { int maskVal = 1 << (7 - shift); byte val = buffer[byteNum]; while (maskVal > 0 && bitNum < lastBit) { val |= maskVal; maskVal >>= 1; ++bitNum; } buffer[byteNum] = val; } // Fill in 8 bits at a time byteNum = bitNum >> 3; while (bitNum < lastBit - 7) { buffer[byteNum++] = (byte)255; bitNum += 8; } // Fill in remaining bits while (bitNum < lastBit) { byteNum = bitNum >> 3; buffer[byteNum] |= 1 << (7 - (bitNum & 0x7)); ++bitNum; } } // Returns run length private int decodeWhiteCodeWord() { int current, entry, bits, isT, twoBits, code = -1; int runLength = 0; boolean isWhite = true; while (isWhite) { current = nextNBits(10); entry = white[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x0f; if (bits == 12) { // Additional Make up code // Get the next 2 bits twoBits = nextLesserThan8Bits(2); // Consolidate the 2 new bits and last 2 bits into 4 bits current = ((current << 2) & 0x000c) | twoBits; entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits runLength += code; updatePointer(4 - bits); } else if (bits == 0) { // ERROR throw new RuntimeException("Invalid code encountered."); } else if (bits == 15) { // EOL throw new RuntimeException("EOL code word encountered in White run."); } else { // 11 bits - 0000 0111 1111 1111 = 0x07ff code = (entry >>> 5) & 0x07ff; runLength += code; updatePointer(10 - bits); if (isT == 0) { isWhite = false; } } } return runLength; } // Returns run length private int decodeBlackCodeWord() { int current, entry, bits, isT, code = -1; int runLength = 0; boolean isWhite = false; while (!isWhite) { current = nextLesserThan8Bits(4); entry = initBlack[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (code == 100) { current = nextNBits(9); entry = black[current]; // Get the 3 fields from the entry isT = entry & 0x0001; bits = (entry >>> 1) & 0x000f; code = (entry >>> 5) & 0x07ff; if (bits == 12) { // Additional makeup codes updatePointer(5); current = nextLesserThan8Bits(4); entry = additionalMakeup[current]; bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111 code = (entry >>> 4) & 0x0fff; // 12 bits runLength += code; updatePointer(4 - bits); } else if (bits == 15) { // EOL code throw new RuntimeException("EOL code word encountered in Black run."); } else { runLength += code; updatePointer(9 - bits); if (isT == 0) { isWhite = true; } } } else if (code == 200) { // Is a Terminating code current = nextLesserThan8Bits(2); entry = twoBitBlack[current]; code = (entry >>> 5) & 0x07ff; runLength += code; bits = (entry >>> 1) & 0x0f; updatePointer(2 - bits); isWhite = true; } else { // Is a Terminating code runLength += code; updatePointer(4 - bits); isWhite = true; } } return runLength; } private int readEOL(boolean isFirstEOL) { if (fillBits == 0) { int next12Bits = nextNBits(12); if (isFirstEOL && next12Bits == 0) { // Might have the case of EOL padding being used even // though it was not flagged in the T4Options field. // This was observed to be the case in TIFFs produced // by a well known vendor who shall remain nameless. if(nextNBits(4) == 1) { // EOL must be padded: reset the fillBits flag. fillBits = 1; return 1; } } if(next12Bits != 1) { throw new RuntimeException("Scanline must begin with EOL code word."); } } else if (fillBits == 1) { // First EOL code word xxxx 0000 0000 0001 will occur // As many fill bits will be present as required to make // the EOL code of 12 bits end on a byte boundary. int bitsLeft = 8 - bitPointer; if (nextNBits(bitsLeft) != 0) { throw new RuntimeException("All fill bits preceding EOL code must be 0."); } // If the number of bitsLeft is less than 8, then to have a 12 // bit EOL sequence, two more bytes are certainly going to be // required. The first of them has to be all zeros, so ensure // that. if (bitsLeft < 4) { if (nextNBits(8) != 0) { throw new RuntimeException("All fill bits preceding EOL code must be 0."); } } // There might be a random number of fill bytes with 0s, so // loop till the EOL of 0000 0001 is found, as long as all // the bytes preceding it are 0's. int n; while ((n = nextNBits(8)) != 1) { // If not all zeros if (n != 0) { throw new RuntimeException("All fill bits preceding EOL code must be 0."); } } } // If one dimensional encoding mode, then always return 1 if (oneD == 0) { return 1; } else { // Otherwise for 2D encoding mode, // The next one bit signifies 1D/2D encoding of next line. return nextLesserThan8Bits(1); } } private void getNextChangingElement(int a0, boolean isWhite, int[] ret) { // Local copies of instance variables int[] pce = this.prevChangingElems; int ces = this.changingElemSize; // If the previous match was at an odd element, we still // have to search the preceeding element. // int start = lastChangingElement & ~0x1; int start = lastChangingElement > 0 ? lastChangingElement - 1 : 0; if (isWhite) { start &= ~0x1; // Search even numbered elements } else { start |= 0x1; // Search odd numbered elements } int i = start; for (; i < ces; i += 2) { int temp = pce[i]; if (temp > a0) { lastChangingElement = i; ret[0] = temp; break; } } if (i + 1 < ces) { ret[1] = pce[i + 1]; } } private int nextNBits(int bitsToGet) { byte b, next, next2next; int l = data.length - 1; int bp = this.bytePointer; if (fillOrder == 1) { b = data[bp]; if (bp == l) { next = 0x00; next2next = 0x00; } else if ((bp + 1) == l) { next = data[bp + 1]; next2next = 0x00; } else { next = data[bp + 1]; next2next = data[bp + 2]; } } else if (fillOrder == 2) { b = flipTable[data[bp] & 0xff]; if (bp == l) { next = 0x00; next2next = 0x00; } else if ((bp + 1) == l) { next = flipTable[data[bp + 1] & 0xff]; next2next = 0x00; } else { next = flipTable[data[bp + 1] & 0xff]; next2next = flipTable[data[bp + 2] & 0xff]; } } else { throw new RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2."); } int bitsLeft = 8 - bitPointer; int bitsFromNextByte = bitsToGet - bitsLeft; int bitsFromNext2NextByte = 0; if (bitsFromNextByte > 8) { bitsFromNext2NextByte = bitsFromNextByte - 8; bitsFromNextByte = 8; } bytePointer++; int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft); int i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); int i3 = 0; if (bitsFromNext2NextByte != 0) { i2 <<= bitsFromNext2NextByte; i3 = (next2next & table2[bitsFromNext2NextByte]) >>> (8 - bitsFromNext2NextByte); i2 |= i3; bytePointer++; bitPointer = bitsFromNext2NextByte; } else { if (bitsFromNextByte == 8) { bitPointer = 0; bytePointer++; } else { bitPointer = bitsFromNextByte; } } int i = i1 | i2; return i; } private int nextLesserThan8Bits(int bitsToGet) { byte b, next; int l = data.length - 1; int bp = this.bytePointer; if (fillOrder == 1) { b = data[bp]; if (bp == l) { next = 0x00; } else { next = data[bp + 1]; } } else if (fillOrder == 2) { b = flipTable[data[bp] & 0xff]; if (bp == l) { next = 0x00; } else { next = flipTable[data[bp + 1] & 0xff]; } } else { throw new RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2."); } int bitsLeft = 8 - bitPointer; int bitsFromNextByte = bitsToGet - bitsLeft; int shift = bitsLeft - bitsToGet; int i1, i2; if (shift >= 0) { i1 = (b & table1[bitsLeft]) >>> shift; bitPointer += bitsToGet; if (bitPointer == 8) { bitPointer = 0; bytePointer++; } } else { i1 = (b & table1[bitsLeft]) << (-shift); i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte); i1 |= i2; bytePointer++; bitPointer = bitsFromNextByte; } return i1; } // Move pointer backwards by given amount of bits private void updatePointer(int bitsToMoveBack) { int i = bitPointer - bitsToMoveBack; if (i < 0) { bytePointer--; bitPointer = 8 + i; } else { bitPointer = i; } } // Move to the next byte boundary private boolean advancePointer() { if (bitPointer != 0) { bytePointer++; bitPointer = 0; } return true; } } src/core/com/lowagie/text/pdf/codec/TIFFField.java100644 0 0 36673 11000354046 17332 0ustar 0 0 /* * Copyright 2003-2008 by Paulo Soares. * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageio.plugins.tiff.TIFFField.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; import java.io.Serializable; /** * A class representing a field in a TIFF 6.0 Image File Directory. * *

    The TIFF file format is described in more detail in the * comments for the TIFFDescriptor class. * *

    A field in a TIFF Image File Directory (IFD). A field is defined * as a sequence of values of identical data type. TIFF 6.0 defines * 12 data types, which are mapped internally onto the Java data types * byte, int, long, float, and double. * *

    This class is not a committed part of the JAI API. It may * be removed or changed in future releases of JAI. * * @see TIFFDirectory */ public class TIFFField extends Object implements Comparable, Serializable { private static final long serialVersionUID = 9088332901412823834L; /** Flag for 8 bit unsigned integers. */ public static final int TIFF_BYTE = 1; /** Flag for null-terminated ASCII strings. */ public static final int TIFF_ASCII = 2; /** Flag for 16 bit unsigned integers. */ public static final int TIFF_SHORT = 3; /** Flag for 32 bit unsigned integers. */ public static final int TIFF_LONG = 4; /** Flag for pairs of 32 bit unsigned integers. */ public static final int TIFF_RATIONAL = 5; /** Flag for 8 bit signed integers. */ public static final int TIFF_SBYTE = 6; /** Flag for 8 bit uninterpreted bytes. */ public static final int TIFF_UNDEFINED = 7; /** Flag for 16 bit signed integers. */ public static final int TIFF_SSHORT = 8; /** Flag for 32 bit signed integers. */ public static final int TIFF_SLONG = 9; /** Flag for pairs of 32 bit signed integers. */ public static final int TIFF_SRATIONAL = 10; /** Flag for 32 bit IEEE floats. */ public static final int TIFF_FLOAT = 11; /** Flag for 64 bit IEEE doubles. */ public static final int TIFF_DOUBLE = 12; /** The tag number. */ int tag; /** The tag type. */ int type; /** The number of data items present in the field. */ int count; /** The field data. */ Object data; /** The default constructor. */ TIFFField() {} /** * Constructs a TIFFField with arbitrary data. The data * parameter must be an array of a Java type appropriate for the * type of the TIFF field. Since there is no available 32-bit * unsigned data type, long is used. The mapping between types is * as follows: * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    TIFF type Java type
    TIFF_BYTE byte
    TIFF_ASCII String
    TIFF_SHORT char
    TIFF_LONG long
    TIFF_RATIONAL long[2]
    TIFF_SBYTE byte
    TIFF_UNDEFINED byte
    TIFF_SSHORT short
    TIFF_SLONG int
    TIFF_SRATIONAL int[2]
    TIFF_FLOAT float
    TIFF_DOUBLE double
    */ public TIFFField(int tag, int type, int count, Object data) { this.tag = tag; this.type = type; this.count = count; this.data = data; } /** * Returns the tag number, between 0 and 65535. */ public int getTag() { return tag; } /** * Returns the type of the data stored in the IFD. * For a TIFF6.0 file, the value will equal one of the * TIFF_ constants defined in this class. For future * revisions of TIFF, higher values are possible. * */ public int getType() { return type; } /** * Returns the number of elements in the IFD. */ public int getCount() { return count; } /** * Returns the data as an uninterpreted array of bytes. * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE, * or TIFF_UNDEFINED; * *

    For data in TIFF_BYTE format, the application must take * care when promoting the data to longer integral types * to avoid sign extension. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED. */ public byte[] getAsBytes() { return (byte[])data; } /** * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SHORT. */ public char[] getAsChars() { return (char[])data; } /** * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SSHORT. */ public short[] getAsShorts() { return (short[])data; } /** * Returns TIFF_SLONG data as an array of ints (signed 32-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SLONG. */ public int[] getAsInts() { return (int[])data; } /** * Returns TIFF_LONG data as an array of longs (signed 64-bit * integers). * *

    A ClassCastException will be thrown if the field is not * of type TIFF_LONG. */ public long[] getAsLongs() { return (long[])data; } /** * Returns TIFF_FLOAT data as an array of floats. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_FLOAT. */ public float[] getAsFloats() { return (float[])data; } /** * Returns TIFF_DOUBLE data as an array of doubles. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_DOUBLE. */ public double[] getAsDoubles() { return (double[])data; } /** * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SRATIONAL. */ public int[][] getAsSRationals() { return (int[][])data; } /** * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_RATTIONAL. */ public long[][] getAsRationals() { return (long[][])data; } /** * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, or TIFF_SLONG format as an int. * *

    TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned; * that is, no sign extension will take place and the returned * value will be in the range [0, 255]. TIFF_SBYTE data will * be returned in the range [-128, 127]. * *

    A ClassCastException will be thrown if the field is not of * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, or TIFF_SLONG. */ public int getAsInt(int index) { switch (type) { case TIFF_BYTE: case TIFF_UNDEFINED: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; default: throw new ClassCastException(); } } /** * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long. * *

    TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned; * that is, no sign extension will take place and the returned * value will be in the range [0, 255]. TIFF_SBYTE data will * be returned in the range [-128, 127]. * *

    A ClassCastException will be thrown if the field is not of * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT, * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG. */ public long getAsLong(int index) { switch (type) { case TIFF_BYTE: case TIFF_UNDEFINED: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; default: throw new ClassCastException(); } } /** * Returns data in any numerical format as a float. Data in * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by * dividing the numerator into the denominator using * double-precision arithmetic and then truncating to single * precision. Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE * format may suffer from truncation. * *

    A ClassCastException will be thrown if the field is * of type TIFF_UNDEFINED or TIFF_ASCII. */ public float getAsFloat(int index) { switch (type) { case TIFF_BYTE: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; case TIFF_FLOAT: return ((float[])data)[index]; case TIFF_DOUBLE: return (float)((double[])data)[index]; case TIFF_SRATIONAL: int[] ivalue = getAsSRational(index); return (float)((double)ivalue[0]/ivalue[1]); case TIFF_RATIONAL: long[] lvalue = getAsRational(index); return (float)((double)lvalue[0]/lvalue[1]); default: throw new ClassCastException(); } } /** * Returns data in any numerical format as a float. Data in * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by * dividing the numerator into the denominator using * double-precision arithmetic. * *

    A ClassCastException will be thrown if the field is of * type TIFF_UNDEFINED or TIFF_ASCII. */ public double getAsDouble(int index) { switch (type) { case TIFF_BYTE: return ((byte[])data)[index] & 0xff; case TIFF_SBYTE: return ((byte[])data)[index]; case TIFF_SHORT: return ((char[])data)[index] & 0xffff; case TIFF_SSHORT: return ((short[])data)[index]; case TIFF_SLONG: return ((int[])data)[index]; case TIFF_LONG: return ((long[])data)[index]; case TIFF_FLOAT: return ((float[])data)[index]; case TIFF_DOUBLE: return ((double[])data)[index]; case TIFF_SRATIONAL: int[] ivalue = getAsSRational(index); return (double)ivalue[0]/ivalue[1]; case TIFF_RATIONAL: long[] lvalue = getAsRational(index); return (double)lvalue[0]/lvalue[1]; default: throw new ClassCastException(); } } /** * Returns a TIFF_ASCII data item as a String. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_ASCII. */ public String getAsString(int index) { return ((String[])data)[index]; } /** * Returns a TIFF_SRATIONAL data item as a two-element array * of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_SRATIONAL. */ public int[] getAsSRational(int index) { return ((int[][])data)[index]; } /** * Returns a TIFF_RATIONAL data item as a two-element array * of ints. * *

    A ClassCastException will be thrown if the field is not * of type TIFF_RATIONAL. */ public long[] getAsRational(int index) { if (type == TIFF_LONG) return getAsLongs(); return ((long[][])data)[index]; } /** * Compares this TIFFField with another * TIFFField by comparing the tags. * *

    Note: this class has a natural ordering that is inconsistent * with equals(). * * @throws IllegalArgumentException if the parameter is null. * @throws ClassCastException if the parameter is not a * TIFFField. */ public int compareTo(Object o) { if(o == null) { throw new IllegalArgumentException(); } int oTag = ((TIFFField)o).getTag(); if(tag < oTag) { return -1; } else if(tag > oTag) { return 1; } else { return 0; } } } src/core/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java100644 0 0 20553 11000354046 20237 0ustar 0 0 /* * Copyright 2003-2008 by Paulo Soares. * * This code was originally released in 2001 by SUN (see class * com.sun.media.imageioimpl.plugins.tiff.TIFFLZWDecompressor.java) * using the BSD license in a specific wording. In a mail dating from * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission * to use the code under the following version of the BSD license: * * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for * use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.lowagie.text.pdf.codec; /** * A class for performing LZW decoding. * * */ public class TIFFLZWDecoder { byte stringTable[][]; byte data[] = null, uncompData[]; int tableIndex, bitsToGet = 9; int bytePointer, bitPointer; int dstIndex; int w, h; int predictor, samplesPerPixel; int nextData = 0; int nextBits = 0; int andTable[] = { 511, 1023, 2047, 4095 }; public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) { this.w = w; this.predictor = predictor; this.samplesPerPixel = samplesPerPixel; } /** * Method to decode LZW compressed data. * * @param data The compressed data. * @param uncompData Array to return the uncompressed data in. * @param h The number of rows the compressed data contains. */ public byte[] decode(byte data[], byte uncompData[], int h) { if(data[0] == (byte)0x00 && data[1] == (byte)0x01) { throw new UnsupportedOperationException("TIFF 5.0-style LZW codes are not supported."); } initializeStringTable(); this.data = data; this.h = h; this.uncompData = uncompData; // Initialize pointers bytePointer = 0; bitPointer = 0; dstIndex = 0; nextData = 0; nextBits = 0; int code, oldCode = 0; byte string[]; while ( ((code = getNextCode()) != 257) && dstIndex < uncompData.length) { if (code == 256) { initializeStringTable(); code = getNextCode(); if (code == 257) { break; } writeString(stringTable[code]); oldCode = code; } else { if (code < tableIndex) { string = stringTable[code]; writeString(string); addStringToTable(stringTable[oldCode], string[0]); oldCode = code; } else { string = stringTable[oldCode]; string = composeString(string, string[0]); writeString(string); addStringToTable(string); oldCode = code; } } } // Horizontal Differencing Predictor if (predictor == 2) { int count; for (int j = 0; j < h; j++) { count = samplesPerPixel * (j * w + 1); for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) { uncompData[count] += uncompData[count - samplesPerPixel]; count++; } } } return uncompData; } /** * Initialize the string table. */ public void initializeStringTable() { stringTable = new byte[4096][]; for (int i=0; i<256; i++) { stringTable[i] = new byte[1]; stringTable[i][0] = (byte)i; } tableIndex = 258; bitsToGet = 9; } /** * Write out the string just uncompressed. */ public void writeString(byte string[]) { // Fix for broken tiff files int max = uncompData.length - dstIndex; if (string.length < max) max = string.length; System.arraycopy(string, 0, uncompData, dstIndex, max); dstIndex += max; } /** * Add a new string to the string table. */ public void addStringToTable(byte oldString[], byte newString) { int length = oldString.length; byte string[] = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Add a new string to the string table. */ public void addStringToTable(byte string[]) { // Add this new String to the table stringTable[tableIndex++] = string; if (tableIndex == 511) { bitsToGet = 10; } else if (tableIndex == 1023) { bitsToGet = 11; } else if (tableIndex == 2047) { bitsToGet = 12; } } /** * Append newString to the end of oldString. */ public byte[] composeString(byte oldString[], byte newString) { int length = oldString.length; byte string[] = new byte[length + 1]; System.arraycopy(oldString, 0, string, 0, length); string[length] = newString; return string; } // Returns the next 9, 10, 11 or 12 bits public int getNextCode() { // Attempt to get the next code. The exception is caught to make // this robust to cases wherein the EndOfInformation code has been // omitted from a strip. Examples of such cases have been observed // in practice. try { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; if (nextBits < bitsToGet) { nextData = (nextData << 8) | (data[bytePointer++] & 0xff); nextBits += 8; } int code = (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9]; nextBits -= bitsToGet; return code; } catch(ArrayIndexOutOfBoundsException e) { // Strip not terminated as expected: return EndOfInformation code. return 257; } } } src/core/com/lowagie/text/pdf/codec/TiffImage.java100644 0 0 66067 11000354046 17471 0ustar 0 0 /* * Copyright 2003-2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec; import java.awt.color.ICC_Profile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.DataFormatException; import java.util.zip.DeflaterOutputStream; import java.util.zip.Inflater; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.Jpeg; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfString; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** Reads TIFF images * @author Paulo Soares (psoares@consiste.pt) */ public class TiffImage { /** Gets the number of pages the TIFF document has. * @param s the file source * @return the number of pages */ public static int getNumberOfPages(RandomAccessFileOrArray s) { try { return TIFFDirectory.getNumDirectories(s); } catch (Exception e) { throw new ExceptionConverter(e); } } static int getDpi(TIFFField fd, int resolutionUnit) { if (fd == null) return 0; long res[] = fd.getAsRational(0); float frac = (float)res[0] / (float)res[1]; int dpi = 0; switch (resolutionUnit) { case TIFFConstants.RESUNIT_INCH: case TIFFConstants.RESUNIT_NONE: dpi = (int)(frac + 0.5); break; case TIFFConstants.RESUNIT_CENTIMETER: dpi = (int)(frac * 2.54 + 0.5); break; } return dpi; } /** Reads a page from a TIFF image. Direct mode is not used. * @param s the file source * @param page the page to get. The first page is 1 * @return the Image */ public static Image getTiffImage(RandomAccessFileOrArray s, int page) { return getTiffImage(s, page, false); } /** Reads a page from a TIFF image. * @param s the file source * @param page the page to get. The first page is 1 * @param direct for single strip, CCITT images, generate the image * by direct byte copying. It's faster but may not work * every time * @return the Image */ public static Image getTiffImage(RandomAccessFileOrArray s, int page, boolean direct) { if (page < 1) throw new IllegalArgumentException("The page number must be >= 1."); try { TIFFDirectory dir = new TIFFDirectory(s, page - 1); if (dir.isTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH)) throw new IllegalArgumentException("Tiles are not supported."); int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: case TIFFConstants.COMPRESSION_CCITTFAX3: case TIFFConstants.COMPRESSION_CCITTFAX4: break; default: return getTiffImageColor(dir, s); } float rotation = 0; if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) { int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION); if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT) rotation = (float)Math.PI; else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT) rotation = (float)(Math.PI / 2.0); else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT) rotation = -(float)(Math.PI / 2.0); } Image img = null; long tiffT4Options = 0; long tiffT6Options = 0; int fillOrder = 1; int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH); int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH); int dpiX = 0; int dpiY = 0; float XYRatio = 0; int resolutionUnit = TIFFConstants.RESUNIT_INCH; if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT)) resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT); dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit); dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit); if (resolutionUnit == TIFFConstants.RESUNIT_NONE) { if (dpiY != 0) XYRatio = (float)dpiX / (float)dpiY; dpiX = 0; dpiY = 0; } int rowsStrip = h; if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) rowsStrip = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP); if (rowsStrip <= 0 || rowsStrip > h) rowsStrip = h; long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS); long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS); if ((size == null || (size.length == 1 && (size[0] == 0 || size[0] + offset[0] > s.length()))) && h == rowsStrip) { // some TIFF producers are really lousy, so... size = new long[]{s.length() - (int)offset[0]}; } boolean reverse = false; TIFFField fillOrderField = dir.getField(TIFFConstants.TIFFTAG_FILLORDER); if (fillOrderField != null) fillOrder = fillOrderField.getAsInt(0); reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB); int params = 0; if (dir.isTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) { long photo = dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC); if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK) params |= Image.CCITT_BLACKIS1; } int imagecomp = 0; switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: imagecomp = Image.CCITTG3_1D; params |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK; break; case TIFFConstants.COMPRESSION_CCITTFAX3: imagecomp = Image.CCITTG3_1D; params |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK; TIFFField t4OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP3OPTIONS); if (t4OptionsField != null) { tiffT4Options = t4OptionsField.getAsLong(0); if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0) imagecomp = Image.CCITTG3_2D; if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0) params |= Image.CCITT_ENCODEDBYTEALIGN; } break; case TIFFConstants.COMPRESSION_CCITTFAX4: imagecomp = Image.CCITTG4; TIFFField t6OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP4OPTIONS); if (t6OptionsField != null) tiffT6Options = t6OptionsField.getAsLong(0); break; } if (direct && rowsStrip == h) { //single strip, direct byte im[] = new byte[(int)size[0]]; s.seek(offset[0]); s.readFully(im); img = Image.getInstance(w, h, false, imagecomp, params, im); img.setInverted(true); } else { int rowsLeft = h; CCITTG4Encoder g4 = new CCITTG4Encoder(w); for (int k = 0; k < offset.length; ++k) { byte im[] = new byte[(int)size[k]]; s.seek(offset[k]); s.readFully(im); int height = Math.min(rowsStrip, rowsLeft); TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height); byte outBuf[] = new byte[(w + 7) / 8 * height]; switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: decoder.decode1D(outBuf, im, 0, height); g4.fax4Encode(outBuf,height); break; case TIFFConstants.COMPRESSION_CCITTFAX3: try { decoder.decode2D(outBuf, im, 0, height, tiffT4Options); } catch (RuntimeException e) { // let's flip the fill bits and try again... tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS; try { decoder.decode2D(outBuf, im, 0, height, tiffT4Options); } catch (RuntimeException e2) { throw e; } } g4.fax4Encode(outBuf, height); break; case TIFFConstants.COMPRESSION_CCITTFAX4: decoder.decodeT6(outBuf, im, 0, height, tiffT6Options); g4.fax4Encode(outBuf, height); break; } rowsLeft -= rowsStrip; } byte g4pic[] = g4.close(); img = Image.getInstance(w, h, false, Image.CCITTG4, params & Image.CCITT_BLACKIS1, g4pic); } img.setDpi(dpiX, dpiY); img.setXYRatio(XYRatio); if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) { try { TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE); ICC_Profile icc_prof = ICC_Profile.getInstance(fd.getAsBytes()); if (icc_prof.getNumComponents() == 1) img.tagICC(icc_prof); } catch (RuntimeException e) { //empty } } img.setOriginalType(Image.ORIGINAL_TIFF); if (rotation != 0) img.setInitialRotation(rotation); return img; } catch (Exception e) { throw new ExceptionConverter(e); } } protected static Image getTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) { try { int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); int predictor = 1; TIFFLZWDecoder lzwDecoder = null; switch (compression) { case TIFFConstants.COMPRESSION_NONE: case TIFFConstants.COMPRESSION_LZW: case TIFFConstants.COMPRESSION_PACKBITS: case TIFFConstants.COMPRESSION_DEFLATE: case TIFFConstants.COMPRESSION_ADOBE_DEFLATE: case TIFFConstants.COMPRESSION_OJPEG: case TIFFConstants.COMPRESSION_JPEG: break; default: throw new IllegalArgumentException("The compression " + compression + " is not supported."); } int photometric = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC); switch (photometric) { case TIFFConstants.PHOTOMETRIC_MINISWHITE: case TIFFConstants.PHOTOMETRIC_MINISBLACK: case TIFFConstants.PHOTOMETRIC_RGB: case TIFFConstants.PHOTOMETRIC_SEPARATED: case TIFFConstants.PHOTOMETRIC_PALETTE: break; default: if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) throw new IllegalArgumentException("The photometric " + photometric + " is not supported."); } float rotation = 0; if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) { int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION); if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT) rotation = (float)Math.PI; else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT) rotation = (float)(Math.PI / 2.0); else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT) rotation = -(float)(Math.PI / 2.0); } if (dir.isTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG) && dir.getFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE) throw new IllegalArgumentException("Planar images are not supported."); if (dir.isTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES)) throw new IllegalArgumentException("Extra samples are not supported."); int samplePerPixel = 1; if (dir.isTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4 samplePerPixel = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL); int bitsPerSample = 1; if (dir.isTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE)) bitsPerSample = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE); switch (bitsPerSample) { case 1: case 2: case 4: case 8: break; default: throw new IllegalArgumentException("Bits per sample " + bitsPerSample + " is not supported."); } Image img = null; int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH); int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH); int dpiX = 0; int dpiY = 0; int resolutionUnit = TIFFConstants.RESUNIT_INCH; if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT)) resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT); dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit); dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit); int fillOrder = 1; boolean reverse = false; TIFFField fillOrderField = dir.getField(TIFFConstants.TIFFTAG_FILLORDER); if (fillOrderField != null) fillOrder = fillOrderField.getAsInt(0); reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB); int rowsStrip = h; if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs rowsStrip = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP); if (rowsStrip <= 0 || rowsStrip > h) rowsStrip = h; long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS); long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS); if ((size == null || (size.length == 1 && (size[0] == 0 || size[0] + offset[0] > s.length()))) && h == rowsStrip) { // some TIFF producers are really lousy, so... size = new long[]{s.length() - (int)offset[0]}; } if (compression == TIFFConstants.COMPRESSION_LZW) { TIFFField predictorField = dir.getField(TIFFConstants.TIFFTAG_PREDICTOR); if (predictorField != null) { predictor = predictorField.getAsInt(0); if (predictor != 1 && predictor != 2) { throw new RuntimeException("Illegal value for Predictor in TIFF file."); } if (predictor == 2 && bitsPerSample != 8) { throw new RuntimeException(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor."); } } lzwDecoder = new TIFFLZWDecoder(w, predictor, samplePerPixel); } int rowsLeft = h; ByteArrayOutputStream stream = null; DeflaterOutputStream zip = null; CCITTG4Encoder g4 = null; if (bitsPerSample == 1 && samplePerPixel == 1) { g4 = new CCITTG4Encoder(w); } else { stream = new ByteArrayOutputStream(); if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) zip = new DeflaterOutputStream(stream); } if (compression == TIFFConstants.COMPRESSION_OJPEG) { // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and // is often missing if ((!dir.isTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))) { throw new IOException("Missing tag(s) for OJPEG compression."); } int jpegOffset = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET); int jpegLength = s.length() - jpegOffset; if (dir.isTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT)) { jpegLength = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) + (int)size[0]; } byte[] jpeg = new byte[Math.min(jpegLength, s.length() - jpegOffset)]; int posFilePointer = s.getFilePointer(); posFilePointer += jpegOffset; s.seek(posFilePointer); s.readFully(jpeg); img = new Jpeg(jpeg); } else if (compression == TIFFConstants.COMPRESSION_JPEG) { if (size.length > 1) throw new IOException("Compression JPEG is only supported with a single strip. This image has " + size.length + " strips."); byte[] jpeg = new byte[(int)size[0]]; s.seek(offset[0]); s.readFully(jpeg); img = new Jpeg(jpeg); } else { for (int k = 0; k < offset.length; ++k) { byte im[] = new byte[(int)size[k]]; s.seek(offset[k]); s.readFully(im); int height = Math.min(rowsStrip, rowsLeft); byte outBuf[] = null; if (compression != TIFFConstants.COMPRESSION_NONE) outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height]; if (reverse) TIFFFaxDecoder.reverseBits(im); switch (compression) { case TIFFConstants.COMPRESSION_DEFLATE: case TIFFConstants.COMPRESSION_ADOBE_DEFLATE: inflate(im, outBuf); break; case TIFFConstants.COMPRESSION_NONE: outBuf = im; break; case TIFFConstants.COMPRESSION_PACKBITS: decodePackbits(im, outBuf); break; case TIFFConstants.COMPRESSION_LZW: lzwDecoder.decode(im, outBuf, height); break; } if (bitsPerSample == 1 && samplePerPixel == 1) { g4.fax4Encode(outBuf, height); } else { zip.write(outBuf); } rowsLeft -= rowsStrip; } if (bitsPerSample == 1 && samplePerPixel == 1) { img = Image.getInstance(w, h, false, Image.CCITTG4, photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.close()); } else { zip.close(); img = Image.getInstance(w, h, samplePerPixel, bitsPerSample, stream.toByteArray()); img.setDeflated(true); } } img.setDpi(dpiX, dpiY); if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) { if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) { try { TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE); ICC_Profile icc_prof = ICC_Profile.getInstance(fd.getAsBytes()); if (samplePerPixel == icc_prof.getNumComponents()) img.tagICC(icc_prof); } catch (RuntimeException e) { //empty } } if (dir.isTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) { TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_COLORMAP); char rgb[] = fd.getAsChars(); byte palette[] = new byte[rgb.length]; int gColor = rgb.length / 3; int bColor = gColor * 2; for (int k = 0; k < gColor; ++k) { palette[k * 3] = (byte)(rgb[k] >>> 8); palette[k * 3 + 1] = (byte)(rgb[k + gColor] >>> 8); palette[k * 3 + 2] = (byte)(rgb[k + bColor] >>> 8); } PdfArray indexed = new PdfArray(); indexed.add(PdfName.INDEXED); indexed.add(PdfName.DEVICERGB); indexed.add(new PdfNumber(gColor - 1)); indexed.add(new PdfString(palette)); PdfDictionary additional = new PdfDictionary(); additional.put(PdfName.COLORSPACE, indexed); img.setAdditional(additional); } img.setOriginalType(Image.ORIGINAL_TIFF); } if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE) img.setInverted(true); if (rotation != 0) img.setInitialRotation(rotation); return img; } catch (Exception e) { throw new ExceptionConverter(e); } } static long[] getArrayLongShort(TIFFDirectory dir, int tag) { TIFFField field = dir.getField(tag); if (field == null) return null; long offset[]; if (field.getType() == TIFFField.TIFF_LONG) offset = field.getAsLongs(); else { // must be short char temp[] = field.getAsChars(); offset = new long[temp.length]; for (int k = 0; k < temp.length; ++k) offset[k] = temp[k]; } return offset; } // Uncompress packbits compressed image data. public static void decodePackbits(byte data[], byte[] dst) { int srcCount = 0, dstCount = 0; byte repeat, b; try { while (dstCount < dst.length) { b = data[srcCount++]; if (b >= 0 && b <= 127) { // literal run packet for (int i=0; i<(b + 1); i++) { dst[dstCount++] = data[srcCount++]; } } else if (b <= -1 && b >= -127) { // 2 byte encoded run packet repeat = data[srcCount++]; for (int i=0; i<(-b + 1); i++) { dst[dstCount++] = repeat; } } else { // no-op packet. Do nothing srcCount++; } } } catch (Exception e) { // do nothing } } public static void inflate(byte[] deflated, byte[] inflated) { Inflater inflater = new Inflater(); inflater.setInput(deflated); try { inflater.inflate(inflated); } catch(DataFormatException dfe) { throw new ExceptionConverter(dfe); } } } src/core/com/lowagie/text/pdf/codec/wmf/InputMeta.java100644 0 0 7501 11012562272 20306 0ustar 0 0 /* * $Id: InputMeta.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import java.awt.Color; import java.io.IOException; import java.io.InputStream; import com.lowagie.text.Utilities; public class InputMeta { InputStream in; int length; public InputMeta(InputStream in) { this.in = in; } public int readWord() throws IOException{ length += 2; int k1 = in.read(); if (k1 < 0) return 0; return (k1 + (in.read() << 8)) & 0xffff; } public int readShort() throws IOException{ int k = readWord(); if (k > 0x7fff) k -= 0x10000; return k; } public int readInt() throws IOException{ length += 4; int k1 = in.read(); if (k1 < 0) return 0; int k2 = in.read() << 8; int k3 = in.read() << 16; return k1 + k2 + k3 + (in.read() << 24); } public int readByte() throws IOException{ ++length; return in.read() & 0xff; } public void skip(int len) throws IOException{ length += len; Utilities.skip(in, len); } public int getLength() { return length; } public Color readColor() throws IOException{ int red = readByte(); int green = readByte(); int blue = readByte(); readByte(); return new Color(red, green, blue); } } src/core/com/lowagie/text/pdf/codec/wmf/MetaBrush.java100644 0 0 7024 11012562272 20272 0ustar 0 0 /* * $Id: MetaBrush.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import java.awt.Color; import java.io.IOException; public class MetaBrush extends MetaObject { public static final int BS_SOLID = 0; public static final int BS_NULL = 1; public static final int BS_HATCHED = 2; public static final int BS_PATTERN = 3; public static final int BS_DIBPATTERN = 5; public static final int HS_HORIZONTAL = 0; public static final int HS_VERTICAL = 1; public static final int HS_FDIAGONAL = 2; public static final int HS_BDIAGONAL = 3; public static final int HS_CROSS = 4; public static final int HS_DIAGCROSS = 5; int style = BS_SOLID; int hatch; Color color = Color.white; public MetaBrush() { type = META_BRUSH; } public void init(InputMeta in) throws IOException { style = in.readWord(); color = in.readColor(); hatch = in.readWord(); } public int getStyle() { return style; } public int getHatch() { return hatch; } public Color getColor() { return color; } } src/core/com/lowagie/text/pdf/codec/wmf/MetaDo.java100644 0 0 100404 11012562272 17605 0ustar 0 0 /* * $Id: MetaDo.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import java.awt.Color; import java.awt.Point; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.codec.BmpImage; public class MetaDo { public static final int META_SETBKCOLOR = 0x0201; public static final int META_SETBKMODE = 0x0102; public static final int META_SETMAPMODE = 0x0103; public static final int META_SETROP2 = 0x0104; public static final int META_SETRELABS = 0x0105; public static final int META_SETPOLYFILLMODE = 0x0106; public static final int META_SETSTRETCHBLTMODE = 0x0107; public static final int META_SETTEXTCHAREXTRA = 0x0108; public static final int META_SETTEXTCOLOR = 0x0209; public static final int META_SETTEXTJUSTIFICATION = 0x020A; public static final int META_SETWINDOWORG = 0x020B; public static final int META_SETWINDOWEXT = 0x020C; public static final int META_SETVIEWPORTORG = 0x020D; public static final int META_SETVIEWPORTEXT = 0x020E; public static final int META_OFFSETWINDOWORG = 0x020F; public static final int META_SCALEWINDOWEXT = 0x0410; public static final int META_OFFSETVIEWPORTORG = 0x0211; public static final int META_SCALEVIEWPORTEXT = 0x0412; public static final int META_LINETO = 0x0213; public static final int META_MOVETO = 0x0214; public static final int META_EXCLUDECLIPRECT = 0x0415; public static final int META_INTERSECTCLIPRECT = 0x0416; public static final int META_ARC = 0x0817; public static final int META_ELLIPSE = 0x0418; public static final int META_FLOODFILL = 0x0419; public static final int META_PIE = 0x081A; public static final int META_RECTANGLE = 0x041B; public static final int META_ROUNDRECT = 0x061C; public static final int META_PATBLT = 0x061D; public static final int META_SAVEDC = 0x001E; public static final int META_SETPIXEL = 0x041F; public static final int META_OFFSETCLIPRGN = 0x0220; public static final int META_TEXTOUT = 0x0521; public static final int META_BITBLT = 0x0922; public static final int META_STRETCHBLT = 0x0B23; public static final int META_POLYGON = 0x0324; public static final int META_POLYLINE = 0x0325; public static final int META_ESCAPE = 0x0626; public static final int META_RESTOREDC = 0x0127; public static final int META_FILLREGION = 0x0228; public static final int META_FRAMEREGION = 0x0429; public static final int META_INVERTREGION = 0x012A; public static final int META_PAINTREGION = 0x012B; public static final int META_SELECTCLIPREGION = 0x012C; public static final int META_SELECTOBJECT = 0x012D; public static final int META_SETTEXTALIGN = 0x012E; public static final int META_CHORD = 0x0830; public static final int META_SETMAPPERFLAGS = 0x0231; public static final int META_EXTTEXTOUT = 0x0a32; public static final int META_SETDIBTODEV = 0x0d33; public static final int META_SELECTPALETTE = 0x0234; public static final int META_REALIZEPALETTE = 0x0035; public static final int META_ANIMATEPALETTE = 0x0436; public static final int META_SETPALENTRIES = 0x0037; public static final int META_POLYPOLYGON = 0x0538; public static final int META_RESIZEPALETTE = 0x0139; public static final int META_DIBBITBLT = 0x0940; public static final int META_DIBSTRETCHBLT = 0x0b41; public static final int META_DIBCREATEPATTERNBRUSH = 0x0142; public static final int META_STRETCHDIB = 0x0f43; public static final int META_EXTFLOODFILL = 0x0548; public static final int META_DELETEOBJECT = 0x01f0; public static final int META_CREATEPALETTE = 0x00f7; public static final int META_CREATEPATTERNBRUSH = 0x01F9; public static final int META_CREATEPENINDIRECT = 0x02FA; public static final int META_CREATEFONTINDIRECT = 0x02FB; public static final int META_CREATEBRUSHINDIRECT = 0x02FC; public static final int META_CREATEREGION = 0x06FF; public PdfContentByte cb; public InputMeta in; int left; int top; int right; int bottom; int inch; MetaState state = new MetaState(); public MetaDo(InputStream in, PdfContentByte cb) { this.cb = cb; this.in = new InputMeta(in); } public void readAll() throws IOException, DocumentException{ if (in.readInt() != 0x9AC6CDD7) { throw new DocumentException("Not a placeable windows metafile"); } in.readWord(); left = in.readShort(); top = in.readShort(); right = in.readShort(); bottom = in.readShort(); inch = in.readWord(); state.setScalingX((float)(right - left) / (float)inch * 72f); state.setScalingY((float)(bottom - top) / (float)inch * 72f); state.setOffsetWx(left); state.setOffsetWy(top); state.setExtentWx(right - left); state.setExtentWy(bottom - top); in.readInt(); in.readWord(); in.skip(18); int tsize; int function; cb.setLineCap(1); cb.setLineJoin(1); for (;;) { int lenMarker = in.getLength(); tsize = in.readInt(); if (tsize < 3) break; function = in.readWord(); switch (function) { case 0: break; case META_CREATEPALETTE: case META_CREATEREGION: case META_DIBCREATEPATTERNBRUSH: state.addMetaObject(new MetaObject()); break; case META_CREATEPENINDIRECT: { MetaPen pen = new MetaPen(); pen.init(in); state.addMetaObject(pen); break; } case META_CREATEBRUSHINDIRECT: { MetaBrush brush = new MetaBrush(); brush.init(in); state.addMetaObject(brush); break; } case META_CREATEFONTINDIRECT: { MetaFont font = new MetaFont(); font.init(in); state.addMetaObject(font); break; } case META_SELECTOBJECT: { int idx = in.readWord(); state.selectMetaObject(idx, cb); break; } case META_DELETEOBJECT: { int idx = in.readWord(); state.deleteMetaObject(idx); break; } case META_SAVEDC: state.saveState(cb); break; case META_RESTOREDC: { int idx = in.readShort(); state.restoreState(idx, cb); break; } case META_SETWINDOWORG: state.setOffsetWy(in.readShort()); state.setOffsetWx(in.readShort()); break; case META_SETWINDOWEXT: state.setExtentWy(in.readShort()); state.setExtentWx(in.readShort()); break; case META_MOVETO: { int y = in.readShort(); Point p = new Point(in.readShort(), y); state.setCurrentPoint(p); break; } case META_LINETO: { int y = in.readShort(); int x = in.readShort(); Point p = state.getCurrentPoint(); cb.moveTo(state.transformX(p.x), state.transformY(p.y)); cb.lineTo(state.transformX(x), state.transformY(y)); cb.stroke(); state.setCurrentPoint(new Point(x, y)); break; } case META_POLYLINE: { state.setLineJoinPolygon(cb); int len = in.readWord(); int x = in.readShort(); int y = in.readShort(); cb.moveTo(state.transformX(x), state.transformY(y)); for (int k = 1; k < len; ++k) { x = in.readShort(); y = in.readShort(); cb.lineTo(state.transformX(x), state.transformY(y)); } cb.stroke(); break; } case META_POLYGON: { if (isNullStrokeFill(false)) break; int len = in.readWord(); int sx = in.readShort(); int sy = in.readShort(); cb.moveTo(state.transformX(sx), state.transformY(sy)); for (int k = 1; k < len; ++k) { int x = in.readShort(); int y = in.readShort(); cb.lineTo(state.transformX(x), state.transformY(y)); } cb.lineTo(state.transformX(sx), state.transformY(sy)); strokeAndFill(); break; } case META_POLYPOLYGON: { if (isNullStrokeFill(false)) break; int numPoly = in.readWord(); int lens[] = new int[numPoly]; for (int k = 0; k < lens.length; ++k) lens[k] = in.readWord(); for (int j = 0; j < lens.length; ++j) { int len = lens[j]; int sx = in.readShort(); int sy = in.readShort(); cb.moveTo(state.transformX(sx), state.transformY(sy)); for (int k = 1; k < len; ++k) { int x = in.readShort(); int y = in.readShort(); cb.lineTo(state.transformX(x), state.transformY(y)); } cb.lineTo(state.transformX(sx), state.transformY(sy)); } strokeAndFill(); break; } case META_ELLIPSE: { if (isNullStrokeFill(state.getLineNeutral())) break; int b = in.readShort(); int r = in.readShort(); int t = in.readShort(); int l = in.readShort(); cb.arc(state.transformX(l), state.transformY(b), state.transformX(r), state.transformY(t), 0, 360); strokeAndFill(); break; } case META_ARC: { if (isNullStrokeFill(state.getLineNeutral())) break; float yend = state.transformY(in.readShort()); float xend = state.transformX(in.readShort()); float ystart = state.transformY(in.readShort()); float xstart = state.transformX(in.readShort()); float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = getArc(cx, cy, xstart, ystart); float arc2 = getArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) arc2 += 360; cb.arc(l, b, r, t, arc1, arc2); cb.stroke(); break; } case META_PIE: { if (isNullStrokeFill(state.getLineNeutral())) break; float yend = state.transformY(in.readShort()); float xend = state.transformX(in.readShort()); float ystart = state.transformY(in.readShort()); float xstart = state.transformX(in.readShort()); float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = getArc(cx, cy, xstart, ystart); float arc2 = getArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) arc2 += 360; ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2); if (ar.isEmpty()) break; float pt[] = (float [])ar.get(0); cb.moveTo(cx, cy); cb.lineTo(pt[0], pt[1]); for (int k = 0; k < ar.size(); ++k) { pt = (float [])ar.get(k); cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); } cb.lineTo(cx, cy); strokeAndFill(); break; } case META_CHORD: { if (isNullStrokeFill(state.getLineNeutral())) break; float yend = state.transformY(in.readShort()); float xend = state.transformX(in.readShort()); float ystart = state.transformY(in.readShort()); float xstart = state.transformX(in.readShort()); float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); float cx = (r + l) / 2; float cy = (t + b) / 2; float arc1 = getArc(cx, cy, xstart, ystart); float arc2 = getArc(cx, cy, xend, yend); arc2 -= arc1; if (arc2 <= 0) arc2 += 360; ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2); if (ar.isEmpty()) break; float pt[] = (float [])ar.get(0); cx = pt[0]; cy = pt[1]; cb.moveTo(cx, cy); for (int k = 0; k < ar.size(); ++k) { pt = (float [])ar.get(k); cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); } cb.lineTo(cx, cy); strokeAndFill(); break; } case META_RECTANGLE: { if (isNullStrokeFill(true)) break; float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); cb.rectangle(l, b, r - l, t - b); strokeAndFill(); break; } case META_ROUNDRECT: { if (isNullStrokeFill(true)) break; float h = state.transformY(0) - state.transformY(in.readShort()); float w = state.transformX(in.readShort()) - state.transformX(0); float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); cb.roundRectangle(l, b, r - l, t - b, (h + w) / 4); strokeAndFill(); break; } case META_INTERSECTCLIPRECT: { float b = state.transformY(in.readShort()); float r = state.transformX(in.readShort()); float t = state.transformY(in.readShort()); float l = state.transformX(in.readShort()); cb.rectangle(l, b, r - l, t - b); cb.eoClip(); cb.newPath(); break; } case META_EXTTEXTOUT: { int y = in.readShort(); int x = in.readShort(); int count = in.readWord(); int flag = in.readWord(); int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; if ((flag & (MetaFont.ETO_CLIPPED | MetaFont.ETO_OPAQUE)) != 0) { x1 = in.readShort(); y1 = in.readShort(); x2 = in.readShort(); y2 = in.readShort(); } byte text[] = new byte[count]; int k; for (k = 0; k < count; ++k) { byte c = (byte)in.readByte(); if (c == 0) break; text[k] = c; } String s; try { s = new String(text, 0, k, "Cp1252"); } catch (UnsupportedEncodingException e) { s = new String(text, 0, k); } outputText(x, y, flag, x1, y1, x2, y2, s); break; } case META_TEXTOUT: { int count = in.readWord(); byte text[] = new byte[count]; int k; for (k = 0; k < count; ++k) { byte c = (byte)in.readByte(); if (c == 0) break; text[k] = c; } String s; try { s = new String(text, 0, k, "Cp1252"); } catch (UnsupportedEncodingException e) { s = new String(text, 0, k); } count = (count + 1) & 0xfffe; in.skip(count - k); int y = in.readShort(); int x = in.readShort(); outputText(x, y, 0, 0, 0, 0, 0, s); break; } case META_SETBKCOLOR: state.setCurrentBackgroundColor(in.readColor()); break; case META_SETTEXTCOLOR: state.setCurrentTextColor(in.readColor()); break; case META_SETTEXTALIGN: state.setTextAlign(in.readWord()); break; case META_SETBKMODE: state.setBackgroundMode(in.readWord()); break; case META_SETPOLYFILLMODE: state.setPolyFillMode(in.readWord()); break; case META_SETPIXEL: { Color color = in.readColor(); int y = in.readShort(); int x = in.readShort(); cb.saveState(); cb.setColorFill(color); cb.rectangle(state.transformX(x), state.transformY(y), .2f, .2f); cb.fill(); cb.restoreState(); break; } case META_DIBSTRETCHBLT: case META_STRETCHDIB: { int rop = in.readInt(); if (function == META_STRETCHDIB) { /*int usage = */ in.readWord(); } int srcHeight = in.readShort(); int srcWidth = in.readShort(); int ySrc = in.readShort(); int xSrc = in.readShort(); float destHeight = state.transformY(in.readShort()) - state.transformY(0); float destWidth = state.transformX(in.readShort()) - state.transformX(0); float yDest = state.transformY(in.readShort()); float xDest = state.transformX(in.readShort()); byte b[] = new byte[(tsize * 2) - (in.getLength() - lenMarker)]; for (int k = 0; k < b.length; ++k) b[k] = (byte)in.readByte(); try { ByteArrayInputStream inb = new ByteArrayInputStream(b); Image bmp = BmpImage.getImage(inb, true, b.length); cb.saveState(); cb.rectangle(xDest, yDest, destWidth, destHeight); cb.clip(); cb.newPath(); bmp.scaleAbsolute(destWidth * bmp.getWidth() / srcWidth, -destHeight * bmp.getHeight() / srcHeight); bmp.setAbsolutePosition(xDest - destWidth * xSrc / srcWidth, yDest + destHeight * ySrc / srcHeight - bmp.getScaledHeight()); cb.addImage(bmp); cb.restoreState(); } catch (Exception e) { // empty on purpose } break; } } in.skip((tsize * 2) - (in.getLength() - lenMarker)); } state.cleanup(cb); } public void outputText(int x, int y, int flag, int x1, int y1, int x2, int y2, String text) { MetaFont font = state.getCurrentFont(); float refX = state.transformX(x); float refY = state.transformY(y); float angle = state.transformAngle(font.getAngle()); float sin = (float)Math.sin(angle); float cos = (float)Math.cos(angle); float fontSize = font.getFontSize(state); BaseFont bf = font.getFont(); int align = state.getTextAlign(); float textWidth = bf.getWidthPoint(text, fontSize); float tx = 0; float ty = 0; float descender = bf.getFontDescriptor(BaseFont.DESCENT, fontSize); float ury = bf.getFontDescriptor(BaseFont.BBOXURY, fontSize); cb.saveState(); cb.concatCTM(cos, sin, -sin, cos, refX, refY); if ((align & MetaState.TA_CENTER) == MetaState.TA_CENTER) tx = -textWidth / 2; else if ((align & MetaState.TA_RIGHT) == MetaState.TA_RIGHT) tx = -textWidth; if ((align & MetaState.TA_BASELINE) == MetaState.TA_BASELINE) ty = 0; else if ((align & MetaState.TA_BOTTOM) == MetaState.TA_BOTTOM) ty = -descender; else ty = -ury; Color textColor; if (state.getBackgroundMode() == MetaState.OPAQUE) { textColor = state.getCurrentBackgroundColor(); cb.setColorFill(textColor); cb.rectangle(tx, ty + descender, textWidth, ury - descender); cb.fill(); } textColor = state.getCurrentTextColor(); cb.setColorFill(textColor); cb.beginText(); cb.setFontAndSize(bf, fontSize); cb.setTextMatrix(tx, ty); cb.showText(text); cb.endText(); if (font.isUnderline()) { cb.rectangle(tx, ty - fontSize / 4, textWidth, fontSize / 15); cb.fill(); } if (font.isStrikeout()) { cb.rectangle(tx, ty + fontSize / 3, textWidth, fontSize / 15); cb.fill(); } cb.restoreState(); } public boolean isNullStrokeFill(boolean isRectangle) { MetaPen pen = state.getCurrentPen(); MetaBrush brush = state.getCurrentBrush(); boolean noPen = (pen.getStyle() == MetaPen.PS_NULL); int style = brush.getStyle(); boolean isBrush = (style == MetaBrush.BS_SOLID || (style == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE)); boolean result = noPen && !isBrush; if (!noPen) { if (isRectangle) state.setLineJoinRectangle(cb); else state.setLineJoinPolygon(cb); } return result; } public void strokeAndFill(){ MetaPen pen = state.getCurrentPen(); MetaBrush brush = state.getCurrentBrush(); int penStyle = pen.getStyle(); int brushStyle = brush.getStyle(); if (penStyle == MetaPen.PS_NULL) { cb.closePath(); if (state.getPolyFillMode() == MetaState.ALTERNATE) { cb.eoFill(); } else { cb.fill(); } } else { boolean isBrush = (brushStyle == MetaBrush.BS_SOLID || (brushStyle == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE)); if (isBrush) { if (state.getPolyFillMode() == MetaState.ALTERNATE) cb.closePathEoFillStroke(); else cb.closePathFillStroke(); } else { cb.closePathStroke(); } } } static float getArc(float xCenter, float yCenter, float xDot, float yDot) { double s = Math.atan2(yDot - yCenter, xDot - xCenter); if (s < 0) s += Math.PI * 2; return (float)(s / Math.PI * 180); } public static byte[] wrapBMP(Image image) throws IOException { if (image.getOriginalType() != Image.ORIGINAL_BMP) throw new IOException("Only BMP can be wrapped in WMF."); InputStream imgIn; byte data[] = null; if (image.getOriginalData() == null) { imgIn = image.getUrl().openStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); int b = 0; while ((b = imgIn.read()) != -1) out.write(b); imgIn.close(); data = out.toByteArray(); } else data = image.getOriginalData(); int sizeBmpWords = (data.length - 14 + 1) >>> 1; ByteArrayOutputStream os = new ByteArrayOutputStream(); // write metafile header writeWord(os, 1); writeWord(os, 9); writeWord(os, 0x0300); writeDWord(os, 9 + 4 + 5 + 5 + (13 + sizeBmpWords) + 3); // total metafile size writeWord(os, 1); writeDWord(os, 14 + sizeBmpWords); // max record size writeWord(os, 0); // write records writeDWord(os, 4); writeWord(os, META_SETMAPMODE); writeWord(os, 8); writeDWord(os, 5); writeWord(os, META_SETWINDOWORG); writeWord(os, 0); writeWord(os, 0); writeDWord(os, 5); writeWord(os, META_SETWINDOWEXT); writeWord(os, (int)image.getHeight()); writeWord(os, (int)image.getWidth()); writeDWord(os, 13 + sizeBmpWords); writeWord(os, META_DIBSTRETCHBLT); writeDWord(os, 0x00cc0020); writeWord(os, (int)image.getHeight()); writeWord(os, (int)image.getWidth()); writeWord(os, 0); writeWord(os, 0); writeWord(os, (int)image.getHeight()); writeWord(os, (int)image.getWidth()); writeWord(os, 0); writeWord(os, 0); os.write(data, 14, data.length - 14); if ((data.length & 1) == 1) os.write(0); // writeDWord(os, 14 + sizeBmpWords); // writeWord(os, META_STRETCHDIB); // writeDWord(os, 0x00cc0020); // writeWord(os, 0); // writeWord(os, (int)image.height()); // writeWord(os, (int)image.width()); // writeWord(os, 0); // writeWord(os, 0); // writeWord(os, (int)image.height()); // writeWord(os, (int)image.width()); // writeWord(os, 0); // writeWord(os, 0); // os.write(data, 14, data.length - 14); // if ((data.length & 1) == 1) // os.write(0); writeDWord(os, 3); writeWord(os, 0); os.close(); return os.toByteArray(); } public static void writeWord(OutputStream os, int v) throws IOException { os.write(v & 0xff); os.write((v >>> 8) & 0xff); } public static void writeDWord(OutputStream os, int v) throws IOException { writeWord(os, v & 0xffff); writeWord(os, (v >>> 16) & 0xffff); } }src/core/com/lowagie/text/pdf/codec/wmf/MetaFont.java100644 0 0 17522 11012562272 20141 0ustar 0 0 /* * $Id: MetaFont.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import com.lowagie.text.Document; import java.io.IOException; import java.io.UnsupportedEncodingException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.pdf.BaseFont; public class MetaFont extends MetaObject { static final String fontNames[] = { "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Symbol", "ZapfDingbats"}; static final int MARKER_BOLD = 1; static final int MARKER_ITALIC = 2; static final int MARKER_COURIER = 0; static final int MARKER_HELVETICA = 4; static final int MARKER_TIMES = 8; static final int MARKER_SYMBOL = 12; static final int DEFAULT_PITCH = 0; static final int FIXED_PITCH = 1; static final int VARIABLE_PITCH = 2; static final int FF_DONTCARE = 0; static final int FF_ROMAN = 1; static final int FF_SWISS = 2; static final int FF_MODERN = 3; static final int FF_SCRIPT = 4; static final int FF_DECORATIVE = 5; static final int BOLDTHRESHOLD = 600; static final int nameSize = 32; static final int ETO_OPAQUE = 2; static final int ETO_CLIPPED = 4; int height; float angle; int bold; int italic; boolean underline; boolean strikeout; int charset; int pitchAndFamily; String faceName = "arial"; BaseFont font = null; public MetaFont() { type = META_FONT; } public void init(InputMeta in) throws IOException { height = Math.abs(in.readShort()); in.skip(2); angle = (float)(in.readShort() / 1800.0 * Math.PI); in.skip(2); bold = (in.readShort() >= BOLDTHRESHOLD ? MARKER_BOLD : 0); italic = (in.readByte() != 0 ? MARKER_ITALIC : 0); underline = (in.readByte() != 0); strikeout = (in.readByte() != 0); charset = in.readByte(); in.skip(3); pitchAndFamily = in.readByte(); byte name[] = new byte[nameSize]; int k; for (k = 0; k < nameSize; ++k) { int c = in.readByte(); if (c == 0) { break; } name[k] = (byte)c; } try { faceName = new String(name, 0, k, "Cp1252"); } catch (UnsupportedEncodingException e) { faceName = new String(name, 0, k); } faceName = faceName.toLowerCase(); } public BaseFont getFont() { if (font != null) return font; Font ff2 = FontFactory.getFont(faceName, BaseFont.CP1252, true, 10, ((italic != 0) ? Font.ITALIC : 0) | ((bold != 0) ? Font.BOLD : 0)); font = ff2.getBaseFont(); if (font != null) return font; String fontName; if (faceName.indexOf("courier") != -1 || faceName.indexOf("terminal") != -1 || faceName.indexOf("fixedsys") != -1) { fontName = fontNames[MARKER_COURIER + italic + bold]; } else if (faceName.indexOf("ms sans serif") != -1 || faceName.indexOf("arial") != -1 || faceName.indexOf("system") != -1) { fontName = fontNames[MARKER_HELVETICA + italic + bold]; } else if (faceName.indexOf("arial black") != -1) { fontName = fontNames[MARKER_HELVETICA + italic + MARKER_BOLD]; } else if (faceName.indexOf("times") != -1 || faceName.indexOf("ms serif") != -1 || faceName.indexOf("roman") != -1) { fontName = fontNames[MARKER_TIMES + italic + bold]; } else if (faceName.indexOf("symbol") != -1) { fontName = fontNames[MARKER_SYMBOL]; } else { int pitch = pitchAndFamily & 3; int family = (pitchAndFamily >> 4) & 7; switch (family) { case FF_MODERN: fontName = fontNames[MARKER_COURIER + italic + bold]; break; case FF_ROMAN: fontName = fontNames[MARKER_TIMES + italic + bold]; break; case FF_SWISS: case FF_SCRIPT: case FF_DECORATIVE: fontName = fontNames[MARKER_HELVETICA + italic + bold]; break; default: { switch (pitch) { case FIXED_PITCH: fontName = fontNames[MARKER_COURIER + italic + bold]; break; default: fontName = fontNames[MARKER_HELVETICA + italic + bold]; break; } } } } try { font = BaseFont.createFont(fontName, "Cp1252", false); } catch (Exception e) { throw new ExceptionConverter(e); } return font; } public float getAngle() { return angle; } public boolean isUnderline() { return underline; } public boolean isStrikeout() { return strikeout; } public float getFontSize(MetaState state) { return Math.abs(state.transformY(height) - state.transformY(0)) * Document.wmfFontCorrection; } } src/core/com/lowagie/text/pdf/codec/wmf/MetaObject.java100644 0 0 5612 11012562272 20416 0ustar 0 0 /* * $Id: MetaObject.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; public class MetaObject { public static final int META_NOT_SUPPORTED = 0; public static final int META_PEN = 1; public static final int META_BRUSH = 2; public static final int META_FONT = 3; public int type = META_NOT_SUPPORTED; public MetaObject() { } public MetaObject(int type) { this.type = type; } public int getType() { return type; } } src/core/com/lowagie/text/pdf/codec/wmf/MetaPen.java100644 0 0 6571 11012562272 17737 0ustar 0 0 /* * $Id: MetaPen.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import java.awt.Color; import java.io.IOException; public class MetaPen extends MetaObject { public static final int PS_SOLID = 0; public static final int PS_DASH = 1; public static final int PS_DOT = 2; public static final int PS_DASHDOT = 3; public static final int PS_DASHDOTDOT = 4; public static final int PS_NULL = 5; public static final int PS_INSIDEFRAME = 6; int style = PS_SOLID; int penWidth = 1; Color color = Color.black; public MetaPen() { type = META_PEN; } public void init(InputMeta in) throws IOException { style = in.readWord(); penWidth = in.readShort(); in.readWord(); color = in.readColor(); } public int getStyle() { return style; } public int getPenWidth() { return penWidth; } public Color getColor() { return color; } } src/core/com/lowagie/text/pdf/codec/wmf/MetaState.java100644 0 0 27434 11036112745 20320 0ustar 0 0 /* * $Id: MetaState.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.codec.wmf; import java.awt.Color; import java.awt.Point; import java.util.ArrayList; import java.util.Stack; import com.lowagie.text.pdf.PdfContentByte; public class MetaState { public static final int TA_NOUPDATECP = 0; public static final int TA_UPDATECP = 1; public static final int TA_LEFT = 0; public static final int TA_RIGHT = 2; public static final int TA_CENTER = 6; public static final int TA_TOP = 0; public static final int TA_BOTTOM = 8; public static final int TA_BASELINE = 24; public static final int TRANSPARENT = 1; public static final int OPAQUE = 2; public static final int ALTERNATE = 1; public static final int WINDING = 2; public Stack savedStates; public ArrayList MetaObjects; public Point currentPoint; public MetaPen currentPen; public MetaBrush currentBrush; public MetaFont currentFont; public Color currentBackgroundColor = Color.white; public Color currentTextColor = Color.black; public int backgroundMode = OPAQUE; public int polyFillMode = ALTERNATE; public int lineJoin = 1; public int textAlign; public int offsetWx; public int offsetWy; public int extentWx; public int extentWy; public float scalingX; public float scalingY; /** Creates new MetaState */ public MetaState() { savedStates = new Stack(); MetaObjects = new ArrayList(); currentPoint = new Point(0, 0); currentPen = new MetaPen(); currentBrush = new MetaBrush(); currentFont = new MetaFont(); } public MetaState(MetaState state) { setMetaState(state); } public void setMetaState(MetaState state) { savedStates = state.savedStates; MetaObjects = state.MetaObjects; currentPoint = state.currentPoint; currentPen = state.currentPen; currentBrush = state.currentBrush; currentFont = state.currentFont; currentBackgroundColor = state.currentBackgroundColor; currentTextColor = state.currentTextColor; backgroundMode = state.backgroundMode; polyFillMode = state.polyFillMode; textAlign = state.textAlign; lineJoin = state.lineJoin; offsetWx = state.offsetWx; offsetWy = state.offsetWy; extentWx = state.extentWx; extentWy = state.extentWy; scalingX = state.scalingX; scalingY = state.scalingY; } public void addMetaObject(MetaObject object) { for (int k = 0; k < MetaObjects.size(); ++k) { if (MetaObjects.get(k) == null) { MetaObjects.set(k, object); return; } } MetaObjects.add(object); } public void selectMetaObject(int index, PdfContentByte cb) { MetaObject obj = (MetaObject)MetaObjects.get(index); if (obj == null) return; int style; switch (obj.getType()) { case MetaObject.META_BRUSH: currentBrush = (MetaBrush)obj; style = currentBrush.getStyle(); if (style == MetaBrush.BS_SOLID) { Color color = currentBrush.getColor(); cb.setColorFill(color); } else if (style == MetaBrush.BS_HATCHED) { Color color = currentBackgroundColor; cb.setColorFill(color); } break; case MetaObject.META_PEN: { currentPen = (MetaPen)obj; style = currentPen.getStyle(); if (style != MetaPen.PS_NULL) { Color color = currentPen.getColor(); cb.setColorStroke(color); cb.setLineWidth(Math.abs(currentPen.getPenWidth() * scalingX / extentWx)); switch (style) { case MetaPen.PS_DASH: cb.setLineDash(18, 6, 0); break; case MetaPen.PS_DASHDOT: cb.setLiteral("[9 6 3 6]0 d\n"); break; case MetaPen.PS_DASHDOTDOT: cb.setLiteral("[9 3 3 3 3 3]0 d\n"); break; case MetaPen.PS_DOT: cb.setLineDash(3, 0); break; default: cb.setLineDash(0); break; } } break; } case MetaObject.META_FONT: { currentFont = (MetaFont)obj; break; } } } public void deleteMetaObject(int index) { MetaObjects.set(index, null); } public void saveState(PdfContentByte cb) { cb.saveState(); MetaState state = new MetaState(this); savedStates.push(state); } public void restoreState(int index, PdfContentByte cb) { int pops; if (index < 0) pops = Math.min(-index, savedStates.size()); else pops = Math.max(savedStates.size() - index, 0); if (pops == 0) return; MetaState state = null; while (pops-- != 0) { cb.restoreState(); state = (MetaState)savedStates.pop(); } setMetaState(state); } public void cleanup(PdfContentByte cb) { int k = savedStates.size(); while (k-- > 0) cb.restoreState(); } public float transformX(int x) { return ((float)x - offsetWx) * scalingX / extentWx; } public float transformY(int y) { return (1f - ((float)y - offsetWy) / extentWy) * scalingY; } public void setScalingX(float scalingX) { this.scalingX = scalingX; } public void setScalingY(float scalingY) { this.scalingY = scalingY; } public void setOffsetWx(int offsetWx) { this.offsetWx = offsetWx; } public void setOffsetWy(int offsetWy) { this.offsetWy = offsetWy; } public void setExtentWx(int extentWx) { this.extentWx = extentWx; } public void setExtentWy(int extentWy) { this.extentWy = extentWy; } public float transformAngle(float angle) { float ta = scalingY < 0 ? -angle : angle; return (float)(scalingX < 0 ? Math.PI - ta : ta); } public void setCurrentPoint(Point p) { currentPoint = p; } public Point getCurrentPoint() { return currentPoint; } public MetaBrush getCurrentBrush() { return currentBrush; } public MetaPen getCurrentPen() { return currentPen; } public MetaFont getCurrentFont() { return currentFont; } /** Getter for property currentBackgroundColor. * @return Value of property currentBackgroundColor. */ public Color getCurrentBackgroundColor() { return currentBackgroundColor; } /** Setter for property currentBackgroundColor. * @param currentBackgroundColor New value of property currentBackgroundColor. */ public void setCurrentBackgroundColor(Color currentBackgroundColor) { this.currentBackgroundColor = currentBackgroundColor; } /** Getter for property currentTextColor. * @return Value of property currentTextColor. */ public Color getCurrentTextColor() { return currentTextColor; } /** Setter for property currentTextColor. * @param currentTextColor New value of property currentTextColor. */ public void setCurrentTextColor(Color currentTextColor) { this.currentTextColor = currentTextColor; } /** Getter for property backgroundMode. * @return Value of property backgroundMode. */ public int getBackgroundMode() { return backgroundMode; } /** Setter for property backgroundMode. * @param backgroundMode New value of property backgroundMode. */ public void setBackgroundMode(int backgroundMode) { this.backgroundMode = backgroundMode; } /** Getter for property textAlign. * @return Value of property textAlign. */ public int getTextAlign() { return textAlign; } /** Setter for property textAlign. * @param textAlign New value of property textAlign. */ public void setTextAlign(int textAlign) { this.textAlign = textAlign; } /** Getter for property polyFillMode. * @return Value of property polyFillMode. */ public int getPolyFillMode() { return polyFillMode; } /** Setter for property polyFillMode. * @param polyFillMode New value of property polyFillMode. */ public void setPolyFillMode(int polyFillMode) { this.polyFillMode = polyFillMode; } public void setLineJoinRectangle(PdfContentByte cb) { if (lineJoin != 0) { lineJoin = 0; cb.setLineJoin(0); } } public void setLineJoinPolygon(PdfContentByte cb) { if (lineJoin == 0) { lineJoin = 1; cb.setLineJoin(1); } } public boolean getLineNeutral() { return (lineJoin == 0); } } src/core/com/lowagie/text/pdf/collection/PdfCollection.java100644 0 0 3147 11000354032 21402 0ustar 0 0 package com.lowagie.text.pdf.collection; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfString; public class PdfCollection extends PdfDictionary { /** A type of PDF Collection */ public static final int DETAILS = 0; /** A type of PDF Collection */ public static final int TILE = 1; /** A type of PDF Collection */ public static final int HIDDEN = 2; /** * Constructs a PDF Collection. * @param type the type of PDF collection. */ public PdfCollection(int type) { super(PdfName.COLLECTION); switch(type) { case TILE: put(PdfName.VIEW, PdfName.T); break; case HIDDEN: put(PdfName.VIEW, PdfName.H); break; default: put(PdfName.VIEW, PdfName.D); } } /** * Identifies the document that will be initially presented * in the user interface. * @param description the description that was used when attaching the file to the document */ public void setInitialDocument(String description) { put(PdfName.D, new PdfString(description, null)); } /** * Sets the Collection schema dictionary. * @param schema an overview of the collection fields */ public void setSchema(PdfCollectionSchema schema) { put(PdfName.SCHEMA, schema); } /** * Gets the Collection schema dictionary. * @return schema an overview of the collection fields */ public PdfCollectionSchema getSchema() { return (PdfCollectionSchema)get(PdfName.SCHEMA); } /** * Sets the Collection sort dictionary. * @param sort a collection sort dictionary */ public void setSort(PdfCollectionSort sort) { put(PdfName.SORT, sort); } }src/core/com/lowagie/text/pdf/collection/PdfCollectionField.java100644 0 0 6550 11012562266 22364 0ustar 0 0 package com.lowagie.text.pdf.collection; import com.lowagie.text.pdf.PdfBoolean; import com.lowagie.text.pdf.PdfDate; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfString; /** * @author blowagie * */ public class PdfCollectionField extends PdfDictionary { /** A possible type of collection field. */ public static final int TEXT = 0; /** A possible type of collection field. */ public static final int DATE = 1; /** A possible type of collection field. */ public static final int NUMBER = 2; /** A possible type of collection field. */ public static final int FILENAME = 3; /** A possible type of collection field. */ public static final int DESC = 4; /** A possible type of collection field. */ public static final int MODDATE = 5; /** A possible type of collection field. */ public static final int CREATIONDATE = 6; /** A possible type of collection field. */ public static final int SIZE = 7; /** * The type of the PDF collection field. * @since 2.1.2 (was called type previously) */ protected int fieldType; /** * Creates a PdfCollectionField. * @param name the field name * @param type the field type */ public PdfCollectionField(String name, int type) { super(PdfName.COLLECTIONFIELD); put(PdfName.N, new PdfString(name, PdfObject.TEXT_UNICODE)); this.fieldType = type; switch(type) { default: put(PdfName.SUBTYPE, PdfName.S); break; case DATE: put(PdfName.SUBTYPE, PdfName.D); break; case NUMBER: put(PdfName.SUBTYPE, PdfName.N); break; case FILENAME: put(PdfName.SUBTYPE, PdfName.F); break; case DESC: put(PdfName.SUBTYPE, PdfName.DESC); break; case MODDATE: put(PdfName.SUBTYPE, PdfName.MODDATE); break; case CREATIONDATE: put(PdfName.SUBTYPE, PdfName.CREATIONDATE); break; case SIZE: put(PdfName.SUBTYPE, PdfName.SIZE); break; } } /** * The relative order of the field name. Fields are sorted in ascending order. * @param i a number indicating the order of the field */ public void setOrder(int i) { put(PdfName.O, new PdfNumber(i)); } /** * Sets the initial visibility of the field. * @param visible the default is true (visible) */ public void setVisible(boolean visible) { put(PdfName.V, new PdfBoolean(visible)); } /** * Indication if the field value should be editable in the viewer. * @param editable the default is false (not editable) */ public void setEditable(boolean editable) { put(PdfName.E, new PdfBoolean(editable)); } /** * Checks if the type of the field is suitable for a Collection Item. */ public boolean isCollectionItem() { switch(fieldType) { case TEXT: case DATE: case NUMBER: return true; default: return false; } } /** * Returns a PdfObject that can be used as the value of a Collection Item. * @param v value the value that has to be changed into a PdfObject (PdfString, PdfDate or PdfNumber) */ public PdfObject getValue(String v) { switch(fieldType) { case TEXT: return new PdfString(v, PdfObject.TEXT_UNICODE); case DATE: return new PdfDate(PdfDate.decode(v)); case NUMBER: return new PdfNumber(v); } throw new IllegalArgumentException(v + " is not an acceptable value for the field " + get(PdfName.N).toString()); } }src/core/com/lowagie/text/pdf/collection/PdfCollectionItem.java100644 0 0 5762 11012562266 22243 0ustar 0 0 package com.lowagie.text.pdf.collection; import java.util.Calendar; import com.lowagie.text.pdf.PdfDate; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfString; public class PdfCollectionItem extends PdfDictionary { /** The PdfCollectionSchema with the names and types of the items. */ PdfCollectionSchema schema; /** * Constructs a Collection Item that can be added to a PdfFileSpecification. */ public PdfCollectionItem(PdfCollectionSchema schema) { super(PdfName.COLLECTIONITEM); this.schema = schema; } /** * Sets the value of the collection item. * @param value */ public void addItem(String key, String value) { PdfName fieldname = new PdfName(key); PdfCollectionField field = (PdfCollectionField)schema.get(fieldname); put(fieldname, field.getValue(value)); } /** * Sets the value of the collection item. * @param value */ public void addItem(String key, PdfString value) { PdfName fieldname = new PdfName(key); PdfCollectionField field = (PdfCollectionField)schema.get(fieldname); if (field.fieldType == PdfCollectionField.TEXT) { put(fieldname, value); } } /** * Sets the value of the collection item. * @param d */ public void addItem(String key, PdfDate d) { PdfName fieldname = new PdfName(key); PdfCollectionField field = (PdfCollectionField)schema.get(fieldname); if (field.fieldType == PdfCollectionField.DATE) { put(fieldname, d); } } /** * Sets the value of the collection item. * @param n */ public void addItem(String key, PdfNumber n) { PdfName fieldname = new PdfName(key); PdfCollectionField field = (PdfCollectionField)schema.get(fieldname); if (field.fieldType == PdfCollectionField.NUMBER) { put(fieldname, n); } } /** * Sets the value of the collection item. * @param c */ public void addItem(String key, Calendar c) { addItem(key, new PdfDate(c)); } /** * Sets the value of the collection item. * @param i */ public void addItem(String key, int i) { addItem(key, new PdfNumber(i)); } /** * Sets the value of the collection item. * @param f */ public void addItem(String key, float f) { addItem(key, new PdfNumber(f)); } /** * Sets the value of the collection item. * @param d */ public void addItem(String key, double d) { addItem(key, new PdfNumber(d)); } /** * Adds a prefix for the Collection item. * You can only use this method after you have set the value of the item. * @param prefix a prefix */ public void setPrefix(String key, String prefix) { PdfName fieldname = new PdfName(key); PdfObject o = get(fieldname); if (o == null) throw new IllegalArgumentException("You must set a value before adding a prefix."); PdfDictionary dict = new PdfDictionary(PdfName.COLLECTIONSUBITEM); dict.put(PdfName.D, o); dict.put(PdfName.P, new PdfString(prefix, PdfObject.TEXT_UNICODE)); put(fieldname, dict); } }src/core/com/lowagie/text/pdf/collection/PdfCollectionSchema.java100644 0 0 1041 11000354032 22512 0ustar 0 0 package com.lowagie.text.pdf.collection; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; public class PdfCollectionSchema extends PdfDictionary { /** * Creates a Collection Schema dictionary. */ public PdfCollectionSchema() { super(PdfName.COLLECTIONSCHEMA); } /** * Adds a Collection field to the Schema. * @param name the name of the collection field * @param field a Collection Field */ public void addField(String name, PdfCollectionField field) { put(new PdfName(name), field); } } src/core/com/lowagie/text/pdf/collection/PdfCollectionSort.java100644 0 0 4045 11036112744 22263 0ustar 0 0 package com.lowagie.text.pdf.collection; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfBoolean; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; public class PdfCollectionSort extends PdfDictionary { /** * Constructs a PDF Collection Sort Dictionary. * @param key the key of the field that will be used to sort entries */ public PdfCollectionSort(String key) { super(PdfName.COLLECTIONSORT); put(PdfName.S, new PdfName(key)); } /** * Constructs a PDF Collection Sort Dictionary. * @param keys the keys of the fields that will be used to sort entries */ public PdfCollectionSort(String[] keys) { super(PdfName.COLLECTIONSORT); PdfArray array = new PdfArray(); for (int i = 0; i < keys.length; i++) { array.add(new PdfName(keys[i])); } put(PdfName.S, array); } /** * Defines the sort order of the field (ascending or descending). * @param ascending true is the default, use false for descending order */ public void setSortOrder(boolean ascending) { PdfObject o = get(PdfName.S); if (o instanceof PdfName) { put(PdfName.A, new PdfBoolean(ascending)); } else { throw new IllegalArgumentException("You have to define a boolean array for this collection sort dictionary."); } } /** * Defines the sort order of the field (ascending or descending). * @param ascending an array with every element corresponding with a name of a field. */ public void setSortOrder(boolean[] ascending) { PdfObject o = get(PdfName.S); if (o instanceof PdfArray) { if (((PdfArray)o).size() != ascending.length) { throw new IllegalArgumentException("The number of booleans in this array doesn't correspond with the number of fields."); } PdfArray array = new PdfArray(); for (int i = 0; i < ascending.length; i++) { array.add(new PdfBoolean(ascending[i])); } put(PdfName.A, array); } else { throw new IllegalArgumentException("You need a single boolean for this collection sort dictionary."); } } } src/core/com/lowagie/text/pdf/collection/PdfTargetDictionary.java100644 0 0 6653 11000354032 22570 0ustar 0 0 package com.lowagie.text.pdf.collection; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfString; public class PdfTargetDictionary extends PdfDictionary { /** * Creates dictionary referring to a target document that is the parent of the current document. * @param nested null if this is the actual target, another target if this is only an intermediate target. */ public PdfTargetDictionary(PdfTargetDictionary nested) { super(); put(PdfName.R, PdfName.P); if (nested != null) setAdditionalPath(nested); } /** * Creates a dictionary referring to a target document. * @param child if false, this refers to the parent document; if true, this refers to a child document, and you'll have to specify where to find the child using the other methods of this class */ public PdfTargetDictionary(boolean child) { super(); if (child) { put(PdfName.R, PdfName.C); } else { put(PdfName.R, PdfName.P); } } /** * If this dictionary refers to a child that is a document level attachment, * you need to specify the name that was used to attach the document. * @param target the name in the EmbeddedFiles name tree */ public void setEmbeddedFileName(String target) { put(PdfName.N, new PdfString(target, null)); } /** * If this dictionary refers to a child that is a file attachment added to a page, * you need to specify the name of the page (or use setFileAttachmentPage to specify the page number). * Once you have specified the page, you still need to specify the attachment using another method. * @param name the named destination referring to the page with the file attachment. */ public void setFileAttachmentPagename(String name) { put(PdfName.P, new PdfString(name, null)); } /** * If this dictionary refers to a child that is a file attachment added to a page, * you need to specify the page number (or use setFileAttachmentPagename to specify a named destination). * Once you have specified the page, you still need to specify the attachment using another method. * @param page the page number of the page with the file attachment. */ public void setFileAttachmentPage(int page) { put(PdfName.P, new PdfNumber(page)); } /** * If this dictionary refers to a child that is a file attachment added to a page, * you need to specify the page with setFileAttachmentPage or setFileAttachmentPageName, * and then specify the name of the attachment added to this page (or use setFileAttachmentIndex). * @param name the name of the attachment */ public void setFileAttachmentName(String name) { put(PdfName.A, new PdfString(name, PdfObject.TEXT_UNICODE)); } /** * If this dictionary refers to a child that is a file attachment added to a page, * you need to specify the page with setFileAttachmentPage or setFileAttachmentPageName, * and then specify the index of the attachment added to this page (or use setFileAttachmentName). * @param annotation the number of the attachment */ public void setFileAttachmentIndex(int annotation) { put(PdfName.A, new PdfNumber(annotation)); } /** * If this dictionary refers to an intermediate target, you can * add the next target in the sequence. * @param nested the next target in the sequence */ public void setAdditionalPath(PdfTargetDictionary nested) { put(PdfName.T, nested); } } src/core/com/lowagie/text/pdf/crypto/AESCipher.java100644 0 0 10255 11000354033 17624 0ustar 0 0 /* * $Id: AESCipher.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.crypto; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; /** * Creates an AES Cipher with CBC and padding PKCS5/7. * @author Paulo Soares (psoares@consiste.pt) */ public class AESCipher { private PaddedBufferedBlockCipher bp; /** Creates a new instance of AESCipher */ public AESCipher(boolean forEncryption, byte[] key, byte[] iv) { BlockCipher aes = new AESFastEngine(); BlockCipher cbc = new CBCBlockCipher(aes); bp = new PaddedBufferedBlockCipher(cbc); KeyParameter kp = new KeyParameter(key); ParametersWithIV piv = new ParametersWithIV(kp, iv); bp.init(forEncryption, piv); } public byte[] update(byte[] inp, int inpOff, int inpLen) { int neededLen = bp.getUpdateOutputSize(inpLen); byte[] outp = null; if (neededLen > 0) outp = new byte[neededLen]; else neededLen = 0; bp.processBytes(inp, inpOff, inpLen, outp, 0); return outp; } public byte[] doFinal() { int neededLen = bp.getOutputSize(0); byte[] outp = new byte[neededLen]; int n = 0; try { n = bp.doFinal(outp, 0); } catch (Exception ex) { return outp; } if (n != outp.length) { byte[] outp2 = new byte[n]; System.arraycopy(outp, 0, outp2, 0, n); return outp2; } else return outp; } } src/core/com/lowagie/text/pdf/crypto/ARCFOUREncryption.java100644 0 0 10122 11000354033 21226 0ustar 0 0 /* * $Id: ARCFOUREncryption.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.crypto; public class ARCFOUREncryption { private byte state[] = new byte[256]; private int x; private int y; /** Creates a new instance of ARCFOUREncryption */ public ARCFOUREncryption() { } public void prepareARCFOURKey(byte key[]) { prepareARCFOURKey(key, 0, key.length); } public void prepareARCFOURKey(byte key[], int off, int len) { int index1 = 0; int index2 = 0; for (int k = 0; k < 256; ++k) state[k] = (byte)k; x = 0; y = 0; byte tmp; for (int k = 0; k < 256; ++k) { index2 = (key[index1 + off] + state[k] + index2) & 255; tmp = state[k]; state[k] = state[index2]; state[index2] = tmp; index1 = (index1 + 1) % len; } } public void encryptARCFOUR(byte dataIn[], int off, int len, byte dataOut[], int offOut) { int length = len + off; byte tmp; for (int k = off; k < length; ++k) { x = (x + 1) & 255; y = (state[x] + y) & 255; tmp = state[x]; state[x] = state[y]; state[y] = tmp; dataOut[k - off + offOut] = (byte)(dataIn[k] ^ state[(state[x] + state[y]) & 255]); } } public void encryptARCFOUR(byte data[], int off, int len) { encryptARCFOUR(data, off, len, data, off); } public void encryptARCFOUR(byte dataIn[], byte dataOut[]) { encryptARCFOUR(dataIn, 0, dataIn.length, dataOut, 0); } public void encryptARCFOUR(byte data[]) { encryptARCFOUR(data, 0, data.length, data, 0); } }src/core/com/lowagie/text/pdf/crypto/IVGenerator.java100644 0 0 7131 11000663663 20241 0ustar 0 0 /* * $Id: IVGenerator.java 3242 2008-04-13 23:00:20Z xlv $ * * Copyright 2006 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.crypto; /** * An initialization vector generator for a CBC block encryption. It's a random generator based on ARCFOUR. * @author Paulo Soares (psoares@consiste.pt) */ public final class IVGenerator { private static ARCFOUREncryption arcfour; static { arcfour = new ARCFOUREncryption(); long time = System.currentTimeMillis(); long mem = Runtime.getRuntime().freeMemory(); String s = time + "+" + mem; arcfour.prepareARCFOURKey(s.getBytes()); } /** Creates a new instance of IVGenerator */ private IVGenerator() { } /** * Gets a 16 byte random initialization vector. * @return a 16 byte random initialization vector */ public static byte[] getIV() { return getIV(16); } /** * Gets a random initialization vector. * @param len the length of the initialization vector * @return a random initialization vector */ public static byte[] getIV(int len) { byte[] b = new byte[len]; synchronized (arcfour) { arcfour.encryptARCFOUR(b); } return b; } }src/core/com/lowagie/text/pdf/draw/DottedLineSeparator.java100644 0 0 7332 11012562272 21405 0ustar 0 0 /* * $Id: DottedLineSeparator.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.draw; import com.lowagie.text.pdf.PdfContentByte; /** * Element that draws a dotted line from left to right. * Can be added directly to a document or column. * Can also be used to create a separator chunk. * @since 2.1.2 */ public class DottedLineSeparator extends LineSeparator { /** the gap between the dots. */ protected float gap = 5; /** * @see com.lowagie.text.pdf.draw.DrawInterface#draw(com.lowagie.text.pdf.PdfContentByte, float, float, float, float, float) */ public void draw(PdfContentByte canvas, float llx, float lly, float urx, float ury, float y) { canvas.saveState(); canvas.setLineWidth(lineWidth); canvas.setLineCap(PdfContentByte.LINE_CAP_ROUND); canvas.setLineDash(0, gap, gap / 2); drawLine(canvas, llx, urx, y); canvas.restoreState(); } /** * Getter for the gap between the center of the dots of the dotted line. * @return the gap between the center of the dots */ public float getGap() { return gap; } /** * Setter for the gap between the center of the dots of the dotted line. * @param gap the gap between the center of the dots */ public void setGap(float gap) { this.gap = gap; } }src/core/com/lowagie/text/pdf/draw/DrawInterface.java100644 0 0 6657 11012562272 20220 0ustar 0 0 /* * $Id: DrawInterface.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.draw; import com.lowagie.text.pdf.PdfContentByte; /** * Interface for an Element that allows you to draw something at the current * vertical position. Trivial implementations are LineSeparator and VerticalPositionMark. * It is also used to define what has to be drawn by a separator chunk. * @since 2.1.2 */ public interface DrawInterface { /** * Implement this method if you want to draw something at the current Y position * (for instance a line). * @param canvas the canvas on which you can draw * @param llx the x coordinate of the left page margin * @param lly the y coordinate of the bottom page margin * @param urx the x coordinate of the right page margin * @param ury the y coordinate of the top page margin * @param y the current y position on the page */ public void draw(PdfContentByte canvas, float llx, float lly, float urx, float ury, float y); }src/core/com/lowagie/text/pdf/draw/LineSeparator.java100644 0 0 16107 11012562272 20261 0ustar 0 0 /* * $Id: LineSeparator.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.draw; import com.lowagie.text.Element; import com.lowagie.text.pdf.PdfContentByte; import java.awt.Color; /** * Element that draws a solid line from left to right. * Can be added directly to a document or column. * Can also be used to create a separator chunk. * @author Paulo Soares * @since 2.1.2 */ public class LineSeparator extends VerticalPositionMark { /** The thickness of the line. */ protected float lineWidth = 1; /** The width of the line as a percentage of the available page width. */ protected float percentage = 100; /** The color of the line. */ protected Color lineColor; /** The alignment of the line. */ protected int alignment = Element.ALIGN_CENTER; /** * Creates a new instance of the LineSeparator class. * @param lineWidth the thickness of the line * @param percentage the width of the line as a percentage of the available page width * @param lineColor the color of the line * @param align the alignment * @param offset the offset of the line relative to the current baseline (negative = under the baseline) */ public LineSeparator(float lineWidth, float percentage, Color lineColor, int align, float offset) { this.lineWidth = lineWidth; this.percentage = percentage; this.lineColor = lineColor; this.alignment = align; this.offset = offset; } /** * Creates a new instance of the LineSeparator class with * default values: lineWidth 1 user unit, width 100%, centered with offset 0. */ public LineSeparator() { } /** * @see com.lowagie.text.pdf.draw.DrawInterface#draw(com.lowagie.text.pdf.PdfContentByte, float, float, float, float, float) */ public void draw(PdfContentByte canvas, float llx, float lly, float urx, float ury, float y) { canvas.saveState(); drawLine(canvas, llx, urx, y); canvas.restoreState(); } /** * Draws a horizontal line. * @param canvas the canvas to draw on * @param leftX the left x coordinate * @param rightX the right x coordindate * @param y the y coordinate */ public void drawLine(PdfContentByte canvas, float leftX, float rightX, float y) { float w; if (getPercentage() < 0) w = -getPercentage(); else w = (rightX - leftX) * getPercentage() / 100.0f; float s; switch (getAlignment()) { case Element.ALIGN_LEFT: s = 0; break; case Element.ALIGN_RIGHT: s = rightX - leftX - w; break; default: s = (rightX - leftX - w) / 2; break; } canvas.setLineWidth(getLineWidth()); if (getLineColor() != null) canvas.setColorStroke(getLineColor()); canvas.moveTo(s + leftX, y + offset); canvas.lineTo(s + w + leftX, y + offset); canvas.stroke(); } /** * Getter for the line width. * @return the thickness of the line that will be drawn. */ public float getLineWidth() { return lineWidth; } /** * Setter for the line width. * @param lineWidth the thickness of the line that will be drawn. */ public void setLineWidth(float lineWidth) { this.lineWidth = lineWidth; } /** * Setter for the width as a percentage of the available width. * @return a width percentage */ public float getPercentage() { return percentage; } /** * Setter for the width as a percentage of the available width. * @param percentage a width percentage */ public void setPercentage(float percentage) { this.percentage = percentage; } /** * Getter for the color of the line that will be drawn. * @return a color */ public Color getLineColor() { return lineColor; } /** * Setter for the color of the line that will be drawn. * @param color a color */ public void setLineColor(Color color) { this.lineColor = color; } /** * Getter for the alignment of the line. * @return an alignment value */ public int getAlignment() { return alignment; } /** * Setter for the alignment of the line. * @param align an alignment value */ public void setAlignment(int align) { this.alignment = align; } }src/core/com/lowagie/text/pdf/draw/VerticalPositionMark.java100644 0 0 13703 11012562272 21621 0ustar 0 0 /* * $Id: VerticalPositionMark.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.draw; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementListener; import com.lowagie.text.pdf.PdfContentByte; /** * Helper class implementing the DrawInterface. Can be used to add * horizontal or vertical separators. Won't draw anything unless * you implement the draw method. * @since 2.1.2 */ public class VerticalPositionMark implements DrawInterface, Element { /** Another implementation of the DrawInterface; its draw method will overrule LineSeparator.draw(). */ protected DrawInterface drawInterface = null; /** The offset for the line. */ protected float offset = 0; /** * Creates a vertical position mark that won't draw anything unless * you define a DrawInterface. */ public VerticalPositionMark() { } /** * Creates a vertical position mark that won't draw anything unless * you define a DrawInterface. * @param drawInterface the drawInterface for this vertical position mark. * @param offset the offset for this vertical position mark. */ public VerticalPositionMark(DrawInterface drawInterface, float offset) { this.drawInterface = drawInterface; this.offset = offset; } /** * @see com.lowagie.text.pdf.draw.DrawInterface#draw(com.lowagie.text.pdf.PdfContentByte, float, float, float, float, float) */ public void draw(PdfContentByte canvas, float llx, float lly, float urx, float ury, float y) { if (drawInterface != null) { drawInterface.draw(canvas, llx, lly, urx, ury, y + offset); } } /** * @see com.lowagie.text.Element#process(com.lowagie.text.ElementListener) */ public boolean process(ElementListener listener) { try { return listener.add(this); } catch (DocumentException e) { return false; } } /** * @see com.lowagie.text.Element#type() */ public int type() { return Element.YMARK; } /** * @see com.lowagie.text.Element#isContent() */ public boolean isContent() { return true; } /** * @see com.lowagie.text.Element#isNestable() */ public boolean isNestable() { return false; } /** * @see com.lowagie.text.Element#getChunks() */ public ArrayList getChunks() { ArrayList list = new ArrayList(); list.add(new Chunk(this, true)); return list; } /** * Getter for the interface with the overruling draw() method. * @return a DrawInterface implementation */ public DrawInterface getDrawInterface() { return drawInterface; } /** * Setter for the interface with the overruling draw() method. * @param drawInterface a DrawInterface implementation */ public void setDrawInterface(DrawInterface drawInterface) { this.drawInterface = drawInterface; } /** * Getter for the offset relative to the baseline of the current line. * @return an offset */ public float getOffset() { return offset; } /** * Setter for the offset. The offset is relative to the current * Y position. If you want to underline something, you have to * choose a negative offset. * @param offset an offset */ public void setOffset(float offset) { this.offset = offset; } } src/core/com/lowagie/text/pdf/events/FieldPositioningEvents.java100644 0 0 16545 11154165265 22531 0ustar 0 0 /* * Copyright 2005 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.events; import java.io.IOException; import java.util.HashMap; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfFormField; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPCellEvent; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfRectangle; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.TextField; /** * Class that can be used to position AcroForm fields. */ public class FieldPositioningEvents extends PdfPageEventHelper implements PdfPCellEvent { /** * Keeps a map with fields that are to be positioned in inGenericTag. */ protected HashMap genericChunkFields = new HashMap(); /** * Keeps the form field that is to be positioned in a cellLayout event. */ protected PdfFormField cellField = null; /** * The PdfWriter to use when a field has to added in a cell event. */ protected PdfWriter fieldWriter = null; /** * The PdfFormField that is the parent of the field added in a cell event. */ protected PdfFormField parent = null; /** Creates a new event. This constructor will be used if you need to position fields with Chunk objects. */ public FieldPositioningEvents() {} /** Some extra padding that will be taken into account when defining the widget. */ public float padding; /** * Add a PdfFormField that has to be tied to a generic Chunk. */ public void addField(String text, PdfFormField field) { genericChunkFields.put(text, field); } /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. */ public FieldPositioningEvents(PdfWriter writer, PdfFormField field) { this.cellField = field; this.fieldWriter = writer; } /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. */ public FieldPositioningEvents(PdfFormField parent, PdfFormField field) { this.cellField = field; this.parent = parent; } /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. * @throws DocumentException * @throws IOException*/ public FieldPositioningEvents(PdfWriter writer, String text) throws IOException, DocumentException { this.fieldWriter = writer; TextField tf = new TextField(writer, new Rectangle(0, 0), text); tf.setFontSize(14); cellField = tf.getTextField(); } /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. * @throws DocumentException * @throws IOException*/ public FieldPositioningEvents(PdfWriter writer, PdfFormField parent, String text) throws IOException, DocumentException { this.parent = parent; TextField tf = new TextField(writer, new Rectangle(0, 0), text); tf.setFontSize(14); cellField = tf.getTextField(); } /** * @param padding The padding to set. */ public void setPadding(float padding) { this.padding = padding; } /** * @param parent The parent to set. */ public void setParent(PdfFormField parent) { this.parent = parent; } /** * @see com.lowagie.text.pdf.PdfPageEvent#onGenericTag(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document, com.lowagie.text.Rectangle, java.lang.String) */ public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { rect.setBottom(rect.getBottom() - 3); PdfFormField field = (PdfFormField) genericChunkFields.get(text); if (field == null) { TextField tf = new TextField(writer, new Rectangle(rect.getLeft(padding), rect.getBottom(padding), rect.getRight(padding), rect.getTop(padding)), text); tf.setFontSize(14); try { field = tf.getTextField(); } catch (Exception e) { throw new ExceptionConverter(e); } } else { field.put(PdfName.RECT, new PdfRectangle(rect.getLeft(padding), rect.getBottom(padding), rect.getRight(padding), rect.getTop(padding))); } if (parent == null) writer.addAnnotation(field); else parent.addKid(field); } /** * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell, com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[]) */ public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases) { if (cellField == null || (fieldWriter == null && parent == null)) throw new ExceptionConverter(new IllegalArgumentException("You have used the wrong constructor for this FieldPositioningEvents class.")); cellField.put(PdfName.RECT, new PdfRectangle(rect.getLeft(padding), rect.getBottom(padding), rect.getRight(padding), rect.getTop(padding))); if (parent == null) fieldWriter.addAnnotation(cellField); else parent.addKid(cellField); } }src/core/com/lowagie/text/pdf/events/IndexEvents.java100644 0 0 27024 11000354037 20307 0ustar 0 0 /* * Copyright 2005 by Michael Niedermair. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.events; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfWriter; /** * Class for an index. * * @author Michael Niedermair */ public class IndexEvents extends PdfPageEventHelper { /** * keeps the indextag with the pagenumber */ private Map indextag = new TreeMap(); /** * All the text that is passed to this event, gets registered in the indexentry. * * @see com.lowagie.text.pdf.PdfPageEventHelper#onGenericTag( * com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document, * com.lowagie.text.Rectangle, java.lang.String) */ public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { indextag.put(text, new Integer(writer.getPageNumber())); } // -------------------------------------------------------------------- /** * indexcounter */ private long indexcounter = 0; /** * the list for the index entry */ private List indexentry = new ArrayList(); /** * Create an index entry. * * @param text The text for the Chunk. * @param in1 The first level. * @param in2 The second level. * @param in3 The third level. * @return Returns the Chunk. */ public Chunk create(final String text, final String in1, final String in2, final String in3) { Chunk chunk = new Chunk(text); String tag = "idx_" + (indexcounter++); chunk.setGenericTag(tag); chunk.setLocalDestination(tag); Entry entry = new Entry(in1, in2, in3, tag); indexentry.add(entry); return chunk; } /** * Create an index entry. * * @param text The text for the Chunk. * @param in1 The first level. * @return Returns the Chunk. */ public Chunk create(final String text, final String in1) { return create(text, in1, "", ""); } /** * Create an index entry. * * @param text The text for the Chunk. * @param in1 The first level. * @param in2 The second level. * @return Returns the Chunk. */ public Chunk create(final String text, final String in1, final String in2) { return create(text, in1, in2, ""); } /** * Create an index entry. * * @param text The text. * @param in1 The first level. * @param in2 The second level. * @param in3 The third level. */ public void create(final Chunk text, final String in1, final String in2, final String in3) { String tag = "idx_" + (indexcounter++); text.setGenericTag(tag); text.setLocalDestination(tag); Entry entry = new Entry(in1, in2, in3, tag); indexentry.add(entry); } /** * Create an index entry. * * @param text The text. * @param in1 The first level. */ public void create(final Chunk text, final String in1) { create(text, in1, "", ""); } /** * Create an index entry. * * @param text The text. * @param in1 The first level. * @param in2 The second level. */ public void create(final Chunk text, final String in1, final String in2) { create(text, in1, in2, ""); } /** * Comparator for sorting the index */ private Comparator comparator = new Comparator() { public int compare(Object arg0, Object arg1) { Entry en1 = (Entry) arg0; Entry en2 = (Entry) arg1; int rt = 0; if (en1.getIn1() != null && en2.getIn1() != null) { if ((rt = en1.getIn1().compareToIgnoreCase(en2.getIn1())) == 0) { // in1 equals if (en1.getIn2() != null && en2.getIn2() != null) { if ((rt = en1.getIn2() .compareToIgnoreCase(en2.getIn2())) == 0) { // in2 equals if (en1.getIn3() != null && en2.getIn3() != null) { rt = en1.getIn3().compareToIgnoreCase( en2.getIn3()); } } } } } return rt; } }; /** * Set the comparator. * @param aComparator The comparator to set. */ public void setComparator(Comparator aComparator) { comparator = aComparator; } /** * Returns the sorted list with the entries and the collected page numbers. * @return Returns the sorted list with the entries and the collected page numbers. */ public List getSortedEntries() { Map grouped = new HashMap(); for (int i = 0; i < indexentry.size(); i++) { Entry e = (Entry) indexentry.get(i); String key = e.getKey(); Entry master = (Entry) grouped.get(key); if (master != null) { master.addPageNumberAndTag(e.getPageNumber(), e.getTag()); } else { e.addPageNumberAndTag(e.getPageNumber(), e.getTag()); grouped.put(key, e); } } // copy to a list and sort it List sorted = new ArrayList(grouped.values()); Collections.sort(sorted, comparator); return sorted; } // -------------------------------------------------------------------- /** * Class for an index entry. *

    * In the first step, only in1, in2,in3 and tag are used. * After the collections of the index entries, pagenumbers are used. *

    */ public class Entry { /** * first level */ private String in1; /** * second level */ private String in2; /** * third level */ private String in3; /** * the tag */ private String tag; /** * the list of all page numbers. */ private List pagenumbers = new ArrayList(); /** * the list of all tags. */ private List tags = new ArrayList(); /** * Create a new object. * @param aIn1 The first level. * @param aIn2 The second level. * @param aIn3 The third level. * @param aTag The tag. */ public Entry(final String aIn1, final String aIn2, final String aIn3, final String aTag) { in1 = aIn1; in2 = aIn2; in3 = aIn3; tag = aTag; } /** * Returns the in1. * @return Returns the in1. */ public String getIn1() { return in1; } /** * Returns the in2. * @return Returns the in2. */ public String getIn2() { return in2; } /** * Returns the in3. * @return Returns the in3. */ public String getIn3() { return in3; } /** * Returns the tag. * @return Returns the tag. */ public String getTag() { return tag; } /** * Returns the pagenumber for this entry. * @return Returns the pagenumber for this entry. */ public int getPageNumber() { int rt = -1; Integer i = (Integer) indextag.get(tag); if (i != null) { rt = i.intValue(); } return rt; } /** * Add a pagenumber. * @param number The page number. * @param tag */ public void addPageNumberAndTag(final int number, final String tag) { pagenumbers.add(new Integer(number)); tags.add(tag); } /** * Returns the key for the map-entry. * @return Returns the key for the map-entry. */ public String getKey() { return in1 + "!" + in2 + "!" + in3; } /** * Returns the pagenumbers. * @return Returns the pagenumbers. */ public List getPagenumbers() { return pagenumbers; } /** * Returns the tags. * @return Returns the tags. */ public List getTags() { return tags; } /** * print the entry (only for test) * @return the toString implementation of the entry */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append(in1).append(' '); buf.append(in2).append(' '); buf.append(in3).append(' '); for (int i = 0; i < pagenumbers.size(); i++) { buf.append(pagenumbers.get(i)).append(' '); } return buf.toString(); } } }src/core/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java100644 0 0 7257 11012562267 22361 0ustar 0 0 /* * $Id: PdfPCellEventForwarder.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.events; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPCellEvent; /** * If you want to add more than one event to a cell, * you have to construct a PdfPCellEventForwarder, add the * different events to this object and add the forwarder to * the PdfPCell. */ public class PdfPCellEventForwarder implements PdfPCellEvent { /** ArrayList containing all the PageEvents that have to be executed. */ protected ArrayList events = new ArrayList(); /** * Add a page event to the forwarder. * @param event an event that has to be added to the forwarder. */ public void addCellEvent(PdfPCellEvent event) { events.add(event); } /** * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell, com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[]) */ public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { PdfPCellEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPCellEvent)i.next(); event.cellLayout(cell, position, canvases); } } }src/core/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java100644 0 0 7365 11012562267 22531 0ustar 0 0 /* * $Id: PdfPTableEventForwarder.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.events; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfPTableEvent; /** * If you want to add more than one page event to a PdfPTable, * you have to construct a PdfPTableEventForwarder, add the * different events to this object and add the forwarder to * the PdfWriter. */ public class PdfPTableEventForwarder implements PdfPTableEvent { /** ArrayList containing all the PageEvents that have to be executed. */ protected ArrayList events = new ArrayList(); /** * Add a page event to the forwarder. * @param event an event that has to be added to the forwarder. */ public void addTableEvent(PdfPTableEvent event) { events.add(event); } /** * @see com.lowagie.text.pdf.PdfPTableEvent#tableLayout(com.lowagie.text.pdf.PdfPTable, float[][], float[], int, int, com.lowagie.text.pdf.PdfContentByte[]) */ public void tableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) { PdfPTableEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPTableEvent)i.next(); event.tableLayout(table, widths, heights, headerRows, rowStart, canvases); } } }src/core/com/lowagie/text/pdf/events/PdfPageEventForwarder.java100644 0 0 23603 11012562267 22247 0ustar 0 0 /* * $Id: PdfPageEventForwarder.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.events; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfPageEvent; import com.lowagie.text.pdf.PdfWriter; /** * If you want to add more than one page event to a PdfWriter, * you have to construct a PdfPageEventForwarder, add the * different events to this object and add the forwarder to * the PdfWriter. */ public class PdfPageEventForwarder implements PdfPageEvent { /** ArrayList containing all the PageEvents that have to be executed. */ protected ArrayList events = new ArrayList(); /** * Add a page event to the forwarder. * @param event an event that has to be added to the forwarder. */ public void addPageEvent(PdfPageEvent event) { events.add(event); } /** * Called when the document is opened. * * @param writer * the PdfWriter for this document * @param document * the document */ public void onOpenDocument(PdfWriter writer, Document document) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onOpenDocument(writer, document); } } /** * Called when a page is initialized. *

    * Note that if even if a page is not written this method is still called. * It is preferable to use onEndPage to avoid infinite loops. * * @param writer * the PdfWriter for this document * @param document * the document */ public void onStartPage(PdfWriter writer, Document document) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onStartPage(writer, document); } } /** * Called when a page is finished, just before being written to the * document. * * @param writer * the PdfWriter for this document * @param document * the document */ public void onEndPage(PdfWriter writer, Document document) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onEndPage(writer, document); } } /** * Called when the document is closed. *

    * Note that this method is called with the page number equal to the last * page plus one. * * @param writer * the PdfWriter for this document * @param document * the document */ public void onCloseDocument(PdfWriter writer, Document document) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onCloseDocument(writer, document); } } /** * Called when a Paragraph is written. *

    * paragraphPosition will hold the height at which the * paragraph will be written to. This is useful to insert bookmarks with * more control. * * @param writer * the PdfWriter for this document * @param document * the document * @param paragraphPosition * the position the paragraph will be written to */ public void onParagraph(PdfWriter writer, Document document, float paragraphPosition) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onParagraph(writer, document, paragraphPosition); } } /** * Called when a Paragraph is written. *

    * paragraphPosition will hold the height of the end of the * paragraph. * * @param writer * the PdfWriter for this document * @param document * the document * @param paragraphPosition * the position of the end of the paragraph */ public void onParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onParagraphEnd(writer, document, paragraphPosition); } } /** * Called when a Chapter is written. *

    * position will hold the height at which the chapter will be * written to. * * @param writer * the PdfWriter for this document * @param document * the document * @param paragraphPosition * the position the chapter will be written to * @param title * the title of the Chapter */ public void onChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onChapter(writer, document, paragraphPosition, title); } } /** * Called when the end of a Chapter is reached. *

    * position will hold the height of the end of the chapter. * * @param writer * the PdfWriter for this document * @param document * the document * @param position * the position of the end of the chapter. */ public void onChapterEnd(PdfWriter writer, Document document, float position) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onChapterEnd(writer, document, position); } } /** * Called when a Section is written. *

    * position will hold the height at which the section will be * written to. * * @param writer * the PdfWriter for this document * @param document * the document * @param paragraphPosition * the position the section will be written to * @param depth * the number depth of the Section * @param title * the title of the section */ public void onSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onSection(writer, document, paragraphPosition, depth, title); } } /** * Called when the end of a Section is reached. *

    * position will hold the height of the section end. * * @param writer * the PdfWriter for this document * @param document * the document * @param position * the position of the end of the section */ public void onSectionEnd(PdfWriter writer, Document document, float position) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onSectionEnd(writer, document, position); } } /** * Called when a Chunk with a generic tag is written. *

    * It is useful to pinpoint the Chunk location to generate * bookmarks, for example. * * @param writer * the PdfWriter for this document * @param document * the document * @param rect * the Rectangle containing the Chunk * * @param text * the text of the tag */ public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { PdfPageEvent event; for (Iterator i = events.iterator(); i.hasNext(); ) { event = (PdfPageEvent)i.next(); event.onGenericTag(writer, document, rect, text); } } }src/core/com/lowagie/text/pdf/fonts/Courier-Bold.afm100644 0 0 36473 11000354125 20016 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jun 23 16:28:00 1997 Comment UniqueID 43048 Comment VMusage 41139 52164 FontName Courier-Bold FullName Courier Bold FamilyName Courier Weight Bold ItalicAngle 0 IsFixedPitch true CharacterSet ExtendedRoman FontBBox -113 -250 749 801 UnderlinePosition -100 UnderlineThickness 50 Version 003.000 Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 439 Ascender 629 Descender -157 StdHW 84 StdVW 106 StartCharMetrics 315 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ; C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; C 49 ; WX 600 ; N one ; B 81 0 539 616 ; C 50 ; WX 600 ; N two ; B 61 0 499 616 ; C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; C 52 ; WX 600 ; N four ; B 53 0 507 616 ; C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; C 60 ; WX 600 ; N less ; B 66 15 523 501 ; C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; C 65 ; WX 600 ; N A ; B -9 0 609 562 ; C 66 ; WX 600 ; N B ; B 30 0 573 562 ; C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; C 68 ; WX 600 ; N D ; B 30 0 594 562 ; C 69 ; WX 600 ; N E ; B 25 0 560 562 ; C 70 ; WX 600 ; N F ; B 39 0 570 562 ; C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; C 72 ; WX 600 ; N H ; B 20 0 580 562 ; C 73 ; WX 600 ; N I ; B 77 0 523 562 ; C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; C 75 ; WX 600 ; N K ; B 21 0 599 562 ; C 76 ; WX 600 ; N L ; B 39 0 578 562 ; C 77 ; WX 600 ; N M ; B -2 0 602 562 ; C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; C 80 ; WX 600 ; N P ; B 48 0 559 562 ; C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; C 82 ; WX 600 ; N R ; B 24 0 599 562 ; C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; C 84 ; WX 600 ; N T ; B 21 0 579 562 ; C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; C 86 ; WX 600 ; N V ; B -13 0 613 562 ; C 87 ; WX 600 ; N W ; B -18 0 618 562 ; C 88 ; WX 600 ; N X ; B 12 0 588 562 ; C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; C 104 ; WX 600 ; N h ; B 5 0 592 626 ; C 105 ; WX 600 ; N i ; B 77 0 523 658 ; C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; C 107 ; WX 600 ; N k ; B 20 0 585 626 ; C 108 ; WX 600 ; N l ; B 77 0 523 626 ; C 109 ; WX 600 ; N m ; B -22 0 626 454 ; C 110 ; WX 600 ; N n ; B 18 0 592 454 ; C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; C 114 ; WX 600 ; N r ; B 47 0 580 454 ; C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; C 118 ; WX 600 ; N v ; B -1 0 601 439 ; C 119 ; WX 600 ; N w ; B -18 0 618 439 ; C 120 ; WX 600 ; N x ; B 6 0 594 439 ; C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; C 122 ; WX 600 ; N z ; B 81 0 520 439 ; C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ; C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ; C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; C 168 ; WX 600 ; N currency ; B 54 49 546 517 ; C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; C 174 ; WX 600 ; N fi ; B 12 0 593 626 ; C 175 ; WX 600 ; N fl ; B 12 0 593 626 ; C 177 ; WX 600 ; N endash ; B 65 203 535 313 ; C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ; C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ; C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; C 193 ; WX 600 ; N grave ; B 132 508 395 661 ; C 194 ; WX 600 ; N acute ; B 205 508 468 661 ; C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ; C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ; C 197 ; WX 600 ; N macron ; B 88 505 512 585 ; C 198 ; WX 600 ; N breve ; B 83 468 517 631 ; C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ; C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ; C 202 ; WX 600 ; N ring ; B 198 481 402 678 ; C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ; C 207 ; WX 600 ; N caron ; B 103 493 497 667 ; C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ; C 225 ; WX 600 ; N AE ; B -29 0 602 562 ; C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ; C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; C 234 ; WX 600 ; N OE ; B -25 0 595 562 ; C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ; C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ; C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ; C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ; C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ; C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ; C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ; C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ; C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ; C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ; C -1 ; WX 600 ; N divide ; B 71 16 529 500 ; C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ; C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ; C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ; C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ; C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ; C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ; C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ; C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ; C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ; C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ; C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ; C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ; C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ; C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ; C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ; C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ; C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ; C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ; C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ; C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ; C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ; C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ; C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ; C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ; C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ; C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ; C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ; C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ; C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ; C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ; C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ; C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ; C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ; C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ; C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ; C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ; C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ; C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ; C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ; C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ; C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ; C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ; C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ; C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ; C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ; C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ; C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ; C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ; C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ; C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ; C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ; C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ; C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ; C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ; C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ; C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ; C -1 ; WX 600 ; N racute ; B 47 0 580 661 ; C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ; C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ; C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ; C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ; C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ; C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ; C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ; C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ; C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ; C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ; C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ; C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ; C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ; C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ; C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ; C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ; C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ; C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ; C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ; C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ; C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ; C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ; C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ; C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ; C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ; C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ; C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ; C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ; C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ; C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ; C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ; C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ; C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ; C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ; C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ; C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ; C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ; C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ; C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ; C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ; C -1 ; WX 600 ; N degree ; B 86 243 474 616 ; C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ; C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ; C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ; C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ; C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ; C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ; C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ; C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ; C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ; C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ; C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ; C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ; C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ; C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ; C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ; C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ; C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ; C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ; C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ; C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ; C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ; C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ; C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ; C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ; C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ; C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Courier-BoldOblique.afm100644 0 0 36575 11000354125 21342 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Mon Jun 23 16:28:46 1997 Comment UniqueID 43049 Comment VMusage 17529 79244 FontName Courier-BoldOblique FullName Courier Bold Oblique FamilyName Courier Weight Bold ItalicAngle -12 IsFixedPitch true CharacterSet ExtendedRoman FontBBox -57 -250 869 801 UnderlinePosition -100 UnderlineThickness 50 Version 003.000 Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 439 Ascender 629 Descender -157 StdHW 84 StdVW 106 StartCharMetrics 315 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ; C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ; C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ; C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ; C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ; C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ; C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ; C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ; C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ; C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; C 46 ; WX 600 ; N period ; B 206 -15 427 171 ; C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ; C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ; C 49 ; WX 600 ; N one ; B 93 0 562 616 ; C 50 ; WX 600 ; N two ; B 61 0 594 616 ; C 51 ; WX 600 ; N three ; B 71 -15 571 616 ; C 52 ; WX 600 ; N four ; B 81 0 559 616 ; C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; C 54 ; WX 600 ; N six ; B 135 -15 652 616 ; C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ; C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ; C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ; C 60 ; WX 600 ; N less ; B 120 15 613 501 ; C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; C 63 ; WX 600 ; N question ; B 183 -14 592 580 ; C 64 ; WX 600 ; N at ; B 65 -15 642 616 ; C 65 ; WX 600 ; N A ; B -9 0 632 562 ; C 66 ; WX 600 ; N B ; B 30 0 630 562 ; C 67 ; WX 600 ; N C ; B 74 -18 675 580 ; C 68 ; WX 600 ; N D ; B 30 0 664 562 ; C 69 ; WX 600 ; N E ; B 25 0 670 562 ; C 70 ; WX 600 ; N F ; B 39 0 684 562 ; C 71 ; WX 600 ; N G ; B 74 -18 675 580 ; C 72 ; WX 600 ; N H ; B 20 0 700 562 ; C 73 ; WX 600 ; N I ; B 77 0 643 562 ; C 74 ; WX 600 ; N J ; B 58 -18 721 562 ; C 75 ; WX 600 ; N K ; B 21 0 692 562 ; C 76 ; WX 600 ; N L ; B 39 0 636 562 ; C 77 ; WX 600 ; N M ; B -2 0 722 562 ; C 78 ; WX 600 ; N N ; B 8 -12 730 562 ; C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; C 80 ; WX 600 ; N P ; B 48 0 643 562 ; C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ; C 82 ; WX 600 ; N R ; B 24 0 617 562 ; C 83 ; WX 600 ; N S ; B 54 -22 673 582 ; C 84 ; WX 600 ; N T ; B 86 0 679 562 ; C 85 ; WX 600 ; N U ; B 101 -18 716 562 ; C 86 ; WX 600 ; N V ; B 84 0 733 562 ; C 87 ; WX 600 ; N W ; B 79 0 738 562 ; C 88 ; WX 600 ; N X ; B 12 0 690 562 ; C 89 ; WX 600 ; N Y ; B 109 0 709 562 ; C 90 ; WX 600 ; N Z ; B 62 0 637 562 ; C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ; C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ; C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ; C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; C 97 ; WX 600 ; N a ; B 61 -15 593 454 ; C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; C 100 ; WX 600 ; N d ; B 60 -15 645 626 ; C 101 ; WX 600 ; N e ; B 81 -15 605 454 ; C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 40 -146 674 454 ; C 104 ; WX 600 ; N h ; B 18 0 615 626 ; C 105 ; WX 600 ; N i ; B 77 0 546 658 ; C 106 ; WX 600 ; N j ; B 36 -146 580 658 ; C 107 ; WX 600 ; N k ; B 33 0 643 626 ; C 108 ; WX 600 ; N l ; B 77 0 546 626 ; C 109 ; WX 600 ; N m ; B -22 0 649 454 ; C 110 ; WX 600 ; N n ; B 18 0 615 454 ; C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; C 112 ; WX 600 ; N p ; B -32 -142 622 454 ; C 113 ; WX 600 ; N q ; B 60 -142 685 454 ; C 114 ; WX 600 ; N r ; B 47 0 655 454 ; C 115 ; WX 600 ; N s ; B 66 -17 608 459 ; C 116 ; WX 600 ; N t ; B 118 -15 567 562 ; C 117 ; WX 600 ; N u ; B 70 -15 592 439 ; C 118 ; WX 600 ; N v ; B 70 0 695 439 ; C 119 ; WX 600 ; N w ; B 53 0 712 439 ; C 120 ; WX 600 ; N x ; B 6 0 671 439 ; C 121 ; WX 600 ; N y ; B -21 -142 695 439 ; C 122 ; WX 600 ; N z ; B 81 0 614 439 ; C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ; C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ; C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ; C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ; C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ; C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ; C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ; C 165 ; WX 600 ; N yen ; B 98 0 710 562 ; C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ; C 167 ; WX 600 ; N section ; B 74 -70 620 580 ; C 168 ; WX 600 ; N currency ; B 77 49 644 517 ; C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ; C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ; C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ; C 174 ; WX 600 ; N fi ; B 12 0 644 626 ; C 175 ; WX 600 ; N fl ; B 12 0 644 626 ; C 177 ; WX 600 ; N endash ; B 108 203 602 313 ; C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ; C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ; C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ; C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ; C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ; C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ; C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ; C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ; C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ; C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ; C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ; C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ; C 193 ; WX 600 ; N grave ; B 272 508 503 661 ; C 194 ; WX 600 ; N acute ; B 312 508 609 661 ; C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ; C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ; C 197 ; WX 600 ; N macron ; B 195 505 637 585 ; C 198 ; WX 600 ; N breve ; B 217 468 652 631 ; C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ; C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ; C 202 ; WX 600 ; N ring ; B 319 481 528 678 ; C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ; C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ; C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ; C 207 ; WX 600 ; N caron ; B 238 493 633 667 ; C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ; C 225 ; WX 600 ; N AE ; B -29 0 708 562 ; C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ; C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ; C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ; C 234 ; WX 600 ; N OE ; B 26 0 701 562 ; C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ; C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ; C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ; C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ; C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ; C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ; C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ; C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ; C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ; C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ; C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ; C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ; C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ; C -1 ; WX 600 ; N divide ; B 114 16 596 500 ; C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ; C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ; C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ; C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ; C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ; C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ; C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ; C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ; C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ; C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ; C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ; C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ; C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ; C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ; C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ; C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ; C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ; C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ; C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ; C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ; C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ; C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ; C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ; C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ; C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ; C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ; C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ; C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ; C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ; C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ; C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ; C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ; C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ; C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ; C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ; C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ; C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ; C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ; C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ; C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ; C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ; C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ; C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ; C -1 ; WX 600 ; N threesuperior ; B 193 222 526 616 ; C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ; C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ; C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ; C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ; C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ; C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ; C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ; C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ; C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ; C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ; C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ; C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ; C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ; C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ; C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ; C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ; C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ; C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ; C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ; C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ; C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ; C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ; C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ; C -1 ; WX 600 ; N racute ; B 47 0 655 661 ; C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ; C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ; C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ; C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ; C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ; C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ; C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ; C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ; C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ; C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ; C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ; C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ; C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ; C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ; C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ; C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ; C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ; C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ; C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ; C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ; C -1 ; WX 600 ; N twosuperior ; B 191 230 542 616 ; C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ; C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ; C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ; C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ; C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ; C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ; C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ; C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ; C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ; C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ; C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ; C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ; C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ; C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ; C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ; C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ; C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ; C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ; C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ; C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ; C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ; C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ; C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ; C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ; C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ; C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ; C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ; C -1 ; WX 600 ; N degree ; B 173 243 570 616 ; C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ; C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ; C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ; C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ; C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ; C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ; C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ; C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ; C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ; C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ; C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ; C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ; C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ; C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ; C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ; C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ; C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ; C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ; C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ; C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ; C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ; C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ; C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ; C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ; C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ; C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ; C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ; C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ; C -1 ; WX 600 ; N onesuperior ; B 212 230 514 616 ; C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ; C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Courier-Oblique.afm100644 0 0 36647 11000354125 20541 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 17:37:52 1997 Comment UniqueID 43051 Comment VMusage 16248 75829 FontName Courier-Oblique FullName Courier Oblique FamilyName Courier Weight Medium ItalicAngle -12 IsFixedPitch true CharacterSet ExtendedRoman FontBBox -27 -250 849 805 UnderlinePosition -100 UnderlineThickness 50 Version 003.000 Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 426 Ascender 629 Descender -157 StdHW 51 StdVW 51 StartCharMetrics 315 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ; C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; C 49 ; WX 600 ; N one ; B 98 0 515 622 ; C 50 ; WX 600 ; N two ; B 70 0 568 622 ; C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; C 52 ; WX 600 ; N four ; B 108 0 541 622 ; C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; C 60 ; WX 600 ; N less ; B 96 42 610 472 ; C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; C 65 ; WX 600 ; N A ; B 3 0 607 562 ; C 66 ; WX 600 ; N B ; B 43 0 616 562 ; C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; C 68 ; WX 600 ; N D ; B 43 0 645 562 ; C 69 ; WX 600 ; N E ; B 53 0 660 562 ; C 70 ; WX 600 ; N F ; B 53 0 660 562 ; C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; C 72 ; WX 600 ; N H ; B 32 0 687 562 ; C 73 ; WX 600 ; N I ; B 96 0 623 562 ; C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; C 75 ; WX 600 ; N K ; B 38 0 671 562 ; C 76 ; WX 600 ; N L ; B 47 0 607 562 ; C 77 ; WX 600 ; N M ; B 4 0 715 562 ; C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; C 80 ; WX 600 ; N P ; B 79 0 644 562 ; C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; C 82 ; WX 600 ; N R ; B 38 0 598 562 ; C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; C 84 ; WX 600 ; N T ; B 108 0 665 562 ; C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; C 88 ; WX 600 ; N X ; B 23 0 675 562 ; C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; C 104 ; WX 600 ; N h ; B 33 0 592 629 ; C 105 ; WX 600 ; N i ; B 95 0 515 657 ; C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; C 107 ; WX 600 ; N k ; B 58 0 633 629 ; C 108 ; WX 600 ; N l ; B 95 0 515 629 ; C 109 ; WX 600 ; N m ; B -5 0 615 441 ; C 110 ; WX 600 ; N n ; B 26 0 585 441 ; C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; C 114 ; WX 600 ; N r ; B 60 0 636 441 ; C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; C 120 ; WX 600 ; N x ; B 20 0 655 426 ; C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; C 122 ; WX 600 ; N z ; B 99 0 593 426 ; C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ; C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ; C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; C 168 ; WX 600 ; N currency ; B 94 58 628 506 ; C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; C 174 ; WX 600 ; N fi ; B 3 0 619 629 ; C 175 ; WX 600 ; N fl ; B 3 0 619 629 ; C 177 ; WX 600 ; N endash ; B 124 231 586 285 ; C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ; C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ; C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; C 193 ; WX 600 ; N grave ; B 294 497 484 672 ; C 194 ; WX 600 ; N acute ; B 348 497 612 672 ; C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ; C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ; C 197 ; WX 600 ; N macron ; B 232 525 600 565 ; C 198 ; WX 600 ; N breve ; B 279 501 576 609 ; C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ; C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ; C 202 ; WX 600 ; N ring ; B 332 463 500 627 ; C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ; C 207 ; WX 600 ; N caron ; B 262 492 614 669 ; C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ; C 225 ; WX 600 ; N AE ; B 3 0 655 562 ; C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ; C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; C 234 ; WX 600 ; N OE ; B 59 0 672 562 ; C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ; C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ; C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ; C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ; C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ; C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ; C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ; C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ; C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ; C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ; C -1 ; WX 600 ; N divide ; B 136 48 573 467 ; C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ; C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ; C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ; C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ; C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ; C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ; C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ; C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ; C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ; C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ; C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ; C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ; C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ; C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ; C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ; C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ; C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ; C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ; C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ; C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ; C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ; C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ; C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ; C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ; C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ; C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ; C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ; C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ; C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ; C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ; C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ; C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ; C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ; C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ; C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ; C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ; C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ; C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ; C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ; C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ; C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ; C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ; C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ; C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ; C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ; C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ; C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ; C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ; C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ; C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ; C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ; C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ; C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ; C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ; C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ; C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ; C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ; C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ; C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ; C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ; C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ; C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ; C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ; C -1 ; WX 600 ; N racute ; B 60 0 636 672 ; C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ; C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ; C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ; C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ; C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ; C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ; C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ; C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ; C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ; C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ; C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ; C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ; C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ; C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ; C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ; C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ; C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ; C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ; C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ; C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ; C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ; C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ; C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ; C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ; C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ; C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ; C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ; C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ; C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ; C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ; C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ; C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ; C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ; C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ; C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ; C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ; C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ; C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ; C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ; C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ; C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ; C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ; C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ; C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ; C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ; C -1 ; WX 600 ; N degree ; B 214 269 576 622 ; C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ; C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ; C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ; C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ; C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ; C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ; C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ; C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ; C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ; C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ; C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ; C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ; C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ; C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ; C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ; C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ; C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ; C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ; C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ; C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ; C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ; C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ; C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ; C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ; C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ; C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ; C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ; C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ; C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Courier.afm100644 0 0 36475 11000354125 17142 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 17:27:09 1997 Comment UniqueID 43050 Comment VMusage 39754 50779 FontName Courier FullName Courier FamilyName Courier Weight Medium ItalicAngle 0 IsFixedPitch true CharacterSet ExtendedRoman FontBBox -23 -250 715 805 UnderlinePosition -100 UnderlineThickness 50 Version 003.000 Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. EncodingScheme AdobeStandardEncoding CapHeight 562 XHeight 426 Ascender 629 Descender -157 StdHW 51 StdVW 51 StartCharMetrics 315 C 32 ; WX 600 ; N space ; B 0 0 0 0 ; C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ; C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; C 49 ; WX 600 ; N one ; B 96 0 505 622 ; C 50 ; WX 600 ; N two ; B 70 0 471 622 ; C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; C 52 ; WX 600 ; N four ; B 78 0 500 622 ; C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; C 60 ; WX 600 ; N less ; B 41 42 519 472 ; C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; C 65 ; WX 600 ; N A ; B 3 0 597 562 ; C 66 ; WX 600 ; N B ; B 43 0 559 562 ; C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; C 68 ; WX 600 ; N D ; B 43 0 574 562 ; C 69 ; WX 600 ; N E ; B 53 0 550 562 ; C 70 ; WX 600 ; N F ; B 53 0 545 562 ; C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; C 72 ; WX 600 ; N H ; B 32 0 568 562 ; C 73 ; WX 600 ; N I ; B 96 0 504 562 ; C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; C 75 ; WX 600 ; N K ; B 38 0 582 562 ; C 76 ; WX 600 ; N L ; B 47 0 554 562 ; C 77 ; WX 600 ; N M ; B 4 0 596 562 ; C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; C 80 ; WX 600 ; N P ; B 79 0 558 562 ; C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; C 82 ; WX 600 ; N R ; B 38 0 588 562 ; C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; C 84 ; WX 600 ; N T ; B 38 0 563 562 ; C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; C 88 ; WX 600 ; N X ; B 23 0 577 562 ; C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; C 104 ; WX 600 ; N h ; B 18 0 582 629 ; C 105 ; WX 600 ; N i ; B 95 0 505 657 ; C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; C 107 ; WX 600 ; N k ; B 43 0 580 629 ; C 108 ; WX 600 ; N l ; B 95 0 505 629 ; C 109 ; WX 600 ; N m ; B -5 0 605 441 ; C 110 ; WX 600 ; N n ; B 26 0 575 441 ; C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; C 114 ; WX 600 ; N r ; B 60 0 559 441 ; C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; C 120 ; WX 600 ; N x ; B 20 0 580 426 ; C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; C 122 ; WX 600 ; N z ; B 99 0 502 426 ; C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ; C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ; C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; C 168 ; WX 600 ; N currency ; B 73 58 527 506 ; C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; C 174 ; WX 600 ; N fi ; B 3 0 597 629 ; C 175 ; WX 600 ; N fl ; B 3 0 597 629 ; C 177 ; WX 600 ; N endash ; B 75 231 525 285 ; C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ; C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ; C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; C 193 ; WX 600 ; N grave ; B 151 497 378 672 ; C 194 ; WX 600 ; N acute ; B 242 497 469 672 ; C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ; C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ; C 197 ; WX 600 ; N macron ; B 120 525 480 565 ; C 198 ; WX 600 ; N breve ; B 153 501 447 609 ; C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ; C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ; C 202 ; WX 600 ; N ring ; B 218 463 382 627 ; C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ; C 207 ; WX 600 ; N caron ; B 124 492 476 669 ; C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ; C 225 ; WX 600 ; N AE ; B 3 0 550 562 ; C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ; C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; C 234 ; WX 600 ; N OE ; B 7 0 567 562 ; C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ; C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ; C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ; C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ; C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ; C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ; C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ; C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ; C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ; C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ; C -1 ; WX 600 ; N divide ; B 87 48 513 467 ; C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ; C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ; C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ; C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ; C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ; C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ; C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ; C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ; C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ; C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ; C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ; C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ; C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ; C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ; C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ; C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ; C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ; C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ; C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ; C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ; C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ; C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ; C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ; C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ; C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ; C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ; C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ; C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ; C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ; C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ; C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ; C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ; C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ; C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ; C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ; C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ; C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ; C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ; C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ; C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ; C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ; C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ; C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ; C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ; C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ; C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ; C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ; C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ; C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ; C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ; C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ; C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ; C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ; C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ; C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ; C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ; C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ; C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ; C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ; C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ; C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ; C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ; C -1 ; WX 600 ; N racute ; B 60 0 559 672 ; C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ; C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ; C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ; C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ; C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ; C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ; C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ; C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ; C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ; C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ; C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ; C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ; C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ; C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ; C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ; C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ; C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ; C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ; C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ; C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ; C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ; C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ; C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ; C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ; C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ; C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ; C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ; C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ; C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ; C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ; C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ; C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ; C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ; C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ; C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ; C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ; C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ; C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ; C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ; C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ; C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ; C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ; C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ; C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ; C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ; C -1 ; WX 600 ; N degree ; B 123 269 477 622 ; C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ; C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ; C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ; C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ; C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ; C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ; C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ; C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ; C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ; C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ; C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ; C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ; C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ; C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ; C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ; C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ; C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ; C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ; C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ; C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ; C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ; C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ; C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ; C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ; C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ; C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ; C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ; C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ; C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java100644 0 0 5245 11000354125 21613 0ustar 0 0 /* * Copyright 2004 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.fonts; /** * A class to facilitate the loading of resources * * @author Paulo Soares (psoares@consiste.pt) */ public class FontsResourceAnchor { /** * Creates a FontsResourceAnchor */ public FontsResourceAnchor() { } } src/core/com/lowagie/text/pdf/fonts/Helvetica-Bold.afm100644 0 0 214640 11000354125 20324 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:43:52 1997 Comment UniqueID 43052 Comment VMusage 37169 48194 FontName Helvetica-Bold FullName Helvetica Bold FamilyName Helvetica Weight Bold ItalicAngle 0 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -170 -228 1003 962 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StdHW 118 StdVW 140 StartCharMetrics 315 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ; C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ; C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ; C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ; C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ; C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ; C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ; C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ; C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ; C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ; C 43 ; WX 584 ; N plus ; B 40 0 544 506 ; C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ; C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ; C 46 ; WX 278 ; N period ; B 64 0 214 146 ; C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ; C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ; C 49 ; WX 556 ; N one ; B 69 0 378 710 ; C 50 ; WX 556 ; N two ; B 26 0 511 710 ; C 51 ; WX 556 ; N three ; B 27 -19 516 710 ; C 52 ; WX 556 ; N four ; B 27 0 526 710 ; C 53 ; WX 556 ; N five ; B 27 -19 516 698 ; C 54 ; WX 556 ; N six ; B 31 -19 520 710 ; C 55 ; WX 556 ; N seven ; B 25 0 528 698 ; C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ; C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ; C 58 ; WX 333 ; N colon ; B 92 0 242 512 ; C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ; C 60 ; WX 584 ; N less ; B 38 -8 546 514 ; C 61 ; WX 584 ; N equal ; B 40 87 544 419 ; C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ; C 63 ; WX 611 ; N question ; B 60 0 556 727 ; C 64 ; WX 975 ; N at ; B 118 -19 856 737 ; C 65 ; WX 722 ; N A ; B 20 0 702 718 ; C 66 ; WX 722 ; N B ; B 76 0 669 718 ; C 67 ; WX 722 ; N C ; B 44 -19 684 737 ; C 68 ; WX 722 ; N D ; B 76 0 685 718 ; C 69 ; WX 667 ; N E ; B 76 0 621 718 ; C 70 ; WX 611 ; N F ; B 76 0 587 718 ; C 71 ; WX 778 ; N G ; B 44 -19 713 737 ; C 72 ; WX 722 ; N H ; B 71 0 651 718 ; C 73 ; WX 278 ; N I ; B 64 0 214 718 ; C 74 ; WX 556 ; N J ; B 22 -18 484 718 ; C 75 ; WX 722 ; N K ; B 87 0 722 718 ; C 76 ; WX 611 ; N L ; B 76 0 583 718 ; C 77 ; WX 833 ; N M ; B 69 0 765 718 ; C 78 ; WX 722 ; N N ; B 69 0 654 718 ; C 79 ; WX 778 ; N O ; B 44 -19 734 737 ; C 80 ; WX 667 ; N P ; B 76 0 627 718 ; C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ; C 82 ; WX 722 ; N R ; B 76 0 677 718 ; C 83 ; WX 667 ; N S ; B 39 -19 629 737 ; C 84 ; WX 611 ; N T ; B 14 0 598 718 ; C 85 ; WX 722 ; N U ; B 72 -19 651 718 ; C 86 ; WX 667 ; N V ; B 19 0 648 718 ; C 87 ; WX 944 ; N W ; B 16 0 929 718 ; C 88 ; WX 667 ; N X ; B 14 0 653 718 ; C 89 ; WX 667 ; N Y ; B 15 0 653 718 ; C 90 ; WX 611 ; N Z ; B 25 0 586 718 ; C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ; C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ; C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ; C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ; C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ; C 97 ; WX 556 ; N a ; B 29 -14 527 546 ; C 98 ; WX 611 ; N b ; B 61 -14 578 718 ; C 99 ; WX 556 ; N c ; B 34 -14 524 546 ; C 100 ; WX 611 ; N d ; B 34 -14 551 718 ; C 101 ; WX 556 ; N e ; B 23 -14 528 546 ; C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B 40 -217 553 546 ; C 104 ; WX 611 ; N h ; B 65 0 546 718 ; C 105 ; WX 278 ; N i ; B 69 0 209 725 ; C 106 ; WX 278 ; N j ; B 3 -214 209 725 ; C 107 ; WX 556 ; N k ; B 69 0 562 718 ; C 108 ; WX 278 ; N l ; B 69 0 209 718 ; C 109 ; WX 889 ; N m ; B 64 0 826 546 ; C 110 ; WX 611 ; N n ; B 65 0 546 546 ; C 111 ; WX 611 ; N o ; B 34 -14 578 546 ; C 112 ; WX 611 ; N p ; B 62 -207 578 546 ; C 113 ; WX 611 ; N q ; B 34 -207 552 546 ; C 114 ; WX 389 ; N r ; B 64 0 373 546 ; C 115 ; WX 556 ; N s ; B 30 -14 519 546 ; C 116 ; WX 333 ; N t ; B 10 -6 309 676 ; C 117 ; WX 611 ; N u ; B 66 -14 545 532 ; C 118 ; WX 556 ; N v ; B 13 0 543 532 ; C 119 ; WX 778 ; N w ; B 10 0 769 532 ; C 120 ; WX 556 ; N x ; B 15 0 541 532 ; C 121 ; WX 556 ; N y ; B 10 -214 539 532 ; C 122 ; WX 500 ; N z ; B 20 0 480 532 ; C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ; C 124 ; WX 280 ; N bar ; B 84 -225 196 775 ; C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ; C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ; C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ; C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ; C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ; C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ; C 165 ; WX 556 ; N yen ; B -9 0 565 698 ; C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ; C 167 ; WX 556 ; N section ; B 34 -184 522 727 ; C 168 ; WX 556 ; N currency ; B -3 76 559 636 ; C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ; C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ; C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ; C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ; C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ; C 174 ; WX 611 ; N fi ; B 10 0 542 727 ; C 175 ; WX 611 ; N fl ; B 10 0 542 727 ; C 177 ; WX 556 ; N endash ; B 0 227 556 333 ; C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ; C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ; C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ; C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ; C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ; C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ; C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ; C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ; C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ; C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ; C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ; C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ; C 193 ; WX 333 ; N grave ; B -23 604 225 750 ; C 194 ; WX 333 ; N acute ; B 108 604 356 750 ; C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ; C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ; C 197 ; WX 333 ; N macron ; B -6 604 339 678 ; C 198 ; WX 333 ; N breve ; B -2 604 335 750 ; C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ; C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ; C 202 ; WX 333 ; N ring ; B 59 568 275 776 ; C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ; C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ; C 207 ; WX 333 ; N caron ; B -10 604 343 750 ; C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ; C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ; C 227 ; WX 370 ; N ordfeminine ; B 22 401 347 737 ; C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ; C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ; C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ; C 235 ; WX 365 ; N ordmasculine ; B 6 401 360 737 ; C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ; C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ; C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ; C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ; C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ; C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ; C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ; C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ; C -1 ; WX 556 ; N abreve ; B 29 -14 527 750 ; C -1 ; WX 611 ; N uhungarumlaut ; B 66 -14 625 750 ; C -1 ; WX 556 ; N ecaron ; B 23 -14 528 750 ; C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ; C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ; C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ; C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ; C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ; C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ; C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ; C -1 ; WX 556 ; N scommaaccent ; B 30 -228 519 546 ; C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ; C -1 ; WX 722 ; N Uring ; B 72 -19 651 962 ; C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ; C -1 ; WX 556 ; N aogonek ; B 29 -224 545 546 ; C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ; C -1 ; WX 611 ; N uogonek ; B 66 -228 545 532 ; C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ; C -1 ; WX 722 ; N Dcroat ; B -5 0 685 718 ; C -1 ; WX 250 ; N commaaccent ; B 64 -228 199 -50 ; C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ; C -1 ; WX 667 ; N Emacron ; B 76 0 621 864 ; C -1 ; WX 556 ; N ccaron ; B 34 -14 524 750 ; C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ; C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 654 718 ; C -1 ; WX 278 ; N lacute ; B 69 0 329 936 ; C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ; C -1 ; WX 611 ; N Tcommaaccent ; B 14 -228 598 718 ; C -1 ; WX 722 ; N Cacute ; B 44 -19 684 936 ; C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ; C -1 ; WX 667 ; N Edotaccent ; B 76 0 621 915 ; C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ; C -1 ; WX 556 ; N scedilla ; B 30 -228 519 546 ; C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ; C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; C -1 ; WX 722 ; N Rcaron ; B 76 0 677 936 ; C -1 ; WX 778 ; N Gcommaaccent ; B 44 -228 713 737 ; C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ; C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ; C -1 ; WX 722 ; N Amacron ; B 20 0 702 864 ; C -1 ; WX 389 ; N rcaron ; B 18 0 373 750 ; C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ; C -1 ; WX 611 ; N Zdotaccent ; B 25 0 586 915 ; C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ; C -1 ; WX 778 ; N Omacron ; B 44 -19 734 864 ; C -1 ; WX 722 ; N Racute ; B 76 0 677 936 ; C -1 ; WX 667 ; N Sacute ; B 39 -19 629 936 ; C -1 ; WX 743 ; N dcaron ; B 34 -14 750 718 ; C -1 ; WX 722 ; N Umacron ; B 72 -19 651 864 ; C -1 ; WX 611 ; N uring ; B 66 -14 545 776 ; C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ; C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ; C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; C -1 ; WX 722 ; N Abreve ; B 20 0 702 936 ; C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ; C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ; C -1 ; WX 611 ; N Tcaron ; B 14 0 598 936 ; C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ; C -1 ; WX 722 ; N Nacute ; B 69 0 654 936 ; C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ; C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ; C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ; C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ; C -1 ; WX 556 ; N cacute ; B 34 -14 524 750 ; C -1 ; WX 611 ; N nacute ; B 65 0 546 750 ; C -1 ; WX 611 ; N umacron ; B 66 -14 545 678 ; C -1 ; WX 722 ; N Ncaron ; B 69 0 654 936 ; C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ; C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ; C -1 ; WX 280 ; N brokenbar ; B 84 -150 196 700 ; C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ; C -1 ; WX 778 ; N Gbreve ; B 44 -19 713 936 ; C -1 ; WX 278 ; N Idotaccent ; B 64 0 214 915 ; C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ; C -1 ; WX 389 ; N racute ; B 64 0 384 750 ; C -1 ; WX 611 ; N omacron ; B 34 -14 578 678 ; C -1 ; WX 611 ; N Zacute ; B 25 0 586 936 ; C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ; C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ; C -1 ; WX 278 ; N lcommaaccent ; B 69 -228 213 718 ; C -1 ; WX 389 ; N tcaron ; B 10 -6 421 878 ; C -1 ; WX 556 ; N eogonek ; B 23 -228 528 546 ; C -1 ; WX 722 ; N Uogonek ; B 72 -228 651 718 ; C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ; C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ; C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ; C -1 ; WX 500 ; N zacute ; B 20 0 480 750 ; C -1 ; WX 278 ; N iogonek ; B 16 -224 249 725 ; C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ; C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ; C -1 ; WX 556 ; N amacron ; B 29 -14 527 678 ; C -1 ; WX 556 ; N sacute ; B 30 -14 519 750 ; C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ; C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ; C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ; C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ; C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ; C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ; C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ; C -1 ; WX 611 ; N ohungarumlaut ; B 34 -14 625 750 ; C -1 ; WX 667 ; N Eogonek ; B 76 -224 639 718 ; C -1 ; WX 611 ; N dcroat ; B 34 -14 650 718 ; C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ; C -1 ; WX 667 ; N Scedilla ; B 39 -228 629 737 ; C -1 ; WX 400 ; N lcaron ; B 69 0 408 718 ; C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 722 718 ; C -1 ; WX 611 ; N Lacute ; B 76 0 583 936 ; C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ; C -1 ; WX 556 ; N edotaccent ; B 23 -14 528 729 ; C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ; C -1 ; WX 278 ; N Imacron ; B -33 0 312 864 ; C -1 ; WX 611 ; N Lcaron ; B 76 0 583 718 ; C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ; C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ; C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 72 -19 681 936 ; C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ; C -1 ; WX 556 ; N emacron ; B 23 -14 528 678 ; C -1 ; WX 611 ; N gbreve ; B 40 -217 553 750 ; C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ; C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ; C -1 ; WX 667 ; N Scommaaccent ; B 39 -228 629 737 ; C -1 ; WX 778 ; N Ohungarumlaut ; B 44 -19 734 936 ; C -1 ; WX 400 ; N degree ; B 57 426 343 712 ; C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ; C -1 ; WX 722 ; N Ccaron ; B 44 -19 684 936 ; C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ; C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; C -1 ; WX 722 ; N Dcaron ; B 76 0 685 936 ; C -1 ; WX 389 ; N rcommaaccent ; B 64 -228 373 546 ; C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ; C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ; C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 677 718 ; C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 583 718 ; C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ; C -1 ; WX 722 ; N Aogonek ; B 20 -224 742 718 ; C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ; C -1 ; WX 500 ; N zdotaccent ; B 20 0 480 729 ; C -1 ; WX 667 ; N Ecaron ; B 76 0 621 936 ; C -1 ; WX 278 ; N Iogonek ; B -11 -228 222 718 ; C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 562 718 ; C -1 ; WX 584 ; N minus ; B 40 197 544 309 ; C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ; C -1 ; WX 611 ; N ncaron ; B 65 0 546 750 ; C -1 ; WX 333 ; N tcommaaccent ; B 10 -228 309 676 ; C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ; C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ; C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ; C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; C -1 ; WX 611 ; N gcommaaccent ; B 40 -217 553 850 ; C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ; C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ; C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 546 546 ; C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ; C -1 ; WX 278 ; N imacron ; B -8 0 285 678 ; C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2481 KPX A C -40 KPX A Cacute -40 KPX A Ccaron -40 KPX A Ccedilla -40 KPX A G -50 KPX A Gbreve -50 KPX A Gcommaaccent -50 KPX A O -40 KPX A Oacute -40 KPX A Ocircumflex -40 KPX A Odieresis -40 KPX A Ograve -40 KPX A Ohungarumlaut -40 KPX A Omacron -40 KPX A Oslash -40 KPX A Otilde -40 KPX A Q -40 KPX A T -90 KPX A Tcaron -90 KPX A Tcommaaccent -90 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -80 KPX A W -60 KPX A Y -110 KPX A Yacute -110 KPX A Ydieresis -110 KPX A u -30 KPX A uacute -30 KPX A ucircumflex -30 KPX A udieresis -30 KPX A ugrave -30 KPX A uhungarumlaut -30 KPX A umacron -30 KPX A uogonek -30 KPX A uring -30 KPX A v -40 KPX A w -30 KPX A y -30 KPX A yacute -30 KPX A ydieresis -30 KPX Aacute C -40 KPX Aacute Cacute -40 KPX Aacute Ccaron -40 KPX Aacute Ccedilla -40 KPX Aacute G -50 KPX Aacute Gbreve -50 KPX Aacute Gcommaaccent -50 KPX Aacute O -40 KPX Aacute Oacute -40 KPX Aacute Ocircumflex -40 KPX Aacute Odieresis -40 KPX Aacute Ograve -40 KPX Aacute Ohungarumlaut -40 KPX Aacute Omacron -40 KPX Aacute Oslash -40 KPX Aacute Otilde -40 KPX Aacute Q -40 KPX Aacute T -90 KPX Aacute Tcaron -90 KPX Aacute Tcommaaccent -90 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -80 KPX Aacute W -60 KPX Aacute Y -110 KPX Aacute Yacute -110 KPX Aacute Ydieresis -110 KPX Aacute u -30 KPX Aacute uacute -30 KPX Aacute ucircumflex -30 KPX Aacute udieresis -30 KPX Aacute ugrave -30 KPX Aacute uhungarumlaut -30 KPX Aacute umacron -30 KPX Aacute uogonek -30 KPX Aacute uring -30 KPX Aacute v -40 KPX Aacute w -30 KPX Aacute y -30 KPX Aacute yacute -30 KPX Aacute ydieresis -30 KPX Abreve C -40 KPX Abreve Cacute -40 KPX Abreve Ccaron -40 KPX Abreve Ccedilla -40 KPX Abreve G -50 KPX Abreve Gbreve -50 KPX Abreve Gcommaaccent -50 KPX Abreve O -40 KPX Abreve Oacute -40 KPX Abreve Ocircumflex -40 KPX Abreve Odieresis -40 KPX Abreve Ograve -40 KPX Abreve Ohungarumlaut -40 KPX Abreve Omacron -40 KPX Abreve Oslash -40 KPX Abreve Otilde -40 KPX Abreve Q -40 KPX Abreve T -90 KPX Abreve Tcaron -90 KPX Abreve Tcommaaccent -90 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -80 KPX Abreve W -60 KPX Abreve Y -110 KPX Abreve Yacute -110 KPX Abreve Ydieresis -110 KPX Abreve u -30 KPX Abreve uacute -30 KPX Abreve ucircumflex -30 KPX Abreve udieresis -30 KPX Abreve ugrave -30 KPX Abreve uhungarumlaut -30 KPX Abreve umacron -30 KPX Abreve uogonek -30 KPX Abreve uring -30 KPX Abreve v -40 KPX Abreve w -30 KPX Abreve y -30 KPX Abreve yacute -30 KPX Abreve ydieresis -30 KPX Acircumflex C -40 KPX Acircumflex Cacute -40 KPX Acircumflex Ccaron -40 KPX Acircumflex Ccedilla -40 KPX Acircumflex G -50 KPX Acircumflex Gbreve -50 KPX Acircumflex Gcommaaccent -50 KPX Acircumflex O -40 KPX Acircumflex Oacute -40 KPX Acircumflex Ocircumflex -40 KPX Acircumflex Odieresis -40 KPX Acircumflex Ograve -40 KPX Acircumflex Ohungarumlaut -40 KPX Acircumflex Omacron -40 KPX Acircumflex Oslash -40 KPX Acircumflex Otilde -40 KPX Acircumflex Q -40 KPX Acircumflex T -90 KPX Acircumflex Tcaron -90 KPX Acircumflex Tcommaaccent -90 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -80 KPX Acircumflex W -60 KPX Acircumflex Y -110 KPX Acircumflex Yacute -110 KPX Acircumflex Ydieresis -110 KPX Acircumflex u -30 KPX Acircumflex uacute -30 KPX Acircumflex ucircumflex -30 KPX Acircumflex udieresis -30 KPX Acircumflex ugrave -30 KPX Acircumflex uhungarumlaut -30 KPX Acircumflex umacron -30 KPX Acircumflex uogonek -30 KPX Acircumflex uring -30 KPX Acircumflex v -40 KPX Acircumflex w -30 KPX Acircumflex y -30 KPX Acircumflex yacute -30 KPX Acircumflex ydieresis -30 KPX Adieresis C -40 KPX Adieresis Cacute -40 KPX Adieresis Ccaron -40 KPX Adieresis Ccedilla -40 KPX Adieresis G -50 KPX Adieresis Gbreve -50 KPX Adieresis Gcommaaccent -50 KPX Adieresis O -40 KPX Adieresis Oacute -40 KPX Adieresis Ocircumflex -40 KPX Adieresis Odieresis -40 KPX Adieresis Ograve -40 KPX Adieresis Ohungarumlaut -40 KPX Adieresis Omacron -40 KPX Adieresis Oslash -40 KPX Adieresis Otilde -40 KPX Adieresis Q -40 KPX Adieresis T -90 KPX Adieresis Tcaron -90 KPX Adieresis Tcommaaccent -90 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -80 KPX Adieresis W -60 KPX Adieresis Y -110 KPX Adieresis Yacute -110 KPX Adieresis Ydieresis -110 KPX Adieresis u -30 KPX Adieresis uacute -30 KPX Adieresis ucircumflex -30 KPX Adieresis udieresis -30 KPX Adieresis ugrave -30 KPX Adieresis uhungarumlaut -30 KPX Adieresis umacron -30 KPX Adieresis uogonek -30 KPX Adieresis uring -30 KPX Adieresis v -40 KPX Adieresis w -30 KPX Adieresis y -30 KPX Adieresis yacute -30 KPX Adieresis ydieresis -30 KPX Agrave C -40 KPX Agrave Cacute -40 KPX Agrave Ccaron -40 KPX Agrave Ccedilla -40 KPX Agrave G -50 KPX Agrave Gbreve -50 KPX Agrave Gcommaaccent -50 KPX Agrave O -40 KPX Agrave Oacute -40 KPX Agrave Ocircumflex -40 KPX Agrave Odieresis -40 KPX Agrave Ograve -40 KPX Agrave Ohungarumlaut -40 KPX Agrave Omacron -40 KPX Agrave Oslash -40 KPX Agrave Otilde -40 KPX Agrave Q -40 KPX Agrave T -90 KPX Agrave Tcaron -90 KPX Agrave Tcommaaccent -90 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -80 KPX Agrave W -60 KPX Agrave Y -110 KPX Agrave Yacute -110 KPX Agrave Ydieresis -110 KPX Agrave u -30 KPX Agrave uacute -30 KPX Agrave ucircumflex -30 KPX Agrave udieresis -30 KPX Agrave ugrave -30 KPX Agrave uhungarumlaut -30 KPX Agrave umacron -30 KPX Agrave uogonek -30 KPX Agrave uring -30 KPX Agrave v -40 KPX Agrave w -30 KPX Agrave y -30 KPX Agrave yacute -30 KPX Agrave ydieresis -30 KPX Amacron C -40 KPX Amacron Cacute -40 KPX Amacron Ccaron -40 KPX Amacron Ccedilla -40 KPX Amacron G -50 KPX Amacron Gbreve -50 KPX Amacron Gcommaaccent -50 KPX Amacron O -40 KPX Amacron Oacute -40 KPX Amacron Ocircumflex -40 KPX Amacron Odieresis -40 KPX Amacron Ograve -40 KPX Amacron Ohungarumlaut -40 KPX Amacron Omacron -40 KPX Amacron Oslash -40 KPX Amacron Otilde -40 KPX Amacron Q -40 KPX Amacron T -90 KPX Amacron Tcaron -90 KPX Amacron Tcommaaccent -90 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -80 KPX Amacron W -60 KPX Amacron Y -110 KPX Amacron Yacute -110 KPX Amacron Ydieresis -110 KPX Amacron u -30 KPX Amacron uacute -30 KPX Amacron ucircumflex -30 KPX Amacron udieresis -30 KPX Amacron ugrave -30 KPX Amacron uhungarumlaut -30 KPX Amacron umacron -30 KPX Amacron uogonek -30 KPX Amacron uring -30 KPX Amacron v -40 KPX Amacron w -30 KPX Amacron y -30 KPX Amacron yacute -30 KPX Amacron ydieresis -30 KPX Aogonek C -40 KPX Aogonek Cacute -40 KPX Aogonek Ccaron -40 KPX Aogonek Ccedilla -40 KPX Aogonek G -50 KPX Aogonek Gbreve -50 KPX Aogonek Gcommaaccent -50 KPX Aogonek O -40 KPX Aogonek Oacute -40 KPX Aogonek Ocircumflex -40 KPX Aogonek Odieresis -40 KPX Aogonek Ograve -40 KPX Aogonek Ohungarumlaut -40 KPX Aogonek Omacron -40 KPX Aogonek Oslash -40 KPX Aogonek Otilde -40 KPX Aogonek Q -40 KPX Aogonek T -90 KPX Aogonek Tcaron -90 KPX Aogonek Tcommaaccent -90 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -80 KPX Aogonek W -60 KPX Aogonek Y -110 KPX Aogonek Yacute -110 KPX Aogonek Ydieresis -110 KPX Aogonek u -30 KPX Aogonek uacute -30 KPX Aogonek ucircumflex -30 KPX Aogonek udieresis -30 KPX Aogonek ugrave -30 KPX Aogonek uhungarumlaut -30 KPX Aogonek umacron -30 KPX Aogonek uogonek -30 KPX Aogonek uring -30 KPX Aogonek v -40 KPX Aogonek w -30 KPX Aogonek y -30 KPX Aogonek yacute -30 KPX Aogonek ydieresis -30 KPX Aring C -40 KPX Aring Cacute -40 KPX Aring Ccaron -40 KPX Aring Ccedilla -40 KPX Aring G -50 KPX Aring Gbreve -50 KPX Aring Gcommaaccent -50 KPX Aring O -40 KPX Aring Oacute -40 KPX Aring Ocircumflex -40 KPX Aring Odieresis -40 KPX Aring Ograve -40 KPX Aring Ohungarumlaut -40 KPX Aring Omacron -40 KPX Aring Oslash -40 KPX Aring Otilde -40 KPX Aring Q -40 KPX Aring T -90 KPX Aring Tcaron -90 KPX Aring Tcommaaccent -90 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -80 KPX Aring W -60 KPX Aring Y -110 KPX Aring Yacute -110 KPX Aring Ydieresis -110 KPX Aring u -30 KPX Aring uacute -30 KPX Aring ucircumflex -30 KPX Aring udieresis -30 KPX Aring ugrave -30 KPX Aring uhungarumlaut -30 KPX Aring umacron -30 KPX Aring uogonek -30 KPX Aring uring -30 KPX Aring v -40 KPX Aring w -30 KPX Aring y -30 KPX Aring yacute -30 KPX Aring ydieresis -30 KPX Atilde C -40 KPX Atilde Cacute -40 KPX Atilde Ccaron -40 KPX Atilde Ccedilla -40 KPX Atilde G -50 KPX Atilde Gbreve -50 KPX Atilde Gcommaaccent -50 KPX Atilde O -40 KPX Atilde Oacute -40 KPX Atilde Ocircumflex -40 KPX Atilde Odieresis -40 KPX Atilde Ograve -40 KPX Atilde Ohungarumlaut -40 KPX Atilde Omacron -40 KPX Atilde Oslash -40 KPX Atilde Otilde -40 KPX Atilde Q -40 KPX Atilde T -90 KPX Atilde Tcaron -90 KPX Atilde Tcommaaccent -90 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -80 KPX Atilde W -60 KPX Atilde Y -110 KPX Atilde Yacute -110 KPX Atilde Ydieresis -110 KPX Atilde u -30 KPX Atilde uacute -30 KPX Atilde ucircumflex -30 KPX Atilde udieresis -30 KPX Atilde ugrave -30 KPX Atilde uhungarumlaut -30 KPX Atilde umacron -30 KPX Atilde uogonek -30 KPX Atilde uring -30 KPX Atilde v -40 KPX Atilde w -30 KPX Atilde y -30 KPX Atilde yacute -30 KPX Atilde ydieresis -30 KPX B A -30 KPX B Aacute -30 KPX B Abreve -30 KPX B Acircumflex -30 KPX B Adieresis -30 KPX B Agrave -30 KPX B Amacron -30 KPX B Aogonek -30 KPX B Aring -30 KPX B Atilde -30 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -40 KPX D Aacute -40 KPX D Abreve -40 KPX D Acircumflex -40 KPX D Adieresis -40 KPX D Agrave -40 KPX D Amacron -40 KPX D Aogonek -40 KPX D Aring -40 KPX D Atilde -40 KPX D V -40 KPX D W -40 KPX D Y -70 KPX D Yacute -70 KPX D Ydieresis -70 KPX D comma -30 KPX D period -30 KPX Dcaron A -40 KPX Dcaron Aacute -40 KPX Dcaron Abreve -40 KPX Dcaron Acircumflex -40 KPX Dcaron Adieresis -40 KPX Dcaron Agrave -40 KPX Dcaron Amacron -40 KPX Dcaron Aogonek -40 KPX Dcaron Aring -40 KPX Dcaron Atilde -40 KPX Dcaron V -40 KPX Dcaron W -40 KPX Dcaron Y -70 KPX Dcaron Yacute -70 KPX Dcaron Ydieresis -70 KPX Dcaron comma -30 KPX Dcaron period -30 KPX Dcroat A -40 KPX Dcroat Aacute -40 KPX Dcroat Abreve -40 KPX Dcroat Acircumflex -40 KPX Dcroat Adieresis -40 KPX Dcroat Agrave -40 KPX Dcroat Amacron -40 KPX Dcroat Aogonek -40 KPX Dcroat Aring -40 KPX Dcroat Atilde -40 KPX Dcroat V -40 KPX Dcroat W -40 KPX Dcroat Y -70 KPX Dcroat Yacute -70 KPX Dcroat Ydieresis -70 KPX Dcroat comma -30 KPX Dcroat period -30 KPX F A -80 KPX F Aacute -80 KPX F Abreve -80 KPX F Acircumflex -80 KPX F Adieresis -80 KPX F Agrave -80 KPX F Amacron -80 KPX F Aogonek -80 KPX F Aring -80 KPX F Atilde -80 KPX F a -20 KPX F aacute -20 KPX F abreve -20 KPX F acircumflex -20 KPX F adieresis -20 KPX F agrave -20 KPX F amacron -20 KPX F aogonek -20 KPX F aring -20 KPX F atilde -20 KPX F comma -100 KPX F period -100 KPX J A -20 KPX J Aacute -20 KPX J Abreve -20 KPX J Acircumflex -20 KPX J Adieresis -20 KPX J Agrave -20 KPX J Amacron -20 KPX J Aogonek -20 KPX J Aring -20 KPX J Atilde -20 KPX J comma -20 KPX J period -20 KPX J u -20 KPX J uacute -20 KPX J ucircumflex -20 KPX J udieresis -20 KPX J ugrave -20 KPX J uhungarumlaut -20 KPX J umacron -20 KPX J uogonek -20 KPX J uring -20 KPX K O -30 KPX K Oacute -30 KPX K Ocircumflex -30 KPX K Odieresis -30 KPX K Ograve -30 KPX K Ohungarumlaut -30 KPX K Omacron -30 KPX K Oslash -30 KPX K Otilde -30 KPX K e -15 KPX K eacute -15 KPX K ecaron -15 KPX K ecircumflex -15 KPX K edieresis -15 KPX K edotaccent -15 KPX K egrave -15 KPX K emacron -15 KPX K eogonek -15 KPX K o -35 KPX K oacute -35 KPX K ocircumflex -35 KPX K odieresis -35 KPX K ograve -35 KPX K ohungarumlaut -35 KPX K omacron -35 KPX K oslash -35 KPX K otilde -35 KPX K u -30 KPX K uacute -30 KPX K ucircumflex -30 KPX K udieresis -30 KPX K ugrave -30 KPX K uhungarumlaut -30 KPX K umacron -30 KPX K uogonek -30 KPX K uring -30 KPX K y -40 KPX K yacute -40 KPX K ydieresis -40 KPX Kcommaaccent O -30 KPX Kcommaaccent Oacute -30 KPX Kcommaaccent Ocircumflex -30 KPX Kcommaaccent Odieresis -30 KPX Kcommaaccent Ograve -30 KPX Kcommaaccent Ohungarumlaut -30 KPX Kcommaaccent Omacron -30 KPX Kcommaaccent Oslash -30 KPX Kcommaaccent Otilde -30 KPX Kcommaaccent e -15 KPX Kcommaaccent eacute -15 KPX Kcommaaccent ecaron -15 KPX Kcommaaccent ecircumflex -15 KPX Kcommaaccent edieresis -15 KPX Kcommaaccent edotaccent -15 KPX Kcommaaccent egrave -15 KPX Kcommaaccent emacron -15 KPX Kcommaaccent eogonek -15 KPX Kcommaaccent o -35 KPX Kcommaaccent oacute -35 KPX Kcommaaccent ocircumflex -35 KPX Kcommaaccent odieresis -35 KPX Kcommaaccent ograve -35 KPX Kcommaaccent ohungarumlaut -35 KPX Kcommaaccent omacron -35 KPX Kcommaaccent oslash -35 KPX Kcommaaccent otilde -35 KPX Kcommaaccent u -30 KPX Kcommaaccent uacute -30 KPX Kcommaaccent ucircumflex -30 KPX Kcommaaccent udieresis -30 KPX Kcommaaccent ugrave -30 KPX Kcommaaccent uhungarumlaut -30 KPX Kcommaaccent umacron -30 KPX Kcommaaccent uogonek -30 KPX Kcommaaccent uring -30 KPX Kcommaaccent y -40 KPX Kcommaaccent yacute -40 KPX Kcommaaccent ydieresis -40 KPX L T -90 KPX L Tcaron -90 KPX L Tcommaaccent -90 KPX L V -110 KPX L W -80 KPX L Y -120 KPX L Yacute -120 KPX L Ydieresis -120 KPX L quotedblright -140 KPX L quoteright -140 KPX L y -30 KPX L yacute -30 KPX L ydieresis -30 KPX Lacute T -90 KPX Lacute Tcaron -90 KPX Lacute Tcommaaccent -90 KPX Lacute V -110 KPX Lacute W -80 KPX Lacute Y -120 KPX Lacute Yacute -120 KPX Lacute Ydieresis -120 KPX Lacute quotedblright -140 KPX Lacute quoteright -140 KPX Lacute y -30 KPX Lacute yacute -30 KPX Lacute ydieresis -30 KPX Lcommaaccent T -90 KPX Lcommaaccent Tcaron -90 KPX Lcommaaccent Tcommaaccent -90 KPX Lcommaaccent V -110 KPX Lcommaaccent W -80 KPX Lcommaaccent Y -120 KPX Lcommaaccent Yacute -120 KPX Lcommaaccent Ydieresis -120 KPX Lcommaaccent quotedblright -140 KPX Lcommaaccent quoteright -140 KPX Lcommaaccent y -30 KPX Lcommaaccent yacute -30 KPX Lcommaaccent ydieresis -30 KPX Lslash T -90 KPX Lslash Tcaron -90 KPX Lslash Tcommaaccent -90 KPX Lslash V -110 KPX Lslash W -80 KPX Lslash Y -120 KPX Lslash Yacute -120 KPX Lslash Ydieresis -120 KPX Lslash quotedblright -140 KPX Lslash quoteright -140 KPX Lslash y -30 KPX Lslash yacute -30 KPX Lslash ydieresis -30 KPX O A -50 KPX O Aacute -50 KPX O Abreve -50 KPX O Acircumflex -50 KPX O Adieresis -50 KPX O Agrave -50 KPX O Amacron -50 KPX O Aogonek -50 KPX O Aring -50 KPX O Atilde -50 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -50 KPX O X -50 KPX O Y -70 KPX O Yacute -70 KPX O Ydieresis -70 KPX O comma -40 KPX O period -40 KPX Oacute A -50 KPX Oacute Aacute -50 KPX Oacute Abreve -50 KPX Oacute Acircumflex -50 KPX Oacute Adieresis -50 KPX Oacute Agrave -50 KPX Oacute Amacron -50 KPX Oacute Aogonek -50 KPX Oacute Aring -50 KPX Oacute Atilde -50 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -50 KPX Oacute X -50 KPX Oacute Y -70 KPX Oacute Yacute -70 KPX Oacute Ydieresis -70 KPX Oacute comma -40 KPX Oacute period -40 KPX Ocircumflex A -50 KPX Ocircumflex Aacute -50 KPX Ocircumflex Abreve -50 KPX Ocircumflex Acircumflex -50 KPX Ocircumflex Adieresis -50 KPX Ocircumflex Agrave -50 KPX Ocircumflex Amacron -50 KPX Ocircumflex Aogonek -50 KPX Ocircumflex Aring -50 KPX Ocircumflex Atilde -50 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -50 KPX Ocircumflex X -50 KPX Ocircumflex Y -70 KPX Ocircumflex Yacute -70 KPX Ocircumflex Ydieresis -70 KPX Ocircumflex comma -40 KPX Ocircumflex period -40 KPX Odieresis A -50 KPX Odieresis Aacute -50 KPX Odieresis Abreve -50 KPX Odieresis Acircumflex -50 KPX Odieresis Adieresis -50 KPX Odieresis Agrave -50 KPX Odieresis Amacron -50 KPX Odieresis Aogonek -50 KPX Odieresis Aring -50 KPX Odieresis Atilde -50 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -50 KPX Odieresis X -50 KPX Odieresis Y -70 KPX Odieresis Yacute -70 KPX Odieresis Ydieresis -70 KPX Odieresis comma -40 KPX Odieresis period -40 KPX Ograve A -50 KPX Ograve Aacute -50 KPX Ograve Abreve -50 KPX Ograve Acircumflex -50 KPX Ograve Adieresis -50 KPX Ograve Agrave -50 KPX Ograve Amacron -50 KPX Ograve Aogonek -50 KPX Ograve Aring -50 KPX Ograve Atilde -50 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -50 KPX Ograve X -50 KPX Ograve Y -70 KPX Ograve Yacute -70 KPX Ograve Ydieresis -70 KPX Ograve comma -40 KPX Ograve period -40 KPX Ohungarumlaut A -50 KPX Ohungarumlaut Aacute -50 KPX Ohungarumlaut Abreve -50 KPX Ohungarumlaut Acircumflex -50 KPX Ohungarumlaut Adieresis -50 KPX Ohungarumlaut Agrave -50 KPX Ohungarumlaut Amacron -50 KPX Ohungarumlaut Aogonek -50 KPX Ohungarumlaut Aring -50 KPX Ohungarumlaut Atilde -50 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -50 KPX Ohungarumlaut X -50 KPX Ohungarumlaut Y -70 KPX Ohungarumlaut Yacute -70 KPX Ohungarumlaut Ydieresis -70 KPX Ohungarumlaut comma -40 KPX Ohungarumlaut period -40 KPX Omacron A -50 KPX Omacron Aacute -50 KPX Omacron Abreve -50 KPX Omacron Acircumflex -50 KPX Omacron Adieresis -50 KPX Omacron Agrave -50 KPX Omacron Amacron -50 KPX Omacron Aogonek -50 KPX Omacron Aring -50 KPX Omacron Atilde -50 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -50 KPX Omacron X -50 KPX Omacron Y -70 KPX Omacron Yacute -70 KPX Omacron Ydieresis -70 KPX Omacron comma -40 KPX Omacron period -40 KPX Oslash A -50 KPX Oslash Aacute -50 KPX Oslash Abreve -50 KPX Oslash Acircumflex -50 KPX Oslash Adieresis -50 KPX Oslash Agrave -50 KPX Oslash Amacron -50 KPX Oslash Aogonek -50 KPX Oslash Aring -50 KPX Oslash Atilde -50 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -50 KPX Oslash X -50 KPX Oslash Y -70 KPX Oslash Yacute -70 KPX Oslash Ydieresis -70 KPX Oslash comma -40 KPX Oslash period -40 KPX Otilde A -50 KPX Otilde Aacute -50 KPX Otilde Abreve -50 KPX Otilde Acircumflex -50 KPX Otilde Adieresis -50 KPX Otilde Agrave -50 KPX Otilde Amacron -50 KPX Otilde Aogonek -50 KPX Otilde Aring -50 KPX Otilde Atilde -50 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -50 KPX Otilde X -50 KPX Otilde Y -70 KPX Otilde Yacute -70 KPX Otilde Ydieresis -70 KPX Otilde comma -40 KPX Otilde period -40 KPX P A -100 KPX P Aacute -100 KPX P Abreve -100 KPX P Acircumflex -100 KPX P Adieresis -100 KPX P Agrave -100 KPX P Amacron -100 KPX P Aogonek -100 KPX P Aring -100 KPX P Atilde -100 KPX P a -30 KPX P aacute -30 KPX P abreve -30 KPX P acircumflex -30 KPX P adieresis -30 KPX P agrave -30 KPX P amacron -30 KPX P aogonek -30 KPX P aring -30 KPX P atilde -30 KPX P comma -120 KPX P e -30 KPX P eacute -30 KPX P ecaron -30 KPX P ecircumflex -30 KPX P edieresis -30 KPX P edotaccent -30 KPX P egrave -30 KPX P emacron -30 KPX P eogonek -30 KPX P o -40 KPX P oacute -40 KPX P ocircumflex -40 KPX P odieresis -40 KPX P ograve -40 KPX P ohungarumlaut -40 KPX P omacron -40 KPX P oslash -40 KPX P otilde -40 KPX P period -120 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX Q comma 20 KPX Q period 20 KPX R O -20 KPX R Oacute -20 KPX R Ocircumflex -20 KPX R Odieresis -20 KPX R Ograve -20 KPX R Ohungarumlaut -20 KPX R Omacron -20 KPX R Oslash -20 KPX R Otilde -20 KPX R T -20 KPX R Tcaron -20 KPX R Tcommaaccent -20 KPX R U -20 KPX R Uacute -20 KPX R Ucircumflex -20 KPX R Udieresis -20 KPX R Ugrave -20 KPX R Uhungarumlaut -20 KPX R Umacron -20 KPX R Uogonek -20 KPX R Uring -20 KPX R V -50 KPX R W -40 KPX R Y -50 KPX R Yacute -50 KPX R Ydieresis -50 KPX Racute O -20 KPX Racute Oacute -20 KPX Racute Ocircumflex -20 KPX Racute Odieresis -20 KPX Racute Ograve -20 KPX Racute Ohungarumlaut -20 KPX Racute Omacron -20 KPX Racute Oslash -20 KPX Racute Otilde -20 KPX Racute T -20 KPX Racute Tcaron -20 KPX Racute Tcommaaccent -20 KPX Racute U -20 KPX Racute Uacute -20 KPX Racute Ucircumflex -20 KPX Racute Udieresis -20 KPX Racute Ugrave -20 KPX Racute Uhungarumlaut -20 KPX Racute Umacron -20 KPX Racute Uogonek -20 KPX Racute Uring -20 KPX Racute V -50 KPX Racute W -40 KPX Racute Y -50 KPX Racute Yacute -50 KPX Racute Ydieresis -50 KPX Rcaron O -20 KPX Rcaron Oacute -20 KPX Rcaron Ocircumflex -20 KPX Rcaron Odieresis -20 KPX Rcaron Ograve -20 KPX Rcaron Ohungarumlaut -20 KPX Rcaron Omacron -20 KPX Rcaron Oslash -20 KPX Rcaron Otilde -20 KPX Rcaron T -20 KPX Rcaron Tcaron -20 KPX Rcaron Tcommaaccent -20 KPX Rcaron U -20 KPX Rcaron Uacute -20 KPX Rcaron Ucircumflex -20 KPX Rcaron Udieresis -20 KPX Rcaron Ugrave -20 KPX Rcaron Uhungarumlaut -20 KPX Rcaron Umacron -20 KPX Rcaron Uogonek -20 KPX Rcaron Uring -20 KPX Rcaron V -50 KPX Rcaron W -40 KPX Rcaron Y -50 KPX Rcaron Yacute -50 KPX Rcaron Ydieresis -50 KPX Rcommaaccent O -20 KPX Rcommaaccent Oacute -20 KPX Rcommaaccent Ocircumflex -20 KPX Rcommaaccent Odieresis -20 KPX Rcommaaccent Ograve -20 KPX Rcommaaccent Ohungarumlaut -20 KPX Rcommaaccent Omacron -20 KPX Rcommaaccent Oslash -20 KPX Rcommaaccent Otilde -20 KPX Rcommaaccent T -20 KPX Rcommaaccent Tcaron -20 KPX Rcommaaccent Tcommaaccent -20 KPX Rcommaaccent U -20 KPX Rcommaaccent Uacute -20 KPX Rcommaaccent Ucircumflex -20 KPX Rcommaaccent Udieresis -20 KPX Rcommaaccent Ugrave -20 KPX Rcommaaccent Uhungarumlaut -20 KPX Rcommaaccent Umacron -20 KPX Rcommaaccent Uogonek -20 KPX Rcommaaccent Uring -20 KPX Rcommaaccent V -50 KPX Rcommaaccent W -40 KPX Rcommaaccent Y -50 KPX Rcommaaccent Yacute -50 KPX Rcommaaccent Ydieresis -50 KPX T A -90 KPX T Aacute -90 KPX T Abreve -90 KPX T Acircumflex -90 KPX T Adieresis -90 KPX T Agrave -90 KPX T Amacron -90 KPX T Aogonek -90 KPX T Aring -90 KPX T Atilde -90 KPX T O -40 KPX T Oacute -40 KPX T Ocircumflex -40 KPX T Odieresis -40 KPX T Ograve -40 KPX T Ohungarumlaut -40 KPX T Omacron -40 KPX T Oslash -40 KPX T Otilde -40 KPX T a -80 KPX T aacute -80 KPX T abreve -80 KPX T acircumflex -80 KPX T adieresis -80 KPX T agrave -80 KPX T amacron -80 KPX T aogonek -80 KPX T aring -80 KPX T atilde -80 KPX T colon -40 KPX T comma -80 KPX T e -60 KPX T eacute -60 KPX T ecaron -60 KPX T ecircumflex -60 KPX T edieresis -60 KPX T edotaccent -60 KPX T egrave -60 KPX T emacron -60 KPX T eogonek -60 KPX T hyphen -120 KPX T o -80 KPX T oacute -80 KPX T ocircumflex -80 KPX T odieresis -80 KPX T ograve -80 KPX T ohungarumlaut -80 KPX T omacron -80 KPX T oslash -80 KPX T otilde -80 KPX T period -80 KPX T r -80 KPX T racute -80 KPX T rcommaaccent -80 KPX T semicolon -40 KPX T u -90 KPX T uacute -90 KPX T ucircumflex -90 KPX T udieresis -90 KPX T ugrave -90 KPX T uhungarumlaut -90 KPX T umacron -90 KPX T uogonek -90 KPX T uring -90 KPX T w -60 KPX T y -60 KPX T yacute -60 KPX T ydieresis -60 KPX Tcaron A -90 KPX Tcaron Aacute -90 KPX Tcaron Abreve -90 KPX Tcaron Acircumflex -90 KPX Tcaron Adieresis -90 KPX Tcaron Agrave -90 KPX Tcaron Amacron -90 KPX Tcaron Aogonek -90 KPX Tcaron Aring -90 KPX Tcaron Atilde -90 KPX Tcaron O -40 KPX Tcaron Oacute -40 KPX Tcaron Ocircumflex -40 KPX Tcaron Odieresis -40 KPX Tcaron Ograve -40 KPX Tcaron Ohungarumlaut -40 KPX Tcaron Omacron -40 KPX Tcaron Oslash -40 KPX Tcaron Otilde -40 KPX Tcaron a -80 KPX Tcaron aacute -80 KPX Tcaron abreve -80 KPX Tcaron acircumflex -80 KPX Tcaron adieresis -80 KPX Tcaron agrave -80 KPX Tcaron amacron -80 KPX Tcaron aogonek -80 KPX Tcaron aring -80 KPX Tcaron atilde -80 KPX Tcaron colon -40 KPX Tcaron comma -80 KPX Tcaron e -60 KPX Tcaron eacute -60 KPX Tcaron ecaron -60 KPX Tcaron ecircumflex -60 KPX Tcaron edieresis -60 KPX Tcaron edotaccent -60 KPX Tcaron egrave -60 KPX Tcaron emacron -60 KPX Tcaron eogonek -60 KPX Tcaron hyphen -120 KPX Tcaron o -80 KPX Tcaron oacute -80 KPX Tcaron ocircumflex -80 KPX Tcaron odieresis -80 KPX Tcaron ograve -80 KPX Tcaron ohungarumlaut -80 KPX Tcaron omacron -80 KPX Tcaron oslash -80 KPX Tcaron otilde -80 KPX Tcaron period -80 KPX Tcaron r -80 KPX Tcaron racute -80 KPX Tcaron rcommaaccent -80 KPX Tcaron semicolon -40 KPX Tcaron u -90 KPX Tcaron uacute -90 KPX Tcaron ucircumflex -90 KPX Tcaron udieresis -90 KPX Tcaron ugrave -90 KPX Tcaron uhungarumlaut -90 KPX Tcaron umacron -90 KPX Tcaron uogonek -90 KPX Tcaron uring -90 KPX Tcaron w -60 KPX Tcaron y -60 KPX Tcaron yacute -60 KPX Tcaron ydieresis -60 KPX Tcommaaccent A -90 KPX Tcommaaccent Aacute -90 KPX Tcommaaccent Abreve -90 KPX Tcommaaccent Acircumflex -90 KPX Tcommaaccent Adieresis -90 KPX Tcommaaccent Agrave -90 KPX Tcommaaccent Amacron -90 KPX Tcommaaccent Aogonek -90 KPX Tcommaaccent Aring -90 KPX Tcommaaccent Atilde -90 KPX Tcommaaccent O -40 KPX Tcommaaccent Oacute -40 KPX Tcommaaccent Ocircumflex -40 KPX Tcommaaccent Odieresis -40 KPX Tcommaaccent Ograve -40 KPX Tcommaaccent Ohungarumlaut -40 KPX Tcommaaccent Omacron -40 KPX Tcommaaccent Oslash -40 KPX Tcommaaccent Otilde -40 KPX Tcommaaccent a -80 KPX Tcommaaccent aacute -80 KPX Tcommaaccent abreve -80 KPX Tcommaaccent acircumflex -80 KPX Tcommaaccent adieresis -80 KPX Tcommaaccent agrave -80 KPX Tcommaaccent amacron -80 KPX Tcommaaccent aogonek -80 KPX Tcommaaccent aring -80 KPX Tcommaaccent atilde -80 KPX Tcommaaccent colon -40 KPX Tcommaaccent comma -80 KPX Tcommaaccent e -60 KPX Tcommaaccent eacute -60 KPX Tcommaaccent ecaron -60 KPX Tcommaaccent ecircumflex -60 KPX Tcommaaccent edieresis -60 KPX Tcommaaccent edotaccent -60 KPX Tcommaaccent egrave -60 KPX Tcommaaccent emacron -60 KPX Tcommaaccent eogonek -60 KPX Tcommaaccent hyphen -120 KPX Tcommaaccent o -80 KPX Tcommaaccent oacute -80 KPX Tcommaaccent ocircumflex -80 KPX Tcommaaccent odieresis -80 KPX Tcommaaccent ograve -80 KPX Tcommaaccent ohungarumlaut -80 KPX Tcommaaccent omacron -80 KPX Tcommaaccent oslash -80 KPX Tcommaaccent otilde -80 KPX Tcommaaccent period -80 KPX Tcommaaccent r -80 KPX Tcommaaccent racute -80 KPX Tcommaaccent rcommaaccent -80 KPX Tcommaaccent semicolon -40 KPX Tcommaaccent u -90 KPX Tcommaaccent uacute -90 KPX Tcommaaccent ucircumflex -90 KPX Tcommaaccent udieresis -90 KPX Tcommaaccent ugrave -90 KPX Tcommaaccent uhungarumlaut -90 KPX Tcommaaccent umacron -90 KPX Tcommaaccent uogonek -90 KPX Tcommaaccent uring -90 KPX Tcommaaccent w -60 KPX Tcommaaccent y -60 KPX Tcommaaccent yacute -60 KPX Tcommaaccent ydieresis -60 KPX U A -50 KPX U Aacute -50 KPX U Abreve -50 KPX U Acircumflex -50 KPX U Adieresis -50 KPX U Agrave -50 KPX U Amacron -50 KPX U Aogonek -50 KPX U Aring -50 KPX U Atilde -50 KPX U comma -30 KPX U period -30 KPX Uacute A -50 KPX Uacute Aacute -50 KPX Uacute Abreve -50 KPX Uacute Acircumflex -50 KPX Uacute Adieresis -50 KPX Uacute Agrave -50 KPX Uacute Amacron -50 KPX Uacute Aogonek -50 KPX Uacute Aring -50 KPX Uacute Atilde -50 KPX Uacute comma -30 KPX Uacute period -30 KPX Ucircumflex A -50 KPX Ucircumflex Aacute -50 KPX Ucircumflex Abreve -50 KPX Ucircumflex Acircumflex -50 KPX Ucircumflex Adieresis -50 KPX Ucircumflex Agrave -50 KPX Ucircumflex Amacron -50 KPX Ucircumflex Aogonek -50 KPX Ucircumflex Aring -50 KPX Ucircumflex Atilde -50 KPX Ucircumflex comma -30 KPX Ucircumflex period -30 KPX Udieresis A -50 KPX Udieresis Aacute -50 KPX Udieresis Abreve -50 KPX Udieresis Acircumflex -50 KPX Udieresis Adieresis -50 KPX Udieresis Agrave -50 KPX Udieresis Amacron -50 KPX Udieresis Aogonek -50 KPX Udieresis Aring -50 KPX Udieresis Atilde -50 KPX Udieresis comma -30 KPX Udieresis period -30 KPX Ugrave A -50 KPX Ugrave Aacute -50 KPX Ugrave Abreve -50 KPX Ugrave Acircumflex -50 KPX Ugrave Adieresis -50 KPX Ugrave Agrave -50 KPX Ugrave Amacron -50 KPX Ugrave Aogonek -50 KPX Ugrave Aring -50 KPX Ugrave Atilde -50 KPX Ugrave comma -30 KPX Ugrave period -30 KPX Uhungarumlaut A -50 KPX Uhungarumlaut Aacute -50 KPX Uhungarumlaut Abreve -50 KPX Uhungarumlaut Acircumflex -50 KPX Uhungarumlaut Adieresis -50 KPX Uhungarumlaut Agrave -50 KPX Uhungarumlaut Amacron -50 KPX Uhungarumlaut Aogonek -50 KPX Uhungarumlaut Aring -50 KPX Uhungarumlaut Atilde -50 KPX Uhungarumlaut comma -30 KPX Uhungarumlaut period -30 KPX Umacron A -50 KPX Umacron Aacute -50 KPX Umacron Abreve -50 KPX Umacron Acircumflex -50 KPX Umacron Adieresis -50 KPX Umacron Agrave -50 KPX Umacron Amacron -50 KPX Umacron Aogonek -50 KPX Umacron Aring -50 KPX Umacron Atilde -50 KPX Umacron comma -30 KPX Umacron period -30 KPX Uogonek A -50 KPX Uogonek Aacute -50 KPX Uogonek Abreve -50 KPX Uogonek Acircumflex -50 KPX Uogonek Adieresis -50 KPX Uogonek Agrave -50 KPX Uogonek Amacron -50 KPX Uogonek Aogonek -50 KPX Uogonek Aring -50 KPX Uogonek Atilde -50 KPX Uogonek comma -30 KPX Uogonek period -30 KPX Uring A -50 KPX Uring Aacute -50 KPX Uring Abreve -50 KPX Uring Acircumflex -50 KPX Uring Adieresis -50 KPX Uring Agrave -50 KPX Uring Amacron -50 KPX Uring Aogonek -50 KPX Uring Aring -50 KPX Uring Atilde -50 KPX Uring comma -30 KPX Uring period -30 KPX V A -80 KPX V Aacute -80 KPX V Abreve -80 KPX V Acircumflex -80 KPX V Adieresis -80 KPX V Agrave -80 KPX V Amacron -80 KPX V Aogonek -80 KPX V Aring -80 KPX V Atilde -80 KPX V G -50 KPX V Gbreve -50 KPX V Gcommaaccent -50 KPX V O -50 KPX V Oacute -50 KPX V Ocircumflex -50 KPX V Odieresis -50 KPX V Ograve -50 KPX V Ohungarumlaut -50 KPX V Omacron -50 KPX V Oslash -50 KPX V Otilde -50 KPX V a -60 KPX V aacute -60 KPX V abreve -60 KPX V acircumflex -60 KPX V adieresis -60 KPX V agrave -60 KPX V amacron -60 KPX V aogonek -60 KPX V aring -60 KPX V atilde -60 KPX V colon -40 KPX V comma -120 KPX V e -50 KPX V eacute -50 KPX V ecaron -50 KPX V ecircumflex -50 KPX V edieresis -50 KPX V edotaccent -50 KPX V egrave -50 KPX V emacron -50 KPX V eogonek -50 KPX V hyphen -80 KPX V o -90 KPX V oacute -90 KPX V ocircumflex -90 KPX V odieresis -90 KPX V ograve -90 KPX V ohungarumlaut -90 KPX V omacron -90 KPX V oslash -90 KPX V otilde -90 KPX V period -120 KPX V semicolon -40 KPX V u -60 KPX V uacute -60 KPX V ucircumflex -60 KPX V udieresis -60 KPX V ugrave -60 KPX V uhungarumlaut -60 KPX V umacron -60 KPX V uogonek -60 KPX V uring -60 KPX W A -60 KPX W Aacute -60 KPX W Abreve -60 KPX W Acircumflex -60 KPX W Adieresis -60 KPX W Agrave -60 KPX W Amacron -60 KPX W Aogonek -60 KPX W Aring -60 KPX W Atilde -60 KPX W O -20 KPX W Oacute -20 KPX W Ocircumflex -20 KPX W Odieresis -20 KPX W Ograve -20 KPX W Ohungarumlaut -20 KPX W Omacron -20 KPX W Oslash -20 KPX W Otilde -20 KPX W a -40 KPX W aacute -40 KPX W abreve -40 KPX W acircumflex -40 KPX W adieresis -40 KPX W agrave -40 KPX W amacron -40 KPX W aogonek -40 KPX W aring -40 KPX W atilde -40 KPX W colon -10 KPX W comma -80 KPX W e -35 KPX W eacute -35 KPX W ecaron -35 KPX W ecircumflex -35 KPX W edieresis -35 KPX W edotaccent -35 KPX W egrave -35 KPX W emacron -35 KPX W eogonek -35 KPX W hyphen -40 KPX W o -60 KPX W oacute -60 KPX W ocircumflex -60 KPX W odieresis -60 KPX W ograve -60 KPX W ohungarumlaut -60 KPX W omacron -60 KPX W oslash -60 KPX W otilde -60 KPX W period -80 KPX W semicolon -10 KPX W u -45 KPX W uacute -45 KPX W ucircumflex -45 KPX W udieresis -45 KPX W ugrave -45 KPX W uhungarumlaut -45 KPX W umacron -45 KPX W uogonek -45 KPX W uring -45 KPX W y -20 KPX W yacute -20 KPX W ydieresis -20 KPX Y A -110 KPX Y Aacute -110 KPX Y Abreve -110 KPX Y Acircumflex -110 KPX Y Adieresis -110 KPX Y Agrave -110 KPX Y Amacron -110 KPX Y Aogonek -110 KPX Y Aring -110 KPX Y Atilde -110 KPX Y O -70 KPX Y Oacute -70 KPX Y Ocircumflex -70 KPX Y Odieresis -70 KPX Y Ograve -70 KPX Y Ohungarumlaut -70 KPX Y Omacron -70 KPX Y Oslash -70 KPX Y Otilde -70 KPX Y a -90 KPX Y aacute -90 KPX Y abreve -90 KPX Y acircumflex -90 KPX Y adieresis -90 KPX Y agrave -90 KPX Y amacron -90 KPX Y aogonek -90 KPX Y aring -90 KPX Y atilde -90 KPX Y colon -50 KPX Y comma -100 KPX Y e -80 KPX Y eacute -80 KPX Y ecaron -80 KPX Y ecircumflex -80 KPX Y edieresis -80 KPX Y edotaccent -80 KPX Y egrave -80 KPX Y emacron -80 KPX Y eogonek -80 KPX Y o -100 KPX Y oacute -100 KPX Y ocircumflex -100 KPX Y odieresis -100 KPX Y ograve -100 KPX Y ohungarumlaut -100 KPX Y omacron -100 KPX Y oslash -100 KPX Y otilde -100 KPX Y period -100 KPX Y semicolon -50 KPX Y u -100 KPX Y uacute -100 KPX Y ucircumflex -100 KPX Y udieresis -100 KPX Y ugrave -100 KPX Y uhungarumlaut -100 KPX Y umacron -100 KPX Y uogonek -100 KPX Y uring -100 KPX Yacute A -110 KPX Yacute Aacute -110 KPX Yacute Abreve -110 KPX Yacute Acircumflex -110 KPX Yacute Adieresis -110 KPX Yacute Agrave -110 KPX Yacute Amacron -110 KPX Yacute Aogonek -110 KPX Yacute Aring -110 KPX Yacute Atilde -110 KPX Yacute O -70 KPX Yacute Oacute -70 KPX Yacute Ocircumflex -70 KPX Yacute Odieresis -70 KPX Yacute Ograve -70 KPX Yacute Ohungarumlaut -70 KPX Yacute Omacron -70 KPX Yacute Oslash -70 KPX Yacute Otilde -70 KPX Yacute a -90 KPX Yacute aacute -90 KPX Yacute abreve -90 KPX Yacute acircumflex -90 KPX Yacute adieresis -90 KPX Yacute agrave -90 KPX Yacute amacron -90 KPX Yacute aogonek -90 KPX Yacute aring -90 KPX Yacute atilde -90 KPX Yacute colon -50 KPX Yacute comma -100 KPX Yacute e -80 KPX Yacute eacute -80 KPX Yacute ecaron -80 KPX Yacute ecircumflex -80 KPX Yacute edieresis -80 KPX Yacute edotaccent -80 KPX Yacute egrave -80 KPX Yacute emacron -80 KPX Yacute eogonek -80 KPX Yacute o -100 KPX Yacute oacute -100 KPX Yacute ocircumflex -100 KPX Yacute odieresis -100 KPX Yacute ograve -100 KPX Yacute ohungarumlaut -100 KPX Yacute omacron -100 KPX Yacute oslash -100 KPX Yacute otilde -100 KPX Yacute period -100 KPX Yacute semicolon -50 KPX Yacute u -100 KPX Yacute uacute -100 KPX Yacute ucircumflex -100 KPX Yacute udieresis -100 KPX Yacute ugrave -100 KPX Yacute uhungarumlaut -100 KPX Yacute umacron -100 KPX Yacute uogonek -100 KPX Yacute uring -100 KPX Ydieresis A -110 KPX Ydieresis Aacute -110 KPX Ydieresis Abreve -110 KPX Ydieresis Acircumflex -110 KPX Ydieresis Adieresis -110 KPX Ydieresis Agrave -110 KPX Ydieresis Amacron -110 KPX Ydieresis Aogonek -110 KPX Ydieresis Aring -110 KPX Ydieresis Atilde -110 KPX Ydieresis O -70 KPX Ydieresis Oacute -70 KPX Ydieresis Ocircumflex -70 KPX Ydieresis Odieresis -70 KPX Ydieresis Ograve -70 KPX Ydieresis Ohungarumlaut -70 KPX Ydieresis Omacron -70 KPX Ydieresis Oslash -70 KPX Ydieresis Otilde -70 KPX Ydieresis a -90 KPX Ydieresis aacute -90 KPX Ydieresis abreve -90 KPX Ydieresis acircumflex -90 KPX Ydieresis adieresis -90 KPX Ydieresis agrave -90 KPX Ydieresis amacron -90 KPX Ydieresis aogonek -90 KPX Ydieresis aring -90 KPX Ydieresis atilde -90 KPX Ydieresis colon -50 KPX Ydieresis comma -100 KPX Ydieresis e -80 KPX Ydieresis eacute -80 KPX Ydieresis ecaron -80 KPX Ydieresis ecircumflex -80 KPX Ydieresis edieresis -80 KPX Ydieresis edotaccent -80 KPX Ydieresis egrave -80 KPX Ydieresis emacron -80 KPX Ydieresis eogonek -80 KPX Ydieresis o -100 KPX Ydieresis oacute -100 KPX Ydieresis ocircumflex -100 KPX Ydieresis odieresis -100 KPX Ydieresis ograve -100 KPX Ydieresis ohungarumlaut -100 KPX Ydieresis omacron -100 KPX Ydieresis oslash -100 KPX Ydieresis otilde -100 KPX Ydieresis period -100 KPX Ydieresis semicolon -50 KPX Ydieresis u -100 KPX Ydieresis uacute -100 KPX Ydieresis ucircumflex -100 KPX Ydieresis udieresis -100 KPX Ydieresis ugrave -100 KPX Ydieresis uhungarumlaut -100 KPX Ydieresis umacron -100 KPX Ydieresis uogonek -100 KPX Ydieresis uring -100 KPX a g -10 KPX a gbreve -10 KPX a gcommaaccent -10 KPX a v -15 KPX a w -15 KPX a y -20 KPX a yacute -20 KPX a ydieresis -20 KPX aacute g -10 KPX aacute gbreve -10 KPX aacute gcommaaccent -10 KPX aacute v -15 KPX aacute w -15 KPX aacute y -20 KPX aacute yacute -20 KPX aacute ydieresis -20 KPX abreve g -10 KPX abreve gbreve -10 KPX abreve gcommaaccent -10 KPX abreve v -15 KPX abreve w -15 KPX abreve y -20 KPX abreve yacute -20 KPX abreve ydieresis -20 KPX acircumflex g -10 KPX acircumflex gbreve -10 KPX acircumflex gcommaaccent -10 KPX acircumflex v -15 KPX acircumflex w -15 KPX acircumflex y -20 KPX acircumflex yacute -20 KPX acircumflex ydieresis -20 KPX adieresis g -10 KPX adieresis gbreve -10 KPX adieresis gcommaaccent -10 KPX adieresis v -15 KPX adieresis w -15 KPX adieresis y -20 KPX adieresis yacute -20 KPX adieresis ydieresis -20 KPX agrave g -10 KPX agrave gbreve -10 KPX agrave gcommaaccent -10 KPX agrave v -15 KPX agrave w -15 KPX agrave y -20 KPX agrave yacute -20 KPX agrave ydieresis -20 KPX amacron g -10 KPX amacron gbreve -10 KPX amacron gcommaaccent -10 KPX amacron v -15 KPX amacron w -15 KPX amacron y -20 KPX amacron yacute -20 KPX amacron ydieresis -20 KPX aogonek g -10 KPX aogonek gbreve -10 KPX aogonek gcommaaccent -10 KPX aogonek v -15 KPX aogonek w -15 KPX aogonek y -20 KPX aogonek yacute -20 KPX aogonek ydieresis -20 KPX aring g -10 KPX aring gbreve -10 KPX aring gcommaaccent -10 KPX aring v -15 KPX aring w -15 KPX aring y -20 KPX aring yacute -20 KPX aring ydieresis -20 KPX atilde g -10 KPX atilde gbreve -10 KPX atilde gcommaaccent -10 KPX atilde v -15 KPX atilde w -15 KPX atilde y -20 KPX atilde yacute -20 KPX atilde ydieresis -20 KPX b l -10 KPX b lacute -10 KPX b lcommaaccent -10 KPX b lslash -10 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -20 KPX b y -20 KPX b yacute -20 KPX b ydieresis -20 KPX c h -10 KPX c k -20 KPX c kcommaaccent -20 KPX c l -20 KPX c lacute -20 KPX c lcommaaccent -20 KPX c lslash -20 KPX c y -10 KPX c yacute -10 KPX c ydieresis -10 KPX cacute h -10 KPX cacute k -20 KPX cacute kcommaaccent -20 KPX cacute l -20 KPX cacute lacute -20 KPX cacute lcommaaccent -20 KPX cacute lslash -20 KPX cacute y -10 KPX cacute yacute -10 KPX cacute ydieresis -10 KPX ccaron h -10 KPX ccaron k -20 KPX ccaron kcommaaccent -20 KPX ccaron l -20 KPX ccaron lacute -20 KPX ccaron lcommaaccent -20 KPX ccaron lslash -20 KPX ccaron y -10 KPX ccaron yacute -10 KPX ccaron ydieresis -10 KPX ccedilla h -10 KPX ccedilla k -20 KPX ccedilla kcommaaccent -20 KPX ccedilla l -20 KPX ccedilla lacute -20 KPX ccedilla lcommaaccent -20 KPX ccedilla lslash -20 KPX ccedilla y -10 KPX ccedilla yacute -10 KPX ccedilla ydieresis -10 KPX colon space -40 KPX comma quotedblright -120 KPX comma quoteright -120 KPX comma space -40 KPX d d -10 KPX d dcroat -10 KPX d v -15 KPX d w -15 KPX d y -15 KPX d yacute -15 KPX d ydieresis -15 KPX dcroat d -10 KPX dcroat dcroat -10 KPX dcroat v -15 KPX dcroat w -15 KPX dcroat y -15 KPX dcroat yacute -15 KPX dcroat ydieresis -15 KPX e comma 10 KPX e period 20 KPX e v -15 KPX e w -15 KPX e x -15 KPX e y -15 KPX e yacute -15 KPX e ydieresis -15 KPX eacute comma 10 KPX eacute period 20 KPX eacute v -15 KPX eacute w -15 KPX eacute x -15 KPX eacute y -15 KPX eacute yacute -15 KPX eacute ydieresis -15 KPX ecaron comma 10 KPX ecaron period 20 KPX ecaron v -15 KPX ecaron w -15 KPX ecaron x -15 KPX ecaron y -15 KPX ecaron yacute -15 KPX ecaron ydieresis -15 KPX ecircumflex comma 10 KPX ecircumflex period 20 KPX ecircumflex v -15 KPX ecircumflex w -15 KPX ecircumflex x -15 KPX ecircumflex y -15 KPX ecircumflex yacute -15 KPX ecircumflex ydieresis -15 KPX edieresis comma 10 KPX edieresis period 20 KPX edieresis v -15 KPX edieresis w -15 KPX edieresis x -15 KPX edieresis y -15 KPX edieresis yacute -15 KPX edieresis ydieresis -15 KPX edotaccent comma 10 KPX edotaccent period 20 KPX edotaccent v -15 KPX edotaccent w -15 KPX edotaccent x -15 KPX edotaccent y -15 KPX edotaccent yacute -15 KPX edotaccent ydieresis -15 KPX egrave comma 10 KPX egrave period 20 KPX egrave v -15 KPX egrave w -15 KPX egrave x -15 KPX egrave y -15 KPX egrave yacute -15 KPX egrave ydieresis -15 KPX emacron comma 10 KPX emacron period 20 KPX emacron v -15 KPX emacron w -15 KPX emacron x -15 KPX emacron y -15 KPX emacron yacute -15 KPX emacron ydieresis -15 KPX eogonek comma 10 KPX eogonek period 20 KPX eogonek v -15 KPX eogonek w -15 KPX eogonek x -15 KPX eogonek y -15 KPX eogonek yacute -15 KPX eogonek ydieresis -15 KPX f comma -10 KPX f e -10 KPX f eacute -10 KPX f ecaron -10 KPX f ecircumflex -10 KPX f edieresis -10 KPX f edotaccent -10 KPX f egrave -10 KPX f emacron -10 KPX f eogonek -10 KPX f o -20 KPX f oacute -20 KPX f ocircumflex -20 KPX f odieresis -20 KPX f ograve -20 KPX f ohungarumlaut -20 KPX f omacron -20 KPX f oslash -20 KPX f otilde -20 KPX f period -10 KPX f quotedblright 30 KPX f quoteright 30 KPX g e 10 KPX g eacute 10 KPX g ecaron 10 KPX g ecircumflex 10 KPX g edieresis 10 KPX g edotaccent 10 KPX g egrave 10 KPX g emacron 10 KPX g eogonek 10 KPX g g -10 KPX g gbreve -10 KPX g gcommaaccent -10 KPX gbreve e 10 KPX gbreve eacute 10 KPX gbreve ecaron 10 KPX gbreve ecircumflex 10 KPX gbreve edieresis 10 KPX gbreve edotaccent 10 KPX gbreve egrave 10 KPX gbreve emacron 10 KPX gbreve eogonek 10 KPX gbreve g -10 KPX gbreve gbreve -10 KPX gbreve gcommaaccent -10 KPX gcommaaccent e 10 KPX gcommaaccent eacute 10 KPX gcommaaccent ecaron 10 KPX gcommaaccent ecircumflex 10 KPX gcommaaccent edieresis 10 KPX gcommaaccent edotaccent 10 KPX gcommaaccent egrave 10 KPX gcommaaccent emacron 10 KPX gcommaaccent eogonek 10 KPX gcommaaccent g -10 KPX gcommaaccent gbreve -10 KPX gcommaaccent gcommaaccent -10 KPX h y -20 KPX h yacute -20 KPX h ydieresis -20 KPX k o -15 KPX k oacute -15 KPX k ocircumflex -15 KPX k odieresis -15 KPX k ograve -15 KPX k ohungarumlaut -15 KPX k omacron -15 KPX k oslash -15 KPX k otilde -15 KPX kcommaaccent o -15 KPX kcommaaccent oacute -15 KPX kcommaaccent ocircumflex -15 KPX kcommaaccent odieresis -15 KPX kcommaaccent ograve -15 KPX kcommaaccent ohungarumlaut -15 KPX kcommaaccent omacron -15 KPX kcommaaccent oslash -15 KPX kcommaaccent otilde -15 KPX l w -15 KPX l y -15 KPX l yacute -15 KPX l ydieresis -15 KPX lacute w -15 KPX lacute y -15 KPX lacute yacute -15 KPX lacute ydieresis -15 KPX lcommaaccent w -15 KPX lcommaaccent y -15 KPX lcommaaccent yacute -15 KPX lcommaaccent ydieresis -15 KPX lslash w -15 KPX lslash y -15 KPX lslash yacute -15 KPX lslash ydieresis -15 KPX m u -20 KPX m uacute -20 KPX m ucircumflex -20 KPX m udieresis -20 KPX m ugrave -20 KPX m uhungarumlaut -20 KPX m umacron -20 KPX m uogonek -20 KPX m uring -20 KPX m y -30 KPX m yacute -30 KPX m ydieresis -30 KPX n u -10 KPX n uacute -10 KPX n ucircumflex -10 KPX n udieresis -10 KPX n ugrave -10 KPX n uhungarumlaut -10 KPX n umacron -10 KPX n uogonek -10 KPX n uring -10 KPX n v -40 KPX n y -20 KPX n yacute -20 KPX n ydieresis -20 KPX nacute u -10 KPX nacute uacute -10 KPX nacute ucircumflex -10 KPX nacute udieresis -10 KPX nacute ugrave -10 KPX nacute uhungarumlaut -10 KPX nacute umacron -10 KPX nacute uogonek -10 KPX nacute uring -10 KPX nacute v -40 KPX nacute y -20 KPX nacute yacute -20 KPX nacute ydieresis -20 KPX ncaron u -10 KPX ncaron uacute -10 KPX ncaron ucircumflex -10 KPX ncaron udieresis -10 KPX ncaron ugrave -10 KPX ncaron uhungarumlaut -10 KPX ncaron umacron -10 KPX ncaron uogonek -10 KPX ncaron uring -10 KPX ncaron v -40 KPX ncaron y -20 KPX ncaron yacute -20 KPX ncaron ydieresis -20 KPX ncommaaccent u -10 KPX ncommaaccent uacute -10 KPX ncommaaccent ucircumflex -10 KPX ncommaaccent udieresis -10 KPX ncommaaccent ugrave -10 KPX ncommaaccent uhungarumlaut -10 KPX ncommaaccent umacron -10 KPX ncommaaccent uogonek -10 KPX ncommaaccent uring -10 KPX ncommaaccent v -40 KPX ncommaaccent y -20 KPX ncommaaccent yacute -20 KPX ncommaaccent ydieresis -20 KPX ntilde u -10 KPX ntilde uacute -10 KPX ntilde ucircumflex -10 KPX ntilde udieresis -10 KPX ntilde ugrave -10 KPX ntilde uhungarumlaut -10 KPX ntilde umacron -10 KPX ntilde uogonek -10 KPX ntilde uring -10 KPX ntilde v -40 KPX ntilde y -20 KPX ntilde yacute -20 KPX ntilde ydieresis -20 KPX o v -20 KPX o w -15 KPX o x -30 KPX o y -20 KPX o yacute -20 KPX o ydieresis -20 KPX oacute v -20 KPX oacute w -15 KPX oacute x -30 KPX oacute y -20 KPX oacute yacute -20 KPX oacute ydieresis -20 KPX ocircumflex v -20 KPX ocircumflex w -15 KPX ocircumflex x -30 KPX ocircumflex y -20 KPX ocircumflex yacute -20 KPX ocircumflex ydieresis -20 KPX odieresis v -20 KPX odieresis w -15 KPX odieresis x -30 KPX odieresis y -20 KPX odieresis yacute -20 KPX odieresis ydieresis -20 KPX ograve v -20 KPX ograve w -15 KPX ograve x -30 KPX ograve y -20 KPX ograve yacute -20 KPX ograve ydieresis -20 KPX ohungarumlaut v -20 KPX ohungarumlaut w -15 KPX ohungarumlaut x -30 KPX ohungarumlaut y -20 KPX ohungarumlaut yacute -20 KPX ohungarumlaut ydieresis -20 KPX omacron v -20 KPX omacron w -15 KPX omacron x -30 KPX omacron y -20 KPX omacron yacute -20 KPX omacron ydieresis -20 KPX oslash v -20 KPX oslash w -15 KPX oslash x -30 KPX oslash y -20 KPX oslash yacute -20 KPX oslash ydieresis -20 KPX otilde v -20 KPX otilde w -15 KPX otilde x -30 KPX otilde y -20 KPX otilde yacute -20 KPX otilde ydieresis -20 KPX p y -15 KPX p yacute -15 KPX p ydieresis -15 KPX period quotedblright -120 KPX period quoteright -120 KPX period space -40 KPX quotedblright space -80 KPX quoteleft quoteleft -46 KPX quoteright d -80 KPX quoteright dcroat -80 KPX quoteright l -20 KPX quoteright lacute -20 KPX quoteright lcommaaccent -20 KPX quoteright lslash -20 KPX quoteright quoteright -46 KPX quoteright r -40 KPX quoteright racute -40 KPX quoteright rcaron -40 KPX quoteright rcommaaccent -40 KPX quoteright s -60 KPX quoteright sacute -60 KPX quoteright scaron -60 KPX quoteright scedilla -60 KPX quoteright scommaaccent -60 KPX quoteright space -80 KPX quoteright v -20 KPX r c -20 KPX r cacute -20 KPX r ccaron -20 KPX r ccedilla -20 KPX r comma -60 KPX r d -20 KPX r dcroat -20 KPX r g -15 KPX r gbreve -15 KPX r gcommaaccent -15 KPX r hyphen -20 KPX r o -20 KPX r oacute -20 KPX r ocircumflex -20 KPX r odieresis -20 KPX r ograve -20 KPX r ohungarumlaut -20 KPX r omacron -20 KPX r oslash -20 KPX r otilde -20 KPX r period -60 KPX r q -20 KPX r s -15 KPX r sacute -15 KPX r scaron -15 KPX r scedilla -15 KPX r scommaaccent -15 KPX r t 20 KPX r tcommaaccent 20 KPX r v 10 KPX r y 10 KPX r yacute 10 KPX r ydieresis 10 KPX racute c -20 KPX racute cacute -20 KPX racute ccaron -20 KPX racute ccedilla -20 KPX racute comma -60 KPX racute d -20 KPX racute dcroat -20 KPX racute g -15 KPX racute gbreve -15 KPX racute gcommaaccent -15 KPX racute hyphen -20 KPX racute o -20 KPX racute oacute -20 KPX racute ocircumflex -20 KPX racute odieresis -20 KPX racute ograve -20 KPX racute ohungarumlaut -20 KPX racute omacron -20 KPX racute oslash -20 KPX racute otilde -20 KPX racute period -60 KPX racute q -20 KPX racute s -15 KPX racute sacute -15 KPX racute scaron -15 KPX racute scedilla -15 KPX racute scommaaccent -15 KPX racute t 20 KPX racute tcommaaccent 20 KPX racute v 10 KPX racute y 10 KPX racute yacute 10 KPX racute ydieresis 10 KPX rcaron c -20 KPX rcaron cacute -20 KPX rcaron ccaron -20 KPX rcaron ccedilla -20 KPX rcaron comma -60 KPX rcaron d -20 KPX rcaron dcroat -20 KPX rcaron g -15 KPX rcaron gbreve -15 KPX rcaron gcommaaccent -15 KPX rcaron hyphen -20 KPX rcaron o -20 KPX rcaron oacute -20 KPX rcaron ocircumflex -20 KPX rcaron odieresis -20 KPX rcaron ograve -20 KPX rcaron ohungarumlaut -20 KPX rcaron omacron -20 KPX rcaron oslash -20 KPX rcaron otilde -20 KPX rcaron period -60 KPX rcaron q -20 KPX rcaron s -15 KPX rcaron sacute -15 KPX rcaron scaron -15 KPX rcaron scedilla -15 KPX rcaron scommaaccent -15 KPX rcaron t 20 KPX rcaron tcommaaccent 20 KPX rcaron v 10 KPX rcaron y 10 KPX rcaron yacute 10 KPX rcaron ydieresis 10 KPX rcommaaccent c -20 KPX rcommaaccent cacute -20 KPX rcommaaccent ccaron -20 KPX rcommaaccent ccedilla -20 KPX rcommaaccent comma -60 KPX rcommaaccent d -20 KPX rcommaaccent dcroat -20 KPX rcommaaccent g -15 KPX rcommaaccent gbreve -15 KPX rcommaaccent gcommaaccent -15 KPX rcommaaccent hyphen -20 KPX rcommaaccent o -20 KPX rcommaaccent oacute -20 KPX rcommaaccent ocircumflex -20 KPX rcommaaccent odieresis -20 KPX rcommaaccent ograve -20 KPX rcommaaccent ohungarumlaut -20 KPX rcommaaccent omacron -20 KPX rcommaaccent oslash -20 KPX rcommaaccent otilde -20 KPX rcommaaccent period -60 KPX rcommaaccent q -20 KPX rcommaaccent s -15 KPX rcommaaccent sacute -15 KPX rcommaaccent scaron -15 KPX rcommaaccent scedilla -15 KPX rcommaaccent scommaaccent -15 KPX rcommaaccent t 20 KPX rcommaaccent tcommaaccent 20 KPX rcommaaccent v 10 KPX rcommaaccent y 10 KPX rcommaaccent yacute 10 KPX rcommaaccent ydieresis 10 KPX s w -15 KPX sacute w -15 KPX scaron w -15 KPX scedilla w -15 KPX scommaaccent w -15 KPX semicolon space -40 KPX space T -100 KPX space Tcaron -100 KPX space Tcommaaccent -100 KPX space V -80 KPX space W -80 KPX space Y -120 KPX space Yacute -120 KPX space Ydieresis -120 KPX space quotedblleft -80 KPX space quoteleft -60 KPX v a -20 KPX v aacute -20 KPX v abreve -20 KPX v acircumflex -20 KPX v adieresis -20 KPX v agrave -20 KPX v amacron -20 KPX v aogonek -20 KPX v aring -20 KPX v atilde -20 KPX v comma -80 KPX v o -30 KPX v oacute -30 KPX v ocircumflex -30 KPX v odieresis -30 KPX v ograve -30 KPX v ohungarumlaut -30 KPX v omacron -30 KPX v oslash -30 KPX v otilde -30 KPX v period -80 KPX w comma -40 KPX w o -20 KPX w oacute -20 KPX w ocircumflex -20 KPX w odieresis -20 KPX w ograve -20 KPX w ohungarumlaut -20 KPX w omacron -20 KPX w oslash -20 KPX w otilde -20 KPX w period -40 KPX x e -10 KPX x eacute -10 KPX x ecaron -10 KPX x ecircumflex -10 KPX x edieresis -10 KPX x edotaccent -10 KPX x egrave -10 KPX x emacron -10 KPX x eogonek -10 KPX y a -30 KPX y aacute -30 KPX y abreve -30 KPX y acircumflex -30 KPX y adieresis -30 KPX y agrave -30 KPX y amacron -30 KPX y aogonek -30 KPX y aring -30 KPX y atilde -30 KPX y comma -80 KPX y e -10 KPX y eacute -10 KPX y ecaron -10 KPX y ecircumflex -10 KPX y edieresis -10 KPX y edotaccent -10 KPX y egrave -10 KPX y emacron -10 KPX y eogonek -10 KPX y o -25 KPX y oacute -25 KPX y ocircumflex -25 KPX y odieresis -25 KPX y ograve -25 KPX y ohungarumlaut -25 KPX y omacron -25 KPX y oslash -25 KPX y otilde -25 KPX y period -80 KPX yacute a -30 KPX yacute aacute -30 KPX yacute abreve -30 KPX yacute acircumflex -30 KPX yacute adieresis -30 KPX yacute agrave -30 KPX yacute amacron -30 KPX yacute aogonek -30 KPX yacute aring -30 KPX yacute atilde -30 KPX yacute comma -80 KPX yacute e -10 KPX yacute eacute -10 KPX yacute ecaron -10 KPX yacute ecircumflex -10 KPX yacute edieresis -10 KPX yacute edotaccent -10 KPX yacute egrave -10 KPX yacute emacron -10 KPX yacute eogonek -10 KPX yacute o -25 KPX yacute oacute -25 KPX yacute ocircumflex -25 KPX yacute odieresis -25 KPX yacute ograve -25 KPX yacute ohungarumlaut -25 KPX yacute omacron -25 KPX yacute oslash -25 KPX yacute otilde -25 KPX yacute period -80 KPX ydieresis a -30 KPX ydieresis aacute -30 KPX ydieresis abreve -30 KPX ydieresis acircumflex -30 KPX ydieresis adieresis -30 KPX ydieresis agrave -30 KPX ydieresis amacron -30 KPX ydieresis aogonek -30 KPX ydieresis aring -30 KPX ydieresis atilde -30 KPX ydieresis comma -80 KPX ydieresis e -10 KPX ydieresis eacute -10 KPX ydieresis ecaron -10 KPX ydieresis ecircumflex -10 KPX ydieresis edieresis -10 KPX ydieresis edotaccent -10 KPX ydieresis egrave -10 KPX ydieresis emacron -10 KPX ydieresis eogonek -10 KPX ydieresis o -25 KPX ydieresis oacute -25 KPX ydieresis ocircumflex -25 KPX ydieresis odieresis -25 KPX ydieresis ograve -25 KPX ydieresis ohungarumlaut -25 KPX ydieresis omacron -25 KPX ydieresis oslash -25 KPX ydieresis otilde -25 KPX ydieresis period -80 KPX z e 10 KPX z eacute 10 KPX z ecaron 10 KPX z ecircumflex 10 KPX z edieresis 10 KPX z edotaccent 10 KPX z egrave 10 KPX z emacron 10 KPX z eogonek 10 KPX zacute e 10 KPX zacute eacute 10 KPX zacute ecaron 10 KPX zacute ecircumflex 10 KPX zacute edieresis 10 KPX zacute edotaccent 10 KPX zacute egrave 10 KPX zacute emacron 10 KPX zacute eogonek 10 KPX zcaron e 10 KPX zcaron eacute 10 KPX zcaron ecaron 10 KPX zcaron ecircumflex 10 KPX zcaron edieresis 10 KPX zcaron edotaccent 10 KPX zcaron egrave 10 KPX zcaron emacron 10 KPX zcaron eogonek 10 KPX zdotaccent e 10 KPX zdotaccent eacute 10 KPX zdotaccent ecaron 10 KPX zdotaccent ecircumflex 10 KPX zdotaccent edieresis 10 KPX zdotaccent edotaccent 10 KPX zdotaccent egrave 10 KPX zdotaccent emacron 10 KPX zdotaccent eogonek 10 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Helvetica-BoldOblique.afm100644 0 0 215000 11000354125 21634 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:45:12 1997 Comment UniqueID 43053 Comment VMusage 14482 68586 FontName Helvetica-BoldOblique FullName Helvetica Bold Oblique FamilyName Helvetica Weight Bold ItalicAngle -12 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -174 -228 1114 962 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 532 Ascender 718 Descender -207 StdHW 118 StdVW 140 StartCharMetrics 315 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ; C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ; C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ; C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ; C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ; C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ; C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ; C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ; C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ; C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ; C 43 ; WX 584 ; N plus ; B 82 0 610 506 ; C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ; C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ; C 46 ; WX 278 ; N period ; B 64 0 245 146 ; C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ; C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ; C 49 ; WX 556 ; N one ; B 173 0 529 710 ; C 50 ; WX 556 ; N two ; B 26 0 619 710 ; C 51 ; WX 556 ; N three ; B 65 -19 608 710 ; C 52 ; WX 556 ; N four ; B 60 0 598 710 ; C 53 ; WX 556 ; N five ; B 64 -19 636 698 ; C 54 ; WX 556 ; N six ; B 85 -19 619 710 ; C 55 ; WX 556 ; N seven ; B 125 0 676 698 ; C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ; C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ; C 58 ; WX 333 ; N colon ; B 92 0 351 512 ; C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ; C 60 ; WX 584 ; N less ; B 82 -8 655 514 ; C 61 ; WX 584 ; N equal ; B 58 87 633 419 ; C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ; C 63 ; WX 611 ; N question ; B 165 0 671 727 ; C 64 ; WX 975 ; N at ; B 186 -19 954 737 ; C 65 ; WX 722 ; N A ; B 20 0 702 718 ; C 66 ; WX 722 ; N B ; B 76 0 764 718 ; C 67 ; WX 722 ; N C ; B 107 -19 789 737 ; C 68 ; WX 722 ; N D ; B 76 0 777 718 ; C 69 ; WX 667 ; N E ; B 76 0 757 718 ; C 70 ; WX 611 ; N F ; B 76 0 740 718 ; C 71 ; WX 778 ; N G ; B 108 -19 817 737 ; C 72 ; WX 722 ; N H ; B 71 0 804 718 ; C 73 ; WX 278 ; N I ; B 64 0 367 718 ; C 74 ; WX 556 ; N J ; B 60 -18 637 718 ; C 75 ; WX 722 ; N K ; B 87 0 858 718 ; C 76 ; WX 611 ; N L ; B 76 0 611 718 ; C 77 ; WX 833 ; N M ; B 69 0 918 718 ; C 78 ; WX 722 ; N N ; B 69 0 807 718 ; C 79 ; WX 778 ; N O ; B 107 -19 823 737 ; C 80 ; WX 667 ; N P ; B 76 0 738 718 ; C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ; C 82 ; WX 722 ; N R ; B 76 0 778 718 ; C 83 ; WX 667 ; N S ; B 81 -19 718 737 ; C 84 ; WX 611 ; N T ; B 140 0 751 718 ; C 85 ; WX 722 ; N U ; B 116 -19 804 718 ; C 86 ; WX 667 ; N V ; B 172 0 801 718 ; C 87 ; WX 944 ; N W ; B 169 0 1082 718 ; C 88 ; WX 667 ; N X ; B 14 0 791 718 ; C 89 ; WX 667 ; N Y ; B 168 0 806 718 ; C 90 ; WX 611 ; N Z ; B 25 0 737 718 ; C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ; C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ; C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ; C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ; C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ; C 97 ; WX 556 ; N a ; B 55 -14 583 546 ; C 98 ; WX 611 ; N b ; B 61 -14 645 718 ; C 99 ; WX 556 ; N c ; B 79 -14 599 546 ; C 100 ; WX 611 ; N d ; B 82 -14 704 718 ; C 101 ; WX 556 ; N e ; B 70 -14 593 546 ; C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ; C 103 ; WX 611 ; N g ; B 38 -217 666 546 ; C 104 ; WX 611 ; N h ; B 65 0 629 718 ; C 105 ; WX 278 ; N i ; B 69 0 363 725 ; C 106 ; WX 278 ; N j ; B -42 -214 363 725 ; C 107 ; WX 556 ; N k ; B 69 0 670 718 ; C 108 ; WX 278 ; N l ; B 69 0 362 718 ; C 109 ; WX 889 ; N m ; B 64 0 909 546 ; C 110 ; WX 611 ; N n ; B 65 0 629 546 ; C 111 ; WX 611 ; N o ; B 82 -14 643 546 ; C 112 ; WX 611 ; N p ; B 18 -207 645 546 ; C 113 ; WX 611 ; N q ; B 80 -207 665 546 ; C 114 ; WX 389 ; N r ; B 64 0 489 546 ; C 115 ; WX 556 ; N s ; B 63 -14 584 546 ; C 116 ; WX 333 ; N t ; B 100 -6 422 676 ; C 117 ; WX 611 ; N u ; B 98 -14 658 532 ; C 118 ; WX 556 ; N v ; B 126 0 656 532 ; C 119 ; WX 778 ; N w ; B 123 0 882 532 ; C 120 ; WX 556 ; N x ; B 15 0 648 532 ; C 121 ; WX 556 ; N y ; B 42 -214 652 532 ; C 122 ; WX 500 ; N z ; B 20 0 583 532 ; C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ; C 124 ; WX 280 ; N bar ; B 36 -225 361 775 ; C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ; C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ; C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ; C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ; C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ; C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ; C 165 ; WX 556 ; N yen ; B 60 0 713 698 ; C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ; C 167 ; WX 556 ; N section ; B 61 -184 598 727 ; C 168 ; WX 556 ; N currency ; B 27 76 680 636 ; C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ; C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ; C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ; C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ; C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ; C 174 ; WX 611 ; N fi ; B 87 0 696 727 ; C 175 ; WX 611 ; N fl ; B 87 0 695 727 ; C 177 ; WX 556 ; N endash ; B 48 227 627 333 ; C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ; C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ; C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ; C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ; C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ; C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ; C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ; C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ; C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ; C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ; C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ; C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ; C 193 ; WX 333 ; N grave ; B 136 604 353 750 ; C 194 ; WX 333 ; N acute ; B 236 604 515 750 ; C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ; C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ; C 197 ; WX 333 ; N macron ; B 122 604 483 678 ; C 198 ; WX 333 ; N breve ; B 156 604 494 750 ; C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ; C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ; C 202 ; WX 333 ; N ring ; B 200 568 420 776 ; C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ; C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ; C 207 ; WX 333 ; N caron ; B 149 604 502 750 ; C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ; C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ; C 227 ; WX 370 ; N ordfeminine ; B 125 401 465 737 ; C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ; C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ; C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ; C 235 ; WX 365 ; N ordmasculine ; B 123 401 485 737 ; C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ; C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ; C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ; C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ; C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ; C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ; C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ; C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ; C -1 ; WX 556 ; N abreve ; B 55 -14 606 750 ; C -1 ; WX 611 ; N uhungarumlaut ; B 98 -14 784 750 ; C -1 ; WX 556 ; N ecaron ; B 70 -14 614 750 ; C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ; C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ; C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ; C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ; C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ; C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ; C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ; C -1 ; WX 556 ; N scommaaccent ; B 63 -228 584 546 ; C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ; C -1 ; WX 722 ; N Uring ; B 116 -19 804 962 ; C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ; C -1 ; WX 556 ; N aogonek ; B 55 -224 583 546 ; C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ; C -1 ; WX 611 ; N uogonek ; B 98 -228 658 532 ; C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ; C -1 ; WX 722 ; N Dcroat ; B 62 0 777 718 ; C -1 ; WX 250 ; N commaaccent ; B 16 -228 188 -50 ; C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ; C -1 ; WX 667 ; N Emacron ; B 76 0 757 864 ; C -1 ; WX 556 ; N ccaron ; B 79 -14 614 750 ; C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ; C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 807 718 ; C -1 ; WX 278 ; N lacute ; B 69 0 528 936 ; C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ; C -1 ; WX 611 ; N Tcommaaccent ; B 140 -228 751 718 ; C -1 ; WX 722 ; N Cacute ; B 107 -19 789 936 ; C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ; C -1 ; WX 667 ; N Edotaccent ; B 76 0 757 915 ; C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ; C -1 ; WX 556 ; N scedilla ; B 63 -228 584 546 ; C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ; C -1 ; WX 494 ; N lozenge ; B 90 0 564 745 ; C -1 ; WX 722 ; N Rcaron ; B 76 0 778 936 ; C -1 ; WX 778 ; N Gcommaaccent ; B 108 -228 817 737 ; C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ; C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ; C -1 ; WX 722 ; N Amacron ; B 20 0 718 864 ; C -1 ; WX 389 ; N rcaron ; B 64 0 530 750 ; C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ; C -1 ; WX 611 ; N Zdotaccent ; B 25 0 737 915 ; C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ; C -1 ; WX 778 ; N Omacron ; B 107 -19 823 864 ; C -1 ; WX 722 ; N Racute ; B 76 0 778 936 ; C -1 ; WX 667 ; N Sacute ; B 81 -19 722 936 ; C -1 ; WX 743 ; N dcaron ; B 82 -14 903 718 ; C -1 ; WX 722 ; N Umacron ; B 116 -19 804 864 ; C -1 ; WX 611 ; N uring ; B 98 -14 658 776 ; C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ; C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ; C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ; C -1 ; WX 722 ; N Abreve ; B 20 0 729 936 ; C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ; C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ; C -1 ; WX 611 ; N Tcaron ; B 140 0 751 936 ; C -1 ; WX 494 ; N partialdiff ; B 43 -21 585 750 ; C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ; C -1 ; WX 722 ; N Nacute ; B 69 0 807 936 ; C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ; C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ; C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ; C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ; C -1 ; WX 556 ; N cacute ; B 79 -14 627 750 ; C -1 ; WX 611 ; N nacute ; B 65 0 654 750 ; C -1 ; WX 611 ; N umacron ; B 98 -14 658 678 ; C -1 ; WX 722 ; N Ncaron ; B 69 0 807 936 ; C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ; C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ; C -1 ; WX 280 ; N brokenbar ; B 52 -150 345 700 ; C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ; C -1 ; WX 778 ; N Gbreve ; B 108 -19 817 936 ; C -1 ; WX 278 ; N Idotaccent ; B 64 0 397 915 ; C -1 ; WX 600 ; N summation ; B 14 -10 670 706 ; C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ; C -1 ; WX 389 ; N racute ; B 64 0 543 750 ; C -1 ; WX 611 ; N omacron ; B 82 -14 643 678 ; C -1 ; WX 611 ; N Zacute ; B 25 0 737 936 ; C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 629 704 ; C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ; C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ; C -1 ; WX 278 ; N lcommaaccent ; B 30 -228 362 718 ; C -1 ; WX 389 ; N tcaron ; B 100 -6 608 878 ; C -1 ; WX 556 ; N eogonek ; B 70 -228 593 546 ; C -1 ; WX 722 ; N Uogonek ; B 116 -228 804 718 ; C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ; C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ; C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ; C -1 ; WX 500 ; N zacute ; B 20 0 599 750 ; C -1 ; WX 278 ; N iogonek ; B -14 -224 363 725 ; C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ; C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ; C -1 ; WX 556 ; N amacron ; B 55 -14 595 678 ; C -1 ; WX 556 ; N sacute ; B 63 -14 627 750 ; C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ; C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ; C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ; C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ; C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ; C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ; C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ; C -1 ; WX 611 ; N ohungarumlaut ; B 82 -14 784 750 ; C -1 ; WX 667 ; N Eogonek ; B 76 -224 757 718 ; C -1 ; WX 611 ; N dcroat ; B 82 -14 789 718 ; C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ; C -1 ; WX 667 ; N Scedilla ; B 81 -228 718 737 ; C -1 ; WX 400 ; N lcaron ; B 69 0 561 718 ; C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 858 718 ; C -1 ; WX 611 ; N Lacute ; B 76 0 611 936 ; C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ; C -1 ; WX 556 ; N edotaccent ; B 70 -14 593 729 ; C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ; C -1 ; WX 278 ; N Imacron ; B 64 0 496 864 ; C -1 ; WX 611 ; N Lcaron ; B 76 0 643 718 ; C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ; C -1 ; WX 549 ; N lessequal ; B 29 0 676 704 ; C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ; C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 116 -19 880 936 ; C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ; C -1 ; WX 556 ; N emacron ; B 70 -14 595 678 ; C -1 ; WX 611 ; N gbreve ; B 38 -217 666 750 ; C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ; C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ; C -1 ; WX 667 ; N Scommaaccent ; B 81 -228 718 737 ; C -1 ; WX 778 ; N Ohungarumlaut ; B 107 -19 908 936 ; C -1 ; WX 400 ; N degree ; B 175 426 467 712 ; C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ; C -1 ; WX 722 ; N Ccaron ; B 107 -19 789 936 ; C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ; C -1 ; WX 549 ; N radical ; B 112 -46 689 850 ; C -1 ; WX 722 ; N Dcaron ; B 76 0 777 936 ; C -1 ; WX 389 ; N rcommaaccent ; B 26 -228 489 546 ; C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ; C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ; C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 778 718 ; C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 611 718 ; C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ; C -1 ; WX 722 ; N Aogonek ; B 20 -224 702 718 ; C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ; C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ; C -1 ; WX 500 ; N zdotaccent ; B 20 0 583 729 ; C -1 ; WX 667 ; N Ecaron ; B 76 0 757 936 ; C -1 ; WX 278 ; N Iogonek ; B -41 -228 367 718 ; C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 670 718 ; C -1 ; WX 584 ; N minus ; B 82 197 610 309 ; C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ; C -1 ; WX 611 ; N ncaron ; B 65 0 641 750 ; C -1 ; WX 333 ; N tcommaaccent ; B 58 -228 422 676 ; C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ; C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ; C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ; C -1 ; WX 549 ; N notequal ; B 32 -49 630 570 ; C -1 ; WX 611 ; N gcommaaccent ; B 38 -217 666 850 ; C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ; C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ; C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 629 546 ; C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ; C -1 ; WX 278 ; N imacron ; B 69 0 429 678 ; C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2481 KPX A C -40 KPX A Cacute -40 KPX A Ccaron -40 KPX A Ccedilla -40 KPX A G -50 KPX A Gbreve -50 KPX A Gcommaaccent -50 KPX A O -40 KPX A Oacute -40 KPX A Ocircumflex -40 KPX A Odieresis -40 KPX A Ograve -40 KPX A Ohungarumlaut -40 KPX A Omacron -40 KPX A Oslash -40 KPX A Otilde -40 KPX A Q -40 KPX A T -90 KPX A Tcaron -90 KPX A Tcommaaccent -90 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -80 KPX A W -60 KPX A Y -110 KPX A Yacute -110 KPX A Ydieresis -110 KPX A u -30 KPX A uacute -30 KPX A ucircumflex -30 KPX A udieresis -30 KPX A ugrave -30 KPX A uhungarumlaut -30 KPX A umacron -30 KPX A uogonek -30 KPX A uring -30 KPX A v -40 KPX A w -30 KPX A y -30 KPX A yacute -30 KPX A ydieresis -30 KPX Aacute C -40 KPX Aacute Cacute -40 KPX Aacute Ccaron -40 KPX Aacute Ccedilla -40 KPX Aacute G -50 KPX Aacute Gbreve -50 KPX Aacute Gcommaaccent -50 KPX Aacute O -40 KPX Aacute Oacute -40 KPX Aacute Ocircumflex -40 KPX Aacute Odieresis -40 KPX Aacute Ograve -40 KPX Aacute Ohungarumlaut -40 KPX Aacute Omacron -40 KPX Aacute Oslash -40 KPX Aacute Otilde -40 KPX Aacute Q -40 KPX Aacute T -90 KPX Aacute Tcaron -90 KPX Aacute Tcommaaccent -90 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -80 KPX Aacute W -60 KPX Aacute Y -110 KPX Aacute Yacute -110 KPX Aacute Ydieresis -110 KPX Aacute u -30 KPX Aacute uacute -30 KPX Aacute ucircumflex -30 KPX Aacute udieresis -30 KPX Aacute ugrave -30 KPX Aacute uhungarumlaut -30 KPX Aacute umacron -30 KPX Aacute uogonek -30 KPX Aacute uring -30 KPX Aacute v -40 KPX Aacute w -30 KPX Aacute y -30 KPX Aacute yacute -30 KPX Aacute ydieresis -30 KPX Abreve C -40 KPX Abreve Cacute -40 KPX Abreve Ccaron -40 KPX Abreve Ccedilla -40 KPX Abreve G -50 KPX Abreve Gbreve -50 KPX Abreve Gcommaaccent -50 KPX Abreve O -40 KPX Abreve Oacute -40 KPX Abreve Ocircumflex -40 KPX Abreve Odieresis -40 KPX Abreve Ograve -40 KPX Abreve Ohungarumlaut -40 KPX Abreve Omacron -40 KPX Abreve Oslash -40 KPX Abreve Otilde -40 KPX Abreve Q -40 KPX Abreve T -90 KPX Abreve Tcaron -90 KPX Abreve Tcommaaccent -90 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -80 KPX Abreve W -60 KPX Abreve Y -110 KPX Abreve Yacute -110 KPX Abreve Ydieresis -110 KPX Abreve u -30 KPX Abreve uacute -30 KPX Abreve ucircumflex -30 KPX Abreve udieresis -30 KPX Abreve ugrave -30 KPX Abreve uhungarumlaut -30 KPX Abreve umacron -30 KPX Abreve uogonek -30 KPX Abreve uring -30 KPX Abreve v -40 KPX Abreve w -30 KPX Abreve y -30 KPX Abreve yacute -30 KPX Abreve ydieresis -30 KPX Acircumflex C -40 KPX Acircumflex Cacute -40 KPX Acircumflex Ccaron -40 KPX Acircumflex Ccedilla -40 KPX Acircumflex G -50 KPX Acircumflex Gbreve -50 KPX Acircumflex Gcommaaccent -50 KPX Acircumflex O -40 KPX Acircumflex Oacute -40 KPX Acircumflex Ocircumflex -40 KPX Acircumflex Odieresis -40 KPX Acircumflex Ograve -40 KPX Acircumflex Ohungarumlaut -40 KPX Acircumflex Omacron -40 KPX Acircumflex Oslash -40 KPX Acircumflex Otilde -40 KPX Acircumflex Q -40 KPX Acircumflex T -90 KPX Acircumflex Tcaron -90 KPX Acircumflex Tcommaaccent -90 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -80 KPX Acircumflex W -60 KPX Acircumflex Y -110 KPX Acircumflex Yacute -110 KPX Acircumflex Ydieresis -110 KPX Acircumflex u -30 KPX Acircumflex uacute -30 KPX Acircumflex ucircumflex -30 KPX Acircumflex udieresis -30 KPX Acircumflex ugrave -30 KPX Acircumflex uhungarumlaut -30 KPX Acircumflex umacron -30 KPX Acircumflex uogonek -30 KPX Acircumflex uring -30 KPX Acircumflex v -40 KPX Acircumflex w -30 KPX Acircumflex y -30 KPX Acircumflex yacute -30 KPX Acircumflex ydieresis -30 KPX Adieresis C -40 KPX Adieresis Cacute -40 KPX Adieresis Ccaron -40 KPX Adieresis Ccedilla -40 KPX Adieresis G -50 KPX Adieresis Gbreve -50 KPX Adieresis Gcommaaccent -50 KPX Adieresis O -40 KPX Adieresis Oacute -40 KPX Adieresis Ocircumflex -40 KPX Adieresis Odieresis -40 KPX Adieresis Ograve -40 KPX Adieresis Ohungarumlaut -40 KPX Adieresis Omacron -40 KPX Adieresis Oslash -40 KPX Adieresis Otilde -40 KPX Adieresis Q -40 KPX Adieresis T -90 KPX Adieresis Tcaron -90 KPX Adieresis Tcommaaccent -90 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -80 KPX Adieresis W -60 KPX Adieresis Y -110 KPX Adieresis Yacute -110 KPX Adieresis Ydieresis -110 KPX Adieresis u -30 KPX Adieresis uacute -30 KPX Adieresis ucircumflex -30 KPX Adieresis udieresis -30 KPX Adieresis ugrave -30 KPX Adieresis uhungarumlaut -30 KPX Adieresis umacron -30 KPX Adieresis uogonek -30 KPX Adieresis uring -30 KPX Adieresis v -40 KPX Adieresis w -30 KPX Adieresis y -30 KPX Adieresis yacute -30 KPX Adieresis ydieresis -30 KPX Agrave C -40 KPX Agrave Cacute -40 KPX Agrave Ccaron -40 KPX Agrave Ccedilla -40 KPX Agrave G -50 KPX Agrave Gbreve -50 KPX Agrave Gcommaaccent -50 KPX Agrave O -40 KPX Agrave Oacute -40 KPX Agrave Ocircumflex -40 KPX Agrave Odieresis -40 KPX Agrave Ograve -40 KPX Agrave Ohungarumlaut -40 KPX Agrave Omacron -40 KPX Agrave Oslash -40 KPX Agrave Otilde -40 KPX Agrave Q -40 KPX Agrave T -90 KPX Agrave Tcaron -90 KPX Agrave Tcommaaccent -90 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -80 KPX Agrave W -60 KPX Agrave Y -110 KPX Agrave Yacute -110 KPX Agrave Ydieresis -110 KPX Agrave u -30 KPX Agrave uacute -30 KPX Agrave ucircumflex -30 KPX Agrave udieresis -30 KPX Agrave ugrave -30 KPX Agrave uhungarumlaut -30 KPX Agrave umacron -30 KPX Agrave uogonek -30 KPX Agrave uring -30 KPX Agrave v -40 KPX Agrave w -30 KPX Agrave y -30 KPX Agrave yacute -30 KPX Agrave ydieresis -30 KPX Amacron C -40 KPX Amacron Cacute -40 KPX Amacron Ccaron -40 KPX Amacron Ccedilla -40 KPX Amacron G -50 KPX Amacron Gbreve -50 KPX Amacron Gcommaaccent -50 KPX Amacron O -40 KPX Amacron Oacute -40 KPX Amacron Ocircumflex -40 KPX Amacron Odieresis -40 KPX Amacron Ograve -40 KPX Amacron Ohungarumlaut -40 KPX Amacron Omacron -40 KPX Amacron Oslash -40 KPX Amacron Otilde -40 KPX Amacron Q -40 KPX Amacron T -90 KPX Amacron Tcaron -90 KPX Amacron Tcommaaccent -90 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -80 KPX Amacron W -60 KPX Amacron Y -110 KPX Amacron Yacute -110 KPX Amacron Ydieresis -110 KPX Amacron u -30 KPX Amacron uacute -30 KPX Amacron ucircumflex -30 KPX Amacron udieresis -30 KPX Amacron ugrave -30 KPX Amacron uhungarumlaut -30 KPX Amacron umacron -30 KPX Amacron uogonek -30 KPX Amacron uring -30 KPX Amacron v -40 KPX Amacron w -30 KPX Amacron y -30 KPX Amacron yacute -30 KPX Amacron ydieresis -30 KPX Aogonek C -40 KPX Aogonek Cacute -40 KPX Aogonek Ccaron -40 KPX Aogonek Ccedilla -40 KPX Aogonek G -50 KPX Aogonek Gbreve -50 KPX Aogonek Gcommaaccent -50 KPX Aogonek O -40 KPX Aogonek Oacute -40 KPX Aogonek Ocircumflex -40 KPX Aogonek Odieresis -40 KPX Aogonek Ograve -40 KPX Aogonek Ohungarumlaut -40 KPX Aogonek Omacron -40 KPX Aogonek Oslash -40 KPX Aogonek Otilde -40 KPX Aogonek Q -40 KPX Aogonek T -90 KPX Aogonek Tcaron -90 KPX Aogonek Tcommaaccent -90 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -80 KPX Aogonek W -60 KPX Aogonek Y -110 KPX Aogonek Yacute -110 KPX Aogonek Ydieresis -110 KPX Aogonek u -30 KPX Aogonek uacute -30 KPX Aogonek ucircumflex -30 KPX Aogonek udieresis -30 KPX Aogonek ugrave -30 KPX Aogonek uhungarumlaut -30 KPX Aogonek umacron -30 KPX Aogonek uogonek -30 KPX Aogonek uring -30 KPX Aogonek v -40 KPX Aogonek w -30 KPX Aogonek y -30 KPX Aogonek yacute -30 KPX Aogonek ydieresis -30 KPX Aring C -40 KPX Aring Cacute -40 KPX Aring Ccaron -40 KPX Aring Ccedilla -40 KPX Aring G -50 KPX Aring Gbreve -50 KPX Aring Gcommaaccent -50 KPX Aring O -40 KPX Aring Oacute -40 KPX Aring Ocircumflex -40 KPX Aring Odieresis -40 KPX Aring Ograve -40 KPX Aring Ohungarumlaut -40 KPX Aring Omacron -40 KPX Aring Oslash -40 KPX Aring Otilde -40 KPX Aring Q -40 KPX Aring T -90 KPX Aring Tcaron -90 KPX Aring Tcommaaccent -90 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -80 KPX Aring W -60 KPX Aring Y -110 KPX Aring Yacute -110 KPX Aring Ydieresis -110 KPX Aring u -30 KPX Aring uacute -30 KPX Aring ucircumflex -30 KPX Aring udieresis -30 KPX Aring ugrave -30 KPX Aring uhungarumlaut -30 KPX Aring umacron -30 KPX Aring uogonek -30 KPX Aring uring -30 KPX Aring v -40 KPX Aring w -30 KPX Aring y -30 KPX Aring yacute -30 KPX Aring ydieresis -30 KPX Atilde C -40 KPX Atilde Cacute -40 KPX Atilde Ccaron -40 KPX Atilde Ccedilla -40 KPX Atilde G -50 KPX Atilde Gbreve -50 KPX Atilde Gcommaaccent -50 KPX Atilde O -40 KPX Atilde Oacute -40 KPX Atilde Ocircumflex -40 KPX Atilde Odieresis -40 KPX Atilde Ograve -40 KPX Atilde Ohungarumlaut -40 KPX Atilde Omacron -40 KPX Atilde Oslash -40 KPX Atilde Otilde -40 KPX Atilde Q -40 KPX Atilde T -90 KPX Atilde Tcaron -90 KPX Atilde Tcommaaccent -90 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -80 KPX Atilde W -60 KPX Atilde Y -110 KPX Atilde Yacute -110 KPX Atilde Ydieresis -110 KPX Atilde u -30 KPX Atilde uacute -30 KPX Atilde ucircumflex -30 KPX Atilde udieresis -30 KPX Atilde ugrave -30 KPX Atilde uhungarumlaut -30 KPX Atilde umacron -30 KPX Atilde uogonek -30 KPX Atilde uring -30 KPX Atilde v -40 KPX Atilde w -30 KPX Atilde y -30 KPX Atilde yacute -30 KPX Atilde ydieresis -30 KPX B A -30 KPX B Aacute -30 KPX B Abreve -30 KPX B Acircumflex -30 KPX B Adieresis -30 KPX B Agrave -30 KPX B Amacron -30 KPX B Aogonek -30 KPX B Aring -30 KPX B Atilde -30 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -40 KPX D Aacute -40 KPX D Abreve -40 KPX D Acircumflex -40 KPX D Adieresis -40 KPX D Agrave -40 KPX D Amacron -40 KPX D Aogonek -40 KPX D Aring -40 KPX D Atilde -40 KPX D V -40 KPX D W -40 KPX D Y -70 KPX D Yacute -70 KPX D Ydieresis -70 KPX D comma -30 KPX D period -30 KPX Dcaron A -40 KPX Dcaron Aacute -40 KPX Dcaron Abreve -40 KPX Dcaron Acircumflex -40 KPX Dcaron Adieresis -40 KPX Dcaron Agrave -40 KPX Dcaron Amacron -40 KPX Dcaron Aogonek -40 KPX Dcaron Aring -40 KPX Dcaron Atilde -40 KPX Dcaron V -40 KPX Dcaron W -40 KPX Dcaron Y -70 KPX Dcaron Yacute -70 KPX Dcaron Ydieresis -70 KPX Dcaron comma -30 KPX Dcaron period -30 KPX Dcroat A -40 KPX Dcroat Aacute -40 KPX Dcroat Abreve -40 KPX Dcroat Acircumflex -40 KPX Dcroat Adieresis -40 KPX Dcroat Agrave -40 KPX Dcroat Amacron -40 KPX Dcroat Aogonek -40 KPX Dcroat Aring -40 KPX Dcroat Atilde -40 KPX Dcroat V -40 KPX Dcroat W -40 KPX Dcroat Y -70 KPX Dcroat Yacute -70 KPX Dcroat Ydieresis -70 KPX Dcroat comma -30 KPX Dcroat period -30 KPX F A -80 KPX F Aacute -80 KPX F Abreve -80 KPX F Acircumflex -80 KPX F Adieresis -80 KPX F Agrave -80 KPX F Amacron -80 KPX F Aogonek -80 KPX F Aring -80 KPX F Atilde -80 KPX F a -20 KPX F aacute -20 KPX F abreve -20 KPX F acircumflex -20 KPX F adieresis -20 KPX F agrave -20 KPX F amacron -20 KPX F aogonek -20 KPX F aring -20 KPX F atilde -20 KPX F comma -100 KPX F period -100 KPX J A -20 KPX J Aacute -20 KPX J Abreve -20 KPX J Acircumflex -20 KPX J Adieresis -20 KPX J Agrave -20 KPX J Amacron -20 KPX J Aogonek -20 KPX J Aring -20 KPX J Atilde -20 KPX J comma -20 KPX J period -20 KPX J u -20 KPX J uacute -20 KPX J ucircumflex -20 KPX J udieresis -20 KPX J ugrave -20 KPX J uhungarumlaut -20 KPX J umacron -20 KPX J uogonek -20 KPX J uring -20 KPX K O -30 KPX K Oacute -30 KPX K Ocircumflex -30 KPX K Odieresis -30 KPX K Ograve -30 KPX K Ohungarumlaut -30 KPX K Omacron -30 KPX K Oslash -30 KPX K Otilde -30 KPX K e -15 KPX K eacute -15 KPX K ecaron -15 KPX K ecircumflex -15 KPX K edieresis -15 KPX K edotaccent -15 KPX K egrave -15 KPX K emacron -15 KPX K eogonek -15 KPX K o -35 KPX K oacute -35 KPX K ocircumflex -35 KPX K odieresis -35 KPX K ograve -35 KPX K ohungarumlaut -35 KPX K omacron -35 KPX K oslash -35 KPX K otilde -35 KPX K u -30 KPX K uacute -30 KPX K ucircumflex -30 KPX K udieresis -30 KPX K ugrave -30 KPX K uhungarumlaut -30 KPX K umacron -30 KPX K uogonek -30 KPX K uring -30 KPX K y -40 KPX K yacute -40 KPX K ydieresis -40 KPX Kcommaaccent O -30 KPX Kcommaaccent Oacute -30 KPX Kcommaaccent Ocircumflex -30 KPX Kcommaaccent Odieresis -30 KPX Kcommaaccent Ograve -30 KPX Kcommaaccent Ohungarumlaut -30 KPX Kcommaaccent Omacron -30 KPX Kcommaaccent Oslash -30 KPX Kcommaaccent Otilde -30 KPX Kcommaaccent e -15 KPX Kcommaaccent eacute -15 KPX Kcommaaccent ecaron -15 KPX Kcommaaccent ecircumflex -15 KPX Kcommaaccent edieresis -15 KPX Kcommaaccent edotaccent -15 KPX Kcommaaccent egrave -15 KPX Kcommaaccent emacron -15 KPX Kcommaaccent eogonek -15 KPX Kcommaaccent o -35 KPX Kcommaaccent oacute -35 KPX Kcommaaccent ocircumflex -35 KPX Kcommaaccent odieresis -35 KPX Kcommaaccent ograve -35 KPX Kcommaaccent ohungarumlaut -35 KPX Kcommaaccent omacron -35 KPX Kcommaaccent oslash -35 KPX Kcommaaccent otilde -35 KPX Kcommaaccent u -30 KPX Kcommaaccent uacute -30 KPX Kcommaaccent ucircumflex -30 KPX Kcommaaccent udieresis -30 KPX Kcommaaccent ugrave -30 KPX Kcommaaccent uhungarumlaut -30 KPX Kcommaaccent umacron -30 KPX Kcommaaccent uogonek -30 KPX Kcommaaccent uring -30 KPX Kcommaaccent y -40 KPX Kcommaaccent yacute -40 KPX Kcommaaccent ydieresis -40 KPX L T -90 KPX L Tcaron -90 KPX L Tcommaaccent -90 KPX L V -110 KPX L W -80 KPX L Y -120 KPX L Yacute -120 KPX L Ydieresis -120 KPX L quotedblright -140 KPX L quoteright -140 KPX L y -30 KPX L yacute -30 KPX L ydieresis -30 KPX Lacute T -90 KPX Lacute Tcaron -90 KPX Lacute Tcommaaccent -90 KPX Lacute V -110 KPX Lacute W -80 KPX Lacute Y -120 KPX Lacute Yacute -120 KPX Lacute Ydieresis -120 KPX Lacute quotedblright -140 KPX Lacute quoteright -140 KPX Lacute y -30 KPX Lacute yacute -30 KPX Lacute ydieresis -30 KPX Lcommaaccent T -90 KPX Lcommaaccent Tcaron -90 KPX Lcommaaccent Tcommaaccent -90 KPX Lcommaaccent V -110 KPX Lcommaaccent W -80 KPX Lcommaaccent Y -120 KPX Lcommaaccent Yacute -120 KPX Lcommaaccent Ydieresis -120 KPX Lcommaaccent quotedblright -140 KPX Lcommaaccent quoteright -140 KPX Lcommaaccent y -30 KPX Lcommaaccent yacute -30 KPX Lcommaaccent ydieresis -30 KPX Lslash T -90 KPX Lslash Tcaron -90 KPX Lslash Tcommaaccent -90 KPX Lslash V -110 KPX Lslash W -80 KPX Lslash Y -120 KPX Lslash Yacute -120 KPX Lslash Ydieresis -120 KPX Lslash quotedblright -140 KPX Lslash quoteright -140 KPX Lslash y -30 KPX Lslash yacute -30 KPX Lslash ydieresis -30 KPX O A -50 KPX O Aacute -50 KPX O Abreve -50 KPX O Acircumflex -50 KPX O Adieresis -50 KPX O Agrave -50 KPX O Amacron -50 KPX O Aogonek -50 KPX O Aring -50 KPX O Atilde -50 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -50 KPX O X -50 KPX O Y -70 KPX O Yacute -70 KPX O Ydieresis -70 KPX O comma -40 KPX O period -40 KPX Oacute A -50 KPX Oacute Aacute -50 KPX Oacute Abreve -50 KPX Oacute Acircumflex -50 KPX Oacute Adieresis -50 KPX Oacute Agrave -50 KPX Oacute Amacron -50 KPX Oacute Aogonek -50 KPX Oacute Aring -50 KPX Oacute Atilde -50 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -50 KPX Oacute X -50 KPX Oacute Y -70 KPX Oacute Yacute -70 KPX Oacute Ydieresis -70 KPX Oacute comma -40 KPX Oacute period -40 KPX Ocircumflex A -50 KPX Ocircumflex Aacute -50 KPX Ocircumflex Abreve -50 KPX Ocircumflex Acircumflex -50 KPX Ocircumflex Adieresis -50 KPX Ocircumflex Agrave -50 KPX Ocircumflex Amacron -50 KPX Ocircumflex Aogonek -50 KPX Ocircumflex Aring -50 KPX Ocircumflex Atilde -50 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -50 KPX Ocircumflex X -50 KPX Ocircumflex Y -70 KPX Ocircumflex Yacute -70 KPX Ocircumflex Ydieresis -70 KPX Ocircumflex comma -40 KPX Ocircumflex period -40 KPX Odieresis A -50 KPX Odieresis Aacute -50 KPX Odieresis Abreve -50 KPX Odieresis Acircumflex -50 KPX Odieresis Adieresis -50 KPX Odieresis Agrave -50 KPX Odieresis Amacron -50 KPX Odieresis Aogonek -50 KPX Odieresis Aring -50 KPX Odieresis Atilde -50 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -50 KPX Odieresis X -50 KPX Odieresis Y -70 KPX Odieresis Yacute -70 KPX Odieresis Ydieresis -70 KPX Odieresis comma -40 KPX Odieresis period -40 KPX Ograve A -50 KPX Ograve Aacute -50 KPX Ograve Abreve -50 KPX Ograve Acircumflex -50 KPX Ograve Adieresis -50 KPX Ograve Agrave -50 KPX Ograve Amacron -50 KPX Ograve Aogonek -50 KPX Ograve Aring -50 KPX Ograve Atilde -50 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -50 KPX Ograve X -50 KPX Ograve Y -70 KPX Ograve Yacute -70 KPX Ograve Ydieresis -70 KPX Ograve comma -40 KPX Ograve period -40 KPX Ohungarumlaut A -50 KPX Ohungarumlaut Aacute -50 KPX Ohungarumlaut Abreve -50 KPX Ohungarumlaut Acircumflex -50 KPX Ohungarumlaut Adieresis -50 KPX Ohungarumlaut Agrave -50 KPX Ohungarumlaut Amacron -50 KPX Ohungarumlaut Aogonek -50 KPX Ohungarumlaut Aring -50 KPX Ohungarumlaut Atilde -50 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -50 KPX Ohungarumlaut X -50 KPX Ohungarumlaut Y -70 KPX Ohungarumlaut Yacute -70 KPX Ohungarumlaut Ydieresis -70 KPX Ohungarumlaut comma -40 KPX Ohungarumlaut period -40 KPX Omacron A -50 KPX Omacron Aacute -50 KPX Omacron Abreve -50 KPX Omacron Acircumflex -50 KPX Omacron Adieresis -50 KPX Omacron Agrave -50 KPX Omacron Amacron -50 KPX Omacron Aogonek -50 KPX Omacron Aring -50 KPX Omacron Atilde -50 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -50 KPX Omacron X -50 KPX Omacron Y -70 KPX Omacron Yacute -70 KPX Omacron Ydieresis -70 KPX Omacron comma -40 KPX Omacron period -40 KPX Oslash A -50 KPX Oslash Aacute -50 KPX Oslash Abreve -50 KPX Oslash Acircumflex -50 KPX Oslash Adieresis -50 KPX Oslash Agrave -50 KPX Oslash Amacron -50 KPX Oslash Aogonek -50 KPX Oslash Aring -50 KPX Oslash Atilde -50 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -50 KPX Oslash X -50 KPX Oslash Y -70 KPX Oslash Yacute -70 KPX Oslash Ydieresis -70 KPX Oslash comma -40 KPX Oslash period -40 KPX Otilde A -50 KPX Otilde Aacute -50 KPX Otilde Abreve -50 KPX Otilde Acircumflex -50 KPX Otilde Adieresis -50 KPX Otilde Agrave -50 KPX Otilde Amacron -50 KPX Otilde Aogonek -50 KPX Otilde Aring -50 KPX Otilde Atilde -50 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -50 KPX Otilde X -50 KPX Otilde Y -70 KPX Otilde Yacute -70 KPX Otilde Ydieresis -70 KPX Otilde comma -40 KPX Otilde period -40 KPX P A -100 KPX P Aacute -100 KPX P Abreve -100 KPX P Acircumflex -100 KPX P Adieresis -100 KPX P Agrave -100 KPX P Amacron -100 KPX P Aogonek -100 KPX P Aring -100 KPX P Atilde -100 KPX P a -30 KPX P aacute -30 KPX P abreve -30 KPX P acircumflex -30 KPX P adieresis -30 KPX P agrave -30 KPX P amacron -30 KPX P aogonek -30 KPX P aring -30 KPX P atilde -30 KPX P comma -120 KPX P e -30 KPX P eacute -30 KPX P ecaron -30 KPX P ecircumflex -30 KPX P edieresis -30 KPX P edotaccent -30 KPX P egrave -30 KPX P emacron -30 KPX P eogonek -30 KPX P o -40 KPX P oacute -40 KPX P ocircumflex -40 KPX P odieresis -40 KPX P ograve -40 KPX P ohungarumlaut -40 KPX P omacron -40 KPX P oslash -40 KPX P otilde -40 KPX P period -120 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX Q comma 20 KPX Q period 20 KPX R O -20 KPX R Oacute -20 KPX R Ocircumflex -20 KPX R Odieresis -20 KPX R Ograve -20 KPX R Ohungarumlaut -20 KPX R Omacron -20 KPX R Oslash -20 KPX R Otilde -20 KPX R T -20 KPX R Tcaron -20 KPX R Tcommaaccent -20 KPX R U -20 KPX R Uacute -20 KPX R Ucircumflex -20 KPX R Udieresis -20 KPX R Ugrave -20 KPX R Uhungarumlaut -20 KPX R Umacron -20 KPX R Uogonek -20 KPX R Uring -20 KPX R V -50 KPX R W -40 KPX R Y -50 KPX R Yacute -50 KPX R Ydieresis -50 KPX Racute O -20 KPX Racute Oacute -20 KPX Racute Ocircumflex -20 KPX Racute Odieresis -20 KPX Racute Ograve -20 KPX Racute Ohungarumlaut -20 KPX Racute Omacron -20 KPX Racute Oslash -20 KPX Racute Otilde -20 KPX Racute T -20 KPX Racute Tcaron -20 KPX Racute Tcommaaccent -20 KPX Racute U -20 KPX Racute Uacute -20 KPX Racute Ucircumflex -20 KPX Racute Udieresis -20 KPX Racute Ugrave -20 KPX Racute Uhungarumlaut -20 KPX Racute Umacron -20 KPX Racute Uogonek -20 KPX Racute Uring -20 KPX Racute V -50 KPX Racute W -40 KPX Racute Y -50 KPX Racute Yacute -50 KPX Racute Ydieresis -50 KPX Rcaron O -20 KPX Rcaron Oacute -20 KPX Rcaron Ocircumflex -20 KPX Rcaron Odieresis -20 KPX Rcaron Ograve -20 KPX Rcaron Ohungarumlaut -20 KPX Rcaron Omacron -20 KPX Rcaron Oslash -20 KPX Rcaron Otilde -20 KPX Rcaron T -20 KPX Rcaron Tcaron -20 KPX Rcaron Tcommaaccent -20 KPX Rcaron U -20 KPX Rcaron Uacute -20 KPX Rcaron Ucircumflex -20 KPX Rcaron Udieresis -20 KPX Rcaron Ugrave -20 KPX Rcaron Uhungarumlaut -20 KPX Rcaron Umacron -20 KPX Rcaron Uogonek -20 KPX Rcaron Uring -20 KPX Rcaron V -50 KPX Rcaron W -40 KPX Rcaron Y -50 KPX Rcaron Yacute -50 KPX Rcaron Ydieresis -50 KPX Rcommaaccent O -20 KPX Rcommaaccent Oacute -20 KPX Rcommaaccent Ocircumflex -20 KPX Rcommaaccent Odieresis -20 KPX Rcommaaccent Ograve -20 KPX Rcommaaccent Ohungarumlaut -20 KPX Rcommaaccent Omacron -20 KPX Rcommaaccent Oslash -20 KPX Rcommaaccent Otilde -20 KPX Rcommaaccent T -20 KPX Rcommaaccent Tcaron -20 KPX Rcommaaccent Tcommaaccent -20 KPX Rcommaaccent U -20 KPX Rcommaaccent Uacute -20 KPX Rcommaaccent Ucircumflex -20 KPX Rcommaaccent Udieresis -20 KPX Rcommaaccent Ugrave -20 KPX Rcommaaccent Uhungarumlaut -20 KPX Rcommaaccent Umacron -20 KPX Rcommaaccent Uogonek -20 KPX Rcommaaccent Uring -20 KPX Rcommaaccent V -50 KPX Rcommaaccent W -40 KPX Rcommaaccent Y -50 KPX Rcommaaccent Yacute -50 KPX Rcommaaccent Ydieresis -50 KPX T A -90 KPX T Aacute -90 KPX T Abreve -90 KPX T Acircumflex -90 KPX T Adieresis -90 KPX T Agrave -90 KPX T Amacron -90 KPX T Aogonek -90 KPX T Aring -90 KPX T Atilde -90 KPX T O -40 KPX T Oacute -40 KPX T Ocircumflex -40 KPX T Odieresis -40 KPX T Ograve -40 KPX T Ohungarumlaut -40 KPX T Omacron -40 KPX T Oslash -40 KPX T Otilde -40 KPX T a -80 KPX T aacute -80 KPX T abreve -80 KPX T acircumflex -80 KPX T adieresis -80 KPX T agrave -80 KPX T amacron -80 KPX T aogonek -80 KPX T aring -80 KPX T atilde -80 KPX T colon -40 KPX T comma -80 KPX T e -60 KPX T eacute -60 KPX T ecaron -60 KPX T ecircumflex -60 KPX T edieresis -60 KPX T edotaccent -60 KPX T egrave -60 KPX T emacron -60 KPX T eogonek -60 KPX T hyphen -120 KPX T o -80 KPX T oacute -80 KPX T ocircumflex -80 KPX T odieresis -80 KPX T ograve -80 KPX T ohungarumlaut -80 KPX T omacron -80 KPX T oslash -80 KPX T otilde -80 KPX T period -80 KPX T r -80 KPX T racute -80 KPX T rcommaaccent -80 KPX T semicolon -40 KPX T u -90 KPX T uacute -90 KPX T ucircumflex -90 KPX T udieresis -90 KPX T ugrave -90 KPX T uhungarumlaut -90 KPX T umacron -90 KPX T uogonek -90 KPX T uring -90 KPX T w -60 KPX T y -60 KPX T yacute -60 KPX T ydieresis -60 KPX Tcaron A -90 KPX Tcaron Aacute -90 KPX Tcaron Abreve -90 KPX Tcaron Acircumflex -90 KPX Tcaron Adieresis -90 KPX Tcaron Agrave -90 KPX Tcaron Amacron -90 KPX Tcaron Aogonek -90 KPX Tcaron Aring -90 KPX Tcaron Atilde -90 KPX Tcaron O -40 KPX Tcaron Oacute -40 KPX Tcaron Ocircumflex -40 KPX Tcaron Odieresis -40 KPX Tcaron Ograve -40 KPX Tcaron Ohungarumlaut -40 KPX Tcaron Omacron -40 KPX Tcaron Oslash -40 KPX Tcaron Otilde -40 KPX Tcaron a -80 KPX Tcaron aacute -80 KPX Tcaron abreve -80 KPX Tcaron acircumflex -80 KPX Tcaron adieresis -80 KPX Tcaron agrave -80 KPX Tcaron amacron -80 KPX Tcaron aogonek -80 KPX Tcaron aring -80 KPX Tcaron atilde -80 KPX Tcaron colon -40 KPX Tcaron comma -80 KPX Tcaron e -60 KPX Tcaron eacute -60 KPX Tcaron ecaron -60 KPX Tcaron ecircumflex -60 KPX Tcaron edieresis -60 KPX Tcaron edotaccent -60 KPX Tcaron egrave -60 KPX Tcaron emacron -60 KPX Tcaron eogonek -60 KPX Tcaron hyphen -120 KPX Tcaron o -80 KPX Tcaron oacute -80 KPX Tcaron ocircumflex -80 KPX Tcaron odieresis -80 KPX Tcaron ograve -80 KPX Tcaron ohungarumlaut -80 KPX Tcaron omacron -80 KPX Tcaron oslash -80 KPX Tcaron otilde -80 KPX Tcaron period -80 KPX Tcaron r -80 KPX Tcaron racute -80 KPX Tcaron rcommaaccent -80 KPX Tcaron semicolon -40 KPX Tcaron u -90 KPX Tcaron uacute -90 KPX Tcaron ucircumflex -90 KPX Tcaron udieresis -90 KPX Tcaron ugrave -90 KPX Tcaron uhungarumlaut -90 KPX Tcaron umacron -90 KPX Tcaron uogonek -90 KPX Tcaron uring -90 KPX Tcaron w -60 KPX Tcaron y -60 KPX Tcaron yacute -60 KPX Tcaron ydieresis -60 KPX Tcommaaccent A -90 KPX Tcommaaccent Aacute -90 KPX Tcommaaccent Abreve -90 KPX Tcommaaccent Acircumflex -90 KPX Tcommaaccent Adieresis -90 KPX Tcommaaccent Agrave -90 KPX Tcommaaccent Amacron -90 KPX Tcommaaccent Aogonek -90 KPX Tcommaaccent Aring -90 KPX Tcommaaccent Atilde -90 KPX Tcommaaccent O -40 KPX Tcommaaccent Oacute -40 KPX Tcommaaccent Ocircumflex -40 KPX Tcommaaccent Odieresis -40 KPX Tcommaaccent Ograve -40 KPX Tcommaaccent Ohungarumlaut -40 KPX Tcommaaccent Omacron -40 KPX Tcommaaccent Oslash -40 KPX Tcommaaccent Otilde -40 KPX Tcommaaccent a -80 KPX Tcommaaccent aacute -80 KPX Tcommaaccent abreve -80 KPX Tcommaaccent acircumflex -80 KPX Tcommaaccent adieresis -80 KPX Tcommaaccent agrave -80 KPX Tcommaaccent amacron -80 KPX Tcommaaccent aogonek -80 KPX Tcommaaccent aring -80 KPX Tcommaaccent atilde -80 KPX Tcommaaccent colon -40 KPX Tcommaaccent comma -80 KPX Tcommaaccent e -60 KPX Tcommaaccent eacute -60 KPX Tcommaaccent ecaron -60 KPX Tcommaaccent ecircumflex -60 KPX Tcommaaccent edieresis -60 KPX Tcommaaccent edotaccent -60 KPX Tcommaaccent egrave -60 KPX Tcommaaccent emacron -60 KPX Tcommaaccent eogonek -60 KPX Tcommaaccent hyphen -120 KPX Tcommaaccent o -80 KPX Tcommaaccent oacute -80 KPX Tcommaaccent ocircumflex -80 KPX Tcommaaccent odieresis -80 KPX Tcommaaccent ograve -80 KPX Tcommaaccent ohungarumlaut -80 KPX Tcommaaccent omacron -80 KPX Tcommaaccent oslash -80 KPX Tcommaaccent otilde -80 KPX Tcommaaccent period -80 KPX Tcommaaccent r -80 KPX Tcommaaccent racute -80 KPX Tcommaaccent rcommaaccent -80 KPX Tcommaaccent semicolon -40 KPX Tcommaaccent u -90 KPX Tcommaaccent uacute -90 KPX Tcommaaccent ucircumflex -90 KPX Tcommaaccent udieresis -90 KPX Tcommaaccent ugrave -90 KPX Tcommaaccent uhungarumlaut -90 KPX Tcommaaccent umacron -90 KPX Tcommaaccent uogonek -90 KPX Tcommaaccent uring -90 KPX Tcommaaccent w -60 KPX Tcommaaccent y -60 KPX Tcommaaccent yacute -60 KPX Tcommaaccent ydieresis -60 KPX U A -50 KPX U Aacute -50 KPX U Abreve -50 KPX U Acircumflex -50 KPX U Adieresis -50 KPX U Agrave -50 KPX U Amacron -50 KPX U Aogonek -50 KPX U Aring -50 KPX U Atilde -50 KPX U comma -30 KPX U period -30 KPX Uacute A -50 KPX Uacute Aacute -50 KPX Uacute Abreve -50 KPX Uacute Acircumflex -50 KPX Uacute Adieresis -50 KPX Uacute Agrave -50 KPX Uacute Amacron -50 KPX Uacute Aogonek -50 KPX Uacute Aring -50 KPX Uacute Atilde -50 KPX Uacute comma -30 KPX Uacute period -30 KPX Ucircumflex A -50 KPX Ucircumflex Aacute -50 KPX Ucircumflex Abreve -50 KPX Ucircumflex Acircumflex -50 KPX Ucircumflex Adieresis -50 KPX Ucircumflex Agrave -50 KPX Ucircumflex Amacron -50 KPX Ucircumflex Aogonek -50 KPX Ucircumflex Aring -50 KPX Ucircumflex Atilde -50 KPX Ucircumflex comma -30 KPX Ucircumflex period -30 KPX Udieresis A -50 KPX Udieresis Aacute -50 KPX Udieresis Abreve -50 KPX Udieresis Acircumflex -50 KPX Udieresis Adieresis -50 KPX Udieresis Agrave -50 KPX Udieresis Amacron -50 KPX Udieresis Aogonek -50 KPX Udieresis Aring -50 KPX Udieresis Atilde -50 KPX Udieresis comma -30 KPX Udieresis period -30 KPX Ugrave A -50 KPX Ugrave Aacute -50 KPX Ugrave Abreve -50 KPX Ugrave Acircumflex -50 KPX Ugrave Adieresis -50 KPX Ugrave Agrave -50 KPX Ugrave Amacron -50 KPX Ugrave Aogonek -50 KPX Ugrave Aring -50 KPX Ugrave Atilde -50 KPX Ugrave comma -30 KPX Ugrave period -30 KPX Uhungarumlaut A -50 KPX Uhungarumlaut Aacute -50 KPX Uhungarumlaut Abreve -50 KPX Uhungarumlaut Acircumflex -50 KPX Uhungarumlaut Adieresis -50 KPX Uhungarumlaut Agrave -50 KPX Uhungarumlaut Amacron -50 KPX Uhungarumlaut Aogonek -50 KPX Uhungarumlaut Aring -50 KPX Uhungarumlaut Atilde -50 KPX Uhungarumlaut comma -30 KPX Uhungarumlaut period -30 KPX Umacron A -50 KPX Umacron Aacute -50 KPX Umacron Abreve -50 KPX Umacron Acircumflex -50 KPX Umacron Adieresis -50 KPX Umacron Agrave -50 KPX Umacron Amacron -50 KPX Umacron Aogonek -50 KPX Umacron Aring -50 KPX Umacron Atilde -50 KPX Umacron comma -30 KPX Umacron period -30 KPX Uogonek A -50 KPX Uogonek Aacute -50 KPX Uogonek Abreve -50 KPX Uogonek Acircumflex -50 KPX Uogonek Adieresis -50 KPX Uogonek Agrave -50 KPX Uogonek Amacron -50 KPX Uogonek Aogonek -50 KPX Uogonek Aring -50 KPX Uogonek Atilde -50 KPX Uogonek comma -30 KPX Uogonek period -30 KPX Uring A -50 KPX Uring Aacute -50 KPX Uring Abreve -50 KPX Uring Acircumflex -50 KPX Uring Adieresis -50 KPX Uring Agrave -50 KPX Uring Amacron -50 KPX Uring Aogonek -50 KPX Uring Aring -50 KPX Uring Atilde -50 KPX Uring comma -30 KPX Uring period -30 KPX V A -80 KPX V Aacute -80 KPX V Abreve -80 KPX V Acircumflex -80 KPX V Adieresis -80 KPX V Agrave -80 KPX V Amacron -80 KPX V Aogonek -80 KPX V Aring -80 KPX V Atilde -80 KPX V G -50 KPX V Gbreve -50 KPX V Gcommaaccent -50 KPX V O -50 KPX V Oacute -50 KPX V Ocircumflex -50 KPX V Odieresis -50 KPX V Ograve -50 KPX V Ohungarumlaut -50 KPX V Omacron -50 KPX V Oslash -50 KPX V Otilde -50 KPX V a -60 KPX V aacute -60 KPX V abreve -60 KPX V acircumflex -60 KPX V adieresis -60 KPX V agrave -60 KPX V amacron -60 KPX V aogonek -60 KPX V aring -60 KPX V atilde -60 KPX V colon -40 KPX V comma -120 KPX V e -50 KPX V eacute -50 KPX V ecaron -50 KPX V ecircumflex -50 KPX V edieresis -50 KPX V edotaccent -50 KPX V egrave -50 KPX V emacron -50 KPX V eogonek -50 KPX V hyphen -80 KPX V o -90 KPX V oacute -90 KPX V ocircumflex -90 KPX V odieresis -90 KPX V ograve -90 KPX V ohungarumlaut -90 KPX V omacron -90 KPX V oslash -90 KPX V otilde -90 KPX V period -120 KPX V semicolon -40 KPX V u -60 KPX V uacute -60 KPX V ucircumflex -60 KPX V udieresis -60 KPX V ugrave -60 KPX V uhungarumlaut -60 KPX V umacron -60 KPX V uogonek -60 KPX V uring -60 KPX W A -60 KPX W Aacute -60 KPX W Abreve -60 KPX W Acircumflex -60 KPX W Adieresis -60 KPX W Agrave -60 KPX W Amacron -60 KPX W Aogonek -60 KPX W Aring -60 KPX W Atilde -60 KPX W O -20 KPX W Oacute -20 KPX W Ocircumflex -20 KPX W Odieresis -20 KPX W Ograve -20 KPX W Ohungarumlaut -20 KPX W Omacron -20 KPX W Oslash -20 KPX W Otilde -20 KPX W a -40 KPX W aacute -40 KPX W abreve -40 KPX W acircumflex -40 KPX W adieresis -40 KPX W agrave -40 KPX W amacron -40 KPX W aogonek -40 KPX W aring -40 KPX W atilde -40 KPX W colon -10 KPX W comma -80 KPX W e -35 KPX W eacute -35 KPX W ecaron -35 KPX W ecircumflex -35 KPX W edieresis -35 KPX W edotaccent -35 KPX W egrave -35 KPX W emacron -35 KPX W eogonek -35 KPX W hyphen -40 KPX W o -60 KPX W oacute -60 KPX W ocircumflex -60 KPX W odieresis -60 KPX W ograve -60 KPX W ohungarumlaut -60 KPX W omacron -60 KPX W oslash -60 KPX W otilde -60 KPX W period -80 KPX W semicolon -10 KPX W u -45 KPX W uacute -45 KPX W ucircumflex -45 KPX W udieresis -45 KPX W ugrave -45 KPX W uhungarumlaut -45 KPX W umacron -45 KPX W uogonek -45 KPX W uring -45 KPX W y -20 KPX W yacute -20 KPX W ydieresis -20 KPX Y A -110 KPX Y Aacute -110 KPX Y Abreve -110 KPX Y Acircumflex -110 KPX Y Adieresis -110 KPX Y Agrave -110 KPX Y Amacron -110 KPX Y Aogonek -110 KPX Y Aring -110 KPX Y Atilde -110 KPX Y O -70 KPX Y Oacute -70 KPX Y Ocircumflex -70 KPX Y Odieresis -70 KPX Y Ograve -70 KPX Y Ohungarumlaut -70 KPX Y Omacron -70 KPX Y Oslash -70 KPX Y Otilde -70 KPX Y a -90 KPX Y aacute -90 KPX Y abreve -90 KPX Y acircumflex -90 KPX Y adieresis -90 KPX Y agrave -90 KPX Y amacron -90 KPX Y aogonek -90 KPX Y aring -90 KPX Y atilde -90 KPX Y colon -50 KPX Y comma -100 KPX Y e -80 KPX Y eacute -80 KPX Y ecaron -80 KPX Y ecircumflex -80 KPX Y edieresis -80 KPX Y edotaccent -80 KPX Y egrave -80 KPX Y emacron -80 KPX Y eogonek -80 KPX Y o -100 KPX Y oacute -100 KPX Y ocircumflex -100 KPX Y odieresis -100 KPX Y ograve -100 KPX Y ohungarumlaut -100 KPX Y omacron -100 KPX Y oslash -100 KPX Y otilde -100 KPX Y period -100 KPX Y semicolon -50 KPX Y u -100 KPX Y uacute -100 KPX Y ucircumflex -100 KPX Y udieresis -100 KPX Y ugrave -100 KPX Y uhungarumlaut -100 KPX Y umacron -100 KPX Y uogonek -100 KPX Y uring -100 KPX Yacute A -110 KPX Yacute Aacute -110 KPX Yacute Abreve -110 KPX Yacute Acircumflex -110 KPX Yacute Adieresis -110 KPX Yacute Agrave -110 KPX Yacute Amacron -110 KPX Yacute Aogonek -110 KPX Yacute Aring -110 KPX Yacute Atilde -110 KPX Yacute O -70 KPX Yacute Oacute -70 KPX Yacute Ocircumflex -70 KPX Yacute Odieresis -70 KPX Yacute Ograve -70 KPX Yacute Ohungarumlaut -70 KPX Yacute Omacron -70 KPX Yacute Oslash -70 KPX Yacute Otilde -70 KPX Yacute a -90 KPX Yacute aacute -90 KPX Yacute abreve -90 KPX Yacute acircumflex -90 KPX Yacute adieresis -90 KPX Yacute agrave -90 KPX Yacute amacron -90 KPX Yacute aogonek -90 KPX Yacute aring -90 KPX Yacute atilde -90 KPX Yacute colon -50 KPX Yacute comma -100 KPX Yacute e -80 KPX Yacute eacute -80 KPX Yacute ecaron -80 KPX Yacute ecircumflex -80 KPX Yacute edieresis -80 KPX Yacute edotaccent -80 KPX Yacute egrave -80 KPX Yacute emacron -80 KPX Yacute eogonek -80 KPX Yacute o -100 KPX Yacute oacute -100 KPX Yacute ocircumflex -100 KPX Yacute odieresis -100 KPX Yacute ograve -100 KPX Yacute ohungarumlaut -100 KPX Yacute omacron -100 KPX Yacute oslash -100 KPX Yacute otilde -100 KPX Yacute period -100 KPX Yacute semicolon -50 KPX Yacute u -100 KPX Yacute uacute -100 KPX Yacute ucircumflex -100 KPX Yacute udieresis -100 KPX Yacute ugrave -100 KPX Yacute uhungarumlaut -100 KPX Yacute umacron -100 KPX Yacute uogonek -100 KPX Yacute uring -100 KPX Ydieresis A -110 KPX Ydieresis Aacute -110 KPX Ydieresis Abreve -110 KPX Ydieresis Acircumflex -110 KPX Ydieresis Adieresis -110 KPX Ydieresis Agrave -110 KPX Ydieresis Amacron -110 KPX Ydieresis Aogonek -110 KPX Ydieresis Aring -110 KPX Ydieresis Atilde -110 KPX Ydieresis O -70 KPX Ydieresis Oacute -70 KPX Ydieresis Ocircumflex -70 KPX Ydieresis Odieresis -70 KPX Ydieresis Ograve -70 KPX Ydieresis Ohungarumlaut -70 KPX Ydieresis Omacron -70 KPX Ydieresis Oslash -70 KPX Ydieresis Otilde -70 KPX Ydieresis a -90 KPX Ydieresis aacute -90 KPX Ydieresis abreve -90 KPX Ydieresis acircumflex -90 KPX Ydieresis adieresis -90 KPX Ydieresis agrave -90 KPX Ydieresis amacron -90 KPX Ydieresis aogonek -90 KPX Ydieresis aring -90 KPX Ydieresis atilde -90 KPX Ydieresis colon -50 KPX Ydieresis comma -100 KPX Ydieresis e -80 KPX Ydieresis eacute -80 KPX Ydieresis ecaron -80 KPX Ydieresis ecircumflex -80 KPX Ydieresis edieresis -80 KPX Ydieresis edotaccent -80 KPX Ydieresis egrave -80 KPX Ydieresis emacron -80 KPX Ydieresis eogonek -80 KPX Ydieresis o -100 KPX Ydieresis oacute -100 KPX Ydieresis ocircumflex -100 KPX Ydieresis odieresis -100 KPX Ydieresis ograve -100 KPX Ydieresis ohungarumlaut -100 KPX Ydieresis omacron -100 KPX Ydieresis oslash -100 KPX Ydieresis otilde -100 KPX Ydieresis period -100 KPX Ydieresis semicolon -50 KPX Ydieresis u -100 KPX Ydieresis uacute -100 KPX Ydieresis ucircumflex -100 KPX Ydieresis udieresis -100 KPX Ydieresis ugrave -100 KPX Ydieresis uhungarumlaut -100 KPX Ydieresis umacron -100 KPX Ydieresis uogonek -100 KPX Ydieresis uring -100 KPX a g -10 KPX a gbreve -10 KPX a gcommaaccent -10 KPX a v -15 KPX a w -15 KPX a y -20 KPX a yacute -20 KPX a ydieresis -20 KPX aacute g -10 KPX aacute gbreve -10 KPX aacute gcommaaccent -10 KPX aacute v -15 KPX aacute w -15 KPX aacute y -20 KPX aacute yacute -20 KPX aacute ydieresis -20 KPX abreve g -10 KPX abreve gbreve -10 KPX abreve gcommaaccent -10 KPX abreve v -15 KPX abreve w -15 KPX abreve y -20 KPX abreve yacute -20 KPX abreve ydieresis -20 KPX acircumflex g -10 KPX acircumflex gbreve -10 KPX acircumflex gcommaaccent -10 KPX acircumflex v -15 KPX acircumflex w -15 KPX acircumflex y -20 KPX acircumflex yacute -20 KPX acircumflex ydieresis -20 KPX adieresis g -10 KPX adieresis gbreve -10 KPX adieresis gcommaaccent -10 KPX adieresis v -15 KPX adieresis w -15 KPX adieresis y -20 KPX adieresis yacute -20 KPX adieresis ydieresis -20 KPX agrave g -10 KPX agrave gbreve -10 KPX agrave gcommaaccent -10 KPX agrave v -15 KPX agrave w -15 KPX agrave y -20 KPX agrave yacute -20 KPX agrave ydieresis -20 KPX amacron g -10 KPX amacron gbreve -10 KPX amacron gcommaaccent -10 KPX amacron v -15 KPX amacron w -15 KPX amacron y -20 KPX amacron yacute -20 KPX amacron ydieresis -20 KPX aogonek g -10 KPX aogonek gbreve -10 KPX aogonek gcommaaccent -10 KPX aogonek v -15 KPX aogonek w -15 KPX aogonek y -20 KPX aogonek yacute -20 KPX aogonek ydieresis -20 KPX aring g -10 KPX aring gbreve -10 KPX aring gcommaaccent -10 KPX aring v -15 KPX aring w -15 KPX aring y -20 KPX aring yacute -20 KPX aring ydieresis -20 KPX atilde g -10 KPX atilde gbreve -10 KPX atilde gcommaaccent -10 KPX atilde v -15 KPX atilde w -15 KPX atilde y -20 KPX atilde yacute -20 KPX atilde ydieresis -20 KPX b l -10 KPX b lacute -10 KPX b lcommaaccent -10 KPX b lslash -10 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -20 KPX b y -20 KPX b yacute -20 KPX b ydieresis -20 KPX c h -10 KPX c k -20 KPX c kcommaaccent -20 KPX c l -20 KPX c lacute -20 KPX c lcommaaccent -20 KPX c lslash -20 KPX c y -10 KPX c yacute -10 KPX c ydieresis -10 KPX cacute h -10 KPX cacute k -20 KPX cacute kcommaaccent -20 KPX cacute l -20 KPX cacute lacute -20 KPX cacute lcommaaccent -20 KPX cacute lslash -20 KPX cacute y -10 KPX cacute yacute -10 KPX cacute ydieresis -10 KPX ccaron h -10 KPX ccaron k -20 KPX ccaron kcommaaccent -20 KPX ccaron l -20 KPX ccaron lacute -20 KPX ccaron lcommaaccent -20 KPX ccaron lslash -20 KPX ccaron y -10 KPX ccaron yacute -10 KPX ccaron ydieresis -10 KPX ccedilla h -10 KPX ccedilla k -20 KPX ccedilla kcommaaccent -20 KPX ccedilla l -20 KPX ccedilla lacute -20 KPX ccedilla lcommaaccent -20 KPX ccedilla lslash -20 KPX ccedilla y -10 KPX ccedilla yacute -10 KPX ccedilla ydieresis -10 KPX colon space -40 KPX comma quotedblright -120 KPX comma quoteright -120 KPX comma space -40 KPX d d -10 KPX d dcroat -10 KPX d v -15 KPX d w -15 KPX d y -15 KPX d yacute -15 KPX d ydieresis -15 KPX dcroat d -10 KPX dcroat dcroat -10 KPX dcroat v -15 KPX dcroat w -15 KPX dcroat y -15 KPX dcroat yacute -15 KPX dcroat ydieresis -15 KPX e comma 10 KPX e period 20 KPX e v -15 KPX e w -15 KPX e x -15 KPX e y -15 KPX e yacute -15 KPX e ydieresis -15 KPX eacute comma 10 KPX eacute period 20 KPX eacute v -15 KPX eacute w -15 KPX eacute x -15 KPX eacute y -15 KPX eacute yacute -15 KPX eacute ydieresis -15 KPX ecaron comma 10 KPX ecaron period 20 KPX ecaron v -15 KPX ecaron w -15 KPX ecaron x -15 KPX ecaron y -15 KPX ecaron yacute -15 KPX ecaron ydieresis -15 KPX ecircumflex comma 10 KPX ecircumflex period 20 KPX ecircumflex v -15 KPX ecircumflex w -15 KPX ecircumflex x -15 KPX ecircumflex y -15 KPX ecircumflex yacute -15 KPX ecircumflex ydieresis -15 KPX edieresis comma 10 KPX edieresis period 20 KPX edieresis v -15 KPX edieresis w -15 KPX edieresis x -15 KPX edieresis y -15 KPX edieresis yacute -15 KPX edieresis ydieresis -15 KPX edotaccent comma 10 KPX edotaccent period 20 KPX edotaccent v -15 KPX edotaccent w -15 KPX edotaccent x -15 KPX edotaccent y -15 KPX edotaccent yacute -15 KPX edotaccent ydieresis -15 KPX egrave comma 10 KPX egrave period 20 KPX egrave v -15 KPX egrave w -15 KPX egrave x -15 KPX egrave y -15 KPX egrave yacute -15 KPX egrave ydieresis -15 KPX emacron comma 10 KPX emacron period 20 KPX emacron v -15 KPX emacron w -15 KPX emacron x -15 KPX emacron y -15 KPX emacron yacute -15 KPX emacron ydieresis -15 KPX eogonek comma 10 KPX eogonek period 20 KPX eogonek v -15 KPX eogonek w -15 KPX eogonek x -15 KPX eogonek y -15 KPX eogonek yacute -15 KPX eogonek ydieresis -15 KPX f comma -10 KPX f e -10 KPX f eacute -10 KPX f ecaron -10 KPX f ecircumflex -10 KPX f edieresis -10 KPX f edotaccent -10 KPX f egrave -10 KPX f emacron -10 KPX f eogonek -10 KPX f o -20 KPX f oacute -20 KPX f ocircumflex -20 KPX f odieresis -20 KPX f ograve -20 KPX f ohungarumlaut -20 KPX f omacron -20 KPX f oslash -20 KPX f otilde -20 KPX f period -10 KPX f quotedblright 30 KPX f quoteright 30 KPX g e 10 KPX g eacute 10 KPX g ecaron 10 KPX g ecircumflex 10 KPX g edieresis 10 KPX g edotaccent 10 KPX g egrave 10 KPX g emacron 10 KPX g eogonek 10 KPX g g -10 KPX g gbreve -10 KPX g gcommaaccent -10 KPX gbreve e 10 KPX gbreve eacute 10 KPX gbreve ecaron 10 KPX gbreve ecircumflex 10 KPX gbreve edieresis 10 KPX gbreve edotaccent 10 KPX gbreve egrave 10 KPX gbreve emacron 10 KPX gbreve eogonek 10 KPX gbreve g -10 KPX gbreve gbreve -10 KPX gbreve gcommaaccent -10 KPX gcommaaccent e 10 KPX gcommaaccent eacute 10 KPX gcommaaccent ecaron 10 KPX gcommaaccent ecircumflex 10 KPX gcommaaccent edieresis 10 KPX gcommaaccent edotaccent 10 KPX gcommaaccent egrave 10 KPX gcommaaccent emacron 10 KPX gcommaaccent eogonek 10 KPX gcommaaccent g -10 KPX gcommaaccent gbreve -10 KPX gcommaaccent gcommaaccent -10 KPX h y -20 KPX h yacute -20 KPX h ydieresis -20 KPX k o -15 KPX k oacute -15 KPX k ocircumflex -15 KPX k odieresis -15 KPX k ograve -15 KPX k ohungarumlaut -15 KPX k omacron -15 KPX k oslash -15 KPX k otilde -15 KPX kcommaaccent o -15 KPX kcommaaccent oacute -15 KPX kcommaaccent ocircumflex -15 KPX kcommaaccent odieresis -15 KPX kcommaaccent ograve -15 KPX kcommaaccent ohungarumlaut -15 KPX kcommaaccent omacron -15 KPX kcommaaccent oslash -15 KPX kcommaaccent otilde -15 KPX l w -15 KPX l y -15 KPX l yacute -15 KPX l ydieresis -15 KPX lacute w -15 KPX lacute y -15 KPX lacute yacute -15 KPX lacute ydieresis -15 KPX lcommaaccent w -15 KPX lcommaaccent y -15 KPX lcommaaccent yacute -15 KPX lcommaaccent ydieresis -15 KPX lslash w -15 KPX lslash y -15 KPX lslash yacute -15 KPX lslash ydieresis -15 KPX m u -20 KPX m uacute -20 KPX m ucircumflex -20 KPX m udieresis -20 KPX m ugrave -20 KPX m uhungarumlaut -20 KPX m umacron -20 KPX m uogonek -20 KPX m uring -20 KPX m y -30 KPX m yacute -30 KPX m ydieresis -30 KPX n u -10 KPX n uacute -10 KPX n ucircumflex -10 KPX n udieresis -10 KPX n ugrave -10 KPX n uhungarumlaut -10 KPX n umacron -10 KPX n uogonek -10 KPX n uring -10 KPX n v -40 KPX n y -20 KPX n yacute -20 KPX n ydieresis -20 KPX nacute u -10 KPX nacute uacute -10 KPX nacute ucircumflex -10 KPX nacute udieresis -10 KPX nacute ugrave -10 KPX nacute uhungarumlaut -10 KPX nacute umacron -10 KPX nacute uogonek -10 KPX nacute uring -10 KPX nacute v -40 KPX nacute y -20 KPX nacute yacute -20 KPX nacute ydieresis -20 KPX ncaron u -10 KPX ncaron uacute -10 KPX ncaron ucircumflex -10 KPX ncaron udieresis -10 KPX ncaron ugrave -10 KPX ncaron uhungarumlaut -10 KPX ncaron umacron -10 KPX ncaron uogonek -10 KPX ncaron uring -10 KPX ncaron v -40 KPX ncaron y -20 KPX ncaron yacute -20 KPX ncaron ydieresis -20 KPX ncommaaccent u -10 KPX ncommaaccent uacute -10 KPX ncommaaccent ucircumflex -10 KPX ncommaaccent udieresis -10 KPX ncommaaccent ugrave -10 KPX ncommaaccent uhungarumlaut -10 KPX ncommaaccent umacron -10 KPX ncommaaccent uogonek -10 KPX ncommaaccent uring -10 KPX ncommaaccent v -40 KPX ncommaaccent y -20 KPX ncommaaccent yacute -20 KPX ncommaaccent ydieresis -20 KPX ntilde u -10 KPX ntilde uacute -10 KPX ntilde ucircumflex -10 KPX ntilde udieresis -10 KPX ntilde ugrave -10 KPX ntilde uhungarumlaut -10 KPX ntilde umacron -10 KPX ntilde uogonek -10 KPX ntilde uring -10 KPX ntilde v -40 KPX ntilde y -20 KPX ntilde yacute -20 KPX ntilde ydieresis -20 KPX o v -20 KPX o w -15 KPX o x -30 KPX o y -20 KPX o yacute -20 KPX o ydieresis -20 KPX oacute v -20 KPX oacute w -15 KPX oacute x -30 KPX oacute y -20 KPX oacute yacute -20 KPX oacute ydieresis -20 KPX ocircumflex v -20 KPX ocircumflex w -15 KPX ocircumflex x -30 KPX ocircumflex y -20 KPX ocircumflex yacute -20 KPX ocircumflex ydieresis -20 KPX odieresis v -20 KPX odieresis w -15 KPX odieresis x -30 KPX odieresis y -20 KPX odieresis yacute -20 KPX odieresis ydieresis -20 KPX ograve v -20 KPX ograve w -15 KPX ograve x -30 KPX ograve y -20 KPX ograve yacute -20 KPX ograve ydieresis -20 KPX ohungarumlaut v -20 KPX ohungarumlaut w -15 KPX ohungarumlaut x -30 KPX ohungarumlaut y -20 KPX ohungarumlaut yacute -20 KPX ohungarumlaut ydieresis -20 KPX omacron v -20 KPX omacron w -15 KPX omacron x -30 KPX omacron y -20 KPX omacron yacute -20 KPX omacron ydieresis -20 KPX oslash v -20 KPX oslash w -15 KPX oslash x -30 KPX oslash y -20 KPX oslash yacute -20 KPX oslash ydieresis -20 KPX otilde v -20 KPX otilde w -15 KPX otilde x -30 KPX otilde y -20 KPX otilde yacute -20 KPX otilde ydieresis -20 KPX p y -15 KPX p yacute -15 KPX p ydieresis -15 KPX period quotedblright -120 KPX period quoteright -120 KPX period space -40 KPX quotedblright space -80 KPX quoteleft quoteleft -46 KPX quoteright d -80 KPX quoteright dcroat -80 KPX quoteright l -20 KPX quoteright lacute -20 KPX quoteright lcommaaccent -20 KPX quoteright lslash -20 KPX quoteright quoteright -46 KPX quoteright r -40 KPX quoteright racute -40 KPX quoteright rcaron -40 KPX quoteright rcommaaccent -40 KPX quoteright s -60 KPX quoteright sacute -60 KPX quoteright scaron -60 KPX quoteright scedilla -60 KPX quoteright scommaaccent -60 KPX quoteright space -80 KPX quoteright v -20 KPX r c -20 KPX r cacute -20 KPX r ccaron -20 KPX r ccedilla -20 KPX r comma -60 KPX r d -20 KPX r dcroat -20 KPX r g -15 KPX r gbreve -15 KPX r gcommaaccent -15 KPX r hyphen -20 KPX r o -20 KPX r oacute -20 KPX r ocircumflex -20 KPX r odieresis -20 KPX r ograve -20 KPX r ohungarumlaut -20 KPX r omacron -20 KPX r oslash -20 KPX r otilde -20 KPX r period -60 KPX r q -20 KPX r s -15 KPX r sacute -15 KPX r scaron -15 KPX r scedilla -15 KPX r scommaaccent -15 KPX r t 20 KPX r tcommaaccent 20 KPX r v 10 KPX r y 10 KPX r yacute 10 KPX r ydieresis 10 KPX racute c -20 KPX racute cacute -20 KPX racute ccaron -20 KPX racute ccedilla -20 KPX racute comma -60 KPX racute d -20 KPX racute dcroat -20 KPX racute g -15 KPX racute gbreve -15 KPX racute gcommaaccent -15 KPX racute hyphen -20 KPX racute o -20 KPX racute oacute -20 KPX racute ocircumflex -20 KPX racute odieresis -20 KPX racute ograve -20 KPX racute ohungarumlaut -20 KPX racute omacron -20 KPX racute oslash -20 KPX racute otilde -20 KPX racute period -60 KPX racute q -20 KPX racute s -15 KPX racute sacute -15 KPX racute scaron -15 KPX racute scedilla -15 KPX racute scommaaccent -15 KPX racute t 20 KPX racute tcommaaccent 20 KPX racute v 10 KPX racute y 10 KPX racute yacute 10 KPX racute ydieresis 10 KPX rcaron c -20 KPX rcaron cacute -20 KPX rcaron ccaron -20 KPX rcaron ccedilla -20 KPX rcaron comma -60 KPX rcaron d -20 KPX rcaron dcroat -20 KPX rcaron g -15 KPX rcaron gbreve -15 KPX rcaron gcommaaccent -15 KPX rcaron hyphen -20 KPX rcaron o -20 KPX rcaron oacute -20 KPX rcaron ocircumflex -20 KPX rcaron odieresis -20 KPX rcaron ograve -20 KPX rcaron ohungarumlaut -20 KPX rcaron omacron -20 KPX rcaron oslash -20 KPX rcaron otilde -20 KPX rcaron period -60 KPX rcaron q -20 KPX rcaron s -15 KPX rcaron sacute -15 KPX rcaron scaron -15 KPX rcaron scedilla -15 KPX rcaron scommaaccent -15 KPX rcaron t 20 KPX rcaron tcommaaccent 20 KPX rcaron v 10 KPX rcaron y 10 KPX rcaron yacute 10 KPX rcaron ydieresis 10 KPX rcommaaccent c -20 KPX rcommaaccent cacute -20 KPX rcommaaccent ccaron -20 KPX rcommaaccent ccedilla -20 KPX rcommaaccent comma -60 KPX rcommaaccent d -20 KPX rcommaaccent dcroat -20 KPX rcommaaccent g -15 KPX rcommaaccent gbreve -15 KPX rcommaaccent gcommaaccent -15 KPX rcommaaccent hyphen -20 KPX rcommaaccent o -20 KPX rcommaaccent oacute -20 KPX rcommaaccent ocircumflex -20 KPX rcommaaccent odieresis -20 KPX rcommaaccent ograve -20 KPX rcommaaccent ohungarumlaut -20 KPX rcommaaccent omacron -20 KPX rcommaaccent oslash -20 KPX rcommaaccent otilde -20 KPX rcommaaccent period -60 KPX rcommaaccent q -20 KPX rcommaaccent s -15 KPX rcommaaccent sacute -15 KPX rcommaaccent scaron -15 KPX rcommaaccent scedilla -15 KPX rcommaaccent scommaaccent -15 KPX rcommaaccent t 20 KPX rcommaaccent tcommaaccent 20 KPX rcommaaccent v 10 KPX rcommaaccent y 10 KPX rcommaaccent yacute 10 KPX rcommaaccent ydieresis 10 KPX s w -15 KPX sacute w -15 KPX scaron w -15 KPX scedilla w -15 KPX scommaaccent w -15 KPX semicolon space -40 KPX space T -100 KPX space Tcaron -100 KPX space Tcommaaccent -100 KPX space V -80 KPX space W -80 KPX space Y -120 KPX space Yacute -120 KPX space Ydieresis -120 KPX space quotedblleft -80 KPX space quoteleft -60 KPX v a -20 KPX v aacute -20 KPX v abreve -20 KPX v acircumflex -20 KPX v adieresis -20 KPX v agrave -20 KPX v amacron -20 KPX v aogonek -20 KPX v aring -20 KPX v atilde -20 KPX v comma -80 KPX v o -30 KPX v oacute -30 KPX v ocircumflex -30 KPX v odieresis -30 KPX v ograve -30 KPX v ohungarumlaut -30 KPX v omacron -30 KPX v oslash -30 KPX v otilde -30 KPX v period -80 KPX w comma -40 KPX w o -20 KPX w oacute -20 KPX w ocircumflex -20 KPX w odieresis -20 KPX w ograve -20 KPX w ohungarumlaut -20 KPX w omacron -20 KPX w oslash -20 KPX w otilde -20 KPX w period -40 KPX x e -10 KPX x eacute -10 KPX x ecaron -10 KPX x ecircumflex -10 KPX x edieresis -10 KPX x edotaccent -10 KPX x egrave -10 KPX x emacron -10 KPX x eogonek -10 KPX y a -30 KPX y aacute -30 KPX y abreve -30 KPX y acircumflex -30 KPX y adieresis -30 KPX y agrave -30 KPX y amacron -30 KPX y aogonek -30 KPX y aring -30 KPX y atilde -30 KPX y comma -80 KPX y e -10 KPX y eacute -10 KPX y ecaron -10 KPX y ecircumflex -10 KPX y edieresis -10 KPX y edotaccent -10 KPX y egrave -10 KPX y emacron -10 KPX y eogonek -10 KPX y o -25 KPX y oacute -25 KPX y ocircumflex -25 KPX y odieresis -25 KPX y ograve -25 KPX y ohungarumlaut -25 KPX y omacron -25 KPX y oslash -25 KPX y otilde -25 KPX y period -80 KPX yacute a -30 KPX yacute aacute -30 KPX yacute abreve -30 KPX yacute acircumflex -30 KPX yacute adieresis -30 KPX yacute agrave -30 KPX yacute amacron -30 KPX yacute aogonek -30 KPX yacute aring -30 KPX yacute atilde -30 KPX yacute comma -80 KPX yacute e -10 KPX yacute eacute -10 KPX yacute ecaron -10 KPX yacute ecircumflex -10 KPX yacute edieresis -10 KPX yacute edotaccent -10 KPX yacute egrave -10 KPX yacute emacron -10 KPX yacute eogonek -10 KPX yacute o -25 KPX yacute oacute -25 KPX yacute ocircumflex -25 KPX yacute odieresis -25 KPX yacute ograve -25 KPX yacute ohungarumlaut -25 KPX yacute omacron -25 KPX yacute oslash -25 KPX yacute otilde -25 KPX yacute period -80 KPX ydieresis a -30 KPX ydieresis aacute -30 KPX ydieresis abreve -30 KPX ydieresis acircumflex -30 KPX ydieresis adieresis -30 KPX ydieresis agrave -30 KPX ydieresis amacron -30 KPX ydieresis aogonek -30 KPX ydieresis aring -30 KPX ydieresis atilde -30 KPX ydieresis comma -80 KPX ydieresis e -10 KPX ydieresis eacute -10 KPX ydieresis ecaron -10 KPX ydieresis ecircumflex -10 KPX ydieresis edieresis -10 KPX ydieresis edotaccent -10 KPX ydieresis egrave -10 KPX ydieresis emacron -10 KPX ydieresis eogonek -10 KPX ydieresis o -25 KPX ydieresis oacute -25 KPX ydieresis ocircumflex -25 KPX ydieresis odieresis -25 KPX ydieresis ograve -25 KPX ydieresis ohungarumlaut -25 KPX ydieresis omacron -25 KPX ydieresis oslash -25 KPX ydieresis otilde -25 KPX ydieresis period -80 KPX z e 10 KPX z eacute 10 KPX z ecaron 10 KPX z ecircumflex 10 KPX z edieresis 10 KPX z edotaccent 10 KPX z egrave 10 KPX z emacron 10 KPX z eogonek 10 KPX zacute e 10 KPX zacute eacute 10 KPX zacute ecaron 10 KPX zacute ecircumflex 10 KPX zacute edieresis 10 KPX zacute edotaccent 10 KPX zacute egrave 10 KPX zacute emacron 10 KPX zacute eogonek 10 KPX zcaron e 10 KPX zcaron eacute 10 KPX zcaron ecaron 10 KPX zcaron ecircumflex 10 KPX zcaron edieresis 10 KPX zcaron edotaccent 10 KPX zcaron egrave 10 KPX zcaron emacron 10 KPX zcaron eogonek 10 KPX zdotaccent e 10 KPX zdotaccent eacute 10 KPX zdotaccent ecaron 10 KPX zdotaccent ecircumflex 10 KPX zdotaccent edieresis 10 KPX zdotaccent edotaccent 10 KPX zdotaccent egrave 10 KPX zdotaccent emacron 10 KPX zdotaccent eogonek 10 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Helvetica-Oblique.afm100644 0 0 227203 11000354125 21043 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:44:31 1997 Comment UniqueID 43055 Comment VMusage 14960 69346 FontName Helvetica-Oblique FullName Helvetica Oblique FamilyName Helvetica Weight Medium ItalicAngle -12 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -170 -225 1116 931 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StdHW 76 StdVW 88 StartCharMetrics 315 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ; C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ; C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ; C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ; C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ; C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ; C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ; C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ; C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ; C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ; C 43 ; WX 584 ; N plus ; B 85 0 606 505 ; C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ; C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ; C 46 ; WX 278 ; N period ; B 87 0 214 106 ; C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ; C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ; C 49 ; WX 556 ; N one ; B 207 0 508 703 ; C 50 ; WX 556 ; N two ; B 26 0 617 703 ; C 51 ; WX 556 ; N three ; B 75 -19 610 703 ; C 52 ; WX 556 ; N four ; B 61 0 576 703 ; C 53 ; WX 556 ; N five ; B 68 -19 621 688 ; C 54 ; WX 556 ; N six ; B 91 -19 615 703 ; C 55 ; WX 556 ; N seven ; B 137 0 669 688 ; C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ; C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ; C 58 ; WX 278 ; N colon ; B 87 0 301 516 ; C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ; C 60 ; WX 584 ; N less ; B 94 11 641 495 ; C 61 ; WX 584 ; N equal ; B 63 115 628 390 ; C 62 ; WX 584 ; N greater ; B 50 11 597 495 ; C 63 ; WX 556 ; N question ; B 161 0 610 727 ; C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ; C 65 ; WX 667 ; N A ; B 14 0 654 718 ; C 66 ; WX 667 ; N B ; B 74 0 712 718 ; C 67 ; WX 722 ; N C ; B 108 -19 782 737 ; C 68 ; WX 722 ; N D ; B 81 0 764 718 ; C 69 ; WX 667 ; N E ; B 86 0 762 718 ; C 70 ; WX 611 ; N F ; B 86 0 736 718 ; C 71 ; WX 778 ; N G ; B 111 -19 799 737 ; C 72 ; WX 722 ; N H ; B 77 0 799 718 ; C 73 ; WX 278 ; N I ; B 91 0 341 718 ; C 74 ; WX 500 ; N J ; B 47 -19 581 718 ; C 75 ; WX 667 ; N K ; B 76 0 808 718 ; C 76 ; WX 556 ; N L ; B 76 0 555 718 ; C 77 ; WX 833 ; N M ; B 73 0 914 718 ; C 78 ; WX 722 ; N N ; B 76 0 799 718 ; C 79 ; WX 778 ; N O ; B 105 -19 826 737 ; C 80 ; WX 667 ; N P ; B 86 0 737 718 ; C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ; C 82 ; WX 722 ; N R ; B 88 0 773 718 ; C 83 ; WX 667 ; N S ; B 90 -19 713 737 ; C 84 ; WX 611 ; N T ; B 148 0 750 718 ; C 85 ; WX 722 ; N U ; B 123 -19 797 718 ; C 86 ; WX 667 ; N V ; B 173 0 800 718 ; C 87 ; WX 944 ; N W ; B 169 0 1081 718 ; C 88 ; WX 667 ; N X ; B 19 0 790 718 ; C 89 ; WX 667 ; N Y ; B 167 0 806 718 ; C 90 ; WX 611 ; N Z ; B 23 0 741 718 ; C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ; C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ; C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ; C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ; C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ; C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ; C 97 ; WX 556 ; N a ; B 61 -15 559 538 ; C 98 ; WX 556 ; N b ; B 58 -15 584 718 ; C 99 ; WX 500 ; N c ; B 74 -15 553 538 ; C 100 ; WX 556 ; N d ; B 84 -15 652 718 ; C 101 ; WX 556 ; N e ; B 84 -15 578 538 ; C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 42 -220 610 538 ; C 104 ; WX 556 ; N h ; B 65 0 573 718 ; C 105 ; WX 222 ; N i ; B 67 0 308 718 ; C 106 ; WX 222 ; N j ; B -60 -210 308 718 ; C 107 ; WX 500 ; N k ; B 67 0 600 718 ; C 108 ; WX 222 ; N l ; B 67 0 308 718 ; C 109 ; WX 833 ; N m ; B 65 0 852 538 ; C 110 ; WX 556 ; N n ; B 65 0 573 538 ; C 111 ; WX 556 ; N o ; B 83 -14 585 538 ; C 112 ; WX 556 ; N p ; B 14 -207 584 538 ; C 113 ; WX 556 ; N q ; B 84 -207 605 538 ; C 114 ; WX 333 ; N r ; B 77 0 446 538 ; C 115 ; WX 500 ; N s ; B 63 -15 529 538 ; C 116 ; WX 278 ; N t ; B 102 -7 368 669 ; C 117 ; WX 556 ; N u ; B 94 -15 600 523 ; C 118 ; WX 500 ; N v ; B 119 0 603 523 ; C 119 ; WX 722 ; N w ; B 125 0 820 523 ; C 120 ; WX 500 ; N x ; B 11 0 594 523 ; C 121 ; WX 500 ; N y ; B 15 -214 600 523 ; C 122 ; WX 500 ; N z ; B 31 0 571 523 ; C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ; C 124 ; WX 260 ; N bar ; B 46 -225 332 775 ; C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ; C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ; C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ; C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ; C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ; C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ; C 165 ; WX 556 ; N yen ; B 81 0 699 688 ; C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ; C 167 ; WX 556 ; N section ; B 76 -191 584 737 ; C 168 ; WX 556 ; N currency ; B 60 99 646 603 ; C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ; C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ; C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ; C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ; C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ; C 174 ; WX 500 ; N fi ; B 86 0 587 728 ; C 175 ; WX 500 ; N fl ; B 86 0 585 728 ; C 177 ; WX 556 ; N endash ; B 51 240 623 313 ; C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ; C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ; C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ; C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ; C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ; C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ; C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ; C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ; C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ; C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ; C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ; C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ; C 193 ; WX 333 ; N grave ; B 170 593 337 734 ; C 194 ; WX 333 ; N acute ; B 248 593 475 734 ; C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ; C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ; C 197 ; WX 333 ; N macron ; B 143 627 468 684 ; C 198 ; WX 333 ; N breve ; B 167 595 476 731 ; C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ; C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ; C 202 ; WX 333 ; N ring ; B 214 572 402 756 ; C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ; C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ; C 207 ; WX 333 ; N caron ; B 177 593 468 734 ; C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ; C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ; C 227 ; WX 370 ; N ordfeminine ; B 127 405 449 737 ; C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ; C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ; C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ; C 235 ; WX 365 ; N ordmasculine ; B 141 405 468 737 ; C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ; C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ; C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ; C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ; C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ; C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ; C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ; C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ; C -1 ; WX 556 ; N abreve ; B 61 -15 578 731 ; C -1 ; WX 556 ; N uhungarumlaut ; B 94 -15 677 734 ; C -1 ; WX 556 ; N ecaron ; B 84 -15 580 734 ; C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ; C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ; C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ; C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ; C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ; C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ; C -1 ; WX 500 ; N scommaaccent ; B 63 -225 529 538 ; C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ; C -1 ; WX 722 ; N Uring ; B 123 -19 797 931 ; C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ; C -1 ; WX 556 ; N aogonek ; B 61 -220 559 538 ; C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ; C -1 ; WX 556 ; N uogonek ; B 94 -225 600 523 ; C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ; C -1 ; WX 722 ; N Dcroat ; B 69 0 764 718 ; C -1 ; WX 250 ; N commaaccent ; B 39 -225 172 -40 ; C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ; C -1 ; WX 667 ; N Emacron ; B 86 0 762 879 ; C -1 ; WX 500 ; N ccaron ; B 74 -15 553 734 ; C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ; C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 799 718 ; C -1 ; WX 222 ; N lacute ; B 67 0 461 929 ; C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ; C -1 ; WX 611 ; N Tcommaaccent ; B 148 -225 750 718 ; C -1 ; WX 722 ; N Cacute ; B 108 -19 782 929 ; C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ; C -1 ; WX 667 ; N Edotaccent ; B 86 0 762 901 ; C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ; C -1 ; WX 500 ; N scedilla ; B 63 -225 529 538 ; C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ; C -1 ; WX 471 ; N lozenge ; B 88 0 540 728 ; C -1 ; WX 722 ; N Rcaron ; B 88 0 773 929 ; C -1 ; WX 778 ; N Gcommaaccent ; B 111 -225 799 737 ; C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ; C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ; C -1 ; WX 667 ; N Amacron ; B 14 0 677 879 ; C -1 ; WX 333 ; N rcaron ; B 77 0 508 734 ; C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ; C -1 ; WX 611 ; N Zdotaccent ; B 23 0 741 901 ; C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ; C -1 ; WX 778 ; N Omacron ; B 105 -19 826 879 ; C -1 ; WX 722 ; N Racute ; B 88 0 773 929 ; C -1 ; WX 667 ; N Sacute ; B 90 -19 713 929 ; C -1 ; WX 643 ; N dcaron ; B 84 -15 808 718 ; C -1 ; WX 722 ; N Umacron ; B 123 -19 797 879 ; C -1 ; WX 556 ; N uring ; B 94 -15 600 756 ; C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ; C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ; C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; C -1 ; WX 667 ; N Abreve ; B 14 0 685 926 ; C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ; C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ; C -1 ; WX 611 ; N Tcaron ; B 148 0 750 929 ; C -1 ; WX 476 ; N partialdiff ; B 41 -38 550 714 ; C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ; C -1 ; WX 722 ; N Nacute ; B 76 0 799 929 ; C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ; C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ; C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ; C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ; C -1 ; WX 500 ; N cacute ; B 74 -15 559 734 ; C -1 ; WX 556 ; N nacute ; B 65 0 587 734 ; C -1 ; WX 556 ; N umacron ; B 94 -15 600 684 ; C -1 ; WX 722 ; N Ncaron ; B 76 0 799 929 ; C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ; C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ; C -1 ; WX 260 ; N brokenbar ; B 62 -150 316 700 ; C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ; C -1 ; WX 778 ; N Gbreve ; B 111 -19 799 926 ; C -1 ; WX 278 ; N Idotaccent ; B 91 0 377 901 ; C -1 ; WX 600 ; N summation ; B 15 -10 671 706 ; C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ; C -1 ; WX 333 ; N racute ; B 77 0 475 734 ; C -1 ; WX 556 ; N omacron ; B 83 -14 585 684 ; C -1 ; WX 611 ; N Zacute ; B 23 0 741 929 ; C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 620 674 ; C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ; C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ; C -1 ; WX 222 ; N lcommaaccent ; B 25 -225 308 718 ; C -1 ; WX 317 ; N tcaron ; B 102 -7 501 808 ; C -1 ; WX 556 ; N eogonek ; B 84 -225 578 538 ; C -1 ; WX 722 ; N Uogonek ; B 123 -225 797 718 ; C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ; C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ; C -1 ; WX 500 ; N zacute ; B 31 0 571 734 ; C -1 ; WX 222 ; N iogonek ; B -61 -225 308 718 ; C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ; C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ; C -1 ; WX 556 ; N amacron ; B 61 -15 580 684 ; C -1 ; WX 500 ; N sacute ; B 63 -15 559 734 ; C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ; C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ; C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ; C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ; C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ; C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ; C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ; C -1 ; WX 556 ; N ohungarumlaut ; B 83 -14 677 734 ; C -1 ; WX 667 ; N Eogonek ; B 86 -220 762 718 ; C -1 ; WX 556 ; N dcroat ; B 84 -15 689 718 ; C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ; C -1 ; WX 667 ; N Scedilla ; B 90 -225 713 737 ; C -1 ; WX 299 ; N lcaron ; B 67 0 464 718 ; C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 808 718 ; C -1 ; WX 556 ; N Lacute ; B 76 0 555 929 ; C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ; C -1 ; WX 556 ; N edotaccent ; B 84 -15 578 706 ; C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ; C -1 ; WX 278 ; N Imacron ; B 91 0 483 879 ; C -1 ; WX 556 ; N Lcaron ; B 76 0 570 718 ; C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ; C -1 ; WX 549 ; N lessequal ; B 26 0 666 674 ; C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ; C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 123 -19 801 929 ; C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ; C -1 ; WX 556 ; N emacron ; B 84 -15 580 684 ; C -1 ; WX 556 ; N gbreve ; B 42 -220 610 731 ; C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ; C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ; C -1 ; WX 667 ; N Scommaaccent ; B 90 -225 713 737 ; C -1 ; WX 778 ; N Ohungarumlaut ; B 105 -19 829 929 ; C -1 ; WX 400 ; N degree ; B 169 411 468 703 ; C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ; C -1 ; WX 722 ; N Ccaron ; B 108 -19 782 929 ; C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ; C -1 ; WX 453 ; N radical ; B 79 -80 617 762 ; C -1 ; WX 722 ; N Dcaron ; B 81 0 764 929 ; C -1 ; WX 333 ; N rcommaaccent ; B 30 -225 446 538 ; C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ; C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ; C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 773 718 ; C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 555 718 ; C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ; C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ; C -1 ; WX 500 ; N zdotaccent ; B 31 0 571 706 ; C -1 ; WX 667 ; N Ecaron ; B 86 0 762 929 ; C -1 ; WX 278 ; N Iogonek ; B -33 -225 341 718 ; C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 600 718 ; C -1 ; WX 584 ; N minus ; B 85 216 606 289 ; C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ; C -1 ; WX 556 ; N ncaron ; B 65 0 580 734 ; C -1 ; WX 278 ; N tcommaaccent ; B 63 -225 368 669 ; C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ; C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ; C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ; C -1 ; WX 549 ; N notequal ; B 34 -35 623 551 ; C -1 ; WX 556 ; N gcommaaccent ; B 42 -220 610 822 ; C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ; C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ; C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 573 538 ; C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ; C -1 ; WX 278 ; N imacron ; B 95 0 417 684 ; C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2705 KPX A C -30 KPX A Cacute -30 KPX A Ccaron -30 KPX A Ccedilla -30 KPX A G -30 KPX A Gbreve -30 KPX A Gcommaaccent -30 KPX A O -30 KPX A Oacute -30 KPX A Ocircumflex -30 KPX A Odieresis -30 KPX A Ograve -30 KPX A Ohungarumlaut -30 KPX A Omacron -30 KPX A Oslash -30 KPX A Otilde -30 KPX A Q -30 KPX A T -120 KPX A Tcaron -120 KPX A Tcommaaccent -120 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -70 KPX A W -50 KPX A Y -100 KPX A Yacute -100 KPX A Ydieresis -100 KPX A u -30 KPX A uacute -30 KPX A ucircumflex -30 KPX A udieresis -30 KPX A ugrave -30 KPX A uhungarumlaut -30 KPX A umacron -30 KPX A uogonek -30 KPX A uring -30 KPX A v -40 KPX A w -40 KPX A y -40 KPX A yacute -40 KPX A ydieresis -40 KPX Aacute C -30 KPX Aacute Cacute -30 KPX Aacute Ccaron -30 KPX Aacute Ccedilla -30 KPX Aacute G -30 KPX Aacute Gbreve -30 KPX Aacute Gcommaaccent -30 KPX Aacute O -30 KPX Aacute Oacute -30 KPX Aacute Ocircumflex -30 KPX Aacute Odieresis -30 KPX Aacute Ograve -30 KPX Aacute Ohungarumlaut -30 KPX Aacute Omacron -30 KPX Aacute Oslash -30 KPX Aacute Otilde -30 KPX Aacute Q -30 KPX Aacute T -120 KPX Aacute Tcaron -120 KPX Aacute Tcommaaccent -120 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -70 KPX Aacute W -50 KPX Aacute Y -100 KPX Aacute Yacute -100 KPX Aacute Ydieresis -100 KPX Aacute u -30 KPX Aacute uacute -30 KPX Aacute ucircumflex -30 KPX Aacute udieresis -30 KPX Aacute ugrave -30 KPX Aacute uhungarumlaut -30 KPX Aacute umacron -30 KPX Aacute uogonek -30 KPX Aacute uring -30 KPX Aacute v -40 KPX Aacute w -40 KPX Aacute y -40 KPX Aacute yacute -40 KPX Aacute ydieresis -40 KPX Abreve C -30 KPX Abreve Cacute -30 KPX Abreve Ccaron -30 KPX Abreve Ccedilla -30 KPX Abreve G -30 KPX Abreve Gbreve -30 KPX Abreve Gcommaaccent -30 KPX Abreve O -30 KPX Abreve Oacute -30 KPX Abreve Ocircumflex -30 KPX Abreve Odieresis -30 KPX Abreve Ograve -30 KPX Abreve Ohungarumlaut -30 KPX Abreve Omacron -30 KPX Abreve Oslash -30 KPX Abreve Otilde -30 KPX Abreve Q -30 KPX Abreve T -120 KPX Abreve Tcaron -120 KPX Abreve Tcommaaccent -120 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -70 KPX Abreve W -50 KPX Abreve Y -100 KPX Abreve Yacute -100 KPX Abreve Ydieresis -100 KPX Abreve u -30 KPX Abreve uacute -30 KPX Abreve ucircumflex -30 KPX Abreve udieresis -30 KPX Abreve ugrave -30 KPX Abreve uhungarumlaut -30 KPX Abreve umacron -30 KPX Abreve uogonek -30 KPX Abreve uring -30 KPX Abreve v -40 KPX Abreve w -40 KPX Abreve y -40 KPX Abreve yacute -40 KPX Abreve ydieresis -40 KPX Acircumflex C -30 KPX Acircumflex Cacute -30 KPX Acircumflex Ccaron -30 KPX Acircumflex Ccedilla -30 KPX Acircumflex G -30 KPX Acircumflex Gbreve -30 KPX Acircumflex Gcommaaccent -30 KPX Acircumflex O -30 KPX Acircumflex Oacute -30 KPX Acircumflex Ocircumflex -30 KPX Acircumflex Odieresis -30 KPX Acircumflex Ograve -30 KPX Acircumflex Ohungarumlaut -30 KPX Acircumflex Omacron -30 KPX Acircumflex Oslash -30 KPX Acircumflex Otilde -30 KPX Acircumflex Q -30 KPX Acircumflex T -120 KPX Acircumflex Tcaron -120 KPX Acircumflex Tcommaaccent -120 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -70 KPX Acircumflex W -50 KPX Acircumflex Y -100 KPX Acircumflex Yacute -100 KPX Acircumflex Ydieresis -100 KPX Acircumflex u -30 KPX Acircumflex uacute -30 KPX Acircumflex ucircumflex -30 KPX Acircumflex udieresis -30 KPX Acircumflex ugrave -30 KPX Acircumflex uhungarumlaut -30 KPX Acircumflex umacron -30 KPX Acircumflex uogonek -30 KPX Acircumflex uring -30 KPX Acircumflex v -40 KPX Acircumflex w -40 KPX Acircumflex y -40 KPX Acircumflex yacute -40 KPX Acircumflex ydieresis -40 KPX Adieresis C -30 KPX Adieresis Cacute -30 KPX Adieresis Ccaron -30 KPX Adieresis Ccedilla -30 KPX Adieresis G -30 KPX Adieresis Gbreve -30 KPX Adieresis Gcommaaccent -30 KPX Adieresis O -30 KPX Adieresis Oacute -30 KPX Adieresis Ocircumflex -30 KPX Adieresis Odieresis -30 KPX Adieresis Ograve -30 KPX Adieresis Ohungarumlaut -30 KPX Adieresis Omacron -30 KPX Adieresis Oslash -30 KPX Adieresis Otilde -30 KPX Adieresis Q -30 KPX Adieresis T -120 KPX Adieresis Tcaron -120 KPX Adieresis Tcommaaccent -120 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -70 KPX Adieresis W -50 KPX Adieresis Y -100 KPX Adieresis Yacute -100 KPX Adieresis Ydieresis -100 KPX Adieresis u -30 KPX Adieresis uacute -30 KPX Adieresis ucircumflex -30 KPX Adieresis udieresis -30 KPX Adieresis ugrave -30 KPX Adieresis uhungarumlaut -30 KPX Adieresis umacron -30 KPX Adieresis uogonek -30 KPX Adieresis uring -30 KPX Adieresis v -40 KPX Adieresis w -40 KPX Adieresis y -40 KPX Adieresis yacute -40 KPX Adieresis ydieresis -40 KPX Agrave C -30 KPX Agrave Cacute -30 KPX Agrave Ccaron -30 KPX Agrave Ccedilla -30 KPX Agrave G -30 KPX Agrave Gbreve -30 KPX Agrave Gcommaaccent -30 KPX Agrave O -30 KPX Agrave Oacute -30 KPX Agrave Ocircumflex -30 KPX Agrave Odieresis -30 KPX Agrave Ograve -30 KPX Agrave Ohungarumlaut -30 KPX Agrave Omacron -30 KPX Agrave Oslash -30 KPX Agrave Otilde -30 KPX Agrave Q -30 KPX Agrave T -120 KPX Agrave Tcaron -120 KPX Agrave Tcommaaccent -120 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -70 KPX Agrave W -50 KPX Agrave Y -100 KPX Agrave Yacute -100 KPX Agrave Ydieresis -100 KPX Agrave u -30 KPX Agrave uacute -30 KPX Agrave ucircumflex -30 KPX Agrave udieresis -30 KPX Agrave ugrave -30 KPX Agrave uhungarumlaut -30 KPX Agrave umacron -30 KPX Agrave uogonek -30 KPX Agrave uring -30 KPX Agrave v -40 KPX Agrave w -40 KPX Agrave y -40 KPX Agrave yacute -40 KPX Agrave ydieresis -40 KPX Amacron C -30 KPX Amacron Cacute -30 KPX Amacron Ccaron -30 KPX Amacron Ccedilla -30 KPX Amacron G -30 KPX Amacron Gbreve -30 KPX Amacron Gcommaaccent -30 KPX Amacron O -30 KPX Amacron Oacute -30 KPX Amacron Ocircumflex -30 KPX Amacron Odieresis -30 KPX Amacron Ograve -30 KPX Amacron Ohungarumlaut -30 KPX Amacron Omacron -30 KPX Amacron Oslash -30 KPX Amacron Otilde -30 KPX Amacron Q -30 KPX Amacron T -120 KPX Amacron Tcaron -120 KPX Amacron Tcommaaccent -120 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -70 KPX Amacron W -50 KPX Amacron Y -100 KPX Amacron Yacute -100 KPX Amacron Ydieresis -100 KPX Amacron u -30 KPX Amacron uacute -30 KPX Amacron ucircumflex -30 KPX Amacron udieresis -30 KPX Amacron ugrave -30 KPX Amacron uhungarumlaut -30 KPX Amacron umacron -30 KPX Amacron uogonek -30 KPX Amacron uring -30 KPX Amacron v -40 KPX Amacron w -40 KPX Amacron y -40 KPX Amacron yacute -40 KPX Amacron ydieresis -40 KPX Aogonek C -30 KPX Aogonek Cacute -30 KPX Aogonek Ccaron -30 KPX Aogonek Ccedilla -30 KPX Aogonek G -30 KPX Aogonek Gbreve -30 KPX Aogonek Gcommaaccent -30 KPX Aogonek O -30 KPX Aogonek Oacute -30 KPX Aogonek Ocircumflex -30 KPX Aogonek Odieresis -30 KPX Aogonek Ograve -30 KPX Aogonek Ohungarumlaut -30 KPX Aogonek Omacron -30 KPX Aogonek Oslash -30 KPX Aogonek Otilde -30 KPX Aogonek Q -30 KPX Aogonek T -120 KPX Aogonek Tcaron -120 KPX Aogonek Tcommaaccent -120 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -70 KPX Aogonek W -50 KPX Aogonek Y -100 KPX Aogonek Yacute -100 KPX Aogonek Ydieresis -100 KPX Aogonek u -30 KPX Aogonek uacute -30 KPX Aogonek ucircumflex -30 KPX Aogonek udieresis -30 KPX Aogonek ugrave -30 KPX Aogonek uhungarumlaut -30 KPX Aogonek umacron -30 KPX Aogonek uogonek -30 KPX Aogonek uring -30 KPX Aogonek v -40 KPX Aogonek w -40 KPX Aogonek y -40 KPX Aogonek yacute -40 KPX Aogonek ydieresis -40 KPX Aring C -30 KPX Aring Cacute -30 KPX Aring Ccaron -30 KPX Aring Ccedilla -30 KPX Aring G -30 KPX Aring Gbreve -30 KPX Aring Gcommaaccent -30 KPX Aring O -30 KPX Aring Oacute -30 KPX Aring Ocircumflex -30 KPX Aring Odieresis -30 KPX Aring Ograve -30 KPX Aring Ohungarumlaut -30 KPX Aring Omacron -30 KPX Aring Oslash -30 KPX Aring Otilde -30 KPX Aring Q -30 KPX Aring T -120 KPX Aring Tcaron -120 KPX Aring Tcommaaccent -120 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -70 KPX Aring W -50 KPX Aring Y -100 KPX Aring Yacute -100 KPX Aring Ydieresis -100 KPX Aring u -30 KPX Aring uacute -30 KPX Aring ucircumflex -30 KPX Aring udieresis -30 KPX Aring ugrave -30 KPX Aring uhungarumlaut -30 KPX Aring umacron -30 KPX Aring uogonek -30 KPX Aring uring -30 KPX Aring v -40 KPX Aring w -40 KPX Aring y -40 KPX Aring yacute -40 KPX Aring ydieresis -40 KPX Atilde C -30 KPX Atilde Cacute -30 KPX Atilde Ccaron -30 KPX Atilde Ccedilla -30 KPX Atilde G -30 KPX Atilde Gbreve -30 KPX Atilde Gcommaaccent -30 KPX Atilde O -30 KPX Atilde Oacute -30 KPX Atilde Ocircumflex -30 KPX Atilde Odieresis -30 KPX Atilde Ograve -30 KPX Atilde Ohungarumlaut -30 KPX Atilde Omacron -30 KPX Atilde Oslash -30 KPX Atilde Otilde -30 KPX Atilde Q -30 KPX Atilde T -120 KPX Atilde Tcaron -120 KPX Atilde Tcommaaccent -120 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -70 KPX Atilde W -50 KPX Atilde Y -100 KPX Atilde Yacute -100 KPX Atilde Ydieresis -100 KPX Atilde u -30 KPX Atilde uacute -30 KPX Atilde ucircumflex -30 KPX Atilde udieresis -30 KPX Atilde ugrave -30 KPX Atilde uhungarumlaut -30 KPX Atilde umacron -30 KPX Atilde uogonek -30 KPX Atilde uring -30 KPX Atilde v -40 KPX Atilde w -40 KPX Atilde y -40 KPX Atilde yacute -40 KPX Atilde ydieresis -40 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX B comma -20 KPX B period -20 KPX C comma -30 KPX C period -30 KPX Cacute comma -30 KPX Cacute period -30 KPX Ccaron comma -30 KPX Ccaron period -30 KPX Ccedilla comma -30 KPX Ccedilla period -30 KPX D A -40 KPX D Aacute -40 KPX D Abreve -40 KPX D Acircumflex -40 KPX D Adieresis -40 KPX D Agrave -40 KPX D Amacron -40 KPX D Aogonek -40 KPX D Aring -40 KPX D Atilde -40 KPX D V -70 KPX D W -40 KPX D Y -90 KPX D Yacute -90 KPX D Ydieresis -90 KPX D comma -70 KPX D period -70 KPX Dcaron A -40 KPX Dcaron Aacute -40 KPX Dcaron Abreve -40 KPX Dcaron Acircumflex -40 KPX Dcaron Adieresis -40 KPX Dcaron Agrave -40 KPX Dcaron Amacron -40 KPX Dcaron Aogonek -40 KPX Dcaron Aring -40 KPX Dcaron Atilde -40 KPX Dcaron V -70 KPX Dcaron W -40 KPX Dcaron Y -90 KPX Dcaron Yacute -90 KPX Dcaron Ydieresis -90 KPX Dcaron comma -70 KPX Dcaron period -70 KPX Dcroat A -40 KPX Dcroat Aacute -40 KPX Dcroat Abreve -40 KPX Dcroat Acircumflex -40 KPX Dcroat Adieresis -40 KPX Dcroat Agrave -40 KPX Dcroat Amacron -40 KPX Dcroat Aogonek -40 KPX Dcroat Aring -40 KPX Dcroat Atilde -40 KPX Dcroat V -70 KPX Dcroat W -40 KPX Dcroat Y -90 KPX Dcroat Yacute -90 KPX Dcroat Ydieresis -90 KPX Dcroat comma -70 KPX Dcroat period -70 KPX F A -80 KPX F Aacute -80 KPX F Abreve -80 KPX F Acircumflex -80 KPX F Adieresis -80 KPX F Agrave -80 KPX F Amacron -80 KPX F Aogonek -80 KPX F Aring -80 KPX F Atilde -80 KPX F a -50 KPX F aacute -50 KPX F abreve -50 KPX F acircumflex -50 KPX F adieresis -50 KPX F agrave -50 KPX F amacron -50 KPX F aogonek -50 KPX F aring -50 KPX F atilde -50 KPX F comma -150 KPX F e -30 KPX F eacute -30 KPX F ecaron -30 KPX F ecircumflex -30 KPX F edieresis -30 KPX F edotaccent -30 KPX F egrave -30 KPX F emacron -30 KPX F eogonek -30 KPX F o -30 KPX F oacute -30 KPX F ocircumflex -30 KPX F odieresis -30 KPX F ograve -30 KPX F ohungarumlaut -30 KPX F omacron -30 KPX F oslash -30 KPX F otilde -30 KPX F period -150 KPX F r -45 KPX F racute -45 KPX F rcaron -45 KPX F rcommaaccent -45 KPX J A -20 KPX J Aacute -20 KPX J Abreve -20 KPX J Acircumflex -20 KPX J Adieresis -20 KPX J Agrave -20 KPX J Amacron -20 KPX J Aogonek -20 KPX J Aring -20 KPX J Atilde -20 KPX J a -20 KPX J aacute -20 KPX J abreve -20 KPX J acircumflex -20 KPX J adieresis -20 KPX J agrave -20 KPX J amacron -20 KPX J aogonek -20 KPX J aring -20 KPX J atilde -20 KPX J comma -30 KPX J period -30 KPX J u -20 KPX J uacute -20 KPX J ucircumflex -20 KPX J udieresis -20 KPX J ugrave -20 KPX J uhungarumlaut -20 KPX J umacron -20 KPX J uogonek -20 KPX J uring -20 KPX K O -50 KPX K Oacute -50 KPX K Ocircumflex -50 KPX K Odieresis -50 KPX K Ograve -50 KPX K Ohungarumlaut -50 KPX K Omacron -50 KPX K Oslash -50 KPX K Otilde -50 KPX K e -40 KPX K eacute -40 KPX K ecaron -40 KPX K ecircumflex -40 KPX K edieresis -40 KPX K edotaccent -40 KPX K egrave -40 KPX K emacron -40 KPX K eogonek -40 KPX K o -40 KPX K oacute -40 KPX K ocircumflex -40 KPX K odieresis -40 KPX K ograve -40 KPX K ohungarumlaut -40 KPX K omacron -40 KPX K oslash -40 KPX K otilde -40 KPX K u -30 KPX K uacute -30 KPX K ucircumflex -30 KPX K udieresis -30 KPX K ugrave -30 KPX K uhungarumlaut -30 KPX K umacron -30 KPX K uogonek -30 KPX K uring -30 KPX K y -50 KPX K yacute -50 KPX K ydieresis -50 KPX Kcommaaccent O -50 KPX Kcommaaccent Oacute -50 KPX Kcommaaccent Ocircumflex -50 KPX Kcommaaccent Odieresis -50 KPX Kcommaaccent Ograve -50 KPX Kcommaaccent Ohungarumlaut -50 KPX Kcommaaccent Omacron -50 KPX Kcommaaccent Oslash -50 KPX Kcommaaccent Otilde -50 KPX Kcommaaccent e -40 KPX Kcommaaccent eacute -40 KPX Kcommaaccent ecaron -40 KPX Kcommaaccent ecircumflex -40 KPX Kcommaaccent edieresis -40 KPX Kcommaaccent edotaccent -40 KPX Kcommaaccent egrave -40 KPX Kcommaaccent emacron -40 KPX Kcommaaccent eogonek -40 KPX Kcommaaccent o -40 KPX Kcommaaccent oacute -40 KPX Kcommaaccent ocircumflex -40 KPX Kcommaaccent odieresis -40 KPX Kcommaaccent ograve -40 KPX Kcommaaccent ohungarumlaut -40 KPX Kcommaaccent omacron -40 KPX Kcommaaccent oslash -40 KPX Kcommaaccent otilde -40 KPX Kcommaaccent u -30 KPX Kcommaaccent uacute -30 KPX Kcommaaccent ucircumflex -30 KPX Kcommaaccent udieresis -30 KPX Kcommaaccent ugrave -30 KPX Kcommaaccent uhungarumlaut -30 KPX Kcommaaccent umacron -30 KPX Kcommaaccent uogonek -30 KPX Kcommaaccent uring -30 KPX Kcommaaccent y -50 KPX Kcommaaccent yacute -50 KPX Kcommaaccent ydieresis -50 KPX L T -110 KPX L Tcaron -110 KPX L Tcommaaccent -110 KPX L V -110 KPX L W -70 KPX L Y -140 KPX L Yacute -140 KPX L Ydieresis -140 KPX L quotedblright -140 KPX L quoteright -160 KPX L y -30 KPX L yacute -30 KPX L ydieresis -30 KPX Lacute T -110 KPX Lacute Tcaron -110 KPX Lacute Tcommaaccent -110 KPX Lacute V -110 KPX Lacute W -70 KPX Lacute Y -140 KPX Lacute Yacute -140 KPX Lacute Ydieresis -140 KPX Lacute quotedblright -140 KPX Lacute quoteright -160 KPX Lacute y -30 KPX Lacute yacute -30 KPX Lacute ydieresis -30 KPX Lcaron T -110 KPX Lcaron Tcaron -110 KPX Lcaron Tcommaaccent -110 KPX Lcaron V -110 KPX Lcaron W -70 KPX Lcaron Y -140 KPX Lcaron Yacute -140 KPX Lcaron Ydieresis -140 KPX Lcaron quotedblright -140 KPX Lcaron quoteright -160 KPX Lcaron y -30 KPX Lcaron yacute -30 KPX Lcaron ydieresis -30 KPX Lcommaaccent T -110 KPX Lcommaaccent Tcaron -110 KPX Lcommaaccent Tcommaaccent -110 KPX Lcommaaccent V -110 KPX Lcommaaccent W -70 KPX Lcommaaccent Y -140 KPX Lcommaaccent Yacute -140 KPX Lcommaaccent Ydieresis -140 KPX Lcommaaccent quotedblright -140 KPX Lcommaaccent quoteright -160 KPX Lcommaaccent y -30 KPX Lcommaaccent yacute -30 KPX Lcommaaccent ydieresis -30 KPX Lslash T -110 KPX Lslash Tcaron -110 KPX Lslash Tcommaaccent -110 KPX Lslash V -110 KPX Lslash W -70 KPX Lslash Y -140 KPX Lslash Yacute -140 KPX Lslash Ydieresis -140 KPX Lslash quotedblright -140 KPX Lslash quoteright -160 KPX Lslash y -30 KPX Lslash yacute -30 KPX Lslash ydieresis -30 KPX O A -20 KPX O Aacute -20 KPX O Abreve -20 KPX O Acircumflex -20 KPX O Adieresis -20 KPX O Agrave -20 KPX O Amacron -20 KPX O Aogonek -20 KPX O Aring -20 KPX O Atilde -20 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -30 KPX O X -60 KPX O Y -70 KPX O Yacute -70 KPX O Ydieresis -70 KPX O comma -40 KPX O period -40 KPX Oacute A -20 KPX Oacute Aacute -20 KPX Oacute Abreve -20 KPX Oacute Acircumflex -20 KPX Oacute Adieresis -20 KPX Oacute Agrave -20 KPX Oacute Amacron -20 KPX Oacute Aogonek -20 KPX Oacute Aring -20 KPX Oacute Atilde -20 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -30 KPX Oacute X -60 KPX Oacute Y -70 KPX Oacute Yacute -70 KPX Oacute Ydieresis -70 KPX Oacute comma -40 KPX Oacute period -40 KPX Ocircumflex A -20 KPX Ocircumflex Aacute -20 KPX Ocircumflex Abreve -20 KPX Ocircumflex Acircumflex -20 KPX Ocircumflex Adieresis -20 KPX Ocircumflex Agrave -20 KPX Ocircumflex Amacron -20 KPX Ocircumflex Aogonek -20 KPX Ocircumflex Aring -20 KPX Ocircumflex Atilde -20 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -30 KPX Ocircumflex X -60 KPX Ocircumflex Y -70 KPX Ocircumflex Yacute -70 KPX Ocircumflex Ydieresis -70 KPX Ocircumflex comma -40 KPX Ocircumflex period -40 KPX Odieresis A -20 KPX Odieresis Aacute -20 KPX Odieresis Abreve -20 KPX Odieresis Acircumflex -20 KPX Odieresis Adieresis -20 KPX Odieresis Agrave -20 KPX Odieresis Amacron -20 KPX Odieresis Aogonek -20 KPX Odieresis Aring -20 KPX Odieresis Atilde -20 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -30 KPX Odieresis X -60 KPX Odieresis Y -70 KPX Odieresis Yacute -70 KPX Odieresis Ydieresis -70 KPX Odieresis comma -40 KPX Odieresis period -40 KPX Ograve A -20 KPX Ograve Aacute -20 KPX Ograve Abreve -20 KPX Ograve Acircumflex -20 KPX Ograve Adieresis -20 KPX Ograve Agrave -20 KPX Ograve Amacron -20 KPX Ograve Aogonek -20 KPX Ograve Aring -20 KPX Ograve Atilde -20 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -30 KPX Ograve X -60 KPX Ograve Y -70 KPX Ograve Yacute -70 KPX Ograve Ydieresis -70 KPX Ograve comma -40 KPX Ograve period -40 KPX Ohungarumlaut A -20 KPX Ohungarumlaut Aacute -20 KPX Ohungarumlaut Abreve -20 KPX Ohungarumlaut Acircumflex -20 KPX Ohungarumlaut Adieresis -20 KPX Ohungarumlaut Agrave -20 KPX Ohungarumlaut Amacron -20 KPX Ohungarumlaut Aogonek -20 KPX Ohungarumlaut Aring -20 KPX Ohungarumlaut Atilde -20 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -30 KPX Ohungarumlaut X -60 KPX Ohungarumlaut Y -70 KPX Ohungarumlaut Yacute -70 KPX Ohungarumlaut Ydieresis -70 KPX Ohungarumlaut comma -40 KPX Ohungarumlaut period -40 KPX Omacron A -20 KPX Omacron Aacute -20 KPX Omacron Abreve -20 KPX Omacron Acircumflex -20 KPX Omacron Adieresis -20 KPX Omacron Agrave -20 KPX Omacron Amacron -20 KPX Omacron Aogonek -20 KPX Omacron Aring -20 KPX Omacron Atilde -20 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -30 KPX Omacron X -60 KPX Omacron Y -70 KPX Omacron Yacute -70 KPX Omacron Ydieresis -70 KPX Omacron comma -40 KPX Omacron period -40 KPX Oslash A -20 KPX Oslash Aacute -20 KPX Oslash Abreve -20 KPX Oslash Acircumflex -20 KPX Oslash Adieresis -20 KPX Oslash Agrave -20 KPX Oslash Amacron -20 KPX Oslash Aogonek -20 KPX Oslash Aring -20 KPX Oslash Atilde -20 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -30 KPX Oslash X -60 KPX Oslash Y -70 KPX Oslash Yacute -70 KPX Oslash Ydieresis -70 KPX Oslash comma -40 KPX Oslash period -40 KPX Otilde A -20 KPX Otilde Aacute -20 KPX Otilde Abreve -20 KPX Otilde Acircumflex -20 KPX Otilde Adieresis -20 KPX Otilde Agrave -20 KPX Otilde Amacron -20 KPX Otilde Aogonek -20 KPX Otilde Aring -20 KPX Otilde Atilde -20 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -30 KPX Otilde X -60 KPX Otilde Y -70 KPX Otilde Yacute -70 KPX Otilde Ydieresis -70 KPX Otilde comma -40 KPX Otilde period -40 KPX P A -120 KPX P Aacute -120 KPX P Abreve -120 KPX P Acircumflex -120 KPX P Adieresis -120 KPX P Agrave -120 KPX P Amacron -120 KPX P Aogonek -120 KPX P Aring -120 KPX P Atilde -120 KPX P a -40 KPX P aacute -40 KPX P abreve -40 KPX P acircumflex -40 KPX P adieresis -40 KPX P agrave -40 KPX P amacron -40 KPX P aogonek -40 KPX P aring -40 KPX P atilde -40 KPX P comma -180 KPX P e -50 KPX P eacute -50 KPX P ecaron -50 KPX P ecircumflex -50 KPX P edieresis -50 KPX P edotaccent -50 KPX P egrave -50 KPX P emacron -50 KPX P eogonek -50 KPX P o -50 KPX P oacute -50 KPX P ocircumflex -50 KPX P odieresis -50 KPX P ograve -50 KPX P ohungarumlaut -50 KPX P omacron -50 KPX P oslash -50 KPX P otilde -50 KPX P period -180 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX R O -20 KPX R Oacute -20 KPX R Ocircumflex -20 KPX R Odieresis -20 KPX R Ograve -20 KPX R Ohungarumlaut -20 KPX R Omacron -20 KPX R Oslash -20 KPX R Otilde -20 KPX R T -30 KPX R Tcaron -30 KPX R Tcommaaccent -30 KPX R U -40 KPX R Uacute -40 KPX R Ucircumflex -40 KPX R Udieresis -40 KPX R Ugrave -40 KPX R Uhungarumlaut -40 KPX R Umacron -40 KPX R Uogonek -40 KPX R Uring -40 KPX R V -50 KPX R W -30 KPX R Y -50 KPX R Yacute -50 KPX R Ydieresis -50 KPX Racute O -20 KPX Racute Oacute -20 KPX Racute Ocircumflex -20 KPX Racute Odieresis -20 KPX Racute Ograve -20 KPX Racute Ohungarumlaut -20 KPX Racute Omacron -20 KPX Racute Oslash -20 KPX Racute Otilde -20 KPX Racute T -30 KPX Racute Tcaron -30 KPX Racute Tcommaaccent -30 KPX Racute U -40 KPX Racute Uacute -40 KPX Racute Ucircumflex -40 KPX Racute Udieresis -40 KPX Racute Ugrave -40 KPX Racute Uhungarumlaut -40 KPX Racute Umacron -40 KPX Racute Uogonek -40 KPX Racute Uring -40 KPX Racute V -50 KPX Racute W -30 KPX Racute Y -50 KPX Racute Yacute -50 KPX Racute Ydieresis -50 KPX Rcaron O -20 KPX Rcaron Oacute -20 KPX Rcaron Ocircumflex -20 KPX Rcaron Odieresis -20 KPX Rcaron Ograve -20 KPX Rcaron Ohungarumlaut -20 KPX Rcaron Omacron -20 KPX Rcaron Oslash -20 KPX Rcaron Otilde -20 KPX Rcaron T -30 KPX Rcaron Tcaron -30 KPX Rcaron Tcommaaccent -30 KPX Rcaron U -40 KPX Rcaron Uacute -40 KPX Rcaron Ucircumflex -40 KPX Rcaron Udieresis -40 KPX Rcaron Ugrave -40 KPX Rcaron Uhungarumlaut -40 KPX Rcaron Umacron -40 KPX Rcaron Uogonek -40 KPX Rcaron Uring -40 KPX Rcaron V -50 KPX Rcaron W -30 KPX Rcaron Y -50 KPX Rcaron Yacute -50 KPX Rcaron Ydieresis -50 KPX Rcommaaccent O -20 KPX Rcommaaccent Oacute -20 KPX Rcommaaccent Ocircumflex -20 KPX Rcommaaccent Odieresis -20 KPX Rcommaaccent Ograve -20 KPX Rcommaaccent Ohungarumlaut -20 KPX Rcommaaccent Omacron -20 KPX Rcommaaccent Oslash -20 KPX Rcommaaccent Otilde -20 KPX Rcommaaccent T -30 KPX Rcommaaccent Tcaron -30 KPX Rcommaaccent Tcommaaccent -30 KPX Rcommaaccent U -40 KPX Rcommaaccent Uacute -40 KPX Rcommaaccent Ucircumflex -40 KPX Rcommaaccent Udieresis -40 KPX Rcommaaccent Ugrave -40 KPX Rcommaaccent Uhungarumlaut -40 KPX Rcommaaccent Umacron -40 KPX Rcommaaccent Uogonek -40 KPX Rcommaaccent Uring -40 KPX Rcommaaccent V -50 KPX Rcommaaccent W -30 KPX Rcommaaccent Y -50 KPX Rcommaaccent Yacute -50 KPX Rcommaaccent Ydieresis -50 KPX S comma -20 KPX S period -20 KPX Sacute comma -20 KPX Sacute period -20 KPX Scaron comma -20 KPX Scaron period -20 KPX Scedilla comma -20 KPX Scedilla period -20 KPX Scommaaccent comma -20 KPX Scommaaccent period -20 KPX T A -120 KPX T Aacute -120 KPX T Abreve -120 KPX T Acircumflex -120 KPX T Adieresis -120 KPX T Agrave -120 KPX T Amacron -120 KPX T Aogonek -120 KPX T Aring -120 KPX T Atilde -120 KPX T O -40 KPX T Oacute -40 KPX T Ocircumflex -40 KPX T Odieresis -40 KPX T Ograve -40 KPX T Ohungarumlaut -40 KPX T Omacron -40 KPX T Oslash -40 KPX T Otilde -40 KPX T a -120 KPX T aacute -120 KPX T abreve -60 KPX T acircumflex -120 KPX T adieresis -120 KPX T agrave -120 KPX T amacron -60 KPX T aogonek -120 KPX T aring -120 KPX T atilde -60 KPX T colon -20 KPX T comma -120 KPX T e -120 KPX T eacute -120 KPX T ecaron -120 KPX T ecircumflex -120 KPX T edieresis -120 KPX T edotaccent -120 KPX T egrave -60 KPX T emacron -60 KPX T eogonek -120 KPX T hyphen -140 KPX T o -120 KPX T oacute -120 KPX T ocircumflex -120 KPX T odieresis -120 KPX T ograve -120 KPX T ohungarumlaut -120 KPX T omacron -60 KPX T oslash -120 KPX T otilde -60 KPX T period -120 KPX T r -120 KPX T racute -120 KPX T rcaron -120 KPX T rcommaaccent -120 KPX T semicolon -20 KPX T u -120 KPX T uacute -120 KPX T ucircumflex -120 KPX T udieresis -120 KPX T ugrave -120 KPX T uhungarumlaut -120 KPX T umacron -60 KPX T uogonek -120 KPX T uring -120 KPX T w -120 KPX T y -120 KPX T yacute -120 KPX T ydieresis -60 KPX Tcaron A -120 KPX Tcaron Aacute -120 KPX Tcaron Abreve -120 KPX Tcaron Acircumflex -120 KPX Tcaron Adieresis -120 KPX Tcaron Agrave -120 KPX Tcaron Amacron -120 KPX Tcaron Aogonek -120 KPX Tcaron Aring -120 KPX Tcaron Atilde -120 KPX Tcaron O -40 KPX Tcaron Oacute -40 KPX Tcaron Ocircumflex -40 KPX Tcaron Odieresis -40 KPX Tcaron Ograve -40 KPX Tcaron Ohungarumlaut -40 KPX Tcaron Omacron -40 KPX Tcaron Oslash -40 KPX Tcaron Otilde -40 KPX Tcaron a -120 KPX Tcaron aacute -120 KPX Tcaron abreve -60 KPX Tcaron acircumflex -120 KPX Tcaron adieresis -120 KPX Tcaron agrave -120 KPX Tcaron amacron -60 KPX Tcaron aogonek -120 KPX Tcaron aring -120 KPX Tcaron atilde -60 KPX Tcaron colon -20 KPX Tcaron comma -120 KPX Tcaron e -120 KPX Tcaron eacute -120 KPX Tcaron ecaron -120 KPX Tcaron ecircumflex -120 KPX Tcaron edieresis -120 KPX Tcaron edotaccent -120 KPX Tcaron egrave -60 KPX Tcaron emacron -60 KPX Tcaron eogonek -120 KPX Tcaron hyphen -140 KPX Tcaron o -120 KPX Tcaron oacute -120 KPX Tcaron ocircumflex -120 KPX Tcaron odieresis -120 KPX Tcaron ograve -120 KPX Tcaron ohungarumlaut -120 KPX Tcaron omacron -60 KPX Tcaron oslash -120 KPX Tcaron otilde -60 KPX Tcaron period -120 KPX Tcaron r -120 KPX Tcaron racute -120 KPX Tcaron rcaron -120 KPX Tcaron rcommaaccent -120 KPX Tcaron semicolon -20 KPX Tcaron u -120 KPX Tcaron uacute -120 KPX Tcaron ucircumflex -120 KPX Tcaron udieresis -120 KPX Tcaron ugrave -120 KPX Tcaron uhungarumlaut -120 KPX Tcaron umacron -60 KPX Tcaron uogonek -120 KPX Tcaron uring -120 KPX Tcaron w -120 KPX Tcaron y -120 KPX Tcaron yacute -120 KPX Tcaron ydieresis -60 KPX Tcommaaccent A -120 KPX Tcommaaccent Aacute -120 KPX Tcommaaccent Abreve -120 KPX Tcommaaccent Acircumflex -120 KPX Tcommaaccent Adieresis -120 KPX Tcommaaccent Agrave -120 KPX Tcommaaccent Amacron -120 KPX Tcommaaccent Aogonek -120 KPX Tcommaaccent Aring -120 KPX Tcommaaccent Atilde -120 KPX Tcommaaccent O -40 KPX Tcommaaccent Oacute -40 KPX Tcommaaccent Ocircumflex -40 KPX Tcommaaccent Odieresis -40 KPX Tcommaaccent Ograve -40 KPX Tcommaaccent Ohungarumlaut -40 KPX Tcommaaccent Omacron -40 KPX Tcommaaccent Oslash -40 KPX Tcommaaccent Otilde -40 KPX Tcommaaccent a -120 KPX Tcommaaccent aacute -120 KPX Tcommaaccent abreve -60 KPX Tcommaaccent acircumflex -120 KPX Tcommaaccent adieresis -120 KPX Tcommaaccent agrave -120 KPX Tcommaaccent amacron -60 KPX Tcommaaccent aogonek -120 KPX Tcommaaccent aring -120 KPX Tcommaaccent atilde -60 KPX Tcommaaccent colon -20 KPX Tcommaaccent comma -120 KPX Tcommaaccent e -120 KPX Tcommaaccent eacute -120 KPX Tcommaaccent ecaron -120 KPX Tcommaaccent ecircumflex -120 KPX Tcommaaccent edieresis -120 KPX Tcommaaccent edotaccent -120 KPX Tcommaaccent egrave -60 KPX Tcommaaccent emacron -60 KPX Tcommaaccent eogonek -120 KPX Tcommaaccent hyphen -140 KPX Tcommaaccent o -120 KPX Tcommaaccent oacute -120 KPX Tcommaaccent ocircumflex -120 KPX Tcommaaccent odieresis -120 KPX Tcommaaccent ograve -120 KPX Tcommaaccent ohungarumlaut -120 KPX Tcommaaccent omacron -60 KPX Tcommaaccent oslash -120 KPX Tcommaaccent otilde -60 KPX Tcommaaccent period -120 KPX Tcommaaccent r -120 KPX Tcommaaccent racute -120 KPX Tcommaaccent rcaron -120 KPX Tcommaaccent rcommaaccent -120 KPX Tcommaaccent semicolon -20 KPX Tcommaaccent u -120 KPX Tcommaaccent uacute -120 KPX Tcommaaccent ucircumflex -120 KPX Tcommaaccent udieresis -120 KPX Tcommaaccent ugrave -120 KPX Tcommaaccent uhungarumlaut -120 KPX Tcommaaccent umacron -60 KPX Tcommaaccent uogonek -120 KPX Tcommaaccent uring -120 KPX Tcommaaccent w -120 KPX Tcommaaccent y -120 KPX Tcommaaccent yacute -120 KPX Tcommaaccent ydieresis -60 KPX U A -40 KPX U Aacute -40 KPX U Abreve -40 KPX U Acircumflex -40 KPX U Adieresis -40 KPX U Agrave -40 KPX U Amacron -40 KPX U Aogonek -40 KPX U Aring -40 KPX U Atilde -40 KPX U comma -40 KPX U period -40 KPX Uacute A -40 KPX Uacute Aacute -40 KPX Uacute Abreve -40 KPX Uacute Acircumflex -40 KPX Uacute Adieresis -40 KPX Uacute Agrave -40 KPX Uacute Amacron -40 KPX Uacute Aogonek -40 KPX Uacute Aring -40 KPX Uacute Atilde -40 KPX Uacute comma -40 KPX Uacute period -40 KPX Ucircumflex A -40 KPX Ucircumflex Aacute -40 KPX Ucircumflex Abreve -40 KPX Ucircumflex Acircumflex -40 KPX Ucircumflex Adieresis -40 KPX Ucircumflex Agrave -40 KPX Ucircumflex Amacron -40 KPX Ucircumflex Aogonek -40 KPX Ucircumflex Aring -40 KPX Ucircumflex Atilde -40 KPX Ucircumflex comma -40 KPX Ucircumflex period -40 KPX Udieresis A -40 KPX Udieresis Aacute -40 KPX Udieresis Abreve -40 KPX Udieresis Acircumflex -40 KPX Udieresis Adieresis -40 KPX Udieresis Agrave -40 KPX Udieresis Amacron -40 KPX Udieresis Aogonek -40 KPX Udieresis Aring -40 KPX Udieresis Atilde -40 KPX Udieresis comma -40 KPX Udieresis period -40 KPX Ugrave A -40 KPX Ugrave Aacute -40 KPX Ugrave Abreve -40 KPX Ugrave Acircumflex -40 KPX Ugrave Adieresis -40 KPX Ugrave Agrave -40 KPX Ugrave Amacron -40 KPX Ugrave Aogonek -40 KPX Ugrave Aring -40 KPX Ugrave Atilde -40 KPX Ugrave comma -40 KPX Ugrave period -40 KPX Uhungarumlaut A -40 KPX Uhungarumlaut Aacute -40 KPX Uhungarumlaut Abreve -40 KPX Uhungarumlaut Acircumflex -40 KPX Uhungarumlaut Adieresis -40 KPX Uhungarumlaut Agrave -40 KPX Uhungarumlaut Amacron -40 KPX Uhungarumlaut Aogonek -40 KPX Uhungarumlaut Aring -40 KPX Uhungarumlaut Atilde -40 KPX Uhungarumlaut comma -40 KPX Uhungarumlaut period -40 KPX Umacron A -40 KPX Umacron Aacute -40 KPX Umacron Abreve -40 KPX Umacron Acircumflex -40 KPX Umacron Adieresis -40 KPX Umacron Agrave -40 KPX Umacron Amacron -40 KPX Umacron Aogonek -40 KPX Umacron Aring -40 KPX Umacron Atilde -40 KPX Umacron comma -40 KPX Umacron period -40 KPX Uogonek A -40 KPX Uogonek Aacute -40 KPX Uogonek Abreve -40 KPX Uogonek Acircumflex -40 KPX Uogonek Adieresis -40 KPX Uogonek Agrave -40 KPX Uogonek Amacron -40 KPX Uogonek Aogonek -40 KPX Uogonek Aring -40 KPX Uogonek Atilde -40 KPX Uogonek comma -40 KPX Uogonek period -40 KPX Uring A -40 KPX Uring Aacute -40 KPX Uring Abreve -40 KPX Uring Acircumflex -40 KPX Uring Adieresis -40 KPX Uring Agrave -40 KPX Uring Amacron -40 KPX Uring Aogonek -40 KPX Uring Aring -40 KPX Uring Atilde -40 KPX Uring comma -40 KPX Uring period -40 KPX V A -80 KPX V Aacute -80 KPX V Abreve -80 KPX V Acircumflex -80 KPX V Adieresis -80 KPX V Agrave -80 KPX V Amacron -80 KPX V Aogonek -80 KPX V Aring -80 KPX V Atilde -80 KPX V G -40 KPX V Gbreve -40 KPX V Gcommaaccent -40 KPX V O -40 KPX V Oacute -40 KPX V Ocircumflex -40 KPX V Odieresis -40 KPX V Ograve -40 KPX V Ohungarumlaut -40 KPX V Omacron -40 KPX V Oslash -40 KPX V Otilde -40 KPX V a -70 KPX V aacute -70 KPX V abreve -70 KPX V acircumflex -70 KPX V adieresis -70 KPX V agrave -70 KPX V amacron -70 KPX V aogonek -70 KPX V aring -70 KPX V atilde -70 KPX V colon -40 KPX V comma -125 KPX V e -80 KPX V eacute -80 KPX V ecaron -80 KPX V ecircumflex -80 KPX V edieresis -80 KPX V edotaccent -80 KPX V egrave -80 KPX V emacron -80 KPX V eogonek -80 KPX V hyphen -80 KPX V o -80 KPX V oacute -80 KPX V ocircumflex -80 KPX V odieresis -80 KPX V ograve -80 KPX V ohungarumlaut -80 KPX V omacron -80 KPX V oslash -80 KPX V otilde -80 KPX V period -125 KPX V semicolon -40 KPX V u -70 KPX V uacute -70 KPX V ucircumflex -70 KPX V udieresis -70 KPX V ugrave -70 KPX V uhungarumlaut -70 KPX V umacron -70 KPX V uogonek -70 KPX V uring -70 KPX W A -50 KPX W Aacute -50 KPX W Abreve -50 KPX W Acircumflex -50 KPX W Adieresis -50 KPX W Agrave -50 KPX W Amacron -50 KPX W Aogonek -50 KPX W Aring -50 KPX W Atilde -50 KPX W O -20 KPX W Oacute -20 KPX W Ocircumflex -20 KPX W Odieresis -20 KPX W Ograve -20 KPX W Ohungarumlaut -20 KPX W Omacron -20 KPX W Oslash -20 KPX W Otilde -20 KPX W a -40 KPX W aacute -40 KPX W abreve -40 KPX W acircumflex -40 KPX W adieresis -40 KPX W agrave -40 KPX W amacron -40 KPX W aogonek -40 KPX W aring -40 KPX W atilde -40 KPX W comma -80 KPX W e -30 KPX W eacute -30 KPX W ecaron -30 KPX W ecircumflex -30 KPX W edieresis -30 KPX W edotaccent -30 KPX W egrave -30 KPX W emacron -30 KPX W eogonek -30 KPX W hyphen -40 KPX W o -30 KPX W oacute -30 KPX W ocircumflex -30 KPX W odieresis -30 KPX W ograve -30 KPX W ohungarumlaut -30 KPX W omacron -30 KPX W oslash -30 KPX W otilde -30 KPX W period -80 KPX W u -30 KPX W uacute -30 KPX W ucircumflex -30 KPX W udieresis -30 KPX W ugrave -30 KPX W uhungarumlaut -30 KPX W umacron -30 KPX W uogonek -30 KPX W uring -30 KPX W y -20 KPX W yacute -20 KPX W ydieresis -20 KPX Y A -110 KPX Y Aacute -110 KPX Y Abreve -110 KPX Y Acircumflex -110 KPX Y Adieresis -110 KPX Y Agrave -110 KPX Y Amacron -110 KPX Y Aogonek -110 KPX Y Aring -110 KPX Y Atilde -110 KPX Y O -85 KPX Y Oacute -85 KPX Y Ocircumflex -85 KPX Y Odieresis -85 KPX Y Ograve -85 KPX Y Ohungarumlaut -85 KPX Y Omacron -85 KPX Y Oslash -85 KPX Y Otilde -85 KPX Y a -140 KPX Y aacute -140 KPX Y abreve -70 KPX Y acircumflex -140 KPX Y adieresis -140 KPX Y agrave -140 KPX Y amacron -70 KPX Y aogonek -140 KPX Y aring -140 KPX Y atilde -140 KPX Y colon -60 KPX Y comma -140 KPX Y e -140 KPX Y eacute -140 KPX Y ecaron -140 KPX Y ecircumflex -140 KPX Y edieresis -140 KPX Y edotaccent -140 KPX Y egrave -140 KPX Y emacron -70 KPX Y eogonek -140 KPX Y hyphen -140 KPX Y i -20 KPX Y iacute -20 KPX Y iogonek -20 KPX Y o -140 KPX Y oacute -140 KPX Y ocircumflex -140 KPX Y odieresis -140 KPX Y ograve -140 KPX Y ohungarumlaut -140 KPX Y omacron -140 KPX Y oslash -140 KPX Y otilde -140 KPX Y period -140 KPX Y semicolon -60 KPX Y u -110 KPX Y uacute -110 KPX Y ucircumflex -110 KPX Y udieresis -110 KPX Y ugrave -110 KPX Y uhungarumlaut -110 KPX Y umacron -110 KPX Y uogonek -110 KPX Y uring -110 KPX Yacute A -110 KPX Yacute Aacute -110 KPX Yacute Abreve -110 KPX Yacute Acircumflex -110 KPX Yacute Adieresis -110 KPX Yacute Agrave -110 KPX Yacute Amacron -110 KPX Yacute Aogonek -110 KPX Yacute Aring -110 KPX Yacute Atilde -110 KPX Yacute O -85 KPX Yacute Oacute -85 KPX Yacute Ocircumflex -85 KPX Yacute Odieresis -85 KPX Yacute Ograve -85 KPX Yacute Ohungarumlaut -85 KPX Yacute Omacron -85 KPX Yacute Oslash -85 KPX Yacute Otilde -85 KPX Yacute a -140 KPX Yacute aacute -140 KPX Yacute abreve -70 KPX Yacute acircumflex -140 KPX Yacute adieresis -140 KPX Yacute agrave -140 KPX Yacute amacron -70 KPX Yacute aogonek -140 KPX Yacute aring -140 KPX Yacute atilde -70 KPX Yacute colon -60 KPX Yacute comma -140 KPX Yacute e -140 KPX Yacute eacute -140 KPX Yacute ecaron -140 KPX Yacute ecircumflex -140 KPX Yacute edieresis -140 KPX Yacute edotaccent -140 KPX Yacute egrave -140 KPX Yacute emacron -70 KPX Yacute eogonek -140 KPX Yacute hyphen -140 KPX Yacute i -20 KPX Yacute iacute -20 KPX Yacute iogonek -20 KPX Yacute o -140 KPX Yacute oacute -140 KPX Yacute ocircumflex -140 KPX Yacute odieresis -140 KPX Yacute ograve -140 KPX Yacute ohungarumlaut -140 KPX Yacute omacron -70 KPX Yacute oslash -140 KPX Yacute otilde -140 KPX Yacute period -140 KPX Yacute semicolon -60 KPX Yacute u -110 KPX Yacute uacute -110 KPX Yacute ucircumflex -110 KPX Yacute udieresis -110 KPX Yacute ugrave -110 KPX Yacute uhungarumlaut -110 KPX Yacute umacron -110 KPX Yacute uogonek -110 KPX Yacute uring -110 KPX Ydieresis A -110 KPX Ydieresis Aacute -110 KPX Ydieresis Abreve -110 KPX Ydieresis Acircumflex -110 KPX Ydieresis Adieresis -110 KPX Ydieresis Agrave -110 KPX Ydieresis Amacron -110 KPX Ydieresis Aogonek -110 KPX Ydieresis Aring -110 KPX Ydieresis Atilde -110 KPX Ydieresis O -85 KPX Ydieresis Oacute -85 KPX Ydieresis Ocircumflex -85 KPX Ydieresis Odieresis -85 KPX Ydieresis Ograve -85 KPX Ydieresis Ohungarumlaut -85 KPX Ydieresis Omacron -85 KPX Ydieresis Oslash -85 KPX Ydieresis Otilde -85 KPX Ydieresis a -140 KPX Ydieresis aacute -140 KPX Ydieresis abreve -70 KPX Ydieresis acircumflex -140 KPX Ydieresis adieresis -140 KPX Ydieresis agrave -140 KPX Ydieresis amacron -70 KPX Ydieresis aogonek -140 KPX Ydieresis aring -140 KPX Ydieresis atilde -70 KPX Ydieresis colon -60 KPX Ydieresis comma -140 KPX Ydieresis e -140 KPX Ydieresis eacute -140 KPX Ydieresis ecaron -140 KPX Ydieresis ecircumflex -140 KPX Ydieresis edieresis -140 KPX Ydieresis edotaccent -140 KPX Ydieresis egrave -140 KPX Ydieresis emacron -70 KPX Ydieresis eogonek -140 KPX Ydieresis hyphen -140 KPX Ydieresis i -20 KPX Ydieresis iacute -20 KPX Ydieresis iogonek -20 KPX Ydieresis o -140 KPX Ydieresis oacute -140 KPX Ydieresis ocircumflex -140 KPX Ydieresis odieresis -140 KPX Ydieresis ograve -140 KPX Ydieresis ohungarumlaut -140 KPX Ydieresis omacron -140 KPX Ydieresis oslash -140 KPX Ydieresis otilde -140 KPX Ydieresis period -140 KPX Ydieresis semicolon -60 KPX Ydieresis u -110 KPX Ydieresis uacute -110 KPX Ydieresis ucircumflex -110 KPX Ydieresis udieresis -110 KPX Ydieresis ugrave -110 KPX Ydieresis uhungarumlaut -110 KPX Ydieresis umacron -110 KPX Ydieresis uogonek -110 KPX Ydieresis uring -110 KPX a v -20 KPX a w -20 KPX a y -30 KPX a yacute -30 KPX a ydieresis -30 KPX aacute v -20 KPX aacute w -20 KPX aacute y -30 KPX aacute yacute -30 KPX aacute ydieresis -30 KPX abreve v -20 KPX abreve w -20 KPX abreve y -30 KPX abreve yacute -30 KPX abreve ydieresis -30 KPX acircumflex v -20 KPX acircumflex w -20 KPX acircumflex y -30 KPX acircumflex yacute -30 KPX acircumflex ydieresis -30 KPX adieresis v -20 KPX adieresis w -20 KPX adieresis y -30 KPX adieresis yacute -30 KPX adieresis ydieresis -30 KPX agrave v -20 KPX agrave w -20 KPX agrave y -30 KPX agrave yacute -30 KPX agrave ydieresis -30 KPX amacron v -20 KPX amacron w -20 KPX amacron y -30 KPX amacron yacute -30 KPX amacron ydieresis -30 KPX aogonek v -20 KPX aogonek w -20 KPX aogonek y -30 KPX aogonek yacute -30 KPX aogonek ydieresis -30 KPX aring v -20 KPX aring w -20 KPX aring y -30 KPX aring yacute -30 KPX aring ydieresis -30 KPX atilde v -20 KPX atilde w -20 KPX atilde y -30 KPX atilde yacute -30 KPX atilde ydieresis -30 KPX b b -10 KPX b comma -40 KPX b l -20 KPX b lacute -20 KPX b lcommaaccent -20 KPX b lslash -20 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -20 KPX b y -20 KPX b yacute -20 KPX b ydieresis -20 KPX c comma -15 KPX c k -20 KPX c kcommaaccent -20 KPX cacute comma -15 KPX cacute k -20 KPX cacute kcommaaccent -20 KPX ccaron comma -15 KPX ccaron k -20 KPX ccaron kcommaaccent -20 KPX ccedilla comma -15 KPX ccedilla k -20 KPX ccedilla kcommaaccent -20 KPX colon space -50 KPX comma quotedblright -100 KPX comma quoteright -100 KPX e comma -15 KPX e period -15 KPX e v -30 KPX e w -20 KPX e x -30 KPX e y -20 KPX e yacute -20 KPX e ydieresis -20 KPX eacute comma -15 KPX eacute period -15 KPX eacute v -30 KPX eacute w -20 KPX eacute x -30 KPX eacute y -20 KPX eacute yacute -20 KPX eacute ydieresis -20 KPX ecaron comma -15 KPX ecaron period -15 KPX ecaron v -30 KPX ecaron w -20 KPX ecaron x -30 KPX ecaron y -20 KPX ecaron yacute -20 KPX ecaron ydieresis -20 KPX ecircumflex comma -15 KPX ecircumflex period -15 KPX ecircumflex v -30 KPX ecircumflex w -20 KPX ecircumflex x -30 KPX ecircumflex y -20 KPX ecircumflex yacute -20 KPX ecircumflex ydieresis -20 KPX edieresis comma -15 KPX edieresis period -15 KPX edieresis v -30 KPX edieresis w -20 KPX edieresis x -30 KPX edieresis y -20 KPX edieresis yacute -20 KPX edieresis ydieresis -20 KPX edotaccent comma -15 KPX edotaccent period -15 KPX edotaccent v -30 KPX edotaccent w -20 KPX edotaccent x -30 KPX edotaccent y -20 KPX edotaccent yacute -20 KPX edotaccent ydieresis -20 KPX egrave comma -15 KPX egrave period -15 KPX egrave v -30 KPX egrave w -20 KPX egrave x -30 KPX egrave y -20 KPX egrave yacute -20 KPX egrave ydieresis -20 KPX emacron comma -15 KPX emacron period -15 KPX emacron v -30 KPX emacron w -20 KPX emacron x -30 KPX emacron y -20 KPX emacron yacute -20 KPX emacron ydieresis -20 KPX eogonek comma -15 KPX eogonek period -15 KPX eogonek v -30 KPX eogonek w -20 KPX eogonek x -30 KPX eogonek y -20 KPX eogonek yacute -20 KPX eogonek ydieresis -20 KPX f a -30 KPX f aacute -30 KPX f abreve -30 KPX f acircumflex -30 KPX f adieresis -30 KPX f agrave -30 KPX f amacron -30 KPX f aogonek -30 KPX f aring -30 KPX f atilde -30 KPX f comma -30 KPX f dotlessi -28 KPX f e -30 KPX f eacute -30 KPX f ecaron -30 KPX f ecircumflex -30 KPX f edieresis -30 KPX f edotaccent -30 KPX f egrave -30 KPX f emacron -30 KPX f eogonek -30 KPX f o -30 KPX f oacute -30 KPX f ocircumflex -30 KPX f odieresis -30 KPX f ograve -30 KPX f ohungarumlaut -30 KPX f omacron -30 KPX f oslash -30 KPX f otilde -30 KPX f period -30 KPX f quotedblright 60 KPX f quoteright 50 KPX g r -10 KPX g racute -10 KPX g rcaron -10 KPX g rcommaaccent -10 KPX gbreve r -10 KPX gbreve racute -10 KPX gbreve rcaron -10 KPX gbreve rcommaaccent -10 KPX gcommaaccent r -10 KPX gcommaaccent racute -10 KPX gcommaaccent rcaron -10 KPX gcommaaccent rcommaaccent -10 KPX h y -30 KPX h yacute -30 KPX h ydieresis -30 KPX k e -20 KPX k eacute -20 KPX k ecaron -20 KPX k ecircumflex -20 KPX k edieresis -20 KPX k edotaccent -20 KPX k egrave -20 KPX k emacron -20 KPX k eogonek -20 KPX k o -20 KPX k oacute -20 KPX k ocircumflex -20 KPX k odieresis -20 KPX k ograve -20 KPX k ohungarumlaut -20 KPX k omacron -20 KPX k oslash -20 KPX k otilde -20 KPX kcommaaccent e -20 KPX kcommaaccent eacute -20 KPX kcommaaccent ecaron -20 KPX kcommaaccent ecircumflex -20 KPX kcommaaccent edieresis -20 KPX kcommaaccent edotaccent -20 KPX kcommaaccent egrave -20 KPX kcommaaccent emacron -20 KPX kcommaaccent eogonek -20 KPX kcommaaccent o -20 KPX kcommaaccent oacute -20 KPX kcommaaccent ocircumflex -20 KPX kcommaaccent odieresis -20 KPX kcommaaccent ograve -20 KPX kcommaaccent ohungarumlaut -20 KPX kcommaaccent omacron -20 KPX kcommaaccent oslash -20 KPX kcommaaccent otilde -20 KPX m u -10 KPX m uacute -10 KPX m ucircumflex -10 KPX m udieresis -10 KPX m ugrave -10 KPX m uhungarumlaut -10 KPX m umacron -10 KPX m uogonek -10 KPX m uring -10 KPX m y -15 KPX m yacute -15 KPX m ydieresis -15 KPX n u -10 KPX n uacute -10 KPX n ucircumflex -10 KPX n udieresis -10 KPX n ugrave -10 KPX n uhungarumlaut -10 KPX n umacron -10 KPX n uogonek -10 KPX n uring -10 KPX n v -20 KPX n y -15 KPX n yacute -15 KPX n ydieresis -15 KPX nacute u -10 KPX nacute uacute -10 KPX nacute ucircumflex -10 KPX nacute udieresis -10 KPX nacute ugrave -10 KPX nacute uhungarumlaut -10 KPX nacute umacron -10 KPX nacute uogonek -10 KPX nacute uring -10 KPX nacute v -20 KPX nacute y -15 KPX nacute yacute -15 KPX nacute ydieresis -15 KPX ncaron u -10 KPX ncaron uacute -10 KPX ncaron ucircumflex -10 KPX ncaron udieresis -10 KPX ncaron ugrave -10 KPX ncaron uhungarumlaut -10 KPX ncaron umacron -10 KPX ncaron uogonek -10 KPX ncaron uring -10 KPX ncaron v -20 KPX ncaron y -15 KPX ncaron yacute -15 KPX ncaron ydieresis -15 KPX ncommaaccent u -10 KPX ncommaaccent uacute -10 KPX ncommaaccent ucircumflex -10 KPX ncommaaccent udieresis -10 KPX ncommaaccent ugrave -10 KPX ncommaaccent uhungarumlaut -10 KPX ncommaaccent umacron -10 KPX ncommaaccent uogonek -10 KPX ncommaaccent uring -10 KPX ncommaaccent v -20 KPX ncommaaccent y -15 KPX ncommaaccent yacute -15 KPX ncommaaccent ydieresis -15 KPX ntilde u -10 KPX ntilde uacute -10 KPX ntilde ucircumflex -10 KPX ntilde udieresis -10 KPX ntilde ugrave -10 KPX ntilde uhungarumlaut -10 KPX ntilde umacron -10 KPX ntilde uogonek -10 KPX ntilde uring -10 KPX ntilde v -20 KPX ntilde y -15 KPX ntilde yacute -15 KPX ntilde ydieresis -15 KPX o comma -40 KPX o period -40 KPX o v -15 KPX o w -15 KPX o x -30 KPX o y -30 KPX o yacute -30 KPX o ydieresis -30 KPX oacute comma -40 KPX oacute period -40 KPX oacute v -15 KPX oacute w -15 KPX oacute x -30 KPX oacute y -30 KPX oacute yacute -30 KPX oacute ydieresis -30 KPX ocircumflex comma -40 KPX ocircumflex period -40 KPX ocircumflex v -15 KPX ocircumflex w -15 KPX ocircumflex x -30 KPX ocircumflex y -30 KPX ocircumflex yacute -30 KPX ocircumflex ydieresis -30 KPX odieresis comma -40 KPX odieresis period -40 KPX odieresis v -15 KPX odieresis w -15 KPX odieresis x -30 KPX odieresis y -30 KPX odieresis yacute -30 KPX odieresis ydieresis -30 KPX ograve comma -40 KPX ograve period -40 KPX ograve v -15 KPX ograve w -15 KPX ograve x -30 KPX ograve y -30 KPX ograve yacute -30 KPX ograve ydieresis -30 KPX ohungarumlaut comma -40 KPX ohungarumlaut period -40 KPX ohungarumlaut v -15 KPX ohungarumlaut w -15 KPX ohungarumlaut x -30 KPX ohungarumlaut y -30 KPX ohungarumlaut yacute -30 KPX ohungarumlaut ydieresis -30 KPX omacron comma -40 KPX omacron period -40 KPX omacron v -15 KPX omacron w -15 KPX omacron x -30 KPX omacron y -30 KPX omacron yacute -30 KPX omacron ydieresis -30 KPX oslash a -55 KPX oslash aacute -55 KPX oslash abreve -55 KPX oslash acircumflex -55 KPX oslash adieresis -55 KPX oslash agrave -55 KPX oslash amacron -55 KPX oslash aogonek -55 KPX oslash aring -55 KPX oslash atilde -55 KPX oslash b -55 KPX oslash c -55 KPX oslash cacute -55 KPX oslash ccaron -55 KPX oslash ccedilla -55 KPX oslash comma -95 KPX oslash d -55 KPX oslash dcroat -55 KPX oslash e -55 KPX oslash eacute -55 KPX oslash ecaron -55 KPX oslash ecircumflex -55 KPX oslash edieresis -55 KPX oslash edotaccent -55 KPX oslash egrave -55 KPX oslash emacron -55 KPX oslash eogonek -55 KPX oslash f -55 KPX oslash g -55 KPX oslash gbreve -55 KPX oslash gcommaaccent -55 KPX oslash h -55 KPX oslash i -55 KPX oslash iacute -55 KPX oslash icircumflex -55 KPX oslash idieresis -55 KPX oslash igrave -55 KPX oslash imacron -55 KPX oslash iogonek -55 KPX oslash j -55 KPX oslash k -55 KPX oslash kcommaaccent -55 KPX oslash l -55 KPX oslash lacute -55 KPX oslash lcommaaccent -55 KPX oslash lslash -55 KPX oslash m -55 KPX oslash n -55 KPX oslash nacute -55 KPX oslash ncaron -55 KPX oslash ncommaaccent -55 KPX oslash ntilde -55 KPX oslash o -55 KPX oslash oacute -55 KPX oslash ocircumflex -55 KPX oslash odieresis -55 KPX oslash ograve -55 KPX oslash ohungarumlaut -55 KPX oslash omacron -55 KPX oslash oslash -55 KPX oslash otilde -55 KPX oslash p -55 KPX oslash period -95 KPX oslash q -55 KPX oslash r -55 KPX oslash racute -55 KPX oslash rcaron -55 KPX oslash rcommaaccent -55 KPX oslash s -55 KPX oslash sacute -55 KPX oslash scaron -55 KPX oslash scedilla -55 KPX oslash scommaaccent -55 KPX oslash t -55 KPX oslash tcommaaccent -55 KPX oslash u -55 KPX oslash uacute -55 KPX oslash ucircumflex -55 KPX oslash udieresis -55 KPX oslash ugrave -55 KPX oslash uhungarumlaut -55 KPX oslash umacron -55 KPX oslash uogonek -55 KPX oslash uring -55 KPX oslash v -70 KPX oslash w -70 KPX oslash x -85 KPX oslash y -70 KPX oslash yacute -70 KPX oslash ydieresis -70 KPX oslash z -55 KPX oslash zacute -55 KPX oslash zcaron -55 KPX oslash zdotaccent -55 KPX otilde comma -40 KPX otilde period -40 KPX otilde v -15 KPX otilde w -15 KPX otilde x -30 KPX otilde y -30 KPX otilde yacute -30 KPX otilde ydieresis -30 KPX p comma -35 KPX p period -35 KPX p y -30 KPX p yacute -30 KPX p ydieresis -30 KPX period quotedblright -100 KPX period quoteright -100 KPX period space -60 KPX quotedblright space -40 KPX quoteleft quoteleft -57 KPX quoteright d -50 KPX quoteright dcroat -50 KPX quoteright quoteright -57 KPX quoteright r -50 KPX quoteright racute -50 KPX quoteright rcaron -50 KPX quoteright rcommaaccent -50 KPX quoteright s -50 KPX quoteright sacute -50 KPX quoteright scaron -50 KPX quoteright scedilla -50 KPX quoteright scommaaccent -50 KPX quoteright space -70 KPX r a -10 KPX r aacute -10 KPX r abreve -10 KPX r acircumflex -10 KPX r adieresis -10 KPX r agrave -10 KPX r amacron -10 KPX r aogonek -10 KPX r aring -10 KPX r atilde -10 KPX r colon 30 KPX r comma -50 KPX r i 15 KPX r iacute 15 KPX r icircumflex 15 KPX r idieresis 15 KPX r igrave 15 KPX r imacron 15 KPX r iogonek 15 KPX r k 15 KPX r kcommaaccent 15 KPX r l 15 KPX r lacute 15 KPX r lcommaaccent 15 KPX r lslash 15 KPX r m 25 KPX r n 25 KPX r nacute 25 KPX r ncaron 25 KPX r ncommaaccent 25 KPX r ntilde 25 KPX r p 30 KPX r period -50 KPX r semicolon 30 KPX r t 40 KPX r tcommaaccent 40 KPX r u 15 KPX r uacute 15 KPX r ucircumflex 15 KPX r udieresis 15 KPX r ugrave 15 KPX r uhungarumlaut 15 KPX r umacron 15 KPX r uogonek 15 KPX r uring 15 KPX r v 30 KPX r y 30 KPX r yacute 30 KPX r ydieresis 30 KPX racute a -10 KPX racute aacute -10 KPX racute abreve -10 KPX racute acircumflex -10 KPX racute adieresis -10 KPX racute agrave -10 KPX racute amacron -10 KPX racute aogonek -10 KPX racute aring -10 KPX racute atilde -10 KPX racute colon 30 KPX racute comma -50 KPX racute i 15 KPX racute iacute 15 KPX racute icircumflex 15 KPX racute idieresis 15 KPX racute igrave 15 KPX racute imacron 15 KPX racute iogonek 15 KPX racute k 15 KPX racute kcommaaccent 15 KPX racute l 15 KPX racute lacute 15 KPX racute lcommaaccent 15 KPX racute lslash 15 KPX racute m 25 KPX racute n 25 KPX racute nacute 25 KPX racute ncaron 25 KPX racute ncommaaccent 25 KPX racute ntilde 25 KPX racute p 30 KPX racute period -50 KPX racute semicolon 30 KPX racute t 40 KPX racute tcommaaccent 40 KPX racute u 15 KPX racute uacute 15 KPX racute ucircumflex 15 KPX racute udieresis 15 KPX racute ugrave 15 KPX racute uhungarumlaut 15 KPX racute umacron 15 KPX racute uogonek 15 KPX racute uring 15 KPX racute v 30 KPX racute y 30 KPX racute yacute 30 KPX racute ydieresis 30 KPX rcaron a -10 KPX rcaron aacute -10 KPX rcaron abreve -10 KPX rcaron acircumflex -10 KPX rcaron adieresis -10 KPX rcaron agrave -10 KPX rcaron amacron -10 KPX rcaron aogonek -10 KPX rcaron aring -10 KPX rcaron atilde -10 KPX rcaron colon 30 KPX rcaron comma -50 KPX rcaron i 15 KPX rcaron iacute 15 KPX rcaron icircumflex 15 KPX rcaron idieresis 15 KPX rcaron igrave 15 KPX rcaron imacron 15 KPX rcaron iogonek 15 KPX rcaron k 15 KPX rcaron kcommaaccent 15 KPX rcaron l 15 KPX rcaron lacute 15 KPX rcaron lcommaaccent 15 KPX rcaron lslash 15 KPX rcaron m 25 KPX rcaron n 25 KPX rcaron nacute 25 KPX rcaron ncaron 25 KPX rcaron ncommaaccent 25 KPX rcaron ntilde 25 KPX rcaron p 30 KPX rcaron period -50 KPX rcaron semicolon 30 KPX rcaron t 40 KPX rcaron tcommaaccent 40 KPX rcaron u 15 KPX rcaron uacute 15 KPX rcaron ucircumflex 15 KPX rcaron udieresis 15 KPX rcaron ugrave 15 KPX rcaron uhungarumlaut 15 KPX rcaron umacron 15 KPX rcaron uogonek 15 KPX rcaron uring 15 KPX rcaron v 30 KPX rcaron y 30 KPX rcaron yacute 30 KPX rcaron ydieresis 30 KPX rcommaaccent a -10 KPX rcommaaccent aacute -10 KPX rcommaaccent abreve -10 KPX rcommaaccent acircumflex -10 KPX rcommaaccent adieresis -10 KPX rcommaaccent agrave -10 KPX rcommaaccent amacron -10 KPX rcommaaccent aogonek -10 KPX rcommaaccent aring -10 KPX rcommaaccent atilde -10 KPX rcommaaccent colon 30 KPX rcommaaccent comma -50 KPX rcommaaccent i 15 KPX rcommaaccent iacute 15 KPX rcommaaccent icircumflex 15 KPX rcommaaccent idieresis 15 KPX rcommaaccent igrave 15 KPX rcommaaccent imacron 15 KPX rcommaaccent iogonek 15 KPX rcommaaccent k 15 KPX rcommaaccent kcommaaccent 15 KPX rcommaaccent l 15 KPX rcommaaccent lacute 15 KPX rcommaaccent lcommaaccent 15 KPX rcommaaccent lslash 15 KPX rcommaaccent m 25 KPX rcommaaccent n 25 KPX rcommaaccent nacute 25 KPX rcommaaccent ncaron 25 KPX rcommaaccent ncommaaccent 25 KPX rcommaaccent ntilde 25 KPX rcommaaccent p 30 KPX rcommaaccent period -50 KPX rcommaaccent semicolon 30 KPX rcommaaccent t 40 KPX rcommaaccent tcommaaccent 40 KPX rcommaaccent u 15 KPX rcommaaccent uacute 15 KPX rcommaaccent ucircumflex 15 KPX rcommaaccent udieresis 15 KPX rcommaaccent ugrave 15 KPX rcommaaccent uhungarumlaut 15 KPX rcommaaccent umacron 15 KPX rcommaaccent uogonek 15 KPX rcommaaccent uring 15 KPX rcommaaccent v 30 KPX rcommaaccent y 30 KPX rcommaaccent yacute 30 KPX rcommaaccent ydieresis 30 KPX s comma -15 KPX s period -15 KPX s w -30 KPX sacute comma -15 KPX sacute period -15 KPX sacute w -30 KPX scaron comma -15 KPX scaron period -15 KPX scaron w -30 KPX scedilla comma -15 KPX scedilla period -15 KPX scedilla w -30 KPX scommaaccent comma -15 KPX scommaaccent period -15 KPX scommaaccent w -30 KPX semicolon space -50 KPX space T -50 KPX space Tcaron -50 KPX space Tcommaaccent -50 KPX space V -50 KPX space W -40 KPX space Y -90 KPX space Yacute -90 KPX space Ydieresis -90 KPX space quotedblleft -30 KPX space quoteleft -60 KPX v a -25 KPX v aacute -25 KPX v abreve -25 KPX v acircumflex -25 KPX v adieresis -25 KPX v agrave -25 KPX v amacron -25 KPX v aogonek -25 KPX v aring -25 KPX v atilde -25 KPX v comma -80 KPX v e -25 KPX v eacute -25 KPX v ecaron -25 KPX v ecircumflex -25 KPX v edieresis -25 KPX v edotaccent -25 KPX v egrave -25 KPX v emacron -25 KPX v eogonek -25 KPX v o -25 KPX v oacute -25 KPX v ocircumflex -25 KPX v odieresis -25 KPX v ograve -25 KPX v ohungarumlaut -25 KPX v omacron -25 KPX v oslash -25 KPX v otilde -25 KPX v period -80 KPX w a -15 KPX w aacute -15 KPX w abreve -15 KPX w acircumflex -15 KPX w adieresis -15 KPX w agrave -15 KPX w amacron -15 KPX w aogonek -15 KPX w aring -15 KPX w atilde -15 KPX w comma -60 KPX w e -10 KPX w eacute -10 KPX w ecaron -10 KPX w ecircumflex -10 KPX w edieresis -10 KPX w edotaccent -10 KPX w egrave -10 KPX w emacron -10 KPX w eogonek -10 KPX w o -10 KPX w oacute -10 KPX w ocircumflex -10 KPX w odieresis -10 KPX w ograve -10 KPX w ohungarumlaut -10 KPX w omacron -10 KPX w oslash -10 KPX w otilde -10 KPX w period -60 KPX x e -30 KPX x eacute -30 KPX x ecaron -30 KPX x ecircumflex -30 KPX x edieresis -30 KPX x edotaccent -30 KPX x egrave -30 KPX x emacron -30 KPX x eogonek -30 KPX y a -20 KPX y aacute -20 KPX y abreve -20 KPX y acircumflex -20 KPX y adieresis -20 KPX y agrave -20 KPX y amacron -20 KPX y aogonek -20 KPX y aring -20 KPX y atilde -20 KPX y comma -100 KPX y e -20 KPX y eacute -20 KPX y ecaron -20 KPX y ecircumflex -20 KPX y edieresis -20 KPX y edotaccent -20 KPX y egrave -20 KPX y emacron -20 KPX y eogonek -20 KPX y o -20 KPX y oacute -20 KPX y ocircumflex -20 KPX y odieresis -20 KPX y ograve -20 KPX y ohungarumlaut -20 KPX y omacron -20 KPX y oslash -20 KPX y otilde -20 KPX y period -100 KPX yacute a -20 KPX yacute aacute -20 KPX yacute abreve -20 KPX yacute acircumflex -20 KPX yacute adieresis -20 KPX yacute agrave -20 KPX yacute amacron -20 KPX yacute aogonek -20 KPX yacute aring -20 KPX yacute atilde -20 KPX yacute comma -100 KPX yacute e -20 KPX yacute eacute -20 KPX yacute ecaron -20 KPX yacute ecircumflex -20 KPX yacute edieresis -20 KPX yacute edotaccent -20 KPX yacute egrave -20 KPX yacute emacron -20 KPX yacute eogonek -20 KPX yacute o -20 KPX yacute oacute -20 KPX yacute ocircumflex -20 KPX yacute odieresis -20 KPX yacute ograve -20 KPX yacute ohungarumlaut -20 KPX yacute omacron -20 KPX yacute oslash -20 KPX yacute otilde -20 KPX yacute period -100 KPX ydieresis a -20 KPX ydieresis aacute -20 KPX ydieresis abreve -20 KPX ydieresis acircumflex -20 KPX ydieresis adieresis -20 KPX ydieresis agrave -20 KPX ydieresis amacron -20 KPX ydieresis aogonek -20 KPX ydieresis aring -20 KPX ydieresis atilde -20 KPX ydieresis comma -100 KPX ydieresis e -20 KPX ydieresis eacute -20 KPX ydieresis ecaron -20 KPX ydieresis ecircumflex -20 KPX ydieresis edieresis -20 KPX ydieresis edotaccent -20 KPX ydieresis egrave -20 KPX ydieresis emacron -20 KPX ydieresis eogonek -20 KPX ydieresis o -20 KPX ydieresis oacute -20 KPX ydieresis ocircumflex -20 KPX ydieresis odieresis -20 KPX ydieresis ograve -20 KPX ydieresis ohungarumlaut -20 KPX ydieresis omacron -20 KPX ydieresis oslash -20 KPX ydieresis otilde -20 KPX ydieresis period -100 KPX z e -15 KPX z eacute -15 KPX z ecaron -15 KPX z ecircumflex -15 KPX z edieresis -15 KPX z edotaccent -15 KPX z egrave -15 KPX z emacron -15 KPX z eogonek -15 KPX z o -15 KPX z oacute -15 KPX z ocircumflex -15 KPX z odieresis -15 KPX z ograve -15 KPX z ohungarumlaut -15 KPX z omacron -15 KPX z oslash -15 KPX z otilde -15 KPX zacute e -15 KPX zacute eacute -15 KPX zacute ecaron -15 KPX zacute ecircumflex -15 KPX zacute edieresis -15 KPX zacute edotaccent -15 KPX zacute egrave -15 KPX zacute emacron -15 KPX zacute eogonek -15 KPX zacute o -15 KPX zacute oacute -15 KPX zacute ocircumflex -15 KPX zacute odieresis -15 KPX zacute ograve -15 KPX zacute ohungarumlaut -15 KPX zacute omacron -15 KPX zacute oslash -15 KPX zacute otilde -15 KPX zcaron e -15 KPX zcaron eacute -15 KPX zcaron ecaron -15 KPX zcaron ecircumflex -15 KPX zcaron edieresis -15 KPX zcaron edotaccent -15 KPX zcaron egrave -15 KPX zcaron emacron -15 KPX zcaron eogonek -15 KPX zcaron o -15 KPX zcaron oacute -15 KPX zcaron ocircumflex -15 KPX zcaron odieresis -15 KPX zcaron ograve -15 KPX zcaron ohungarumlaut -15 KPX zcaron omacron -15 KPX zcaron oslash -15 KPX zcaron otilde -15 KPX zdotaccent e -15 KPX zdotaccent eacute -15 KPX zdotaccent ecaron -15 KPX zdotaccent ecircumflex -15 KPX zdotaccent edieresis -15 KPX zdotaccent edotaccent -15 KPX zdotaccent egrave -15 KPX zdotaccent emacron -15 KPX zdotaccent eogonek -15 KPX zdotaccent o -15 KPX zdotaccent oacute -15 KPX zdotaccent ocircumflex -15 KPX zdotaccent odieresis -15 KPX zdotaccent ograve -15 KPX zdotaccent ohungarumlaut -15 KPX zdotaccent omacron -15 KPX zdotaccent oslash -15 KPX zdotaccent otilde -15 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Helvetica.afm100644 0 0 227037 11000354125 17452 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:38:23 1997 Comment UniqueID 43054 Comment VMusage 37069 48094 FontName Helvetica FullName Helvetica FamilyName Helvetica Weight Medium ItalicAngle 0 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -166 -225 1000 931 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 718 XHeight 523 Ascender 718 Descender -207 StdHW 76 StdVW 88 StartCharMetrics 315 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ; C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ; C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ; C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ; C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ; C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ; C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ; C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ; C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ; C 43 ; WX 584 ; N plus ; B 39 0 545 505 ; C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ; C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ; C 46 ; WX 278 ; N period ; B 87 0 191 106 ; C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ; C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ; C 49 ; WX 556 ; N one ; B 101 0 359 703 ; C 50 ; WX 556 ; N two ; B 26 0 507 703 ; C 51 ; WX 556 ; N three ; B 34 -19 522 703 ; C 52 ; WX 556 ; N four ; B 25 0 523 703 ; C 53 ; WX 556 ; N five ; B 32 -19 514 688 ; C 54 ; WX 556 ; N six ; B 38 -19 518 703 ; C 55 ; WX 556 ; N seven ; B 37 0 523 688 ; C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ; C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ; C 58 ; WX 278 ; N colon ; B 87 0 191 516 ; C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ; C 60 ; WX 584 ; N less ; B 48 11 536 495 ; C 61 ; WX 584 ; N equal ; B 39 115 545 390 ; C 62 ; WX 584 ; N greater ; B 48 11 536 495 ; C 63 ; WX 556 ; N question ; B 56 0 492 727 ; C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ; C 65 ; WX 667 ; N A ; B 14 0 654 718 ; C 66 ; WX 667 ; N B ; B 74 0 627 718 ; C 67 ; WX 722 ; N C ; B 44 -19 681 737 ; C 68 ; WX 722 ; N D ; B 81 0 674 718 ; C 69 ; WX 667 ; N E ; B 86 0 616 718 ; C 70 ; WX 611 ; N F ; B 86 0 583 718 ; C 71 ; WX 778 ; N G ; B 48 -19 704 737 ; C 72 ; WX 722 ; N H ; B 77 0 646 718 ; C 73 ; WX 278 ; N I ; B 91 0 188 718 ; C 74 ; WX 500 ; N J ; B 17 -19 428 718 ; C 75 ; WX 667 ; N K ; B 76 0 663 718 ; C 76 ; WX 556 ; N L ; B 76 0 537 718 ; C 77 ; WX 833 ; N M ; B 73 0 761 718 ; C 78 ; WX 722 ; N N ; B 76 0 646 718 ; C 79 ; WX 778 ; N O ; B 39 -19 739 737 ; C 80 ; WX 667 ; N P ; B 86 0 622 718 ; C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ; C 82 ; WX 722 ; N R ; B 88 0 684 718 ; C 83 ; WX 667 ; N S ; B 49 -19 620 737 ; C 84 ; WX 611 ; N T ; B 14 0 597 718 ; C 85 ; WX 722 ; N U ; B 79 -19 644 718 ; C 86 ; WX 667 ; N V ; B 20 0 647 718 ; C 87 ; WX 944 ; N W ; B 16 0 928 718 ; C 88 ; WX 667 ; N X ; B 19 0 648 718 ; C 89 ; WX 667 ; N Y ; B 14 0 653 718 ; C 90 ; WX 611 ; N Z ; B 23 0 588 718 ; C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ; C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ; C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ; C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ; C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ; C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ; C 97 ; WX 556 ; N a ; B 36 -15 530 538 ; C 98 ; WX 556 ; N b ; B 58 -15 517 718 ; C 99 ; WX 500 ; N c ; B 30 -15 477 538 ; C 100 ; WX 556 ; N d ; B 35 -15 499 718 ; C 101 ; WX 556 ; N e ; B 40 -15 516 538 ; C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ; C 103 ; WX 556 ; N g ; B 40 -220 499 538 ; C 104 ; WX 556 ; N h ; B 65 0 491 718 ; C 105 ; WX 222 ; N i ; B 67 0 155 718 ; C 106 ; WX 222 ; N j ; B -16 -210 155 718 ; C 107 ; WX 500 ; N k ; B 67 0 501 718 ; C 108 ; WX 222 ; N l ; B 67 0 155 718 ; C 109 ; WX 833 ; N m ; B 65 0 769 538 ; C 110 ; WX 556 ; N n ; B 65 0 491 538 ; C 111 ; WX 556 ; N o ; B 35 -14 521 538 ; C 112 ; WX 556 ; N p ; B 58 -207 517 538 ; C 113 ; WX 556 ; N q ; B 35 -207 494 538 ; C 114 ; WX 333 ; N r ; B 77 0 332 538 ; C 115 ; WX 500 ; N s ; B 32 -15 464 538 ; C 116 ; WX 278 ; N t ; B 14 -7 257 669 ; C 117 ; WX 556 ; N u ; B 68 -15 489 523 ; C 118 ; WX 500 ; N v ; B 8 0 492 523 ; C 119 ; WX 722 ; N w ; B 14 0 709 523 ; C 120 ; WX 500 ; N x ; B 11 0 490 523 ; C 121 ; WX 500 ; N y ; B 11 -214 489 523 ; C 122 ; WX 500 ; N z ; B 31 0 469 523 ; C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ; C 124 ; WX 260 ; N bar ; B 94 -225 167 775 ; C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ; C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ; C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ; C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ; C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ; C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ; C 165 ; WX 556 ; N yen ; B 3 0 553 688 ; C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ; C 167 ; WX 556 ; N section ; B 43 -191 512 737 ; C 168 ; WX 556 ; N currency ; B 28 99 528 603 ; C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ; C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ; C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ; C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ; C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ; C 174 ; WX 500 ; N fi ; B 14 0 434 728 ; C 175 ; WX 500 ; N fl ; B 14 0 432 728 ; C 177 ; WX 556 ; N endash ; B 0 240 556 313 ; C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ; C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ; C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ; C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ; C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ; C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ; C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ; C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ; C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ; C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ; C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ; C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ; C 193 ; WX 333 ; N grave ; B 14 593 211 734 ; C 194 ; WX 333 ; N acute ; B 122 593 319 734 ; C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ; C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ; C 197 ; WX 333 ; N macron ; B 10 627 323 684 ; C 198 ; WX 333 ; N breve ; B 13 595 321 731 ; C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ; C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ; C 202 ; WX 333 ; N ring ; B 75 572 259 756 ; C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ; C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ; C 207 ; WX 333 ; N caron ; B 21 593 312 734 ; C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ; C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ; C 227 ; WX 370 ; N ordfeminine ; B 24 405 346 737 ; C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ; C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ; C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ; C 235 ; WX 365 ; N ordmasculine ; B 25 405 341 737 ; C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ; C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ; C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ; C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ; C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ; C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ; C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ; C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ; C -1 ; WX 556 ; N abreve ; B 36 -15 530 731 ; C -1 ; WX 556 ; N uhungarumlaut ; B 68 -15 521 734 ; C -1 ; WX 556 ; N ecaron ; B 40 -15 516 734 ; C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ; C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ; C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ; C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ; C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ; C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ; C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ; C -1 ; WX 500 ; N scommaaccent ; B 32 -225 464 538 ; C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ; C -1 ; WX 722 ; N Uring ; B 79 -19 644 931 ; C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ; C -1 ; WX 556 ; N aogonek ; B 36 -220 547 538 ; C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ; C -1 ; WX 556 ; N uogonek ; B 68 -225 519 523 ; C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ; C -1 ; WX 722 ; N Dcroat ; B 0 0 674 718 ; C -1 ; WX 250 ; N commaaccent ; B 87 -225 181 -40 ; C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ; C -1 ; WX 667 ; N Emacron ; B 86 0 616 879 ; C -1 ; WX 500 ; N ccaron ; B 30 -15 477 734 ; C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ; C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 646 718 ; C -1 ; WX 222 ; N lacute ; B 67 0 264 929 ; C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ; C -1 ; WX 611 ; N Tcommaaccent ; B 14 -225 597 718 ; C -1 ; WX 722 ; N Cacute ; B 44 -19 681 929 ; C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ; C -1 ; WX 667 ; N Edotaccent ; B 86 0 616 901 ; C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ; C -1 ; WX 500 ; N scedilla ; B 32 -225 464 538 ; C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ; C -1 ; WX 471 ; N lozenge ; B 10 0 462 728 ; C -1 ; WX 722 ; N Rcaron ; B 88 0 684 929 ; C -1 ; WX 778 ; N Gcommaaccent ; B 48 -225 704 737 ; C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ; C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ; C -1 ; WX 667 ; N Amacron ; B 14 0 654 879 ; C -1 ; WX 333 ; N rcaron ; B 61 0 352 734 ; C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ; C -1 ; WX 611 ; N Zdotaccent ; B 23 0 588 901 ; C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ; C -1 ; WX 778 ; N Omacron ; B 39 -19 739 879 ; C -1 ; WX 722 ; N Racute ; B 88 0 684 929 ; C -1 ; WX 667 ; N Sacute ; B 49 -19 620 929 ; C -1 ; WX 643 ; N dcaron ; B 35 -15 655 718 ; C -1 ; WX 722 ; N Umacron ; B 79 -19 644 879 ; C -1 ; WX 556 ; N uring ; B 68 -15 489 756 ; C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ; C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ; C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ; C -1 ; WX 667 ; N Abreve ; B 14 0 654 926 ; C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ; C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ; C -1 ; WX 611 ; N Tcaron ; B 14 0 597 929 ; C -1 ; WX 476 ; N partialdiff ; B 13 -38 463 714 ; C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ; C -1 ; WX 722 ; N Nacute ; B 76 0 646 929 ; C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ; C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ; C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ; C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ; C -1 ; WX 500 ; N cacute ; B 30 -15 477 734 ; C -1 ; WX 556 ; N nacute ; B 65 0 491 734 ; C -1 ; WX 556 ; N umacron ; B 68 -15 489 684 ; C -1 ; WX 722 ; N Ncaron ; B 76 0 646 929 ; C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ; C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ; C -1 ; WX 260 ; N brokenbar ; B 94 -150 167 700 ; C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ; C -1 ; WX 778 ; N Gbreve ; B 48 -19 704 926 ; C -1 ; WX 278 ; N Idotaccent ; B 91 0 188 901 ; C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ; C -1 ; WX 333 ; N racute ; B 77 0 332 734 ; C -1 ; WX 556 ; N omacron ; B 35 -14 521 684 ; C -1 ; WX 611 ; N Zacute ; B 23 0 588 929 ; C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 674 ; C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ; C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ; C -1 ; WX 222 ; N lcommaaccent ; B 67 -225 167 718 ; C -1 ; WX 317 ; N tcaron ; B 14 -7 329 808 ; C -1 ; WX 556 ; N eogonek ; B 40 -225 516 538 ; C -1 ; WX 722 ; N Uogonek ; B 79 -225 644 718 ; C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ; C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ; C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ; C -1 ; WX 500 ; N zacute ; B 31 0 469 734 ; C -1 ; WX 222 ; N iogonek ; B -31 -225 183 718 ; C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ; C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ; C -1 ; WX 556 ; N amacron ; B 36 -15 530 684 ; C -1 ; WX 500 ; N sacute ; B 32 -15 464 734 ; C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ; C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ; C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ; C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ; C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ; C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ; C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ; C -1 ; WX 556 ; N ohungarumlaut ; B 35 -14 521 734 ; C -1 ; WX 667 ; N Eogonek ; B 86 -220 633 718 ; C -1 ; WX 556 ; N dcroat ; B 35 -15 550 718 ; C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ; C -1 ; WX 667 ; N Scedilla ; B 49 -225 620 737 ; C -1 ; WX 299 ; N lcaron ; B 67 0 311 718 ; C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 663 718 ; C -1 ; WX 556 ; N Lacute ; B 76 0 537 929 ; C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ; C -1 ; WX 556 ; N edotaccent ; B 40 -15 516 706 ; C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ; C -1 ; WX 278 ; N Imacron ; B -17 0 296 879 ; C -1 ; WX 556 ; N Lcaron ; B 76 0 537 718 ; C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ; C -1 ; WX 549 ; N lessequal ; B 26 0 523 674 ; C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ; C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 79 -19 644 929 ; C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ; C -1 ; WX 556 ; N emacron ; B 40 -15 516 684 ; C -1 ; WX 556 ; N gbreve ; B 40 -220 499 731 ; C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ; C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ; C -1 ; WX 667 ; N Scommaaccent ; B 49 -225 620 737 ; C -1 ; WX 778 ; N Ohungarumlaut ; B 39 -19 739 929 ; C -1 ; WX 400 ; N degree ; B 54 411 346 703 ; C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ; C -1 ; WX 722 ; N Ccaron ; B 44 -19 681 929 ; C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ; C -1 ; WX 453 ; N radical ; B -4 -80 458 762 ; C -1 ; WX 722 ; N Dcaron ; B 81 0 674 929 ; C -1 ; WX 333 ; N rcommaaccent ; B 77 -225 332 538 ; C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ; C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ; C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 684 718 ; C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 537 718 ; C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ; C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ; C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ; C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ; C -1 ; WX 500 ; N zdotaccent ; B 31 0 469 706 ; C -1 ; WX 667 ; N Ecaron ; B 86 0 616 929 ; C -1 ; WX 278 ; N Iogonek ; B -3 -225 211 718 ; C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 501 718 ; C -1 ; WX 584 ; N minus ; B 39 216 545 289 ; C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ; C -1 ; WX 556 ; N ncaron ; B 65 0 491 734 ; C -1 ; WX 278 ; N tcommaaccent ; B 14 -225 257 669 ; C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ; C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ; C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ; C -1 ; WX 549 ; N notequal ; B 12 -35 537 551 ; C -1 ; WX 556 ; N gcommaaccent ; B 40 -220 499 822 ; C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ; C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ; C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 491 538 ; C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ; C -1 ; WX 278 ; N imacron ; B 5 0 272 684 ; C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2705 KPX A C -30 KPX A Cacute -30 KPX A Ccaron -30 KPX A Ccedilla -30 KPX A G -30 KPX A Gbreve -30 KPX A Gcommaaccent -30 KPX A O -30 KPX A Oacute -30 KPX A Ocircumflex -30 KPX A Odieresis -30 KPX A Ograve -30 KPX A Ohungarumlaut -30 KPX A Omacron -30 KPX A Oslash -30 KPX A Otilde -30 KPX A Q -30 KPX A T -120 KPX A Tcaron -120 KPX A Tcommaaccent -120 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -70 KPX A W -50 KPX A Y -100 KPX A Yacute -100 KPX A Ydieresis -100 KPX A u -30 KPX A uacute -30 KPX A ucircumflex -30 KPX A udieresis -30 KPX A ugrave -30 KPX A uhungarumlaut -30 KPX A umacron -30 KPX A uogonek -30 KPX A uring -30 KPX A v -40 KPX A w -40 KPX A y -40 KPX A yacute -40 KPX A ydieresis -40 KPX Aacute C -30 KPX Aacute Cacute -30 KPX Aacute Ccaron -30 KPX Aacute Ccedilla -30 KPX Aacute G -30 KPX Aacute Gbreve -30 KPX Aacute Gcommaaccent -30 KPX Aacute O -30 KPX Aacute Oacute -30 KPX Aacute Ocircumflex -30 KPX Aacute Odieresis -30 KPX Aacute Ograve -30 KPX Aacute Ohungarumlaut -30 KPX Aacute Omacron -30 KPX Aacute Oslash -30 KPX Aacute Otilde -30 KPX Aacute Q -30 KPX Aacute T -120 KPX Aacute Tcaron -120 KPX Aacute Tcommaaccent -120 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -70 KPX Aacute W -50 KPX Aacute Y -100 KPX Aacute Yacute -100 KPX Aacute Ydieresis -100 KPX Aacute u -30 KPX Aacute uacute -30 KPX Aacute ucircumflex -30 KPX Aacute udieresis -30 KPX Aacute ugrave -30 KPX Aacute uhungarumlaut -30 KPX Aacute umacron -30 KPX Aacute uogonek -30 KPX Aacute uring -30 KPX Aacute v -40 KPX Aacute w -40 KPX Aacute y -40 KPX Aacute yacute -40 KPX Aacute ydieresis -40 KPX Abreve C -30 KPX Abreve Cacute -30 KPX Abreve Ccaron -30 KPX Abreve Ccedilla -30 KPX Abreve G -30 KPX Abreve Gbreve -30 KPX Abreve Gcommaaccent -30 KPX Abreve O -30 KPX Abreve Oacute -30 KPX Abreve Ocircumflex -30 KPX Abreve Odieresis -30 KPX Abreve Ograve -30 KPX Abreve Ohungarumlaut -30 KPX Abreve Omacron -30 KPX Abreve Oslash -30 KPX Abreve Otilde -30 KPX Abreve Q -30 KPX Abreve T -120 KPX Abreve Tcaron -120 KPX Abreve Tcommaaccent -120 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -70 KPX Abreve W -50 KPX Abreve Y -100 KPX Abreve Yacute -100 KPX Abreve Ydieresis -100 KPX Abreve u -30 KPX Abreve uacute -30 KPX Abreve ucircumflex -30 KPX Abreve udieresis -30 KPX Abreve ugrave -30 KPX Abreve uhungarumlaut -30 KPX Abreve umacron -30 KPX Abreve uogonek -30 KPX Abreve uring -30 KPX Abreve v -40 KPX Abreve w -40 KPX Abreve y -40 KPX Abreve yacute -40 KPX Abreve ydieresis -40 KPX Acircumflex C -30 KPX Acircumflex Cacute -30 KPX Acircumflex Ccaron -30 KPX Acircumflex Ccedilla -30 KPX Acircumflex G -30 KPX Acircumflex Gbreve -30 KPX Acircumflex Gcommaaccent -30 KPX Acircumflex O -30 KPX Acircumflex Oacute -30 KPX Acircumflex Ocircumflex -30 KPX Acircumflex Odieresis -30 KPX Acircumflex Ograve -30 KPX Acircumflex Ohungarumlaut -30 KPX Acircumflex Omacron -30 KPX Acircumflex Oslash -30 KPX Acircumflex Otilde -30 KPX Acircumflex Q -30 KPX Acircumflex T -120 KPX Acircumflex Tcaron -120 KPX Acircumflex Tcommaaccent -120 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -70 KPX Acircumflex W -50 KPX Acircumflex Y -100 KPX Acircumflex Yacute -100 KPX Acircumflex Ydieresis -100 KPX Acircumflex u -30 KPX Acircumflex uacute -30 KPX Acircumflex ucircumflex -30 KPX Acircumflex udieresis -30 KPX Acircumflex ugrave -30 KPX Acircumflex uhungarumlaut -30 KPX Acircumflex umacron -30 KPX Acircumflex uogonek -30 KPX Acircumflex uring -30 KPX Acircumflex v -40 KPX Acircumflex w -40 KPX Acircumflex y -40 KPX Acircumflex yacute -40 KPX Acircumflex ydieresis -40 KPX Adieresis C -30 KPX Adieresis Cacute -30 KPX Adieresis Ccaron -30 KPX Adieresis Ccedilla -30 KPX Adieresis G -30 KPX Adieresis Gbreve -30 KPX Adieresis Gcommaaccent -30 KPX Adieresis O -30 KPX Adieresis Oacute -30 KPX Adieresis Ocircumflex -30 KPX Adieresis Odieresis -30 KPX Adieresis Ograve -30 KPX Adieresis Ohungarumlaut -30 KPX Adieresis Omacron -30 KPX Adieresis Oslash -30 KPX Adieresis Otilde -30 KPX Adieresis Q -30 KPX Adieresis T -120 KPX Adieresis Tcaron -120 KPX Adieresis Tcommaaccent -120 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -70 KPX Adieresis W -50 KPX Adieresis Y -100 KPX Adieresis Yacute -100 KPX Adieresis Ydieresis -100 KPX Adieresis u -30 KPX Adieresis uacute -30 KPX Adieresis ucircumflex -30 KPX Adieresis udieresis -30 KPX Adieresis ugrave -30 KPX Adieresis uhungarumlaut -30 KPX Adieresis umacron -30 KPX Adieresis uogonek -30 KPX Adieresis uring -30 KPX Adieresis v -40 KPX Adieresis w -40 KPX Adieresis y -40 KPX Adieresis yacute -40 KPX Adieresis ydieresis -40 KPX Agrave C -30 KPX Agrave Cacute -30 KPX Agrave Ccaron -30 KPX Agrave Ccedilla -30 KPX Agrave G -30 KPX Agrave Gbreve -30 KPX Agrave Gcommaaccent -30 KPX Agrave O -30 KPX Agrave Oacute -30 KPX Agrave Ocircumflex -30 KPX Agrave Odieresis -30 KPX Agrave Ograve -30 KPX Agrave Ohungarumlaut -30 KPX Agrave Omacron -30 KPX Agrave Oslash -30 KPX Agrave Otilde -30 KPX Agrave Q -30 KPX Agrave T -120 KPX Agrave Tcaron -120 KPX Agrave Tcommaaccent -120 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -70 KPX Agrave W -50 KPX Agrave Y -100 KPX Agrave Yacute -100 KPX Agrave Ydieresis -100 KPX Agrave u -30 KPX Agrave uacute -30 KPX Agrave ucircumflex -30 KPX Agrave udieresis -30 KPX Agrave ugrave -30 KPX Agrave uhungarumlaut -30 KPX Agrave umacron -30 KPX Agrave uogonek -30 KPX Agrave uring -30 KPX Agrave v -40 KPX Agrave w -40 KPX Agrave y -40 KPX Agrave yacute -40 KPX Agrave ydieresis -40 KPX Amacron C -30 KPX Amacron Cacute -30 KPX Amacron Ccaron -30 KPX Amacron Ccedilla -30 KPX Amacron G -30 KPX Amacron Gbreve -30 KPX Amacron Gcommaaccent -30 KPX Amacron O -30 KPX Amacron Oacute -30 KPX Amacron Ocircumflex -30 KPX Amacron Odieresis -30 KPX Amacron Ograve -30 KPX Amacron Ohungarumlaut -30 KPX Amacron Omacron -30 KPX Amacron Oslash -30 KPX Amacron Otilde -30 KPX Amacron Q -30 KPX Amacron T -120 KPX Amacron Tcaron -120 KPX Amacron Tcommaaccent -120 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -70 KPX Amacron W -50 KPX Amacron Y -100 KPX Amacron Yacute -100 KPX Amacron Ydieresis -100 KPX Amacron u -30 KPX Amacron uacute -30 KPX Amacron ucircumflex -30 KPX Amacron udieresis -30 KPX Amacron ugrave -30 KPX Amacron uhungarumlaut -30 KPX Amacron umacron -30 KPX Amacron uogonek -30 KPX Amacron uring -30 KPX Amacron v -40 KPX Amacron w -40 KPX Amacron y -40 KPX Amacron yacute -40 KPX Amacron ydieresis -40 KPX Aogonek C -30 KPX Aogonek Cacute -30 KPX Aogonek Ccaron -30 KPX Aogonek Ccedilla -30 KPX Aogonek G -30 KPX Aogonek Gbreve -30 KPX Aogonek Gcommaaccent -30 KPX Aogonek O -30 KPX Aogonek Oacute -30 KPX Aogonek Ocircumflex -30 KPX Aogonek Odieresis -30 KPX Aogonek Ograve -30 KPX Aogonek Ohungarumlaut -30 KPX Aogonek Omacron -30 KPX Aogonek Oslash -30 KPX Aogonek Otilde -30 KPX Aogonek Q -30 KPX Aogonek T -120 KPX Aogonek Tcaron -120 KPX Aogonek Tcommaaccent -120 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -70 KPX Aogonek W -50 KPX Aogonek Y -100 KPX Aogonek Yacute -100 KPX Aogonek Ydieresis -100 KPX Aogonek u -30 KPX Aogonek uacute -30 KPX Aogonek ucircumflex -30 KPX Aogonek udieresis -30 KPX Aogonek ugrave -30 KPX Aogonek uhungarumlaut -30 KPX Aogonek umacron -30 KPX Aogonek uogonek -30 KPX Aogonek uring -30 KPX Aogonek v -40 KPX Aogonek w -40 KPX Aogonek y -40 KPX Aogonek yacute -40 KPX Aogonek ydieresis -40 KPX Aring C -30 KPX Aring Cacute -30 KPX Aring Ccaron -30 KPX Aring Ccedilla -30 KPX Aring G -30 KPX Aring Gbreve -30 KPX Aring Gcommaaccent -30 KPX Aring O -30 KPX Aring Oacute -30 KPX Aring Ocircumflex -30 KPX Aring Odieresis -30 KPX Aring Ograve -30 KPX Aring Ohungarumlaut -30 KPX Aring Omacron -30 KPX Aring Oslash -30 KPX Aring Otilde -30 KPX Aring Q -30 KPX Aring T -120 KPX Aring Tcaron -120 KPX Aring Tcommaaccent -120 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -70 KPX Aring W -50 KPX Aring Y -100 KPX Aring Yacute -100 KPX Aring Ydieresis -100 KPX Aring u -30 KPX Aring uacute -30 KPX Aring ucircumflex -30 KPX Aring udieresis -30 KPX Aring ugrave -30 KPX Aring uhungarumlaut -30 KPX Aring umacron -30 KPX Aring uogonek -30 KPX Aring uring -30 KPX Aring v -40 KPX Aring w -40 KPX Aring y -40 KPX Aring yacute -40 KPX Aring ydieresis -40 KPX Atilde C -30 KPX Atilde Cacute -30 KPX Atilde Ccaron -30 KPX Atilde Ccedilla -30 KPX Atilde G -30 KPX Atilde Gbreve -30 KPX Atilde Gcommaaccent -30 KPX Atilde O -30 KPX Atilde Oacute -30 KPX Atilde Ocircumflex -30 KPX Atilde Odieresis -30 KPX Atilde Ograve -30 KPX Atilde Ohungarumlaut -30 KPX Atilde Omacron -30 KPX Atilde Oslash -30 KPX Atilde Otilde -30 KPX Atilde Q -30 KPX Atilde T -120 KPX Atilde Tcaron -120 KPX Atilde Tcommaaccent -120 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -70 KPX Atilde W -50 KPX Atilde Y -100 KPX Atilde Yacute -100 KPX Atilde Ydieresis -100 KPX Atilde u -30 KPX Atilde uacute -30 KPX Atilde ucircumflex -30 KPX Atilde udieresis -30 KPX Atilde ugrave -30 KPX Atilde uhungarumlaut -30 KPX Atilde umacron -30 KPX Atilde uogonek -30 KPX Atilde uring -30 KPX Atilde v -40 KPX Atilde w -40 KPX Atilde y -40 KPX Atilde yacute -40 KPX Atilde ydieresis -40 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX B comma -20 KPX B period -20 KPX C comma -30 KPX C period -30 KPX Cacute comma -30 KPX Cacute period -30 KPX Ccaron comma -30 KPX Ccaron period -30 KPX Ccedilla comma -30 KPX Ccedilla period -30 KPX D A -40 KPX D Aacute -40 KPX D Abreve -40 KPX D Acircumflex -40 KPX D Adieresis -40 KPX D Agrave -40 KPX D Amacron -40 KPX D Aogonek -40 KPX D Aring -40 KPX D Atilde -40 KPX D V -70 KPX D W -40 KPX D Y -90 KPX D Yacute -90 KPX D Ydieresis -90 KPX D comma -70 KPX D period -70 KPX Dcaron A -40 KPX Dcaron Aacute -40 KPX Dcaron Abreve -40 KPX Dcaron Acircumflex -40 KPX Dcaron Adieresis -40 KPX Dcaron Agrave -40 KPX Dcaron Amacron -40 KPX Dcaron Aogonek -40 KPX Dcaron Aring -40 KPX Dcaron Atilde -40 KPX Dcaron V -70 KPX Dcaron W -40 KPX Dcaron Y -90 KPX Dcaron Yacute -90 KPX Dcaron Ydieresis -90 KPX Dcaron comma -70 KPX Dcaron period -70 KPX Dcroat A -40 KPX Dcroat Aacute -40 KPX Dcroat Abreve -40 KPX Dcroat Acircumflex -40 KPX Dcroat Adieresis -40 KPX Dcroat Agrave -40 KPX Dcroat Amacron -40 KPX Dcroat Aogonek -40 KPX Dcroat Aring -40 KPX Dcroat Atilde -40 KPX Dcroat V -70 KPX Dcroat W -40 KPX Dcroat Y -90 KPX Dcroat Yacute -90 KPX Dcroat Ydieresis -90 KPX Dcroat comma -70 KPX Dcroat period -70 KPX F A -80 KPX F Aacute -80 KPX F Abreve -80 KPX F Acircumflex -80 KPX F Adieresis -80 KPX F Agrave -80 KPX F Amacron -80 KPX F Aogonek -80 KPX F Aring -80 KPX F Atilde -80 KPX F a -50 KPX F aacute -50 KPX F abreve -50 KPX F acircumflex -50 KPX F adieresis -50 KPX F agrave -50 KPX F amacron -50 KPX F aogonek -50 KPX F aring -50 KPX F atilde -50 KPX F comma -150 KPX F e -30 KPX F eacute -30 KPX F ecaron -30 KPX F ecircumflex -30 KPX F edieresis -30 KPX F edotaccent -30 KPX F egrave -30 KPX F emacron -30 KPX F eogonek -30 KPX F o -30 KPX F oacute -30 KPX F ocircumflex -30 KPX F odieresis -30 KPX F ograve -30 KPX F ohungarumlaut -30 KPX F omacron -30 KPX F oslash -30 KPX F otilde -30 KPX F period -150 KPX F r -45 KPX F racute -45 KPX F rcaron -45 KPX F rcommaaccent -45 KPX J A -20 KPX J Aacute -20 KPX J Abreve -20 KPX J Acircumflex -20 KPX J Adieresis -20 KPX J Agrave -20 KPX J Amacron -20 KPX J Aogonek -20 KPX J Aring -20 KPX J Atilde -20 KPX J a -20 KPX J aacute -20 KPX J abreve -20 KPX J acircumflex -20 KPX J adieresis -20 KPX J agrave -20 KPX J amacron -20 KPX J aogonek -20 KPX J aring -20 KPX J atilde -20 KPX J comma -30 KPX J period -30 KPX J u -20 KPX J uacute -20 KPX J ucircumflex -20 KPX J udieresis -20 KPX J ugrave -20 KPX J uhungarumlaut -20 KPX J umacron -20 KPX J uogonek -20 KPX J uring -20 KPX K O -50 KPX K Oacute -50 KPX K Ocircumflex -50 KPX K Odieresis -50 KPX K Ograve -50 KPX K Ohungarumlaut -50 KPX K Omacron -50 KPX K Oslash -50 KPX K Otilde -50 KPX K e -40 KPX K eacute -40 KPX K ecaron -40 KPX K ecircumflex -40 KPX K edieresis -40 KPX K edotaccent -40 KPX K egrave -40 KPX K emacron -40 KPX K eogonek -40 KPX K o -40 KPX K oacute -40 KPX K ocircumflex -40 KPX K odieresis -40 KPX K ograve -40 KPX K ohungarumlaut -40 KPX K omacron -40 KPX K oslash -40 KPX K otilde -40 KPX K u -30 KPX K uacute -30 KPX K ucircumflex -30 KPX K udieresis -30 KPX K ugrave -30 KPX K uhungarumlaut -30 KPX K umacron -30 KPX K uogonek -30 KPX K uring -30 KPX K y -50 KPX K yacute -50 KPX K ydieresis -50 KPX Kcommaaccent O -50 KPX Kcommaaccent Oacute -50 KPX Kcommaaccent Ocircumflex -50 KPX Kcommaaccent Odieresis -50 KPX Kcommaaccent Ograve -50 KPX Kcommaaccent Ohungarumlaut -50 KPX Kcommaaccent Omacron -50 KPX Kcommaaccent Oslash -50 KPX Kcommaaccent Otilde -50 KPX Kcommaaccent e -40 KPX Kcommaaccent eacute -40 KPX Kcommaaccent ecaron -40 KPX Kcommaaccent ecircumflex -40 KPX Kcommaaccent edieresis -40 KPX Kcommaaccent edotaccent -40 KPX Kcommaaccent egrave -40 KPX Kcommaaccent emacron -40 KPX Kcommaaccent eogonek -40 KPX Kcommaaccent o -40 KPX Kcommaaccent oacute -40 KPX Kcommaaccent ocircumflex -40 KPX Kcommaaccent odieresis -40 KPX Kcommaaccent ograve -40 KPX Kcommaaccent ohungarumlaut -40 KPX Kcommaaccent omacron -40 KPX Kcommaaccent oslash -40 KPX Kcommaaccent otilde -40 KPX Kcommaaccent u -30 KPX Kcommaaccent uacute -30 KPX Kcommaaccent ucircumflex -30 KPX Kcommaaccent udieresis -30 KPX Kcommaaccent ugrave -30 KPX Kcommaaccent uhungarumlaut -30 KPX Kcommaaccent umacron -30 KPX Kcommaaccent uogonek -30 KPX Kcommaaccent uring -30 KPX Kcommaaccent y -50 KPX Kcommaaccent yacute -50 KPX Kcommaaccent ydieresis -50 KPX L T -110 KPX L Tcaron -110 KPX L Tcommaaccent -110 KPX L V -110 KPX L W -70 KPX L Y -140 KPX L Yacute -140 KPX L Ydieresis -140 KPX L quotedblright -140 KPX L quoteright -160 KPX L y -30 KPX L yacute -30 KPX L ydieresis -30 KPX Lacute T -110 KPX Lacute Tcaron -110 KPX Lacute Tcommaaccent -110 KPX Lacute V -110 KPX Lacute W -70 KPX Lacute Y -140 KPX Lacute Yacute -140 KPX Lacute Ydieresis -140 KPX Lacute quotedblright -140 KPX Lacute quoteright -160 KPX Lacute y -30 KPX Lacute yacute -30 KPX Lacute ydieresis -30 KPX Lcaron T -110 KPX Lcaron Tcaron -110 KPX Lcaron Tcommaaccent -110 KPX Lcaron V -110 KPX Lcaron W -70 KPX Lcaron Y -140 KPX Lcaron Yacute -140 KPX Lcaron Ydieresis -140 KPX Lcaron quotedblright -140 KPX Lcaron quoteright -160 KPX Lcaron y -30 KPX Lcaron yacute -30 KPX Lcaron ydieresis -30 KPX Lcommaaccent T -110 KPX Lcommaaccent Tcaron -110 KPX Lcommaaccent Tcommaaccent -110 KPX Lcommaaccent V -110 KPX Lcommaaccent W -70 KPX Lcommaaccent Y -140 KPX Lcommaaccent Yacute -140 KPX Lcommaaccent Ydieresis -140 KPX Lcommaaccent quotedblright -140 KPX Lcommaaccent quoteright -160 KPX Lcommaaccent y -30 KPX Lcommaaccent yacute -30 KPX Lcommaaccent ydieresis -30 KPX Lslash T -110 KPX Lslash Tcaron -110 KPX Lslash Tcommaaccent -110 KPX Lslash V -110 KPX Lslash W -70 KPX Lslash Y -140 KPX Lslash Yacute -140 KPX Lslash Ydieresis -140 KPX Lslash quotedblright -140 KPX Lslash quoteright -160 KPX Lslash y -30 KPX Lslash yacute -30 KPX Lslash ydieresis -30 KPX O A -20 KPX O Aacute -20 KPX O Abreve -20 KPX O Acircumflex -20 KPX O Adieresis -20 KPX O Agrave -20 KPX O Amacron -20 KPX O Aogonek -20 KPX O Aring -20 KPX O Atilde -20 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -30 KPX O X -60 KPX O Y -70 KPX O Yacute -70 KPX O Ydieresis -70 KPX O comma -40 KPX O period -40 KPX Oacute A -20 KPX Oacute Aacute -20 KPX Oacute Abreve -20 KPX Oacute Acircumflex -20 KPX Oacute Adieresis -20 KPX Oacute Agrave -20 KPX Oacute Amacron -20 KPX Oacute Aogonek -20 KPX Oacute Aring -20 KPX Oacute Atilde -20 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -30 KPX Oacute X -60 KPX Oacute Y -70 KPX Oacute Yacute -70 KPX Oacute Ydieresis -70 KPX Oacute comma -40 KPX Oacute period -40 KPX Ocircumflex A -20 KPX Ocircumflex Aacute -20 KPX Ocircumflex Abreve -20 KPX Ocircumflex Acircumflex -20 KPX Ocircumflex Adieresis -20 KPX Ocircumflex Agrave -20 KPX Ocircumflex Amacron -20 KPX Ocircumflex Aogonek -20 KPX Ocircumflex Aring -20 KPX Ocircumflex Atilde -20 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -30 KPX Ocircumflex X -60 KPX Ocircumflex Y -70 KPX Ocircumflex Yacute -70 KPX Ocircumflex Ydieresis -70 KPX Ocircumflex comma -40 KPX Ocircumflex period -40 KPX Odieresis A -20 KPX Odieresis Aacute -20 KPX Odieresis Abreve -20 KPX Odieresis Acircumflex -20 KPX Odieresis Adieresis -20 KPX Odieresis Agrave -20 KPX Odieresis Amacron -20 KPX Odieresis Aogonek -20 KPX Odieresis Aring -20 KPX Odieresis Atilde -20 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -30 KPX Odieresis X -60 KPX Odieresis Y -70 KPX Odieresis Yacute -70 KPX Odieresis Ydieresis -70 KPX Odieresis comma -40 KPX Odieresis period -40 KPX Ograve A -20 KPX Ograve Aacute -20 KPX Ograve Abreve -20 KPX Ograve Acircumflex -20 KPX Ograve Adieresis -20 KPX Ograve Agrave -20 KPX Ograve Amacron -20 KPX Ograve Aogonek -20 KPX Ograve Aring -20 KPX Ograve Atilde -20 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -30 KPX Ograve X -60 KPX Ograve Y -70 KPX Ograve Yacute -70 KPX Ograve Ydieresis -70 KPX Ograve comma -40 KPX Ograve period -40 KPX Ohungarumlaut A -20 KPX Ohungarumlaut Aacute -20 KPX Ohungarumlaut Abreve -20 KPX Ohungarumlaut Acircumflex -20 KPX Ohungarumlaut Adieresis -20 KPX Ohungarumlaut Agrave -20 KPX Ohungarumlaut Amacron -20 KPX Ohungarumlaut Aogonek -20 KPX Ohungarumlaut Aring -20 KPX Ohungarumlaut Atilde -20 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -30 KPX Ohungarumlaut X -60 KPX Ohungarumlaut Y -70 KPX Ohungarumlaut Yacute -70 KPX Ohungarumlaut Ydieresis -70 KPX Ohungarumlaut comma -40 KPX Ohungarumlaut period -40 KPX Omacron A -20 KPX Omacron Aacute -20 KPX Omacron Abreve -20 KPX Omacron Acircumflex -20 KPX Omacron Adieresis -20 KPX Omacron Agrave -20 KPX Omacron Amacron -20 KPX Omacron Aogonek -20 KPX Omacron Aring -20 KPX Omacron Atilde -20 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -30 KPX Omacron X -60 KPX Omacron Y -70 KPX Omacron Yacute -70 KPX Omacron Ydieresis -70 KPX Omacron comma -40 KPX Omacron period -40 KPX Oslash A -20 KPX Oslash Aacute -20 KPX Oslash Abreve -20 KPX Oslash Acircumflex -20 KPX Oslash Adieresis -20 KPX Oslash Agrave -20 KPX Oslash Amacron -20 KPX Oslash Aogonek -20 KPX Oslash Aring -20 KPX Oslash Atilde -20 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -30 KPX Oslash X -60 KPX Oslash Y -70 KPX Oslash Yacute -70 KPX Oslash Ydieresis -70 KPX Oslash comma -40 KPX Oslash period -40 KPX Otilde A -20 KPX Otilde Aacute -20 KPX Otilde Abreve -20 KPX Otilde Acircumflex -20 KPX Otilde Adieresis -20 KPX Otilde Agrave -20 KPX Otilde Amacron -20 KPX Otilde Aogonek -20 KPX Otilde Aring -20 KPX Otilde Atilde -20 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -30 KPX Otilde X -60 KPX Otilde Y -70 KPX Otilde Yacute -70 KPX Otilde Ydieresis -70 KPX Otilde comma -40 KPX Otilde period -40 KPX P A -120 KPX P Aacute -120 KPX P Abreve -120 KPX P Acircumflex -120 KPX P Adieresis -120 KPX P Agrave -120 KPX P Amacron -120 KPX P Aogonek -120 KPX P Aring -120 KPX P Atilde -120 KPX P a -40 KPX P aacute -40 KPX P abreve -40 KPX P acircumflex -40 KPX P adieresis -40 KPX P agrave -40 KPX P amacron -40 KPX P aogonek -40 KPX P aring -40 KPX P atilde -40 KPX P comma -180 KPX P e -50 KPX P eacute -50 KPX P ecaron -50 KPX P ecircumflex -50 KPX P edieresis -50 KPX P edotaccent -50 KPX P egrave -50 KPX P emacron -50 KPX P eogonek -50 KPX P o -50 KPX P oacute -50 KPX P ocircumflex -50 KPX P odieresis -50 KPX P ograve -50 KPX P ohungarumlaut -50 KPX P omacron -50 KPX P oslash -50 KPX P otilde -50 KPX P period -180 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX R O -20 KPX R Oacute -20 KPX R Ocircumflex -20 KPX R Odieresis -20 KPX R Ograve -20 KPX R Ohungarumlaut -20 KPX R Omacron -20 KPX R Oslash -20 KPX R Otilde -20 KPX R T -30 KPX R Tcaron -30 KPX R Tcommaaccent -30 KPX R U -40 KPX R Uacute -40 KPX R Ucircumflex -40 KPX R Udieresis -40 KPX R Ugrave -40 KPX R Uhungarumlaut -40 KPX R Umacron -40 KPX R Uogonek -40 KPX R Uring -40 KPX R V -50 KPX R W -30 KPX R Y -50 KPX R Yacute -50 KPX R Ydieresis -50 KPX Racute O -20 KPX Racute Oacute -20 KPX Racute Ocircumflex -20 KPX Racute Odieresis -20 KPX Racute Ograve -20 KPX Racute Ohungarumlaut -20 KPX Racute Omacron -20 KPX Racute Oslash -20 KPX Racute Otilde -20 KPX Racute T -30 KPX Racute Tcaron -30 KPX Racute Tcommaaccent -30 KPX Racute U -40 KPX Racute Uacute -40 KPX Racute Ucircumflex -40 KPX Racute Udieresis -40 KPX Racute Ugrave -40 KPX Racute Uhungarumlaut -40 KPX Racute Umacron -40 KPX Racute Uogonek -40 KPX Racute Uring -40 KPX Racute V -50 KPX Racute W -30 KPX Racute Y -50 KPX Racute Yacute -50 KPX Racute Ydieresis -50 KPX Rcaron O -20 KPX Rcaron Oacute -20 KPX Rcaron Ocircumflex -20 KPX Rcaron Odieresis -20 KPX Rcaron Ograve -20 KPX Rcaron Ohungarumlaut -20 KPX Rcaron Omacron -20 KPX Rcaron Oslash -20 KPX Rcaron Otilde -20 KPX Rcaron T -30 KPX Rcaron Tcaron -30 KPX Rcaron Tcommaaccent -30 KPX Rcaron U -40 KPX Rcaron Uacute -40 KPX Rcaron Ucircumflex -40 KPX Rcaron Udieresis -40 KPX Rcaron Ugrave -40 KPX Rcaron Uhungarumlaut -40 KPX Rcaron Umacron -40 KPX Rcaron Uogonek -40 KPX Rcaron Uring -40 KPX Rcaron V -50 KPX Rcaron W -30 KPX Rcaron Y -50 KPX Rcaron Yacute -50 KPX Rcaron Ydieresis -50 KPX Rcommaaccent O -20 KPX Rcommaaccent Oacute -20 KPX Rcommaaccent Ocircumflex -20 KPX Rcommaaccent Odieresis -20 KPX Rcommaaccent Ograve -20 KPX Rcommaaccent Ohungarumlaut -20 KPX Rcommaaccent Omacron -20 KPX Rcommaaccent Oslash -20 KPX Rcommaaccent Otilde -20 KPX Rcommaaccent T -30 KPX Rcommaaccent Tcaron -30 KPX Rcommaaccent Tcommaaccent -30 KPX Rcommaaccent U -40 KPX Rcommaaccent Uacute -40 KPX Rcommaaccent Ucircumflex -40 KPX Rcommaaccent Udieresis -40 KPX Rcommaaccent Ugrave -40 KPX Rcommaaccent Uhungarumlaut -40 KPX Rcommaaccent Umacron -40 KPX Rcommaaccent Uogonek -40 KPX Rcommaaccent Uring -40 KPX Rcommaaccent V -50 KPX Rcommaaccent W -30 KPX Rcommaaccent Y -50 KPX Rcommaaccent Yacute -50 KPX Rcommaaccent Ydieresis -50 KPX S comma -20 KPX S period -20 KPX Sacute comma -20 KPX Sacute period -20 KPX Scaron comma -20 KPX Scaron period -20 KPX Scedilla comma -20 KPX Scedilla period -20 KPX Scommaaccent comma -20 KPX Scommaaccent period -20 KPX T A -120 KPX T Aacute -120 KPX T Abreve -120 KPX T Acircumflex -120 KPX T Adieresis -120 KPX T Agrave -120 KPX T Amacron -120 KPX T Aogonek -120 KPX T Aring -120 KPX T Atilde -120 KPX T O -40 KPX T Oacute -40 KPX T Ocircumflex -40 KPX T Odieresis -40 KPX T Ograve -40 KPX T Ohungarumlaut -40 KPX T Omacron -40 KPX T Oslash -40 KPX T Otilde -40 KPX T a -120 KPX T aacute -120 KPX T abreve -60 KPX T acircumflex -120 KPX T adieresis -120 KPX T agrave -120 KPX T amacron -60 KPX T aogonek -120 KPX T aring -120 KPX T atilde -60 KPX T colon -20 KPX T comma -120 KPX T e -120 KPX T eacute -120 KPX T ecaron -120 KPX T ecircumflex -120 KPX T edieresis -120 KPX T edotaccent -120 KPX T egrave -60 KPX T emacron -60 KPX T eogonek -120 KPX T hyphen -140 KPX T o -120 KPX T oacute -120 KPX T ocircumflex -120 KPX T odieresis -120 KPX T ograve -120 KPX T ohungarumlaut -120 KPX T omacron -60 KPX T oslash -120 KPX T otilde -60 KPX T period -120 KPX T r -120 KPX T racute -120 KPX T rcaron -120 KPX T rcommaaccent -120 KPX T semicolon -20 KPX T u -120 KPX T uacute -120 KPX T ucircumflex -120 KPX T udieresis -120 KPX T ugrave -120 KPX T uhungarumlaut -120 KPX T umacron -60 KPX T uogonek -120 KPX T uring -120 KPX T w -120 KPX T y -120 KPX T yacute -120 KPX T ydieresis -60 KPX Tcaron A -120 KPX Tcaron Aacute -120 KPX Tcaron Abreve -120 KPX Tcaron Acircumflex -120 KPX Tcaron Adieresis -120 KPX Tcaron Agrave -120 KPX Tcaron Amacron -120 KPX Tcaron Aogonek -120 KPX Tcaron Aring -120 KPX Tcaron Atilde -120 KPX Tcaron O -40 KPX Tcaron Oacute -40 KPX Tcaron Ocircumflex -40 KPX Tcaron Odieresis -40 KPX Tcaron Ograve -40 KPX Tcaron Ohungarumlaut -40 KPX Tcaron Omacron -40 KPX Tcaron Oslash -40 KPX Tcaron Otilde -40 KPX Tcaron a -120 KPX Tcaron aacute -120 KPX Tcaron abreve -60 KPX Tcaron acircumflex -120 KPX Tcaron adieresis -120 KPX Tcaron agrave -120 KPX Tcaron amacron -60 KPX Tcaron aogonek -120 KPX Tcaron aring -120 KPX Tcaron atilde -60 KPX Tcaron colon -20 KPX Tcaron comma -120 KPX Tcaron e -120 KPX Tcaron eacute -120 KPX Tcaron ecaron -120 KPX Tcaron ecircumflex -120 KPX Tcaron edieresis -120 KPX Tcaron edotaccent -120 KPX Tcaron egrave -60 KPX Tcaron emacron -60 KPX Tcaron eogonek -120 KPX Tcaron hyphen -140 KPX Tcaron o -120 KPX Tcaron oacute -120 KPX Tcaron ocircumflex -120 KPX Tcaron odieresis -120 KPX Tcaron ograve -120 KPX Tcaron ohungarumlaut -120 KPX Tcaron omacron -60 KPX Tcaron oslash -120 KPX Tcaron otilde -60 KPX Tcaron period -120 KPX Tcaron r -120 KPX Tcaron racute -120 KPX Tcaron rcaron -120 KPX Tcaron rcommaaccent -120 KPX Tcaron semicolon -20 KPX Tcaron u -120 KPX Tcaron uacute -120 KPX Tcaron ucircumflex -120 KPX Tcaron udieresis -120 KPX Tcaron ugrave -120 KPX Tcaron uhungarumlaut -120 KPX Tcaron umacron -60 KPX Tcaron uogonek -120 KPX Tcaron uring -120 KPX Tcaron w -120 KPX Tcaron y -120 KPX Tcaron yacute -120 KPX Tcaron ydieresis -60 KPX Tcommaaccent A -120 KPX Tcommaaccent Aacute -120 KPX Tcommaaccent Abreve -120 KPX Tcommaaccent Acircumflex -120 KPX Tcommaaccent Adieresis -120 KPX Tcommaaccent Agrave -120 KPX Tcommaaccent Amacron -120 KPX Tcommaaccent Aogonek -120 KPX Tcommaaccent Aring -120 KPX Tcommaaccent Atilde -120 KPX Tcommaaccent O -40 KPX Tcommaaccent Oacute -40 KPX Tcommaaccent Ocircumflex -40 KPX Tcommaaccent Odieresis -40 KPX Tcommaaccent Ograve -40 KPX Tcommaaccent Ohungarumlaut -40 KPX Tcommaaccent Omacron -40 KPX Tcommaaccent Oslash -40 KPX Tcommaaccent Otilde -40 KPX Tcommaaccent a -120 KPX Tcommaaccent aacute -120 KPX Tcommaaccent abreve -60 KPX Tcommaaccent acircumflex -120 KPX Tcommaaccent adieresis -120 KPX Tcommaaccent agrave -120 KPX Tcommaaccent amacron -60 KPX Tcommaaccent aogonek -120 KPX Tcommaaccent aring -120 KPX Tcommaaccent atilde -60 KPX Tcommaaccent colon -20 KPX Tcommaaccent comma -120 KPX Tcommaaccent e -120 KPX Tcommaaccent eacute -120 KPX Tcommaaccent ecaron -120 KPX Tcommaaccent ecircumflex -120 KPX Tcommaaccent edieresis -120 KPX Tcommaaccent edotaccent -120 KPX Tcommaaccent egrave -60 KPX Tcommaaccent emacron -60 KPX Tcommaaccent eogonek -120 KPX Tcommaaccent hyphen -140 KPX Tcommaaccent o -120 KPX Tcommaaccent oacute -120 KPX Tcommaaccent ocircumflex -120 KPX Tcommaaccent odieresis -120 KPX Tcommaaccent ograve -120 KPX Tcommaaccent ohungarumlaut -120 KPX Tcommaaccent omacron -60 KPX Tcommaaccent oslash -120 KPX Tcommaaccent otilde -60 KPX Tcommaaccent period -120 KPX Tcommaaccent r -120 KPX Tcommaaccent racute -120 KPX Tcommaaccent rcaron -120 KPX Tcommaaccent rcommaaccent -120 KPX Tcommaaccent semicolon -20 KPX Tcommaaccent u -120 KPX Tcommaaccent uacute -120 KPX Tcommaaccent ucircumflex -120 KPX Tcommaaccent udieresis -120 KPX Tcommaaccent ugrave -120 KPX Tcommaaccent uhungarumlaut -120 KPX Tcommaaccent umacron -60 KPX Tcommaaccent uogonek -120 KPX Tcommaaccent uring -120 KPX Tcommaaccent w -120 KPX Tcommaaccent y -120 KPX Tcommaaccent yacute -120 KPX Tcommaaccent ydieresis -60 KPX U A -40 KPX U Aacute -40 KPX U Abreve -40 KPX U Acircumflex -40 KPX U Adieresis -40 KPX U Agrave -40 KPX U Amacron -40 KPX U Aogonek -40 KPX U Aring -40 KPX U Atilde -40 KPX U comma -40 KPX U period -40 KPX Uacute A -40 KPX Uacute Aacute -40 KPX Uacute Abreve -40 KPX Uacute Acircumflex -40 KPX Uacute Adieresis -40 KPX Uacute Agrave -40 KPX Uacute Amacron -40 KPX Uacute Aogonek -40 KPX Uacute Aring -40 KPX Uacute Atilde -40 KPX Uacute comma -40 KPX Uacute period -40 KPX Ucircumflex A -40 KPX Ucircumflex Aacute -40 KPX Ucircumflex Abreve -40 KPX Ucircumflex Acircumflex -40 KPX Ucircumflex Adieresis -40 KPX Ucircumflex Agrave -40 KPX Ucircumflex Amacron -40 KPX Ucircumflex Aogonek -40 KPX Ucircumflex Aring -40 KPX Ucircumflex Atilde -40 KPX Ucircumflex comma -40 KPX Ucircumflex period -40 KPX Udieresis A -40 KPX Udieresis Aacute -40 KPX Udieresis Abreve -40 KPX Udieresis Acircumflex -40 KPX Udieresis Adieresis -40 KPX Udieresis Agrave -40 KPX Udieresis Amacron -40 KPX Udieresis Aogonek -40 KPX Udieresis Aring -40 KPX Udieresis Atilde -40 KPX Udieresis comma -40 KPX Udieresis period -40 KPX Ugrave A -40 KPX Ugrave Aacute -40 KPX Ugrave Abreve -40 KPX Ugrave Acircumflex -40 KPX Ugrave Adieresis -40 KPX Ugrave Agrave -40 KPX Ugrave Amacron -40 KPX Ugrave Aogonek -40 KPX Ugrave Aring -40 KPX Ugrave Atilde -40 KPX Ugrave comma -40 KPX Ugrave period -40 KPX Uhungarumlaut A -40 KPX Uhungarumlaut Aacute -40 KPX Uhungarumlaut Abreve -40 KPX Uhungarumlaut Acircumflex -40 KPX Uhungarumlaut Adieresis -40 KPX Uhungarumlaut Agrave -40 KPX Uhungarumlaut Amacron -40 KPX Uhungarumlaut Aogonek -40 KPX Uhungarumlaut Aring -40 KPX Uhungarumlaut Atilde -40 KPX Uhungarumlaut comma -40 KPX Uhungarumlaut period -40 KPX Umacron A -40 KPX Umacron Aacute -40 KPX Umacron Abreve -40 KPX Umacron Acircumflex -40 KPX Umacron Adieresis -40 KPX Umacron Agrave -40 KPX Umacron Amacron -40 KPX Umacron Aogonek -40 KPX Umacron Aring -40 KPX Umacron Atilde -40 KPX Umacron comma -40 KPX Umacron period -40 KPX Uogonek A -40 KPX Uogonek Aacute -40 KPX Uogonek Abreve -40 KPX Uogonek Acircumflex -40 KPX Uogonek Adieresis -40 KPX Uogonek Agrave -40 KPX Uogonek Amacron -40 KPX Uogonek Aogonek -40 KPX Uogonek Aring -40 KPX Uogonek Atilde -40 KPX Uogonek comma -40 KPX Uogonek period -40 KPX Uring A -40 KPX Uring Aacute -40 KPX Uring Abreve -40 KPX Uring Acircumflex -40 KPX Uring Adieresis -40 KPX Uring Agrave -40 KPX Uring Amacron -40 KPX Uring Aogonek -40 KPX Uring Aring -40 KPX Uring Atilde -40 KPX Uring comma -40 KPX Uring period -40 KPX V A -80 KPX V Aacute -80 KPX V Abreve -80 KPX V Acircumflex -80 KPX V Adieresis -80 KPX V Agrave -80 KPX V Amacron -80 KPX V Aogonek -80 KPX V Aring -80 KPX V Atilde -80 KPX V G -40 KPX V Gbreve -40 KPX V Gcommaaccent -40 KPX V O -40 KPX V Oacute -40 KPX V Ocircumflex -40 KPX V Odieresis -40 KPX V Ograve -40 KPX V Ohungarumlaut -40 KPX V Omacron -40 KPX V Oslash -40 KPX V Otilde -40 KPX V a -70 KPX V aacute -70 KPX V abreve -70 KPX V acircumflex -70 KPX V adieresis -70 KPX V agrave -70 KPX V amacron -70 KPX V aogonek -70 KPX V aring -70 KPX V atilde -70 KPX V colon -40 KPX V comma -125 KPX V e -80 KPX V eacute -80 KPX V ecaron -80 KPX V ecircumflex -80 KPX V edieresis -80 KPX V edotaccent -80 KPX V egrave -80 KPX V emacron -80 KPX V eogonek -80 KPX V hyphen -80 KPX V o -80 KPX V oacute -80 KPX V ocircumflex -80 KPX V odieresis -80 KPX V ograve -80 KPX V ohungarumlaut -80 KPX V omacron -80 KPX V oslash -80 KPX V otilde -80 KPX V period -125 KPX V semicolon -40 KPX V u -70 KPX V uacute -70 KPX V ucircumflex -70 KPX V udieresis -70 KPX V ugrave -70 KPX V uhungarumlaut -70 KPX V umacron -70 KPX V uogonek -70 KPX V uring -70 KPX W A -50 KPX W Aacute -50 KPX W Abreve -50 KPX W Acircumflex -50 KPX W Adieresis -50 KPX W Agrave -50 KPX W Amacron -50 KPX W Aogonek -50 KPX W Aring -50 KPX W Atilde -50 KPX W O -20 KPX W Oacute -20 KPX W Ocircumflex -20 KPX W Odieresis -20 KPX W Ograve -20 KPX W Ohungarumlaut -20 KPX W Omacron -20 KPX W Oslash -20 KPX W Otilde -20 KPX W a -40 KPX W aacute -40 KPX W abreve -40 KPX W acircumflex -40 KPX W adieresis -40 KPX W agrave -40 KPX W amacron -40 KPX W aogonek -40 KPX W aring -40 KPX W atilde -40 KPX W comma -80 KPX W e -30 KPX W eacute -30 KPX W ecaron -30 KPX W ecircumflex -30 KPX W edieresis -30 KPX W edotaccent -30 KPX W egrave -30 KPX W emacron -30 KPX W eogonek -30 KPX W hyphen -40 KPX W o -30 KPX W oacute -30 KPX W ocircumflex -30 KPX W odieresis -30 KPX W ograve -30 KPX W ohungarumlaut -30 KPX W omacron -30 KPX W oslash -30 KPX W otilde -30 KPX W period -80 KPX W u -30 KPX W uacute -30 KPX W ucircumflex -30 KPX W udieresis -30 KPX W ugrave -30 KPX W uhungarumlaut -30 KPX W umacron -30 KPX W uogonek -30 KPX W uring -30 KPX W y -20 KPX W yacute -20 KPX W ydieresis -20 KPX Y A -110 KPX Y Aacute -110 KPX Y Abreve -110 KPX Y Acircumflex -110 KPX Y Adieresis -110 KPX Y Agrave -110 KPX Y Amacron -110 KPX Y Aogonek -110 KPX Y Aring -110 KPX Y Atilde -110 KPX Y O -85 KPX Y Oacute -85 KPX Y Ocircumflex -85 KPX Y Odieresis -85 KPX Y Ograve -85 KPX Y Ohungarumlaut -85 KPX Y Omacron -85 KPX Y Oslash -85 KPX Y Otilde -85 KPX Y a -140 KPX Y aacute -140 KPX Y abreve -70 KPX Y acircumflex -140 KPX Y adieresis -140 KPX Y agrave -140 KPX Y amacron -70 KPX Y aogonek -140 KPX Y aring -140 KPX Y atilde -140 KPX Y colon -60 KPX Y comma -140 KPX Y e -140 KPX Y eacute -140 KPX Y ecaron -140 KPX Y ecircumflex -140 KPX Y edieresis -140 KPX Y edotaccent -140 KPX Y egrave -140 KPX Y emacron -70 KPX Y eogonek -140 KPX Y hyphen -140 KPX Y i -20 KPX Y iacute -20 KPX Y iogonek -20 KPX Y o -140 KPX Y oacute -140 KPX Y ocircumflex -140 KPX Y odieresis -140 KPX Y ograve -140 KPX Y ohungarumlaut -140 KPX Y omacron -140 KPX Y oslash -140 KPX Y otilde -140 KPX Y period -140 KPX Y semicolon -60 KPX Y u -110 KPX Y uacute -110 KPX Y ucircumflex -110 KPX Y udieresis -110 KPX Y ugrave -110 KPX Y uhungarumlaut -110 KPX Y umacron -110 KPX Y uogonek -110 KPX Y uring -110 KPX Yacute A -110 KPX Yacute Aacute -110 KPX Yacute Abreve -110 KPX Yacute Acircumflex -110 KPX Yacute Adieresis -110 KPX Yacute Agrave -110 KPX Yacute Amacron -110 KPX Yacute Aogonek -110 KPX Yacute Aring -110 KPX Yacute Atilde -110 KPX Yacute O -85 KPX Yacute Oacute -85 KPX Yacute Ocircumflex -85 KPX Yacute Odieresis -85 KPX Yacute Ograve -85 KPX Yacute Ohungarumlaut -85 KPX Yacute Omacron -85 KPX Yacute Oslash -85 KPX Yacute Otilde -85 KPX Yacute a -140 KPX Yacute aacute -140 KPX Yacute abreve -70 KPX Yacute acircumflex -140 KPX Yacute adieresis -140 KPX Yacute agrave -140 KPX Yacute amacron -70 KPX Yacute aogonek -140 KPX Yacute aring -140 KPX Yacute atilde -70 KPX Yacute colon -60 KPX Yacute comma -140 KPX Yacute e -140 KPX Yacute eacute -140 KPX Yacute ecaron -140 KPX Yacute ecircumflex -140 KPX Yacute edieresis -140 KPX Yacute edotaccent -140 KPX Yacute egrave -140 KPX Yacute emacron -70 KPX Yacute eogonek -140 KPX Yacute hyphen -140 KPX Yacute i -20 KPX Yacute iacute -20 KPX Yacute iogonek -20 KPX Yacute o -140 KPX Yacute oacute -140 KPX Yacute ocircumflex -140 KPX Yacute odieresis -140 KPX Yacute ograve -140 KPX Yacute ohungarumlaut -140 KPX Yacute omacron -70 KPX Yacute oslash -140 KPX Yacute otilde -140 KPX Yacute period -140 KPX Yacute semicolon -60 KPX Yacute u -110 KPX Yacute uacute -110 KPX Yacute ucircumflex -110 KPX Yacute udieresis -110 KPX Yacute ugrave -110 KPX Yacute uhungarumlaut -110 KPX Yacute umacron -110 KPX Yacute uogonek -110 KPX Yacute uring -110 KPX Ydieresis A -110 KPX Ydieresis Aacute -110 KPX Ydieresis Abreve -110 KPX Ydieresis Acircumflex -110 KPX Ydieresis Adieresis -110 KPX Ydieresis Agrave -110 KPX Ydieresis Amacron -110 KPX Ydieresis Aogonek -110 KPX Ydieresis Aring -110 KPX Ydieresis Atilde -110 KPX Ydieresis O -85 KPX Ydieresis Oacute -85 KPX Ydieresis Ocircumflex -85 KPX Ydieresis Odieresis -85 KPX Ydieresis Ograve -85 KPX Ydieresis Ohungarumlaut -85 KPX Ydieresis Omacron -85 KPX Ydieresis Oslash -85 KPX Ydieresis Otilde -85 KPX Ydieresis a -140 KPX Ydieresis aacute -140 KPX Ydieresis abreve -70 KPX Ydieresis acircumflex -140 KPX Ydieresis adieresis -140 KPX Ydieresis agrave -140 KPX Ydieresis amacron -70 KPX Ydieresis aogonek -140 KPX Ydieresis aring -140 KPX Ydieresis atilde -70 KPX Ydieresis colon -60 KPX Ydieresis comma -140 KPX Ydieresis e -140 KPX Ydieresis eacute -140 KPX Ydieresis ecaron -140 KPX Ydieresis ecircumflex -140 KPX Ydieresis edieresis -140 KPX Ydieresis edotaccent -140 KPX Ydieresis egrave -140 KPX Ydieresis emacron -70 KPX Ydieresis eogonek -140 KPX Ydieresis hyphen -140 KPX Ydieresis i -20 KPX Ydieresis iacute -20 KPX Ydieresis iogonek -20 KPX Ydieresis o -140 KPX Ydieresis oacute -140 KPX Ydieresis ocircumflex -140 KPX Ydieresis odieresis -140 KPX Ydieresis ograve -140 KPX Ydieresis ohungarumlaut -140 KPX Ydieresis omacron -140 KPX Ydieresis oslash -140 KPX Ydieresis otilde -140 KPX Ydieresis period -140 KPX Ydieresis semicolon -60 KPX Ydieresis u -110 KPX Ydieresis uacute -110 KPX Ydieresis ucircumflex -110 KPX Ydieresis udieresis -110 KPX Ydieresis ugrave -110 KPX Ydieresis uhungarumlaut -110 KPX Ydieresis umacron -110 KPX Ydieresis uogonek -110 KPX Ydieresis uring -110 KPX a v -20 KPX a w -20 KPX a y -30 KPX a yacute -30 KPX a ydieresis -30 KPX aacute v -20 KPX aacute w -20 KPX aacute y -30 KPX aacute yacute -30 KPX aacute ydieresis -30 KPX abreve v -20 KPX abreve w -20 KPX abreve y -30 KPX abreve yacute -30 KPX abreve ydieresis -30 KPX acircumflex v -20 KPX acircumflex w -20 KPX acircumflex y -30 KPX acircumflex yacute -30 KPX acircumflex ydieresis -30 KPX adieresis v -20 KPX adieresis w -20 KPX adieresis y -30 KPX adieresis yacute -30 KPX adieresis ydieresis -30 KPX agrave v -20 KPX agrave w -20 KPX agrave y -30 KPX agrave yacute -30 KPX agrave ydieresis -30 KPX amacron v -20 KPX amacron w -20 KPX amacron y -30 KPX amacron yacute -30 KPX amacron ydieresis -30 KPX aogonek v -20 KPX aogonek w -20 KPX aogonek y -30 KPX aogonek yacute -30 KPX aogonek ydieresis -30 KPX aring v -20 KPX aring w -20 KPX aring y -30 KPX aring yacute -30 KPX aring ydieresis -30 KPX atilde v -20 KPX atilde w -20 KPX atilde y -30 KPX atilde yacute -30 KPX atilde ydieresis -30 KPX b b -10 KPX b comma -40 KPX b l -20 KPX b lacute -20 KPX b lcommaaccent -20 KPX b lslash -20 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -20 KPX b y -20 KPX b yacute -20 KPX b ydieresis -20 KPX c comma -15 KPX c k -20 KPX c kcommaaccent -20 KPX cacute comma -15 KPX cacute k -20 KPX cacute kcommaaccent -20 KPX ccaron comma -15 KPX ccaron k -20 KPX ccaron kcommaaccent -20 KPX ccedilla comma -15 KPX ccedilla k -20 KPX ccedilla kcommaaccent -20 KPX colon space -50 KPX comma quotedblright -100 KPX comma quoteright -100 KPX e comma -15 KPX e period -15 KPX e v -30 KPX e w -20 KPX e x -30 KPX e y -20 KPX e yacute -20 KPX e ydieresis -20 KPX eacute comma -15 KPX eacute period -15 KPX eacute v -30 KPX eacute w -20 KPX eacute x -30 KPX eacute y -20 KPX eacute yacute -20 KPX eacute ydieresis -20 KPX ecaron comma -15 KPX ecaron period -15 KPX ecaron v -30 KPX ecaron w -20 KPX ecaron x -30 KPX ecaron y -20 KPX ecaron yacute -20 KPX ecaron ydieresis -20 KPX ecircumflex comma -15 KPX ecircumflex period -15 KPX ecircumflex v -30 KPX ecircumflex w -20 KPX ecircumflex x -30 KPX ecircumflex y -20 KPX ecircumflex yacute -20 KPX ecircumflex ydieresis -20 KPX edieresis comma -15 KPX edieresis period -15 KPX edieresis v -30 KPX edieresis w -20 KPX edieresis x -30 KPX edieresis y -20 KPX edieresis yacute -20 KPX edieresis ydieresis -20 KPX edotaccent comma -15 KPX edotaccent period -15 KPX edotaccent v -30 KPX edotaccent w -20 KPX edotaccent x -30 KPX edotaccent y -20 KPX edotaccent yacute -20 KPX edotaccent ydieresis -20 KPX egrave comma -15 KPX egrave period -15 KPX egrave v -30 KPX egrave w -20 KPX egrave x -30 KPX egrave y -20 KPX egrave yacute -20 KPX egrave ydieresis -20 KPX emacron comma -15 KPX emacron period -15 KPX emacron v -30 KPX emacron w -20 KPX emacron x -30 KPX emacron y -20 KPX emacron yacute -20 KPX emacron ydieresis -20 KPX eogonek comma -15 KPX eogonek period -15 KPX eogonek v -30 KPX eogonek w -20 KPX eogonek x -30 KPX eogonek y -20 KPX eogonek yacute -20 KPX eogonek ydieresis -20 KPX f a -30 KPX f aacute -30 KPX f abreve -30 KPX f acircumflex -30 KPX f adieresis -30 KPX f agrave -30 KPX f amacron -30 KPX f aogonek -30 KPX f aring -30 KPX f atilde -30 KPX f comma -30 KPX f dotlessi -28 KPX f e -30 KPX f eacute -30 KPX f ecaron -30 KPX f ecircumflex -30 KPX f edieresis -30 KPX f edotaccent -30 KPX f egrave -30 KPX f emacron -30 KPX f eogonek -30 KPX f o -30 KPX f oacute -30 KPX f ocircumflex -30 KPX f odieresis -30 KPX f ograve -30 KPX f ohungarumlaut -30 KPX f omacron -30 KPX f oslash -30 KPX f otilde -30 KPX f period -30 KPX f quotedblright 60 KPX f quoteright 50 KPX g r -10 KPX g racute -10 KPX g rcaron -10 KPX g rcommaaccent -10 KPX gbreve r -10 KPX gbreve racute -10 KPX gbreve rcaron -10 KPX gbreve rcommaaccent -10 KPX gcommaaccent r -10 KPX gcommaaccent racute -10 KPX gcommaaccent rcaron -10 KPX gcommaaccent rcommaaccent -10 KPX h y -30 KPX h yacute -30 KPX h ydieresis -30 KPX k e -20 KPX k eacute -20 KPX k ecaron -20 KPX k ecircumflex -20 KPX k edieresis -20 KPX k edotaccent -20 KPX k egrave -20 KPX k emacron -20 KPX k eogonek -20 KPX k o -20 KPX k oacute -20 KPX k ocircumflex -20 KPX k odieresis -20 KPX k ograve -20 KPX k ohungarumlaut -20 KPX k omacron -20 KPX k oslash -20 KPX k otilde -20 KPX kcommaaccent e -20 KPX kcommaaccent eacute -20 KPX kcommaaccent ecaron -20 KPX kcommaaccent ecircumflex -20 KPX kcommaaccent edieresis -20 KPX kcommaaccent edotaccent -20 KPX kcommaaccent egrave -20 KPX kcommaaccent emacron -20 KPX kcommaaccent eogonek -20 KPX kcommaaccent o -20 KPX kcommaaccent oacute -20 KPX kcommaaccent ocircumflex -20 KPX kcommaaccent odieresis -20 KPX kcommaaccent ograve -20 KPX kcommaaccent ohungarumlaut -20 KPX kcommaaccent omacron -20 KPX kcommaaccent oslash -20 KPX kcommaaccent otilde -20 KPX m u -10 KPX m uacute -10 KPX m ucircumflex -10 KPX m udieresis -10 KPX m ugrave -10 KPX m uhungarumlaut -10 KPX m umacron -10 KPX m uogonek -10 KPX m uring -10 KPX m y -15 KPX m yacute -15 KPX m ydieresis -15 KPX n u -10 KPX n uacute -10 KPX n ucircumflex -10 KPX n udieresis -10 KPX n ugrave -10 KPX n uhungarumlaut -10 KPX n umacron -10 KPX n uogonek -10 KPX n uring -10 KPX n v -20 KPX n y -15 KPX n yacute -15 KPX n ydieresis -15 KPX nacute u -10 KPX nacute uacute -10 KPX nacute ucircumflex -10 KPX nacute udieresis -10 KPX nacute ugrave -10 KPX nacute uhungarumlaut -10 KPX nacute umacron -10 KPX nacute uogonek -10 KPX nacute uring -10 KPX nacute v -20 KPX nacute y -15 KPX nacute yacute -15 KPX nacute ydieresis -15 KPX ncaron u -10 KPX ncaron uacute -10 KPX ncaron ucircumflex -10 KPX ncaron udieresis -10 KPX ncaron ugrave -10 KPX ncaron uhungarumlaut -10 KPX ncaron umacron -10 KPX ncaron uogonek -10 KPX ncaron uring -10 KPX ncaron v -20 KPX ncaron y -15 KPX ncaron yacute -15 KPX ncaron ydieresis -15 KPX ncommaaccent u -10 KPX ncommaaccent uacute -10 KPX ncommaaccent ucircumflex -10 KPX ncommaaccent udieresis -10 KPX ncommaaccent ugrave -10 KPX ncommaaccent uhungarumlaut -10 KPX ncommaaccent umacron -10 KPX ncommaaccent uogonek -10 KPX ncommaaccent uring -10 KPX ncommaaccent v -20 KPX ncommaaccent y -15 KPX ncommaaccent yacute -15 KPX ncommaaccent ydieresis -15 KPX ntilde u -10 KPX ntilde uacute -10 KPX ntilde ucircumflex -10 KPX ntilde udieresis -10 KPX ntilde ugrave -10 KPX ntilde uhungarumlaut -10 KPX ntilde umacron -10 KPX ntilde uogonek -10 KPX ntilde uring -10 KPX ntilde v -20 KPX ntilde y -15 KPX ntilde yacute -15 KPX ntilde ydieresis -15 KPX o comma -40 KPX o period -40 KPX o v -15 KPX o w -15 KPX o x -30 KPX o y -30 KPX o yacute -30 KPX o ydieresis -30 KPX oacute comma -40 KPX oacute period -40 KPX oacute v -15 KPX oacute w -15 KPX oacute x -30 KPX oacute y -30 KPX oacute yacute -30 KPX oacute ydieresis -30 KPX ocircumflex comma -40 KPX ocircumflex period -40 KPX ocircumflex v -15 KPX ocircumflex w -15 KPX ocircumflex x -30 KPX ocircumflex y -30 KPX ocircumflex yacute -30 KPX ocircumflex ydieresis -30 KPX odieresis comma -40 KPX odieresis period -40 KPX odieresis v -15 KPX odieresis w -15 KPX odieresis x -30 KPX odieresis y -30 KPX odieresis yacute -30 KPX odieresis ydieresis -30 KPX ograve comma -40 KPX ograve period -40 KPX ograve v -15 KPX ograve w -15 KPX ograve x -30 KPX ograve y -30 KPX ograve yacute -30 KPX ograve ydieresis -30 KPX ohungarumlaut comma -40 KPX ohungarumlaut period -40 KPX ohungarumlaut v -15 KPX ohungarumlaut w -15 KPX ohungarumlaut x -30 KPX ohungarumlaut y -30 KPX ohungarumlaut yacute -30 KPX ohungarumlaut ydieresis -30 KPX omacron comma -40 KPX omacron period -40 KPX omacron v -15 KPX omacron w -15 KPX omacron x -30 KPX omacron y -30 KPX omacron yacute -30 KPX omacron ydieresis -30 KPX oslash a -55 KPX oslash aacute -55 KPX oslash abreve -55 KPX oslash acircumflex -55 KPX oslash adieresis -55 KPX oslash agrave -55 KPX oslash amacron -55 KPX oslash aogonek -55 KPX oslash aring -55 KPX oslash atilde -55 KPX oslash b -55 KPX oslash c -55 KPX oslash cacute -55 KPX oslash ccaron -55 KPX oslash ccedilla -55 KPX oslash comma -95 KPX oslash d -55 KPX oslash dcroat -55 KPX oslash e -55 KPX oslash eacute -55 KPX oslash ecaron -55 KPX oslash ecircumflex -55 KPX oslash edieresis -55 KPX oslash edotaccent -55 KPX oslash egrave -55 KPX oslash emacron -55 KPX oslash eogonek -55 KPX oslash f -55 KPX oslash g -55 KPX oslash gbreve -55 KPX oslash gcommaaccent -55 KPX oslash h -55 KPX oslash i -55 KPX oslash iacute -55 KPX oslash icircumflex -55 KPX oslash idieresis -55 KPX oslash igrave -55 KPX oslash imacron -55 KPX oslash iogonek -55 KPX oslash j -55 KPX oslash k -55 KPX oslash kcommaaccent -55 KPX oslash l -55 KPX oslash lacute -55 KPX oslash lcommaaccent -55 KPX oslash lslash -55 KPX oslash m -55 KPX oslash n -55 KPX oslash nacute -55 KPX oslash ncaron -55 KPX oslash ncommaaccent -55 KPX oslash ntilde -55 KPX oslash o -55 KPX oslash oacute -55 KPX oslash ocircumflex -55 KPX oslash odieresis -55 KPX oslash ograve -55 KPX oslash ohungarumlaut -55 KPX oslash omacron -55 KPX oslash oslash -55 KPX oslash otilde -55 KPX oslash p -55 KPX oslash period -95 KPX oslash q -55 KPX oslash r -55 KPX oslash racute -55 KPX oslash rcaron -55 KPX oslash rcommaaccent -55 KPX oslash s -55 KPX oslash sacute -55 KPX oslash scaron -55 KPX oslash scedilla -55 KPX oslash scommaaccent -55 KPX oslash t -55 KPX oslash tcommaaccent -55 KPX oslash u -55 KPX oslash uacute -55 KPX oslash ucircumflex -55 KPX oslash udieresis -55 KPX oslash ugrave -55 KPX oslash uhungarumlaut -55 KPX oslash umacron -55 KPX oslash uogonek -55 KPX oslash uring -55 KPX oslash v -70 KPX oslash w -70 KPX oslash x -85 KPX oslash y -70 KPX oslash yacute -70 KPX oslash ydieresis -70 KPX oslash z -55 KPX oslash zacute -55 KPX oslash zcaron -55 KPX oslash zdotaccent -55 KPX otilde comma -40 KPX otilde period -40 KPX otilde v -15 KPX otilde w -15 KPX otilde x -30 KPX otilde y -30 KPX otilde yacute -30 KPX otilde ydieresis -30 KPX p comma -35 KPX p period -35 KPX p y -30 KPX p yacute -30 KPX p ydieresis -30 KPX period quotedblright -100 KPX period quoteright -100 KPX period space -60 KPX quotedblright space -40 KPX quoteleft quoteleft -57 KPX quoteright d -50 KPX quoteright dcroat -50 KPX quoteright quoteright -57 KPX quoteright r -50 KPX quoteright racute -50 KPX quoteright rcaron -50 KPX quoteright rcommaaccent -50 KPX quoteright s -50 KPX quoteright sacute -50 KPX quoteright scaron -50 KPX quoteright scedilla -50 KPX quoteright scommaaccent -50 KPX quoteright space -70 KPX r a -10 KPX r aacute -10 KPX r abreve -10 KPX r acircumflex -10 KPX r adieresis -10 KPX r agrave -10 KPX r amacron -10 KPX r aogonek -10 KPX r aring -10 KPX r atilde -10 KPX r colon 30 KPX r comma -50 KPX r i 15 KPX r iacute 15 KPX r icircumflex 15 KPX r idieresis 15 KPX r igrave 15 KPX r imacron 15 KPX r iogonek 15 KPX r k 15 KPX r kcommaaccent 15 KPX r l 15 KPX r lacute 15 KPX r lcommaaccent 15 KPX r lslash 15 KPX r m 25 KPX r n 25 KPX r nacute 25 KPX r ncaron 25 KPX r ncommaaccent 25 KPX r ntilde 25 KPX r p 30 KPX r period -50 KPX r semicolon 30 KPX r t 40 KPX r tcommaaccent 40 KPX r u 15 KPX r uacute 15 KPX r ucircumflex 15 KPX r udieresis 15 KPX r ugrave 15 KPX r uhungarumlaut 15 KPX r umacron 15 KPX r uogonek 15 KPX r uring 15 KPX r v 30 KPX r y 30 KPX r yacute 30 KPX r ydieresis 30 KPX racute a -10 KPX racute aacute -10 KPX racute abreve -10 KPX racute acircumflex -10 KPX racute adieresis -10 KPX racute agrave -10 KPX racute amacron -10 KPX racute aogonek -10 KPX racute aring -10 KPX racute atilde -10 KPX racute colon 30 KPX racute comma -50 KPX racute i 15 KPX racute iacute 15 KPX racute icircumflex 15 KPX racute idieresis 15 KPX racute igrave 15 KPX racute imacron 15 KPX racute iogonek 15 KPX racute k 15 KPX racute kcommaaccent 15 KPX racute l 15 KPX racute lacute 15 KPX racute lcommaaccent 15 KPX racute lslash 15 KPX racute m 25 KPX racute n 25 KPX racute nacute 25 KPX racute ncaron 25 KPX racute ncommaaccent 25 KPX racute ntilde 25 KPX racute p 30 KPX racute period -50 KPX racute semicolon 30 KPX racute t 40 KPX racute tcommaaccent 40 KPX racute u 15 KPX racute uacute 15 KPX racute ucircumflex 15 KPX racute udieresis 15 KPX racute ugrave 15 KPX racute uhungarumlaut 15 KPX racute umacron 15 KPX racute uogonek 15 KPX racute uring 15 KPX racute v 30 KPX racute y 30 KPX racute yacute 30 KPX racute ydieresis 30 KPX rcaron a -10 KPX rcaron aacute -10 KPX rcaron abreve -10 KPX rcaron acircumflex -10 KPX rcaron adieresis -10 KPX rcaron agrave -10 KPX rcaron amacron -10 KPX rcaron aogonek -10 KPX rcaron aring -10 KPX rcaron atilde -10 KPX rcaron colon 30 KPX rcaron comma -50 KPX rcaron i 15 KPX rcaron iacute 15 KPX rcaron icircumflex 15 KPX rcaron idieresis 15 KPX rcaron igrave 15 KPX rcaron imacron 15 KPX rcaron iogonek 15 KPX rcaron k 15 KPX rcaron kcommaaccent 15 KPX rcaron l 15 KPX rcaron lacute 15 KPX rcaron lcommaaccent 15 KPX rcaron lslash 15 KPX rcaron m 25 KPX rcaron n 25 KPX rcaron nacute 25 KPX rcaron ncaron 25 KPX rcaron ncommaaccent 25 KPX rcaron ntilde 25 KPX rcaron p 30 KPX rcaron period -50 KPX rcaron semicolon 30 KPX rcaron t 40 KPX rcaron tcommaaccent 40 KPX rcaron u 15 KPX rcaron uacute 15 KPX rcaron ucircumflex 15 KPX rcaron udieresis 15 KPX rcaron ugrave 15 KPX rcaron uhungarumlaut 15 KPX rcaron umacron 15 KPX rcaron uogonek 15 KPX rcaron uring 15 KPX rcaron v 30 KPX rcaron y 30 KPX rcaron yacute 30 KPX rcaron ydieresis 30 KPX rcommaaccent a -10 KPX rcommaaccent aacute -10 KPX rcommaaccent abreve -10 KPX rcommaaccent acircumflex -10 KPX rcommaaccent adieresis -10 KPX rcommaaccent agrave -10 KPX rcommaaccent amacron -10 KPX rcommaaccent aogonek -10 KPX rcommaaccent aring -10 KPX rcommaaccent atilde -10 KPX rcommaaccent colon 30 KPX rcommaaccent comma -50 KPX rcommaaccent i 15 KPX rcommaaccent iacute 15 KPX rcommaaccent icircumflex 15 KPX rcommaaccent idieresis 15 KPX rcommaaccent igrave 15 KPX rcommaaccent imacron 15 KPX rcommaaccent iogonek 15 KPX rcommaaccent k 15 KPX rcommaaccent kcommaaccent 15 KPX rcommaaccent l 15 KPX rcommaaccent lacute 15 KPX rcommaaccent lcommaaccent 15 KPX rcommaaccent lslash 15 KPX rcommaaccent m 25 KPX rcommaaccent n 25 KPX rcommaaccent nacute 25 KPX rcommaaccent ncaron 25 KPX rcommaaccent ncommaaccent 25 KPX rcommaaccent ntilde 25 KPX rcommaaccent p 30 KPX rcommaaccent period -50 KPX rcommaaccent semicolon 30 KPX rcommaaccent t 40 KPX rcommaaccent tcommaaccent 40 KPX rcommaaccent u 15 KPX rcommaaccent uacute 15 KPX rcommaaccent ucircumflex 15 KPX rcommaaccent udieresis 15 KPX rcommaaccent ugrave 15 KPX rcommaaccent uhungarumlaut 15 KPX rcommaaccent umacron 15 KPX rcommaaccent uogonek 15 KPX rcommaaccent uring 15 KPX rcommaaccent v 30 KPX rcommaaccent y 30 KPX rcommaaccent yacute 30 KPX rcommaaccent ydieresis 30 KPX s comma -15 KPX s period -15 KPX s w -30 KPX sacute comma -15 KPX sacute period -15 KPX sacute w -30 KPX scaron comma -15 KPX scaron period -15 KPX scaron w -30 KPX scedilla comma -15 KPX scedilla period -15 KPX scedilla w -30 KPX scommaaccent comma -15 KPX scommaaccent period -15 KPX scommaaccent w -30 KPX semicolon space -50 KPX space T -50 KPX space Tcaron -50 KPX space Tcommaaccent -50 KPX space V -50 KPX space W -40 KPX space Y -90 KPX space Yacute -90 KPX space Ydieresis -90 KPX space quotedblleft -30 KPX space quoteleft -60 KPX v a -25 KPX v aacute -25 KPX v abreve -25 KPX v acircumflex -25 KPX v adieresis -25 KPX v agrave -25 KPX v amacron -25 KPX v aogonek -25 KPX v aring -25 KPX v atilde -25 KPX v comma -80 KPX v e -25 KPX v eacute -25 KPX v ecaron -25 KPX v ecircumflex -25 KPX v edieresis -25 KPX v edotaccent -25 KPX v egrave -25 KPX v emacron -25 KPX v eogonek -25 KPX v o -25 KPX v oacute -25 KPX v ocircumflex -25 KPX v odieresis -25 KPX v ograve -25 KPX v ohungarumlaut -25 KPX v omacron -25 KPX v oslash -25 KPX v otilde -25 KPX v period -80 KPX w a -15 KPX w aacute -15 KPX w abreve -15 KPX w acircumflex -15 KPX w adieresis -15 KPX w agrave -15 KPX w amacron -15 KPX w aogonek -15 KPX w aring -15 KPX w atilde -15 KPX w comma -60 KPX w e -10 KPX w eacute -10 KPX w ecaron -10 KPX w ecircumflex -10 KPX w edieresis -10 KPX w edotaccent -10 KPX w egrave -10 KPX w emacron -10 KPX w eogonek -10 KPX w o -10 KPX w oacute -10 KPX w ocircumflex -10 KPX w odieresis -10 KPX w ograve -10 KPX w ohungarumlaut -10 KPX w omacron -10 KPX w oslash -10 KPX w otilde -10 KPX w period -60 KPX x e -30 KPX x eacute -30 KPX x ecaron -30 KPX x ecircumflex -30 KPX x edieresis -30 KPX x edotaccent -30 KPX x egrave -30 KPX x emacron -30 KPX x eogonek -30 KPX y a -20 KPX y aacute -20 KPX y abreve -20 KPX y acircumflex -20 KPX y adieresis -20 KPX y agrave -20 KPX y amacron -20 KPX y aogonek -20 KPX y aring -20 KPX y atilde -20 KPX y comma -100 KPX y e -20 KPX y eacute -20 KPX y ecaron -20 KPX y ecircumflex -20 KPX y edieresis -20 KPX y edotaccent -20 KPX y egrave -20 KPX y emacron -20 KPX y eogonek -20 KPX y o -20 KPX y oacute -20 KPX y ocircumflex -20 KPX y odieresis -20 KPX y ograve -20 KPX y ohungarumlaut -20 KPX y omacron -20 KPX y oslash -20 KPX y otilde -20 KPX y period -100 KPX yacute a -20 KPX yacute aacute -20 KPX yacute abreve -20 KPX yacute acircumflex -20 KPX yacute adieresis -20 KPX yacute agrave -20 KPX yacute amacron -20 KPX yacute aogonek -20 KPX yacute aring -20 KPX yacute atilde -20 KPX yacute comma -100 KPX yacute e -20 KPX yacute eacute -20 KPX yacute ecaron -20 KPX yacute ecircumflex -20 KPX yacute edieresis -20 KPX yacute edotaccent -20 KPX yacute egrave -20 KPX yacute emacron -20 KPX yacute eogonek -20 KPX yacute o -20 KPX yacute oacute -20 KPX yacute ocircumflex -20 KPX yacute odieresis -20 KPX yacute ograve -20 KPX yacute ohungarumlaut -20 KPX yacute omacron -20 KPX yacute oslash -20 KPX yacute otilde -20 KPX yacute period -100 KPX ydieresis a -20 KPX ydieresis aacute -20 KPX ydieresis abreve -20 KPX ydieresis acircumflex -20 KPX ydieresis adieresis -20 KPX ydieresis agrave -20 KPX ydieresis amacron -20 KPX ydieresis aogonek -20 KPX ydieresis aring -20 KPX ydieresis atilde -20 KPX ydieresis comma -100 KPX ydieresis e -20 KPX ydieresis eacute -20 KPX ydieresis ecaron -20 KPX ydieresis ecircumflex -20 KPX ydieresis edieresis -20 KPX ydieresis edotaccent -20 KPX ydieresis egrave -20 KPX ydieresis emacron -20 KPX ydieresis eogonek -20 KPX ydieresis o -20 KPX ydieresis oacute -20 KPX ydieresis ocircumflex -20 KPX ydieresis odieresis -20 KPX ydieresis ograve -20 KPX ydieresis ohungarumlaut -20 KPX ydieresis omacron -20 KPX ydieresis oslash -20 KPX ydieresis otilde -20 KPX ydieresis period -100 KPX z e -15 KPX z eacute -15 KPX z ecaron -15 KPX z ecircumflex -15 KPX z edieresis -15 KPX z edotaccent -15 KPX z egrave -15 KPX z emacron -15 KPX z eogonek -15 KPX z o -15 KPX z oacute -15 KPX z ocircumflex -15 KPX z odieresis -15 KPX z ograve -15 KPX z ohungarumlaut -15 KPX z omacron -15 KPX z oslash -15 KPX z otilde -15 KPX zacute e -15 KPX zacute eacute -15 KPX zacute ecaron -15 KPX zacute ecircumflex -15 KPX zacute edieresis -15 KPX zacute edotaccent -15 KPX zacute egrave -15 KPX zacute emacron -15 KPX zacute eogonek -15 KPX zacute o -15 KPX zacute oacute -15 KPX zacute ocircumflex -15 KPX zacute odieresis -15 KPX zacute ograve -15 KPX zacute ohungarumlaut -15 KPX zacute omacron -15 KPX zacute oslash -15 KPX zacute otilde -15 KPX zcaron e -15 KPX zcaron eacute -15 KPX zcaron ecaron -15 KPX zcaron ecircumflex -15 KPX zcaron edieresis -15 KPX zcaron edotaccent -15 KPX zcaron egrave -15 KPX zcaron emacron -15 KPX zcaron eogonek -15 KPX zcaron o -15 KPX zcaron oacute -15 KPX zcaron ocircumflex -15 KPX zcaron odieresis -15 KPX zcaron ograve -15 KPX zcaron ohungarumlaut -15 KPX zcaron omacron -15 KPX zcaron oslash -15 KPX zcaron otilde -15 KPX zdotaccent e -15 KPX zdotaccent eacute -15 KPX zdotaccent ecaron -15 KPX zdotaccent ecircumflex -15 KPX zdotaccent edieresis -15 KPX zdotaccent edotaccent -15 KPX zdotaccent egrave -15 KPX zdotaccent emacron -15 KPX zdotaccent eogonek -15 KPX zdotaccent o -15 KPX zdotaccent oacute -15 KPX zdotaccent ocircumflex -15 KPX zdotaccent odieresis -15 KPX zdotaccent ograve -15 KPX zdotaccent ohungarumlaut -15 KPX zdotaccent omacron -15 KPX zdotaccent oslash -15 KPX zdotaccent otilde -15 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Symbol.afm100644 0 0 23341 11000354125 16763 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. Comment Creation Date: Thu May 1 15:12:25 1997 Comment UniqueID 43064 Comment VMusage 30820 39997 FontName Symbol FullName Symbol FamilyName Symbol Weight Medium ItalicAngle 0 IsFixedPitch false CharacterSet Special FontBBox -180 -293 1090 1010 UnderlinePosition -100 UnderlineThickness 50 Version 001.008 Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved. EncodingScheme FontSpecific StdHW 92 StdVW 85 StartCharMetrics 190 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ; C 34 ; WX 713 ; N universal ; B 31 0 681 705 ; C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ; C 36 ; WX 549 ; N existential ; B 25 0 478 707 ; C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ; C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ; C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ; C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ; C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ; C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ; C 43 ; WX 549 ; N plus ; B 10 0 539 533 ; C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ; C 45 ; WX 549 ; N minus ; B 11 233 535 288 ; C 46 ; WX 250 ; N period ; B 69 -17 181 95 ; C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ; C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ; C 49 ; WX 500 ; N one ; B 117 0 390 673 ; C 50 ; WX 500 ; N two ; B 25 0 475 685 ; C 51 ; WX 500 ; N three ; B 43 -14 435 685 ; C 52 ; WX 500 ; N four ; B 15 0 469 685 ; C 53 ; WX 500 ; N five ; B 32 -14 445 690 ; C 54 ; WX 500 ; N six ; B 34 -14 468 685 ; C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ; C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ; C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ; C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ; C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ; C 60 ; WX 549 ; N less ; B 26 0 523 522 ; C 61 ; WX 549 ; N equal ; B 11 141 537 390 ; C 62 ; WX 549 ; N greater ; B 26 0 523 522 ; C 63 ; WX 444 ; N question ; B 70 -17 412 686 ; C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ; C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ; C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ; C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ; C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ; C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ; C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ; C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ; C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ; C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ; C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ; C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ; C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ; C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ; C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ; C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ; C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ; C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ; C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ; C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ; C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ; C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ; C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ; C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ; C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ; C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ; C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ; C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ; C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ; C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ; C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ; C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ; C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ; C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ; C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ; C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ; C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ; C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ; C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ; C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ; C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ; C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ; C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ; C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ; C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ; C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ; C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ; C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ; C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ; C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ; C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ; C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ; C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ; C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ; C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ; C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ; C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ; C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ; C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ; C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ; C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ; C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ; C 126 ; WX 549 ; N similar ; B 17 203 529 307 ; C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ; C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ; C 162 ; WX 247 ; N minute ; B 27 459 228 735 ; C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ; C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ; C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ; C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ; C 167 ; WX 753 ; N club ; B 86 -26 660 533 ; C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ; C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ; C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ; C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ; C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ; C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ; C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ; C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ; C 176 ; WX 400 ; N degree ; B 50 385 350 685 ; C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ; C 178 ; WX 411 ; N second ; B 20 459 413 737 ; C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ; C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ; C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ; C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ; C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ; C 184 ; WX 549 ; N divide ; B 10 71 536 456 ; C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ; C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ; C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ; C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ; C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ; C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ; C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ; C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ; C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ; C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ; C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ; C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ; C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ; C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ; C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ; C 200 ; WX 768 ; N union ; B 40 -17 732 492 ; C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ; C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ; C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ; C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ; C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ; C 206 ; WX 713 ; N element ; B 45 0 505 468 ; C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ; C 208 ; WX 768 ; N angle ; B 26 0 738 673 ; C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ; C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ; C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ; C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ; C 213 ; WX 823 ; N product ; B 25 -101 803 751 ; C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ; C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ; C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ; C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ; C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ; C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ; C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ; C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ; C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ; C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ; C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ; C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ; C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ; C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ; C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ; C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ; C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ; C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ; C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ; C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ; C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ; C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ; C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ; C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ; C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ; C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ; C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ; C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ; C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ; C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ; C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ; C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ; C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ; C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ; C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ; C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ; C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ; C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ; C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ; C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ; C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Times-Bold.afm100644 0 0 202427 11000354125 17501 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:52:56 1997 Comment UniqueID 43065 Comment VMusage 41636 52661 FontName Times-Bold FullName Times Bold FamilyName Times Weight Bold ItalicAngle 0 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -168 -218 1000 935 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 676 XHeight 461 Ascender 683 Descender -217 StdHW 44 StdVW 139 StartCharMetrics 315 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ; C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ; C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ; C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ; C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ; C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ; C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ; C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ; C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ; C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ; C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ; C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ; C 46 ; WX 250 ; N period ; B 41 -13 210 156 ; C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ; C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ; C 49 ; WX 500 ; N one ; B 65 0 442 688 ; C 50 ; WX 500 ; N two ; B 17 0 478 688 ; C 51 ; WX 500 ; N three ; B 16 -14 468 688 ; C 52 ; WX 500 ; N four ; B 19 0 475 688 ; C 53 ; WX 500 ; N five ; B 22 -8 470 676 ; C 54 ; WX 500 ; N six ; B 28 -13 475 688 ; C 55 ; WX 500 ; N seven ; B 17 0 477 676 ; C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ; C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ; C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ; C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ; C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; C 63 ; WX 500 ; N question ; B 57 -13 445 689 ; C 64 ; WX 930 ; N at ; B 108 -19 822 691 ; C 65 ; WX 722 ; N A ; B 9 0 689 690 ; C 66 ; WX 667 ; N B ; B 16 0 619 676 ; C 67 ; WX 722 ; N C ; B 49 -19 687 691 ; C 68 ; WX 722 ; N D ; B 14 0 690 676 ; C 69 ; WX 667 ; N E ; B 16 0 641 676 ; C 70 ; WX 611 ; N F ; B 16 0 583 676 ; C 71 ; WX 778 ; N G ; B 37 -19 755 691 ; C 72 ; WX 778 ; N H ; B 21 0 759 676 ; C 73 ; WX 389 ; N I ; B 20 0 370 676 ; C 74 ; WX 500 ; N J ; B 3 -96 479 676 ; C 75 ; WX 778 ; N K ; B 30 0 769 676 ; C 76 ; WX 667 ; N L ; B 19 0 638 676 ; C 77 ; WX 944 ; N M ; B 14 0 921 676 ; C 78 ; WX 722 ; N N ; B 16 -18 701 676 ; C 79 ; WX 778 ; N O ; B 35 -19 743 691 ; C 80 ; WX 611 ; N P ; B 16 0 600 676 ; C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ; C 82 ; WX 722 ; N R ; B 26 0 715 676 ; C 83 ; WX 556 ; N S ; B 35 -19 513 692 ; C 84 ; WX 667 ; N T ; B 31 0 636 676 ; C 85 ; WX 722 ; N U ; B 16 -19 701 676 ; C 86 ; WX 722 ; N V ; B 16 -18 701 676 ; C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ; C 88 ; WX 722 ; N X ; B 16 0 699 676 ; C 89 ; WX 722 ; N Y ; B 15 0 699 676 ; C 90 ; WX 667 ; N Z ; B 28 0 634 676 ; C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ; C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ; C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ; C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ; C 97 ; WX 500 ; N a ; B 25 -14 488 473 ; C 98 ; WX 556 ; N b ; B 17 -14 521 676 ; C 99 ; WX 444 ; N c ; B 25 -14 430 473 ; C 100 ; WX 556 ; N d ; B 25 -14 534 676 ; C 101 ; WX 444 ; N e ; B 25 -14 426 473 ; C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 28 -206 483 473 ; C 104 ; WX 556 ; N h ; B 16 0 534 676 ; C 105 ; WX 278 ; N i ; B 16 0 255 691 ; C 106 ; WX 333 ; N j ; B -57 -203 263 691 ; C 107 ; WX 556 ; N k ; B 22 0 543 676 ; C 108 ; WX 278 ; N l ; B 16 0 255 676 ; C 109 ; WX 833 ; N m ; B 16 0 814 473 ; C 110 ; WX 556 ; N n ; B 21 0 539 473 ; C 111 ; WX 500 ; N o ; B 25 -14 476 473 ; C 112 ; WX 556 ; N p ; B 19 -205 524 473 ; C 113 ; WX 556 ; N q ; B 34 -205 536 473 ; C 114 ; WX 444 ; N r ; B 29 0 434 473 ; C 115 ; WX 389 ; N s ; B 25 -14 361 473 ; C 116 ; WX 333 ; N t ; B 20 -12 332 630 ; C 117 ; WX 556 ; N u ; B 16 -14 537 461 ; C 118 ; WX 500 ; N v ; B 21 -14 485 461 ; C 119 ; WX 722 ; N w ; B 23 -14 707 461 ; C 120 ; WX 500 ; N x ; B 12 0 484 461 ; C 121 ; WX 500 ; N y ; B 16 -205 480 461 ; C 122 ; WX 444 ; N z ; B 21 0 420 461 ; C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ; C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ; C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ; C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ; C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ; C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ; C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ; C 165 ; WX 500 ; N yen ; B -64 0 547 676 ; C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ; C 167 ; WX 500 ; N section ; B 57 -132 443 691 ; C 168 ; WX 500 ; N currency ; B -26 61 526 613 ; C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ; C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ; C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ; C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ; C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ; C 174 ; WX 556 ; N fi ; B 14 0 536 691 ; C 175 ; WX 556 ; N fl ; B 14 0 536 691 ; C 177 ; WX 500 ; N endash ; B 0 181 500 271 ; C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ; C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ; C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ; C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ; C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ; C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ; C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ; C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ; C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ; C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ; C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ; C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ; C 193 ; WX 333 ; N grave ; B 8 528 246 713 ; C 194 ; WX 333 ; N acute ; B 86 528 324 713 ; C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ; C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ; C 197 ; WX 333 ; N macron ; B 1 565 331 637 ; C 198 ; WX 333 ; N breve ; B 15 528 318 691 ; C 199 ; WX 333 ; N dotaccent ; B 103 536 258 691 ; C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ; C 202 ; WX 333 ; N ring ; B 60 527 273 740 ; C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ; C 206 ; WX 333 ; N ogonek ; B 90 -193 319 24 ; C 207 ; WX 333 ; N caron ; B -2 528 335 704 ; C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ; C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ; C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ; C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ; C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ; C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ; C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ; C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ; C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ; C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ; C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ; C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ; C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ; C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ; C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ; C -1 ; WX 500 ; N abreve ; B 25 -14 488 691 ; C -1 ; WX 556 ; N uhungarumlaut ; B 16 -14 557 713 ; C -1 ; WX 444 ; N ecaron ; B 25 -14 426 704 ; C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ; C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ; C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ; C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ; C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ; C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ; C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ; C -1 ; WX 389 ; N scommaaccent ; B 25 -218 361 473 ; C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ; C -1 ; WX 722 ; N Uring ; B 16 -19 701 935 ; C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ; C -1 ; WX 500 ; N aogonek ; B 25 -193 504 473 ; C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ; C -1 ; WX 556 ; N uogonek ; B 16 -193 539 461 ; C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ; C -1 ; WX 722 ; N Dcroat ; B 6 0 690 676 ; C -1 ; WX 250 ; N commaaccent ; B 47 -218 203 -50 ; C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ; C -1 ; WX 667 ; N Emacron ; B 16 0 641 847 ; C -1 ; WX 444 ; N ccaron ; B 25 -14 430 704 ; C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ; C -1 ; WX 722 ; N Ncommaaccent ; B 16 -188 701 676 ; C -1 ; WX 278 ; N lacute ; B 16 0 297 923 ; C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ; C -1 ; WX 667 ; N Tcommaaccent ; B 31 -218 636 676 ; C -1 ; WX 722 ; N Cacute ; B 49 -19 687 923 ; C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ; C -1 ; WX 667 ; N Edotaccent ; B 16 0 641 901 ; C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ; C -1 ; WX 389 ; N scedilla ; B 25 -218 361 473 ; C -1 ; WX 278 ; N iacute ; B 16 0 289 713 ; C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; C -1 ; WX 722 ; N Rcaron ; B 26 0 715 914 ; C -1 ; WX 778 ; N Gcommaaccent ; B 37 -218 755 691 ; C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ; C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ; C -1 ; WX 722 ; N Amacron ; B 9 0 689 847 ; C -1 ; WX 444 ; N rcaron ; B 29 0 434 704 ; C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ; C -1 ; WX 667 ; N Zdotaccent ; B 28 0 634 901 ; C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ; C -1 ; WX 778 ; N Omacron ; B 35 -19 743 847 ; C -1 ; WX 722 ; N Racute ; B 26 0 715 923 ; C -1 ; WX 556 ; N Sacute ; B 35 -19 513 923 ; C -1 ; WX 672 ; N dcaron ; B 25 -14 681 682 ; C -1 ; WX 722 ; N Umacron ; B 16 -19 701 847 ; C -1 ; WX 556 ; N uring ; B 16 -14 537 740 ; C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ; C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ; C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ; C -1 ; WX 722 ; N Abreve ; B 9 0 689 901 ; C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ; C -1 ; WX 667 ; N Tcaron ; B 31 0 636 914 ; C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ; C -1 ; WX 722 ; N Nacute ; B 16 -18 701 923 ; C -1 ; WX 278 ; N icircumflex ; B -37 0 300 704 ; C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ; C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ; C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ; C -1 ; WX 444 ; N cacute ; B 25 -14 430 713 ; C -1 ; WX 556 ; N nacute ; B 21 0 539 713 ; C -1 ; WX 556 ; N umacron ; B 16 -14 537 637 ; C -1 ; WX 722 ; N Ncaron ; B 16 -18 701 914 ; C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ; C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ; C -1 ; WX 778 ; N Gbreve ; B 37 -19 755 901 ; C -1 ; WX 389 ; N Idotaccent ; B 20 0 370 901 ; C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ; C -1 ; WX 444 ; N racute ; B 29 0 434 713 ; C -1 ; WX 500 ; N omacron ; B 25 -14 476 637 ; C -1 ; WX 667 ; N Zacute ; B 28 0 634 923 ; C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ; C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ; C -1 ; WX 278 ; N lcommaaccent ; B 16 -218 255 676 ; C -1 ; WX 416 ; N tcaron ; B 20 -12 425 815 ; C -1 ; WX 444 ; N eogonek ; B 25 -193 426 473 ; C -1 ; WX 722 ; N Uogonek ; B 16 -193 701 676 ; C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ; C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ; C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ; C -1 ; WX 444 ; N zacute ; B 21 0 420 713 ; C -1 ; WX 278 ; N iogonek ; B 16 -193 274 691 ; C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ; C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ; C -1 ; WX 500 ; N amacron ; B 25 -14 488 637 ; C -1 ; WX 389 ; N sacute ; B 25 -14 361 713 ; C -1 ; WX 278 ; N idieresis ; B -37 0 300 667 ; C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ; C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ; C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ; C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ; C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ; C -1 ; WX 278 ; N igrave ; B -27 0 255 713 ; C -1 ; WX 500 ; N ohungarumlaut ; B 25 -14 529 713 ; C -1 ; WX 667 ; N Eogonek ; B 16 -193 644 676 ; C -1 ; WX 556 ; N dcroat ; B 25 -14 534 676 ; C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ; C -1 ; WX 556 ; N Scedilla ; B 35 -218 513 692 ; C -1 ; WX 394 ; N lcaron ; B 16 0 412 682 ; C -1 ; WX 778 ; N Kcommaaccent ; B 30 -218 769 676 ; C -1 ; WX 667 ; N Lacute ; B 19 0 638 923 ; C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ; C -1 ; WX 444 ; N edotaccent ; B 25 -14 426 691 ; C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ; C -1 ; WX 389 ; N Imacron ; B 20 0 370 847 ; C -1 ; WX 667 ; N Lcaron ; B 19 0 652 682 ; C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ; C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ; C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 16 -19 701 923 ; C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ; C -1 ; WX 444 ; N emacron ; B 25 -14 426 637 ; C -1 ; WX 500 ; N gbreve ; B 28 -206 483 691 ; C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ; C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ; C -1 ; WX 556 ; N Scommaaccent ; B 35 -218 513 692 ; C -1 ; WX 778 ; N Ohungarumlaut ; B 35 -19 743 923 ; C -1 ; WX 400 ; N degree ; B 57 402 343 688 ; C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ; C -1 ; WX 722 ; N Ccaron ; B 49 -19 687 914 ; C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ; C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; C -1 ; WX 722 ; N Dcaron ; B 14 0 690 914 ; C -1 ; WX 444 ; N rcommaaccent ; B 29 -218 434 473 ; C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ; C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ; C -1 ; WX 722 ; N Rcommaaccent ; B 26 -218 715 676 ; C -1 ; WX 667 ; N Lcommaaccent ; B 19 -218 638 676 ; C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ; C -1 ; WX 722 ; N Aogonek ; B 9 -193 699 690 ; C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ; C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ; C -1 ; WX 444 ; N zdotaccent ; B 21 0 420 691 ; C -1 ; WX 667 ; N Ecaron ; B 16 0 641 914 ; C -1 ; WX 389 ; N Iogonek ; B 20 -193 370 676 ; C -1 ; WX 556 ; N kcommaaccent ; B 22 -218 543 676 ; C -1 ; WX 570 ; N minus ; B 33 209 537 297 ; C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ; C -1 ; WX 556 ; N ncaron ; B 21 0 539 704 ; C -1 ; WX 333 ; N tcommaaccent ; B 20 -218 332 630 ; C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ; C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ; C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ; C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; C -1 ; WX 500 ; N gcommaaccent ; B 28 -206 483 829 ; C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ; C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ; C -1 ; WX 556 ; N ncommaaccent ; B 21 -218 539 473 ; C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ; C -1 ; WX 278 ; N imacron ; B -8 0 272 637 ; C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2242 KPX A C -55 KPX A Cacute -55 KPX A Ccaron -55 KPX A Ccedilla -55 KPX A G -55 KPX A Gbreve -55 KPX A Gcommaaccent -55 KPX A O -45 KPX A Oacute -45 KPX A Ocircumflex -45 KPX A Odieresis -45 KPX A Ograve -45 KPX A Ohungarumlaut -45 KPX A Omacron -45 KPX A Oslash -45 KPX A Otilde -45 KPX A Q -45 KPX A T -95 KPX A Tcaron -95 KPX A Tcommaaccent -95 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -145 KPX A W -130 KPX A Y -100 KPX A Yacute -100 KPX A Ydieresis -100 KPX A p -25 KPX A quoteright -74 KPX A u -50 KPX A uacute -50 KPX A ucircumflex -50 KPX A udieresis -50 KPX A ugrave -50 KPX A uhungarumlaut -50 KPX A umacron -50 KPX A uogonek -50 KPX A uring -50 KPX A v -100 KPX A w -90 KPX A y -74 KPX A yacute -74 KPX A ydieresis -74 KPX Aacute C -55 KPX Aacute Cacute -55 KPX Aacute Ccaron -55 KPX Aacute Ccedilla -55 KPX Aacute G -55 KPX Aacute Gbreve -55 KPX Aacute Gcommaaccent -55 KPX Aacute O -45 KPX Aacute Oacute -45 KPX Aacute Ocircumflex -45 KPX Aacute Odieresis -45 KPX Aacute Ograve -45 KPX Aacute Ohungarumlaut -45 KPX Aacute Omacron -45 KPX Aacute Oslash -45 KPX Aacute Otilde -45 KPX Aacute Q -45 KPX Aacute T -95 KPX Aacute Tcaron -95 KPX Aacute Tcommaaccent -95 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -145 KPX Aacute W -130 KPX Aacute Y -100 KPX Aacute Yacute -100 KPX Aacute Ydieresis -100 KPX Aacute p -25 KPX Aacute quoteright -74 KPX Aacute u -50 KPX Aacute uacute -50 KPX Aacute ucircumflex -50 KPX Aacute udieresis -50 KPX Aacute ugrave -50 KPX Aacute uhungarumlaut -50 KPX Aacute umacron -50 KPX Aacute uogonek -50 KPX Aacute uring -50 KPX Aacute v -100 KPX Aacute w -90 KPX Aacute y -74 KPX Aacute yacute -74 KPX Aacute ydieresis -74 KPX Abreve C -55 KPX Abreve Cacute -55 KPX Abreve Ccaron -55 KPX Abreve Ccedilla -55 KPX Abreve G -55 KPX Abreve Gbreve -55 KPX Abreve Gcommaaccent -55 KPX Abreve O -45 KPX Abreve Oacute -45 KPX Abreve Ocircumflex -45 KPX Abreve Odieresis -45 KPX Abreve Ograve -45 KPX Abreve Ohungarumlaut -45 KPX Abreve Omacron -45 KPX Abreve Oslash -45 KPX Abreve Otilde -45 KPX Abreve Q -45 KPX Abreve T -95 KPX Abreve Tcaron -95 KPX Abreve Tcommaaccent -95 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -145 KPX Abreve W -130 KPX Abreve Y -100 KPX Abreve Yacute -100 KPX Abreve Ydieresis -100 KPX Abreve p -25 KPX Abreve quoteright -74 KPX Abreve u -50 KPX Abreve uacute -50 KPX Abreve ucircumflex -50 KPX Abreve udieresis -50 KPX Abreve ugrave -50 KPX Abreve uhungarumlaut -50 KPX Abreve umacron -50 KPX Abreve uogonek -50 KPX Abreve uring -50 KPX Abreve v -100 KPX Abreve w -90 KPX Abreve y -74 KPX Abreve yacute -74 KPX Abreve ydieresis -74 KPX Acircumflex C -55 KPX Acircumflex Cacute -55 KPX Acircumflex Ccaron -55 KPX Acircumflex Ccedilla -55 KPX Acircumflex G -55 KPX Acircumflex Gbreve -55 KPX Acircumflex Gcommaaccent -55 KPX Acircumflex O -45 KPX Acircumflex Oacute -45 KPX Acircumflex Ocircumflex -45 KPX Acircumflex Odieresis -45 KPX Acircumflex Ograve -45 KPX Acircumflex Ohungarumlaut -45 KPX Acircumflex Omacron -45 KPX Acircumflex Oslash -45 KPX Acircumflex Otilde -45 KPX Acircumflex Q -45 KPX Acircumflex T -95 KPX Acircumflex Tcaron -95 KPX Acircumflex Tcommaaccent -95 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -145 KPX Acircumflex W -130 KPX Acircumflex Y -100 KPX Acircumflex Yacute -100 KPX Acircumflex Ydieresis -100 KPX Acircumflex p -25 KPX Acircumflex quoteright -74 KPX Acircumflex u -50 KPX Acircumflex uacute -50 KPX Acircumflex ucircumflex -50 KPX Acircumflex udieresis -50 KPX Acircumflex ugrave -50 KPX Acircumflex uhungarumlaut -50 KPX Acircumflex umacron -50 KPX Acircumflex uogonek -50 KPX Acircumflex uring -50 KPX Acircumflex v -100 KPX Acircumflex w -90 KPX Acircumflex y -74 KPX Acircumflex yacute -74 KPX Acircumflex ydieresis -74 KPX Adieresis C -55 KPX Adieresis Cacute -55 KPX Adieresis Ccaron -55 KPX Adieresis Ccedilla -55 KPX Adieresis G -55 KPX Adieresis Gbreve -55 KPX Adieresis Gcommaaccent -55 KPX Adieresis O -45 KPX Adieresis Oacute -45 KPX Adieresis Ocircumflex -45 KPX Adieresis Odieresis -45 KPX Adieresis Ograve -45 KPX Adieresis Ohungarumlaut -45 KPX Adieresis Omacron -45 KPX Adieresis Oslash -45 KPX Adieresis Otilde -45 KPX Adieresis Q -45 KPX Adieresis T -95 KPX Adieresis Tcaron -95 KPX Adieresis Tcommaaccent -95 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -145 KPX Adieresis W -130 KPX Adieresis Y -100 KPX Adieresis Yacute -100 KPX Adieresis Ydieresis -100 KPX Adieresis p -25 KPX Adieresis quoteright -74 KPX Adieresis u -50 KPX Adieresis uacute -50 KPX Adieresis ucircumflex -50 KPX Adieresis udieresis -50 KPX Adieresis ugrave -50 KPX Adieresis uhungarumlaut -50 KPX Adieresis umacron -50 KPX Adieresis uogonek -50 KPX Adieresis uring -50 KPX Adieresis v -100 KPX Adieresis w -90 KPX Adieresis y -74 KPX Adieresis yacute -74 KPX Adieresis ydieresis -74 KPX Agrave C -55 KPX Agrave Cacute -55 KPX Agrave Ccaron -55 KPX Agrave Ccedilla -55 KPX Agrave G -55 KPX Agrave Gbreve -55 KPX Agrave Gcommaaccent -55 KPX Agrave O -45 KPX Agrave Oacute -45 KPX Agrave Ocircumflex -45 KPX Agrave Odieresis -45 KPX Agrave Ograve -45 KPX Agrave Ohungarumlaut -45 KPX Agrave Omacron -45 KPX Agrave Oslash -45 KPX Agrave Otilde -45 KPX Agrave Q -45 KPX Agrave T -95 KPX Agrave Tcaron -95 KPX Agrave Tcommaaccent -95 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -145 KPX Agrave W -130 KPX Agrave Y -100 KPX Agrave Yacute -100 KPX Agrave Ydieresis -100 KPX Agrave p -25 KPX Agrave quoteright -74 KPX Agrave u -50 KPX Agrave uacute -50 KPX Agrave ucircumflex -50 KPX Agrave udieresis -50 KPX Agrave ugrave -50 KPX Agrave uhungarumlaut -50 KPX Agrave umacron -50 KPX Agrave uogonek -50 KPX Agrave uring -50 KPX Agrave v -100 KPX Agrave w -90 KPX Agrave y -74 KPX Agrave yacute -74 KPX Agrave ydieresis -74 KPX Amacron C -55 KPX Amacron Cacute -55 KPX Amacron Ccaron -55 KPX Amacron Ccedilla -55 KPX Amacron G -55 KPX Amacron Gbreve -55 KPX Amacron Gcommaaccent -55 KPX Amacron O -45 KPX Amacron Oacute -45 KPX Amacron Ocircumflex -45 KPX Amacron Odieresis -45 KPX Amacron Ograve -45 KPX Amacron Ohungarumlaut -45 KPX Amacron Omacron -45 KPX Amacron Oslash -45 KPX Amacron Otilde -45 KPX Amacron Q -45 KPX Amacron T -95 KPX Amacron Tcaron -95 KPX Amacron Tcommaaccent -95 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -145 KPX Amacron W -130 KPX Amacron Y -100 KPX Amacron Yacute -100 KPX Amacron Ydieresis -100 KPX Amacron p -25 KPX Amacron quoteright -74 KPX Amacron u -50 KPX Amacron uacute -50 KPX Amacron ucircumflex -50 KPX Amacron udieresis -50 KPX Amacron ugrave -50 KPX Amacron uhungarumlaut -50 KPX Amacron umacron -50 KPX Amacron uogonek -50 KPX Amacron uring -50 KPX Amacron v -100 KPX Amacron w -90 KPX Amacron y -74 KPX Amacron yacute -74 KPX Amacron ydieresis -74 KPX Aogonek C -55 KPX Aogonek Cacute -55 KPX Aogonek Ccaron -55 KPX Aogonek Ccedilla -55 KPX Aogonek G -55 KPX Aogonek Gbreve -55 KPX Aogonek Gcommaaccent -55 KPX Aogonek O -45 KPX Aogonek Oacute -45 KPX Aogonek Ocircumflex -45 KPX Aogonek Odieresis -45 KPX Aogonek Ograve -45 KPX Aogonek Ohungarumlaut -45 KPX Aogonek Omacron -45 KPX Aogonek Oslash -45 KPX Aogonek Otilde -45 KPX Aogonek Q -45 KPX Aogonek T -95 KPX Aogonek Tcaron -95 KPX Aogonek Tcommaaccent -95 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -145 KPX Aogonek W -130 KPX Aogonek Y -100 KPX Aogonek Yacute -100 KPX Aogonek Ydieresis -100 KPX Aogonek p -25 KPX Aogonek quoteright -74 KPX Aogonek u -50 KPX Aogonek uacute -50 KPX Aogonek ucircumflex -50 KPX Aogonek udieresis -50 KPX Aogonek ugrave -50 KPX Aogonek uhungarumlaut -50 KPX Aogonek umacron -50 KPX Aogonek uogonek -50 KPX Aogonek uring -50 KPX Aogonek v -100 KPX Aogonek w -90 KPX Aogonek y -34 KPX Aogonek yacute -34 KPX Aogonek ydieresis -34 KPX Aring C -55 KPX Aring Cacute -55 KPX Aring Ccaron -55 KPX Aring Ccedilla -55 KPX Aring G -55 KPX Aring Gbreve -55 KPX Aring Gcommaaccent -55 KPX Aring O -45 KPX Aring Oacute -45 KPX Aring Ocircumflex -45 KPX Aring Odieresis -45 KPX Aring Ograve -45 KPX Aring Ohungarumlaut -45 KPX Aring Omacron -45 KPX Aring Oslash -45 KPX Aring Otilde -45 KPX Aring Q -45 KPX Aring T -95 KPX Aring Tcaron -95 KPX Aring Tcommaaccent -95 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -145 KPX Aring W -130 KPX Aring Y -100 KPX Aring Yacute -100 KPX Aring Ydieresis -100 KPX Aring p -25 KPX Aring quoteright -74 KPX Aring u -50 KPX Aring uacute -50 KPX Aring ucircumflex -50 KPX Aring udieresis -50 KPX Aring ugrave -50 KPX Aring uhungarumlaut -50 KPX Aring umacron -50 KPX Aring uogonek -50 KPX Aring uring -50 KPX Aring v -100 KPX Aring w -90 KPX Aring y -74 KPX Aring yacute -74 KPX Aring ydieresis -74 KPX Atilde C -55 KPX Atilde Cacute -55 KPX Atilde Ccaron -55 KPX Atilde Ccedilla -55 KPX Atilde G -55 KPX Atilde Gbreve -55 KPX Atilde Gcommaaccent -55 KPX Atilde O -45 KPX Atilde Oacute -45 KPX Atilde Ocircumflex -45 KPX Atilde Odieresis -45 KPX Atilde Ograve -45 KPX Atilde Ohungarumlaut -45 KPX Atilde Omacron -45 KPX Atilde Oslash -45 KPX Atilde Otilde -45 KPX Atilde Q -45 KPX Atilde T -95 KPX Atilde Tcaron -95 KPX Atilde Tcommaaccent -95 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -145 KPX Atilde W -130 KPX Atilde Y -100 KPX Atilde Yacute -100 KPX Atilde Ydieresis -100 KPX Atilde p -25 KPX Atilde quoteright -74 KPX Atilde u -50 KPX Atilde uacute -50 KPX Atilde ucircumflex -50 KPX Atilde udieresis -50 KPX Atilde ugrave -50 KPX Atilde uhungarumlaut -50 KPX Atilde umacron -50 KPX Atilde uogonek -50 KPX Atilde uring -50 KPX Atilde v -100 KPX Atilde w -90 KPX Atilde y -74 KPX Atilde yacute -74 KPX Atilde ydieresis -74 KPX B A -30 KPX B Aacute -30 KPX B Abreve -30 KPX B Acircumflex -30 KPX B Adieresis -30 KPX B Agrave -30 KPX B Amacron -30 KPX B Aogonek -30 KPX B Aring -30 KPX B Atilde -30 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -35 KPX D Aacute -35 KPX D Abreve -35 KPX D Acircumflex -35 KPX D Adieresis -35 KPX D Agrave -35 KPX D Amacron -35 KPX D Aogonek -35 KPX D Aring -35 KPX D Atilde -35 KPX D V -40 KPX D W -40 KPX D Y -40 KPX D Yacute -40 KPX D Ydieresis -40 KPX D period -20 KPX Dcaron A -35 KPX Dcaron Aacute -35 KPX Dcaron Abreve -35 KPX Dcaron Acircumflex -35 KPX Dcaron Adieresis -35 KPX Dcaron Agrave -35 KPX Dcaron Amacron -35 KPX Dcaron Aogonek -35 KPX Dcaron Aring -35 KPX Dcaron Atilde -35 KPX Dcaron V -40 KPX Dcaron W -40 KPX Dcaron Y -40 KPX Dcaron Yacute -40 KPX Dcaron Ydieresis -40 KPX Dcaron period -20 KPX Dcroat A -35 KPX Dcroat Aacute -35 KPX Dcroat Abreve -35 KPX Dcroat Acircumflex -35 KPX Dcroat Adieresis -35 KPX Dcroat Agrave -35 KPX Dcroat Amacron -35 KPX Dcroat Aogonek -35 KPX Dcroat Aring -35 KPX Dcroat Atilde -35 KPX Dcroat V -40 KPX Dcroat W -40 KPX Dcroat Y -40 KPX Dcroat Yacute -40 KPX Dcroat Ydieresis -40 KPX Dcroat period -20 KPX F A -90 KPX F Aacute -90 KPX F Abreve -90 KPX F Acircumflex -90 KPX F Adieresis -90 KPX F Agrave -90 KPX F Amacron -90 KPX F Aogonek -90 KPX F Aring -90 KPX F Atilde -90 KPX F a -25 KPX F aacute -25 KPX F abreve -25 KPX F acircumflex -25 KPX F adieresis -25 KPX F agrave -25 KPX F amacron -25 KPX F aogonek -25 KPX F aring -25 KPX F atilde -25 KPX F comma -92 KPX F e -25 KPX F eacute -25 KPX F ecaron -25 KPX F ecircumflex -25 KPX F edieresis -25 KPX F edotaccent -25 KPX F egrave -25 KPX F emacron -25 KPX F eogonek -25 KPX F o -25 KPX F oacute -25 KPX F ocircumflex -25 KPX F odieresis -25 KPX F ograve -25 KPX F ohungarumlaut -25 KPX F omacron -25 KPX F oslash -25 KPX F otilde -25 KPX F period -110 KPX J A -30 KPX J Aacute -30 KPX J Abreve -30 KPX J Acircumflex -30 KPX J Adieresis -30 KPX J Agrave -30 KPX J Amacron -30 KPX J Aogonek -30 KPX J Aring -30 KPX J Atilde -30 KPX J a -15 KPX J aacute -15 KPX J abreve -15 KPX J acircumflex -15 KPX J adieresis -15 KPX J agrave -15 KPX J amacron -15 KPX J aogonek -15 KPX J aring -15 KPX J atilde -15 KPX J e -15 KPX J eacute -15 KPX J ecaron -15 KPX J ecircumflex -15 KPX J edieresis -15 KPX J edotaccent -15 KPX J egrave -15 KPX J emacron -15 KPX J eogonek -15 KPX J o -15 KPX J oacute -15 KPX J ocircumflex -15 KPX J odieresis -15 KPX J ograve -15 KPX J ohungarumlaut -15 KPX J omacron -15 KPX J oslash -15 KPX J otilde -15 KPX J period -20 KPX J u -15 KPX J uacute -15 KPX J ucircumflex -15 KPX J udieresis -15 KPX J ugrave -15 KPX J uhungarumlaut -15 KPX J umacron -15 KPX J uogonek -15 KPX J uring -15 KPX K O -30 KPX K Oacute -30 KPX K Ocircumflex -30 KPX K Odieresis -30 KPX K Ograve -30 KPX K Ohungarumlaut -30 KPX K Omacron -30 KPX K Oslash -30 KPX K Otilde -30 KPX K e -25 KPX K eacute -25 KPX K ecaron -25 KPX K ecircumflex -25 KPX K edieresis -25 KPX K edotaccent -25 KPX K egrave -25 KPX K emacron -25 KPX K eogonek -25 KPX K o -25 KPX K oacute -25 KPX K ocircumflex -25 KPX K odieresis -25 KPX K ograve -25 KPX K ohungarumlaut -25 KPX K omacron -25 KPX K oslash -25 KPX K otilde -25 KPX K u -15 KPX K uacute -15 KPX K ucircumflex -15 KPX K udieresis -15 KPX K ugrave -15 KPX K uhungarumlaut -15 KPX K umacron -15 KPX K uogonek -15 KPX K uring -15 KPX K y -45 KPX K yacute -45 KPX K ydieresis -45 KPX Kcommaaccent O -30 KPX Kcommaaccent Oacute -30 KPX Kcommaaccent Ocircumflex -30 KPX Kcommaaccent Odieresis -30 KPX Kcommaaccent Ograve -30 KPX Kcommaaccent Ohungarumlaut -30 KPX Kcommaaccent Omacron -30 KPX Kcommaaccent Oslash -30 KPX Kcommaaccent Otilde -30 KPX Kcommaaccent e -25 KPX Kcommaaccent eacute -25 KPX Kcommaaccent ecaron -25 KPX Kcommaaccent ecircumflex -25 KPX Kcommaaccent edieresis -25 KPX Kcommaaccent edotaccent -25 KPX Kcommaaccent egrave -25 KPX Kcommaaccent emacron -25 KPX Kcommaaccent eogonek -25 KPX Kcommaaccent o -25 KPX Kcommaaccent oacute -25 KPX Kcommaaccent ocircumflex -25 KPX Kcommaaccent odieresis -25 KPX Kcommaaccent ograve -25 KPX Kcommaaccent ohungarumlaut -25 KPX Kcommaaccent omacron -25 KPX Kcommaaccent oslash -25 KPX Kcommaaccent otilde -25 KPX Kcommaaccent u -15 KPX Kcommaaccent uacute -15 KPX Kcommaaccent ucircumflex -15 KPX Kcommaaccent udieresis -15 KPX Kcommaaccent ugrave -15 KPX Kcommaaccent uhungarumlaut -15 KPX Kcommaaccent umacron -15 KPX Kcommaaccent uogonek -15 KPX Kcommaaccent uring -15 KPX Kcommaaccent y -45 KPX Kcommaaccent yacute -45 KPX Kcommaaccent ydieresis -45 KPX L T -92 KPX L Tcaron -92 KPX L Tcommaaccent -92 KPX L V -92 KPX L W -92 KPX L Y -92 KPX L Yacute -92 KPX L Ydieresis -92 KPX L quotedblright -20 KPX L quoteright -110 KPX L y -55 KPX L yacute -55 KPX L ydieresis -55 KPX Lacute T -92 KPX Lacute Tcaron -92 KPX Lacute Tcommaaccent -92 KPX Lacute V -92 KPX Lacute W -92 KPX Lacute Y -92 KPX Lacute Yacute -92 KPX Lacute Ydieresis -92 KPX Lacute quotedblright -20 KPX Lacute quoteright -110 KPX Lacute y -55 KPX Lacute yacute -55 KPX Lacute ydieresis -55 KPX Lcommaaccent T -92 KPX Lcommaaccent Tcaron -92 KPX Lcommaaccent Tcommaaccent -92 KPX Lcommaaccent V -92 KPX Lcommaaccent W -92 KPX Lcommaaccent Y -92 KPX Lcommaaccent Yacute -92 KPX Lcommaaccent Ydieresis -92 KPX Lcommaaccent quotedblright -20 KPX Lcommaaccent quoteright -110 KPX Lcommaaccent y -55 KPX Lcommaaccent yacute -55 KPX Lcommaaccent ydieresis -55 KPX Lslash T -92 KPX Lslash Tcaron -92 KPX Lslash Tcommaaccent -92 KPX Lslash V -92 KPX Lslash W -92 KPX Lslash Y -92 KPX Lslash Yacute -92 KPX Lslash Ydieresis -92 KPX Lslash quotedblright -20 KPX Lslash quoteright -110 KPX Lslash y -55 KPX Lslash yacute -55 KPX Lslash ydieresis -55 KPX N A -20 KPX N Aacute -20 KPX N Abreve -20 KPX N Acircumflex -20 KPX N Adieresis -20 KPX N Agrave -20 KPX N Amacron -20 KPX N Aogonek -20 KPX N Aring -20 KPX N Atilde -20 KPX Nacute A -20 KPX Nacute Aacute -20 KPX Nacute Abreve -20 KPX Nacute Acircumflex -20 KPX Nacute Adieresis -20 KPX Nacute Agrave -20 KPX Nacute Amacron -20 KPX Nacute Aogonek -20 KPX Nacute Aring -20 KPX Nacute Atilde -20 KPX Ncaron A -20 KPX Ncaron Aacute -20 KPX Ncaron Abreve -20 KPX Ncaron Acircumflex -20 KPX Ncaron Adieresis -20 KPX Ncaron Agrave -20 KPX Ncaron Amacron -20 KPX Ncaron Aogonek -20 KPX Ncaron Aring -20 KPX Ncaron Atilde -20 KPX Ncommaaccent A -20 KPX Ncommaaccent Aacute -20 KPX Ncommaaccent Abreve -20 KPX Ncommaaccent Acircumflex -20 KPX Ncommaaccent Adieresis -20 KPX Ncommaaccent Agrave -20 KPX Ncommaaccent Amacron -20 KPX Ncommaaccent Aogonek -20 KPX Ncommaaccent Aring -20 KPX Ncommaaccent Atilde -20 KPX Ntilde A -20 KPX Ntilde Aacute -20 KPX Ntilde Abreve -20 KPX Ntilde Acircumflex -20 KPX Ntilde Adieresis -20 KPX Ntilde Agrave -20 KPX Ntilde Amacron -20 KPX Ntilde Aogonek -20 KPX Ntilde Aring -20 KPX Ntilde Atilde -20 KPX O A -40 KPX O Aacute -40 KPX O Abreve -40 KPX O Acircumflex -40 KPX O Adieresis -40 KPX O Agrave -40 KPX O Amacron -40 KPX O Aogonek -40 KPX O Aring -40 KPX O Atilde -40 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -50 KPX O X -40 KPX O Y -50 KPX O Yacute -50 KPX O Ydieresis -50 KPX Oacute A -40 KPX Oacute Aacute -40 KPX Oacute Abreve -40 KPX Oacute Acircumflex -40 KPX Oacute Adieresis -40 KPX Oacute Agrave -40 KPX Oacute Amacron -40 KPX Oacute Aogonek -40 KPX Oacute Aring -40 KPX Oacute Atilde -40 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -50 KPX Oacute X -40 KPX Oacute Y -50 KPX Oacute Yacute -50 KPX Oacute Ydieresis -50 KPX Ocircumflex A -40 KPX Ocircumflex Aacute -40 KPX Ocircumflex Abreve -40 KPX Ocircumflex Acircumflex -40 KPX Ocircumflex Adieresis -40 KPX Ocircumflex Agrave -40 KPX Ocircumflex Amacron -40 KPX Ocircumflex Aogonek -40 KPX Ocircumflex Aring -40 KPX Ocircumflex Atilde -40 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -50 KPX Ocircumflex X -40 KPX Ocircumflex Y -50 KPX Ocircumflex Yacute -50 KPX Ocircumflex Ydieresis -50 KPX Odieresis A -40 KPX Odieresis Aacute -40 KPX Odieresis Abreve -40 KPX Odieresis Acircumflex -40 KPX Odieresis Adieresis -40 KPX Odieresis Agrave -40 KPX Odieresis Amacron -40 KPX Odieresis Aogonek -40 KPX Odieresis Aring -40 KPX Odieresis Atilde -40 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -50 KPX Odieresis X -40 KPX Odieresis Y -50 KPX Odieresis Yacute -50 KPX Odieresis Ydieresis -50 KPX Ograve A -40 KPX Ograve Aacute -40 KPX Ograve Abreve -40 KPX Ograve Acircumflex -40 KPX Ograve Adieresis -40 KPX Ograve Agrave -40 KPX Ograve Amacron -40 KPX Ograve Aogonek -40 KPX Ograve Aring -40 KPX Ograve Atilde -40 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -50 KPX Ograve X -40 KPX Ograve Y -50 KPX Ograve Yacute -50 KPX Ograve Ydieresis -50 KPX Ohungarumlaut A -40 KPX Ohungarumlaut Aacute -40 KPX Ohungarumlaut Abreve -40 KPX Ohungarumlaut Acircumflex -40 KPX Ohungarumlaut Adieresis -40 KPX Ohungarumlaut Agrave -40 KPX Ohungarumlaut Amacron -40 KPX Ohungarumlaut Aogonek -40 KPX Ohungarumlaut Aring -40 KPX Ohungarumlaut Atilde -40 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -50 KPX Ohungarumlaut X -40 KPX Ohungarumlaut Y -50 KPX Ohungarumlaut Yacute -50 KPX Ohungarumlaut Ydieresis -50 KPX Omacron A -40 KPX Omacron Aacute -40 KPX Omacron Abreve -40 KPX Omacron Acircumflex -40 KPX Omacron Adieresis -40 KPX Omacron Agrave -40 KPX Omacron Amacron -40 KPX Omacron Aogonek -40 KPX Omacron Aring -40 KPX Omacron Atilde -40 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -50 KPX Omacron X -40 KPX Omacron Y -50 KPX Omacron Yacute -50 KPX Omacron Ydieresis -50 KPX Oslash A -40 KPX Oslash Aacute -40 KPX Oslash Abreve -40 KPX Oslash Acircumflex -40 KPX Oslash Adieresis -40 KPX Oslash Agrave -40 KPX Oslash Amacron -40 KPX Oslash Aogonek -40 KPX Oslash Aring -40 KPX Oslash Atilde -40 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -50 KPX Oslash X -40 KPX Oslash Y -50 KPX Oslash Yacute -50 KPX Oslash Ydieresis -50 KPX Otilde A -40 KPX Otilde Aacute -40 KPX Otilde Abreve -40 KPX Otilde Acircumflex -40 KPX Otilde Adieresis -40 KPX Otilde Agrave -40 KPX Otilde Amacron -40 KPX Otilde Aogonek -40 KPX Otilde Aring -40 KPX Otilde Atilde -40 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -50 KPX Otilde X -40 KPX Otilde Y -50 KPX Otilde Yacute -50 KPX Otilde Ydieresis -50 KPX P A -74 KPX P Aacute -74 KPX P Abreve -74 KPX P Acircumflex -74 KPX P Adieresis -74 KPX P Agrave -74 KPX P Amacron -74 KPX P Aogonek -74 KPX P Aring -74 KPX P Atilde -74 KPX P a -10 KPX P aacute -10 KPX P abreve -10 KPX P acircumflex -10 KPX P adieresis -10 KPX P agrave -10 KPX P amacron -10 KPX P aogonek -10 KPX P aring -10 KPX P atilde -10 KPX P comma -92 KPX P e -20 KPX P eacute -20 KPX P ecaron -20 KPX P ecircumflex -20 KPX P edieresis -20 KPX P edotaccent -20 KPX P egrave -20 KPX P emacron -20 KPX P eogonek -20 KPX P o -20 KPX P oacute -20 KPX P ocircumflex -20 KPX P odieresis -20 KPX P ograve -20 KPX P ohungarumlaut -20 KPX P omacron -20 KPX P oslash -20 KPX P otilde -20 KPX P period -110 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX Q period -20 KPX R O -30 KPX R Oacute -30 KPX R Ocircumflex -30 KPX R Odieresis -30 KPX R Ograve -30 KPX R Ohungarumlaut -30 KPX R Omacron -30 KPX R Oslash -30 KPX R Otilde -30 KPX R T -40 KPX R Tcaron -40 KPX R Tcommaaccent -40 KPX R U -30 KPX R Uacute -30 KPX R Ucircumflex -30 KPX R Udieresis -30 KPX R Ugrave -30 KPX R Uhungarumlaut -30 KPX R Umacron -30 KPX R Uogonek -30 KPX R Uring -30 KPX R V -55 KPX R W -35 KPX R Y -35 KPX R Yacute -35 KPX R Ydieresis -35 KPX Racute O -30 KPX Racute Oacute -30 KPX Racute Ocircumflex -30 KPX Racute Odieresis -30 KPX Racute Ograve -30 KPX Racute Ohungarumlaut -30 KPX Racute Omacron -30 KPX Racute Oslash -30 KPX Racute Otilde -30 KPX Racute T -40 KPX Racute Tcaron -40 KPX Racute Tcommaaccent -40 KPX Racute U -30 KPX Racute Uacute -30 KPX Racute Ucircumflex -30 KPX Racute Udieresis -30 KPX Racute Ugrave -30 KPX Racute Uhungarumlaut -30 KPX Racute Umacron -30 KPX Racute Uogonek -30 KPX Racute Uring -30 KPX Racute V -55 KPX Racute W -35 KPX Racute Y -35 KPX Racute Yacute -35 KPX Racute Ydieresis -35 KPX Rcaron O -30 KPX Rcaron Oacute -30 KPX Rcaron Ocircumflex -30 KPX Rcaron Odieresis -30 KPX Rcaron Ograve -30 KPX Rcaron Ohungarumlaut -30 KPX Rcaron Omacron -30 KPX Rcaron Oslash -30 KPX Rcaron Otilde -30 KPX Rcaron T -40 KPX Rcaron Tcaron -40 KPX Rcaron Tcommaaccent -40 KPX Rcaron U -30 KPX Rcaron Uacute -30 KPX Rcaron Ucircumflex -30 KPX Rcaron Udieresis -30 KPX Rcaron Ugrave -30 KPX Rcaron Uhungarumlaut -30 KPX Rcaron Umacron -30 KPX Rcaron Uogonek -30 KPX Rcaron Uring -30 KPX Rcaron V -55 KPX Rcaron W -35 KPX Rcaron Y -35 KPX Rcaron Yacute -35 KPX Rcaron Ydieresis -35 KPX Rcommaaccent O -30 KPX Rcommaaccent Oacute -30 KPX Rcommaaccent Ocircumflex -30 KPX Rcommaaccent Odieresis -30 KPX Rcommaaccent Ograve -30 KPX Rcommaaccent Ohungarumlaut -30 KPX Rcommaaccent Omacron -30 KPX Rcommaaccent Oslash -30 KPX Rcommaaccent Otilde -30 KPX Rcommaaccent T -40 KPX Rcommaaccent Tcaron -40 KPX Rcommaaccent Tcommaaccent -40 KPX Rcommaaccent U -30 KPX Rcommaaccent Uacute -30 KPX Rcommaaccent Ucircumflex -30 KPX Rcommaaccent Udieresis -30 KPX Rcommaaccent Ugrave -30 KPX Rcommaaccent Uhungarumlaut -30 KPX Rcommaaccent Umacron -30 KPX Rcommaaccent Uogonek -30 KPX Rcommaaccent Uring -30 KPX Rcommaaccent V -55 KPX Rcommaaccent W -35 KPX Rcommaaccent Y -35 KPX Rcommaaccent Yacute -35 KPX Rcommaaccent Ydieresis -35 KPX T A -90 KPX T Aacute -90 KPX T Abreve -90 KPX T Acircumflex -90 KPX T Adieresis -90 KPX T Agrave -90 KPX T Amacron -90 KPX T Aogonek -90 KPX T Aring -90 KPX T Atilde -90 KPX T O -18 KPX T Oacute -18 KPX T Ocircumflex -18 KPX T Odieresis -18 KPX T Ograve -18 KPX T Ohungarumlaut -18 KPX T Omacron -18 KPX T Oslash -18 KPX T Otilde -18 KPX T a -92 KPX T aacute -92 KPX T abreve -52 KPX T acircumflex -52 KPX T adieresis -52 KPX T agrave -52 KPX T amacron -52 KPX T aogonek -92 KPX T aring -92 KPX T atilde -52 KPX T colon -74 KPX T comma -74 KPX T e -92 KPX T eacute -92 KPX T ecaron -92 KPX T ecircumflex -92 KPX T edieresis -52 KPX T edotaccent -92 KPX T egrave -52 KPX T emacron -52 KPX T eogonek -92 KPX T hyphen -92 KPX T i -18 KPX T iacute -18 KPX T iogonek -18 KPX T o -92 KPX T oacute -92 KPX T ocircumflex -92 KPX T odieresis -92 KPX T ograve -92 KPX T ohungarumlaut -92 KPX T omacron -92 KPX T oslash -92 KPX T otilde -92 KPX T period -90 KPX T r -74 KPX T racute -74 KPX T rcaron -74 KPX T rcommaaccent -74 KPX T semicolon -74 KPX T u -92 KPX T uacute -92 KPX T ucircumflex -92 KPX T udieresis -92 KPX T ugrave -92 KPX T uhungarumlaut -92 KPX T umacron -92 KPX T uogonek -92 KPX T uring -92 KPX T w -74 KPX T y -34 KPX T yacute -34 KPX T ydieresis -34 KPX Tcaron A -90 KPX Tcaron Aacute -90 KPX Tcaron Abreve -90 KPX Tcaron Acircumflex -90 KPX Tcaron Adieresis -90 KPX Tcaron Agrave -90 KPX Tcaron Amacron -90 KPX Tcaron Aogonek -90 KPX Tcaron Aring -90 KPX Tcaron Atilde -90 KPX Tcaron O -18 KPX Tcaron Oacute -18 KPX Tcaron Ocircumflex -18 KPX Tcaron Odieresis -18 KPX Tcaron Ograve -18 KPX Tcaron Ohungarumlaut -18 KPX Tcaron Omacron -18 KPX Tcaron Oslash -18 KPX Tcaron Otilde -18 KPX Tcaron a -92 KPX Tcaron aacute -92 KPX Tcaron abreve -52 KPX Tcaron acircumflex -52 KPX Tcaron adieresis -52 KPX Tcaron agrave -52 KPX Tcaron amacron -52 KPX Tcaron aogonek -92 KPX Tcaron aring -92 KPX Tcaron atilde -52 KPX Tcaron colon -74 KPX Tcaron comma -74 KPX Tcaron e -92 KPX Tcaron eacute -92 KPX Tcaron ecaron -92 KPX Tcaron ecircumflex -92 KPX Tcaron edieresis -52 KPX Tcaron edotaccent -92 KPX Tcaron egrave -52 KPX Tcaron emacron -52 KPX Tcaron eogonek -92 KPX Tcaron hyphen -92 KPX Tcaron i -18 KPX Tcaron iacute -18 KPX Tcaron iogonek -18 KPX Tcaron o -92 KPX Tcaron oacute -92 KPX Tcaron ocircumflex -92 KPX Tcaron odieresis -92 KPX Tcaron ograve -92 KPX Tcaron ohungarumlaut -92 KPX Tcaron omacron -92 KPX Tcaron oslash -92 KPX Tcaron otilde -92 KPX Tcaron period -90 KPX Tcaron r -74 KPX Tcaron racute -74 KPX Tcaron rcaron -74 KPX Tcaron rcommaaccent -74 KPX Tcaron semicolon -74 KPX Tcaron u -92 KPX Tcaron uacute -92 KPX Tcaron ucircumflex -92 KPX Tcaron udieresis -92 KPX Tcaron ugrave -92 KPX Tcaron uhungarumlaut -92 KPX Tcaron umacron -92 KPX Tcaron uogonek -92 KPX Tcaron uring -92 KPX Tcaron w -74 KPX Tcaron y -34 KPX Tcaron yacute -34 KPX Tcaron ydieresis -34 KPX Tcommaaccent A -90 KPX Tcommaaccent Aacute -90 KPX Tcommaaccent Abreve -90 KPX Tcommaaccent Acircumflex -90 KPX Tcommaaccent Adieresis -90 KPX Tcommaaccent Agrave -90 KPX Tcommaaccent Amacron -90 KPX Tcommaaccent Aogonek -90 KPX Tcommaaccent Aring -90 KPX Tcommaaccent Atilde -90 KPX Tcommaaccent O -18 KPX Tcommaaccent Oacute -18 KPX Tcommaaccent Ocircumflex -18 KPX Tcommaaccent Odieresis -18 KPX Tcommaaccent Ograve -18 KPX Tcommaaccent Ohungarumlaut -18 KPX Tcommaaccent Omacron -18 KPX Tcommaaccent Oslash -18 KPX Tcommaaccent Otilde -18 KPX Tcommaaccent a -92 KPX Tcommaaccent aacute -92 KPX Tcommaaccent abreve -52 KPX Tcommaaccent acircumflex -52 KPX Tcommaaccent adieresis -52 KPX Tcommaaccent agrave -52 KPX Tcommaaccent amacron -52 KPX Tcommaaccent aogonek -92 KPX Tcommaaccent aring -92 KPX Tcommaaccent atilde -52 KPX Tcommaaccent colon -74 KPX Tcommaaccent comma -74 KPX Tcommaaccent e -92 KPX Tcommaaccent eacute -92 KPX Tcommaaccent ecaron -92 KPX Tcommaaccent ecircumflex -92 KPX Tcommaaccent edieresis -52 KPX Tcommaaccent edotaccent -92 KPX Tcommaaccent egrave -52 KPX Tcommaaccent emacron -52 KPX Tcommaaccent eogonek -92 KPX Tcommaaccent hyphen -92 KPX Tcommaaccent i -18 KPX Tcommaaccent iacute -18 KPX Tcommaaccent iogonek -18 KPX Tcommaaccent o -92 KPX Tcommaaccent oacute -92 KPX Tcommaaccent ocircumflex -92 KPX Tcommaaccent odieresis -92 KPX Tcommaaccent ograve -92 KPX Tcommaaccent ohungarumlaut -92 KPX Tcommaaccent omacron -92 KPX Tcommaaccent oslash -92 KPX Tcommaaccent otilde -92 KPX Tcommaaccent period -90 KPX Tcommaaccent r -74 KPX Tcommaaccent racute -74 KPX Tcommaaccent rcaron -74 KPX Tcommaaccent rcommaaccent -74 KPX Tcommaaccent semicolon -74 KPX Tcommaaccent u -92 KPX Tcommaaccent uacute -92 KPX Tcommaaccent ucircumflex -92 KPX Tcommaaccent udieresis -92 KPX Tcommaaccent ugrave -92 KPX Tcommaaccent uhungarumlaut -92 KPX Tcommaaccent umacron -92 KPX Tcommaaccent uogonek -92 KPX Tcommaaccent uring -92 KPX Tcommaaccent w -74 KPX Tcommaaccent y -34 KPX Tcommaaccent yacute -34 KPX Tcommaaccent ydieresis -34 KPX U A -60 KPX U Aacute -60 KPX U Abreve -60 KPX U Acircumflex -60 KPX U Adieresis -60 KPX U Agrave -60 KPX U Amacron -60 KPX U Aogonek -60 KPX U Aring -60 KPX U Atilde -60 KPX U comma -50 KPX U period -50 KPX Uacute A -60 KPX Uacute Aacute -60 KPX Uacute Abreve -60 KPX Uacute Acircumflex -60 KPX Uacute Adieresis -60 KPX Uacute Agrave -60 KPX Uacute Amacron -60 KPX Uacute Aogonek -60 KPX Uacute Aring -60 KPX Uacute Atilde -60 KPX Uacute comma -50 KPX Uacute period -50 KPX Ucircumflex A -60 KPX Ucircumflex Aacute -60 KPX Ucircumflex Abreve -60 KPX Ucircumflex Acircumflex -60 KPX Ucircumflex Adieresis -60 KPX Ucircumflex Agrave -60 KPX Ucircumflex Amacron -60 KPX Ucircumflex Aogonek -60 KPX Ucircumflex Aring -60 KPX Ucircumflex Atilde -60 KPX Ucircumflex comma -50 KPX Ucircumflex period -50 KPX Udieresis A -60 KPX Udieresis Aacute -60 KPX Udieresis Abreve -60 KPX Udieresis Acircumflex -60 KPX Udieresis Adieresis -60 KPX Udieresis Agrave -60 KPX Udieresis Amacron -60 KPX Udieresis Aogonek -60 KPX Udieresis Aring -60 KPX Udieresis Atilde -60 KPX Udieresis comma -50 KPX Udieresis period -50 KPX Ugrave A -60 KPX Ugrave Aacute -60 KPX Ugrave Abreve -60 KPX Ugrave Acircumflex -60 KPX Ugrave Adieresis -60 KPX Ugrave Agrave -60 KPX Ugrave Amacron -60 KPX Ugrave Aogonek -60 KPX Ugrave Aring -60 KPX Ugrave Atilde -60 KPX Ugrave comma -50 KPX Ugrave period -50 KPX Uhungarumlaut A -60 KPX Uhungarumlaut Aacute -60 KPX Uhungarumlaut Abreve -60 KPX Uhungarumlaut Acircumflex -60 KPX Uhungarumlaut Adieresis -60 KPX Uhungarumlaut Agrave -60 KPX Uhungarumlaut Amacron -60 KPX Uhungarumlaut Aogonek -60 KPX Uhungarumlaut Aring -60 KPX Uhungarumlaut Atilde -60 KPX Uhungarumlaut comma -50 KPX Uhungarumlaut period -50 KPX Umacron A -60 KPX Umacron Aacute -60 KPX Umacron Abreve -60 KPX Umacron Acircumflex -60 KPX Umacron Adieresis -60 KPX Umacron Agrave -60 KPX Umacron Amacron -60 KPX Umacron Aogonek -60 KPX Umacron Aring -60 KPX Umacron Atilde -60 KPX Umacron comma -50 KPX Umacron period -50 KPX Uogonek A -60 KPX Uogonek Aacute -60 KPX Uogonek Abreve -60 KPX Uogonek Acircumflex -60 KPX Uogonek Adieresis -60 KPX Uogonek Agrave -60 KPX Uogonek Amacron -60 KPX Uogonek Aogonek -60 KPX Uogonek Aring -60 KPX Uogonek Atilde -60 KPX Uogonek comma -50 KPX Uogonek period -50 KPX Uring A -60 KPX Uring Aacute -60 KPX Uring Abreve -60 KPX Uring Acircumflex -60 KPX Uring Adieresis -60 KPX Uring Agrave -60 KPX Uring Amacron -60 KPX Uring Aogonek -60 KPX Uring Aring -60 KPX Uring Atilde -60 KPX Uring comma -50 KPX Uring period -50 KPX V A -135 KPX V Aacute -135 KPX V Abreve -135 KPX V Acircumflex -135 KPX V Adieresis -135 KPX V Agrave -135 KPX V Amacron -135 KPX V Aogonek -135 KPX V Aring -135 KPX V Atilde -135 KPX V G -30 KPX V Gbreve -30 KPX V Gcommaaccent -30 KPX V O -45 KPX V Oacute -45 KPX V Ocircumflex -45 KPX V Odieresis -45 KPX V Ograve -45 KPX V Ohungarumlaut -45 KPX V Omacron -45 KPX V Oslash -45 KPX V Otilde -45 KPX V a -92 KPX V aacute -92 KPX V abreve -92 KPX V acircumflex -92 KPX V adieresis -92 KPX V agrave -92 KPX V amacron -92 KPX V aogonek -92 KPX V aring -92 KPX V atilde -92 KPX V colon -92 KPX V comma -129 KPX V e -100 KPX V eacute -100 KPX V ecaron -100 KPX V ecircumflex -100 KPX V edieresis -100 KPX V edotaccent -100 KPX V egrave -100 KPX V emacron -100 KPX V eogonek -100 KPX V hyphen -74 KPX V i -37 KPX V iacute -37 KPX V icircumflex -37 KPX V idieresis -37 KPX V igrave -37 KPX V imacron -37 KPX V iogonek -37 KPX V o -100 KPX V oacute -100 KPX V ocircumflex -100 KPX V odieresis -100 KPX V ograve -100 KPX V ohungarumlaut -100 KPX V omacron -100 KPX V oslash -100 KPX V otilde -100 KPX V period -145 KPX V semicolon -92 KPX V u -92 KPX V uacute -92 KPX V ucircumflex -92 KPX V udieresis -92 KPX V ugrave -92 KPX V uhungarumlaut -92 KPX V umacron -92 KPX V uogonek -92 KPX V uring -92 KPX W A -120 KPX W Aacute -120 KPX W Abreve -120 KPX W Acircumflex -120 KPX W Adieresis -120 KPX W Agrave -120 KPX W Amacron -120 KPX W Aogonek -120 KPX W Aring -120 KPX W Atilde -120 KPX W O -10 KPX W Oacute -10 KPX W Ocircumflex -10 KPX W Odieresis -10 KPX W Ograve -10 KPX W Ohungarumlaut -10 KPX W Omacron -10 KPX W Oslash -10 KPX W Otilde -10 KPX W a -65 KPX W aacute -65 KPX W abreve -65 KPX W acircumflex -65 KPX W adieresis -65 KPX W agrave -65 KPX W amacron -65 KPX W aogonek -65 KPX W aring -65 KPX W atilde -65 KPX W colon -55 KPX W comma -92 KPX W e -65 KPX W eacute -65 KPX W ecaron -65 KPX W ecircumflex -65 KPX W edieresis -65 KPX W edotaccent -65 KPX W egrave -65 KPX W emacron -65 KPX W eogonek -65 KPX W hyphen -37 KPX W i -18 KPX W iacute -18 KPX W iogonek -18 KPX W o -75 KPX W oacute -75 KPX W ocircumflex -75 KPX W odieresis -75 KPX W ograve -75 KPX W ohungarumlaut -75 KPX W omacron -75 KPX W oslash -75 KPX W otilde -75 KPX W period -92 KPX W semicolon -55 KPX W u -50 KPX W uacute -50 KPX W ucircumflex -50 KPX W udieresis -50 KPX W ugrave -50 KPX W uhungarumlaut -50 KPX W umacron -50 KPX W uogonek -50 KPX W uring -50 KPX W y -60 KPX W yacute -60 KPX W ydieresis -60 KPX Y A -110 KPX Y Aacute -110 KPX Y Abreve -110 KPX Y Acircumflex -110 KPX Y Adieresis -110 KPX Y Agrave -110 KPX Y Amacron -110 KPX Y Aogonek -110 KPX Y Aring -110 KPX Y Atilde -110 KPX Y O -35 KPX Y Oacute -35 KPX Y Ocircumflex -35 KPX Y Odieresis -35 KPX Y Ograve -35 KPX Y Ohungarumlaut -35 KPX Y Omacron -35 KPX Y Oslash -35 KPX Y Otilde -35 KPX Y a -85 KPX Y aacute -85 KPX Y abreve -85 KPX Y acircumflex -85 KPX Y adieresis -85 KPX Y agrave -85 KPX Y amacron -85 KPX Y aogonek -85 KPX Y aring -85 KPX Y atilde -85 KPX Y colon -92 KPX Y comma -92 KPX Y e -111 KPX Y eacute -111 KPX Y ecaron -111 KPX Y ecircumflex -111 KPX Y edieresis -71 KPX Y edotaccent -111 KPX Y egrave -71 KPX Y emacron -71 KPX Y eogonek -111 KPX Y hyphen -92 KPX Y i -37 KPX Y iacute -37 KPX Y iogonek -37 KPX Y o -111 KPX Y oacute -111 KPX Y ocircumflex -111 KPX Y odieresis -111 KPX Y ograve -111 KPX Y ohungarumlaut -111 KPX Y omacron -111 KPX Y oslash -111 KPX Y otilde -111 KPX Y period -92 KPX Y semicolon -92 KPX Y u -92 KPX Y uacute -92 KPX Y ucircumflex -92 KPX Y udieresis -92 KPX Y ugrave -92 KPX Y uhungarumlaut -92 KPX Y umacron -92 KPX Y uogonek -92 KPX Y uring -92 KPX Yacute A -110 KPX Yacute Aacute -110 KPX Yacute Abreve -110 KPX Yacute Acircumflex -110 KPX Yacute Adieresis -110 KPX Yacute Agrave -110 KPX Yacute Amacron -110 KPX Yacute Aogonek -110 KPX Yacute Aring -110 KPX Yacute Atilde -110 KPX Yacute O -35 KPX Yacute Oacute -35 KPX Yacute Ocircumflex -35 KPX Yacute Odieresis -35 KPX Yacute Ograve -35 KPX Yacute Ohungarumlaut -35 KPX Yacute Omacron -35 KPX Yacute Oslash -35 KPX Yacute Otilde -35 KPX Yacute a -85 KPX Yacute aacute -85 KPX Yacute abreve -85 KPX Yacute acircumflex -85 KPX Yacute adieresis -85 KPX Yacute agrave -85 KPX Yacute amacron -85 KPX Yacute aogonek -85 KPX Yacute aring -85 KPX Yacute atilde -85 KPX Yacute colon -92 KPX Yacute comma -92 KPX Yacute e -111 KPX Yacute eacute -111 KPX Yacute ecaron -111 KPX Yacute ecircumflex -111 KPX Yacute edieresis -71 KPX Yacute edotaccent -111 KPX Yacute egrave -71 KPX Yacute emacron -71 KPX Yacute eogonek -111 KPX Yacute hyphen -92 KPX Yacute i -37 KPX Yacute iacute -37 KPX Yacute iogonek -37 KPX Yacute o -111 KPX Yacute oacute -111 KPX Yacute ocircumflex -111 KPX Yacute odieresis -111 KPX Yacute ograve -111 KPX Yacute ohungarumlaut -111 KPX Yacute omacron -111 KPX Yacute oslash -111 KPX Yacute otilde -111 KPX Yacute period -92 KPX Yacute semicolon -92 KPX Yacute u -92 KPX Yacute uacute -92 KPX Yacute ucircumflex -92 KPX Yacute udieresis -92 KPX Yacute ugrave -92 KPX Yacute uhungarumlaut -92 KPX Yacute umacron -92 KPX Yacute uogonek -92 KPX Yacute uring -92 KPX Ydieresis A -110 KPX Ydieresis Aacute -110 KPX Ydieresis Abreve -110 KPX Ydieresis Acircumflex -110 KPX Ydieresis Adieresis -110 KPX Ydieresis Agrave -110 KPX Ydieresis Amacron -110 KPX Ydieresis Aogonek -110 KPX Ydieresis Aring -110 KPX Ydieresis Atilde -110 KPX Ydieresis O -35 KPX Ydieresis Oacute -35 KPX Ydieresis Ocircumflex -35 KPX Ydieresis Odieresis -35 KPX Ydieresis Ograve -35 KPX Ydieresis Ohungarumlaut -35 KPX Ydieresis Omacron -35 KPX Ydieresis Oslash -35 KPX Ydieresis Otilde -35 KPX Ydieresis a -85 KPX Ydieresis aacute -85 KPX Ydieresis abreve -85 KPX Ydieresis acircumflex -85 KPX Ydieresis adieresis -85 KPX Ydieresis agrave -85 KPX Ydieresis amacron -85 KPX Ydieresis aogonek -85 KPX Ydieresis aring -85 KPX Ydieresis atilde -85 KPX Ydieresis colon -92 KPX Ydieresis comma -92 KPX Ydieresis e -111 KPX Ydieresis eacute -111 KPX Ydieresis ecaron -111 KPX Ydieresis ecircumflex -111 KPX Ydieresis edieresis -71 KPX Ydieresis edotaccent -111 KPX Ydieresis egrave -71 KPX Ydieresis emacron -71 KPX Ydieresis eogonek -111 KPX Ydieresis hyphen -92 KPX Ydieresis i -37 KPX Ydieresis iacute -37 KPX Ydieresis iogonek -37 KPX Ydieresis o -111 KPX Ydieresis oacute -111 KPX Ydieresis ocircumflex -111 KPX Ydieresis odieresis -111 KPX Ydieresis ograve -111 KPX Ydieresis ohungarumlaut -111 KPX Ydieresis omacron -111 KPX Ydieresis oslash -111 KPX Ydieresis otilde -111 KPX Ydieresis period -92 KPX Ydieresis semicolon -92 KPX Ydieresis u -92 KPX Ydieresis uacute -92 KPX Ydieresis ucircumflex -92 KPX Ydieresis udieresis -92 KPX Ydieresis ugrave -92 KPX Ydieresis uhungarumlaut -92 KPX Ydieresis umacron -92 KPX Ydieresis uogonek -92 KPX Ydieresis uring -92 KPX a v -25 KPX aacute v -25 KPX abreve v -25 KPX acircumflex v -25 KPX adieresis v -25 KPX agrave v -25 KPX amacron v -25 KPX aogonek v -25 KPX aring v -25 KPX atilde v -25 KPX b b -10 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -15 KPX comma quotedblright -45 KPX comma quoteright -55 KPX d w -15 KPX dcroat w -15 KPX e v -15 KPX eacute v -15 KPX ecaron v -15 KPX ecircumflex v -15 KPX edieresis v -15 KPX edotaccent v -15 KPX egrave v -15 KPX emacron v -15 KPX eogonek v -15 KPX f comma -15 KPX f dotlessi -35 KPX f i -25 KPX f o -25 KPX f oacute -25 KPX f ocircumflex -25 KPX f odieresis -25 KPX f ograve -25 KPX f ohungarumlaut -25 KPX f omacron -25 KPX f oslash -25 KPX f otilde -25 KPX f period -15 KPX f quotedblright 50 KPX f quoteright 55 KPX g period -15 KPX gbreve period -15 KPX gcommaaccent period -15 KPX h y -15 KPX h yacute -15 KPX h ydieresis -15 KPX i v -10 KPX iacute v -10 KPX icircumflex v -10 KPX idieresis v -10 KPX igrave v -10 KPX imacron v -10 KPX iogonek v -10 KPX k e -10 KPX k eacute -10 KPX k ecaron -10 KPX k ecircumflex -10 KPX k edieresis -10 KPX k edotaccent -10 KPX k egrave -10 KPX k emacron -10 KPX k eogonek -10 KPX k o -15 KPX k oacute -15 KPX k ocircumflex -15 KPX k odieresis -15 KPX k ograve -15 KPX k ohungarumlaut -15 KPX k omacron -15 KPX k oslash -15 KPX k otilde -15 KPX k y -15 KPX k yacute -15 KPX k ydieresis -15 KPX kcommaaccent e -10 KPX kcommaaccent eacute -10 KPX kcommaaccent ecaron -10 KPX kcommaaccent ecircumflex -10 KPX kcommaaccent edieresis -10 KPX kcommaaccent edotaccent -10 KPX kcommaaccent egrave -10 KPX kcommaaccent emacron -10 KPX kcommaaccent eogonek -10 KPX kcommaaccent o -15 KPX kcommaaccent oacute -15 KPX kcommaaccent ocircumflex -15 KPX kcommaaccent odieresis -15 KPX kcommaaccent ograve -15 KPX kcommaaccent ohungarumlaut -15 KPX kcommaaccent omacron -15 KPX kcommaaccent oslash -15 KPX kcommaaccent otilde -15 KPX kcommaaccent y -15 KPX kcommaaccent yacute -15 KPX kcommaaccent ydieresis -15 KPX n v -40 KPX nacute v -40 KPX ncaron v -40 KPX ncommaaccent v -40 KPX ntilde v -40 KPX o v -10 KPX o w -10 KPX oacute v -10 KPX oacute w -10 KPX ocircumflex v -10 KPX ocircumflex w -10 KPX odieresis v -10 KPX odieresis w -10 KPX ograve v -10 KPX ograve w -10 KPX ohungarumlaut v -10 KPX ohungarumlaut w -10 KPX omacron v -10 KPX omacron w -10 KPX oslash v -10 KPX oslash w -10 KPX otilde v -10 KPX otilde w -10 KPX period quotedblright -55 KPX period quoteright -55 KPX quotedblleft A -10 KPX quotedblleft Aacute -10 KPX quotedblleft Abreve -10 KPX quotedblleft Acircumflex -10 KPX quotedblleft Adieresis -10 KPX quotedblleft Agrave -10 KPX quotedblleft Amacron -10 KPX quotedblleft Aogonek -10 KPX quotedblleft Aring -10 KPX quotedblleft Atilde -10 KPX quoteleft A -10 KPX quoteleft Aacute -10 KPX quoteleft Abreve -10 KPX quoteleft Acircumflex -10 KPX quoteleft Adieresis -10 KPX quoteleft Agrave -10 KPX quoteleft Amacron -10 KPX quoteleft Aogonek -10 KPX quoteleft Aring -10 KPX quoteleft Atilde -10 KPX quoteleft quoteleft -63 KPX quoteright d -20 KPX quoteright dcroat -20 KPX quoteright quoteright -63 KPX quoteright r -20 KPX quoteright racute -20 KPX quoteright rcaron -20 KPX quoteright rcommaaccent -20 KPX quoteright s -37 KPX quoteright sacute -37 KPX quoteright scaron -37 KPX quoteright scedilla -37 KPX quoteright scommaaccent -37 KPX quoteright space -74 KPX quoteright v -20 KPX r c -18 KPX r cacute -18 KPX r ccaron -18 KPX r ccedilla -18 KPX r comma -92 KPX r e -18 KPX r eacute -18 KPX r ecaron -18 KPX r ecircumflex -18 KPX r edieresis -18 KPX r edotaccent -18 KPX r egrave -18 KPX r emacron -18 KPX r eogonek -18 KPX r g -10 KPX r gbreve -10 KPX r gcommaaccent -10 KPX r hyphen -37 KPX r n -15 KPX r nacute -15 KPX r ncaron -15 KPX r ncommaaccent -15 KPX r ntilde -15 KPX r o -18 KPX r oacute -18 KPX r ocircumflex -18 KPX r odieresis -18 KPX r ograve -18 KPX r ohungarumlaut -18 KPX r omacron -18 KPX r oslash -18 KPX r otilde -18 KPX r p -10 KPX r period -100 KPX r q -18 KPX r v -10 KPX racute c -18 KPX racute cacute -18 KPX racute ccaron -18 KPX racute ccedilla -18 KPX racute comma -92 KPX racute e -18 KPX racute eacute -18 KPX racute ecaron -18 KPX racute ecircumflex -18 KPX racute edieresis -18 KPX racute edotaccent -18 KPX racute egrave -18 KPX racute emacron -18 KPX racute eogonek -18 KPX racute g -10 KPX racute gbreve -10 KPX racute gcommaaccent -10 KPX racute hyphen -37 KPX racute n -15 KPX racute nacute -15 KPX racute ncaron -15 KPX racute ncommaaccent -15 KPX racute ntilde -15 KPX racute o -18 KPX racute oacute -18 KPX racute ocircumflex -18 KPX racute odieresis -18 KPX racute ograve -18 KPX racute ohungarumlaut -18 KPX racute omacron -18 KPX racute oslash -18 KPX racute otilde -18 KPX racute p -10 KPX racute period -100 KPX racute q -18 KPX racute v -10 KPX rcaron c -18 KPX rcaron cacute -18 KPX rcaron ccaron -18 KPX rcaron ccedilla -18 KPX rcaron comma -92 KPX rcaron e -18 KPX rcaron eacute -18 KPX rcaron ecaron -18 KPX rcaron ecircumflex -18 KPX rcaron edieresis -18 KPX rcaron edotaccent -18 KPX rcaron egrave -18 KPX rcaron emacron -18 KPX rcaron eogonek -18 KPX rcaron g -10 KPX rcaron gbreve -10 KPX rcaron gcommaaccent -10 KPX rcaron hyphen -37 KPX rcaron n -15 KPX rcaron nacute -15 KPX rcaron ncaron -15 KPX rcaron ncommaaccent -15 KPX rcaron ntilde -15 KPX rcaron o -18 KPX rcaron oacute -18 KPX rcaron ocircumflex -18 KPX rcaron odieresis -18 KPX rcaron ograve -18 KPX rcaron ohungarumlaut -18 KPX rcaron omacron -18 KPX rcaron oslash -18 KPX rcaron otilde -18 KPX rcaron p -10 KPX rcaron period -100 KPX rcaron q -18 KPX rcaron v -10 KPX rcommaaccent c -18 KPX rcommaaccent cacute -18 KPX rcommaaccent ccaron -18 KPX rcommaaccent ccedilla -18 KPX rcommaaccent comma -92 KPX rcommaaccent e -18 KPX rcommaaccent eacute -18 KPX rcommaaccent ecaron -18 KPX rcommaaccent ecircumflex -18 KPX rcommaaccent edieresis -18 KPX rcommaaccent edotaccent -18 KPX rcommaaccent egrave -18 KPX rcommaaccent emacron -18 KPX rcommaaccent eogonek -18 KPX rcommaaccent g -10 KPX rcommaaccent gbreve -10 KPX rcommaaccent gcommaaccent -10 KPX rcommaaccent hyphen -37 KPX rcommaaccent n -15 KPX rcommaaccent nacute -15 KPX rcommaaccent ncaron -15 KPX rcommaaccent ncommaaccent -15 KPX rcommaaccent ntilde -15 KPX rcommaaccent o -18 KPX rcommaaccent oacute -18 KPX rcommaaccent ocircumflex -18 KPX rcommaaccent odieresis -18 KPX rcommaaccent ograve -18 KPX rcommaaccent ohungarumlaut -18 KPX rcommaaccent omacron -18 KPX rcommaaccent oslash -18 KPX rcommaaccent otilde -18 KPX rcommaaccent p -10 KPX rcommaaccent period -100 KPX rcommaaccent q -18 KPX rcommaaccent v -10 KPX space A -55 KPX space Aacute -55 KPX space Abreve -55 KPX space Acircumflex -55 KPX space Adieresis -55 KPX space Agrave -55 KPX space Amacron -55 KPX space Aogonek -55 KPX space Aring -55 KPX space Atilde -55 KPX space T -30 KPX space Tcaron -30 KPX space Tcommaaccent -30 KPX space V -45 KPX space W -30 KPX space Y -55 KPX space Yacute -55 KPX space Ydieresis -55 KPX v a -10 KPX v aacute -10 KPX v abreve -10 KPX v acircumflex -10 KPX v adieresis -10 KPX v agrave -10 KPX v amacron -10 KPX v aogonek -10 KPX v aring -10 KPX v atilde -10 KPX v comma -55 KPX v e -10 KPX v eacute -10 KPX v ecaron -10 KPX v ecircumflex -10 KPX v edieresis -10 KPX v edotaccent -10 KPX v egrave -10 KPX v emacron -10 KPX v eogonek -10 KPX v o -10 KPX v oacute -10 KPX v ocircumflex -10 KPX v odieresis -10 KPX v ograve -10 KPX v ohungarumlaut -10 KPX v omacron -10 KPX v oslash -10 KPX v otilde -10 KPX v period -70 KPX w comma -55 KPX w o -10 KPX w oacute -10 KPX w ocircumflex -10 KPX w odieresis -10 KPX w ograve -10 KPX w ohungarumlaut -10 KPX w omacron -10 KPX w oslash -10 KPX w otilde -10 KPX w period -70 KPX y comma -55 KPX y e -10 KPX y eacute -10 KPX y ecaron -10 KPX y ecircumflex -10 KPX y edieresis -10 KPX y edotaccent -10 KPX y egrave -10 KPX y emacron -10 KPX y eogonek -10 KPX y o -25 KPX y oacute -25 KPX y ocircumflex -25 KPX y odieresis -25 KPX y ograve -25 KPX y ohungarumlaut -25 KPX y omacron -25 KPX y oslash -25 KPX y otilde -25 KPX y period -70 KPX yacute comma -55 KPX yacute e -10 KPX yacute eacute -10 KPX yacute ecaron -10 KPX yacute ecircumflex -10 KPX yacute edieresis -10 KPX yacute edotaccent -10 KPX yacute egrave -10 KPX yacute emacron -10 KPX yacute eogonek -10 KPX yacute o -25 KPX yacute oacute -25 KPX yacute ocircumflex -25 KPX yacute odieresis -25 KPX yacute ograve -25 KPX yacute ohungarumlaut -25 KPX yacute omacron -25 KPX yacute oslash -25 KPX yacute otilde -25 KPX yacute period -70 KPX ydieresis comma -55 KPX ydieresis e -10 KPX ydieresis eacute -10 KPX ydieresis ecaron -10 KPX ydieresis ecircumflex -10 KPX ydieresis edieresis -10 KPX ydieresis edotaccent -10 KPX ydieresis egrave -10 KPX ydieresis emacron -10 KPX ydieresis eogonek -10 KPX ydieresis o -25 KPX ydieresis oacute -25 KPX ydieresis ocircumflex -25 KPX ydieresis odieresis -25 KPX ydieresis ograve -25 KPX ydieresis ohungarumlaut -25 KPX ydieresis omacron -25 KPX ydieresis oslash -25 KPX ydieresis otilde -25 KPX ydieresis period -70 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Times-BoldItalic.afm100644 0 0 171112 11000354125 20623 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 13:04:06 1997 Comment UniqueID 43066 Comment VMusage 45874 56899 FontName Times-BoldItalic FullName Times Bold Italic FamilyName Times Weight Bold ItalicAngle -15 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -200 -218 996 921 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 669 XHeight 462 Ascender 683 Descender -217 StdHW 42 StdVW 121 StartCharMetrics 315 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ; C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ; C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ; C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ; C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ; C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ; C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ; C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ; C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ; C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ; C 43 ; WX 570 ; N plus ; B 33 0 537 506 ; C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ; C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ; C 46 ; WX 250 ; N period ; B -9 -13 139 135 ; C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ; C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ; C 49 ; WX 500 ; N one ; B 5 0 419 683 ; C 50 ; WX 500 ; N two ; B -27 0 446 683 ; C 51 ; WX 500 ; N three ; B -15 -13 450 683 ; C 52 ; WX 500 ; N four ; B -15 0 503 683 ; C 53 ; WX 500 ; N five ; B -11 -13 487 669 ; C 54 ; WX 500 ; N six ; B 23 -15 509 679 ; C 55 ; WX 500 ; N seven ; B 52 0 525 669 ; C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ; C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ; C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ; C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ; C 60 ; WX 570 ; N less ; B 31 -8 539 514 ; C 61 ; WX 570 ; N equal ; B 33 107 537 399 ; C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ; C 63 ; WX 500 ; N question ; B 79 -13 470 684 ; C 64 ; WX 832 ; N at ; B 63 -18 770 685 ; C 65 ; WX 667 ; N A ; B -67 0 593 683 ; C 66 ; WX 667 ; N B ; B -24 0 624 669 ; C 67 ; WX 667 ; N C ; B 32 -18 677 685 ; C 68 ; WX 722 ; N D ; B -46 0 685 669 ; C 69 ; WX 667 ; N E ; B -27 0 653 669 ; C 70 ; WX 667 ; N F ; B -13 0 660 669 ; C 71 ; WX 722 ; N G ; B 21 -18 706 685 ; C 72 ; WX 778 ; N H ; B -24 0 799 669 ; C 73 ; WX 389 ; N I ; B -32 0 406 669 ; C 74 ; WX 500 ; N J ; B -46 -99 524 669 ; C 75 ; WX 667 ; N K ; B -21 0 702 669 ; C 76 ; WX 611 ; N L ; B -22 0 590 669 ; C 77 ; WX 889 ; N M ; B -29 -12 917 669 ; C 78 ; WX 722 ; N N ; B -27 -15 748 669 ; C 79 ; WX 722 ; N O ; B 27 -18 691 685 ; C 80 ; WX 611 ; N P ; B -27 0 613 669 ; C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ; C 82 ; WX 667 ; N R ; B -29 0 623 669 ; C 83 ; WX 556 ; N S ; B 2 -18 526 685 ; C 84 ; WX 611 ; N T ; B 50 0 650 669 ; C 85 ; WX 722 ; N U ; B 67 -18 744 669 ; C 86 ; WX 667 ; N V ; B 65 -18 715 669 ; C 87 ; WX 889 ; N W ; B 65 -18 940 669 ; C 88 ; WX 667 ; N X ; B -24 0 694 669 ; C 89 ; WX 611 ; N Y ; B 73 0 659 669 ; C 90 ; WX 611 ; N Z ; B -11 0 590 669 ; C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ; C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ; C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ; C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ; C 97 ; WX 500 ; N a ; B -21 -14 455 462 ; C 98 ; WX 500 ; N b ; B -14 -13 444 699 ; C 99 ; WX 444 ; N c ; B -5 -13 392 462 ; C 100 ; WX 500 ; N d ; B -21 -13 517 699 ; C 101 ; WX 444 ; N e ; B 5 -13 398 462 ; C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B -52 -203 478 462 ; C 104 ; WX 556 ; N h ; B -13 -9 498 699 ; C 105 ; WX 278 ; N i ; B 2 -9 263 684 ; C 106 ; WX 278 ; N j ; B -189 -207 279 684 ; C 107 ; WX 500 ; N k ; B -23 -8 483 699 ; C 108 ; WX 278 ; N l ; B 2 -9 290 699 ; C 109 ; WX 778 ; N m ; B -14 -9 722 462 ; C 110 ; WX 556 ; N n ; B -6 -9 493 462 ; C 111 ; WX 500 ; N o ; B -3 -13 441 462 ; C 112 ; WX 500 ; N p ; B -120 -205 446 462 ; C 113 ; WX 500 ; N q ; B 1 -205 471 462 ; C 114 ; WX 389 ; N r ; B -21 0 389 462 ; C 115 ; WX 389 ; N s ; B -19 -13 333 462 ; C 116 ; WX 278 ; N t ; B -11 -9 281 594 ; C 117 ; WX 556 ; N u ; B 15 -9 492 462 ; C 118 ; WX 444 ; N v ; B 16 -13 401 462 ; C 119 ; WX 667 ; N w ; B 16 -13 614 462 ; C 120 ; WX 500 ; N x ; B -46 -13 469 462 ; C 121 ; WX 444 ; N y ; B -94 -205 392 462 ; C 122 ; WX 389 ; N z ; B -43 -78 368 449 ; C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ; C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ; C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ; C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ; C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ; C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ; C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ; C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ; C 165 ; WX 500 ; N yen ; B 33 0 628 669 ; C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ; C 167 ; WX 500 ; N section ; B 36 -143 459 685 ; C 168 ; WX 500 ; N currency ; B -26 34 526 586 ; C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ; C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ; C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ; C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ; C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ; C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ; C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ; C 177 ; WX 500 ; N endash ; B -40 178 477 269 ; C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ; C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ; C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ; C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ; C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ; C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ; C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ; C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ; C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ; C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ; C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ; C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ; C 193 ; WX 333 ; N grave ; B 85 516 297 697 ; C 194 ; WX 333 ; N acute ; B 139 516 379 697 ; C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ; C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ; C 197 ; WX 333 ; N macron ; B 51 553 393 623 ; C 198 ; WX 333 ; N breve ; B 71 516 387 678 ; C 199 ; WX 333 ; N dotaccent ; B 163 550 298 684 ; C 200 ; WX 333 ; N dieresis ; B 55 550 402 684 ; C 202 ; WX 333 ; N ring ; B 127 516 340 729 ; C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ; C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ; C 206 ; WX 333 ; N ogonek ; B 15 -183 244 34 ; C 207 ; WX 333 ; N caron ; B 79 516 411 690 ; C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ; C 225 ; WX 944 ; N AE ; B -64 0 918 669 ; C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ; C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ; C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ; C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ; C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ; C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ; C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ; C 248 ; WX 278 ; N lslash ; B -7 -9 307 699 ; C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ; C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ; C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ; C -1 ; WX 389 ; N Idieresis ; B -32 0 450 862 ; C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ; C -1 ; WX 500 ; N abreve ; B -21 -14 471 678 ; C -1 ; WX 556 ; N uhungarumlaut ; B 15 -9 610 697 ; C -1 ; WX 444 ; N ecaron ; B 5 -13 467 690 ; C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ; C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ; C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ; C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ; C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ; C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ; C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ; C -1 ; WX 389 ; N scommaaccent ; B -19 -218 333 462 ; C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ; C -1 ; WX 722 ; N Uring ; B 67 -18 744 921 ; C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ; C -1 ; WX 500 ; N aogonek ; B -21 -183 455 462 ; C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ; C -1 ; WX 556 ; N uogonek ; B 15 -183 492 462 ; C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ; C -1 ; WX 722 ; N Dcroat ; B -31 0 700 669 ; C -1 ; WX 250 ; N commaaccent ; B -36 -218 131 -50 ; C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ; C -1 ; WX 667 ; N Emacron ; B -27 0 653 830 ; C -1 ; WX 444 ; N ccaron ; B -5 -13 467 690 ; C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ; C -1 ; WX 722 ; N Ncommaaccent ; B -27 -218 748 669 ; C -1 ; WX 278 ; N lacute ; B 2 -9 392 904 ; C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ; C -1 ; WX 611 ; N Tcommaaccent ; B 50 -218 650 669 ; C -1 ; WX 667 ; N Cacute ; B 32 -18 677 904 ; C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ; C -1 ; WX 667 ; N Edotaccent ; B -27 0 653 862 ; C -1 ; WX 389 ; N scaron ; B -19 -13 424 690 ; C -1 ; WX 389 ; N scedilla ; B -19 -218 333 462 ; C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ; C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ; C -1 ; WX 667 ; N Rcaron ; B -29 0 623 897 ; C -1 ; WX 722 ; N Gcommaaccent ; B 21 -218 706 685 ; C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ; C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ; C -1 ; WX 667 ; N Amacron ; B -67 0 593 830 ; C -1 ; WX 389 ; N rcaron ; B -21 0 424 690 ; C -1 ; WX 444 ; N ccedilla ; B -5 -218 392 462 ; C -1 ; WX 611 ; N Zdotaccent ; B -11 0 590 862 ; C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ; C -1 ; WX 722 ; N Omacron ; B 27 -18 691 830 ; C -1 ; WX 667 ; N Racute ; B -29 0 623 904 ; C -1 ; WX 556 ; N Sacute ; B 2 -18 531 904 ; C -1 ; WX 608 ; N dcaron ; B -21 -13 675 708 ; C -1 ; WX 722 ; N Umacron ; B 67 -18 744 830 ; C -1 ; WX 556 ; N uring ; B 15 -9 492 729 ; C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ; C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ; C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ; C -1 ; WX 667 ; N Abreve ; B -67 0 593 885 ; C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ; C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ; C -1 ; WX 611 ; N Tcaron ; B 50 0 650 897 ; C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ; C -1 ; WX 444 ; N ydieresis ; B -94 -205 443 655 ; C -1 ; WX 722 ; N Nacute ; B -27 -15 748 904 ; C -1 ; WX 278 ; N icircumflex ; B -3 -9 324 690 ; C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ; C -1 ; WX 500 ; N adieresis ; B -21 -14 476 655 ; C -1 ; WX 444 ; N edieresis ; B 5 -13 448 655 ; C -1 ; WX 444 ; N cacute ; B -5 -13 435 697 ; C -1 ; WX 556 ; N nacute ; B -6 -9 493 697 ; C -1 ; WX 556 ; N umacron ; B 15 -9 492 623 ; C -1 ; WX 722 ; N Ncaron ; B -27 -15 748 897 ; C -1 ; WX 389 ; N Iacute ; B -32 0 432 904 ; C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ; C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ; C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ; C -1 ; WX 722 ; N Gbreve ; B 21 -18 706 885 ; C -1 ; WX 389 ; N Idotaccent ; B -32 0 406 862 ; C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ; C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ; C -1 ; WX 389 ; N racute ; B -21 0 407 697 ; C -1 ; WX 500 ; N omacron ; B -3 -13 462 623 ; C -1 ; WX 611 ; N Zacute ; B -11 0 590 904 ; C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ; C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ; C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ; C -1 ; WX 278 ; N lcommaaccent ; B -42 -218 290 699 ; C -1 ; WX 366 ; N tcaron ; B -11 -9 434 754 ; C -1 ; WX 444 ; N eogonek ; B 5 -183 398 462 ; C -1 ; WX 722 ; N Uogonek ; B 67 -183 744 669 ; C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ; C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ; C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ; C -1 ; WX 389 ; N zacute ; B -43 -78 407 697 ; C -1 ; WX 278 ; N iogonek ; B -20 -183 263 684 ; C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ; C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ; C -1 ; WX 500 ; N amacron ; B -21 -14 467 623 ; C -1 ; WX 389 ; N sacute ; B -19 -13 407 697 ; C -1 ; WX 278 ; N idieresis ; B 2 -9 364 655 ; C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ; C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ; C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ; C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ; C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ; C -1 ; WX 278 ; N igrave ; B 2 -9 259 697 ; C -1 ; WX 500 ; N ohungarumlaut ; B -3 -13 582 697 ; C -1 ; WX 667 ; N Eogonek ; B -27 -183 653 669 ; C -1 ; WX 500 ; N dcroat ; B -21 -13 552 699 ; C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ; C -1 ; WX 556 ; N Scedilla ; B 2 -218 526 685 ; C -1 ; WX 382 ; N lcaron ; B 2 -9 448 708 ; C -1 ; WX 667 ; N Kcommaaccent ; B -21 -218 702 669 ; C -1 ; WX 611 ; N Lacute ; B -22 0 590 904 ; C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ; C -1 ; WX 444 ; N edotaccent ; B 5 -13 398 655 ; C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ; C -1 ; WX 389 ; N Imacron ; B -32 0 461 830 ; C -1 ; WX 611 ; N Lcaron ; B -22 0 671 718 ; C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ; C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ; C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ; C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 67 -18 744 904 ; C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ; C -1 ; WX 444 ; N emacron ; B 5 -13 439 623 ; C -1 ; WX 500 ; N gbreve ; B -52 -203 478 678 ; C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ; C -1 ; WX 556 ; N Scaron ; B 2 -18 553 897 ; C -1 ; WX 556 ; N Scommaaccent ; B 2 -218 526 685 ; C -1 ; WX 722 ; N Ohungarumlaut ; B 27 -18 723 904 ; C -1 ; WX 400 ; N degree ; B 83 397 369 683 ; C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ; C -1 ; WX 667 ; N Ccaron ; B 32 -18 677 897 ; C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ; C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ; C -1 ; WX 722 ; N Dcaron ; B -46 0 685 897 ; C -1 ; WX 389 ; N rcommaaccent ; B -67 -218 389 462 ; C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ; C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ; C -1 ; WX 667 ; N Rcommaaccent ; B -29 -218 623 669 ; C -1 ; WX 611 ; N Lcommaaccent ; B -22 -218 590 669 ; C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ; C -1 ; WX 667 ; N Aogonek ; B -67 -183 604 683 ; C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ; C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ; C -1 ; WX 389 ; N zdotaccent ; B -43 -78 368 655 ; C -1 ; WX 667 ; N Ecaron ; B -27 0 653 897 ; C -1 ; WX 389 ; N Iogonek ; B -32 -183 406 669 ; C -1 ; WX 500 ; N kcommaaccent ; B -23 -218 483 699 ; C -1 ; WX 606 ; N minus ; B 51 209 555 297 ; C -1 ; WX 389 ; N Icircumflex ; B -32 0 450 897 ; C -1 ; WX 556 ; N ncaron ; B -6 -9 523 690 ; C -1 ; WX 278 ; N tcommaaccent ; B -62 -218 281 594 ; C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ; C -1 ; WX 500 ; N odieresis ; B -3 -13 471 655 ; C -1 ; WX 556 ; N udieresis ; B 15 -9 499 655 ; C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ; C -1 ; WX 500 ; N gcommaaccent ; B -52 -203 478 767 ; C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ; C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ; C -1 ; WX 556 ; N ncommaaccent ; B -6 -218 493 462 ; C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ; C -1 ; WX 278 ; N imacron ; B 2 -9 294 623 ; C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2038 KPX A C -65 KPX A Cacute -65 KPX A Ccaron -65 KPX A Ccedilla -65 KPX A G -60 KPX A Gbreve -60 KPX A Gcommaaccent -60 KPX A O -50 KPX A Oacute -50 KPX A Ocircumflex -50 KPX A Odieresis -50 KPX A Ograve -50 KPX A Ohungarumlaut -50 KPX A Omacron -50 KPX A Oslash -50 KPX A Otilde -50 KPX A Q -55 KPX A T -55 KPX A Tcaron -55 KPX A Tcommaaccent -55 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -95 KPX A W -100 KPX A Y -70 KPX A Yacute -70 KPX A Ydieresis -70 KPX A quoteright -74 KPX A u -30 KPX A uacute -30 KPX A ucircumflex -30 KPX A udieresis -30 KPX A ugrave -30 KPX A uhungarumlaut -30 KPX A umacron -30 KPX A uogonek -30 KPX A uring -30 KPX A v -74 KPX A w -74 KPX A y -74 KPX A yacute -74 KPX A ydieresis -74 KPX Aacute C -65 KPX Aacute Cacute -65 KPX Aacute Ccaron -65 KPX Aacute Ccedilla -65 KPX Aacute G -60 KPX Aacute Gbreve -60 KPX Aacute Gcommaaccent -60 KPX Aacute O -50 KPX Aacute Oacute -50 KPX Aacute Ocircumflex -50 KPX Aacute Odieresis -50 KPX Aacute Ograve -50 KPX Aacute Ohungarumlaut -50 KPX Aacute Omacron -50 KPX Aacute Oslash -50 KPX Aacute Otilde -50 KPX Aacute Q -55 KPX Aacute T -55 KPX Aacute Tcaron -55 KPX Aacute Tcommaaccent -55 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -95 KPX Aacute W -100 KPX Aacute Y -70 KPX Aacute Yacute -70 KPX Aacute Ydieresis -70 KPX Aacute quoteright -74 KPX Aacute u -30 KPX Aacute uacute -30 KPX Aacute ucircumflex -30 KPX Aacute udieresis -30 KPX Aacute ugrave -30 KPX Aacute uhungarumlaut -30 KPX Aacute umacron -30 KPX Aacute uogonek -30 KPX Aacute uring -30 KPX Aacute v -74 KPX Aacute w -74 KPX Aacute y -74 KPX Aacute yacute -74 KPX Aacute ydieresis -74 KPX Abreve C -65 KPX Abreve Cacute -65 KPX Abreve Ccaron -65 KPX Abreve Ccedilla -65 KPX Abreve G -60 KPX Abreve Gbreve -60 KPX Abreve Gcommaaccent -60 KPX Abreve O -50 KPX Abreve Oacute -50 KPX Abreve Ocircumflex -50 KPX Abreve Odieresis -50 KPX Abreve Ograve -50 KPX Abreve Ohungarumlaut -50 KPX Abreve Omacron -50 KPX Abreve Oslash -50 KPX Abreve Otilde -50 KPX Abreve Q -55 KPX Abreve T -55 KPX Abreve Tcaron -55 KPX Abreve Tcommaaccent -55 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -95 KPX Abreve W -100 KPX Abreve Y -70 KPX Abreve Yacute -70 KPX Abreve Ydieresis -70 KPX Abreve quoteright -74 KPX Abreve u -30 KPX Abreve uacute -30 KPX Abreve ucircumflex -30 KPX Abreve udieresis -30 KPX Abreve ugrave -30 KPX Abreve uhungarumlaut -30 KPX Abreve umacron -30 KPX Abreve uogonek -30 KPX Abreve uring -30 KPX Abreve v -74 KPX Abreve w -74 KPX Abreve y -74 KPX Abreve yacute -74 KPX Abreve ydieresis -74 KPX Acircumflex C -65 KPX Acircumflex Cacute -65 KPX Acircumflex Ccaron -65 KPX Acircumflex Ccedilla -65 KPX Acircumflex G -60 KPX Acircumflex Gbreve -60 KPX Acircumflex Gcommaaccent -60 KPX Acircumflex O -50 KPX Acircumflex Oacute -50 KPX Acircumflex Ocircumflex -50 KPX Acircumflex Odieresis -50 KPX Acircumflex Ograve -50 KPX Acircumflex Ohungarumlaut -50 KPX Acircumflex Omacron -50 KPX Acircumflex Oslash -50 KPX Acircumflex Otilde -50 KPX Acircumflex Q -55 KPX Acircumflex T -55 KPX Acircumflex Tcaron -55 KPX Acircumflex Tcommaaccent -55 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -95 KPX Acircumflex W -100 KPX Acircumflex Y -70 KPX Acircumflex Yacute -70 KPX Acircumflex Ydieresis -70 KPX Acircumflex quoteright -74 KPX Acircumflex u -30 KPX Acircumflex uacute -30 KPX Acircumflex ucircumflex -30 KPX Acircumflex udieresis -30 KPX Acircumflex ugrave -30 KPX Acircumflex uhungarumlaut -30 KPX Acircumflex umacron -30 KPX Acircumflex uogonek -30 KPX Acircumflex uring -30 KPX Acircumflex v -74 KPX Acircumflex w -74 KPX Acircumflex y -74 KPX Acircumflex yacute -74 KPX Acircumflex ydieresis -74 KPX Adieresis C -65 KPX Adieresis Cacute -65 KPX Adieresis Ccaron -65 KPX Adieresis Ccedilla -65 KPX Adieresis G -60 KPX Adieresis Gbreve -60 KPX Adieresis Gcommaaccent -60 KPX Adieresis O -50 KPX Adieresis Oacute -50 KPX Adieresis Ocircumflex -50 KPX Adieresis Odieresis -50 KPX Adieresis Ograve -50 KPX Adieresis Ohungarumlaut -50 KPX Adieresis Omacron -50 KPX Adieresis Oslash -50 KPX Adieresis Otilde -50 KPX Adieresis Q -55 KPX Adieresis T -55 KPX Adieresis Tcaron -55 KPX Adieresis Tcommaaccent -55 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -95 KPX Adieresis W -100 KPX Adieresis Y -70 KPX Adieresis Yacute -70 KPX Adieresis Ydieresis -70 KPX Adieresis quoteright -74 KPX Adieresis u -30 KPX Adieresis uacute -30 KPX Adieresis ucircumflex -30 KPX Adieresis udieresis -30 KPX Adieresis ugrave -30 KPX Adieresis uhungarumlaut -30 KPX Adieresis umacron -30 KPX Adieresis uogonek -30 KPX Adieresis uring -30 KPX Adieresis v -74 KPX Adieresis w -74 KPX Adieresis y -74 KPX Adieresis yacute -74 KPX Adieresis ydieresis -74 KPX Agrave C -65 KPX Agrave Cacute -65 KPX Agrave Ccaron -65 KPX Agrave Ccedilla -65 KPX Agrave G -60 KPX Agrave Gbreve -60 KPX Agrave Gcommaaccent -60 KPX Agrave O -50 KPX Agrave Oacute -50 KPX Agrave Ocircumflex -50 KPX Agrave Odieresis -50 KPX Agrave Ograve -50 KPX Agrave Ohungarumlaut -50 KPX Agrave Omacron -50 KPX Agrave Oslash -50 KPX Agrave Otilde -50 KPX Agrave Q -55 KPX Agrave T -55 KPX Agrave Tcaron -55 KPX Agrave Tcommaaccent -55 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -95 KPX Agrave W -100 KPX Agrave Y -70 KPX Agrave Yacute -70 KPX Agrave Ydieresis -70 KPX Agrave quoteright -74 KPX Agrave u -30 KPX Agrave uacute -30 KPX Agrave ucircumflex -30 KPX Agrave udieresis -30 KPX Agrave ugrave -30 KPX Agrave uhungarumlaut -30 KPX Agrave umacron -30 KPX Agrave uogonek -30 KPX Agrave uring -30 KPX Agrave v -74 KPX Agrave w -74 KPX Agrave y -74 KPX Agrave yacute -74 KPX Agrave ydieresis -74 KPX Amacron C -65 KPX Amacron Cacute -65 KPX Amacron Ccaron -65 KPX Amacron Ccedilla -65 KPX Amacron G -60 KPX Amacron Gbreve -60 KPX Amacron Gcommaaccent -60 KPX Amacron O -50 KPX Amacron Oacute -50 KPX Amacron Ocircumflex -50 KPX Amacron Odieresis -50 KPX Amacron Ograve -50 KPX Amacron Ohungarumlaut -50 KPX Amacron Omacron -50 KPX Amacron Oslash -50 KPX Amacron Otilde -50 KPX Amacron Q -55 KPX Amacron T -55 KPX Amacron Tcaron -55 KPX Amacron Tcommaaccent -55 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -95 KPX Amacron W -100 KPX Amacron Y -70 KPX Amacron Yacute -70 KPX Amacron Ydieresis -70 KPX Amacron quoteright -74 KPX Amacron u -30 KPX Amacron uacute -30 KPX Amacron ucircumflex -30 KPX Amacron udieresis -30 KPX Amacron ugrave -30 KPX Amacron uhungarumlaut -30 KPX Amacron umacron -30 KPX Amacron uogonek -30 KPX Amacron uring -30 KPX Amacron v -74 KPX Amacron w -74 KPX Amacron y -74 KPX Amacron yacute -74 KPX Amacron ydieresis -74 KPX Aogonek C -65 KPX Aogonek Cacute -65 KPX Aogonek Ccaron -65 KPX Aogonek Ccedilla -65 KPX Aogonek G -60 KPX Aogonek Gbreve -60 KPX Aogonek Gcommaaccent -60 KPX Aogonek O -50 KPX Aogonek Oacute -50 KPX Aogonek Ocircumflex -50 KPX Aogonek Odieresis -50 KPX Aogonek Ograve -50 KPX Aogonek Ohungarumlaut -50 KPX Aogonek Omacron -50 KPX Aogonek Oslash -50 KPX Aogonek Otilde -50 KPX Aogonek Q -55 KPX Aogonek T -55 KPX Aogonek Tcaron -55 KPX Aogonek Tcommaaccent -55 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -95 KPX Aogonek W -100 KPX Aogonek Y -70 KPX Aogonek Yacute -70 KPX Aogonek Ydieresis -70 KPX Aogonek quoteright -74 KPX Aogonek u -30 KPX Aogonek uacute -30 KPX Aogonek ucircumflex -30 KPX Aogonek udieresis -30 KPX Aogonek ugrave -30 KPX Aogonek uhungarumlaut -30 KPX Aogonek umacron -30 KPX Aogonek uogonek -30 KPX Aogonek uring -30 KPX Aogonek v -74 KPX Aogonek w -74 KPX Aogonek y -34 KPX Aogonek yacute -34 KPX Aogonek ydieresis -34 KPX Aring C -65 KPX Aring Cacute -65 KPX Aring Ccaron -65 KPX Aring Ccedilla -65 KPX Aring G -60 KPX Aring Gbreve -60 KPX Aring Gcommaaccent -60 KPX Aring O -50 KPX Aring Oacute -50 KPX Aring Ocircumflex -50 KPX Aring Odieresis -50 KPX Aring Ograve -50 KPX Aring Ohungarumlaut -50 KPX Aring Omacron -50 KPX Aring Oslash -50 KPX Aring Otilde -50 KPX Aring Q -55 KPX Aring T -55 KPX Aring Tcaron -55 KPX Aring Tcommaaccent -55 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -95 KPX Aring W -100 KPX Aring Y -70 KPX Aring Yacute -70 KPX Aring Ydieresis -70 KPX Aring quoteright -74 KPX Aring u -30 KPX Aring uacute -30 KPX Aring ucircumflex -30 KPX Aring udieresis -30 KPX Aring ugrave -30 KPX Aring uhungarumlaut -30 KPX Aring umacron -30 KPX Aring uogonek -30 KPX Aring uring -30 KPX Aring v -74 KPX Aring w -74 KPX Aring y -74 KPX Aring yacute -74 KPX Aring ydieresis -74 KPX Atilde C -65 KPX Atilde Cacute -65 KPX Atilde Ccaron -65 KPX Atilde Ccedilla -65 KPX Atilde G -60 KPX Atilde Gbreve -60 KPX Atilde Gcommaaccent -60 KPX Atilde O -50 KPX Atilde Oacute -50 KPX Atilde Ocircumflex -50 KPX Atilde Odieresis -50 KPX Atilde Ograve -50 KPX Atilde Ohungarumlaut -50 KPX Atilde Omacron -50 KPX Atilde Oslash -50 KPX Atilde Otilde -50 KPX Atilde Q -55 KPX Atilde T -55 KPX Atilde Tcaron -55 KPX Atilde Tcommaaccent -55 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -95 KPX Atilde W -100 KPX Atilde Y -70 KPX Atilde Yacute -70 KPX Atilde Ydieresis -70 KPX Atilde quoteright -74 KPX Atilde u -30 KPX Atilde uacute -30 KPX Atilde ucircumflex -30 KPX Atilde udieresis -30 KPX Atilde ugrave -30 KPX Atilde uhungarumlaut -30 KPX Atilde umacron -30 KPX Atilde uogonek -30 KPX Atilde uring -30 KPX Atilde v -74 KPX Atilde w -74 KPX Atilde y -74 KPX Atilde yacute -74 KPX Atilde ydieresis -74 KPX B A -25 KPX B Aacute -25 KPX B Abreve -25 KPX B Acircumflex -25 KPX B Adieresis -25 KPX B Agrave -25 KPX B Amacron -25 KPX B Aogonek -25 KPX B Aring -25 KPX B Atilde -25 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -25 KPX D Aacute -25 KPX D Abreve -25 KPX D Acircumflex -25 KPX D Adieresis -25 KPX D Agrave -25 KPX D Amacron -25 KPX D Aogonek -25 KPX D Aring -25 KPX D Atilde -25 KPX D V -50 KPX D W -40 KPX D Y -50 KPX D Yacute -50 KPX D Ydieresis -50 KPX Dcaron A -25 KPX Dcaron Aacute -25 KPX Dcaron Abreve -25 KPX Dcaron Acircumflex -25 KPX Dcaron Adieresis -25 KPX Dcaron Agrave -25 KPX Dcaron Amacron -25 KPX Dcaron Aogonek -25 KPX Dcaron Aring -25 KPX Dcaron Atilde -25 KPX Dcaron V -50 KPX Dcaron W -40 KPX Dcaron Y -50 KPX Dcaron Yacute -50 KPX Dcaron Ydieresis -50 KPX Dcroat A -25 KPX Dcroat Aacute -25 KPX Dcroat Abreve -25 KPX Dcroat Acircumflex -25 KPX Dcroat Adieresis -25 KPX Dcroat Agrave -25 KPX Dcroat Amacron -25 KPX Dcroat Aogonek -25 KPX Dcroat Aring -25 KPX Dcroat Atilde -25 KPX Dcroat V -50 KPX Dcroat W -40 KPX Dcroat Y -50 KPX Dcroat Yacute -50 KPX Dcroat Ydieresis -50 KPX F A -100 KPX F Aacute -100 KPX F Abreve -100 KPX F Acircumflex -100 KPX F Adieresis -100 KPX F Agrave -100 KPX F Amacron -100 KPX F Aogonek -100 KPX F Aring -100 KPX F Atilde -100 KPX F a -95 KPX F aacute -95 KPX F abreve -95 KPX F acircumflex -95 KPX F adieresis -95 KPX F agrave -95 KPX F amacron -95 KPX F aogonek -95 KPX F aring -95 KPX F atilde -95 KPX F comma -129 KPX F e -100 KPX F eacute -100 KPX F ecaron -100 KPX F ecircumflex -100 KPX F edieresis -100 KPX F edotaccent -100 KPX F egrave -100 KPX F emacron -100 KPX F eogonek -100 KPX F i -40 KPX F iacute -40 KPX F icircumflex -40 KPX F idieresis -40 KPX F igrave -40 KPX F imacron -40 KPX F iogonek -40 KPX F o -70 KPX F oacute -70 KPX F ocircumflex -70 KPX F odieresis -70 KPX F ograve -70 KPX F ohungarumlaut -70 KPX F omacron -70 KPX F oslash -70 KPX F otilde -70 KPX F period -129 KPX F r -50 KPX F racute -50 KPX F rcaron -50 KPX F rcommaaccent -50 KPX J A -25 KPX J Aacute -25 KPX J Abreve -25 KPX J Acircumflex -25 KPX J Adieresis -25 KPX J Agrave -25 KPX J Amacron -25 KPX J Aogonek -25 KPX J Aring -25 KPX J Atilde -25 KPX J a -40 KPX J aacute -40 KPX J abreve -40 KPX J acircumflex -40 KPX J adieresis -40 KPX J agrave -40 KPX J amacron -40 KPX J aogonek -40 KPX J aring -40 KPX J atilde -40 KPX J comma -10 KPX J e -40 KPX J eacute -40 KPX J ecaron -40 KPX J ecircumflex -40 KPX J edieresis -40 KPX J edotaccent -40 KPX J egrave -40 KPX J emacron -40 KPX J eogonek -40 KPX J o -40 KPX J oacute -40 KPX J ocircumflex -40 KPX J odieresis -40 KPX J ograve -40 KPX J ohungarumlaut -40 KPX J omacron -40 KPX J oslash -40 KPX J otilde -40 KPX J period -10 KPX J u -40 KPX J uacute -40 KPX J ucircumflex -40 KPX J udieresis -40 KPX J ugrave -40 KPX J uhungarumlaut -40 KPX J umacron -40 KPX J uogonek -40 KPX J uring -40 KPX K O -30 KPX K Oacute -30 KPX K Ocircumflex -30 KPX K Odieresis -30 KPX K Ograve -30 KPX K Ohungarumlaut -30 KPX K Omacron -30 KPX K Oslash -30 KPX K Otilde -30 KPX K e -25 KPX K eacute -25 KPX K ecaron -25 KPX K ecircumflex -25 KPX K edieresis -25 KPX K edotaccent -25 KPX K egrave -25 KPX K emacron -25 KPX K eogonek -25 KPX K o -25 KPX K oacute -25 KPX K ocircumflex -25 KPX K odieresis -25 KPX K ograve -25 KPX K ohungarumlaut -25 KPX K omacron -25 KPX K oslash -25 KPX K otilde -25 KPX K u -20 KPX K uacute -20 KPX K ucircumflex -20 KPX K udieresis -20 KPX K ugrave -20 KPX K uhungarumlaut -20 KPX K umacron -20 KPX K uogonek -20 KPX K uring -20 KPX K y -20 KPX K yacute -20 KPX K ydieresis -20 KPX Kcommaaccent O -30 KPX Kcommaaccent Oacute -30 KPX Kcommaaccent Ocircumflex -30 KPX Kcommaaccent Odieresis -30 KPX Kcommaaccent Ograve -30 KPX Kcommaaccent Ohungarumlaut -30 KPX Kcommaaccent Omacron -30 KPX Kcommaaccent Oslash -30 KPX Kcommaaccent Otilde -30 KPX Kcommaaccent e -25 KPX Kcommaaccent eacute -25 KPX Kcommaaccent ecaron -25 KPX Kcommaaccent ecircumflex -25 KPX Kcommaaccent edieresis -25 KPX Kcommaaccent edotaccent -25 KPX Kcommaaccent egrave -25 KPX Kcommaaccent emacron -25 KPX Kcommaaccent eogonek -25 KPX Kcommaaccent o -25 KPX Kcommaaccent oacute -25 KPX Kcommaaccent ocircumflex -25 KPX Kcommaaccent odieresis -25 KPX Kcommaaccent ograve -25 KPX Kcommaaccent ohungarumlaut -25 KPX Kcommaaccent omacron -25 KPX Kcommaaccent oslash -25 KPX Kcommaaccent otilde -25 KPX Kcommaaccent u -20 KPX Kcommaaccent uacute -20 KPX Kcommaaccent ucircumflex -20 KPX Kcommaaccent udieresis -20 KPX Kcommaaccent ugrave -20 KPX Kcommaaccent uhungarumlaut -20 KPX Kcommaaccent umacron -20 KPX Kcommaaccent uogonek -20 KPX Kcommaaccent uring -20 KPX Kcommaaccent y -20 KPX Kcommaaccent yacute -20 KPX Kcommaaccent ydieresis -20 KPX L T -18 KPX L Tcaron -18 KPX L Tcommaaccent -18 KPX L V -37 KPX L W -37 KPX L Y -37 KPX L Yacute -37 KPX L Ydieresis -37 KPX L quoteright -55 KPX L y -37 KPX L yacute -37 KPX L ydieresis -37 KPX Lacute T -18 KPX Lacute Tcaron -18 KPX Lacute Tcommaaccent -18 KPX Lacute V -37 KPX Lacute W -37 KPX Lacute Y -37 KPX Lacute Yacute -37 KPX Lacute Ydieresis -37 KPX Lacute quoteright -55 KPX Lacute y -37 KPX Lacute yacute -37 KPX Lacute ydieresis -37 KPX Lcommaaccent T -18 KPX Lcommaaccent Tcaron -18 KPX Lcommaaccent Tcommaaccent -18 KPX Lcommaaccent V -37 KPX Lcommaaccent W -37 KPX Lcommaaccent Y -37 KPX Lcommaaccent Yacute -37 KPX Lcommaaccent Ydieresis -37 KPX Lcommaaccent quoteright -55 KPX Lcommaaccent y -37 KPX Lcommaaccent yacute -37 KPX Lcommaaccent ydieresis -37 KPX Lslash T -18 KPX Lslash Tcaron -18 KPX Lslash Tcommaaccent -18 KPX Lslash V -37 KPX Lslash W -37 KPX Lslash Y -37 KPX Lslash Yacute -37 KPX Lslash Ydieresis -37 KPX Lslash quoteright -55 KPX Lslash y -37 KPX Lslash yacute -37 KPX Lslash ydieresis -37 KPX N A -30 KPX N Aacute -30 KPX N Abreve -30 KPX N Acircumflex -30 KPX N Adieresis -30 KPX N Agrave -30 KPX N Amacron -30 KPX N Aogonek -30 KPX N Aring -30 KPX N Atilde -30 KPX Nacute A -30 KPX Nacute Aacute -30 KPX Nacute Abreve -30 KPX Nacute Acircumflex -30 KPX Nacute Adieresis -30 KPX Nacute Agrave -30 KPX Nacute Amacron -30 KPX Nacute Aogonek -30 KPX Nacute Aring -30 KPX Nacute Atilde -30 KPX Ncaron A -30 KPX Ncaron Aacute -30 KPX Ncaron Abreve -30 KPX Ncaron Acircumflex -30 KPX Ncaron Adieresis -30 KPX Ncaron Agrave -30 KPX Ncaron Amacron -30 KPX Ncaron Aogonek -30 KPX Ncaron Aring -30 KPX Ncaron Atilde -30 KPX Ncommaaccent A -30 KPX Ncommaaccent Aacute -30 KPX Ncommaaccent Abreve -30 KPX Ncommaaccent Acircumflex -30 KPX Ncommaaccent Adieresis -30 KPX Ncommaaccent Agrave -30 KPX Ncommaaccent Amacron -30 KPX Ncommaaccent Aogonek -30 KPX Ncommaaccent Aring -30 KPX Ncommaaccent Atilde -30 KPX Ntilde A -30 KPX Ntilde Aacute -30 KPX Ntilde Abreve -30 KPX Ntilde Acircumflex -30 KPX Ntilde Adieresis -30 KPX Ntilde Agrave -30 KPX Ntilde Amacron -30 KPX Ntilde Aogonek -30 KPX Ntilde Aring -30 KPX Ntilde Atilde -30 KPX O A -40 KPX O Aacute -40 KPX O Abreve -40 KPX O Acircumflex -40 KPX O Adieresis -40 KPX O Agrave -40 KPX O Amacron -40 KPX O Aogonek -40 KPX O Aring -40 KPX O Atilde -40 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -50 KPX O X -40 KPX O Y -50 KPX O Yacute -50 KPX O Ydieresis -50 KPX Oacute A -40 KPX Oacute Aacute -40 KPX Oacute Abreve -40 KPX Oacute Acircumflex -40 KPX Oacute Adieresis -40 KPX Oacute Agrave -40 KPX Oacute Amacron -40 KPX Oacute Aogonek -40 KPX Oacute Aring -40 KPX Oacute Atilde -40 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -50 KPX Oacute X -40 KPX Oacute Y -50 KPX Oacute Yacute -50 KPX Oacute Ydieresis -50 KPX Ocircumflex A -40 KPX Ocircumflex Aacute -40 KPX Ocircumflex Abreve -40 KPX Ocircumflex Acircumflex -40 KPX Ocircumflex Adieresis -40 KPX Ocircumflex Agrave -40 KPX Ocircumflex Amacron -40 KPX Ocircumflex Aogonek -40 KPX Ocircumflex Aring -40 KPX Ocircumflex Atilde -40 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -50 KPX Ocircumflex X -40 KPX Ocircumflex Y -50 KPX Ocircumflex Yacute -50 KPX Ocircumflex Ydieresis -50 KPX Odieresis A -40 KPX Odieresis Aacute -40 KPX Odieresis Abreve -40 KPX Odieresis Acircumflex -40 KPX Odieresis Adieresis -40 KPX Odieresis Agrave -40 KPX Odieresis Amacron -40 KPX Odieresis Aogonek -40 KPX Odieresis Aring -40 KPX Odieresis Atilde -40 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -50 KPX Odieresis X -40 KPX Odieresis Y -50 KPX Odieresis Yacute -50 KPX Odieresis Ydieresis -50 KPX Ograve A -40 KPX Ograve Aacute -40 KPX Ograve Abreve -40 KPX Ograve Acircumflex -40 KPX Ograve Adieresis -40 KPX Ograve Agrave -40 KPX Ograve Amacron -40 KPX Ograve Aogonek -40 KPX Ograve Aring -40 KPX Ograve Atilde -40 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -50 KPX Ograve X -40 KPX Ograve Y -50 KPX Ograve Yacute -50 KPX Ograve Ydieresis -50 KPX Ohungarumlaut A -40 KPX Ohungarumlaut Aacute -40 KPX Ohungarumlaut Abreve -40 KPX Ohungarumlaut Acircumflex -40 KPX Ohungarumlaut Adieresis -40 KPX Ohungarumlaut Agrave -40 KPX Ohungarumlaut Amacron -40 KPX Ohungarumlaut Aogonek -40 KPX Ohungarumlaut Aring -40 KPX Ohungarumlaut Atilde -40 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -50 KPX Ohungarumlaut X -40 KPX Ohungarumlaut Y -50 KPX Ohungarumlaut Yacute -50 KPX Ohungarumlaut Ydieresis -50 KPX Omacron A -40 KPX Omacron Aacute -40 KPX Omacron Abreve -40 KPX Omacron Acircumflex -40 KPX Omacron Adieresis -40 KPX Omacron Agrave -40 KPX Omacron Amacron -40 KPX Omacron Aogonek -40 KPX Omacron Aring -40 KPX Omacron Atilde -40 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -50 KPX Omacron X -40 KPX Omacron Y -50 KPX Omacron Yacute -50 KPX Omacron Ydieresis -50 KPX Oslash A -40 KPX Oslash Aacute -40 KPX Oslash Abreve -40 KPX Oslash Acircumflex -40 KPX Oslash Adieresis -40 KPX Oslash Agrave -40 KPX Oslash Amacron -40 KPX Oslash Aogonek -40 KPX Oslash Aring -40 KPX Oslash Atilde -40 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -50 KPX Oslash X -40 KPX Oslash Y -50 KPX Oslash Yacute -50 KPX Oslash Ydieresis -50 KPX Otilde A -40 KPX Otilde Aacute -40 KPX Otilde Abreve -40 KPX Otilde Acircumflex -40 KPX Otilde Adieresis -40 KPX Otilde Agrave -40 KPX Otilde Amacron -40 KPX Otilde Aogonek -40 KPX Otilde Aring -40 KPX Otilde Atilde -40 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -50 KPX Otilde X -40 KPX Otilde Y -50 KPX Otilde Yacute -50 KPX Otilde Ydieresis -50 KPX P A -85 KPX P Aacute -85 KPX P Abreve -85 KPX P Acircumflex -85 KPX P Adieresis -85 KPX P Agrave -85 KPX P Amacron -85 KPX P Aogonek -85 KPX P Aring -85 KPX P Atilde -85 KPX P a -40 KPX P aacute -40 KPX P abreve -40 KPX P acircumflex -40 KPX P adieresis -40 KPX P agrave -40 KPX P amacron -40 KPX P aogonek -40 KPX P aring -40 KPX P atilde -40 KPX P comma -129 KPX P e -50 KPX P eacute -50 KPX P ecaron -50 KPX P ecircumflex -50 KPX P edieresis -50 KPX P edotaccent -50 KPX P egrave -50 KPX P emacron -50 KPX P eogonek -50 KPX P o -55 KPX P oacute -55 KPX P ocircumflex -55 KPX P odieresis -55 KPX P ograve -55 KPX P ohungarumlaut -55 KPX P omacron -55 KPX P oslash -55 KPX P otilde -55 KPX P period -129 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX R O -40 KPX R Oacute -40 KPX R Ocircumflex -40 KPX R Odieresis -40 KPX R Ograve -40 KPX R Ohungarumlaut -40 KPX R Omacron -40 KPX R Oslash -40 KPX R Otilde -40 KPX R T -30 KPX R Tcaron -30 KPX R Tcommaaccent -30 KPX R U -40 KPX R Uacute -40 KPX R Ucircumflex -40 KPX R Udieresis -40 KPX R Ugrave -40 KPX R Uhungarumlaut -40 KPX R Umacron -40 KPX R Uogonek -40 KPX R Uring -40 KPX R V -18 KPX R W -18 KPX R Y -18 KPX R Yacute -18 KPX R Ydieresis -18 KPX Racute O -40 KPX Racute Oacute -40 KPX Racute Ocircumflex -40 KPX Racute Odieresis -40 KPX Racute Ograve -40 KPX Racute Ohungarumlaut -40 KPX Racute Omacron -40 KPX Racute Oslash -40 KPX Racute Otilde -40 KPX Racute T -30 KPX Racute Tcaron -30 KPX Racute Tcommaaccent -30 KPX Racute U -40 KPX Racute Uacute -40 KPX Racute Ucircumflex -40 KPX Racute Udieresis -40 KPX Racute Ugrave -40 KPX Racute Uhungarumlaut -40 KPX Racute Umacron -40 KPX Racute Uogonek -40 KPX Racute Uring -40 KPX Racute V -18 KPX Racute W -18 KPX Racute Y -18 KPX Racute Yacute -18 KPX Racute Ydieresis -18 KPX Rcaron O -40 KPX Rcaron Oacute -40 KPX Rcaron Ocircumflex -40 KPX Rcaron Odieresis -40 KPX Rcaron Ograve -40 KPX Rcaron Ohungarumlaut -40 KPX Rcaron Omacron -40 KPX Rcaron Oslash -40 KPX Rcaron Otilde -40 KPX Rcaron T -30 KPX Rcaron Tcaron -30 KPX Rcaron Tcommaaccent -30 KPX Rcaron U -40 KPX Rcaron Uacute -40 KPX Rcaron Ucircumflex -40 KPX Rcaron Udieresis -40 KPX Rcaron Ugrave -40 KPX Rcaron Uhungarumlaut -40 KPX Rcaron Umacron -40 KPX Rcaron Uogonek -40 KPX Rcaron Uring -40 KPX Rcaron V -18 KPX Rcaron W -18 KPX Rcaron Y -18 KPX Rcaron Yacute -18 KPX Rcaron Ydieresis -18 KPX Rcommaaccent O -40 KPX Rcommaaccent Oacute -40 KPX Rcommaaccent Ocircumflex -40 KPX Rcommaaccent Odieresis -40 KPX Rcommaaccent Ograve -40 KPX Rcommaaccent Ohungarumlaut -40 KPX Rcommaaccent Omacron -40 KPX Rcommaaccent Oslash -40 KPX Rcommaaccent Otilde -40 KPX Rcommaaccent T -30 KPX Rcommaaccent Tcaron -30 KPX Rcommaaccent Tcommaaccent -30 KPX Rcommaaccent U -40 KPX Rcommaaccent Uacute -40 KPX Rcommaaccent Ucircumflex -40 KPX Rcommaaccent Udieresis -40 KPX Rcommaaccent Ugrave -40 KPX Rcommaaccent Uhungarumlaut -40 KPX Rcommaaccent Umacron -40 KPX Rcommaaccent Uogonek -40 KPX Rcommaaccent Uring -40 KPX Rcommaaccent V -18 KPX Rcommaaccent W -18 KPX Rcommaaccent Y -18 KPX Rcommaaccent Yacute -18 KPX Rcommaaccent Ydieresis -18 KPX T A -55 KPX T Aacute -55 KPX T Abreve -55 KPX T Acircumflex -55 KPX T Adieresis -55 KPX T Agrave -55 KPX T Amacron -55 KPX T Aogonek -55 KPX T Aring -55 KPX T Atilde -55 KPX T O -18 KPX T Oacute -18 KPX T Ocircumflex -18 KPX T Odieresis -18 KPX T Ograve -18 KPX T Ohungarumlaut -18 KPX T Omacron -18 KPX T Oslash -18 KPX T Otilde -18 KPX T a -92 KPX T aacute -92 KPX T abreve -92 KPX T acircumflex -92 KPX T adieresis -92 KPX T agrave -92 KPX T amacron -92 KPX T aogonek -92 KPX T aring -92 KPX T atilde -92 KPX T colon -74 KPX T comma -92 KPX T e -92 KPX T eacute -92 KPX T ecaron -92 KPX T ecircumflex -92 KPX T edieresis -52 KPX T edotaccent -92 KPX T egrave -52 KPX T emacron -52 KPX T eogonek -92 KPX T hyphen -92 KPX T i -37 KPX T iacute -37 KPX T iogonek -37 KPX T o -95 KPX T oacute -95 KPX T ocircumflex -95 KPX T odieresis -95 KPX T ograve -95 KPX T ohungarumlaut -95 KPX T omacron -95 KPX T oslash -95 KPX T otilde -95 KPX T period -92 KPX T r -37 KPX T racute -37 KPX T rcaron -37 KPX T rcommaaccent -37 KPX T semicolon -74 KPX T u -37 KPX T uacute -37 KPX T ucircumflex -37 KPX T udieresis -37 KPX T ugrave -37 KPX T uhungarumlaut -37 KPX T umacron -37 KPX T uogonek -37 KPX T uring -37 KPX T w -37 KPX T y -37 KPX T yacute -37 KPX T ydieresis -37 KPX Tcaron A -55 KPX Tcaron Aacute -55 KPX Tcaron Abreve -55 KPX Tcaron Acircumflex -55 KPX Tcaron Adieresis -55 KPX Tcaron Agrave -55 KPX Tcaron Amacron -55 KPX Tcaron Aogonek -55 KPX Tcaron Aring -55 KPX Tcaron Atilde -55 KPX Tcaron O -18 KPX Tcaron Oacute -18 KPX Tcaron Ocircumflex -18 KPX Tcaron Odieresis -18 KPX Tcaron Ograve -18 KPX Tcaron Ohungarumlaut -18 KPX Tcaron Omacron -18 KPX Tcaron Oslash -18 KPX Tcaron Otilde -18 KPX Tcaron a -92 KPX Tcaron aacute -92 KPX Tcaron abreve -92 KPX Tcaron acircumflex -92 KPX Tcaron adieresis -92 KPX Tcaron agrave -92 KPX Tcaron amacron -92 KPX Tcaron aogonek -92 KPX Tcaron aring -92 KPX Tcaron atilde -92 KPX Tcaron colon -74 KPX Tcaron comma -92 KPX Tcaron e -92 KPX Tcaron eacute -92 KPX Tcaron ecaron -92 KPX Tcaron ecircumflex -92 KPX Tcaron edieresis -52 KPX Tcaron edotaccent -92 KPX Tcaron egrave -52 KPX Tcaron emacron -52 KPX Tcaron eogonek -92 KPX Tcaron hyphen -92 KPX Tcaron i -37 KPX Tcaron iacute -37 KPX Tcaron iogonek -37 KPX Tcaron o -95 KPX Tcaron oacute -95 KPX Tcaron ocircumflex -95 KPX Tcaron odieresis -95 KPX Tcaron ograve -95 KPX Tcaron ohungarumlaut -95 KPX Tcaron omacron -95 KPX Tcaron oslash -95 KPX Tcaron otilde -95 KPX Tcaron period -92 KPX Tcaron r -37 KPX Tcaron racute -37 KPX Tcaron rcaron -37 KPX Tcaron rcommaaccent -37 KPX Tcaron semicolon -74 KPX Tcaron u -37 KPX Tcaron uacute -37 KPX Tcaron ucircumflex -37 KPX Tcaron udieresis -37 KPX Tcaron ugrave -37 KPX Tcaron uhungarumlaut -37 KPX Tcaron umacron -37 KPX Tcaron uogonek -37 KPX Tcaron uring -37 KPX Tcaron w -37 KPX Tcaron y -37 KPX Tcaron yacute -37 KPX Tcaron ydieresis -37 KPX Tcommaaccent A -55 KPX Tcommaaccent Aacute -55 KPX Tcommaaccent Abreve -55 KPX Tcommaaccent Acircumflex -55 KPX Tcommaaccent Adieresis -55 KPX Tcommaaccent Agrave -55 KPX Tcommaaccent Amacron -55 KPX Tcommaaccent Aogonek -55 KPX Tcommaaccent Aring -55 KPX Tcommaaccent Atilde -55 KPX Tcommaaccent O -18 KPX Tcommaaccent Oacute -18 KPX Tcommaaccent Ocircumflex -18 KPX Tcommaaccent Odieresis -18 KPX Tcommaaccent Ograve -18 KPX Tcommaaccent Ohungarumlaut -18 KPX Tcommaaccent Omacron -18 KPX Tcommaaccent Oslash -18 KPX Tcommaaccent Otilde -18 KPX Tcommaaccent a -92 KPX Tcommaaccent aacute -92 KPX Tcommaaccent abreve -92 KPX Tcommaaccent acircumflex -92 KPX Tcommaaccent adieresis -92 KPX Tcommaaccent agrave -92 KPX Tcommaaccent amacron -92 KPX Tcommaaccent aogonek -92 KPX Tcommaaccent aring -92 KPX Tcommaaccent atilde -92 KPX Tcommaaccent colon -74 KPX Tcommaaccent comma -92 KPX Tcommaaccent e -92 KPX Tcommaaccent eacute -92 KPX Tcommaaccent ecaron -92 KPX Tcommaaccent ecircumflex -92 KPX Tcommaaccent edieresis -52 KPX Tcommaaccent edotaccent -92 KPX Tcommaaccent egrave -52 KPX Tcommaaccent emacron -52 KPX Tcommaaccent eogonek -92 KPX Tcommaaccent hyphen -92 KPX Tcommaaccent i -37 KPX Tcommaaccent iacute -37 KPX Tcommaaccent iogonek -37 KPX Tcommaaccent o -95 KPX Tcommaaccent oacute -95 KPX Tcommaaccent ocircumflex -95 KPX Tcommaaccent odieresis -95 KPX Tcommaaccent ograve -95 KPX Tcommaaccent ohungarumlaut -95 KPX Tcommaaccent omacron -95 KPX Tcommaaccent oslash -95 KPX Tcommaaccent otilde -95 KPX Tcommaaccent period -92 KPX Tcommaaccent r -37 KPX Tcommaaccent racute -37 KPX Tcommaaccent rcaron -37 KPX Tcommaaccent rcommaaccent -37 KPX Tcommaaccent semicolon -74 KPX Tcommaaccent u -37 KPX Tcommaaccent uacute -37 KPX Tcommaaccent ucircumflex -37 KPX Tcommaaccent udieresis -37 KPX Tcommaaccent ugrave -37 KPX Tcommaaccent uhungarumlaut -37 KPX Tcommaaccent umacron -37 KPX Tcommaaccent uogonek -37 KPX Tcommaaccent uring -37 KPX Tcommaaccent w -37 KPX Tcommaaccent y -37 KPX Tcommaaccent yacute -37 KPX Tcommaaccent ydieresis -37 KPX U A -45 KPX U Aacute -45 KPX U Abreve -45 KPX U Acircumflex -45 KPX U Adieresis -45 KPX U Agrave -45 KPX U Amacron -45 KPX U Aogonek -45 KPX U Aring -45 KPX U Atilde -45 KPX Uacute A -45 KPX Uacute Aacute -45 KPX Uacute Abreve -45 KPX Uacute Acircumflex -45 KPX Uacute Adieresis -45 KPX Uacute Agrave -45 KPX Uacute Amacron -45 KPX Uacute Aogonek -45 KPX Uacute Aring -45 KPX Uacute Atilde -45 KPX Ucircumflex A -45 KPX Ucircumflex Aacute -45 KPX Ucircumflex Abreve -45 KPX Ucircumflex Acircumflex -45 KPX Ucircumflex Adieresis -45 KPX Ucircumflex Agrave -45 KPX Ucircumflex Amacron -45 KPX Ucircumflex Aogonek -45 KPX Ucircumflex Aring -45 KPX Ucircumflex Atilde -45 KPX Udieresis A -45 KPX Udieresis Aacute -45 KPX Udieresis Abreve -45 KPX Udieresis Acircumflex -45 KPX Udieresis Adieresis -45 KPX Udieresis Agrave -45 KPX Udieresis Amacron -45 KPX Udieresis Aogonek -45 KPX Udieresis Aring -45 KPX Udieresis Atilde -45 KPX Ugrave A -45 KPX Ugrave Aacute -45 KPX Ugrave Abreve -45 KPX Ugrave Acircumflex -45 KPX Ugrave Adieresis -45 KPX Ugrave Agrave -45 KPX Ugrave Amacron -45 KPX Ugrave Aogonek -45 KPX Ugrave Aring -45 KPX Ugrave Atilde -45 KPX Uhungarumlaut A -45 KPX Uhungarumlaut Aacute -45 KPX Uhungarumlaut Abreve -45 KPX Uhungarumlaut Acircumflex -45 KPX Uhungarumlaut Adieresis -45 KPX Uhungarumlaut Agrave -45 KPX Uhungarumlaut Amacron -45 KPX Uhungarumlaut Aogonek -45 KPX Uhungarumlaut Aring -45 KPX Uhungarumlaut Atilde -45 KPX Umacron A -45 KPX Umacron Aacute -45 KPX Umacron Abreve -45 KPX Umacron Acircumflex -45 KPX Umacron Adieresis -45 KPX Umacron Agrave -45 KPX Umacron Amacron -45 KPX Umacron Aogonek -45 KPX Umacron Aring -45 KPX Umacron Atilde -45 KPX Uogonek A -45 KPX Uogonek Aacute -45 KPX Uogonek Abreve -45 KPX Uogonek Acircumflex -45 KPX Uogonek Adieresis -45 KPX Uogonek Agrave -45 KPX Uogonek Amacron -45 KPX Uogonek Aogonek -45 KPX Uogonek Aring -45 KPX Uogonek Atilde -45 KPX Uring A -45 KPX Uring Aacute -45 KPX Uring Abreve -45 KPX Uring Acircumflex -45 KPX Uring Adieresis -45 KPX Uring Agrave -45 KPX Uring Amacron -45 KPX Uring Aogonek -45 KPX Uring Aring -45 KPX Uring Atilde -45 KPX V A -85 KPX V Aacute -85 KPX V Abreve -85 KPX V Acircumflex -85 KPX V Adieresis -85 KPX V Agrave -85 KPX V Amacron -85 KPX V Aogonek -85 KPX V Aring -85 KPX V Atilde -85 KPX V G -10 KPX V Gbreve -10 KPX V Gcommaaccent -10 KPX V O -30 KPX V Oacute -30 KPX V Ocircumflex -30 KPX V Odieresis -30 KPX V Ograve -30 KPX V Ohungarumlaut -30 KPX V Omacron -30 KPX V Oslash -30 KPX V Otilde -30 KPX V a -111 KPX V aacute -111 KPX V abreve -111 KPX V acircumflex -111 KPX V adieresis -111 KPX V agrave -111 KPX V amacron -111 KPX V aogonek -111 KPX V aring -111 KPX V atilde -111 KPX V colon -74 KPX V comma -129 KPX V e -111 KPX V eacute -111 KPX V ecaron -111 KPX V ecircumflex -111 KPX V edieresis -71 KPX V edotaccent -111 KPX V egrave -71 KPX V emacron -71 KPX V eogonek -111 KPX V hyphen -70 KPX V i -55 KPX V iacute -55 KPX V iogonek -55 KPX V o -111 KPX V oacute -111 KPX V ocircumflex -111 KPX V odieresis -111 KPX V ograve -111 KPX V ohungarumlaut -111 KPX V omacron -111 KPX V oslash -111 KPX V otilde -111 KPX V period -129 KPX V semicolon -74 KPX V u -55 KPX V uacute -55 KPX V ucircumflex -55 KPX V udieresis -55 KPX V ugrave -55 KPX V uhungarumlaut -55 KPX V umacron -55 KPX V uogonek -55 KPX V uring -55 KPX W A -74 KPX W Aacute -74 KPX W Abreve -74 KPX W Acircumflex -74 KPX W Adieresis -74 KPX W Agrave -74 KPX W Amacron -74 KPX W Aogonek -74 KPX W Aring -74 KPX W Atilde -74 KPX W O -15 KPX W Oacute -15 KPX W Ocircumflex -15 KPX W Odieresis -15 KPX W Ograve -15 KPX W Ohungarumlaut -15 KPX W Omacron -15 KPX W Oslash -15 KPX W Otilde -15 KPX W a -85 KPX W aacute -85 KPX W abreve -85 KPX W acircumflex -85 KPX W adieresis -85 KPX W agrave -85 KPX W amacron -85 KPX W aogonek -85 KPX W aring -85 KPX W atilde -85 KPX W colon -55 KPX W comma -74 KPX W e -90 KPX W eacute -90 KPX W ecaron -90 KPX W ecircumflex -90 KPX W edieresis -50 KPX W edotaccent -90 KPX W egrave -50 KPX W emacron -50 KPX W eogonek -90 KPX W hyphen -50 KPX W i -37 KPX W iacute -37 KPX W iogonek -37 KPX W o -80 KPX W oacute -80 KPX W ocircumflex -80 KPX W odieresis -80 KPX W ograve -80 KPX W ohungarumlaut -80 KPX W omacron -80 KPX W oslash -80 KPX W otilde -80 KPX W period -74 KPX W semicolon -55 KPX W u -55 KPX W uacute -55 KPX W ucircumflex -55 KPX W udieresis -55 KPX W ugrave -55 KPX W uhungarumlaut -55 KPX W umacron -55 KPX W uogonek -55 KPX W uring -55 KPX W y -55 KPX W yacute -55 KPX W ydieresis -55 KPX Y A -74 KPX Y Aacute -74 KPX Y Abreve -74 KPX Y Acircumflex -74 KPX Y Adieresis -74 KPX Y Agrave -74 KPX Y Amacron -74 KPX Y Aogonek -74 KPX Y Aring -74 KPX Y Atilde -74 KPX Y O -25 KPX Y Oacute -25 KPX Y Ocircumflex -25 KPX Y Odieresis -25 KPX Y Ograve -25 KPX Y Ohungarumlaut -25 KPX Y Omacron -25 KPX Y Oslash -25 KPX Y Otilde -25 KPX Y a -92 KPX Y aacute -92 KPX Y abreve -92 KPX Y acircumflex -92 KPX Y adieresis -92 KPX Y agrave -92 KPX Y amacron -92 KPX Y aogonek -92 KPX Y aring -92 KPX Y atilde -92 KPX Y colon -92 KPX Y comma -92 KPX Y e -111 KPX Y eacute -111 KPX Y ecaron -111 KPX Y ecircumflex -71 KPX Y edieresis -71 KPX Y edotaccent -111 KPX Y egrave -71 KPX Y emacron -71 KPX Y eogonek -111 KPX Y hyphen -92 KPX Y i -55 KPX Y iacute -55 KPX Y iogonek -55 KPX Y o -111 KPX Y oacute -111 KPX Y ocircumflex -111 KPX Y odieresis -111 KPX Y ograve -111 KPX Y ohungarumlaut -111 KPX Y omacron -111 KPX Y oslash -111 KPX Y otilde -111 KPX Y period -74 KPX Y semicolon -92 KPX Y u -92 KPX Y uacute -92 KPX Y ucircumflex -92 KPX Y udieresis -92 KPX Y ugrave -92 KPX Y uhungarumlaut -92 KPX Y umacron -92 KPX Y uogonek -92 KPX Y uring -92 KPX Yacute A -74 KPX Yacute Aacute -74 KPX Yacute Abreve -74 KPX Yacute Acircumflex -74 KPX Yacute Adieresis -74 KPX Yacute Agrave -74 KPX Yacute Amacron -74 KPX Yacute Aogonek -74 KPX Yacute Aring -74 KPX Yacute Atilde -74 KPX Yacute O -25 KPX Yacute Oacute -25 KPX Yacute Ocircumflex -25 KPX Yacute Odieresis -25 KPX Yacute Ograve -25 KPX Yacute Ohungarumlaut -25 KPX Yacute Omacron -25 KPX Yacute Oslash -25 KPX Yacute Otilde -25 KPX Yacute a -92 KPX Yacute aacute -92 KPX Yacute abreve -92 KPX Yacute acircumflex -92 KPX Yacute adieresis -92 KPX Yacute agrave -92 KPX Yacute amacron -92 KPX Yacute aogonek -92 KPX Yacute aring -92 KPX Yacute atilde -92 KPX Yacute colon -92 KPX Yacute comma -92 KPX Yacute e -111 KPX Yacute eacute -111 KPX Yacute ecaron -111 KPX Yacute ecircumflex -71 KPX Yacute edieresis -71 KPX Yacute edotaccent -111 KPX Yacute egrave -71 KPX Yacute emacron -71 KPX Yacute eogonek -111 KPX Yacute hyphen -92 KPX Yacute i -55 KPX Yacute iacute -55 KPX Yacute iogonek -55 KPX Yacute o -111 KPX Yacute oacute -111 KPX Yacute ocircumflex -111 KPX Yacute odieresis -111 KPX Yacute ograve -111 KPX Yacute ohungarumlaut -111 KPX Yacute omacron -111 KPX Yacute oslash -111 KPX Yacute otilde -111 KPX Yacute period -74 KPX Yacute semicolon -92 KPX Yacute u -92 KPX Yacute uacute -92 KPX Yacute ucircumflex -92 KPX Yacute udieresis -92 KPX Yacute ugrave -92 KPX Yacute uhungarumlaut -92 KPX Yacute umacron -92 KPX Yacute uogonek -92 KPX Yacute uring -92 KPX Ydieresis A -74 KPX Ydieresis Aacute -74 KPX Ydieresis Abreve -74 KPX Ydieresis Acircumflex -74 KPX Ydieresis Adieresis -74 KPX Ydieresis Agrave -74 KPX Ydieresis Amacron -74 KPX Ydieresis Aogonek -74 KPX Ydieresis Aring -74 KPX Ydieresis Atilde -74 KPX Ydieresis O -25 KPX Ydieresis Oacute -25 KPX Ydieresis Ocircumflex -25 KPX Ydieresis Odieresis -25 KPX Ydieresis Ograve -25 KPX Ydieresis Ohungarumlaut -25 KPX Ydieresis Omacron -25 KPX Ydieresis Oslash -25 KPX Ydieresis Otilde -25 KPX Ydieresis a -92 KPX Ydieresis aacute -92 KPX Ydieresis abreve -92 KPX Ydieresis acircumflex -92 KPX Ydieresis adieresis -92 KPX Ydieresis agrave -92 KPX Ydieresis amacron -92 KPX Ydieresis aogonek -92 KPX Ydieresis aring -92 KPX Ydieresis atilde -92 KPX Ydieresis colon -92 KPX Ydieresis comma -92 KPX Ydieresis e -111 KPX Ydieresis eacute -111 KPX Ydieresis ecaron -111 KPX Ydieresis ecircumflex -71 KPX Ydieresis edieresis -71 KPX Ydieresis edotaccent -111 KPX Ydieresis egrave -71 KPX Ydieresis emacron -71 KPX Ydieresis eogonek -111 KPX Ydieresis hyphen -92 KPX Ydieresis i -55 KPX Ydieresis iacute -55 KPX Ydieresis iogonek -55 KPX Ydieresis o -111 KPX Ydieresis oacute -111 KPX Ydieresis ocircumflex -111 KPX Ydieresis odieresis -111 KPX Ydieresis ograve -111 KPX Ydieresis ohungarumlaut -111 KPX Ydieresis omacron -111 KPX Ydieresis oslash -111 KPX Ydieresis otilde -111 KPX Ydieresis period -74 KPX Ydieresis semicolon -92 KPX Ydieresis u -92 KPX Ydieresis uacute -92 KPX Ydieresis ucircumflex -92 KPX Ydieresis udieresis -92 KPX Ydieresis ugrave -92 KPX Ydieresis uhungarumlaut -92 KPX Ydieresis umacron -92 KPX Ydieresis uogonek -92 KPX Ydieresis uring -92 KPX b b -10 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX c h -10 KPX c k -10 KPX c kcommaaccent -10 KPX cacute h -10 KPX cacute k -10 KPX cacute kcommaaccent -10 KPX ccaron h -10 KPX ccaron k -10 KPX ccaron kcommaaccent -10 KPX ccedilla h -10 KPX ccedilla k -10 KPX ccedilla kcommaaccent -10 KPX comma quotedblright -95 KPX comma quoteright -95 KPX e b -10 KPX eacute b -10 KPX ecaron b -10 KPX ecircumflex b -10 KPX edieresis b -10 KPX edotaccent b -10 KPX egrave b -10 KPX emacron b -10 KPX eogonek b -10 KPX f comma -10 KPX f dotlessi -30 KPX f e -10 KPX f eacute -10 KPX f edotaccent -10 KPX f eogonek -10 KPX f f -18 KPX f o -10 KPX f oacute -10 KPX f ocircumflex -10 KPX f ograve -10 KPX f ohungarumlaut -10 KPX f oslash -10 KPX f otilde -10 KPX f period -10 KPX f quoteright 55 KPX k e -30 KPX k eacute -30 KPX k ecaron -30 KPX k ecircumflex -30 KPX k edieresis -30 KPX k edotaccent -30 KPX k egrave -30 KPX k emacron -30 KPX k eogonek -30 KPX k o -10 KPX k oacute -10 KPX k ocircumflex -10 KPX k odieresis -10 KPX k ograve -10 KPX k ohungarumlaut -10 KPX k omacron -10 KPX k oslash -10 KPX k otilde -10 KPX kcommaaccent e -30 KPX kcommaaccent eacute -30 KPX kcommaaccent ecaron -30 KPX kcommaaccent ecircumflex -30 KPX kcommaaccent edieresis -30 KPX kcommaaccent edotaccent -30 KPX kcommaaccent egrave -30 KPX kcommaaccent emacron -30 KPX kcommaaccent eogonek -30 KPX kcommaaccent o -10 KPX kcommaaccent oacute -10 KPX kcommaaccent ocircumflex -10 KPX kcommaaccent odieresis -10 KPX kcommaaccent ograve -10 KPX kcommaaccent ohungarumlaut -10 KPX kcommaaccent omacron -10 KPX kcommaaccent oslash -10 KPX kcommaaccent otilde -10 KPX n v -40 KPX nacute v -40 KPX ncaron v -40 KPX ncommaaccent v -40 KPX ntilde v -40 KPX o v -15 KPX o w -25 KPX o x -10 KPX o y -10 KPX o yacute -10 KPX o ydieresis -10 KPX oacute v -15 KPX oacute w -25 KPX oacute x -10 KPX oacute y -10 KPX oacute yacute -10 KPX oacute ydieresis -10 KPX ocircumflex v -15 KPX ocircumflex w -25 KPX ocircumflex x -10 KPX ocircumflex y -10 KPX ocircumflex yacute -10 KPX ocircumflex ydieresis -10 KPX odieresis v -15 KPX odieresis w -25 KPX odieresis x -10 KPX odieresis y -10 KPX odieresis yacute -10 KPX odieresis ydieresis -10 KPX ograve v -15 KPX ograve w -25 KPX ograve x -10 KPX ograve y -10 KPX ograve yacute -10 KPX ograve ydieresis -10 KPX ohungarumlaut v -15 KPX ohungarumlaut w -25 KPX ohungarumlaut x -10 KPX ohungarumlaut y -10 KPX ohungarumlaut yacute -10 KPX ohungarumlaut ydieresis -10 KPX omacron v -15 KPX omacron w -25 KPX omacron x -10 KPX omacron y -10 KPX omacron yacute -10 KPX omacron ydieresis -10 KPX oslash v -15 KPX oslash w -25 KPX oslash x -10 KPX oslash y -10 KPX oslash yacute -10 KPX oslash ydieresis -10 KPX otilde v -15 KPX otilde w -25 KPX otilde x -10 KPX otilde y -10 KPX otilde yacute -10 KPX otilde ydieresis -10 KPX period quotedblright -95 KPX period quoteright -95 KPX quoteleft quoteleft -74 KPX quoteright d -15 KPX quoteright dcroat -15 KPX quoteright quoteright -74 KPX quoteright r -15 KPX quoteright racute -15 KPX quoteright rcaron -15 KPX quoteright rcommaaccent -15 KPX quoteright s -74 KPX quoteright sacute -74 KPX quoteright scaron -74 KPX quoteright scedilla -74 KPX quoteright scommaaccent -74 KPX quoteright space -74 KPX quoteright t -37 KPX quoteright tcommaaccent -37 KPX quoteright v -15 KPX r comma -65 KPX r period -65 KPX racute comma -65 KPX racute period -65 KPX rcaron comma -65 KPX rcaron period -65 KPX rcommaaccent comma -65 KPX rcommaaccent period -65 KPX space A -37 KPX space Aacute -37 KPX space Abreve -37 KPX space Acircumflex -37 KPX space Adieresis -37 KPX space Agrave -37 KPX space Amacron -37 KPX space Aogonek -37 KPX space Aring -37 KPX space Atilde -37 KPX space V -70 KPX space W -70 KPX space Y -70 KPX space Yacute -70 KPX space Ydieresis -70 KPX v comma -37 KPX v e -15 KPX v eacute -15 KPX v ecaron -15 KPX v ecircumflex -15 KPX v edieresis -15 KPX v edotaccent -15 KPX v egrave -15 KPX v emacron -15 KPX v eogonek -15 KPX v o -15 KPX v oacute -15 KPX v ocircumflex -15 KPX v odieresis -15 KPX v ograve -15 KPX v ohungarumlaut -15 KPX v omacron -15 KPX v oslash -15 KPX v otilde -15 KPX v period -37 KPX w a -10 KPX w aacute -10 KPX w abreve -10 KPX w acircumflex -10 KPX w adieresis -10 KPX w agrave -10 KPX w amacron -10 KPX w aogonek -10 KPX w aring -10 KPX w atilde -10 KPX w comma -37 KPX w e -10 KPX w eacute -10 KPX w ecaron -10 KPX w ecircumflex -10 KPX w edieresis -10 KPX w edotaccent -10 KPX w egrave -10 KPX w emacron -10 KPX w eogonek -10 KPX w o -15 KPX w oacute -15 KPX w ocircumflex -15 KPX w odieresis -15 KPX w ograve -15 KPX w ohungarumlaut -15 KPX w omacron -15 KPX w oslash -15 KPX w otilde -15 KPX w period -37 KPX x e -10 KPX x eacute -10 KPX x ecaron -10 KPX x ecircumflex -10 KPX x edieresis -10 KPX x edotaccent -10 KPX x egrave -10 KPX x emacron -10 KPX x eogonek -10 KPX y comma -37 KPX y period -37 KPX yacute comma -37 KPX yacute period -37 KPX ydieresis comma -37 KPX ydieresis period -37 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Times-Italic.afm100644 0 0 206603 11000354125 20026 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:56:55 1997 Comment UniqueID 43067 Comment VMusage 47727 58752 FontName Times-Italic FullName Times Italic FamilyName Times Weight Medium ItalicAngle -15.5 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -169 -217 1010 883 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 653 XHeight 441 Ascender 683 Descender -217 StdHW 32 StdVW 76 StartCharMetrics 315 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ; C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ; C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ; C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ; C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ; C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ; C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ; C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ; C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ; C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ; C 43 ; WX 675 ; N plus ; B 86 0 590 506 ; C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ; C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ; C 46 ; WX 250 ; N period ; B 27 -11 138 100 ; C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ; C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ; C 49 ; WX 500 ; N one ; B 49 0 409 676 ; C 50 ; WX 500 ; N two ; B 12 0 452 676 ; C 51 ; WX 500 ; N three ; B 15 -7 465 676 ; C 52 ; WX 500 ; N four ; B 1 0 479 676 ; C 53 ; WX 500 ; N five ; B 15 -7 491 666 ; C 54 ; WX 500 ; N six ; B 30 -7 521 686 ; C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ; C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ; C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ; C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ; C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ; C 60 ; WX 675 ; N less ; B 84 -8 592 514 ; C 61 ; WX 675 ; N equal ; B 86 120 590 386 ; C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ; C 63 ; WX 500 ; N question ; B 132 -12 472 664 ; C 64 ; WX 920 ; N at ; B 118 -18 806 666 ; C 65 ; WX 611 ; N A ; B -51 0 564 668 ; C 66 ; WX 611 ; N B ; B -8 0 588 653 ; C 67 ; WX 667 ; N C ; B 66 -18 689 666 ; C 68 ; WX 722 ; N D ; B -8 0 700 653 ; C 69 ; WX 611 ; N E ; B -1 0 634 653 ; C 70 ; WX 611 ; N F ; B 8 0 645 653 ; C 71 ; WX 722 ; N G ; B 52 -18 722 666 ; C 72 ; WX 722 ; N H ; B -8 0 767 653 ; C 73 ; WX 333 ; N I ; B -8 0 384 653 ; C 74 ; WX 444 ; N J ; B -6 -18 491 653 ; C 75 ; WX 667 ; N K ; B 7 0 722 653 ; C 76 ; WX 556 ; N L ; B -8 0 559 653 ; C 77 ; WX 833 ; N M ; B -18 0 873 653 ; C 78 ; WX 667 ; N N ; B -20 -15 727 653 ; C 79 ; WX 722 ; N O ; B 60 -18 699 666 ; C 80 ; WX 611 ; N P ; B 0 0 605 653 ; C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ; C 82 ; WX 611 ; N R ; B -13 0 588 653 ; C 83 ; WX 500 ; N S ; B 17 -18 508 667 ; C 84 ; WX 556 ; N T ; B 59 0 633 653 ; C 85 ; WX 722 ; N U ; B 102 -18 765 653 ; C 86 ; WX 611 ; N V ; B 76 -18 688 653 ; C 87 ; WX 833 ; N W ; B 71 -18 906 653 ; C 88 ; WX 611 ; N X ; B -29 0 655 653 ; C 89 ; WX 556 ; N Y ; B 78 0 633 653 ; C 90 ; WX 556 ; N Z ; B -6 0 606 653 ; C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ; C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ; C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ; C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ; C 97 ; WX 500 ; N a ; B 17 -11 476 441 ; C 98 ; WX 500 ; N b ; B 23 -11 473 683 ; C 99 ; WX 444 ; N c ; B 30 -11 425 441 ; C 100 ; WX 500 ; N d ; B 15 -13 527 683 ; C 101 ; WX 444 ; N e ; B 31 -11 412 441 ; C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 8 -206 472 441 ; C 104 ; WX 500 ; N h ; B 19 -9 478 683 ; C 105 ; WX 278 ; N i ; B 49 -11 264 654 ; C 106 ; WX 278 ; N j ; B -124 -207 276 654 ; C 107 ; WX 444 ; N k ; B 14 -11 461 683 ; C 108 ; WX 278 ; N l ; B 41 -11 279 683 ; C 109 ; WX 722 ; N m ; B 12 -9 704 441 ; C 110 ; WX 500 ; N n ; B 14 -9 474 441 ; C 111 ; WX 500 ; N o ; B 27 -11 468 441 ; C 112 ; WX 500 ; N p ; B -75 -205 469 441 ; C 113 ; WX 500 ; N q ; B 25 -209 483 441 ; C 114 ; WX 389 ; N r ; B 45 0 412 441 ; C 115 ; WX 389 ; N s ; B 16 -13 366 442 ; C 116 ; WX 278 ; N t ; B 37 -11 296 546 ; C 117 ; WX 500 ; N u ; B 42 -11 475 441 ; C 118 ; WX 444 ; N v ; B 21 -18 426 441 ; C 119 ; WX 667 ; N w ; B 16 -18 648 441 ; C 120 ; WX 444 ; N x ; B -27 -11 447 441 ; C 121 ; WX 444 ; N y ; B -24 -206 426 441 ; C 122 ; WX 389 ; N z ; B -2 -81 380 428 ; C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ; C 124 ; WX 275 ; N bar ; B 105 -217 171 783 ; C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ; C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ; C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ; C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ; C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ; C 165 ; WX 500 ; N yen ; B 27 0 603 653 ; C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ; C 167 ; WX 500 ; N section ; B 53 -162 461 666 ; C 168 ; WX 500 ; N currency ; B -22 53 522 597 ; C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ; C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ; C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ; C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ; C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ; C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ; C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ; C 177 ; WX 500 ; N endash ; B -6 197 505 243 ; C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ; C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ; C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ; C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ; C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ; C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ; C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ; C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ; C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ; C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ; C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ; C 193 ; WX 333 ; N grave ; B 121 492 311 664 ; C 194 ; WX 333 ; N acute ; B 180 494 403 664 ; C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ; C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ; C 197 ; WX 333 ; N macron ; B 99 532 411 583 ; C 198 ; WX 333 ; N breve ; B 117 492 418 650 ; C 199 ; WX 333 ; N dotaccent ; B 207 548 305 646 ; C 200 ; WX 333 ; N dieresis ; B 107 548 405 646 ; C 202 ; WX 333 ; N ring ; B 155 492 355 691 ; C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ; C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ; C 206 ; WX 333 ; N ogonek ; B 20 -169 203 40 ; C 207 ; WX 333 ; N caron ; B 121 492 426 661 ; C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ; C 225 ; WX 889 ; N AE ; B -27 0 911 653 ; C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ; C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ; C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ; C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ; C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ; C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ; C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ; C 248 ; WX 278 ; N lslash ; B 41 -11 312 683 ; C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ; C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ; C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ; C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ; C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ; C -1 ; WX 500 ; N abreve ; B 17 -11 502 650 ; C -1 ; WX 500 ; N uhungarumlaut ; B 42 -11 580 664 ; C -1 ; WX 444 ; N ecaron ; B 31 -11 482 661 ; C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ; C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ; C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ; C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ; C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ; C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ; C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ; C -1 ; WX 389 ; N scommaaccent ; B 16 -217 366 442 ; C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ; C -1 ; WX 722 ; N Uring ; B 102 -18 765 883 ; C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ; C -1 ; WX 500 ; N aogonek ; B 17 -169 476 441 ; C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ; C -1 ; WX 500 ; N uogonek ; B 42 -169 477 441 ; C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ; C -1 ; WX 722 ; N Dcroat ; B -8 0 700 653 ; C -1 ; WX 250 ; N commaaccent ; B 8 -217 133 -50 ; C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ; C -1 ; WX 611 ; N Emacron ; B -1 0 634 795 ; C -1 ; WX 444 ; N ccaron ; B 30 -11 482 661 ; C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ; C -1 ; WX 667 ; N Ncommaaccent ; B -20 -187 727 653 ; C -1 ; WX 278 ; N lacute ; B 41 -11 395 876 ; C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ; C -1 ; WX 556 ; N Tcommaaccent ; B 59 -217 633 653 ; C -1 ; WX 667 ; N Cacute ; B 66 -18 690 876 ; C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ; C -1 ; WX 611 ; N Edotaccent ; B -1 0 634 818 ; C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ; C -1 ; WX 389 ; N scedilla ; B 16 -217 366 442 ; C -1 ; WX 278 ; N iacute ; B 49 -11 355 664 ; C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; C -1 ; WX 611 ; N Rcaron ; B -13 0 588 873 ; C -1 ; WX 722 ; N Gcommaaccent ; B 52 -217 722 666 ; C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ; C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ; C -1 ; WX 611 ; N Amacron ; B -51 0 564 795 ; C -1 ; WX 389 ; N rcaron ; B 45 0 434 661 ; C -1 ; WX 444 ; N ccedilla ; B 30 -217 425 441 ; C -1 ; WX 556 ; N Zdotaccent ; B -6 0 606 818 ; C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ; C -1 ; WX 722 ; N Omacron ; B 60 -18 699 795 ; C -1 ; WX 611 ; N Racute ; B -13 0 588 876 ; C -1 ; WX 500 ; N Sacute ; B 17 -18 508 876 ; C -1 ; WX 544 ; N dcaron ; B 15 -13 658 683 ; C -1 ; WX 722 ; N Umacron ; B 102 -18 765 795 ; C -1 ; WX 500 ; N uring ; B 42 -11 475 691 ; C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ; C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ; C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ; C -1 ; WX 611 ; N Abreve ; B -51 0 564 862 ; C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ; C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ; C -1 ; WX 556 ; N Tcaron ; B 59 0 633 873 ; C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ; C -1 ; WX 667 ; N Nacute ; B -20 -15 727 876 ; C -1 ; WX 278 ; N icircumflex ; B 33 -11 327 661 ; C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ; C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ; C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ; C -1 ; WX 444 ; N cacute ; B 30 -11 459 664 ; C -1 ; WX 500 ; N nacute ; B 14 -9 477 664 ; C -1 ; WX 500 ; N umacron ; B 42 -11 485 583 ; C -1 ; WX 667 ; N Ncaron ; B -20 -15 727 873 ; C -1 ; WX 333 ; N Iacute ; B -8 0 433 876 ; C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ; C -1 ; WX 275 ; N brokenbar ; B 105 -142 171 708 ; C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ; C -1 ; WX 722 ; N Gbreve ; B 52 -18 722 862 ; C -1 ; WX 333 ; N Idotaccent ; B -8 0 384 818 ; C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ; C -1 ; WX 389 ; N racute ; B 45 0 431 664 ; C -1 ; WX 500 ; N omacron ; B 27 -11 495 583 ; C -1 ; WX 556 ; N Zacute ; B -6 0 606 876 ; C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 658 ; C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ; C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ; C -1 ; WX 278 ; N lcommaaccent ; B 22 -217 279 683 ; C -1 ; WX 300 ; N tcaron ; B 37 -11 407 681 ; C -1 ; WX 444 ; N eogonek ; B 31 -169 412 441 ; C -1 ; WX 722 ; N Uogonek ; B 102 -184 765 653 ; C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ; C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ; C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ; C -1 ; WX 389 ; N zacute ; B -2 -81 431 664 ; C -1 ; WX 278 ; N iogonek ; B 49 -169 264 654 ; C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ; C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ; C -1 ; WX 500 ; N amacron ; B 17 -11 495 583 ; C -1 ; WX 389 ; N sacute ; B 16 -13 431 664 ; C -1 ; WX 278 ; N idieresis ; B 49 -11 352 606 ; C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ; C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ; C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ; C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ; C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ; C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ; C -1 ; WX 500 ; N ohungarumlaut ; B 27 -11 590 664 ; C -1 ; WX 611 ; N Eogonek ; B -1 -169 634 653 ; C -1 ; WX 500 ; N dcroat ; B 15 -13 572 683 ; C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ; C -1 ; WX 500 ; N Scedilla ; B 17 -217 508 667 ; C -1 ; WX 300 ; N lcaron ; B 41 -11 407 683 ; C -1 ; WX 667 ; N Kcommaaccent ; B 7 -217 722 653 ; C -1 ; WX 556 ; N Lacute ; B -8 0 559 876 ; C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ; C -1 ; WX 444 ; N edotaccent ; B 31 -11 412 606 ; C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ; C -1 ; WX 333 ; N Imacron ; B -8 0 441 795 ; C -1 ; WX 611 ; N Lcaron ; B -8 0 586 653 ; C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ; C -1 ; WX 549 ; N lessequal ; B 26 0 523 658 ; C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ; C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 102 -18 765 876 ; C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ; C -1 ; WX 444 ; N emacron ; B 31 -11 457 583 ; C -1 ; WX 500 ; N gbreve ; B 8 -206 487 650 ; C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ; C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ; C -1 ; WX 500 ; N Scommaaccent ; B 17 -217 508 667 ; C -1 ; WX 722 ; N Ohungarumlaut ; B 60 -18 699 876 ; C -1 ; WX 400 ; N degree ; B 101 390 387 676 ; C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ; C -1 ; WX 667 ; N Ccaron ; B 66 -18 689 873 ; C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ; C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; C -1 ; WX 722 ; N Dcaron ; B -8 0 700 873 ; C -1 ; WX 389 ; N rcommaaccent ; B -3 -217 412 441 ; C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ; C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ; C -1 ; WX 611 ; N Rcommaaccent ; B -13 -187 588 653 ; C -1 ; WX 556 ; N Lcommaaccent ; B -8 -217 559 653 ; C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ; C -1 ; WX 611 ; N Aogonek ; B -51 -169 566 668 ; C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ; C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ; C -1 ; WX 389 ; N zdotaccent ; B -2 -81 380 606 ; C -1 ; WX 611 ; N Ecaron ; B -1 0 634 873 ; C -1 ; WX 333 ; N Iogonek ; B -8 -169 384 653 ; C -1 ; WX 444 ; N kcommaaccent ; B 14 -187 461 683 ; C -1 ; WX 675 ; N minus ; B 86 220 590 286 ; C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ; C -1 ; WX 500 ; N ncaron ; B 14 -9 510 661 ; C -1 ; WX 278 ; N tcommaaccent ; B 2 -217 296 546 ; C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ; C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ; C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ; C -1 ; WX 549 ; N notequal ; B 12 -29 537 541 ; C -1 ; WX 500 ; N gcommaaccent ; B 8 -206 472 706 ; C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ; C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ; C -1 ; WX 500 ; N ncommaaccent ; B 14 -187 474 441 ; C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ; C -1 ; WX 278 ; N imacron ; B 46 -11 311 583 ; C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2321 KPX A C -30 KPX A Cacute -30 KPX A Ccaron -30 KPX A Ccedilla -30 KPX A G -35 KPX A Gbreve -35 KPX A Gcommaaccent -35 KPX A O -40 KPX A Oacute -40 KPX A Ocircumflex -40 KPX A Odieresis -40 KPX A Ograve -40 KPX A Ohungarumlaut -40 KPX A Omacron -40 KPX A Oslash -40 KPX A Otilde -40 KPX A Q -40 KPX A T -37 KPX A Tcaron -37 KPX A Tcommaaccent -37 KPX A U -50 KPX A Uacute -50 KPX A Ucircumflex -50 KPX A Udieresis -50 KPX A Ugrave -50 KPX A Uhungarumlaut -50 KPX A Umacron -50 KPX A Uogonek -50 KPX A Uring -50 KPX A V -105 KPX A W -95 KPX A Y -55 KPX A Yacute -55 KPX A Ydieresis -55 KPX A quoteright -37 KPX A u -20 KPX A uacute -20 KPX A ucircumflex -20 KPX A udieresis -20 KPX A ugrave -20 KPX A uhungarumlaut -20 KPX A umacron -20 KPX A uogonek -20 KPX A uring -20 KPX A v -55 KPX A w -55 KPX A y -55 KPX A yacute -55 KPX A ydieresis -55 KPX Aacute C -30 KPX Aacute Cacute -30 KPX Aacute Ccaron -30 KPX Aacute Ccedilla -30 KPX Aacute G -35 KPX Aacute Gbreve -35 KPX Aacute Gcommaaccent -35 KPX Aacute O -40 KPX Aacute Oacute -40 KPX Aacute Ocircumflex -40 KPX Aacute Odieresis -40 KPX Aacute Ograve -40 KPX Aacute Ohungarumlaut -40 KPX Aacute Omacron -40 KPX Aacute Oslash -40 KPX Aacute Otilde -40 KPX Aacute Q -40 KPX Aacute T -37 KPX Aacute Tcaron -37 KPX Aacute Tcommaaccent -37 KPX Aacute U -50 KPX Aacute Uacute -50 KPX Aacute Ucircumflex -50 KPX Aacute Udieresis -50 KPX Aacute Ugrave -50 KPX Aacute Uhungarumlaut -50 KPX Aacute Umacron -50 KPX Aacute Uogonek -50 KPX Aacute Uring -50 KPX Aacute V -105 KPX Aacute W -95 KPX Aacute Y -55 KPX Aacute Yacute -55 KPX Aacute Ydieresis -55 KPX Aacute quoteright -37 KPX Aacute u -20 KPX Aacute uacute -20 KPX Aacute ucircumflex -20 KPX Aacute udieresis -20 KPX Aacute ugrave -20 KPX Aacute uhungarumlaut -20 KPX Aacute umacron -20 KPX Aacute uogonek -20 KPX Aacute uring -20 KPX Aacute v -55 KPX Aacute w -55 KPX Aacute y -55 KPX Aacute yacute -55 KPX Aacute ydieresis -55 KPX Abreve C -30 KPX Abreve Cacute -30 KPX Abreve Ccaron -30 KPX Abreve Ccedilla -30 KPX Abreve G -35 KPX Abreve Gbreve -35 KPX Abreve Gcommaaccent -35 KPX Abreve O -40 KPX Abreve Oacute -40 KPX Abreve Ocircumflex -40 KPX Abreve Odieresis -40 KPX Abreve Ograve -40 KPX Abreve Ohungarumlaut -40 KPX Abreve Omacron -40 KPX Abreve Oslash -40 KPX Abreve Otilde -40 KPX Abreve Q -40 KPX Abreve T -37 KPX Abreve Tcaron -37 KPX Abreve Tcommaaccent -37 KPX Abreve U -50 KPX Abreve Uacute -50 KPX Abreve Ucircumflex -50 KPX Abreve Udieresis -50 KPX Abreve Ugrave -50 KPX Abreve Uhungarumlaut -50 KPX Abreve Umacron -50 KPX Abreve Uogonek -50 KPX Abreve Uring -50 KPX Abreve V -105 KPX Abreve W -95 KPX Abreve Y -55 KPX Abreve Yacute -55 KPX Abreve Ydieresis -55 KPX Abreve quoteright -37 KPX Abreve u -20 KPX Abreve uacute -20 KPX Abreve ucircumflex -20 KPX Abreve udieresis -20 KPX Abreve ugrave -20 KPX Abreve uhungarumlaut -20 KPX Abreve umacron -20 KPX Abreve uogonek -20 KPX Abreve uring -20 KPX Abreve v -55 KPX Abreve w -55 KPX Abreve y -55 KPX Abreve yacute -55 KPX Abreve ydieresis -55 KPX Acircumflex C -30 KPX Acircumflex Cacute -30 KPX Acircumflex Ccaron -30 KPX Acircumflex Ccedilla -30 KPX Acircumflex G -35 KPX Acircumflex Gbreve -35 KPX Acircumflex Gcommaaccent -35 KPX Acircumflex O -40 KPX Acircumflex Oacute -40 KPX Acircumflex Ocircumflex -40 KPX Acircumflex Odieresis -40 KPX Acircumflex Ograve -40 KPX Acircumflex Ohungarumlaut -40 KPX Acircumflex Omacron -40 KPX Acircumflex Oslash -40 KPX Acircumflex Otilde -40 KPX Acircumflex Q -40 KPX Acircumflex T -37 KPX Acircumflex Tcaron -37 KPX Acircumflex Tcommaaccent -37 KPX Acircumflex U -50 KPX Acircumflex Uacute -50 KPX Acircumflex Ucircumflex -50 KPX Acircumflex Udieresis -50 KPX Acircumflex Ugrave -50 KPX Acircumflex Uhungarumlaut -50 KPX Acircumflex Umacron -50 KPX Acircumflex Uogonek -50 KPX Acircumflex Uring -50 KPX Acircumflex V -105 KPX Acircumflex W -95 KPX Acircumflex Y -55 KPX Acircumflex Yacute -55 KPX Acircumflex Ydieresis -55 KPX Acircumflex quoteright -37 KPX Acircumflex u -20 KPX Acircumflex uacute -20 KPX Acircumflex ucircumflex -20 KPX Acircumflex udieresis -20 KPX Acircumflex ugrave -20 KPX Acircumflex uhungarumlaut -20 KPX Acircumflex umacron -20 KPX Acircumflex uogonek -20 KPX Acircumflex uring -20 KPX Acircumflex v -55 KPX Acircumflex w -55 KPX Acircumflex y -55 KPX Acircumflex yacute -55 KPX Acircumflex ydieresis -55 KPX Adieresis C -30 KPX Adieresis Cacute -30 KPX Adieresis Ccaron -30 KPX Adieresis Ccedilla -30 KPX Adieresis G -35 KPX Adieresis Gbreve -35 KPX Adieresis Gcommaaccent -35 KPX Adieresis O -40 KPX Adieresis Oacute -40 KPX Adieresis Ocircumflex -40 KPX Adieresis Odieresis -40 KPX Adieresis Ograve -40 KPX Adieresis Ohungarumlaut -40 KPX Adieresis Omacron -40 KPX Adieresis Oslash -40 KPX Adieresis Otilde -40 KPX Adieresis Q -40 KPX Adieresis T -37 KPX Adieresis Tcaron -37 KPX Adieresis Tcommaaccent -37 KPX Adieresis U -50 KPX Adieresis Uacute -50 KPX Adieresis Ucircumflex -50 KPX Adieresis Udieresis -50 KPX Adieresis Ugrave -50 KPX Adieresis Uhungarumlaut -50 KPX Adieresis Umacron -50 KPX Adieresis Uogonek -50 KPX Adieresis Uring -50 KPX Adieresis V -105 KPX Adieresis W -95 KPX Adieresis Y -55 KPX Adieresis Yacute -55 KPX Adieresis Ydieresis -55 KPX Adieresis quoteright -37 KPX Adieresis u -20 KPX Adieresis uacute -20 KPX Adieresis ucircumflex -20 KPX Adieresis udieresis -20 KPX Adieresis ugrave -20 KPX Adieresis uhungarumlaut -20 KPX Adieresis umacron -20 KPX Adieresis uogonek -20 KPX Adieresis uring -20 KPX Adieresis v -55 KPX Adieresis w -55 KPX Adieresis y -55 KPX Adieresis yacute -55 KPX Adieresis ydieresis -55 KPX Agrave C -30 KPX Agrave Cacute -30 KPX Agrave Ccaron -30 KPX Agrave Ccedilla -30 KPX Agrave G -35 KPX Agrave Gbreve -35 KPX Agrave Gcommaaccent -35 KPX Agrave O -40 KPX Agrave Oacute -40 KPX Agrave Ocircumflex -40 KPX Agrave Odieresis -40 KPX Agrave Ograve -40 KPX Agrave Ohungarumlaut -40 KPX Agrave Omacron -40 KPX Agrave Oslash -40 KPX Agrave Otilde -40 KPX Agrave Q -40 KPX Agrave T -37 KPX Agrave Tcaron -37 KPX Agrave Tcommaaccent -37 KPX Agrave U -50 KPX Agrave Uacute -50 KPX Agrave Ucircumflex -50 KPX Agrave Udieresis -50 KPX Agrave Ugrave -50 KPX Agrave Uhungarumlaut -50 KPX Agrave Umacron -50 KPX Agrave Uogonek -50 KPX Agrave Uring -50 KPX Agrave V -105 KPX Agrave W -95 KPX Agrave Y -55 KPX Agrave Yacute -55 KPX Agrave Ydieresis -55 KPX Agrave quoteright -37 KPX Agrave u -20 KPX Agrave uacute -20 KPX Agrave ucircumflex -20 KPX Agrave udieresis -20 KPX Agrave ugrave -20 KPX Agrave uhungarumlaut -20 KPX Agrave umacron -20 KPX Agrave uogonek -20 KPX Agrave uring -20 KPX Agrave v -55 KPX Agrave w -55 KPX Agrave y -55 KPX Agrave yacute -55 KPX Agrave ydieresis -55 KPX Amacron C -30 KPX Amacron Cacute -30 KPX Amacron Ccaron -30 KPX Amacron Ccedilla -30 KPX Amacron G -35 KPX Amacron Gbreve -35 KPX Amacron Gcommaaccent -35 KPX Amacron O -40 KPX Amacron Oacute -40 KPX Amacron Ocircumflex -40 KPX Amacron Odieresis -40 KPX Amacron Ograve -40 KPX Amacron Ohungarumlaut -40 KPX Amacron Omacron -40 KPX Amacron Oslash -40 KPX Amacron Otilde -40 KPX Amacron Q -40 KPX Amacron T -37 KPX Amacron Tcaron -37 KPX Amacron Tcommaaccent -37 KPX Amacron U -50 KPX Amacron Uacute -50 KPX Amacron Ucircumflex -50 KPX Amacron Udieresis -50 KPX Amacron Ugrave -50 KPX Amacron Uhungarumlaut -50 KPX Amacron Umacron -50 KPX Amacron Uogonek -50 KPX Amacron Uring -50 KPX Amacron V -105 KPX Amacron W -95 KPX Amacron Y -55 KPX Amacron Yacute -55 KPX Amacron Ydieresis -55 KPX Amacron quoteright -37 KPX Amacron u -20 KPX Amacron uacute -20 KPX Amacron ucircumflex -20 KPX Amacron udieresis -20 KPX Amacron ugrave -20 KPX Amacron uhungarumlaut -20 KPX Amacron umacron -20 KPX Amacron uogonek -20 KPX Amacron uring -20 KPX Amacron v -55 KPX Amacron w -55 KPX Amacron y -55 KPX Amacron yacute -55 KPX Amacron ydieresis -55 KPX Aogonek C -30 KPX Aogonek Cacute -30 KPX Aogonek Ccaron -30 KPX Aogonek Ccedilla -30 KPX Aogonek G -35 KPX Aogonek Gbreve -35 KPX Aogonek Gcommaaccent -35 KPX Aogonek O -40 KPX Aogonek Oacute -40 KPX Aogonek Ocircumflex -40 KPX Aogonek Odieresis -40 KPX Aogonek Ograve -40 KPX Aogonek Ohungarumlaut -40 KPX Aogonek Omacron -40 KPX Aogonek Oslash -40 KPX Aogonek Otilde -40 KPX Aogonek Q -40 KPX Aogonek T -37 KPX Aogonek Tcaron -37 KPX Aogonek Tcommaaccent -37 KPX Aogonek U -50 KPX Aogonek Uacute -50 KPX Aogonek Ucircumflex -50 KPX Aogonek Udieresis -50 KPX Aogonek Ugrave -50 KPX Aogonek Uhungarumlaut -50 KPX Aogonek Umacron -50 KPX Aogonek Uogonek -50 KPX Aogonek Uring -50 KPX Aogonek V -105 KPX Aogonek W -95 KPX Aogonek Y -55 KPX Aogonek Yacute -55 KPX Aogonek Ydieresis -55 KPX Aogonek quoteright -37 KPX Aogonek u -20 KPX Aogonek uacute -20 KPX Aogonek ucircumflex -20 KPX Aogonek udieresis -20 KPX Aogonek ugrave -20 KPX Aogonek uhungarumlaut -20 KPX Aogonek umacron -20 KPX Aogonek uogonek -20 KPX Aogonek uring -20 KPX Aogonek v -55 KPX Aogonek w -55 KPX Aogonek y -55 KPX Aogonek yacute -55 KPX Aogonek ydieresis -55 KPX Aring C -30 KPX Aring Cacute -30 KPX Aring Ccaron -30 KPX Aring Ccedilla -30 KPX Aring G -35 KPX Aring Gbreve -35 KPX Aring Gcommaaccent -35 KPX Aring O -40 KPX Aring Oacute -40 KPX Aring Ocircumflex -40 KPX Aring Odieresis -40 KPX Aring Ograve -40 KPX Aring Ohungarumlaut -40 KPX Aring Omacron -40 KPX Aring Oslash -40 KPX Aring Otilde -40 KPX Aring Q -40 KPX Aring T -37 KPX Aring Tcaron -37 KPX Aring Tcommaaccent -37 KPX Aring U -50 KPX Aring Uacute -50 KPX Aring Ucircumflex -50 KPX Aring Udieresis -50 KPX Aring Ugrave -50 KPX Aring Uhungarumlaut -50 KPX Aring Umacron -50 KPX Aring Uogonek -50 KPX Aring Uring -50 KPX Aring V -105 KPX Aring W -95 KPX Aring Y -55 KPX Aring Yacute -55 KPX Aring Ydieresis -55 KPX Aring quoteright -37 KPX Aring u -20 KPX Aring uacute -20 KPX Aring ucircumflex -20 KPX Aring udieresis -20 KPX Aring ugrave -20 KPX Aring uhungarumlaut -20 KPX Aring umacron -20 KPX Aring uogonek -20 KPX Aring uring -20 KPX Aring v -55 KPX Aring w -55 KPX Aring y -55 KPX Aring yacute -55 KPX Aring ydieresis -55 KPX Atilde C -30 KPX Atilde Cacute -30 KPX Atilde Ccaron -30 KPX Atilde Ccedilla -30 KPX Atilde G -35 KPX Atilde Gbreve -35 KPX Atilde Gcommaaccent -35 KPX Atilde O -40 KPX Atilde Oacute -40 KPX Atilde Ocircumflex -40 KPX Atilde Odieresis -40 KPX Atilde Ograve -40 KPX Atilde Ohungarumlaut -40 KPX Atilde Omacron -40 KPX Atilde Oslash -40 KPX Atilde Otilde -40 KPX Atilde Q -40 KPX Atilde T -37 KPX Atilde Tcaron -37 KPX Atilde Tcommaaccent -37 KPX Atilde U -50 KPX Atilde Uacute -50 KPX Atilde Ucircumflex -50 KPX Atilde Udieresis -50 KPX Atilde Ugrave -50 KPX Atilde Uhungarumlaut -50 KPX Atilde Umacron -50 KPX Atilde Uogonek -50 KPX Atilde Uring -50 KPX Atilde V -105 KPX Atilde W -95 KPX Atilde Y -55 KPX Atilde Yacute -55 KPX Atilde Ydieresis -55 KPX Atilde quoteright -37 KPX Atilde u -20 KPX Atilde uacute -20 KPX Atilde ucircumflex -20 KPX Atilde udieresis -20 KPX Atilde ugrave -20 KPX Atilde uhungarumlaut -20 KPX Atilde umacron -20 KPX Atilde uogonek -20 KPX Atilde uring -20 KPX Atilde v -55 KPX Atilde w -55 KPX Atilde y -55 KPX Atilde yacute -55 KPX Atilde ydieresis -55 KPX B A -25 KPX B Aacute -25 KPX B Abreve -25 KPX B Acircumflex -25 KPX B Adieresis -25 KPX B Agrave -25 KPX B Amacron -25 KPX B Aogonek -25 KPX B Aring -25 KPX B Atilde -25 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -35 KPX D Aacute -35 KPX D Abreve -35 KPX D Acircumflex -35 KPX D Adieresis -35 KPX D Agrave -35 KPX D Amacron -35 KPX D Aogonek -35 KPX D Aring -35 KPX D Atilde -35 KPX D V -40 KPX D W -40 KPX D Y -40 KPX D Yacute -40 KPX D Ydieresis -40 KPX Dcaron A -35 KPX Dcaron Aacute -35 KPX Dcaron Abreve -35 KPX Dcaron Acircumflex -35 KPX Dcaron Adieresis -35 KPX Dcaron Agrave -35 KPX Dcaron Amacron -35 KPX Dcaron Aogonek -35 KPX Dcaron Aring -35 KPX Dcaron Atilde -35 KPX Dcaron V -40 KPX Dcaron W -40 KPX Dcaron Y -40 KPX Dcaron Yacute -40 KPX Dcaron Ydieresis -40 KPX Dcroat A -35 KPX Dcroat Aacute -35 KPX Dcroat Abreve -35 KPX Dcroat Acircumflex -35 KPX Dcroat Adieresis -35 KPX Dcroat Agrave -35 KPX Dcroat Amacron -35 KPX Dcroat Aogonek -35 KPX Dcroat Aring -35 KPX Dcroat Atilde -35 KPX Dcroat V -40 KPX Dcroat W -40 KPX Dcroat Y -40 KPX Dcroat Yacute -40 KPX Dcroat Ydieresis -40 KPX F A -115 KPX F Aacute -115 KPX F Abreve -115 KPX F Acircumflex -115 KPX F Adieresis -115 KPX F Agrave -115 KPX F Amacron -115 KPX F Aogonek -115 KPX F Aring -115 KPX F Atilde -115 KPX F a -75 KPX F aacute -75 KPX F abreve -75 KPX F acircumflex -75 KPX F adieresis -75 KPX F agrave -75 KPX F amacron -75 KPX F aogonek -75 KPX F aring -75 KPX F atilde -75 KPX F comma -135 KPX F e -75 KPX F eacute -75 KPX F ecaron -75 KPX F ecircumflex -75 KPX F edieresis -75 KPX F edotaccent -75 KPX F egrave -75 KPX F emacron -75 KPX F eogonek -75 KPX F i -45 KPX F iacute -45 KPX F icircumflex -45 KPX F idieresis -45 KPX F igrave -45 KPX F imacron -45 KPX F iogonek -45 KPX F o -105 KPX F oacute -105 KPX F ocircumflex -105 KPX F odieresis -105 KPX F ograve -105 KPX F ohungarumlaut -105 KPX F omacron -105 KPX F oslash -105 KPX F otilde -105 KPX F period -135 KPX F r -55 KPX F racute -55 KPX F rcaron -55 KPX F rcommaaccent -55 KPX J A -40 KPX J Aacute -40 KPX J Abreve -40 KPX J Acircumflex -40 KPX J Adieresis -40 KPX J Agrave -40 KPX J Amacron -40 KPX J Aogonek -40 KPX J Aring -40 KPX J Atilde -40 KPX J a -35 KPX J aacute -35 KPX J abreve -35 KPX J acircumflex -35 KPX J adieresis -35 KPX J agrave -35 KPX J amacron -35 KPX J aogonek -35 KPX J aring -35 KPX J atilde -35 KPX J comma -25 KPX J e -25 KPX J eacute -25 KPX J ecaron -25 KPX J ecircumflex -25 KPX J edieresis -25 KPX J edotaccent -25 KPX J egrave -25 KPX J emacron -25 KPX J eogonek -25 KPX J o -25 KPX J oacute -25 KPX J ocircumflex -25 KPX J odieresis -25 KPX J ograve -25 KPX J ohungarumlaut -25 KPX J omacron -25 KPX J oslash -25 KPX J otilde -25 KPX J period -25 KPX J u -35 KPX J uacute -35 KPX J ucircumflex -35 KPX J udieresis -35 KPX J ugrave -35 KPX J uhungarumlaut -35 KPX J umacron -35 KPX J uogonek -35 KPX J uring -35 KPX K O -50 KPX K Oacute -50 KPX K Ocircumflex -50 KPX K Odieresis -50 KPX K Ograve -50 KPX K Ohungarumlaut -50 KPX K Omacron -50 KPX K Oslash -50 KPX K Otilde -50 KPX K e -35 KPX K eacute -35 KPX K ecaron -35 KPX K ecircumflex -35 KPX K edieresis -35 KPX K edotaccent -35 KPX K egrave -35 KPX K emacron -35 KPX K eogonek -35 KPX K o -40 KPX K oacute -40 KPX K ocircumflex -40 KPX K odieresis -40 KPX K ograve -40 KPX K ohungarumlaut -40 KPX K omacron -40 KPX K oslash -40 KPX K otilde -40 KPX K u -40 KPX K uacute -40 KPX K ucircumflex -40 KPX K udieresis -40 KPX K ugrave -40 KPX K uhungarumlaut -40 KPX K umacron -40 KPX K uogonek -40 KPX K uring -40 KPX K y -40 KPX K yacute -40 KPX K ydieresis -40 KPX Kcommaaccent O -50 KPX Kcommaaccent Oacute -50 KPX Kcommaaccent Ocircumflex -50 KPX Kcommaaccent Odieresis -50 KPX Kcommaaccent Ograve -50 KPX Kcommaaccent Ohungarumlaut -50 KPX Kcommaaccent Omacron -50 KPX Kcommaaccent Oslash -50 KPX Kcommaaccent Otilde -50 KPX Kcommaaccent e -35 KPX Kcommaaccent eacute -35 KPX Kcommaaccent ecaron -35 KPX Kcommaaccent ecircumflex -35 KPX Kcommaaccent edieresis -35 KPX Kcommaaccent edotaccent -35 KPX Kcommaaccent egrave -35 KPX Kcommaaccent emacron -35 KPX Kcommaaccent eogonek -35 KPX Kcommaaccent o -40 KPX Kcommaaccent oacute -40 KPX Kcommaaccent ocircumflex -40 KPX Kcommaaccent odieresis -40 KPX Kcommaaccent ograve -40 KPX Kcommaaccent ohungarumlaut -40 KPX Kcommaaccent omacron -40 KPX Kcommaaccent oslash -40 KPX Kcommaaccent otilde -40 KPX Kcommaaccent u -40 KPX Kcommaaccent uacute -40 KPX Kcommaaccent ucircumflex -40 KPX Kcommaaccent udieresis -40 KPX Kcommaaccent ugrave -40 KPX Kcommaaccent uhungarumlaut -40 KPX Kcommaaccent umacron -40 KPX Kcommaaccent uogonek -40 KPX Kcommaaccent uring -40 KPX Kcommaaccent y -40 KPX Kcommaaccent yacute -40 KPX Kcommaaccent ydieresis -40 KPX L T -20 KPX L Tcaron -20 KPX L Tcommaaccent -20 KPX L V -55 KPX L W -55 KPX L Y -20 KPX L Yacute -20 KPX L Ydieresis -20 KPX L quoteright -37 KPX L y -30 KPX L yacute -30 KPX L ydieresis -30 KPX Lacute T -20 KPX Lacute Tcaron -20 KPX Lacute Tcommaaccent -20 KPX Lacute V -55 KPX Lacute W -55 KPX Lacute Y -20 KPX Lacute Yacute -20 KPX Lacute Ydieresis -20 KPX Lacute quoteright -37 KPX Lacute y -30 KPX Lacute yacute -30 KPX Lacute ydieresis -30 KPX Lcommaaccent T -20 KPX Lcommaaccent Tcaron -20 KPX Lcommaaccent Tcommaaccent -20 KPX Lcommaaccent V -55 KPX Lcommaaccent W -55 KPX Lcommaaccent Y -20 KPX Lcommaaccent Yacute -20 KPX Lcommaaccent Ydieresis -20 KPX Lcommaaccent quoteright -37 KPX Lcommaaccent y -30 KPX Lcommaaccent yacute -30 KPX Lcommaaccent ydieresis -30 KPX Lslash T -20 KPX Lslash Tcaron -20 KPX Lslash Tcommaaccent -20 KPX Lslash V -55 KPX Lslash W -55 KPX Lslash Y -20 KPX Lslash Yacute -20 KPX Lslash Ydieresis -20 KPX Lslash quoteright -37 KPX Lslash y -30 KPX Lslash yacute -30 KPX Lslash ydieresis -30 KPX N A -27 KPX N Aacute -27 KPX N Abreve -27 KPX N Acircumflex -27 KPX N Adieresis -27 KPX N Agrave -27 KPX N Amacron -27 KPX N Aogonek -27 KPX N Aring -27 KPX N Atilde -27 KPX Nacute A -27 KPX Nacute Aacute -27 KPX Nacute Abreve -27 KPX Nacute Acircumflex -27 KPX Nacute Adieresis -27 KPX Nacute Agrave -27 KPX Nacute Amacron -27 KPX Nacute Aogonek -27 KPX Nacute Aring -27 KPX Nacute Atilde -27 KPX Ncaron A -27 KPX Ncaron Aacute -27 KPX Ncaron Abreve -27 KPX Ncaron Acircumflex -27 KPX Ncaron Adieresis -27 KPX Ncaron Agrave -27 KPX Ncaron Amacron -27 KPX Ncaron Aogonek -27 KPX Ncaron Aring -27 KPX Ncaron Atilde -27 KPX Ncommaaccent A -27 KPX Ncommaaccent Aacute -27 KPX Ncommaaccent Abreve -27 KPX Ncommaaccent Acircumflex -27 KPX Ncommaaccent Adieresis -27 KPX Ncommaaccent Agrave -27 KPX Ncommaaccent Amacron -27 KPX Ncommaaccent Aogonek -27 KPX Ncommaaccent Aring -27 KPX Ncommaaccent Atilde -27 KPX Ntilde A -27 KPX Ntilde Aacute -27 KPX Ntilde Abreve -27 KPX Ntilde Acircumflex -27 KPX Ntilde Adieresis -27 KPX Ntilde Agrave -27 KPX Ntilde Amacron -27 KPX Ntilde Aogonek -27 KPX Ntilde Aring -27 KPX Ntilde Atilde -27 KPX O A -55 KPX O Aacute -55 KPX O Abreve -55 KPX O Acircumflex -55 KPX O Adieresis -55 KPX O Agrave -55 KPX O Amacron -55 KPX O Aogonek -55 KPX O Aring -55 KPX O Atilde -55 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -50 KPX O X -40 KPX O Y -50 KPX O Yacute -50 KPX O Ydieresis -50 KPX Oacute A -55 KPX Oacute Aacute -55 KPX Oacute Abreve -55 KPX Oacute Acircumflex -55 KPX Oacute Adieresis -55 KPX Oacute Agrave -55 KPX Oacute Amacron -55 KPX Oacute Aogonek -55 KPX Oacute Aring -55 KPX Oacute Atilde -55 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -50 KPX Oacute X -40 KPX Oacute Y -50 KPX Oacute Yacute -50 KPX Oacute Ydieresis -50 KPX Ocircumflex A -55 KPX Ocircumflex Aacute -55 KPX Ocircumflex Abreve -55 KPX Ocircumflex Acircumflex -55 KPX Ocircumflex Adieresis -55 KPX Ocircumflex Agrave -55 KPX Ocircumflex Amacron -55 KPX Ocircumflex Aogonek -55 KPX Ocircumflex Aring -55 KPX Ocircumflex Atilde -55 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -50 KPX Ocircumflex X -40 KPX Ocircumflex Y -50 KPX Ocircumflex Yacute -50 KPX Ocircumflex Ydieresis -50 KPX Odieresis A -55 KPX Odieresis Aacute -55 KPX Odieresis Abreve -55 KPX Odieresis Acircumflex -55 KPX Odieresis Adieresis -55 KPX Odieresis Agrave -55 KPX Odieresis Amacron -55 KPX Odieresis Aogonek -55 KPX Odieresis Aring -55 KPX Odieresis Atilde -55 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -50 KPX Odieresis X -40 KPX Odieresis Y -50 KPX Odieresis Yacute -50 KPX Odieresis Ydieresis -50 KPX Ograve A -55 KPX Ograve Aacute -55 KPX Ograve Abreve -55 KPX Ograve Acircumflex -55 KPX Ograve Adieresis -55 KPX Ograve Agrave -55 KPX Ograve Amacron -55 KPX Ograve Aogonek -55 KPX Ograve Aring -55 KPX Ograve Atilde -55 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -50 KPX Ograve X -40 KPX Ograve Y -50 KPX Ograve Yacute -50 KPX Ograve Ydieresis -50 KPX Ohungarumlaut A -55 KPX Ohungarumlaut Aacute -55 KPX Ohungarumlaut Abreve -55 KPX Ohungarumlaut Acircumflex -55 KPX Ohungarumlaut Adieresis -55 KPX Ohungarumlaut Agrave -55 KPX Ohungarumlaut Amacron -55 KPX Ohungarumlaut Aogonek -55 KPX Ohungarumlaut Aring -55 KPX Ohungarumlaut Atilde -55 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -50 KPX Ohungarumlaut X -40 KPX Ohungarumlaut Y -50 KPX Ohungarumlaut Yacute -50 KPX Ohungarumlaut Ydieresis -50 KPX Omacron A -55 KPX Omacron Aacute -55 KPX Omacron Abreve -55 KPX Omacron Acircumflex -55 KPX Omacron Adieresis -55 KPX Omacron Agrave -55 KPX Omacron Amacron -55 KPX Omacron Aogonek -55 KPX Omacron Aring -55 KPX Omacron Atilde -55 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -50 KPX Omacron X -40 KPX Omacron Y -50 KPX Omacron Yacute -50 KPX Omacron Ydieresis -50 KPX Oslash A -55 KPX Oslash Aacute -55 KPX Oslash Abreve -55 KPX Oslash Acircumflex -55 KPX Oslash Adieresis -55 KPX Oslash Agrave -55 KPX Oslash Amacron -55 KPX Oslash Aogonek -55 KPX Oslash Aring -55 KPX Oslash Atilde -55 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -50 KPX Oslash X -40 KPX Oslash Y -50 KPX Oslash Yacute -50 KPX Oslash Ydieresis -50 KPX Otilde A -55 KPX Otilde Aacute -55 KPX Otilde Abreve -55 KPX Otilde Acircumflex -55 KPX Otilde Adieresis -55 KPX Otilde Agrave -55 KPX Otilde Amacron -55 KPX Otilde Aogonek -55 KPX Otilde Aring -55 KPX Otilde Atilde -55 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -50 KPX Otilde X -40 KPX Otilde Y -50 KPX Otilde Yacute -50 KPX Otilde Ydieresis -50 KPX P A -90 KPX P Aacute -90 KPX P Abreve -90 KPX P Acircumflex -90 KPX P Adieresis -90 KPX P Agrave -90 KPX P Amacron -90 KPX P Aogonek -90 KPX P Aring -90 KPX P Atilde -90 KPX P a -80 KPX P aacute -80 KPX P abreve -80 KPX P acircumflex -80 KPX P adieresis -80 KPX P agrave -80 KPX P amacron -80 KPX P aogonek -80 KPX P aring -80 KPX P atilde -80 KPX P comma -135 KPX P e -80 KPX P eacute -80 KPX P ecaron -80 KPX P ecircumflex -80 KPX P edieresis -80 KPX P edotaccent -80 KPX P egrave -80 KPX P emacron -80 KPX P eogonek -80 KPX P o -80 KPX P oacute -80 KPX P ocircumflex -80 KPX P odieresis -80 KPX P ograve -80 KPX P ohungarumlaut -80 KPX P omacron -80 KPX P oslash -80 KPX P otilde -80 KPX P period -135 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX R O -40 KPX R Oacute -40 KPX R Ocircumflex -40 KPX R Odieresis -40 KPX R Ograve -40 KPX R Ohungarumlaut -40 KPX R Omacron -40 KPX R Oslash -40 KPX R Otilde -40 KPX R U -40 KPX R Uacute -40 KPX R Ucircumflex -40 KPX R Udieresis -40 KPX R Ugrave -40 KPX R Uhungarumlaut -40 KPX R Umacron -40 KPX R Uogonek -40 KPX R Uring -40 KPX R V -18 KPX R W -18 KPX R Y -18 KPX R Yacute -18 KPX R Ydieresis -18 KPX Racute O -40 KPX Racute Oacute -40 KPX Racute Ocircumflex -40 KPX Racute Odieresis -40 KPX Racute Ograve -40 KPX Racute Ohungarumlaut -40 KPX Racute Omacron -40 KPX Racute Oslash -40 KPX Racute Otilde -40 KPX Racute U -40 KPX Racute Uacute -40 KPX Racute Ucircumflex -40 KPX Racute Udieresis -40 KPX Racute Ugrave -40 KPX Racute Uhungarumlaut -40 KPX Racute Umacron -40 KPX Racute Uogonek -40 KPX Racute Uring -40 KPX Racute V -18 KPX Racute W -18 KPX Racute Y -18 KPX Racute Yacute -18 KPX Racute Ydieresis -18 KPX Rcaron O -40 KPX Rcaron Oacute -40 KPX Rcaron Ocircumflex -40 KPX Rcaron Odieresis -40 KPX Rcaron Ograve -40 KPX Rcaron Ohungarumlaut -40 KPX Rcaron Omacron -40 KPX Rcaron Oslash -40 KPX Rcaron Otilde -40 KPX Rcaron U -40 KPX Rcaron Uacute -40 KPX Rcaron Ucircumflex -40 KPX Rcaron Udieresis -40 KPX Rcaron Ugrave -40 KPX Rcaron Uhungarumlaut -40 KPX Rcaron Umacron -40 KPX Rcaron Uogonek -40 KPX Rcaron Uring -40 KPX Rcaron V -18 KPX Rcaron W -18 KPX Rcaron Y -18 KPX Rcaron Yacute -18 KPX Rcaron Ydieresis -18 KPX Rcommaaccent O -40 KPX Rcommaaccent Oacute -40 KPX Rcommaaccent Ocircumflex -40 KPX Rcommaaccent Odieresis -40 KPX Rcommaaccent Ograve -40 KPX Rcommaaccent Ohungarumlaut -40 KPX Rcommaaccent Omacron -40 KPX Rcommaaccent Oslash -40 KPX Rcommaaccent Otilde -40 KPX Rcommaaccent U -40 KPX Rcommaaccent Uacute -40 KPX Rcommaaccent Ucircumflex -40 KPX Rcommaaccent Udieresis -40 KPX Rcommaaccent Ugrave -40 KPX Rcommaaccent Uhungarumlaut -40 KPX Rcommaaccent Umacron -40 KPX Rcommaaccent Uogonek -40 KPX Rcommaaccent Uring -40 KPX Rcommaaccent V -18 KPX Rcommaaccent W -18 KPX Rcommaaccent Y -18 KPX Rcommaaccent Yacute -18 KPX Rcommaaccent Ydieresis -18 KPX T A -50 KPX T Aacute -50 KPX T Abreve -50 KPX T Acircumflex -50 KPX T Adieresis -50 KPX T Agrave -50 KPX T Amacron -50 KPX T Aogonek -50 KPX T Aring -50 KPX T Atilde -50 KPX T O -18 KPX T Oacute -18 KPX T Ocircumflex -18 KPX T Odieresis -18 KPX T Ograve -18 KPX T Ohungarumlaut -18 KPX T Omacron -18 KPX T Oslash -18 KPX T Otilde -18 KPX T a -92 KPX T aacute -92 KPX T abreve -92 KPX T acircumflex -92 KPX T adieresis -92 KPX T agrave -92 KPX T amacron -92 KPX T aogonek -92 KPX T aring -92 KPX T atilde -92 KPX T colon -55 KPX T comma -74 KPX T e -92 KPX T eacute -92 KPX T ecaron -92 KPX T ecircumflex -52 KPX T edieresis -52 KPX T edotaccent -92 KPX T egrave -52 KPX T emacron -52 KPX T eogonek -92 KPX T hyphen -74 KPX T i -55 KPX T iacute -55 KPX T iogonek -55 KPX T o -92 KPX T oacute -92 KPX T ocircumflex -92 KPX T odieresis -92 KPX T ograve -92 KPX T ohungarumlaut -92 KPX T omacron -92 KPX T oslash -92 KPX T otilde -92 KPX T period -74 KPX T r -55 KPX T racute -55 KPX T rcaron -55 KPX T rcommaaccent -55 KPX T semicolon -65 KPX T u -55 KPX T uacute -55 KPX T ucircumflex -55 KPX T udieresis -55 KPX T ugrave -55 KPX T uhungarumlaut -55 KPX T umacron -55 KPX T uogonek -55 KPX T uring -55 KPX T w -74 KPX T y -74 KPX T yacute -74 KPX T ydieresis -34 KPX Tcaron A -50 KPX Tcaron Aacute -50 KPX Tcaron Abreve -50 KPX Tcaron Acircumflex -50 KPX Tcaron Adieresis -50 KPX Tcaron Agrave -50 KPX Tcaron Amacron -50 KPX Tcaron Aogonek -50 KPX Tcaron Aring -50 KPX Tcaron Atilde -50 KPX Tcaron O -18 KPX Tcaron Oacute -18 KPX Tcaron Ocircumflex -18 KPX Tcaron Odieresis -18 KPX Tcaron Ograve -18 KPX Tcaron Ohungarumlaut -18 KPX Tcaron Omacron -18 KPX Tcaron Oslash -18 KPX Tcaron Otilde -18 KPX Tcaron a -92 KPX Tcaron aacute -92 KPX Tcaron abreve -92 KPX Tcaron acircumflex -92 KPX Tcaron adieresis -92 KPX Tcaron agrave -92 KPX Tcaron amacron -92 KPX Tcaron aogonek -92 KPX Tcaron aring -92 KPX Tcaron atilde -92 KPX Tcaron colon -55 KPX Tcaron comma -74 KPX Tcaron e -92 KPX Tcaron eacute -92 KPX Tcaron ecaron -92 KPX Tcaron ecircumflex -52 KPX Tcaron edieresis -52 KPX Tcaron edotaccent -92 KPX Tcaron egrave -52 KPX Tcaron emacron -52 KPX Tcaron eogonek -92 KPX Tcaron hyphen -74 KPX Tcaron i -55 KPX Tcaron iacute -55 KPX Tcaron iogonek -55 KPX Tcaron o -92 KPX Tcaron oacute -92 KPX Tcaron ocircumflex -92 KPX Tcaron odieresis -92 KPX Tcaron ograve -92 KPX Tcaron ohungarumlaut -92 KPX Tcaron omacron -92 KPX Tcaron oslash -92 KPX Tcaron otilde -92 KPX Tcaron period -74 KPX Tcaron r -55 KPX Tcaron racute -55 KPX Tcaron rcaron -55 KPX Tcaron rcommaaccent -55 KPX Tcaron semicolon -65 KPX Tcaron u -55 KPX Tcaron uacute -55 KPX Tcaron ucircumflex -55 KPX Tcaron udieresis -55 KPX Tcaron ugrave -55 KPX Tcaron uhungarumlaut -55 KPX Tcaron umacron -55 KPX Tcaron uogonek -55 KPX Tcaron uring -55 KPX Tcaron w -74 KPX Tcaron y -74 KPX Tcaron yacute -74 KPX Tcaron ydieresis -34 KPX Tcommaaccent A -50 KPX Tcommaaccent Aacute -50 KPX Tcommaaccent Abreve -50 KPX Tcommaaccent Acircumflex -50 KPX Tcommaaccent Adieresis -50 KPX Tcommaaccent Agrave -50 KPX Tcommaaccent Amacron -50 KPX Tcommaaccent Aogonek -50 KPX Tcommaaccent Aring -50 KPX Tcommaaccent Atilde -50 KPX Tcommaaccent O -18 KPX Tcommaaccent Oacute -18 KPX Tcommaaccent Ocircumflex -18 KPX Tcommaaccent Odieresis -18 KPX Tcommaaccent Ograve -18 KPX Tcommaaccent Ohungarumlaut -18 KPX Tcommaaccent Omacron -18 KPX Tcommaaccent Oslash -18 KPX Tcommaaccent Otilde -18 KPX Tcommaaccent a -92 KPX Tcommaaccent aacute -92 KPX Tcommaaccent abreve -92 KPX Tcommaaccent acircumflex -92 KPX Tcommaaccent adieresis -92 KPX Tcommaaccent agrave -92 KPX Tcommaaccent amacron -92 KPX Tcommaaccent aogonek -92 KPX Tcommaaccent aring -92 KPX Tcommaaccent atilde -92 KPX Tcommaaccent colon -55 KPX Tcommaaccent comma -74 KPX Tcommaaccent e -92 KPX Tcommaaccent eacute -92 KPX Tcommaaccent ecaron -92 KPX Tcommaaccent ecircumflex -52 KPX Tcommaaccent edieresis -52 KPX Tcommaaccent edotaccent -92 KPX Tcommaaccent egrave -52 KPX Tcommaaccent emacron -52 KPX Tcommaaccent eogonek -92 KPX Tcommaaccent hyphen -74 KPX Tcommaaccent i -55 KPX Tcommaaccent iacute -55 KPX Tcommaaccent iogonek -55 KPX Tcommaaccent o -92 KPX Tcommaaccent oacute -92 KPX Tcommaaccent ocircumflex -92 KPX Tcommaaccent odieresis -92 KPX Tcommaaccent ograve -92 KPX Tcommaaccent ohungarumlaut -92 KPX Tcommaaccent omacron -92 KPX Tcommaaccent oslash -92 KPX Tcommaaccent otilde -92 KPX Tcommaaccent period -74 KPX Tcommaaccent r -55 KPX Tcommaaccent racute -55 KPX Tcommaaccent rcaron -55 KPX Tcommaaccent rcommaaccent -55 KPX Tcommaaccent semicolon -65 KPX Tcommaaccent u -55 KPX Tcommaaccent uacute -55 KPX Tcommaaccent ucircumflex -55 KPX Tcommaaccent udieresis -55 KPX Tcommaaccent ugrave -55 KPX Tcommaaccent uhungarumlaut -55 KPX Tcommaaccent umacron -55 KPX Tcommaaccent uogonek -55 KPX Tcommaaccent uring -55 KPX Tcommaaccent w -74 KPX Tcommaaccent y -74 KPX Tcommaaccent yacute -74 KPX Tcommaaccent ydieresis -34 KPX U A -40 KPX U Aacute -40 KPX U Abreve -40 KPX U Acircumflex -40 KPX U Adieresis -40 KPX U Agrave -40 KPX U Amacron -40 KPX U Aogonek -40 KPX U Aring -40 KPX U Atilde -40 KPX U comma -25 KPX U period -25 KPX Uacute A -40 KPX Uacute Aacute -40 KPX Uacute Abreve -40 KPX Uacute Acircumflex -40 KPX Uacute Adieresis -40 KPX Uacute Agrave -40 KPX Uacute Amacron -40 KPX Uacute Aogonek -40 KPX Uacute Aring -40 KPX Uacute Atilde -40 KPX Uacute comma -25 KPX Uacute period -25 KPX Ucircumflex A -40 KPX Ucircumflex Aacute -40 KPX Ucircumflex Abreve -40 KPX Ucircumflex Acircumflex -40 KPX Ucircumflex Adieresis -40 KPX Ucircumflex Agrave -40 KPX Ucircumflex Amacron -40 KPX Ucircumflex Aogonek -40 KPX Ucircumflex Aring -40 KPX Ucircumflex Atilde -40 KPX Ucircumflex comma -25 KPX Ucircumflex period -25 KPX Udieresis A -40 KPX Udieresis Aacute -40 KPX Udieresis Abreve -40 KPX Udieresis Acircumflex -40 KPX Udieresis Adieresis -40 KPX Udieresis Agrave -40 KPX Udieresis Amacron -40 KPX Udieresis Aogonek -40 KPX Udieresis Aring -40 KPX Udieresis Atilde -40 KPX Udieresis comma -25 KPX Udieresis period -25 KPX Ugrave A -40 KPX Ugrave Aacute -40 KPX Ugrave Abreve -40 KPX Ugrave Acircumflex -40 KPX Ugrave Adieresis -40 KPX Ugrave Agrave -40 KPX Ugrave Amacron -40 KPX Ugrave Aogonek -40 KPX Ugrave Aring -40 KPX Ugrave Atilde -40 KPX Ugrave comma -25 KPX Ugrave period -25 KPX Uhungarumlaut A -40 KPX Uhungarumlaut Aacute -40 KPX Uhungarumlaut Abreve -40 KPX Uhungarumlaut Acircumflex -40 KPX Uhungarumlaut Adieresis -40 KPX Uhungarumlaut Agrave -40 KPX Uhungarumlaut Amacron -40 KPX Uhungarumlaut Aogonek -40 KPX Uhungarumlaut Aring -40 KPX Uhungarumlaut Atilde -40 KPX Uhungarumlaut comma -25 KPX Uhungarumlaut period -25 KPX Umacron A -40 KPX Umacron Aacute -40 KPX Umacron Abreve -40 KPX Umacron Acircumflex -40 KPX Umacron Adieresis -40 KPX Umacron Agrave -40 KPX Umacron Amacron -40 KPX Umacron Aogonek -40 KPX Umacron Aring -40 KPX Umacron Atilde -40 KPX Umacron comma -25 KPX Umacron period -25 KPX Uogonek A -40 KPX Uogonek Aacute -40 KPX Uogonek Abreve -40 KPX Uogonek Acircumflex -40 KPX Uogonek Adieresis -40 KPX Uogonek Agrave -40 KPX Uogonek Amacron -40 KPX Uogonek Aogonek -40 KPX Uogonek Aring -40 KPX Uogonek Atilde -40 KPX Uogonek comma -25 KPX Uogonek period -25 KPX Uring A -40 KPX Uring Aacute -40 KPX Uring Abreve -40 KPX Uring Acircumflex -40 KPX Uring Adieresis -40 KPX Uring Agrave -40 KPX Uring Amacron -40 KPX Uring Aogonek -40 KPX Uring Aring -40 KPX Uring Atilde -40 KPX Uring comma -25 KPX Uring period -25 KPX V A -60 KPX V Aacute -60 KPX V Abreve -60 KPX V Acircumflex -60 KPX V Adieresis -60 KPX V Agrave -60 KPX V Amacron -60 KPX V Aogonek -60 KPX V Aring -60 KPX V Atilde -60 KPX V O -30 KPX V Oacute -30 KPX V Ocircumflex -30 KPX V Odieresis -30 KPX V Ograve -30 KPX V Ohungarumlaut -30 KPX V Omacron -30 KPX V Oslash -30 KPX V Otilde -30 KPX V a -111 KPX V aacute -111 KPX V abreve -111 KPX V acircumflex -111 KPX V adieresis -111 KPX V agrave -111 KPX V amacron -111 KPX V aogonek -111 KPX V aring -111 KPX V atilde -111 KPX V colon -65 KPX V comma -129 KPX V e -111 KPX V eacute -111 KPX V ecaron -111 KPX V ecircumflex -111 KPX V edieresis -71 KPX V edotaccent -111 KPX V egrave -71 KPX V emacron -71 KPX V eogonek -111 KPX V hyphen -55 KPX V i -74 KPX V iacute -74 KPX V icircumflex -34 KPX V idieresis -34 KPX V igrave -34 KPX V imacron -34 KPX V iogonek -74 KPX V o -111 KPX V oacute -111 KPX V ocircumflex -111 KPX V odieresis -111 KPX V ograve -111 KPX V ohungarumlaut -111 KPX V omacron -111 KPX V oslash -111 KPX V otilde -111 KPX V period -129 KPX V semicolon -74 KPX V u -74 KPX V uacute -74 KPX V ucircumflex -74 KPX V udieresis -74 KPX V ugrave -74 KPX V uhungarumlaut -74 KPX V umacron -74 KPX V uogonek -74 KPX V uring -74 KPX W A -60 KPX W Aacute -60 KPX W Abreve -60 KPX W Acircumflex -60 KPX W Adieresis -60 KPX W Agrave -60 KPX W Amacron -60 KPX W Aogonek -60 KPX W Aring -60 KPX W Atilde -60 KPX W O -25 KPX W Oacute -25 KPX W Ocircumflex -25 KPX W Odieresis -25 KPX W Ograve -25 KPX W Ohungarumlaut -25 KPX W Omacron -25 KPX W Oslash -25 KPX W Otilde -25 KPX W a -92 KPX W aacute -92 KPX W abreve -92 KPX W acircumflex -92 KPX W adieresis -92 KPX W agrave -92 KPX W amacron -92 KPX W aogonek -92 KPX W aring -92 KPX W atilde -92 KPX W colon -65 KPX W comma -92 KPX W e -92 KPX W eacute -92 KPX W ecaron -92 KPX W ecircumflex -92 KPX W edieresis -52 KPX W edotaccent -92 KPX W egrave -52 KPX W emacron -52 KPX W eogonek -92 KPX W hyphen -37 KPX W i -55 KPX W iacute -55 KPX W iogonek -55 KPX W o -92 KPX W oacute -92 KPX W ocircumflex -92 KPX W odieresis -92 KPX W ograve -92 KPX W ohungarumlaut -92 KPX W omacron -92 KPX W oslash -92 KPX W otilde -92 KPX W period -92 KPX W semicolon -65 KPX W u -55 KPX W uacute -55 KPX W ucircumflex -55 KPX W udieresis -55 KPX W ugrave -55 KPX W uhungarumlaut -55 KPX W umacron -55 KPX W uogonek -55 KPX W uring -55 KPX W y -70 KPX W yacute -70 KPX W ydieresis -70 KPX Y A -50 KPX Y Aacute -50 KPX Y Abreve -50 KPX Y Acircumflex -50 KPX Y Adieresis -50 KPX Y Agrave -50 KPX Y Amacron -50 KPX Y Aogonek -50 KPX Y Aring -50 KPX Y Atilde -50 KPX Y O -15 KPX Y Oacute -15 KPX Y Ocircumflex -15 KPX Y Odieresis -15 KPX Y Ograve -15 KPX Y Ohungarumlaut -15 KPX Y Omacron -15 KPX Y Oslash -15 KPX Y Otilde -15 KPX Y a -92 KPX Y aacute -92 KPX Y abreve -92 KPX Y acircumflex -92 KPX Y adieresis -92 KPX Y agrave -92 KPX Y amacron -92 KPX Y aogonek -92 KPX Y aring -92 KPX Y atilde -92 KPX Y colon -65 KPX Y comma -92 KPX Y e -92 KPX Y eacute -92 KPX Y ecaron -92 KPX Y ecircumflex -92 KPX Y edieresis -52 KPX Y edotaccent -92 KPX Y egrave -52 KPX Y emacron -52 KPX Y eogonek -92 KPX Y hyphen -74 KPX Y i -74 KPX Y iacute -74 KPX Y icircumflex -34 KPX Y idieresis -34 KPX Y igrave -34 KPX Y imacron -34 KPX Y iogonek -74 KPX Y o -92 KPX Y oacute -92 KPX Y ocircumflex -92 KPX Y odieresis -92 KPX Y ograve -92 KPX Y ohungarumlaut -92 KPX Y omacron -92 KPX Y oslash -92 KPX Y otilde -92 KPX Y period -92 KPX Y semicolon -65 KPX Y u -92 KPX Y uacute -92 KPX Y ucircumflex -92 KPX Y udieresis -92 KPX Y ugrave -92 KPX Y uhungarumlaut -92 KPX Y umacron -92 KPX Y uogonek -92 KPX Y uring -92 KPX Yacute A -50 KPX Yacute Aacute -50 KPX Yacute Abreve -50 KPX Yacute Acircumflex -50 KPX Yacute Adieresis -50 KPX Yacute Agrave -50 KPX Yacute Amacron -50 KPX Yacute Aogonek -50 KPX Yacute Aring -50 KPX Yacute Atilde -50 KPX Yacute O -15 KPX Yacute Oacute -15 KPX Yacute Ocircumflex -15 KPX Yacute Odieresis -15 KPX Yacute Ograve -15 KPX Yacute Ohungarumlaut -15 KPX Yacute Omacron -15 KPX Yacute Oslash -15 KPX Yacute Otilde -15 KPX Yacute a -92 KPX Yacute aacute -92 KPX Yacute abreve -92 KPX Yacute acircumflex -92 KPX Yacute adieresis -92 KPX Yacute agrave -92 KPX Yacute amacron -92 KPX Yacute aogonek -92 KPX Yacute aring -92 KPX Yacute atilde -92 KPX Yacute colon -65 KPX Yacute comma -92 KPX Yacute e -92 KPX Yacute eacute -92 KPX Yacute ecaron -92 KPX Yacute ecircumflex -92 KPX Yacute edieresis -52 KPX Yacute edotaccent -92 KPX Yacute egrave -52 KPX Yacute emacron -52 KPX Yacute eogonek -92 KPX Yacute hyphen -74 KPX Yacute i -74 KPX Yacute iacute -74 KPX Yacute icircumflex -34 KPX Yacute idieresis -34 KPX Yacute igrave -34 KPX Yacute imacron -34 KPX Yacute iogonek -74 KPX Yacute o -92 KPX Yacute oacute -92 KPX Yacute ocircumflex -92 KPX Yacute odieresis -92 KPX Yacute ograve -92 KPX Yacute ohungarumlaut -92 KPX Yacute omacron -92 KPX Yacute oslash -92 KPX Yacute otilde -92 KPX Yacute period -92 KPX Yacute semicolon -65 KPX Yacute u -92 KPX Yacute uacute -92 KPX Yacute ucircumflex -92 KPX Yacute udieresis -92 KPX Yacute ugrave -92 KPX Yacute uhungarumlaut -92 KPX Yacute umacron -92 KPX Yacute uogonek -92 KPX Yacute uring -92 KPX Ydieresis A -50 KPX Ydieresis Aacute -50 KPX Ydieresis Abreve -50 KPX Ydieresis Acircumflex -50 KPX Ydieresis Adieresis -50 KPX Ydieresis Agrave -50 KPX Ydieresis Amacron -50 KPX Ydieresis Aogonek -50 KPX Ydieresis Aring -50 KPX Ydieresis Atilde -50 KPX Ydieresis O -15 KPX Ydieresis Oacute -15 KPX Ydieresis Ocircumflex -15 KPX Ydieresis Odieresis -15 KPX Ydieresis Ograve -15 KPX Ydieresis Ohungarumlaut -15 KPX Ydieresis Omacron -15 KPX Ydieresis Oslash -15 KPX Ydieresis Otilde -15 KPX Ydieresis a -92 KPX Ydieresis aacute -92 KPX Ydieresis abreve -92 KPX Ydieresis acircumflex -92 KPX Ydieresis adieresis -92 KPX Ydieresis agrave -92 KPX Ydieresis amacron -92 KPX Ydieresis aogonek -92 KPX Ydieresis aring -92 KPX Ydieresis atilde -92 KPX Ydieresis colon -65 KPX Ydieresis comma -92 KPX Ydieresis e -92 KPX Ydieresis eacute -92 KPX Ydieresis ecaron -92 KPX Ydieresis ecircumflex -92 KPX Ydieresis edieresis -52 KPX Ydieresis edotaccent -92 KPX Ydieresis egrave -52 KPX Ydieresis emacron -52 KPX Ydieresis eogonek -92 KPX Ydieresis hyphen -74 KPX Ydieresis i -74 KPX Ydieresis iacute -74 KPX Ydieresis icircumflex -34 KPX Ydieresis idieresis -34 KPX Ydieresis igrave -34 KPX Ydieresis imacron -34 KPX Ydieresis iogonek -74 KPX Ydieresis o -92 KPX Ydieresis oacute -92 KPX Ydieresis ocircumflex -92 KPX Ydieresis odieresis -92 KPX Ydieresis ograve -92 KPX Ydieresis ohungarumlaut -92 KPX Ydieresis omacron -92 KPX Ydieresis oslash -92 KPX Ydieresis otilde -92 KPX Ydieresis period -92 KPX Ydieresis semicolon -65 KPX Ydieresis u -92 KPX Ydieresis uacute -92 KPX Ydieresis ucircumflex -92 KPX Ydieresis udieresis -92 KPX Ydieresis ugrave -92 KPX Ydieresis uhungarumlaut -92 KPX Ydieresis umacron -92 KPX Ydieresis uogonek -92 KPX Ydieresis uring -92 KPX a g -10 KPX a gbreve -10 KPX a gcommaaccent -10 KPX aacute g -10 KPX aacute gbreve -10 KPX aacute gcommaaccent -10 KPX abreve g -10 KPX abreve gbreve -10 KPX abreve gcommaaccent -10 KPX acircumflex g -10 KPX acircumflex gbreve -10 KPX acircumflex gcommaaccent -10 KPX adieresis g -10 KPX adieresis gbreve -10 KPX adieresis gcommaaccent -10 KPX agrave g -10 KPX agrave gbreve -10 KPX agrave gcommaaccent -10 KPX amacron g -10 KPX amacron gbreve -10 KPX amacron gcommaaccent -10 KPX aogonek g -10 KPX aogonek gbreve -10 KPX aogonek gcommaaccent -10 KPX aring g -10 KPX aring gbreve -10 KPX aring gcommaaccent -10 KPX atilde g -10 KPX atilde gbreve -10 KPX atilde gcommaaccent -10 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX c h -15 KPX c k -20 KPX c kcommaaccent -20 KPX cacute h -15 KPX cacute k -20 KPX cacute kcommaaccent -20 KPX ccaron h -15 KPX ccaron k -20 KPX ccaron kcommaaccent -20 KPX ccedilla h -15 KPX ccedilla k -20 KPX ccedilla kcommaaccent -20 KPX comma quotedblright -140 KPX comma quoteright -140 KPX e comma -10 KPX e g -40 KPX e gbreve -40 KPX e gcommaaccent -40 KPX e period -15 KPX e v -15 KPX e w -15 KPX e x -20 KPX e y -30 KPX e yacute -30 KPX e ydieresis -30 KPX eacute comma -10 KPX eacute g -40 KPX eacute gbreve -40 KPX eacute gcommaaccent -40 KPX eacute period -15 KPX eacute v -15 KPX eacute w -15 KPX eacute x -20 KPX eacute y -30 KPX eacute yacute -30 KPX eacute ydieresis -30 KPX ecaron comma -10 KPX ecaron g -40 KPX ecaron gbreve -40 KPX ecaron gcommaaccent -40 KPX ecaron period -15 KPX ecaron v -15 KPX ecaron w -15 KPX ecaron x -20 KPX ecaron y -30 KPX ecaron yacute -30 KPX ecaron ydieresis -30 KPX ecircumflex comma -10 KPX ecircumflex g -40 KPX ecircumflex gbreve -40 KPX ecircumflex gcommaaccent -40 KPX ecircumflex period -15 KPX ecircumflex v -15 KPX ecircumflex w -15 KPX ecircumflex x -20 KPX ecircumflex y -30 KPX ecircumflex yacute -30 KPX ecircumflex ydieresis -30 KPX edieresis comma -10 KPX edieresis g -40 KPX edieresis gbreve -40 KPX edieresis gcommaaccent -40 KPX edieresis period -15 KPX edieresis v -15 KPX edieresis w -15 KPX edieresis x -20 KPX edieresis y -30 KPX edieresis yacute -30 KPX edieresis ydieresis -30 KPX edotaccent comma -10 KPX edotaccent g -40 KPX edotaccent gbreve -40 KPX edotaccent gcommaaccent -40 KPX edotaccent period -15 KPX edotaccent v -15 KPX edotaccent w -15 KPX edotaccent x -20 KPX edotaccent y -30 KPX edotaccent yacute -30 KPX edotaccent ydieresis -30 KPX egrave comma -10 KPX egrave g -40 KPX egrave gbreve -40 KPX egrave gcommaaccent -40 KPX egrave period -15 KPX egrave v -15 KPX egrave w -15 KPX egrave x -20 KPX egrave y -30 KPX egrave yacute -30 KPX egrave ydieresis -30 KPX emacron comma -10 KPX emacron g -40 KPX emacron gbreve -40 KPX emacron gcommaaccent -40 KPX emacron period -15 KPX emacron v -15 KPX emacron w -15 KPX emacron x -20 KPX emacron y -30 KPX emacron yacute -30 KPX emacron ydieresis -30 KPX eogonek comma -10 KPX eogonek g -40 KPX eogonek gbreve -40 KPX eogonek gcommaaccent -40 KPX eogonek period -15 KPX eogonek v -15 KPX eogonek w -15 KPX eogonek x -20 KPX eogonek y -30 KPX eogonek yacute -30 KPX eogonek ydieresis -30 KPX f comma -10 KPX f dotlessi -60 KPX f f -18 KPX f i -20 KPX f iogonek -20 KPX f period -15 KPX f quoteright 92 KPX g comma -10 KPX g e -10 KPX g eacute -10 KPX g ecaron -10 KPX g ecircumflex -10 KPX g edieresis -10 KPX g edotaccent -10 KPX g egrave -10 KPX g emacron -10 KPX g eogonek -10 KPX g g -10 KPX g gbreve -10 KPX g gcommaaccent -10 KPX g period -15 KPX gbreve comma -10 KPX gbreve e -10 KPX gbreve eacute -10 KPX gbreve ecaron -10 KPX gbreve ecircumflex -10 KPX gbreve edieresis -10 KPX gbreve edotaccent -10 KPX gbreve egrave -10 KPX gbreve emacron -10 KPX gbreve eogonek -10 KPX gbreve g -10 KPX gbreve gbreve -10 KPX gbreve gcommaaccent -10 KPX gbreve period -15 KPX gcommaaccent comma -10 KPX gcommaaccent e -10 KPX gcommaaccent eacute -10 KPX gcommaaccent ecaron -10 KPX gcommaaccent ecircumflex -10 KPX gcommaaccent edieresis -10 KPX gcommaaccent edotaccent -10 KPX gcommaaccent egrave -10 KPX gcommaaccent emacron -10 KPX gcommaaccent eogonek -10 KPX gcommaaccent g -10 KPX gcommaaccent gbreve -10 KPX gcommaaccent gcommaaccent -10 KPX gcommaaccent period -15 KPX k e -10 KPX k eacute -10 KPX k ecaron -10 KPX k ecircumflex -10 KPX k edieresis -10 KPX k edotaccent -10 KPX k egrave -10 KPX k emacron -10 KPX k eogonek -10 KPX k o -10 KPX k oacute -10 KPX k ocircumflex -10 KPX k odieresis -10 KPX k ograve -10 KPX k ohungarumlaut -10 KPX k omacron -10 KPX k oslash -10 KPX k otilde -10 KPX k y -10 KPX k yacute -10 KPX k ydieresis -10 KPX kcommaaccent e -10 KPX kcommaaccent eacute -10 KPX kcommaaccent ecaron -10 KPX kcommaaccent ecircumflex -10 KPX kcommaaccent edieresis -10 KPX kcommaaccent edotaccent -10 KPX kcommaaccent egrave -10 KPX kcommaaccent emacron -10 KPX kcommaaccent eogonek -10 KPX kcommaaccent o -10 KPX kcommaaccent oacute -10 KPX kcommaaccent ocircumflex -10 KPX kcommaaccent odieresis -10 KPX kcommaaccent ograve -10 KPX kcommaaccent ohungarumlaut -10 KPX kcommaaccent omacron -10 KPX kcommaaccent oslash -10 KPX kcommaaccent otilde -10 KPX kcommaaccent y -10 KPX kcommaaccent yacute -10 KPX kcommaaccent ydieresis -10 KPX n v -40 KPX nacute v -40 KPX ncaron v -40 KPX ncommaaccent v -40 KPX ntilde v -40 KPX o g -10 KPX o gbreve -10 KPX o gcommaaccent -10 KPX o v -10 KPX oacute g -10 KPX oacute gbreve -10 KPX oacute gcommaaccent -10 KPX oacute v -10 KPX ocircumflex g -10 KPX ocircumflex gbreve -10 KPX ocircumflex gcommaaccent -10 KPX ocircumflex v -10 KPX odieresis g -10 KPX odieresis gbreve -10 KPX odieresis gcommaaccent -10 KPX odieresis v -10 KPX ograve g -10 KPX ograve gbreve -10 KPX ograve gcommaaccent -10 KPX ograve v -10 KPX ohungarumlaut g -10 KPX ohungarumlaut gbreve -10 KPX ohungarumlaut gcommaaccent -10 KPX ohungarumlaut v -10 KPX omacron g -10 KPX omacron gbreve -10 KPX omacron gcommaaccent -10 KPX omacron v -10 KPX oslash g -10 KPX oslash gbreve -10 KPX oslash gcommaaccent -10 KPX oslash v -10 KPX otilde g -10 KPX otilde gbreve -10 KPX otilde gcommaaccent -10 KPX otilde v -10 KPX period quotedblright -140 KPX period quoteright -140 KPX quoteleft quoteleft -111 KPX quoteright d -25 KPX quoteright dcroat -25 KPX quoteright quoteright -111 KPX quoteright r -25 KPX quoteright racute -25 KPX quoteright rcaron -25 KPX quoteright rcommaaccent -25 KPX quoteright s -40 KPX quoteright sacute -40 KPX quoteright scaron -40 KPX quoteright scedilla -40 KPX quoteright scommaaccent -40 KPX quoteright space -111 KPX quoteright t -30 KPX quoteright tcommaaccent -30 KPX quoteright v -10 KPX r a -15 KPX r aacute -15 KPX r abreve -15 KPX r acircumflex -15 KPX r adieresis -15 KPX r agrave -15 KPX r amacron -15 KPX r aogonek -15 KPX r aring -15 KPX r atilde -15 KPX r c -37 KPX r cacute -37 KPX r ccaron -37 KPX r ccedilla -37 KPX r comma -111 KPX r d -37 KPX r dcroat -37 KPX r e -37 KPX r eacute -37 KPX r ecaron -37 KPX r ecircumflex -37 KPX r edieresis -37 KPX r edotaccent -37 KPX r egrave -37 KPX r emacron -37 KPX r eogonek -37 KPX r g -37 KPX r gbreve -37 KPX r gcommaaccent -37 KPX r hyphen -20 KPX r o -45 KPX r oacute -45 KPX r ocircumflex -45 KPX r odieresis -45 KPX r ograve -45 KPX r ohungarumlaut -45 KPX r omacron -45 KPX r oslash -45 KPX r otilde -45 KPX r period -111 KPX r q -37 KPX r s -10 KPX r sacute -10 KPX r scaron -10 KPX r scedilla -10 KPX r scommaaccent -10 KPX racute a -15 KPX racute aacute -15 KPX racute abreve -15 KPX racute acircumflex -15 KPX racute adieresis -15 KPX racute agrave -15 KPX racute amacron -15 KPX racute aogonek -15 KPX racute aring -15 KPX racute atilde -15 KPX racute c -37 KPX racute cacute -37 KPX racute ccaron -37 KPX racute ccedilla -37 KPX racute comma -111 KPX racute d -37 KPX racute dcroat -37 KPX racute e -37 KPX racute eacute -37 KPX racute ecaron -37 KPX racute ecircumflex -37 KPX racute edieresis -37 KPX racute edotaccent -37 KPX racute egrave -37 KPX racute emacron -37 KPX racute eogonek -37 KPX racute g -37 KPX racute gbreve -37 KPX racute gcommaaccent -37 KPX racute hyphen -20 KPX racute o -45 KPX racute oacute -45 KPX racute ocircumflex -45 KPX racute odieresis -45 KPX racute ograve -45 KPX racute ohungarumlaut -45 KPX racute omacron -45 KPX racute oslash -45 KPX racute otilde -45 KPX racute period -111 KPX racute q -37 KPX racute s -10 KPX racute sacute -10 KPX racute scaron -10 KPX racute scedilla -10 KPX racute scommaaccent -10 KPX rcaron a -15 KPX rcaron aacute -15 KPX rcaron abreve -15 KPX rcaron acircumflex -15 KPX rcaron adieresis -15 KPX rcaron agrave -15 KPX rcaron amacron -15 KPX rcaron aogonek -15 KPX rcaron aring -15 KPX rcaron atilde -15 KPX rcaron c -37 KPX rcaron cacute -37 KPX rcaron ccaron -37 KPX rcaron ccedilla -37 KPX rcaron comma -111 KPX rcaron d -37 KPX rcaron dcroat -37 KPX rcaron e -37 KPX rcaron eacute -37 KPX rcaron ecaron -37 KPX rcaron ecircumflex -37 KPX rcaron edieresis -37 KPX rcaron edotaccent -37 KPX rcaron egrave -37 KPX rcaron emacron -37 KPX rcaron eogonek -37 KPX rcaron g -37 KPX rcaron gbreve -37 KPX rcaron gcommaaccent -37 KPX rcaron hyphen -20 KPX rcaron o -45 KPX rcaron oacute -45 KPX rcaron ocircumflex -45 KPX rcaron odieresis -45 KPX rcaron ograve -45 KPX rcaron ohungarumlaut -45 KPX rcaron omacron -45 KPX rcaron oslash -45 KPX rcaron otilde -45 KPX rcaron period -111 KPX rcaron q -37 KPX rcaron s -10 KPX rcaron sacute -10 KPX rcaron scaron -10 KPX rcaron scedilla -10 KPX rcaron scommaaccent -10 KPX rcommaaccent a -15 KPX rcommaaccent aacute -15 KPX rcommaaccent abreve -15 KPX rcommaaccent acircumflex -15 KPX rcommaaccent adieresis -15 KPX rcommaaccent agrave -15 KPX rcommaaccent amacron -15 KPX rcommaaccent aogonek -15 KPX rcommaaccent aring -15 KPX rcommaaccent atilde -15 KPX rcommaaccent c -37 KPX rcommaaccent cacute -37 KPX rcommaaccent ccaron -37 KPX rcommaaccent ccedilla -37 KPX rcommaaccent comma -111 KPX rcommaaccent d -37 KPX rcommaaccent dcroat -37 KPX rcommaaccent e -37 KPX rcommaaccent eacute -37 KPX rcommaaccent ecaron -37 KPX rcommaaccent ecircumflex -37 KPX rcommaaccent edieresis -37 KPX rcommaaccent edotaccent -37 KPX rcommaaccent egrave -37 KPX rcommaaccent emacron -37 KPX rcommaaccent eogonek -37 KPX rcommaaccent g -37 KPX rcommaaccent gbreve -37 KPX rcommaaccent gcommaaccent -37 KPX rcommaaccent hyphen -20 KPX rcommaaccent o -45 KPX rcommaaccent oacute -45 KPX rcommaaccent ocircumflex -45 KPX rcommaaccent odieresis -45 KPX rcommaaccent ograve -45 KPX rcommaaccent ohungarumlaut -45 KPX rcommaaccent omacron -45 KPX rcommaaccent oslash -45 KPX rcommaaccent otilde -45 KPX rcommaaccent period -111 KPX rcommaaccent q -37 KPX rcommaaccent s -10 KPX rcommaaccent sacute -10 KPX rcommaaccent scaron -10 KPX rcommaaccent scedilla -10 KPX rcommaaccent scommaaccent -10 KPX space A -18 KPX space Aacute -18 KPX space Abreve -18 KPX space Acircumflex -18 KPX space Adieresis -18 KPX space Agrave -18 KPX space Amacron -18 KPX space Aogonek -18 KPX space Aring -18 KPX space Atilde -18 KPX space T -18 KPX space Tcaron -18 KPX space Tcommaaccent -18 KPX space V -35 KPX space W -40 KPX space Y -75 KPX space Yacute -75 KPX space Ydieresis -75 KPX v comma -74 KPX v period -74 KPX w comma -74 KPX w period -74 KPX y comma -55 KPX y period -55 KPX yacute comma -55 KPX yacute period -55 KPX ydieresis comma -55 KPX ydieresis period -55 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/Times-Roman.afm100644 0 0 172637 11000354125 17706 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 12:49:17 1997 Comment UniqueID 43068 Comment VMusage 43909 54934 FontName Times-Roman FullName Times Roman FamilyName Times Weight Roman ItalicAngle 0 IsFixedPitch false CharacterSet ExtendedRoman FontBBox -168 -218 1000 898 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries. EncodingScheme AdobeStandardEncoding CapHeight 662 XHeight 450 Ascender 683 Descender -217 StdHW 28 StdVW 84 StartCharMetrics 315 C 32 ; WX 250 ; N space ; B 0 0 0 0 ; C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ; C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ; C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ; C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ; C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ; C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ; C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ; C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ; C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ; C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ; C 43 ; WX 564 ; N plus ; B 30 0 534 506 ; C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ; C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ; C 46 ; WX 250 ; N period ; B 70 -11 181 100 ; C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ; C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ; C 49 ; WX 500 ; N one ; B 111 0 394 676 ; C 50 ; WX 500 ; N two ; B 30 0 475 676 ; C 51 ; WX 500 ; N three ; B 43 -14 431 676 ; C 52 ; WX 500 ; N four ; B 12 0 472 676 ; C 53 ; WX 500 ; N five ; B 32 -14 438 688 ; C 54 ; WX 500 ; N six ; B 34 -14 468 684 ; C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ; C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ; C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ; C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ; C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ; C 60 ; WX 564 ; N less ; B 28 -8 536 514 ; C 61 ; WX 564 ; N equal ; B 30 120 534 386 ; C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ; C 63 ; WX 444 ; N question ; B 68 -8 414 676 ; C 64 ; WX 921 ; N at ; B 116 -14 809 676 ; C 65 ; WX 722 ; N A ; B 15 0 706 674 ; C 66 ; WX 667 ; N B ; B 17 0 593 662 ; C 67 ; WX 667 ; N C ; B 28 -14 633 676 ; C 68 ; WX 722 ; N D ; B 16 0 685 662 ; C 69 ; WX 611 ; N E ; B 12 0 597 662 ; C 70 ; WX 556 ; N F ; B 12 0 546 662 ; C 71 ; WX 722 ; N G ; B 32 -14 709 676 ; C 72 ; WX 722 ; N H ; B 19 0 702 662 ; C 73 ; WX 333 ; N I ; B 18 0 315 662 ; C 74 ; WX 389 ; N J ; B 10 -14 370 662 ; C 75 ; WX 722 ; N K ; B 34 0 723 662 ; C 76 ; WX 611 ; N L ; B 12 0 598 662 ; C 77 ; WX 889 ; N M ; B 12 0 863 662 ; C 78 ; WX 722 ; N N ; B 12 -11 707 662 ; C 79 ; WX 722 ; N O ; B 34 -14 688 676 ; C 80 ; WX 556 ; N P ; B 16 0 542 662 ; C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ; C 82 ; WX 667 ; N R ; B 17 0 659 662 ; C 83 ; WX 556 ; N S ; B 42 -14 491 676 ; C 84 ; WX 611 ; N T ; B 17 0 593 662 ; C 85 ; WX 722 ; N U ; B 14 -14 705 662 ; C 86 ; WX 722 ; N V ; B 16 -11 697 662 ; C 87 ; WX 944 ; N W ; B 5 -11 932 662 ; C 88 ; WX 722 ; N X ; B 10 0 704 662 ; C 89 ; WX 722 ; N Y ; B 22 0 703 662 ; C 90 ; WX 611 ; N Z ; B 9 0 597 662 ; C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ; C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ; C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ; C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ; C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ; C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ; C 97 ; WX 444 ; N a ; B 37 -10 442 460 ; C 98 ; WX 500 ; N b ; B 3 -10 468 683 ; C 99 ; WX 444 ; N c ; B 25 -10 412 460 ; C 100 ; WX 500 ; N d ; B 27 -10 491 683 ; C 101 ; WX 444 ; N e ; B 25 -10 424 460 ; C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ; C 103 ; WX 500 ; N g ; B 28 -218 470 460 ; C 104 ; WX 500 ; N h ; B 9 0 487 683 ; C 105 ; WX 278 ; N i ; B 16 0 253 683 ; C 106 ; WX 278 ; N j ; B -70 -218 194 683 ; C 107 ; WX 500 ; N k ; B 7 0 505 683 ; C 108 ; WX 278 ; N l ; B 19 0 257 683 ; C 109 ; WX 778 ; N m ; B 16 0 775 460 ; C 110 ; WX 500 ; N n ; B 16 0 485 460 ; C 111 ; WX 500 ; N o ; B 29 -10 470 460 ; C 112 ; WX 500 ; N p ; B 5 -217 470 460 ; C 113 ; WX 500 ; N q ; B 24 -217 488 460 ; C 114 ; WX 333 ; N r ; B 5 0 335 460 ; C 115 ; WX 389 ; N s ; B 51 -10 348 460 ; C 116 ; WX 278 ; N t ; B 13 -10 279 579 ; C 117 ; WX 500 ; N u ; B 9 -10 479 450 ; C 118 ; WX 500 ; N v ; B 19 -14 477 450 ; C 119 ; WX 722 ; N w ; B 21 -14 694 450 ; C 120 ; WX 500 ; N x ; B 17 0 479 450 ; C 121 ; WX 500 ; N y ; B 14 -218 475 450 ; C 122 ; WX 444 ; N z ; B 27 0 418 450 ; C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ; C 124 ; WX 200 ; N bar ; B 67 -218 133 782 ; C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ; C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ; C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ; C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ; C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ; C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ; C 165 ; WX 500 ; N yen ; B -53 0 512 662 ; C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ; C 167 ; WX 500 ; N section ; B 70 -148 426 676 ; C 168 ; WX 500 ; N currency ; B -22 58 522 602 ; C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ; C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ; C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ; C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ; C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ; C 174 ; WX 556 ; N fi ; B 31 0 521 683 ; C 175 ; WX 556 ; N fl ; B 32 0 521 683 ; C 177 ; WX 500 ; N endash ; B 0 201 500 250 ; C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ; C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ; C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ; C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ; C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ; C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ; C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ; C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ; C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ; C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ; C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ; C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ; C 193 ; WX 333 ; N grave ; B 19 507 242 678 ; C 194 ; WX 333 ; N acute ; B 93 507 317 678 ; C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ; C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ; C 197 ; WX 333 ; N macron ; B 11 547 322 601 ; C 198 ; WX 333 ; N breve ; B 26 507 307 664 ; C 199 ; WX 333 ; N dotaccent ; B 118 581 216 681 ; C 200 ; WX 333 ; N dieresis ; B 18 581 315 681 ; C 202 ; WX 333 ; N ring ; B 67 512 266 711 ; C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ; C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ; C 206 ; WX 333 ; N ogonek ; B 62 -165 243 0 ; C 207 ; WX 333 ; N caron ; B 11 507 322 674 ; C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ; C 225 ; WX 889 ; N AE ; B 0 0 863 662 ; C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ; C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ; C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ; C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ; C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ; C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ; C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ; C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ; C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ; C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ; C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ; C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ; C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ; C -1 ; WX 444 ; N abreve ; B 37 -10 442 664 ; C -1 ; WX 500 ; N uhungarumlaut ; B 9 -10 501 678 ; C -1 ; WX 444 ; N ecaron ; B 25 -10 424 674 ; C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ; C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ; C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ; C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ; C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ; C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ; C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ; C -1 ; WX 389 ; N scommaaccent ; B 51 -218 348 460 ; C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ; C -1 ; WX 722 ; N Uring ; B 14 -14 705 898 ; C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ; C -1 ; WX 444 ; N aogonek ; B 37 -165 469 460 ; C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ; C -1 ; WX 500 ; N uogonek ; B 9 -155 487 450 ; C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ; C -1 ; WX 722 ; N Dcroat ; B 16 0 685 662 ; C -1 ; WX 250 ; N commaaccent ; B 59 -218 184 -50 ; C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ; C -1 ; WX 611 ; N Emacron ; B 12 0 597 813 ; C -1 ; WX 444 ; N ccaron ; B 25 -10 412 674 ; C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ; C -1 ; WX 722 ; N Ncommaaccent ; B 12 -198 707 662 ; C -1 ; WX 278 ; N lacute ; B 19 0 290 890 ; C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ; C -1 ; WX 611 ; N Tcommaaccent ; B 17 -218 593 662 ; C -1 ; WX 667 ; N Cacute ; B 28 -14 633 890 ; C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ; C -1 ; WX 611 ; N Edotaccent ; B 12 0 597 835 ; C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ; C -1 ; WX 389 ; N scedilla ; B 51 -215 348 460 ; C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ; C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ; C -1 ; WX 667 ; N Rcaron ; B 17 0 659 886 ; C -1 ; WX 722 ; N Gcommaaccent ; B 32 -218 709 676 ; C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ; C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ; C -1 ; WX 722 ; N Amacron ; B 15 0 706 813 ; C -1 ; WX 333 ; N rcaron ; B 5 0 335 674 ; C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ; C -1 ; WX 611 ; N Zdotaccent ; B 9 0 597 835 ; C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ; C -1 ; WX 722 ; N Omacron ; B 34 -14 688 813 ; C -1 ; WX 667 ; N Racute ; B 17 0 659 890 ; C -1 ; WX 556 ; N Sacute ; B 42 -14 491 890 ; C -1 ; WX 588 ; N dcaron ; B 27 -10 589 695 ; C -1 ; WX 722 ; N Umacron ; B 14 -14 705 813 ; C -1 ; WX 500 ; N uring ; B 9 -10 479 711 ; C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ; C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ; C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ; C -1 ; WX 722 ; N Abreve ; B 15 0 706 876 ; C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ; C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ; C -1 ; WX 611 ; N Tcaron ; B 17 0 593 886 ; C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ; C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ; C -1 ; WX 722 ; N Nacute ; B 12 -11 707 890 ; C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ; C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ; C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ; C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ; C -1 ; WX 444 ; N cacute ; B 25 -10 413 678 ; C -1 ; WX 500 ; N nacute ; B 16 0 485 678 ; C -1 ; WX 500 ; N umacron ; B 9 -10 479 601 ; C -1 ; WX 722 ; N Ncaron ; B 12 -11 707 886 ; C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ; C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ; C -1 ; WX 200 ; N brokenbar ; B 67 -143 133 707 ; C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ; C -1 ; WX 722 ; N Gbreve ; B 32 -14 709 876 ; C -1 ; WX 333 ; N Idotaccent ; B 18 0 315 835 ; C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ; C -1 ; WX 333 ; N racute ; B 5 0 335 678 ; C -1 ; WX 500 ; N omacron ; B 29 -10 470 601 ; C -1 ; WX 611 ; N Zacute ; B 9 0 597 890 ; C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ; C -1 ; WX 549 ; N greaterequal ; B 26 0 523 666 ; C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ; C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ; C -1 ; WX 278 ; N lcommaaccent ; B 19 -218 257 683 ; C -1 ; WX 326 ; N tcaron ; B 13 -10 318 722 ; C -1 ; WX 444 ; N eogonek ; B 25 -165 424 460 ; C -1 ; WX 722 ; N Uogonek ; B 14 -165 705 662 ; C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ; C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ; C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ; C -1 ; WX 444 ; N zacute ; B 27 0 418 678 ; C -1 ; WX 278 ; N iogonek ; B 16 -165 265 683 ; C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ; C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ; C -1 ; WX 444 ; N amacron ; B 37 -10 442 601 ; C -1 ; WX 389 ; N sacute ; B 51 -10 348 678 ; C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ; C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ; C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ; C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ; C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ; C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ; C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ; C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ; C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ; C -1 ; WX 500 ; N ohungarumlaut ; B 29 -10 491 678 ; C -1 ; WX 611 ; N Eogonek ; B 12 -165 597 662 ; C -1 ; WX 500 ; N dcroat ; B 27 -10 500 683 ; C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ; C -1 ; WX 556 ; N Scedilla ; B 42 -215 491 676 ; C -1 ; WX 344 ; N lcaron ; B 19 0 347 695 ; C -1 ; WX 722 ; N Kcommaaccent ; B 34 -198 723 662 ; C -1 ; WX 611 ; N Lacute ; B 12 0 598 890 ; C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ; C -1 ; WX 444 ; N edotaccent ; B 25 -10 424 623 ; C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ; C -1 ; WX 333 ; N Imacron ; B 11 0 322 813 ; C -1 ; WX 611 ; N Lcaron ; B 12 0 598 676 ; C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ; C -1 ; WX 549 ; N lessequal ; B 26 0 523 666 ; C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ; C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ; C -1 ; WX 722 ; N Uhungarumlaut ; B 14 -14 705 890 ; C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ; C -1 ; WX 444 ; N emacron ; B 25 -10 424 601 ; C -1 ; WX 500 ; N gbreve ; B 28 -218 470 664 ; C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ; C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ; C -1 ; WX 556 ; N Scommaaccent ; B 42 -218 491 676 ; C -1 ; WX 722 ; N Ohungarumlaut ; B 34 -14 688 890 ; C -1 ; WX 400 ; N degree ; B 57 390 343 676 ; C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ; C -1 ; WX 667 ; N Ccaron ; B 28 -14 633 886 ; C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ; C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ; C -1 ; WX 722 ; N Dcaron ; B 16 0 685 886 ; C -1 ; WX 333 ; N rcommaaccent ; B 5 -218 335 460 ; C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ; C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ; C -1 ; WX 667 ; N Rcommaaccent ; B 17 -198 659 662 ; C -1 ; WX 611 ; N Lcommaaccent ; B 12 -218 598 662 ; C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ; C -1 ; WX 722 ; N Aogonek ; B 15 -165 738 674 ; C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ; C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ; C -1 ; WX 444 ; N zdotaccent ; B 27 0 418 623 ; C -1 ; WX 611 ; N Ecaron ; B 12 0 597 886 ; C -1 ; WX 333 ; N Iogonek ; B 18 -165 315 662 ; C -1 ; WX 500 ; N kcommaaccent ; B 7 -218 505 683 ; C -1 ; WX 564 ; N minus ; B 30 220 534 286 ; C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ; C -1 ; WX 500 ; N ncaron ; B 16 0 485 674 ; C -1 ; WX 278 ; N tcommaaccent ; B 13 -218 279 579 ; C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ; C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ; C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ; C -1 ; WX 549 ; N notequal ; B 12 -31 537 547 ; C -1 ; WX 500 ; N gcommaaccent ; B 28 -218 470 749 ; C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ; C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ; C -1 ; WX 500 ; N ncommaaccent ; B 16 -218 485 460 ; C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ; C -1 ; WX 278 ; N imacron ; B 6 0 271 601 ; C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ; EndCharMetrics StartKernData StartKernPairs 2073 KPX A C -40 KPX A Cacute -40 KPX A Ccaron -40 KPX A Ccedilla -40 KPX A G -40 KPX A Gbreve -40 KPX A Gcommaaccent -40 KPX A O -55 KPX A Oacute -55 KPX A Ocircumflex -55 KPX A Odieresis -55 KPX A Ograve -55 KPX A Ohungarumlaut -55 KPX A Omacron -55 KPX A Oslash -55 KPX A Otilde -55 KPX A Q -55 KPX A T -111 KPX A Tcaron -111 KPX A Tcommaaccent -111 KPX A U -55 KPX A Uacute -55 KPX A Ucircumflex -55 KPX A Udieresis -55 KPX A Ugrave -55 KPX A Uhungarumlaut -55 KPX A Umacron -55 KPX A Uogonek -55 KPX A Uring -55 KPX A V -135 KPX A W -90 KPX A Y -105 KPX A Yacute -105 KPX A Ydieresis -105 KPX A quoteright -111 KPX A v -74 KPX A w -92 KPX A y -92 KPX A yacute -92 KPX A ydieresis -92 KPX Aacute C -40 KPX Aacute Cacute -40 KPX Aacute Ccaron -40 KPX Aacute Ccedilla -40 KPX Aacute G -40 KPX Aacute Gbreve -40 KPX Aacute Gcommaaccent -40 KPX Aacute O -55 KPX Aacute Oacute -55 KPX Aacute Ocircumflex -55 KPX Aacute Odieresis -55 KPX Aacute Ograve -55 KPX Aacute Ohungarumlaut -55 KPX Aacute Omacron -55 KPX Aacute Oslash -55 KPX Aacute Otilde -55 KPX Aacute Q -55 KPX Aacute T -111 KPX Aacute Tcaron -111 KPX Aacute Tcommaaccent -111 KPX Aacute U -55 KPX Aacute Uacute -55 KPX Aacute Ucircumflex -55 KPX Aacute Udieresis -55 KPX Aacute Ugrave -55 KPX Aacute Uhungarumlaut -55 KPX Aacute Umacron -55 KPX Aacute Uogonek -55 KPX Aacute Uring -55 KPX Aacute V -135 KPX Aacute W -90 KPX Aacute Y -105 KPX Aacute Yacute -105 KPX Aacute Ydieresis -105 KPX Aacute quoteright -111 KPX Aacute v -74 KPX Aacute w -92 KPX Aacute y -92 KPX Aacute yacute -92 KPX Aacute ydieresis -92 KPX Abreve C -40 KPX Abreve Cacute -40 KPX Abreve Ccaron -40 KPX Abreve Ccedilla -40 KPX Abreve G -40 KPX Abreve Gbreve -40 KPX Abreve Gcommaaccent -40 KPX Abreve O -55 KPX Abreve Oacute -55 KPX Abreve Ocircumflex -55 KPX Abreve Odieresis -55 KPX Abreve Ograve -55 KPX Abreve Ohungarumlaut -55 KPX Abreve Omacron -55 KPX Abreve Oslash -55 KPX Abreve Otilde -55 KPX Abreve Q -55 KPX Abreve T -111 KPX Abreve Tcaron -111 KPX Abreve Tcommaaccent -111 KPX Abreve U -55 KPX Abreve Uacute -55 KPX Abreve Ucircumflex -55 KPX Abreve Udieresis -55 KPX Abreve Ugrave -55 KPX Abreve Uhungarumlaut -55 KPX Abreve Umacron -55 KPX Abreve Uogonek -55 KPX Abreve Uring -55 KPX Abreve V -135 KPX Abreve W -90 KPX Abreve Y -105 KPX Abreve Yacute -105 KPX Abreve Ydieresis -105 KPX Abreve quoteright -111 KPX Abreve v -74 KPX Abreve w -92 KPX Abreve y -92 KPX Abreve yacute -92 KPX Abreve ydieresis -92 KPX Acircumflex C -40 KPX Acircumflex Cacute -40 KPX Acircumflex Ccaron -40 KPX Acircumflex Ccedilla -40 KPX Acircumflex G -40 KPX Acircumflex Gbreve -40 KPX Acircumflex Gcommaaccent -40 KPX Acircumflex O -55 KPX Acircumflex Oacute -55 KPX Acircumflex Ocircumflex -55 KPX Acircumflex Odieresis -55 KPX Acircumflex Ograve -55 KPX Acircumflex Ohungarumlaut -55 KPX Acircumflex Omacron -55 KPX Acircumflex Oslash -55 KPX Acircumflex Otilde -55 KPX Acircumflex Q -55 KPX Acircumflex T -111 KPX Acircumflex Tcaron -111 KPX Acircumflex Tcommaaccent -111 KPX Acircumflex U -55 KPX Acircumflex Uacute -55 KPX Acircumflex Ucircumflex -55 KPX Acircumflex Udieresis -55 KPX Acircumflex Ugrave -55 KPX Acircumflex Uhungarumlaut -55 KPX Acircumflex Umacron -55 KPX Acircumflex Uogonek -55 KPX Acircumflex Uring -55 KPX Acircumflex V -135 KPX Acircumflex W -90 KPX Acircumflex Y -105 KPX Acircumflex Yacute -105 KPX Acircumflex Ydieresis -105 KPX Acircumflex quoteright -111 KPX Acircumflex v -74 KPX Acircumflex w -92 KPX Acircumflex y -92 KPX Acircumflex yacute -92 KPX Acircumflex ydieresis -92 KPX Adieresis C -40 KPX Adieresis Cacute -40 KPX Adieresis Ccaron -40 KPX Adieresis Ccedilla -40 KPX Adieresis G -40 KPX Adieresis Gbreve -40 KPX Adieresis Gcommaaccent -40 KPX Adieresis O -55 KPX Adieresis Oacute -55 KPX Adieresis Ocircumflex -55 KPX Adieresis Odieresis -55 KPX Adieresis Ograve -55 KPX Adieresis Ohungarumlaut -55 KPX Adieresis Omacron -55 KPX Adieresis Oslash -55 KPX Adieresis Otilde -55 KPX Adieresis Q -55 KPX Adieresis T -111 KPX Adieresis Tcaron -111 KPX Adieresis Tcommaaccent -111 KPX Adieresis U -55 KPX Adieresis Uacute -55 KPX Adieresis Ucircumflex -55 KPX Adieresis Udieresis -55 KPX Adieresis Ugrave -55 KPX Adieresis Uhungarumlaut -55 KPX Adieresis Umacron -55 KPX Adieresis Uogonek -55 KPX Adieresis Uring -55 KPX Adieresis V -135 KPX Adieresis W -90 KPX Adieresis Y -105 KPX Adieresis Yacute -105 KPX Adieresis Ydieresis -105 KPX Adieresis quoteright -111 KPX Adieresis v -74 KPX Adieresis w -92 KPX Adieresis y -92 KPX Adieresis yacute -92 KPX Adieresis ydieresis -92 KPX Agrave C -40 KPX Agrave Cacute -40 KPX Agrave Ccaron -40 KPX Agrave Ccedilla -40 KPX Agrave G -40 KPX Agrave Gbreve -40 KPX Agrave Gcommaaccent -40 KPX Agrave O -55 KPX Agrave Oacute -55 KPX Agrave Ocircumflex -55 KPX Agrave Odieresis -55 KPX Agrave Ograve -55 KPX Agrave Ohungarumlaut -55 KPX Agrave Omacron -55 KPX Agrave Oslash -55 KPX Agrave Otilde -55 KPX Agrave Q -55 KPX Agrave T -111 KPX Agrave Tcaron -111 KPX Agrave Tcommaaccent -111 KPX Agrave U -55 KPX Agrave Uacute -55 KPX Agrave Ucircumflex -55 KPX Agrave Udieresis -55 KPX Agrave Ugrave -55 KPX Agrave Uhungarumlaut -55 KPX Agrave Umacron -55 KPX Agrave Uogonek -55 KPX Agrave Uring -55 KPX Agrave V -135 KPX Agrave W -90 KPX Agrave Y -105 KPX Agrave Yacute -105 KPX Agrave Ydieresis -105 KPX Agrave quoteright -111 KPX Agrave v -74 KPX Agrave w -92 KPX Agrave y -92 KPX Agrave yacute -92 KPX Agrave ydieresis -92 KPX Amacron C -40 KPX Amacron Cacute -40 KPX Amacron Ccaron -40 KPX Amacron Ccedilla -40 KPX Amacron G -40 KPX Amacron Gbreve -40 KPX Amacron Gcommaaccent -40 KPX Amacron O -55 KPX Amacron Oacute -55 KPX Amacron Ocircumflex -55 KPX Amacron Odieresis -55 KPX Amacron Ograve -55 KPX Amacron Ohungarumlaut -55 KPX Amacron Omacron -55 KPX Amacron Oslash -55 KPX Amacron Otilde -55 KPX Amacron Q -55 KPX Amacron T -111 KPX Amacron Tcaron -111 KPX Amacron Tcommaaccent -111 KPX Amacron U -55 KPX Amacron Uacute -55 KPX Amacron Ucircumflex -55 KPX Amacron Udieresis -55 KPX Amacron Ugrave -55 KPX Amacron Uhungarumlaut -55 KPX Amacron Umacron -55 KPX Amacron Uogonek -55 KPX Amacron Uring -55 KPX Amacron V -135 KPX Amacron W -90 KPX Amacron Y -105 KPX Amacron Yacute -105 KPX Amacron Ydieresis -105 KPX Amacron quoteright -111 KPX Amacron v -74 KPX Amacron w -92 KPX Amacron y -92 KPX Amacron yacute -92 KPX Amacron ydieresis -92 KPX Aogonek C -40 KPX Aogonek Cacute -40 KPX Aogonek Ccaron -40 KPX Aogonek Ccedilla -40 KPX Aogonek G -40 KPX Aogonek Gbreve -40 KPX Aogonek Gcommaaccent -40 KPX Aogonek O -55 KPX Aogonek Oacute -55 KPX Aogonek Ocircumflex -55 KPX Aogonek Odieresis -55 KPX Aogonek Ograve -55 KPX Aogonek Ohungarumlaut -55 KPX Aogonek Omacron -55 KPX Aogonek Oslash -55 KPX Aogonek Otilde -55 KPX Aogonek Q -55 KPX Aogonek T -111 KPX Aogonek Tcaron -111 KPX Aogonek Tcommaaccent -111 KPX Aogonek U -55 KPX Aogonek Uacute -55 KPX Aogonek Ucircumflex -55 KPX Aogonek Udieresis -55 KPX Aogonek Ugrave -55 KPX Aogonek Uhungarumlaut -55 KPX Aogonek Umacron -55 KPX Aogonek Uogonek -55 KPX Aogonek Uring -55 KPX Aogonek V -135 KPX Aogonek W -90 KPX Aogonek Y -105 KPX Aogonek Yacute -105 KPX Aogonek Ydieresis -105 KPX Aogonek quoteright -111 KPX Aogonek v -74 KPX Aogonek w -52 KPX Aogonek y -52 KPX Aogonek yacute -52 KPX Aogonek ydieresis -52 KPX Aring C -40 KPX Aring Cacute -40 KPX Aring Ccaron -40 KPX Aring Ccedilla -40 KPX Aring G -40 KPX Aring Gbreve -40 KPX Aring Gcommaaccent -40 KPX Aring O -55 KPX Aring Oacute -55 KPX Aring Ocircumflex -55 KPX Aring Odieresis -55 KPX Aring Ograve -55 KPX Aring Ohungarumlaut -55 KPX Aring Omacron -55 KPX Aring Oslash -55 KPX Aring Otilde -55 KPX Aring Q -55 KPX Aring T -111 KPX Aring Tcaron -111 KPX Aring Tcommaaccent -111 KPX Aring U -55 KPX Aring Uacute -55 KPX Aring Ucircumflex -55 KPX Aring Udieresis -55 KPX Aring Ugrave -55 KPX Aring Uhungarumlaut -55 KPX Aring Umacron -55 KPX Aring Uogonek -55 KPX Aring Uring -55 KPX Aring V -135 KPX Aring W -90 KPX Aring Y -105 KPX Aring Yacute -105 KPX Aring Ydieresis -105 KPX Aring quoteright -111 KPX Aring v -74 KPX Aring w -92 KPX Aring y -92 KPX Aring yacute -92 KPX Aring ydieresis -92 KPX Atilde C -40 KPX Atilde Cacute -40 KPX Atilde Ccaron -40 KPX Atilde Ccedilla -40 KPX Atilde G -40 KPX Atilde Gbreve -40 KPX Atilde Gcommaaccent -40 KPX Atilde O -55 KPX Atilde Oacute -55 KPX Atilde Ocircumflex -55 KPX Atilde Odieresis -55 KPX Atilde Ograve -55 KPX Atilde Ohungarumlaut -55 KPX Atilde Omacron -55 KPX Atilde Oslash -55 KPX Atilde Otilde -55 KPX Atilde Q -55 KPX Atilde T -111 KPX Atilde Tcaron -111 KPX Atilde Tcommaaccent -111 KPX Atilde U -55 KPX Atilde Uacute -55 KPX Atilde Ucircumflex -55 KPX Atilde Udieresis -55 KPX Atilde Ugrave -55 KPX Atilde Uhungarumlaut -55 KPX Atilde Umacron -55 KPX Atilde Uogonek -55 KPX Atilde Uring -55 KPX Atilde V -135 KPX Atilde W -90 KPX Atilde Y -105 KPX Atilde Yacute -105 KPX Atilde Ydieresis -105 KPX Atilde quoteright -111 KPX Atilde v -74 KPX Atilde w -92 KPX Atilde y -92 KPX Atilde yacute -92 KPX Atilde ydieresis -92 KPX B A -35 KPX B Aacute -35 KPX B Abreve -35 KPX B Acircumflex -35 KPX B Adieresis -35 KPX B Agrave -35 KPX B Amacron -35 KPX B Aogonek -35 KPX B Aring -35 KPX B Atilde -35 KPX B U -10 KPX B Uacute -10 KPX B Ucircumflex -10 KPX B Udieresis -10 KPX B Ugrave -10 KPX B Uhungarumlaut -10 KPX B Umacron -10 KPX B Uogonek -10 KPX B Uring -10 KPX D A -40 KPX D Aacute -40 KPX D Abreve -40 KPX D Acircumflex -40 KPX D Adieresis -40 KPX D Agrave -40 KPX D Amacron -40 KPX D Aogonek -40 KPX D Aring -40 KPX D Atilde -40 KPX D V -40 KPX D W -30 KPX D Y -55 KPX D Yacute -55 KPX D Ydieresis -55 KPX Dcaron A -40 KPX Dcaron Aacute -40 KPX Dcaron Abreve -40 KPX Dcaron Acircumflex -40 KPX Dcaron Adieresis -40 KPX Dcaron Agrave -40 KPX Dcaron Amacron -40 KPX Dcaron Aogonek -40 KPX Dcaron Aring -40 KPX Dcaron Atilde -40 KPX Dcaron V -40 KPX Dcaron W -30 KPX Dcaron Y -55 KPX Dcaron Yacute -55 KPX Dcaron Ydieresis -55 KPX Dcroat A -40 KPX Dcroat Aacute -40 KPX Dcroat Abreve -40 KPX Dcroat Acircumflex -40 KPX Dcroat Adieresis -40 KPX Dcroat Agrave -40 KPX Dcroat Amacron -40 KPX Dcroat Aogonek -40 KPX Dcroat Aring -40 KPX Dcroat Atilde -40 KPX Dcroat V -40 KPX Dcroat W -30 KPX Dcroat Y -55 KPX Dcroat Yacute -55 KPX Dcroat Ydieresis -55 KPX F A -74 KPX F Aacute -74 KPX F Abreve -74 KPX F Acircumflex -74 KPX F Adieresis -74 KPX F Agrave -74 KPX F Amacron -74 KPX F Aogonek -74 KPX F Aring -74 KPX F Atilde -74 KPX F a -15 KPX F aacute -15 KPX F abreve -15 KPX F acircumflex -15 KPX F adieresis -15 KPX F agrave -15 KPX F amacron -15 KPX F aogonek -15 KPX F aring -15 KPX F atilde -15 KPX F comma -80 KPX F o -15 KPX F oacute -15 KPX F ocircumflex -15 KPX F odieresis -15 KPX F ograve -15 KPX F ohungarumlaut -15 KPX F omacron -15 KPX F oslash -15 KPX F otilde -15 KPX F period -80 KPX J A -60 KPX J Aacute -60 KPX J Abreve -60 KPX J Acircumflex -60 KPX J Adieresis -60 KPX J Agrave -60 KPX J Amacron -60 KPX J Aogonek -60 KPX J Aring -60 KPX J Atilde -60 KPX K O -30 KPX K Oacute -30 KPX K Ocircumflex -30 KPX K Odieresis -30 KPX K Ograve -30 KPX K Ohungarumlaut -30 KPX K Omacron -30 KPX K Oslash -30 KPX K Otilde -30 KPX K e -25 KPX K eacute -25 KPX K ecaron -25 KPX K ecircumflex -25 KPX K edieresis -25 KPX K edotaccent -25 KPX K egrave -25 KPX K emacron -25 KPX K eogonek -25 KPX K o -35 KPX K oacute -35 KPX K ocircumflex -35 KPX K odieresis -35 KPX K ograve -35 KPX K ohungarumlaut -35 KPX K omacron -35 KPX K oslash -35 KPX K otilde -35 KPX K u -15 KPX K uacute -15 KPX K ucircumflex -15 KPX K udieresis -15 KPX K ugrave -15 KPX K uhungarumlaut -15 KPX K umacron -15 KPX K uogonek -15 KPX K uring -15 KPX K y -25 KPX K yacute -25 KPX K ydieresis -25 KPX Kcommaaccent O -30 KPX Kcommaaccent Oacute -30 KPX Kcommaaccent Ocircumflex -30 KPX Kcommaaccent Odieresis -30 KPX Kcommaaccent Ograve -30 KPX Kcommaaccent Ohungarumlaut -30 KPX Kcommaaccent Omacron -30 KPX Kcommaaccent Oslash -30 KPX Kcommaaccent Otilde -30 KPX Kcommaaccent e -25 KPX Kcommaaccent eacute -25 KPX Kcommaaccent ecaron -25 KPX Kcommaaccent ecircumflex -25 KPX Kcommaaccent edieresis -25 KPX Kcommaaccent edotaccent -25 KPX Kcommaaccent egrave -25 KPX Kcommaaccent emacron -25 KPX Kcommaaccent eogonek -25 KPX Kcommaaccent o -35 KPX Kcommaaccent oacute -35 KPX Kcommaaccent ocircumflex -35 KPX Kcommaaccent odieresis -35 KPX Kcommaaccent ograve -35 KPX Kcommaaccent ohungarumlaut -35 KPX Kcommaaccent omacron -35 KPX Kcommaaccent oslash -35 KPX Kcommaaccent otilde -35 KPX Kcommaaccent u -15 KPX Kcommaaccent uacute -15 KPX Kcommaaccent ucircumflex -15 KPX Kcommaaccent udieresis -15 KPX Kcommaaccent ugrave -15 KPX Kcommaaccent uhungarumlaut -15 KPX Kcommaaccent umacron -15 KPX Kcommaaccent uogonek -15 KPX Kcommaaccent uring -15 KPX Kcommaaccent y -25 KPX Kcommaaccent yacute -25 KPX Kcommaaccent ydieresis -25 KPX L T -92 KPX L Tcaron -92 KPX L Tcommaaccent -92 KPX L V -100 KPX L W -74 KPX L Y -100 KPX L Yacute -100 KPX L Ydieresis -100 KPX L quoteright -92 KPX L y -55 KPX L yacute -55 KPX L ydieresis -55 KPX Lacute T -92 KPX Lacute Tcaron -92 KPX Lacute Tcommaaccent -92 KPX Lacute V -100 KPX Lacute W -74 KPX Lacute Y -100 KPX Lacute Yacute -100 KPX Lacute Ydieresis -100 KPX Lacute quoteright -92 KPX Lacute y -55 KPX Lacute yacute -55 KPX Lacute ydieresis -55 KPX Lcaron quoteright -92 KPX Lcaron y -55 KPX Lcaron yacute -55 KPX Lcaron ydieresis -55 KPX Lcommaaccent T -92 KPX Lcommaaccent Tcaron -92 KPX Lcommaaccent Tcommaaccent -92 KPX Lcommaaccent V -100 KPX Lcommaaccent W -74 KPX Lcommaaccent Y -100 KPX Lcommaaccent Yacute -100 KPX Lcommaaccent Ydieresis -100 KPX Lcommaaccent quoteright -92 KPX Lcommaaccent y -55 KPX Lcommaaccent yacute -55 KPX Lcommaaccent ydieresis -55 KPX Lslash T -92 KPX Lslash Tcaron -92 KPX Lslash Tcommaaccent -92 KPX Lslash V -100 KPX Lslash W -74 KPX Lslash Y -100 KPX Lslash Yacute -100 KPX Lslash Ydieresis -100 KPX Lslash quoteright -92 KPX Lslash y -55 KPX Lslash yacute -55 KPX Lslash ydieresis -55 KPX N A -35 KPX N Aacute -35 KPX N Abreve -35 KPX N Acircumflex -35 KPX N Adieresis -35 KPX N Agrave -35 KPX N Amacron -35 KPX N Aogonek -35 KPX N Aring -35 KPX N Atilde -35 KPX Nacute A -35 KPX Nacute Aacute -35 KPX Nacute Abreve -35 KPX Nacute Acircumflex -35 KPX Nacute Adieresis -35 KPX Nacute Agrave -35 KPX Nacute Amacron -35 KPX Nacute Aogonek -35 KPX Nacute Aring -35 KPX Nacute Atilde -35 KPX Ncaron A -35 KPX Ncaron Aacute -35 KPX Ncaron Abreve -35 KPX Ncaron Acircumflex -35 KPX Ncaron Adieresis -35 KPX Ncaron Agrave -35 KPX Ncaron Amacron -35 KPX Ncaron Aogonek -35 KPX Ncaron Aring -35 KPX Ncaron Atilde -35 KPX Ncommaaccent A -35 KPX Ncommaaccent Aacute -35 KPX Ncommaaccent Abreve -35 KPX Ncommaaccent Acircumflex -35 KPX Ncommaaccent Adieresis -35 KPX Ncommaaccent Agrave -35 KPX Ncommaaccent Amacron -35 KPX Ncommaaccent Aogonek -35 KPX Ncommaaccent Aring -35 KPX Ncommaaccent Atilde -35 KPX Ntilde A -35 KPX Ntilde Aacute -35 KPX Ntilde Abreve -35 KPX Ntilde Acircumflex -35 KPX Ntilde Adieresis -35 KPX Ntilde Agrave -35 KPX Ntilde Amacron -35 KPX Ntilde Aogonek -35 KPX Ntilde Aring -35 KPX Ntilde Atilde -35 KPX O A -35 KPX O Aacute -35 KPX O Abreve -35 KPX O Acircumflex -35 KPX O Adieresis -35 KPX O Agrave -35 KPX O Amacron -35 KPX O Aogonek -35 KPX O Aring -35 KPX O Atilde -35 KPX O T -40 KPX O Tcaron -40 KPX O Tcommaaccent -40 KPX O V -50 KPX O W -35 KPX O X -40 KPX O Y -50 KPX O Yacute -50 KPX O Ydieresis -50 KPX Oacute A -35 KPX Oacute Aacute -35 KPX Oacute Abreve -35 KPX Oacute Acircumflex -35 KPX Oacute Adieresis -35 KPX Oacute Agrave -35 KPX Oacute Amacron -35 KPX Oacute Aogonek -35 KPX Oacute Aring -35 KPX Oacute Atilde -35 KPX Oacute T -40 KPX Oacute Tcaron -40 KPX Oacute Tcommaaccent -40 KPX Oacute V -50 KPX Oacute W -35 KPX Oacute X -40 KPX Oacute Y -50 KPX Oacute Yacute -50 KPX Oacute Ydieresis -50 KPX Ocircumflex A -35 KPX Ocircumflex Aacute -35 KPX Ocircumflex Abreve -35 KPX Ocircumflex Acircumflex -35 KPX Ocircumflex Adieresis -35 KPX Ocircumflex Agrave -35 KPX Ocircumflex Amacron -35 KPX Ocircumflex Aogonek -35 KPX Ocircumflex Aring -35 KPX Ocircumflex Atilde -35 KPX Ocircumflex T -40 KPX Ocircumflex Tcaron -40 KPX Ocircumflex Tcommaaccent -40 KPX Ocircumflex V -50 KPX Ocircumflex W -35 KPX Ocircumflex X -40 KPX Ocircumflex Y -50 KPX Ocircumflex Yacute -50 KPX Ocircumflex Ydieresis -50 KPX Odieresis A -35 KPX Odieresis Aacute -35 KPX Odieresis Abreve -35 KPX Odieresis Acircumflex -35 KPX Odieresis Adieresis -35 KPX Odieresis Agrave -35 KPX Odieresis Amacron -35 KPX Odieresis Aogonek -35 KPX Odieresis Aring -35 KPX Odieresis Atilde -35 KPX Odieresis T -40 KPX Odieresis Tcaron -40 KPX Odieresis Tcommaaccent -40 KPX Odieresis V -50 KPX Odieresis W -35 KPX Odieresis X -40 KPX Odieresis Y -50 KPX Odieresis Yacute -50 KPX Odieresis Ydieresis -50 KPX Ograve A -35 KPX Ograve Aacute -35 KPX Ograve Abreve -35 KPX Ograve Acircumflex -35 KPX Ograve Adieresis -35 KPX Ograve Agrave -35 KPX Ograve Amacron -35 KPX Ograve Aogonek -35 KPX Ograve Aring -35 KPX Ograve Atilde -35 KPX Ograve T -40 KPX Ograve Tcaron -40 KPX Ograve Tcommaaccent -40 KPX Ograve V -50 KPX Ograve W -35 KPX Ograve X -40 KPX Ograve Y -50 KPX Ograve Yacute -50 KPX Ograve Ydieresis -50 KPX Ohungarumlaut A -35 KPX Ohungarumlaut Aacute -35 KPX Ohungarumlaut Abreve -35 KPX Ohungarumlaut Acircumflex -35 KPX Ohungarumlaut Adieresis -35 KPX Ohungarumlaut Agrave -35 KPX Ohungarumlaut Amacron -35 KPX Ohungarumlaut Aogonek -35 KPX Ohungarumlaut Aring -35 KPX Ohungarumlaut Atilde -35 KPX Ohungarumlaut T -40 KPX Ohungarumlaut Tcaron -40 KPX Ohungarumlaut Tcommaaccent -40 KPX Ohungarumlaut V -50 KPX Ohungarumlaut W -35 KPX Ohungarumlaut X -40 KPX Ohungarumlaut Y -50 KPX Ohungarumlaut Yacute -50 KPX Ohungarumlaut Ydieresis -50 KPX Omacron A -35 KPX Omacron Aacute -35 KPX Omacron Abreve -35 KPX Omacron Acircumflex -35 KPX Omacron Adieresis -35 KPX Omacron Agrave -35 KPX Omacron Amacron -35 KPX Omacron Aogonek -35 KPX Omacron Aring -35 KPX Omacron Atilde -35 KPX Omacron T -40 KPX Omacron Tcaron -40 KPX Omacron Tcommaaccent -40 KPX Omacron V -50 KPX Omacron W -35 KPX Omacron X -40 KPX Omacron Y -50 KPX Omacron Yacute -50 KPX Omacron Ydieresis -50 KPX Oslash A -35 KPX Oslash Aacute -35 KPX Oslash Abreve -35 KPX Oslash Acircumflex -35 KPX Oslash Adieresis -35 KPX Oslash Agrave -35 KPX Oslash Amacron -35 KPX Oslash Aogonek -35 KPX Oslash Aring -35 KPX Oslash Atilde -35 KPX Oslash T -40 KPX Oslash Tcaron -40 KPX Oslash Tcommaaccent -40 KPX Oslash V -50 KPX Oslash W -35 KPX Oslash X -40 KPX Oslash Y -50 KPX Oslash Yacute -50 KPX Oslash Ydieresis -50 KPX Otilde A -35 KPX Otilde Aacute -35 KPX Otilde Abreve -35 KPX Otilde Acircumflex -35 KPX Otilde Adieresis -35 KPX Otilde Agrave -35 KPX Otilde Amacron -35 KPX Otilde Aogonek -35 KPX Otilde Aring -35 KPX Otilde Atilde -35 KPX Otilde T -40 KPX Otilde Tcaron -40 KPX Otilde Tcommaaccent -40 KPX Otilde V -50 KPX Otilde W -35 KPX Otilde X -40 KPX Otilde Y -50 KPX Otilde Yacute -50 KPX Otilde Ydieresis -50 KPX P A -92 KPX P Aacute -92 KPX P Abreve -92 KPX P Acircumflex -92 KPX P Adieresis -92 KPX P Agrave -92 KPX P Amacron -92 KPX P Aogonek -92 KPX P Aring -92 KPX P Atilde -92 KPX P a -15 KPX P aacute -15 KPX P abreve -15 KPX P acircumflex -15 KPX P adieresis -15 KPX P agrave -15 KPX P amacron -15 KPX P aogonek -15 KPX P aring -15 KPX P atilde -15 KPX P comma -111 KPX P period -111 KPX Q U -10 KPX Q Uacute -10 KPX Q Ucircumflex -10 KPX Q Udieresis -10 KPX Q Ugrave -10 KPX Q Uhungarumlaut -10 KPX Q Umacron -10 KPX Q Uogonek -10 KPX Q Uring -10 KPX R O -40 KPX R Oacute -40 KPX R Ocircumflex -40 KPX R Odieresis -40 KPX R Ograve -40 KPX R Ohungarumlaut -40 KPX R Omacron -40 KPX R Oslash -40 KPX R Otilde -40 KPX R T -60 KPX R Tcaron -60 KPX R Tcommaaccent -60 KPX R U -40 KPX R Uacute -40 KPX R Ucircumflex -40 KPX R Udieresis -40 KPX R Ugrave -40 KPX R Uhungarumlaut -40 KPX R Umacron -40 KPX R Uogonek -40 KPX R Uring -40 KPX R V -80 KPX R W -55 KPX R Y -65 KPX R Yacute -65 KPX R Ydieresis -65 KPX Racute O -40 KPX Racute Oacute -40 KPX Racute Ocircumflex -40 KPX Racute Odieresis -40 KPX Racute Ograve -40 KPX Racute Ohungarumlaut -40 KPX Racute Omacron -40 KPX Racute Oslash -40 KPX Racute Otilde -40 KPX Racute T -60 KPX Racute Tcaron -60 KPX Racute Tcommaaccent -60 KPX Racute U -40 KPX Racute Uacute -40 KPX Racute Ucircumflex -40 KPX Racute Udieresis -40 KPX Racute Ugrave -40 KPX Racute Uhungarumlaut -40 KPX Racute Umacron -40 KPX Racute Uogonek -40 KPX Racute Uring -40 KPX Racute V -80 KPX Racute W -55 KPX Racute Y -65 KPX Racute Yacute -65 KPX Racute Ydieresis -65 KPX Rcaron O -40 KPX Rcaron Oacute -40 KPX Rcaron Ocircumflex -40 KPX Rcaron Odieresis -40 KPX Rcaron Ograve -40 KPX Rcaron Ohungarumlaut -40 KPX Rcaron Omacron -40 KPX Rcaron Oslash -40 KPX Rcaron Otilde -40 KPX Rcaron T -60 KPX Rcaron Tcaron -60 KPX Rcaron Tcommaaccent -60 KPX Rcaron U -40 KPX Rcaron Uacute -40 KPX Rcaron Ucircumflex -40 KPX Rcaron Udieresis -40 KPX Rcaron Ugrave -40 KPX Rcaron Uhungarumlaut -40 KPX Rcaron Umacron -40 KPX Rcaron Uogonek -40 KPX Rcaron Uring -40 KPX Rcaron V -80 KPX Rcaron W -55 KPX Rcaron Y -65 KPX Rcaron Yacute -65 KPX Rcaron Ydieresis -65 KPX Rcommaaccent O -40 KPX Rcommaaccent Oacute -40 KPX Rcommaaccent Ocircumflex -40 KPX Rcommaaccent Odieresis -40 KPX Rcommaaccent Ograve -40 KPX Rcommaaccent Ohungarumlaut -40 KPX Rcommaaccent Omacron -40 KPX Rcommaaccent Oslash -40 KPX Rcommaaccent Otilde -40 KPX Rcommaaccent T -60 KPX Rcommaaccent Tcaron -60 KPX Rcommaaccent Tcommaaccent -60 KPX Rcommaaccent U -40 KPX Rcommaaccent Uacute -40 KPX Rcommaaccent Ucircumflex -40 KPX Rcommaaccent Udieresis -40 KPX Rcommaaccent Ugrave -40 KPX Rcommaaccent Uhungarumlaut -40 KPX Rcommaaccent Umacron -40 KPX Rcommaaccent Uogonek -40 KPX Rcommaaccent Uring -40 KPX Rcommaaccent V -80 KPX Rcommaaccent W -55 KPX Rcommaaccent Y -65 KPX Rcommaaccent Yacute -65 KPX Rcommaaccent Ydieresis -65 KPX T A -93 KPX T Aacute -93 KPX T Abreve -93 KPX T Acircumflex -93 KPX T Adieresis -93 KPX T Agrave -93 KPX T Amacron -93 KPX T Aogonek -93 KPX T Aring -93 KPX T Atilde -93 KPX T O -18 KPX T Oacute -18 KPX T Ocircumflex -18 KPX T Odieresis -18 KPX T Ograve -18 KPX T Ohungarumlaut -18 KPX T Omacron -18 KPX T Oslash -18 KPX T Otilde -18 KPX T a -80 KPX T aacute -80 KPX T abreve -80 KPX T acircumflex -80 KPX T adieresis -40 KPX T agrave -40 KPX T amacron -40 KPX T aogonek -80 KPX T aring -80 KPX T atilde -40 KPX T colon -50 KPX T comma -74 KPX T e -70 KPX T eacute -70 KPX T ecaron -70 KPX T ecircumflex -70 KPX T edieresis -30 KPX T edotaccent -70 KPX T egrave -70 KPX T emacron -30 KPX T eogonek -70 KPX T hyphen -92 KPX T i -35 KPX T iacute -35 KPX T iogonek -35 KPX T o -80 KPX T oacute -80 KPX T ocircumflex -80 KPX T odieresis -80 KPX T ograve -80 KPX T ohungarumlaut -80 KPX T omacron -80 KPX T oslash -80 KPX T otilde -80 KPX T period -74 KPX T r -35 KPX T racute -35 KPX T rcaron -35 KPX T rcommaaccent -35 KPX T semicolon -55 KPX T u -45 KPX T uacute -45 KPX T ucircumflex -45 KPX T udieresis -45 KPX T ugrave -45 KPX T uhungarumlaut -45 KPX T umacron -45 KPX T uogonek -45 KPX T uring -45 KPX T w -80 KPX T y -80 KPX T yacute -80 KPX T ydieresis -80 KPX Tcaron A -93 KPX Tcaron Aacute -93 KPX Tcaron Abreve -93 KPX Tcaron Acircumflex -93 KPX Tcaron Adieresis -93 KPX Tcaron Agrave -93 KPX Tcaron Amacron -93 KPX Tcaron Aogonek -93 KPX Tcaron Aring -93 KPX Tcaron Atilde -93 KPX Tcaron O -18 KPX Tcaron Oacute -18 KPX Tcaron Ocircumflex -18 KPX Tcaron Odieresis -18 KPX Tcaron Ograve -18 KPX Tcaron Ohungarumlaut -18 KPX Tcaron Omacron -18 KPX Tcaron Oslash -18 KPX Tcaron Otilde -18 KPX Tcaron a -80 KPX Tcaron aacute -80 KPX Tcaron abreve -80 KPX Tcaron acircumflex -80 KPX Tcaron adieresis -40 KPX Tcaron agrave -40 KPX Tcaron amacron -40 KPX Tcaron aogonek -80 KPX Tcaron aring -80 KPX Tcaron atilde -40 KPX Tcaron colon -50 KPX Tcaron comma -74 KPX Tcaron e -70 KPX Tcaron eacute -70 KPX Tcaron ecaron -70 KPX Tcaron ecircumflex -30 KPX Tcaron edieresis -30 KPX Tcaron edotaccent -70 KPX Tcaron egrave -70 KPX Tcaron emacron -30 KPX Tcaron eogonek -70 KPX Tcaron hyphen -92 KPX Tcaron i -35 KPX Tcaron iacute -35 KPX Tcaron iogonek -35 KPX Tcaron o -80 KPX Tcaron oacute -80 KPX Tcaron ocircumflex -80 KPX Tcaron odieresis -80 KPX Tcaron ograve -80 KPX Tcaron ohungarumlaut -80 KPX Tcaron omacron -80 KPX Tcaron oslash -80 KPX Tcaron otilde -80 KPX Tcaron period -74 KPX Tcaron r -35 KPX Tcaron racute -35 KPX Tcaron rcaron -35 KPX Tcaron rcommaaccent -35 KPX Tcaron semicolon -55 KPX Tcaron u -45 KPX Tcaron uacute -45 KPX Tcaron ucircumflex -45 KPX Tcaron udieresis -45 KPX Tcaron ugrave -45 KPX Tcaron uhungarumlaut -45 KPX Tcaron umacron -45 KPX Tcaron uogonek -45 KPX Tcaron uring -45 KPX Tcaron w -80 KPX Tcaron y -80 KPX Tcaron yacute -80 KPX Tcaron ydieresis -80 KPX Tcommaaccent A -93 KPX Tcommaaccent Aacute -93 KPX Tcommaaccent Abreve -93 KPX Tcommaaccent Acircumflex -93 KPX Tcommaaccent Adieresis -93 KPX Tcommaaccent Agrave -93 KPX Tcommaaccent Amacron -93 KPX Tcommaaccent Aogonek -93 KPX Tcommaaccent Aring -93 KPX Tcommaaccent Atilde -93 KPX Tcommaaccent O -18 KPX Tcommaaccent Oacute -18 KPX Tcommaaccent Ocircumflex -18 KPX Tcommaaccent Odieresis -18 KPX Tcommaaccent Ograve -18 KPX Tcommaaccent Ohungarumlaut -18 KPX Tcommaaccent Omacron -18 KPX Tcommaaccent Oslash -18 KPX Tcommaaccent Otilde -18 KPX Tcommaaccent a -80 KPX Tcommaaccent aacute -80 KPX Tcommaaccent abreve -80 KPX Tcommaaccent acircumflex -80 KPX Tcommaaccent adieresis -40 KPX Tcommaaccent agrave -40 KPX Tcommaaccent amacron -40 KPX Tcommaaccent aogonek -80 KPX Tcommaaccent aring -80 KPX Tcommaaccent atilde -40 KPX Tcommaaccent colon -50 KPX Tcommaaccent comma -74 KPX Tcommaaccent e -70 KPX Tcommaaccent eacute -70 KPX Tcommaaccent ecaron -70 KPX Tcommaaccent ecircumflex -30 KPX Tcommaaccent edieresis -30 KPX Tcommaaccent edotaccent -70 KPX Tcommaaccent egrave -30 KPX Tcommaaccent emacron -70 KPX Tcommaaccent eogonek -70 KPX Tcommaaccent hyphen -92 KPX Tcommaaccent i -35 KPX Tcommaaccent iacute -35 KPX Tcommaaccent iogonek -35 KPX Tcommaaccent o -80 KPX Tcommaaccent oacute -80 KPX Tcommaaccent ocircumflex -80 KPX Tcommaaccent odieresis -80 KPX Tcommaaccent ograve -80 KPX Tcommaaccent ohungarumlaut -80 KPX Tcommaaccent omacron -80 KPX Tcommaaccent oslash -80 KPX Tcommaaccent otilde -80 KPX Tcommaaccent period -74 KPX Tcommaaccent r -35 KPX Tcommaaccent racute -35 KPX Tcommaaccent rcaron -35 KPX Tcommaaccent rcommaaccent -35 KPX Tcommaaccent semicolon -55 KPX Tcommaaccent u -45 KPX Tcommaaccent uacute -45 KPX Tcommaaccent ucircumflex -45 KPX Tcommaaccent udieresis -45 KPX Tcommaaccent ugrave -45 KPX Tcommaaccent uhungarumlaut -45 KPX Tcommaaccent umacron -45 KPX Tcommaaccent uogonek -45 KPX Tcommaaccent uring -45 KPX Tcommaaccent w -80 KPX Tcommaaccent y -80 KPX Tcommaaccent yacute -80 KPX Tcommaaccent ydieresis -80 KPX U A -40 KPX U Aacute -40 KPX U Abreve -40 KPX U Acircumflex -40 KPX U Adieresis -40 KPX U Agrave -40 KPX U Amacron -40 KPX U Aogonek -40 KPX U Aring -40 KPX U Atilde -40 KPX Uacute A -40 KPX Uacute Aacute -40 KPX Uacute Abreve -40 KPX Uacute Acircumflex -40 KPX Uacute Adieresis -40 KPX Uacute Agrave -40 KPX Uacute Amacron -40 KPX Uacute Aogonek -40 KPX Uacute Aring -40 KPX Uacute Atilde -40 KPX Ucircumflex A -40 KPX Ucircumflex Aacute -40 KPX Ucircumflex Abreve -40 KPX Ucircumflex Acircumflex -40 KPX Ucircumflex Adieresis -40 KPX Ucircumflex Agrave -40 KPX Ucircumflex Amacron -40 KPX Ucircumflex Aogonek -40 KPX Ucircumflex Aring -40 KPX Ucircumflex Atilde -40 KPX Udieresis A -40 KPX Udieresis Aacute -40 KPX Udieresis Abreve -40 KPX Udieresis Acircumflex -40 KPX Udieresis Adieresis -40 KPX Udieresis Agrave -40 KPX Udieresis Amacron -40 KPX Udieresis Aogonek -40 KPX Udieresis Aring -40 KPX Udieresis Atilde -40 KPX Ugrave A -40 KPX Ugrave Aacute -40 KPX Ugrave Abreve -40 KPX Ugrave Acircumflex -40 KPX Ugrave Adieresis -40 KPX Ugrave Agrave -40 KPX Ugrave Amacron -40 KPX Ugrave Aogonek -40 KPX Ugrave Aring -40 KPX Ugrave Atilde -40 KPX Uhungarumlaut A -40 KPX Uhungarumlaut Aacute -40 KPX Uhungarumlaut Abreve -40 KPX Uhungarumlaut Acircumflex -40 KPX Uhungarumlaut Adieresis -40 KPX Uhungarumlaut Agrave -40 KPX Uhungarumlaut Amacron -40 KPX Uhungarumlaut Aogonek -40 KPX Uhungarumlaut Aring -40 KPX Uhungarumlaut Atilde -40 KPX Umacron A -40 KPX Umacron Aacute -40 KPX Umacron Abreve -40 KPX Umacron Acircumflex -40 KPX Umacron Adieresis -40 KPX Umacron Agrave -40 KPX Umacron Amacron -40 KPX Umacron Aogonek -40 KPX Umacron Aring -40 KPX Umacron Atilde -40 KPX Uogonek A -40 KPX Uogonek Aacute -40 KPX Uogonek Abreve -40 KPX Uogonek Acircumflex -40 KPX Uogonek Adieresis -40 KPX Uogonek Agrave -40 KPX Uogonek Amacron -40 KPX Uogonek Aogonek -40 KPX Uogonek Aring -40 KPX Uogonek Atilde -40 KPX Uring A -40 KPX Uring Aacute -40 KPX Uring Abreve -40 KPX Uring Acircumflex -40 KPX Uring Adieresis -40 KPX Uring Agrave -40 KPX Uring Amacron -40 KPX Uring Aogonek -40 KPX Uring Aring -40 KPX Uring Atilde -40 KPX V A -135 KPX V Aacute -135 KPX V Abreve -135 KPX V Acircumflex -135 KPX V Adieresis -135 KPX V Agrave -135 KPX V Amacron -135 KPX V Aogonek -135 KPX V Aring -135 KPX V Atilde -135 KPX V G -15 KPX V Gbreve -15 KPX V Gcommaaccent -15 KPX V O -40 KPX V Oacute -40 KPX V Ocircumflex -40 KPX V Odieresis -40 KPX V Ograve -40 KPX V Ohungarumlaut -40 KPX V Omacron -40 KPX V Oslash -40 KPX V Otilde -40 KPX V a -111 KPX V aacute -111 KPX V abreve -111 KPX V acircumflex -71 KPX V adieresis -71 KPX V agrave -71 KPX V amacron -71 KPX V aogonek -111 KPX V aring -111 KPX V atilde -71 KPX V colon -74 KPX V comma -129 KPX V e -111 KPX V eacute -111 KPX V ecaron -71 KPX V ecircumflex -71 KPX V edieresis -71 KPX V edotaccent -111 KPX V egrave -71 KPX V emacron -71 KPX V eogonek -111 KPX V hyphen -100 KPX V i -60 KPX V iacute -60 KPX V icircumflex -20 KPX V idieresis -20 KPX V igrave -20 KPX V imacron -20 KPX V iogonek -60 KPX V o -129 KPX V oacute -129 KPX V ocircumflex -129 KPX V odieresis -89 KPX V ograve -89 KPX V ohungarumlaut -129 KPX V omacron -89 KPX V oslash -129 KPX V otilde -89 KPX V period -129 KPX V semicolon -74 KPX V u -75 KPX V uacute -75 KPX V ucircumflex -75 KPX V udieresis -75 KPX V ugrave -75 KPX V uhungarumlaut -75 KPX V umacron -75 KPX V uogonek -75 KPX V uring -75 KPX W A -120 KPX W Aacute -120 KPX W Abreve -120 KPX W Acircumflex -120 KPX W Adieresis -120 KPX W Agrave -120 KPX W Amacron -120 KPX W Aogonek -120 KPX W Aring -120 KPX W Atilde -120 KPX W O -10 KPX W Oacute -10 KPX W Ocircumflex -10 KPX W Odieresis -10 KPX W Ograve -10 KPX W Ohungarumlaut -10 KPX W Omacron -10 KPX W Oslash -10 KPX W Otilde -10 KPX W a -80 KPX W aacute -80 KPX W abreve -80 KPX W acircumflex -80 KPX W adieresis -80 KPX W agrave -80 KPX W amacron -80 KPX W aogonek -80 KPX W aring -80 KPX W atilde -80 KPX W colon -37 KPX W comma -92 KPX W e -80 KPX W eacute -80 KPX W ecaron -80 KPX W ecircumflex -80 KPX W edieresis -40 KPX W edotaccent -80 KPX W egrave -40 KPX W emacron -40 KPX W eogonek -80 KPX W hyphen -65 KPX W i -40 KPX W iacute -40 KPX W iogonek -40 KPX W o -80 KPX W oacute -80 KPX W ocircumflex -80 KPX W odieresis -80 KPX W ograve -80 KPX W ohungarumlaut -80 KPX W omacron -80 KPX W oslash -80 KPX W otilde -80 KPX W period -92 KPX W semicolon -37 KPX W u -50 KPX W uacute -50 KPX W ucircumflex -50 KPX W udieresis -50 KPX W ugrave -50 KPX W uhungarumlaut -50 KPX W umacron -50 KPX W uogonek -50 KPX W uring -50 KPX W y -73 KPX W yacute -73 KPX W ydieresis -73 KPX Y A -120 KPX Y Aacute -120 KPX Y Abreve -120 KPX Y Acircumflex -120 KPX Y Adieresis -120 KPX Y Agrave -120 KPX Y Amacron -120 KPX Y Aogonek -120 KPX Y Aring -120 KPX Y Atilde -120 KPX Y O -30 KPX Y Oacute -30 KPX Y Ocircumflex -30 KPX Y Odieresis -30 KPX Y Ograve -30 KPX Y Ohungarumlaut -30 KPX Y Omacron -30 KPX Y Oslash -30 KPX Y Otilde -30 KPX Y a -100 KPX Y aacute -100 KPX Y abreve -100 KPX Y acircumflex -100 KPX Y adieresis -60 KPX Y agrave -60 KPX Y amacron -60 KPX Y aogonek -100 KPX Y aring -100 KPX Y atilde -60 KPX Y colon -92 KPX Y comma -129 KPX Y e -100 KPX Y eacute -100 KPX Y ecaron -100 KPX Y ecircumflex -100 KPX Y edieresis -60 KPX Y edotaccent -100 KPX Y egrave -60 KPX Y emacron -60 KPX Y eogonek -100 KPX Y hyphen -111 KPX Y i -55 KPX Y iacute -55 KPX Y iogonek -55 KPX Y o -110 KPX Y oacute -110 KPX Y ocircumflex -110 KPX Y odieresis -70 KPX Y ograve -70 KPX Y ohungarumlaut -110 KPX Y omacron -70 KPX Y oslash -110 KPX Y otilde -70 KPX Y period -129 KPX Y semicolon -92 KPX Y u -111 KPX Y uacute -111 KPX Y ucircumflex -111 KPX Y udieresis -71 KPX Y ugrave -71 KPX Y uhungarumlaut -111 KPX Y umacron -71 KPX Y uogonek -111 KPX Y uring -111 KPX Yacute A -120 KPX Yacute Aacute -120 KPX Yacute Abreve -120 KPX Yacute Acircumflex -120 KPX Yacute Adieresis -120 KPX Yacute Agrave -120 KPX Yacute Amacron -120 KPX Yacute Aogonek -120 KPX Yacute Aring -120 KPX Yacute Atilde -120 KPX Yacute O -30 KPX Yacute Oacute -30 KPX Yacute Ocircumflex -30 KPX Yacute Odieresis -30 KPX Yacute Ograve -30 KPX Yacute Ohungarumlaut -30 KPX Yacute Omacron -30 KPX Yacute Oslash -30 KPX Yacute Otilde -30 KPX Yacute a -100 KPX Yacute aacute -100 KPX Yacute abreve -100 KPX Yacute acircumflex -100 KPX Yacute adieresis -60 KPX Yacute agrave -60 KPX Yacute amacron -60 KPX Yacute aogonek -100 KPX Yacute aring -100 KPX Yacute atilde -60 KPX Yacute colon -92 KPX Yacute comma -129 KPX Yacute e -100 KPX Yacute eacute -100 KPX Yacute ecaron -100 KPX Yacute ecircumflex -100 KPX Yacute edieresis -60 KPX Yacute edotaccent -100 KPX Yacute egrave -60 KPX Yacute emacron -60 KPX Yacute eogonek -100 KPX Yacute hyphen -111 KPX Yacute i -55 KPX Yacute iacute -55 KPX Yacute iogonek -55 KPX Yacute o -110 KPX Yacute oacute -110 KPX Yacute ocircumflex -110 KPX Yacute odieresis -70 KPX Yacute ograve -70 KPX Yacute ohungarumlaut -110 KPX Yacute omacron -70 KPX Yacute oslash -110 KPX Yacute otilde -70 KPX Yacute period -129 KPX Yacute semicolon -92 KPX Yacute u -111 KPX Yacute uacute -111 KPX Yacute ucircumflex -111 KPX Yacute udieresis -71 KPX Yacute ugrave -71 KPX Yacute uhungarumlaut -111 KPX Yacute umacron -71 KPX Yacute uogonek -111 KPX Yacute uring -111 KPX Ydieresis A -120 KPX Ydieresis Aacute -120 KPX Ydieresis Abreve -120 KPX Ydieresis Acircumflex -120 KPX Ydieresis Adieresis -120 KPX Ydieresis Agrave -120 KPX Ydieresis Amacron -120 KPX Ydieresis Aogonek -120 KPX Ydieresis Aring -120 KPX Ydieresis Atilde -120 KPX Ydieresis O -30 KPX Ydieresis Oacute -30 KPX Ydieresis Ocircumflex -30 KPX Ydieresis Odieresis -30 KPX Ydieresis Ograve -30 KPX Ydieresis Ohungarumlaut -30 KPX Ydieresis Omacron -30 KPX Ydieresis Oslash -30 KPX Ydieresis Otilde -30 KPX Ydieresis a -100 KPX Ydieresis aacute -100 KPX Ydieresis abreve -100 KPX Ydieresis acircumflex -100 KPX Ydieresis adieresis -60 KPX Ydieresis agrave -60 KPX Ydieresis amacron -60 KPX Ydieresis aogonek -100 KPX Ydieresis aring -100 KPX Ydieresis atilde -100 KPX Ydieresis colon -92 KPX Ydieresis comma -129 KPX Ydieresis e -100 KPX Ydieresis eacute -100 KPX Ydieresis ecaron -100 KPX Ydieresis ecircumflex -100 KPX Ydieresis edieresis -60 KPX Ydieresis edotaccent -100 KPX Ydieresis egrave -60 KPX Ydieresis emacron -60 KPX Ydieresis eogonek -100 KPX Ydieresis hyphen -111 KPX Ydieresis i -55 KPX Ydieresis iacute -55 KPX Ydieresis iogonek -55 KPX Ydieresis o -110 KPX Ydieresis oacute -110 KPX Ydieresis ocircumflex -110 KPX Ydieresis odieresis -70 KPX Ydieresis ograve -70 KPX Ydieresis ohungarumlaut -110 KPX Ydieresis omacron -70 KPX Ydieresis oslash -110 KPX Ydieresis otilde -70 KPX Ydieresis period -129 KPX Ydieresis semicolon -92 KPX Ydieresis u -111 KPX Ydieresis uacute -111 KPX Ydieresis ucircumflex -111 KPX Ydieresis udieresis -71 KPX Ydieresis ugrave -71 KPX Ydieresis uhungarumlaut -111 KPX Ydieresis umacron -71 KPX Ydieresis uogonek -111 KPX Ydieresis uring -111 KPX a v -20 KPX a w -15 KPX aacute v -20 KPX aacute w -15 KPX abreve v -20 KPX abreve w -15 KPX acircumflex v -20 KPX acircumflex w -15 KPX adieresis v -20 KPX adieresis w -15 KPX agrave v -20 KPX agrave w -15 KPX amacron v -20 KPX amacron w -15 KPX aogonek v -20 KPX aogonek w -15 KPX aring v -20 KPX aring w -15 KPX atilde v -20 KPX atilde w -15 KPX b period -40 KPX b u -20 KPX b uacute -20 KPX b ucircumflex -20 KPX b udieresis -20 KPX b ugrave -20 KPX b uhungarumlaut -20 KPX b umacron -20 KPX b uogonek -20 KPX b uring -20 KPX b v -15 KPX c y -15 KPX c yacute -15 KPX c ydieresis -15 KPX cacute y -15 KPX cacute yacute -15 KPX cacute ydieresis -15 KPX ccaron y -15 KPX ccaron yacute -15 KPX ccaron ydieresis -15 KPX ccedilla y -15 KPX ccedilla yacute -15 KPX ccedilla ydieresis -15 KPX comma quotedblright -70 KPX comma quoteright -70 KPX e g -15 KPX e gbreve -15 KPX e gcommaaccent -15 KPX e v -25 KPX e w -25 KPX e x -15 KPX e y -15 KPX e yacute -15 KPX e ydieresis -15 KPX eacute g -15 KPX eacute gbreve -15 KPX eacute gcommaaccent -15 KPX eacute v -25 KPX eacute w -25 KPX eacute x -15 KPX eacute y -15 KPX eacute yacute -15 KPX eacute ydieresis -15 KPX ecaron g -15 KPX ecaron gbreve -15 KPX ecaron gcommaaccent -15 KPX ecaron v -25 KPX ecaron w -25 KPX ecaron x -15 KPX ecaron y -15 KPX ecaron yacute -15 KPX ecaron ydieresis -15 KPX ecircumflex g -15 KPX ecircumflex gbreve -15 KPX ecircumflex gcommaaccent -15 KPX ecircumflex v -25 KPX ecircumflex w -25 KPX ecircumflex x -15 KPX ecircumflex y -15 KPX ecircumflex yacute -15 KPX ecircumflex ydieresis -15 KPX edieresis g -15 KPX edieresis gbreve -15 KPX edieresis gcommaaccent -15 KPX edieresis v -25 KPX edieresis w -25 KPX edieresis x -15 KPX edieresis y -15 KPX edieresis yacute -15 KPX edieresis ydieresis -15 KPX edotaccent g -15 KPX edotaccent gbreve -15 KPX edotaccent gcommaaccent -15 KPX edotaccent v -25 KPX edotaccent w -25 KPX edotaccent x -15 KPX edotaccent y -15 KPX edotaccent yacute -15 KPX edotaccent ydieresis -15 KPX egrave g -15 KPX egrave gbreve -15 KPX egrave gcommaaccent -15 KPX egrave v -25 KPX egrave w -25 KPX egrave x -15 KPX egrave y -15 KPX egrave yacute -15 KPX egrave ydieresis -15 KPX emacron g -15 KPX emacron gbreve -15 KPX emacron gcommaaccent -15 KPX emacron v -25 KPX emacron w -25 KPX emacron x -15 KPX emacron y -15 KPX emacron yacute -15 KPX emacron ydieresis -15 KPX eogonek g -15 KPX eogonek gbreve -15 KPX eogonek gcommaaccent -15 KPX eogonek v -25 KPX eogonek w -25 KPX eogonek x -15 KPX eogonek y -15 KPX eogonek yacute -15 KPX eogonek ydieresis -15 KPX f a -10 KPX f aacute -10 KPX f abreve -10 KPX f acircumflex -10 KPX f adieresis -10 KPX f agrave -10 KPX f amacron -10 KPX f aogonek -10 KPX f aring -10 KPX f atilde -10 KPX f dotlessi -50 KPX f f -25 KPX f i -20 KPX f iacute -20 KPX f quoteright 55 KPX g a -5 KPX g aacute -5 KPX g abreve -5 KPX g acircumflex -5 KPX g adieresis -5 KPX g agrave -5 KPX g amacron -5 KPX g aogonek -5 KPX g aring -5 KPX g atilde -5 KPX gbreve a -5 KPX gbreve aacute -5 KPX gbreve abreve -5 KPX gbreve acircumflex -5 KPX gbreve adieresis -5 KPX gbreve agrave -5 KPX gbreve amacron -5 KPX gbreve aogonek -5 KPX gbreve aring -5 KPX gbreve atilde -5 KPX gcommaaccent a -5 KPX gcommaaccent aacute -5 KPX gcommaaccent abreve -5 KPX gcommaaccent acircumflex -5 KPX gcommaaccent adieresis -5 KPX gcommaaccent agrave -5 KPX gcommaaccent amacron -5 KPX gcommaaccent aogonek -5 KPX gcommaaccent aring -5 KPX gcommaaccent atilde -5 KPX h y -5 KPX h yacute -5 KPX h ydieresis -5 KPX i v -25 KPX iacute v -25 KPX icircumflex v -25 KPX idieresis v -25 KPX igrave v -25 KPX imacron v -25 KPX iogonek v -25 KPX k e -10 KPX k eacute -10 KPX k ecaron -10 KPX k ecircumflex -10 KPX k edieresis -10 KPX k edotaccent -10 KPX k egrave -10 KPX k emacron -10 KPX k eogonek -10 KPX k o -10 KPX k oacute -10 KPX k ocircumflex -10 KPX k odieresis -10 KPX k ograve -10 KPX k ohungarumlaut -10 KPX k omacron -10 KPX k oslash -10 KPX k otilde -10 KPX k y -15 KPX k yacute -15 KPX k ydieresis -15 KPX kcommaaccent e -10 KPX kcommaaccent eacute -10 KPX kcommaaccent ecaron -10 KPX kcommaaccent ecircumflex -10 KPX kcommaaccent edieresis -10 KPX kcommaaccent edotaccent -10 KPX kcommaaccent egrave -10 KPX kcommaaccent emacron -10 KPX kcommaaccent eogonek -10 KPX kcommaaccent o -10 KPX kcommaaccent oacute -10 KPX kcommaaccent ocircumflex -10 KPX kcommaaccent odieresis -10 KPX kcommaaccent ograve -10 KPX kcommaaccent ohungarumlaut -10 KPX kcommaaccent omacron -10 KPX kcommaaccent oslash -10 KPX kcommaaccent otilde -10 KPX kcommaaccent y -15 KPX kcommaaccent yacute -15 KPX kcommaaccent ydieresis -15 KPX l w -10 KPX lacute w -10 KPX lcommaaccent w -10 KPX lslash w -10 KPX n v -40 KPX n y -15 KPX n yacute -15 KPX n ydieresis -15 KPX nacute v -40 KPX nacute y -15 KPX nacute yacute -15 KPX nacute ydieresis -15 KPX ncaron v -40 KPX ncaron y -15 KPX ncaron yacute -15 KPX ncaron ydieresis -15 KPX ncommaaccent v -40 KPX ncommaaccent y -15 KPX ncommaaccent yacute -15 KPX ncommaaccent ydieresis -15 KPX ntilde v -40 KPX ntilde y -15 KPX ntilde yacute -15 KPX ntilde ydieresis -15 KPX o v -15 KPX o w -25 KPX o y -10 KPX o yacute -10 KPX o ydieresis -10 KPX oacute v -15 KPX oacute w -25 KPX oacute y -10 KPX oacute yacute -10 KPX oacute ydieresis -10 KPX ocircumflex v -15 KPX ocircumflex w -25 KPX ocircumflex y -10 KPX ocircumflex yacute -10 KPX ocircumflex ydieresis -10 KPX odieresis v -15 KPX odieresis w -25 KPX odieresis y -10 KPX odieresis yacute -10 KPX odieresis ydieresis -10 KPX ograve v -15 KPX ograve w -25 KPX ograve y -10 KPX ograve yacute -10 KPX ograve ydieresis -10 KPX ohungarumlaut v -15 KPX ohungarumlaut w -25 KPX ohungarumlaut y -10 KPX ohungarumlaut yacute -10 KPX ohungarumlaut ydieresis -10 KPX omacron v -15 KPX omacron w -25 KPX omacron y -10 KPX omacron yacute -10 KPX omacron ydieresis -10 KPX oslash v -15 KPX oslash w -25 KPX oslash y -10 KPX oslash yacute -10 KPX oslash ydieresis -10 KPX otilde v -15 KPX otilde w -25 KPX otilde y -10 KPX otilde yacute -10 KPX otilde ydieresis -10 KPX p y -10 KPX p yacute -10 KPX p ydieresis -10 KPX period quotedblright -70 KPX period quoteright -70 KPX quotedblleft A -80 KPX quotedblleft Aacute -80 KPX quotedblleft Abreve -80 KPX quotedblleft Acircumflex -80 KPX quotedblleft Adieresis -80 KPX quotedblleft Agrave -80 KPX quotedblleft Amacron -80 KPX quotedblleft Aogonek -80 KPX quotedblleft Aring -80 KPX quotedblleft Atilde -80 KPX quoteleft A -80 KPX quoteleft Aacute -80 KPX quoteleft Abreve -80 KPX quoteleft Acircumflex -80 KPX quoteleft Adieresis -80 KPX quoteleft Agrave -80 KPX quoteleft Amacron -80 KPX quoteleft Aogonek -80 KPX quoteleft Aring -80 KPX quoteleft Atilde -80 KPX quoteleft quoteleft -74 KPX quoteright d -50 KPX quoteright dcroat -50 KPX quoteright l -10 KPX quoteright lacute -10 KPX quoteright lcommaaccent -10 KPX quoteright lslash -10 KPX quoteright quoteright -74 KPX quoteright r -50 KPX quoteright racute -50 KPX quoteright rcaron -50 KPX quoteright rcommaaccent -50 KPX quoteright s -55 KPX quoteright sacute -55 KPX quoteright scaron -55 KPX quoteright scedilla -55 KPX quoteright scommaaccent -55 KPX quoteright space -74 KPX quoteright t -18 KPX quoteright tcommaaccent -18 KPX quoteright v -50 KPX r comma -40 KPX r g -18 KPX r gbreve -18 KPX r gcommaaccent -18 KPX r hyphen -20 KPX r period -55 KPX racute comma -40 KPX racute g -18 KPX racute gbreve -18 KPX racute gcommaaccent -18 KPX racute hyphen -20 KPX racute period -55 KPX rcaron comma -40 KPX rcaron g -18 KPX rcaron gbreve -18 KPX rcaron gcommaaccent -18 KPX rcaron hyphen -20 KPX rcaron period -55 KPX rcommaaccent comma -40 KPX rcommaaccent g -18 KPX rcommaaccent gbreve -18 KPX rcommaaccent gcommaaccent -18 KPX rcommaaccent hyphen -20 KPX rcommaaccent period -55 KPX space A -55 KPX space Aacute -55 KPX space Abreve -55 KPX space Acircumflex -55 KPX space Adieresis -55 KPX space Agrave -55 KPX space Amacron -55 KPX space Aogonek -55 KPX space Aring -55 KPX space Atilde -55 KPX space T -18 KPX space Tcaron -18 KPX space Tcommaaccent -18 KPX space V -50 KPX space W -30 KPX space Y -90 KPX space Yacute -90 KPX space Ydieresis -90 KPX v a -25 KPX v aacute -25 KPX v abreve -25 KPX v acircumflex -25 KPX v adieresis -25 KPX v agrave -25 KPX v amacron -25 KPX v aogonek -25 KPX v aring -25 KPX v atilde -25 KPX v comma -65 KPX v e -15 KPX v eacute -15 KPX v ecaron -15 KPX v ecircumflex -15 KPX v edieresis -15 KPX v edotaccent -15 KPX v egrave -15 KPX v emacron -15 KPX v eogonek -15 KPX v o -20 KPX v oacute -20 KPX v ocircumflex -20 KPX v odieresis -20 KPX v ograve -20 KPX v ohungarumlaut -20 KPX v omacron -20 KPX v oslash -20 KPX v otilde -20 KPX v period -65 KPX w a -10 KPX w aacute -10 KPX w abreve -10 KPX w acircumflex -10 KPX w adieresis -10 KPX w agrave -10 KPX w amacron -10 KPX w aogonek -10 KPX w aring -10 KPX w atilde -10 KPX w comma -65 KPX w o -10 KPX w oacute -10 KPX w ocircumflex -10 KPX w odieresis -10 KPX w ograve -10 KPX w ohungarumlaut -10 KPX w omacron -10 KPX w oslash -10 KPX w otilde -10 KPX w period -65 KPX x e -15 KPX x eacute -15 KPX x ecaron -15 KPX x ecircumflex -15 KPX x edieresis -15 KPX x edotaccent -15 KPX x egrave -15 KPX x emacron -15 KPX x eogonek -15 KPX y comma -65 KPX y period -65 KPX yacute comma -65 KPX yacute period -65 KPX ydieresis comma -65 KPX ydieresis period -65 EndKernPairs EndKernData EndFontMetrics src/core/com/lowagie/text/pdf/fonts/ZapfDingbats.afm100644 0 0 23030 11000354125 20065 0ustar 0 0 StartFontMetrics 4.1 Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved. Comment Creation Date: Thu May 1 15:14:13 1997 Comment UniqueID 43082 Comment VMusage 45775 55535 FontName ZapfDingbats FullName ITC Zapf Dingbats FamilyName ZapfDingbats Weight Medium ItalicAngle 0 IsFixedPitch false CharacterSet Special FontBBox -1 -143 981 820 UnderlinePosition -100 UnderlineThickness 50 Version 002.000 Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation. EncodingScheme FontSpecific StdHW 28 StdVW 90 StartCharMetrics 202 C 32 ; WX 278 ; N space ; B 0 0 0 0 ; C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ; C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ; C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ; C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ; C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ; C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ; C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ; C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ; C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ; C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ; C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ; C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ; C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ; C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ; C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ; C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ; C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ; C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ; C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ; C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ; C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ; C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ; C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ; C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ; C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ; C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ; C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ; C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ; C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ; C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ; C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ; C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ; C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ; C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ; C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ; C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ; C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ; C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ; C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ; C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ; C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ; C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ; C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ; C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ; C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ; C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ; C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ; C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ; C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ; C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ; C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ; C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ; C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ; C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ; C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ; C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ; C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ; C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ; C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ; C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ; C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ; C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ; C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ; C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ; C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ; C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ; C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ; C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ; C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ; C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ; C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ; C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ; C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ; C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ; C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ; C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ; C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ; C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ; C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ; C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ; C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ; C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ; C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ; C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ; C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ; C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ; C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ; C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ; C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ; C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ; C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ; C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ; C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ; C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ; C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ; C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ; C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ; C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ; C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ; C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ; C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ; C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ; C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ; C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ; C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ; C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ; C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ; C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ; C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ; C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ; C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ; C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ; C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ; C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ; C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ; C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ; C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ; C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ; C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ; C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ; C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ; C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ; C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ; C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ; C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ; C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ; C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ; C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ; C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ; C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ; C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ; C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ; C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ; C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ; C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ; C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ; C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ; C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ; C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ; C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ; C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ; C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ; C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ; C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ; C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ; C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ; C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ; C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ; C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ; C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ; C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ; C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ; C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ; C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ; C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ; C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ; C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ; C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ; C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ; C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ; C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ; C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ; C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ; C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ; C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ; C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ; C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ; C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ; C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ; C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ; C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ; C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ; C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ; C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ; C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ; C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ; C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ; C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ; C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ; C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ; C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ; C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ; C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ; C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ; C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ; C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ; C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ; C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ; C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ; C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ; C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ; C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ; C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ; C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ; C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ; C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ; C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ; C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ; C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ; C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ; C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ; EndCharMetrics EndFontMetrics src/core/com/lowagie/text/pdf/fonts/cmap_info.txt100644 0 0 12267 11000354125 17532 0ustar 0 0 The *.cmap and *.properties files in this jar are necessary to produce PDF files with iText that use CJK fonts. Note that whatever value you pass for the 'embedded' parameter with the method BaseFont.createFont, the font WILL NOT BE embedded. To understand why, please read the following information. The fonts that are used in Acrobat Reader when viewing a PDF file that uses CJK fonts will be downloaded in one or more font packs. You can download these fontpacks yourself from this URL: http://www.adobe.com/products/acrobat/acrrasianfontpack.html On this page, you can find the following information: "If the author of an Adobe (R) Portable Document Format (PDF) file embeds CJK and Central European (CE) fonts in a PDF document, then any language version of Adobe Reader (R) software will be able to display the CJK and CE text on any system without additional software. If the author of the PDF document uses CJK or CE fonts but does not embed them in the document, then the correct fonts will need to be installed in order to view the Adobe PDF file on non-native systems." When you download one of the font packs, for instance the font pack for "Chinese Simplified", you will see that the fonts are licensed for use in Adobe Reader only: "Note: The font software contained in this package is being licensed to you solely for use with Adobe (R) Acrobat (R) Reader (R) software ("Acrobat Reader") and is subject to the terms and conditions of the electronic End-User License Agreement accompanying Acrobat Reader." This explains why iText doesn't ever embed a CJK font in the PDF file. These fonts have to be downloaded and used in the context of Adobe Reader; you can not use them with iText to produce a PDF document that has these fonts embedded (as you would do with other fonts) so that they can be viewed in other readers; unless you have a license from Adobe to use these fonts. The *.cmap and *.properties files in this jar, do not contain any font program. They contain information (mappings, metrics,...) that is based on font information distributed on Adobe's site: http://partners.adobe.com/public/developer/acrobat/index_advanced.html#pci The original copyright notice of the mappings is as follows: "Copyright 1990-2000 Adobe Systems Incorporated. All Rights Reserved. Patents Pending NOTICE: All information contained herein is the property of Adobe Systems Incorporated. Permission is granted for redistribution of this file provided this copyright notice is maintained intact and that the contents of this file are not altered in any way from its original form. PostScript and Display PostScript are trademarks of Adobe Systems Incorporated which may be registered in certain jurisdictions." The original files with the mappings are plain text files, and therefore not optimized for being read by a computer software program. That's why they were pre-processed to map directly the Unicode value with the CID value using a 64k char array. No data was changed in this process. Additionally, the iTextAsian.jar contains some properties files with font metrics. These are included for the same reason AFM files are needed (see also the file mustRead.html shipped with the iText.jar). As defined in the PDF reference: "The width information for each glyph is stored both in the font dictionary and in the font program itself. (The two sets of widths must be identical; storing this information in the font dictionary, although redundant, enables a consumer application to determine glyph positioning without having to look inside the font program.)" See PDF Reference sixth edition section 5.1.3 (p393-394). Whereas in the case of CJK fonts, the font program is subject to the Adobe Reader EULA, the font metrics aren't. Page 396: "Glyph metric information is also available separately in the form of Adobe font metrics (AFM) and Adobe composite font metrics (ACFM) files. These files are for use by application programs that generate PDF page descriptions and must make formatting decisions based on the widths and other metrics of glyphs. (...) Specifications for the AFM and ACFM file formats are available in Adobe Technical Note #5004, Adobe Font Metrics File Format Specification; the files can be obtained from the Adobe Solutions Network Web site." Unfortuntately the URL of these files has changed over time, and some metrics files seem to have been removed. However, you'll find sufficient information in the Technical Notes to build your own AFM and/or ACFM files if you ever need font metrics in the Adobe Font Metrics format. Note that the properties files in the iTextAsian.jar contain font metrics, but they are not stored in the AFM or ACFM format. For reasons of performance, the font metrics were stored as key-value pairs. Compare the keys in the properties files with the keys mentioned in Table 5.19 on p456 of the PDF Reference. This way, the necessary key-value pairs can be imported directly into a Font Dictionary that is part of a PDF file created by iText. These specific metrics files were created by Paulo Soares and may be used, copied, and distributed for any purpose and without charge, with or without modification.src/core/com/lowagie/text/pdf/fonts/cmaps/CMap.java100644 0 0 11501 11154165266 17632 0ustar 0 0 /** * Copyright (c) 2005, www.fontbox.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of fontbox; nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * http://www.fontbox.org * */ package com.lowagie.text.pdf.fonts.cmaps; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This class represents a CMap file. * * @author Ben Litchfield (ben@benlitchfield.com) * @since 2.1.4 */ public class CMap { private List codeSpaceRanges = new ArrayList(); private Map singleByteMappings = new HashMap(); private Map doubleByteMappings = new HashMap(); /** * Creates a new instance of CMap. */ public CMap() { //default constructor } /** * This will tell if this cmap has any one byte mappings. * * @return true If there are any one byte mappings, false otherwise. */ public boolean hasOneByteMappings() { return !singleByteMappings.isEmpty(); } /** * This will tell if this cmap has any two byte mappings. * * @return true If there are any two byte mappings, false otherwise. */ public boolean hasTwoByteMappings() { return !doubleByteMappings.isEmpty(); } /** * This will perform a lookup into the map. * * @param code The code used to lookup. * @param offset The offset into the byte array. * @param length The length of the data we are getting. * * @return The string that matches the lookup. */ public String lookup( byte[] code, int offset, int length ) { String result = null; Integer key = null; if( length == 1 ) { key = new Integer( (code[offset]+256)%256 ); result = (String)singleByteMappings.get( key ); } else if( length == 2 ) { int intKey = (code[offset]+256)%256; intKey <<= 8; intKey += (code[offset+1]+256)%256; key = new Integer( intKey ); result = (String)doubleByteMappings.get( key ); } return result; } /** * This will add a mapping. * * @param src The src to the mapping. * @param dest The dest to the mapping. * * @throws IOException if the src is invalid. */ public void addMapping( byte[] src, String dest ) throws IOException { if( src.length == 1 ) { singleByteMappings.put( new Integer( src[0] ), dest ); } else if( src.length == 2 ) { int intSrc = src[0]&0xFF; intSrc <<= 8; intSrc |= (src[1]&0xFF); doubleByteMappings.put( new Integer( intSrc ), dest ); } else { throw new IOException( "Mapping code should be 1 or two bytes and not " + src.length ); } } /** * This will add a codespace range. * * @param range A single codespace range. */ public void addCodespaceRange( CodespaceRange range ) { codeSpaceRanges.add( range ); } /** * Getter for property codeSpaceRanges. * * @return Value of property codeSpaceRanges. */ public List getCodeSpaceRanges() { return codeSpaceRanges; } }src/core/com/lowagie/text/pdf/fonts/cmaps/CMapParser.java100644 0 0 42323 11213370070 21000 0ustar 0 0 /** * Copyright (c) 2005-2006, www.fontbox.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of fontbox; nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * http://www.fontbox.org * */ package com.lowagie.text.pdf.fonts.cmaps; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.PushbackInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This will parser a CMap stream. * * @author Ben Litchfield * @version $Revision: 3943 $ * @since 2.1.4 */ public class CMapParser { private static final String BEGIN_CODESPACE_RANGE = "begincodespacerange"; private static final String BEGIN_BASE_FONT_CHAR = "beginbfchar"; private static final String BEGIN_BASE_FONT_RANGE = "beginbfrange"; private static final String MARK_END_OF_DICTIONARY = ">>"; private static final String MARK_END_OF_ARRAY = "]"; private byte[] tokenParserByteBuffer = new byte[512]; /** * Creates a new instance of CMapParser. */ public CMapParser() { } /** * This will parse the stream and create a cmap object. * * @param input The CMAP stream to parse. * @return The parsed stream as a java object. * * @throws IOException If there is an error parsing the stream. */ public CMap parse( InputStream input ) throws IOException { PushbackInputStream cmapStream = new PushbackInputStream( input ); CMap result = new CMap(); Object previousToken = null; Object token = null; while( (token = parseNextToken( cmapStream )) != null ) { if( token instanceof Operator ) { Operator op = (Operator)token; if( op.op.equals( BEGIN_CODESPACE_RANGE ) ) { Number cosCount = (Number)previousToken; for( int j=0; j= 0 ) { done = true; } value = createStringFromBytes( tokenBytes ); result.addMapping( startCode, value ); increment( startCode ); if( array == null ) { increment( tokenBytes ); } else { arrayIndex++; if( arrayIndex < array.size() ) { tokenBytes = (byte[])array.get( arrayIndex ); } } } } } } previousToken = token; } return result; } private Object parseNextToken( PushbackInputStream is ) throws IOException { Object retval = null; int nextByte = is.read(); //skip whitespace while( nextByte == 0x09 || nextByte == 0x20 || nextByte == 0x0D || nextByte == 0x0A ) { nextByte = is.read(); } switch( nextByte ) { case '%': { //header operations, for now return the entire line //may need to smarter in the future StringBuffer buffer = new StringBuffer(); buffer.append( (char)nextByte ); readUntilEndOfLine( is, buffer ); retval = buffer.toString(); break; } case '(': { StringBuffer buffer = new StringBuffer(); int stringByte = is.read(); while( stringByte != -1 && stringByte != ')' ) { buffer.append( (char)stringByte ); stringByte = is.read(); } retval = buffer.toString(); break; } case '>': { int secondCloseBrace = is.read(); if( secondCloseBrace == '>' ) { retval = MARK_END_OF_DICTIONARY; } else { throw new IOException( "Error: expected the end of a dictionary."); } break; } case ']': { retval = MARK_END_OF_ARRAY; break; } case '[': { List list = new ArrayList(); Object nextToken = parseNextToken( is ); while( nextToken != MARK_END_OF_ARRAY ) { list.add( nextToken ); nextToken = parseNextToken( is ); } retval = list; break; } case '<': { int theNextByte = is.read(); if( theNextByte == '<' ) { Map result = new HashMap(); //we are reading a dictionary Object key = parseNextToken( is ); while( key instanceof LiteralName && key != MARK_END_OF_DICTIONARY ) { Object value = parseNextToken( is ); result.put( ((LiteralName)key).name, value ); key = parseNextToken( is ); } retval = result; } else { //won't read more than 512 bytes int multiplyer = 16; int bufferIndex = -1; while( theNextByte != -1 && theNextByte != '>' ) { int intValue = 0; if( theNextByte >= '0' && theNextByte <= '9' ) { intValue = theNextByte - '0'; } else if( theNextByte >= 'A' && theNextByte <= 'F' ) { intValue = 10 + theNextByte - 'A'; } else if( theNextByte >= 'a' && theNextByte <= 'f' ) { intValue = 10 + theNextByte - 'a'; } else { throw new IOException( "Error: expected hex character and not " + (char)theNextByte + ":" + theNextByte ); } intValue *= multiplyer; if( multiplyer == 16 ) { bufferIndex++; tokenParserByteBuffer[bufferIndex] = 0; multiplyer = 1; } else { multiplyer = 16; } tokenParserByteBuffer[bufferIndex]+= intValue; theNextByte = is.read(); } byte[] finalResult = new byte[bufferIndex+1]; System.arraycopy(tokenParserByteBuffer,0,finalResult, 0, bufferIndex+1); retval = finalResult; } break; } case '/': { StringBuffer buffer = new StringBuffer(); int stringByte = is.read(); while( !isWhitespaceOrEOF( stringByte ) ) { buffer.append( (char)stringByte ); stringByte = is.read(); } retval = new LiteralName( buffer.toString() ); break; } case -1: { //EOF return null; break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { StringBuffer buffer = new StringBuffer(); buffer.append( (char)nextByte ); nextByte = is.read(); while( !isWhitespaceOrEOF( nextByte ) && (Character.isDigit( (char)nextByte )|| nextByte == '.' ) ) { buffer.append( (char)nextByte ); nextByte = is.read(); } is.unread( nextByte ); String value = buffer.toString(); if( value.indexOf( '.' ) >=0 ) { retval = new Double( value ); } else { retval = new Integer( buffer.toString() ); } break; } default: { StringBuffer buffer = new StringBuffer(); buffer.append( (char)nextByte ); nextByte = is.read(); while( !isWhitespaceOrEOF( nextByte ) ) { buffer.append( (char)nextByte ); nextByte = is.read(); } retval = new Operator( buffer.toString() ); break; } } return retval; } private void readUntilEndOfLine( InputStream is, StringBuffer buf ) throws IOException { int nextByte = is.read(); while( nextByte != -1 && nextByte != 0x0D && nextByte != 0x0A ) { buf.append( (char)nextByte ); nextByte = is.read(); } } private boolean isWhitespaceOrEOF( int aByte ) { return aByte == -1 || aByte == 0x20 || aByte == 0x0D || aByte == 0x0A; } private void increment( byte[] data ) { increment( data, data.length-1 ); } private void increment( byte[] data, int position ) { if( position > 0 && (data[position]+256)%256 == 255 ) { data[position]=0; increment( data, position-1); } else { data[position] = (byte)(data[position]+1); } } private String createStringFromBytes( byte[] bytes ) throws IOException { String retval = null; if( bytes.length == 1 ) { retval = new String( bytes ); } else { retval = new String( bytes, "UTF-16BE" ); } return retval; } private int compare( byte[] first, byte[] second ) { int retval = 1; boolean done = false; for( int i=0; i" ); System.exit( -1 ); } CMapParser parser = new CMapParser( ); CMap result = parser.parse( new FileInputStream( args[0] ) ); System.out.println( "Result:" + result ); } }src/core/com/lowagie/text/pdf/fonts/cmaps/CodespaceRange.java100644 0 0 5276 11154165266 21651 0ustar 0 0 /** * Copyright (c) 2005, www.fontbox.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of fontbox; nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * http://www.fontbox.org * */ package com.lowagie.text.pdf.fonts.cmaps; /** * This represents a single entry in the codespace range. * * @author Ben Litchfield (ben@benlitchfield.com) * @version $Revision: 3646 $ * @since 2.1.4 */ public class CodespaceRange { private byte[] start; private byte[] end; /** * Creates a new instance of CodespaceRange. */ public CodespaceRange() { } /** Getter for property end. * @return Value of property end. * */ public byte[] getEnd() { return this.end; } /** Setter for property end. * @param endBytes New value of property end. * */ public void setEnd(byte[] endBytes) { end = endBytes; } /** Getter for property start. * @return Value of property start. * */ public byte[] getStart() { return this.start; } /** Setter for property start. * @param startBytes New value of property start. * */ public void setStart(byte[] startBytes) { start = startBytes; } }src/core/com/lowagie/text/pdf/fonts/glyphlist.txt100644 0 0 273062 11036112746 17652 0ustar 0 0 # Name: Adobe Glyph List # Table version: 2.0 # Date: September 20, 2002 # # See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html # # Format: Semicolon-delimited fields: # (1) glyph name # (2) Unicode scalar value A;0041 AE;00C6 AEacute;01FC AEmacron;01E2 AEsmall;F7E6 Aacute;00C1 Aacutesmall;F7E1 Abreve;0102 Abreveacute;1EAE Abrevecyrillic;04D0 Abrevedotbelow;1EB6 Abrevegrave;1EB0 Abrevehookabove;1EB2 Abrevetilde;1EB4 Acaron;01CD Acircle;24B6 Acircumflex;00C2 Acircumflexacute;1EA4 Acircumflexdotbelow;1EAC Acircumflexgrave;1EA6 Acircumflexhookabove;1EA8 Acircumflexsmall;F7E2 Acircumflextilde;1EAA Acute;F6C9 Acutesmall;F7B4 Acyrillic;0410 Adblgrave;0200 Adieresis;00C4 Adieresiscyrillic;04D2 Adieresismacron;01DE Adieresissmall;F7E4 Adotbelow;1EA0 Adotmacron;01E0 Agrave;00C0 Agravesmall;F7E0 Ahookabove;1EA2 Aiecyrillic;04D4 Ainvertedbreve;0202 Alpha;0391 Alphatonos;0386 Amacron;0100 Amonospace;FF21 Aogonek;0104 Aring;00C5 Aringacute;01FA Aringbelow;1E00 Aringsmall;F7E5 Asmall;F761 Atilde;00C3 Atildesmall;F7E3 Aybarmenian;0531 B;0042 Bcircle;24B7 Bdotaccent;1E02 Bdotbelow;1E04 Becyrillic;0411 Benarmenian;0532 Beta;0392 Bhook;0181 Blinebelow;1E06 Bmonospace;FF22 Brevesmall;F6F4 Bsmall;F762 Btopbar;0182 C;0043 Caarmenian;053E Cacute;0106 Caron;F6CA Caronsmall;F6F5 Ccaron;010C Ccedilla;00C7 Ccedillaacute;1E08 Ccedillasmall;F7E7 Ccircle;24B8 Ccircumflex;0108 Cdot;010A Cdotaccent;010A Cedillasmall;F7B8 Chaarmenian;0549 Cheabkhasiancyrillic;04BC Checyrillic;0427 Chedescenderabkhasiancyrillic;04BE Chedescendercyrillic;04B6 Chedieresiscyrillic;04F4 Cheharmenian;0543 Chekhakassiancyrillic;04CB Cheverticalstrokecyrillic;04B8 Chi;03A7 Chook;0187 Circumflexsmall;F6F6 Cmonospace;FF23 Coarmenian;0551 Csmall;F763 D;0044 DZ;01F1 DZcaron;01C4 Daarmenian;0534 Dafrican;0189 Dcaron;010E Dcedilla;1E10 Dcircle;24B9 Dcircumflexbelow;1E12 Dcroat;0110 Ddotaccent;1E0A Ddotbelow;1E0C Decyrillic;0414 Deicoptic;03EE Delta;2206 Deltagreek;0394 Dhook;018A Dieresis;F6CB DieresisAcute;F6CC DieresisGrave;F6CD Dieresissmall;F7A8 Digammagreek;03DC Djecyrillic;0402 Dlinebelow;1E0E Dmonospace;FF24 Dotaccentsmall;F6F7 Dslash;0110 Dsmall;F764 Dtopbar;018B Dz;01F2 Dzcaron;01C5 Dzeabkhasiancyrillic;04E0 Dzecyrillic;0405 Dzhecyrillic;040F E;0045 Eacute;00C9 Eacutesmall;F7E9 Ebreve;0114 Ecaron;011A Ecedillabreve;1E1C Echarmenian;0535 Ecircle;24BA Ecircumflex;00CA Ecircumflexacute;1EBE Ecircumflexbelow;1E18 Ecircumflexdotbelow;1EC6 Ecircumflexgrave;1EC0 Ecircumflexhookabove;1EC2 Ecircumflexsmall;F7EA Ecircumflextilde;1EC4 Ecyrillic;0404 Edblgrave;0204 Edieresis;00CB Edieresissmall;F7EB Edot;0116 Edotaccent;0116 Edotbelow;1EB8 Efcyrillic;0424 Egrave;00C8 Egravesmall;F7E8 Eharmenian;0537 Ehookabove;1EBA Eightroman;2167 Einvertedbreve;0206 Eiotifiedcyrillic;0464 Elcyrillic;041B Elevenroman;216A Emacron;0112 Emacronacute;1E16 Emacrongrave;1E14 Emcyrillic;041C Emonospace;FF25 Encyrillic;041D Endescendercyrillic;04A2 Eng;014A Enghecyrillic;04A4 Enhookcyrillic;04C7 Eogonek;0118 Eopen;0190 Epsilon;0395 Epsilontonos;0388 Ercyrillic;0420 Ereversed;018E Ereversedcyrillic;042D Escyrillic;0421 Esdescendercyrillic;04AA Esh;01A9 Esmall;F765 Eta;0397 Etarmenian;0538 Etatonos;0389 Eth;00D0 Ethsmall;F7F0 Etilde;1EBC Etildebelow;1E1A Euro;20AC Ezh;01B7 Ezhcaron;01EE Ezhreversed;01B8 F;0046 Fcircle;24BB Fdotaccent;1E1E Feharmenian;0556 Feicoptic;03E4 Fhook;0191 Fitacyrillic;0472 Fiveroman;2164 Fmonospace;FF26 Fourroman;2163 Fsmall;F766 G;0047 GBsquare;3387 Gacute;01F4 Gamma;0393 Gammaafrican;0194 Gangiacoptic;03EA Gbreve;011E Gcaron;01E6 Gcedilla;0122 Gcircle;24BC Gcircumflex;011C Gcommaaccent;0122 Gdot;0120 Gdotaccent;0120 Gecyrillic;0413 Ghadarmenian;0542 Ghemiddlehookcyrillic;0494 Ghestrokecyrillic;0492 Gheupturncyrillic;0490 Ghook;0193 Gimarmenian;0533 Gjecyrillic;0403 Gmacron;1E20 Gmonospace;FF27 Grave;F6CE Gravesmall;F760 Gsmall;F767 Gsmallhook;029B Gstroke;01E4 H;0048 H18533;25CF H18543;25AA H18551;25AB H22073;25A1 HPsquare;33CB Haabkhasiancyrillic;04A8 Hadescendercyrillic;04B2 Hardsigncyrillic;042A Hbar;0126 Hbrevebelow;1E2A Hcedilla;1E28 Hcircle;24BD Hcircumflex;0124 Hdieresis;1E26 Hdotaccent;1E22 Hdotbelow;1E24 Hmonospace;FF28 Hoarmenian;0540 Horicoptic;03E8 Hsmall;F768 Hungarumlaut;F6CF Hungarumlautsmall;F6F8 Hzsquare;3390 I;0049 IAcyrillic;042F IJ;0132 IUcyrillic;042E Iacute;00CD Iacutesmall;F7ED Ibreve;012C Icaron;01CF Icircle;24BE Icircumflex;00CE Icircumflexsmall;F7EE Icyrillic;0406 Idblgrave;0208 Idieresis;00CF Idieresisacute;1E2E Idieresiscyrillic;04E4 Idieresissmall;F7EF Idot;0130 Idotaccent;0130 Idotbelow;1ECA Iebrevecyrillic;04D6 Iecyrillic;0415 Ifraktur;2111 Igrave;00CC Igravesmall;F7EC Ihookabove;1EC8 Iicyrillic;0418 Iinvertedbreve;020A Iishortcyrillic;0419 Imacron;012A Imacroncyrillic;04E2 Imonospace;FF29 Iniarmenian;053B Iocyrillic;0401 Iogonek;012E Iota;0399 Iotaafrican;0196 Iotadieresis;03AA Iotatonos;038A Ismall;F769 Istroke;0197 Itilde;0128 Itildebelow;1E2C Izhitsacyrillic;0474 Izhitsadblgravecyrillic;0476 J;004A Jaarmenian;0541 Jcircle;24BF Jcircumflex;0134 Jecyrillic;0408 Jheharmenian;054B Jmonospace;FF2A Jsmall;F76A K;004B KBsquare;3385 KKsquare;33CD Kabashkircyrillic;04A0 Kacute;1E30 Kacyrillic;041A Kadescendercyrillic;049A Kahookcyrillic;04C3 Kappa;039A Kastrokecyrillic;049E Kaverticalstrokecyrillic;049C Kcaron;01E8 Kcedilla;0136 Kcircle;24C0 Kcommaaccent;0136 Kdotbelow;1E32 Keharmenian;0554 Kenarmenian;053F Khacyrillic;0425 Kheicoptic;03E6 Khook;0198 Kjecyrillic;040C Klinebelow;1E34 Kmonospace;FF2B Koppacyrillic;0480 Koppagreek;03DE Ksicyrillic;046E Ksmall;F76B L;004C LJ;01C7 LL;F6BF Lacute;0139 Lambda;039B Lcaron;013D Lcedilla;013B Lcircle;24C1 Lcircumflexbelow;1E3C Lcommaaccent;013B Ldot;013F Ldotaccent;013F Ldotbelow;1E36 Ldotbelowmacron;1E38 Liwnarmenian;053C Lj;01C8 Ljecyrillic;0409 Llinebelow;1E3A Lmonospace;FF2C Lslash;0141 Lslashsmall;F6F9 Lsmall;F76C M;004D MBsquare;3386 Macron;F6D0 Macronsmall;F7AF Macute;1E3E Mcircle;24C2 Mdotaccent;1E40 Mdotbelow;1E42 Menarmenian;0544 Mmonospace;FF2D Msmall;F76D Mturned;019C Mu;039C N;004E NJ;01CA Nacute;0143 Ncaron;0147 Ncedilla;0145 Ncircle;24C3 Ncircumflexbelow;1E4A Ncommaaccent;0145 Ndotaccent;1E44 Ndotbelow;1E46 Nhookleft;019D Nineroman;2168 Nj;01CB Njecyrillic;040A Nlinebelow;1E48 Nmonospace;FF2E Nowarmenian;0546 Nsmall;F76E Ntilde;00D1 Ntildesmall;F7F1 Nu;039D O;004F OE;0152 OEsmall;F6FA Oacute;00D3 Oacutesmall;F7F3 Obarredcyrillic;04E8 Obarreddieresiscyrillic;04EA Obreve;014E Ocaron;01D1 Ocenteredtilde;019F Ocircle;24C4 Ocircumflex;00D4 Ocircumflexacute;1ED0 Ocircumflexdotbelow;1ED8 Ocircumflexgrave;1ED2 Ocircumflexhookabove;1ED4 Ocircumflexsmall;F7F4 Ocircumflextilde;1ED6 Ocyrillic;041E Odblacute;0150 Odblgrave;020C Odieresis;00D6 Odieresiscyrillic;04E6 Odieresissmall;F7F6 Odotbelow;1ECC Ogoneksmall;F6FB Ograve;00D2 Ogravesmall;F7F2 Oharmenian;0555 Ohm;2126 Ohookabove;1ECE Ohorn;01A0 Ohornacute;1EDA Ohorndotbelow;1EE2 Ohorngrave;1EDC Ohornhookabove;1EDE Ohorntilde;1EE0 Ohungarumlaut;0150 Oi;01A2 Oinvertedbreve;020E Omacron;014C Omacronacute;1E52 Omacrongrave;1E50 Omega;2126 Omegacyrillic;0460 Omegagreek;03A9 Omegaroundcyrillic;047A Omegatitlocyrillic;047C Omegatonos;038F Omicron;039F Omicrontonos;038C Omonospace;FF2F Oneroman;2160 Oogonek;01EA Oogonekmacron;01EC Oopen;0186 Oslash;00D8 Oslashacute;01FE Oslashsmall;F7F8 Osmall;F76F Ostrokeacute;01FE Otcyrillic;047E Otilde;00D5 Otildeacute;1E4C Otildedieresis;1E4E Otildesmall;F7F5 P;0050 Pacute;1E54 Pcircle;24C5 Pdotaccent;1E56 Pecyrillic;041F Peharmenian;054A Pemiddlehookcyrillic;04A6 Phi;03A6 Phook;01A4 Pi;03A0 Piwrarmenian;0553 Pmonospace;FF30 Psi;03A8 Psicyrillic;0470 Psmall;F770 Q;0051 Qcircle;24C6 Qmonospace;FF31 Qsmall;F771 R;0052 Raarmenian;054C Racute;0154 Rcaron;0158 Rcedilla;0156 Rcircle;24C7 Rcommaaccent;0156 Rdblgrave;0210 Rdotaccent;1E58 Rdotbelow;1E5A Rdotbelowmacron;1E5C Reharmenian;0550 Rfraktur;211C Rho;03A1 Ringsmall;F6FC Rinvertedbreve;0212 Rlinebelow;1E5E Rmonospace;FF32 Rsmall;F772 Rsmallinverted;0281 Rsmallinvertedsuperior;02B6 S;0053 SF010000;250C SF020000;2514 SF030000;2510 SF040000;2518 SF050000;253C SF060000;252C SF070000;2534 SF080000;251C SF090000;2524 SF100000;2500 SF110000;2502 SF190000;2561 SF200000;2562 SF210000;2556 SF220000;2555 SF230000;2563 SF240000;2551 SF250000;2557 SF260000;255D SF270000;255C SF280000;255B SF360000;255E SF370000;255F SF380000;255A SF390000;2554 SF400000;2569 SF410000;2566 SF420000;2560 SF430000;2550 SF440000;256C SF450000;2567 SF460000;2568 SF470000;2564 SF480000;2565 SF490000;2559 SF500000;2558 SF510000;2552 SF520000;2553 SF530000;256B SF540000;256A Sacute;015A Sacutedotaccent;1E64 Sampigreek;03E0 Scaron;0160 Scarondotaccent;1E66 Scaronsmall;F6FD Scedilla;015E Schwa;018F Schwacyrillic;04D8 Schwadieresiscyrillic;04DA Scircle;24C8 Scircumflex;015C Scommaaccent;0218 Sdotaccent;1E60 Sdotbelow;1E62 Sdotbelowdotaccent;1E68 Seharmenian;054D Sevenroman;2166 Shaarmenian;0547 Shacyrillic;0428 Shchacyrillic;0429 Sheicoptic;03E2 Shhacyrillic;04BA Shimacoptic;03EC Sigma;03A3 Sixroman;2165 Smonospace;FF33 Softsigncyrillic;042C Ssmall;F773 Stigmagreek;03DA T;0054 Tau;03A4 Tbar;0166 Tcaron;0164 Tcedilla;0162 Tcircle;24C9 Tcircumflexbelow;1E70 Tcommaaccent;0162 Tdotaccent;1E6A Tdotbelow;1E6C Tecyrillic;0422 Tedescendercyrillic;04AC Tenroman;2169 Tetsecyrillic;04B4 Theta;0398 Thook;01AC Thorn;00DE Thornsmall;F7FE Threeroman;2162 Tildesmall;F6FE Tiwnarmenian;054F Tlinebelow;1E6E Tmonospace;FF34 Toarmenian;0539 Tonefive;01BC Tonesix;0184 Tonetwo;01A7 Tretroflexhook;01AE Tsecyrillic;0426 Tshecyrillic;040B Tsmall;F774 Twelveroman;216B Tworoman;2161 U;0055 Uacute;00DA Uacutesmall;F7FA Ubreve;016C Ucaron;01D3 Ucircle;24CA Ucircumflex;00DB Ucircumflexbelow;1E76 Ucircumflexsmall;F7FB Ucyrillic;0423 Udblacute;0170 Udblgrave;0214 Udieresis;00DC Udieresisacute;01D7 Udieresisbelow;1E72 Udieresiscaron;01D9 Udieresiscyrillic;04F0 Udieresisgrave;01DB Udieresismacron;01D5 Udieresissmall;F7FC Udotbelow;1EE4 Ugrave;00D9 Ugravesmall;F7F9 Uhookabove;1EE6 Uhorn;01AF Uhornacute;1EE8 Uhorndotbelow;1EF0 Uhorngrave;1EEA Uhornhookabove;1EEC Uhorntilde;1EEE Uhungarumlaut;0170 Uhungarumlautcyrillic;04F2 Uinvertedbreve;0216 Ukcyrillic;0478 Umacron;016A Umacroncyrillic;04EE Umacrondieresis;1E7A Umonospace;FF35 Uogonek;0172 Upsilon;03A5 Upsilon1;03D2 Upsilonacutehooksymbolgreek;03D3 Upsilonafrican;01B1 Upsilondieresis;03AB Upsilondieresishooksymbolgreek;03D4 Upsilonhooksymbol;03D2 Upsilontonos;038E Uring;016E Ushortcyrillic;040E Usmall;F775 Ustraightcyrillic;04AE Ustraightstrokecyrillic;04B0 Utilde;0168 Utildeacute;1E78 Utildebelow;1E74 V;0056 Vcircle;24CB Vdotbelow;1E7E Vecyrillic;0412 Vewarmenian;054E Vhook;01B2 Vmonospace;FF36 Voarmenian;0548 Vsmall;F776 Vtilde;1E7C W;0057 Wacute;1E82 Wcircle;24CC Wcircumflex;0174 Wdieresis;1E84 Wdotaccent;1E86 Wdotbelow;1E88 Wgrave;1E80 Wmonospace;FF37 Wsmall;F777 X;0058 Xcircle;24CD Xdieresis;1E8C Xdotaccent;1E8A Xeharmenian;053D Xi;039E Xmonospace;FF38 Xsmall;F778 Y;0059 Yacute;00DD Yacutesmall;F7FD Yatcyrillic;0462 Ycircle;24CE Ycircumflex;0176 Ydieresis;0178 Ydieresissmall;F7FF Ydotaccent;1E8E Ydotbelow;1EF4 Yericyrillic;042B Yerudieresiscyrillic;04F8 Ygrave;1EF2 Yhook;01B3 Yhookabove;1EF6 Yiarmenian;0545 Yicyrillic;0407 Yiwnarmenian;0552 Ymonospace;FF39 Ysmall;F779 Ytilde;1EF8 Yusbigcyrillic;046A Yusbigiotifiedcyrillic;046C Yuslittlecyrillic;0466 Yuslittleiotifiedcyrillic;0468 Z;005A Zaarmenian;0536 Zacute;0179 Zcaron;017D Zcaronsmall;F6FF Zcircle;24CF Zcircumflex;1E90 Zdot;017B Zdotaccent;017B Zdotbelow;1E92 Zecyrillic;0417 Zedescendercyrillic;0498 Zedieresiscyrillic;04DE Zeta;0396 Zhearmenian;053A Zhebrevecyrillic;04C1 Zhecyrillic;0416 Zhedescendercyrillic;0496 Zhedieresiscyrillic;04DC Zlinebelow;1E94 Zmonospace;FF3A Zsmall;F77A Zstroke;01B5 a;0061 aabengali;0986 aacute;00E1 aadeva;0906 aagujarati;0A86 aagurmukhi;0A06 aamatragurmukhi;0A3E aarusquare;3303 aavowelsignbengali;09BE aavowelsigndeva;093E aavowelsigngujarati;0ABE abbreviationmarkarmenian;055F abbreviationsigndeva;0970 abengali;0985 abopomofo;311A abreve;0103 abreveacute;1EAF abrevecyrillic;04D1 abrevedotbelow;1EB7 abrevegrave;1EB1 abrevehookabove;1EB3 abrevetilde;1EB5 acaron;01CE acircle;24D0 acircumflex;00E2 acircumflexacute;1EA5 acircumflexdotbelow;1EAD acircumflexgrave;1EA7 acircumflexhookabove;1EA9 acircumflextilde;1EAB acute;00B4 acutebelowcmb;0317 acutecmb;0301 acutecomb;0301 acutedeva;0954 acutelowmod;02CF acutetonecmb;0341 acyrillic;0430 adblgrave;0201 addakgurmukhi;0A71 adeva;0905 adieresis;00E4 adieresiscyrillic;04D3 adieresismacron;01DF adotbelow;1EA1 adotmacron;01E1 ae;00E6 aeacute;01FD aekorean;3150 aemacron;01E3 afii00208;2015 afii08941;20A4 afii10017;0410 afii10018;0411 afii10019;0412 afii10020;0413 afii10021;0414 afii10022;0415 afii10023;0401 afii10024;0416 afii10025;0417 afii10026;0418 afii10027;0419 afii10028;041A afii10029;041B afii10030;041C afii10031;041D afii10032;041E afii10033;041F afii10034;0420 afii10035;0421 afii10036;0422 afii10037;0423 afii10038;0424 afii10039;0425 afii10040;0426 afii10041;0427 afii10042;0428 afii10043;0429 afii10044;042A afii10045;042B afii10046;042C afii10047;042D afii10048;042E afii10049;042F afii10050;0490 afii10051;0402 afii10052;0403 afii10053;0404 afii10054;0405 afii10055;0406 afii10056;0407 afii10057;0408 afii10058;0409 afii10059;040A afii10060;040B afii10061;040C afii10062;040E afii10063;F6C4 afii10064;F6C5 afii10065;0430 afii10066;0431 afii10067;0432 afii10068;0433 afii10069;0434 afii10070;0435 afii10071;0451 afii10072;0436 afii10073;0437 afii10074;0438 afii10075;0439 afii10076;043A afii10077;043B afii10078;043C afii10079;043D afii10080;043E afii10081;043F afii10082;0440 afii10083;0441 afii10084;0442 afii10085;0443 afii10086;0444 afii10087;0445 afii10088;0446 afii10089;0447 afii10090;0448 afii10091;0449 afii10092;044A afii10093;044B afii10094;044C afii10095;044D afii10096;044E afii10097;044F afii10098;0491 afii10099;0452 afii10100;0453 afii10101;0454 afii10102;0455 afii10103;0456 afii10104;0457 afii10105;0458 afii10106;0459 afii10107;045A afii10108;045B afii10109;045C afii10110;045E afii10145;040F afii10146;0462 afii10147;0472 afii10148;0474 afii10192;F6C6 afii10193;045F afii10194;0463 afii10195;0473 afii10196;0475 afii10831;F6C7 afii10832;F6C8 afii10846;04D9 afii299;200E afii300;200F afii301;200D afii57381;066A afii57388;060C afii57392;0660 afii57393;0661 afii57394;0662 afii57395;0663 afii57396;0664 afii57397;0665 afii57398;0666 afii57399;0667 afii57400;0668 afii57401;0669 afii57403;061B afii57407;061F afii57409;0621 afii57410;0622 afii57411;0623 afii57412;0624 afii57413;0625 afii57414;0626 afii57415;0627 afii57416;0628 afii57417;0629 afii57418;062A afii57419;062B afii57420;062C afii57421;062D afii57422;062E afii57423;062F afii57424;0630 afii57425;0631 afii57426;0632 afii57427;0633 afii57428;0634 afii57429;0635 afii57430;0636 afii57431;0637 afii57432;0638 afii57433;0639 afii57434;063A afii57440;0640 afii57441;0641 afii57442;0642 afii57443;0643 afii57444;0644 afii57445;0645 afii57446;0646 afii57448;0648 afii57449;0649 afii57450;064A afii57451;064B afii57452;064C afii57453;064D afii57454;064E afii57455;064F afii57456;0650 afii57457;0651 afii57458;0652 afii57470;0647 afii57505;06A4 afii57506;067E afii57507;0686 afii57508;0698 afii57509;06AF afii57511;0679 afii57512;0688 afii57513;0691 afii57514;06BA afii57519;06D2 afii57534;06D5 afii57636;20AA afii57645;05BE afii57658;05C3 afii57664;05D0 afii57665;05D1 afii57666;05D2 afii57667;05D3 afii57668;05D4 afii57669;05D5 afii57670;05D6 afii57671;05D7 afii57672;05D8 afii57673;05D9 afii57674;05DA afii57675;05DB afii57676;05DC afii57677;05DD afii57678;05DE afii57679;05DF afii57680;05E0 afii57681;05E1 afii57682;05E2 afii57683;05E3 afii57684;05E4 afii57685;05E5 afii57686;05E6 afii57687;05E7 afii57688;05E8 afii57689;05E9 afii57690;05EA afii57694;FB2A afii57695;FB2B afii57700;FB4B afii57705;FB1F afii57716;05F0 afii57717;05F1 afii57718;05F2 afii57723;FB35 afii57793;05B4 afii57794;05B5 afii57795;05B6 afii57796;05BB afii57797;05B8 afii57798;05B7 afii57799;05B0 afii57800;05B2 afii57801;05B1 afii57802;05B3 afii57803;05C2 afii57804;05C1 afii57806;05B9 afii57807;05BC afii57839;05BD afii57841;05BF afii57842;05C0 afii57929;02BC afii61248;2105 afii61289;2113 afii61352;2116 afii61573;202C afii61574;202D afii61575;202E afii61664;200C afii63167;066D afii64937;02BD agrave;00E0 agujarati;0A85 agurmukhi;0A05 ahiragana;3042 ahookabove;1EA3 aibengali;0990 aibopomofo;311E aideva;0910 aiecyrillic;04D5 aigujarati;0A90 aigurmukhi;0A10 aimatragurmukhi;0A48 ainarabic;0639 ainfinalarabic;FECA aininitialarabic;FECB ainmedialarabic;FECC ainvertedbreve;0203 aivowelsignbengali;09C8 aivowelsigndeva;0948 aivowelsigngujarati;0AC8 akatakana;30A2 akatakanahalfwidth;FF71 akorean;314F alef;05D0 alefarabic;0627 alefdageshhebrew;FB30 aleffinalarabic;FE8E alefhamzaabovearabic;0623 alefhamzaabovefinalarabic;FE84 alefhamzabelowarabic;0625 alefhamzabelowfinalarabic;FE88 alefhebrew;05D0 aleflamedhebrew;FB4F alefmaddaabovearabic;0622 alefmaddaabovefinalarabic;FE82 alefmaksuraarabic;0649 alefmaksurafinalarabic;FEF0 alefmaksurainitialarabic;FEF3 alefmaksuramedialarabic;FEF4 alefpatahhebrew;FB2E alefqamatshebrew;FB2F aleph;2135 allequal;224C alpha;03B1 alphatonos;03AC amacron;0101 amonospace;FF41 ampersand;0026 ampersandmonospace;FF06 ampersandsmall;F726 amsquare;33C2 anbopomofo;3122 angbopomofo;3124 angkhankhuthai;0E5A angle;2220 anglebracketleft;3008 anglebracketleftvertical;FE3F anglebracketright;3009 anglebracketrightvertical;FE40 angleleft;2329 angleright;232A angstrom;212B anoteleia;0387 anudattadeva;0952 anusvarabengali;0982 anusvaradeva;0902 anusvaragujarati;0A82 aogonek;0105 apaatosquare;3300 aparen;249C apostrophearmenian;055A apostrophemod;02BC apple;F8FF approaches;2250 approxequal;2248 approxequalorimage;2252 approximatelyequal;2245 araeaekorean;318E araeakorean;318D arc;2312 arighthalfring;1E9A aring;00E5 aringacute;01FB aringbelow;1E01 arrowboth;2194 arrowdashdown;21E3 arrowdashleft;21E0 arrowdashright;21E2 arrowdashup;21E1 arrowdblboth;21D4 arrowdbldown;21D3 arrowdblleft;21D0 arrowdblright;21D2 arrowdblup;21D1 arrowdown;2193 arrowdownleft;2199 arrowdownright;2198 arrowdownwhite;21E9 arrowheaddownmod;02C5 arrowheadleftmod;02C2 arrowheadrightmod;02C3 arrowheadupmod;02C4 arrowhorizex;F8E7 arrowleft;2190 arrowleftdbl;21D0 arrowleftdblstroke;21CD arrowleftoverright;21C6 arrowleftwhite;21E6 arrowright;2192 arrowrightdblstroke;21CF arrowrightheavy;279E arrowrightoverleft;21C4 arrowrightwhite;21E8 arrowtableft;21E4 arrowtabright;21E5 arrowup;2191 arrowupdn;2195 arrowupdnbse;21A8 arrowupdownbase;21A8 arrowupleft;2196 arrowupleftofdown;21C5 arrowupright;2197 arrowupwhite;21E7 arrowvertex;F8E6 asciicircum;005E asciicircummonospace;FF3E asciitilde;007E asciitildemonospace;FF5E ascript;0251 ascriptturned;0252 asmallhiragana;3041 asmallkatakana;30A1 asmallkatakanahalfwidth;FF67 asterisk;002A asteriskaltonearabic;066D asteriskarabic;066D asteriskmath;2217 asteriskmonospace;FF0A asterisksmall;FE61 asterism;2042 asuperior;F6E9 asymptoticallyequal;2243 at;0040 atilde;00E3 atmonospace;FF20 atsmall;FE6B aturned;0250 aubengali;0994 aubopomofo;3120 audeva;0914 augujarati;0A94 augurmukhi;0A14 aulengthmarkbengali;09D7 aumatragurmukhi;0A4C auvowelsignbengali;09CC auvowelsigndeva;094C auvowelsigngujarati;0ACC avagrahadeva;093D aybarmenian;0561 ayin;05E2 ayinaltonehebrew;FB20 ayinhebrew;05E2 b;0062 babengali;09AC backslash;005C backslashmonospace;FF3C badeva;092C bagujarati;0AAC bagurmukhi;0A2C bahiragana;3070 bahtthai;0E3F bakatakana;30D0 bar;007C barmonospace;FF5C bbopomofo;3105 bcircle;24D1 bdotaccent;1E03 bdotbelow;1E05 beamedsixteenthnotes;266C because;2235 becyrillic;0431 beharabic;0628 behfinalarabic;FE90 behinitialarabic;FE91 behiragana;3079 behmedialarabic;FE92 behmeeminitialarabic;FC9F behmeemisolatedarabic;FC08 behnoonfinalarabic;FC6D bekatakana;30D9 benarmenian;0562 bet;05D1 beta;03B2 betasymbolgreek;03D0 betdagesh;FB31 betdageshhebrew;FB31 bethebrew;05D1 betrafehebrew;FB4C bhabengali;09AD bhadeva;092D bhagujarati;0AAD bhagurmukhi;0A2D bhook;0253 bihiragana;3073 bikatakana;30D3 bilabialclick;0298 bindigurmukhi;0A02 birusquare;3331 blackcircle;25CF blackdiamond;25C6 blackdownpointingtriangle;25BC blackleftpointingpointer;25C4 blackleftpointingtriangle;25C0 blacklenticularbracketleft;3010 blacklenticularbracketleftvertical;FE3B blacklenticularbracketright;3011 blacklenticularbracketrightvertical;FE3C blacklowerlefttriangle;25E3 blacklowerrighttriangle;25E2 blackrectangle;25AC blackrightpointingpointer;25BA blackrightpointingtriangle;25B6 blacksmallsquare;25AA blacksmilingface;263B blacksquare;25A0 blackstar;2605 blackupperlefttriangle;25E4 blackupperrighttriangle;25E5 blackuppointingsmalltriangle;25B4 blackuppointingtriangle;25B2 blank;2423 blinebelow;1E07 block;2588 bmonospace;FF42 bobaimaithai;0E1A bohiragana;307C bokatakana;30DC bparen;249D bqsquare;33C3 braceex;F8F4 braceleft;007B braceleftbt;F8F3 braceleftmid;F8F2 braceleftmonospace;FF5B braceleftsmall;FE5B bracelefttp;F8F1 braceleftvertical;FE37 braceright;007D bracerightbt;F8FE bracerightmid;F8FD bracerightmonospace;FF5D bracerightsmall;FE5C bracerighttp;F8FC bracerightvertical;FE38 bracketleft;005B bracketleftbt;F8F0 bracketleftex;F8EF bracketleftmonospace;FF3B bracketlefttp;F8EE bracketright;005D bracketrightbt;F8FB bracketrightex;F8FA bracketrightmonospace;FF3D bracketrighttp;F8F9 breve;02D8 brevebelowcmb;032E brevecmb;0306 breveinvertedbelowcmb;032F breveinvertedcmb;0311 breveinverteddoublecmb;0361 bridgebelowcmb;032A bridgeinvertedbelowcmb;033A brokenbar;00A6 bstroke;0180 bsuperior;F6EA btopbar;0183 buhiragana;3076 bukatakana;30D6 bullet;2022 bulletinverse;25D8 bulletoperator;2219 bullseye;25CE c;0063 caarmenian;056E cabengali;099A cacute;0107 cadeva;091A cagujarati;0A9A cagurmukhi;0A1A calsquare;3388 candrabindubengali;0981 candrabinducmb;0310 candrabindudeva;0901 candrabindugujarati;0A81 capslock;21EA careof;2105 caron;02C7 caronbelowcmb;032C caroncmb;030C carriagereturn;21B5 cbopomofo;3118 ccaron;010D ccedilla;00E7 ccedillaacute;1E09 ccircle;24D2 ccircumflex;0109 ccurl;0255 cdot;010B cdotaccent;010B cdsquare;33C5 cedilla;00B8 cedillacmb;0327 cent;00A2 centigrade;2103 centinferior;F6DF centmonospace;FFE0 centoldstyle;F7A2 centsuperior;F6E0 chaarmenian;0579 chabengali;099B chadeva;091B chagujarati;0A9B chagurmukhi;0A1B chbopomofo;3114 cheabkhasiancyrillic;04BD checkmark;2713 checyrillic;0447 chedescenderabkhasiancyrillic;04BF chedescendercyrillic;04B7 chedieresiscyrillic;04F5 cheharmenian;0573 chekhakassiancyrillic;04CC cheverticalstrokecyrillic;04B9 chi;03C7 chieuchacirclekorean;3277 chieuchaparenkorean;3217 chieuchcirclekorean;3269 chieuchkorean;314A chieuchparenkorean;3209 chochangthai;0E0A chochanthai;0E08 chochingthai;0E09 chochoethai;0E0C chook;0188 cieucacirclekorean;3276 cieucaparenkorean;3216 cieuccirclekorean;3268 cieuckorean;3148 cieucparenkorean;3208 cieucuparenkorean;321C circle;25CB circlemultiply;2297 circleot;2299 circleplus;2295 circlepostalmark;3036 circlewithlefthalfblack;25D0 circlewithrighthalfblack;25D1 circumflex;02C6 circumflexbelowcmb;032D circumflexcmb;0302 clear;2327 clickalveolar;01C2 clickdental;01C0 clicklateral;01C1 clickretroflex;01C3 club;2663 clubsuitblack;2663 clubsuitwhite;2667 cmcubedsquare;33A4 cmonospace;FF43 cmsquaredsquare;33A0 coarmenian;0581 colon;003A colonmonetary;20A1 colonmonospace;FF1A colonsign;20A1 colonsmall;FE55 colontriangularhalfmod;02D1 colontriangularmod;02D0 comma;002C commaabovecmb;0313 commaaboverightcmb;0315 commaaccent;F6C3 commaarabic;060C commaarmenian;055D commainferior;F6E1 commamonospace;FF0C commareversedabovecmb;0314 commareversedmod;02BD commasmall;FE50 commasuperior;F6E2 commaturnedabovecmb;0312 commaturnedmod;02BB compass;263C congruent;2245 contourintegral;222E control;2303 controlACK;0006 controlBEL;0007 controlBS;0008 controlCAN;0018 controlCR;000D controlDC1;0011 controlDC2;0012 controlDC3;0013 controlDC4;0014 controlDEL;007F controlDLE;0010 controlEM;0019 controlENQ;0005 controlEOT;0004 controlESC;001B controlETB;0017 controlETX;0003 controlFF;000C controlFS;001C controlGS;001D controlHT;0009 controlLF;000A controlNAK;0015 controlRS;001E controlSI;000F controlSO;000E controlSOT;0002 controlSTX;0001 controlSUB;001A controlSYN;0016 controlUS;001F controlVT;000B copyright;00A9 copyrightsans;F8E9 copyrightserif;F6D9 cornerbracketleft;300C cornerbracketlefthalfwidth;FF62 cornerbracketleftvertical;FE41 cornerbracketright;300D cornerbracketrighthalfwidth;FF63 cornerbracketrightvertical;FE42 corporationsquare;337F cosquare;33C7 coverkgsquare;33C6 cparen;249E cruzeiro;20A2 cstretched;0297 curlyand;22CF curlyor;22CE currency;00A4 cyrBreve;F6D1 cyrFlex;F6D2 cyrbreve;F6D4 cyrflex;F6D5 d;0064 daarmenian;0564 dabengali;09A6 dadarabic;0636 dadeva;0926 dadfinalarabic;FEBE dadinitialarabic;FEBF dadmedialarabic;FEC0 dagesh;05BC dageshhebrew;05BC dagger;2020 daggerdbl;2021 dagujarati;0AA6 dagurmukhi;0A26 dahiragana;3060 dakatakana;30C0 dalarabic;062F dalet;05D3 daletdagesh;FB33 daletdageshhebrew;FB33 dalethatafpatah;05D3 05B2 dalethatafpatahhebrew;05D3 05B2 dalethatafsegol;05D3 05B1 dalethatafsegolhebrew;05D3 05B1 dalethebrew;05D3 dalethiriq;05D3 05B4 dalethiriqhebrew;05D3 05B4 daletholam;05D3 05B9 daletholamhebrew;05D3 05B9 daletpatah;05D3 05B7 daletpatahhebrew;05D3 05B7 daletqamats;05D3 05B8 daletqamatshebrew;05D3 05B8 daletqubuts;05D3 05BB daletqubutshebrew;05D3 05BB daletsegol;05D3 05B6 daletsegolhebrew;05D3 05B6 daletsheva;05D3 05B0 daletshevahebrew;05D3 05B0 dalettsere;05D3 05B5 dalettserehebrew;05D3 05B5 dalfinalarabic;FEAA dammaarabic;064F dammalowarabic;064F dammatanaltonearabic;064C dammatanarabic;064C danda;0964 dargahebrew;05A7 dargalefthebrew;05A7 dasiapneumatacyrilliccmb;0485 dblGrave;F6D3 dblanglebracketleft;300A dblanglebracketleftvertical;FE3D dblanglebracketright;300B dblanglebracketrightvertical;FE3E dblarchinvertedbelowcmb;032B dblarrowleft;21D4 dblarrowright;21D2 dbldanda;0965 dblgrave;F6D6 dblgravecmb;030F dblintegral;222C dbllowline;2017 dbllowlinecmb;0333 dbloverlinecmb;033F dblprimemod;02BA dblverticalbar;2016 dblverticallineabovecmb;030E dbopomofo;3109 dbsquare;33C8 dcaron;010F dcedilla;1E11 dcircle;24D3 dcircumflexbelow;1E13 dcroat;0111 ddabengali;09A1 ddadeva;0921 ddagujarati;0AA1 ddagurmukhi;0A21 ddalarabic;0688 ddalfinalarabic;FB89 dddhadeva;095C ddhabengali;09A2 ddhadeva;0922 ddhagujarati;0AA2 ddhagurmukhi;0A22 ddotaccent;1E0B ddotbelow;1E0D decimalseparatorarabic;066B decimalseparatorpersian;066B decyrillic;0434 degree;00B0 dehihebrew;05AD dehiragana;3067 deicoptic;03EF dekatakana;30C7 deleteleft;232B deleteright;2326 delta;03B4 deltaturned;018D denominatorminusonenumeratorbengali;09F8 dezh;02A4 dhabengali;09A7 dhadeva;0927 dhagujarati;0AA7 dhagurmukhi;0A27 dhook;0257 dialytikatonos;0385 dialytikatonoscmb;0344 diamond;2666 diamondsuitwhite;2662 dieresis;00A8 dieresisacute;F6D7 dieresisbelowcmb;0324 dieresiscmb;0308 dieresisgrave;F6D8 dieresistonos;0385 dihiragana;3062 dikatakana;30C2 dittomark;3003 divide;00F7 divides;2223 divisionslash;2215 djecyrillic;0452 dkshade;2593 dlinebelow;1E0F dlsquare;3397 dmacron;0111 dmonospace;FF44 dnblock;2584 dochadathai;0E0E dodekthai;0E14 dohiragana;3069 dokatakana;30C9 dollar;0024 dollarinferior;F6E3 dollarmonospace;FF04 dollaroldstyle;F724 dollarsmall;FE69 dollarsuperior;F6E4 dong;20AB dorusquare;3326 dotaccent;02D9 dotaccentcmb;0307 dotbelowcmb;0323 dotbelowcomb;0323 dotkatakana;30FB dotlessi;0131 dotlessj;F6BE dotlessjstrokehook;0284 dotmath;22C5 dottedcircle;25CC doubleyodpatah;FB1F doubleyodpatahhebrew;FB1F downtackbelowcmb;031E downtackmod;02D5 dparen;249F dsuperior;F6EB dtail;0256 dtopbar;018C duhiragana;3065 dukatakana;30C5 dz;01F3 dzaltone;02A3 dzcaron;01C6 dzcurl;02A5 dzeabkhasiancyrillic;04E1 dzecyrillic;0455 dzhecyrillic;045F e;0065 eacute;00E9 earth;2641 ebengali;098F ebopomofo;311C ebreve;0115 ecandradeva;090D ecandragujarati;0A8D ecandravowelsigndeva;0945 ecandravowelsigngujarati;0AC5 ecaron;011B ecedillabreve;1E1D echarmenian;0565 echyiwnarmenian;0587 ecircle;24D4 ecircumflex;00EA ecircumflexacute;1EBF ecircumflexbelow;1E19 ecircumflexdotbelow;1EC7 ecircumflexgrave;1EC1 ecircumflexhookabove;1EC3 ecircumflextilde;1EC5 ecyrillic;0454 edblgrave;0205 edeva;090F edieresis;00EB edot;0117 edotaccent;0117 edotbelow;1EB9 eegurmukhi;0A0F eematragurmukhi;0A47 efcyrillic;0444 egrave;00E8 egujarati;0A8F eharmenian;0567 ehbopomofo;311D ehiragana;3048 ehookabove;1EBB eibopomofo;311F eight;0038 eightarabic;0668 eightbengali;09EE eightcircle;2467 eightcircleinversesansserif;2791 eightdeva;096E eighteencircle;2471 eighteenparen;2485 eighteenperiod;2499 eightgujarati;0AEE eightgurmukhi;0A6E eighthackarabic;0668 eighthangzhou;3028 eighthnotebeamed;266B eightideographicparen;3227 eightinferior;2088 eightmonospace;FF18 eightoldstyle;F738 eightparen;247B eightperiod;248F eightpersian;06F8 eightroman;2177 eightsuperior;2078 eightthai;0E58 einvertedbreve;0207 eiotifiedcyrillic;0465 ekatakana;30A8 ekatakanahalfwidth;FF74 ekonkargurmukhi;0A74 ekorean;3154 elcyrillic;043B element;2208 elevencircle;246A elevenparen;247E elevenperiod;2492 elevenroman;217A ellipsis;2026 ellipsisvertical;22EE emacron;0113 emacronacute;1E17 emacrongrave;1E15 emcyrillic;043C emdash;2014 emdashvertical;FE31 emonospace;FF45 emphasismarkarmenian;055B emptyset;2205 enbopomofo;3123 encyrillic;043D endash;2013 endashvertical;FE32 endescendercyrillic;04A3 eng;014B engbopomofo;3125 enghecyrillic;04A5 enhookcyrillic;04C8 enspace;2002 eogonek;0119 eokorean;3153 eopen;025B eopenclosed;029A eopenreversed;025C eopenreversedclosed;025E eopenreversedhook;025D eparen;24A0 epsilon;03B5 epsilontonos;03AD equal;003D equalmonospace;FF1D equalsmall;FE66 equalsuperior;207C equivalence;2261 erbopomofo;3126 ercyrillic;0440 ereversed;0258 ereversedcyrillic;044D escyrillic;0441 esdescendercyrillic;04AB esh;0283 eshcurl;0286 eshortdeva;090E eshortvowelsigndeva;0946 eshreversedloop;01AA eshsquatreversed;0285 esmallhiragana;3047 esmallkatakana;30A7 esmallkatakanahalfwidth;FF6A estimated;212E esuperior;F6EC eta;03B7 etarmenian;0568 etatonos;03AE eth;00F0 etilde;1EBD etildebelow;1E1B etnahtafoukhhebrew;0591 etnahtafoukhlefthebrew;0591 etnahtahebrew;0591 etnahtalefthebrew;0591 eturned;01DD eukorean;3161 euro;20AC evowelsignbengali;09C7 evowelsigndeva;0947 evowelsigngujarati;0AC7 exclam;0021 exclamarmenian;055C exclamdbl;203C exclamdown;00A1 exclamdownsmall;F7A1 exclammonospace;FF01 exclamsmall;F721 existential;2203 ezh;0292 ezhcaron;01EF ezhcurl;0293 ezhreversed;01B9 ezhtail;01BA f;0066 fadeva;095E fagurmukhi;0A5E fahrenheit;2109 fathaarabic;064E fathalowarabic;064E fathatanarabic;064B fbopomofo;3108 fcircle;24D5 fdotaccent;1E1F feharabic;0641 feharmenian;0586 fehfinalarabic;FED2 fehinitialarabic;FED3 fehmedialarabic;FED4 feicoptic;03E5 female;2640 ff;FB00 ffi;FB03 ffl;FB04 fi;FB01 fifteencircle;246E fifteenparen;2482 fifteenperiod;2496 figuredash;2012 filledbox;25A0 filledrect;25AC finalkaf;05DA finalkafdagesh;FB3A finalkafdageshhebrew;FB3A finalkafhebrew;05DA finalkafqamats;05DA 05B8 finalkafqamatshebrew;05DA 05B8 finalkafsheva;05DA 05B0 finalkafshevahebrew;05DA 05B0 finalmem;05DD finalmemhebrew;05DD finalnun;05DF finalnunhebrew;05DF finalpe;05E3 finalpehebrew;05E3 finaltsadi;05E5 finaltsadihebrew;05E5 firsttonechinese;02C9 fisheye;25C9 fitacyrillic;0473 five;0035 fivearabic;0665 fivebengali;09EB fivecircle;2464 fivecircleinversesansserif;278E fivedeva;096B fiveeighths;215D fivegujarati;0AEB fivegurmukhi;0A6B fivehackarabic;0665 fivehangzhou;3025 fiveideographicparen;3224 fiveinferior;2085 fivemonospace;FF15 fiveoldstyle;F735 fiveparen;2478 fiveperiod;248C fivepersian;06F5 fiveroman;2174 fivesuperior;2075 fivethai;0E55 fl;FB02 florin;0192 fmonospace;FF46 fmsquare;3399 fofanthai;0E1F fofathai;0E1D fongmanthai;0E4F forall;2200 four;0034 fourarabic;0664 fourbengali;09EA fourcircle;2463 fourcircleinversesansserif;278D fourdeva;096A fourgujarati;0AEA fourgurmukhi;0A6A fourhackarabic;0664 fourhangzhou;3024 fourideographicparen;3223 fourinferior;2084 fourmonospace;FF14 fournumeratorbengali;09F7 fouroldstyle;F734 fourparen;2477 fourperiod;248B fourpersian;06F4 fourroman;2173 foursuperior;2074 fourteencircle;246D fourteenparen;2481 fourteenperiod;2495 fourthai;0E54 fourthtonechinese;02CB fparen;24A1 fraction;2044 franc;20A3 g;0067 gabengali;0997 gacute;01F5 gadeva;0917 gafarabic;06AF gaffinalarabic;FB93 gafinitialarabic;FB94 gafmedialarabic;FB95 gagujarati;0A97 gagurmukhi;0A17 gahiragana;304C gakatakana;30AC gamma;03B3 gammalatinsmall;0263 gammasuperior;02E0 gangiacoptic;03EB gbopomofo;310D gbreve;011F gcaron;01E7 gcedilla;0123 gcircle;24D6 gcircumflex;011D gcommaaccent;0123 gdot;0121 gdotaccent;0121 gecyrillic;0433 gehiragana;3052 gekatakana;30B2 geometricallyequal;2251 gereshaccenthebrew;059C gereshhebrew;05F3 gereshmuqdamhebrew;059D germandbls;00DF gershayimaccenthebrew;059E gershayimhebrew;05F4 getamark;3013 ghabengali;0998 ghadarmenian;0572 ghadeva;0918 ghagujarati;0A98 ghagurmukhi;0A18 ghainarabic;063A ghainfinalarabic;FECE ghaininitialarabic;FECF ghainmedialarabic;FED0 ghemiddlehookcyrillic;0495 ghestrokecyrillic;0493 gheupturncyrillic;0491 ghhadeva;095A ghhagurmukhi;0A5A ghook;0260 ghzsquare;3393 gihiragana;304E gikatakana;30AE gimarmenian;0563 gimel;05D2 gimeldagesh;FB32 gimeldageshhebrew;FB32 gimelhebrew;05D2 gjecyrillic;0453 glottalinvertedstroke;01BE glottalstop;0294 glottalstopinverted;0296 glottalstopmod;02C0 glottalstopreversed;0295 glottalstopreversedmod;02C1 glottalstopreversedsuperior;02E4 glottalstopstroke;02A1 glottalstopstrokereversed;02A2 gmacron;1E21 gmonospace;FF47 gohiragana;3054 gokatakana;30B4 gparen;24A2 gpasquare;33AC gradient;2207 grave;0060 gravebelowcmb;0316 gravecmb;0300 gravecomb;0300 gravedeva;0953 gravelowmod;02CE gravemonospace;FF40 gravetonecmb;0340 greater;003E greaterequal;2265 greaterequalorless;22DB greatermonospace;FF1E greaterorequivalent;2273 greaterorless;2277 greateroverequal;2267 greatersmall;FE65 gscript;0261 gstroke;01E5 guhiragana;3050 guillemotleft;00AB guillemotright;00BB guilsinglleft;2039 guilsinglright;203A gukatakana;30B0 guramusquare;3318 gysquare;33C9 h;0068 haabkhasiancyrillic;04A9 haaltonearabic;06C1 habengali;09B9 hadescendercyrillic;04B3 hadeva;0939 hagujarati;0AB9 hagurmukhi;0A39 haharabic;062D hahfinalarabic;FEA2 hahinitialarabic;FEA3 hahiragana;306F hahmedialarabic;FEA4 haitusquare;332A hakatakana;30CF hakatakanahalfwidth;FF8A halantgurmukhi;0A4D hamzaarabic;0621 hamzadammaarabic;0621 064F hamzadammatanarabic;0621 064C hamzafathaarabic;0621 064E hamzafathatanarabic;0621 064B hamzalowarabic;0621 hamzalowkasraarabic;0621 0650 hamzalowkasratanarabic;0621 064D hamzasukunarabic;0621 0652 hangulfiller;3164 hardsigncyrillic;044A harpoonleftbarbup;21BC harpoonrightbarbup;21C0 hasquare;33CA hatafpatah;05B2 hatafpatah16;05B2 hatafpatah23;05B2 hatafpatah2f;05B2 hatafpatahhebrew;05B2 hatafpatahnarrowhebrew;05B2 hatafpatahquarterhebrew;05B2 hatafpatahwidehebrew;05B2 hatafqamats;05B3 hatafqamats1b;05B3 hatafqamats28;05B3 hatafqamats34;05B3 hatafqamatshebrew;05B3 hatafqamatsnarrowhebrew;05B3 hatafqamatsquarterhebrew;05B3 hatafqamatswidehebrew;05B3 hatafsegol;05B1 hatafsegol17;05B1 hatafsegol24;05B1 hatafsegol30;05B1 hatafsegolhebrew;05B1 hatafsegolnarrowhebrew;05B1 hatafsegolquarterhebrew;05B1 hatafsegolwidehebrew;05B1 hbar;0127 hbopomofo;310F hbrevebelow;1E2B hcedilla;1E29 hcircle;24D7 hcircumflex;0125 hdieresis;1E27 hdotaccent;1E23 hdotbelow;1E25 he;05D4 heart;2665 heartsuitblack;2665 heartsuitwhite;2661 hedagesh;FB34 hedageshhebrew;FB34 hehaltonearabic;06C1 heharabic;0647 hehebrew;05D4 hehfinalaltonearabic;FBA7 hehfinalalttwoarabic;FEEA hehfinalarabic;FEEA hehhamzaabovefinalarabic;FBA5 hehhamzaaboveisolatedarabic;FBA4 hehinitialaltonearabic;FBA8 hehinitialarabic;FEEB hehiragana;3078 hehmedialaltonearabic;FBA9 hehmedialarabic;FEEC heiseierasquare;337B hekatakana;30D8 hekatakanahalfwidth;FF8D hekutaarusquare;3336 henghook;0267 herutusquare;3339 het;05D7 hethebrew;05D7 hhook;0266 hhooksuperior;02B1 hieuhacirclekorean;327B hieuhaparenkorean;321B hieuhcirclekorean;326D hieuhkorean;314E hieuhparenkorean;320D hihiragana;3072 hikatakana;30D2 hikatakanahalfwidth;FF8B hiriq;05B4 hiriq14;05B4 hiriq21;05B4 hiriq2d;05B4 hiriqhebrew;05B4 hiriqnarrowhebrew;05B4 hiriqquarterhebrew;05B4 hiriqwidehebrew;05B4 hlinebelow;1E96 hmonospace;FF48 hoarmenian;0570 hohipthai;0E2B hohiragana;307B hokatakana;30DB hokatakanahalfwidth;FF8E holam;05B9 holam19;05B9 holam26;05B9 holam32;05B9 holamhebrew;05B9 holamnarrowhebrew;05B9 holamquarterhebrew;05B9 holamwidehebrew;05B9 honokhukthai;0E2E hookabovecomb;0309 hookcmb;0309 hookpalatalizedbelowcmb;0321 hookretroflexbelowcmb;0322 hoonsquare;3342 horicoptic;03E9 horizontalbar;2015 horncmb;031B hotsprings;2668 house;2302 hparen;24A3 hsuperior;02B0 hturned;0265 huhiragana;3075 huiitosquare;3333 hukatakana;30D5 hukatakanahalfwidth;FF8C hungarumlaut;02DD hungarumlautcmb;030B hv;0195 hyphen;002D hypheninferior;F6E5 hyphenmonospace;FF0D hyphensmall;FE63 hyphensuperior;F6E6 hyphentwo;2010 i;0069 iacute;00ED iacyrillic;044F ibengali;0987 ibopomofo;3127 ibreve;012D icaron;01D0 icircle;24D8 icircumflex;00EE icyrillic;0456 idblgrave;0209 ideographearthcircle;328F ideographfirecircle;328B ideographicallianceparen;323F ideographiccallparen;323A ideographiccentrecircle;32A5 ideographicclose;3006 ideographiccomma;3001 ideographiccommaleft;FF64 ideographiccongratulationparen;3237 ideographiccorrectcircle;32A3 ideographicearthparen;322F ideographicenterpriseparen;323D ideographicexcellentcircle;329D ideographicfestivalparen;3240 ideographicfinancialcircle;3296 ideographicfinancialparen;3236 ideographicfireparen;322B ideographichaveparen;3232 ideographichighcircle;32A4 ideographiciterationmark;3005 ideographiclaborcircle;3298 ideographiclaborparen;3238 ideographicleftcircle;32A7 ideographiclowcircle;32A6 ideographicmedicinecircle;32A9 ideographicmetalparen;322E ideographicmoonparen;322A ideographicnameparen;3234 ideographicperiod;3002 ideographicprintcircle;329E ideographicreachparen;3243 ideographicrepresentparen;3239 ideographicresourceparen;323E ideographicrightcircle;32A8 ideographicsecretcircle;3299 ideographicselfparen;3242 ideographicsocietyparen;3233 ideographicspace;3000 ideographicspecialparen;3235 ideographicstockparen;3231 ideographicstudyparen;323B ideographicsunparen;3230 ideographicsuperviseparen;323C ideographicwaterparen;322C ideographicwoodparen;322D ideographiczero;3007 ideographmetalcircle;328E ideographmooncircle;328A ideographnamecircle;3294 ideographsuncircle;3290 ideographwatercircle;328C ideographwoodcircle;328D ideva;0907 idieresis;00EF idieresisacute;1E2F idieresiscyrillic;04E5 idotbelow;1ECB iebrevecyrillic;04D7 iecyrillic;0435 ieungacirclekorean;3275 ieungaparenkorean;3215 ieungcirclekorean;3267 ieungkorean;3147 ieungparenkorean;3207 igrave;00EC igujarati;0A87 igurmukhi;0A07 ihiragana;3044 ihookabove;1EC9 iibengali;0988 iicyrillic;0438 iideva;0908 iigujarati;0A88 iigurmukhi;0A08 iimatragurmukhi;0A40 iinvertedbreve;020B iishortcyrillic;0439 iivowelsignbengali;09C0 iivowelsigndeva;0940 iivowelsigngujarati;0AC0 ij;0133 ikatakana;30A4 ikatakanahalfwidth;FF72 ikorean;3163 ilde;02DC iluyhebrew;05AC imacron;012B imacroncyrillic;04E3 imageorapproximatelyequal;2253 imatragurmukhi;0A3F imonospace;FF49 increment;2206 infinity;221E iniarmenian;056B integral;222B integralbottom;2321 integralbt;2321 integralex;F8F5 integraltop;2320 integraltp;2320 intersection;2229 intisquare;3305 invbullet;25D8 invcircle;25D9 invsmileface;263B iocyrillic;0451 iogonek;012F iota;03B9 iotadieresis;03CA iotadieresistonos;0390 iotalatin;0269 iotatonos;03AF iparen;24A4 irigurmukhi;0A72 ismallhiragana;3043 ismallkatakana;30A3 ismallkatakanahalfwidth;FF68 issharbengali;09FA istroke;0268 isuperior;F6ED iterationhiragana;309D iterationkatakana;30FD itilde;0129 itildebelow;1E2D iubopomofo;3129 iucyrillic;044E ivowelsignbengali;09BF ivowelsigndeva;093F ivowelsigngujarati;0ABF izhitsacyrillic;0475 izhitsadblgravecyrillic;0477 j;006A jaarmenian;0571 jabengali;099C jadeva;091C jagujarati;0A9C jagurmukhi;0A1C jbopomofo;3110 jcaron;01F0 jcircle;24D9 jcircumflex;0135 jcrossedtail;029D jdotlessstroke;025F jecyrillic;0458 jeemarabic;062C jeemfinalarabic;FE9E jeeminitialarabic;FE9F jeemmedialarabic;FEA0 jeharabic;0698 jehfinalarabic;FB8B jhabengali;099D jhadeva;091D jhagujarati;0A9D jhagurmukhi;0A1D jheharmenian;057B jis;3004 jmonospace;FF4A jparen;24A5 jsuperior;02B2 k;006B kabashkircyrillic;04A1 kabengali;0995 kacute;1E31 kacyrillic;043A kadescendercyrillic;049B kadeva;0915 kaf;05DB kafarabic;0643 kafdagesh;FB3B kafdageshhebrew;FB3B kaffinalarabic;FEDA kafhebrew;05DB kafinitialarabic;FEDB kafmedialarabic;FEDC kafrafehebrew;FB4D kagujarati;0A95 kagurmukhi;0A15 kahiragana;304B kahookcyrillic;04C4 kakatakana;30AB kakatakanahalfwidth;FF76 kappa;03BA kappasymbolgreek;03F0 kapyeounmieumkorean;3171 kapyeounphieuphkorean;3184 kapyeounpieupkorean;3178 kapyeounssangpieupkorean;3179 karoriisquare;330D kashidaautoarabic;0640 kashidaautonosidebearingarabic;0640 kasmallkatakana;30F5 kasquare;3384 kasraarabic;0650 kasratanarabic;064D kastrokecyrillic;049F katahiraprolongmarkhalfwidth;FF70 kaverticalstrokecyrillic;049D kbopomofo;310E kcalsquare;3389 kcaron;01E9 kcedilla;0137 kcircle;24DA kcommaaccent;0137 kdotbelow;1E33 keharmenian;0584 kehiragana;3051 kekatakana;30B1 kekatakanahalfwidth;FF79 kenarmenian;056F kesmallkatakana;30F6 kgreenlandic;0138 khabengali;0996 khacyrillic;0445 khadeva;0916 khagujarati;0A96 khagurmukhi;0A16 khaharabic;062E khahfinalarabic;FEA6 khahinitialarabic;FEA7 khahmedialarabic;FEA8 kheicoptic;03E7 khhadeva;0959 khhagurmukhi;0A59 khieukhacirclekorean;3278 khieukhaparenkorean;3218 khieukhcirclekorean;326A khieukhkorean;314B khieukhparenkorean;320A khokhaithai;0E02 khokhonthai;0E05 khokhuatthai;0E03 khokhwaithai;0E04 khomutthai;0E5B khook;0199 khorakhangthai;0E06 khzsquare;3391 kihiragana;304D kikatakana;30AD kikatakanahalfwidth;FF77 kiroguramusquare;3315 kiromeetorusquare;3316 kirosquare;3314 kiyeokacirclekorean;326E kiyeokaparenkorean;320E kiyeokcirclekorean;3260 kiyeokkorean;3131 kiyeokparenkorean;3200 kiyeoksioskorean;3133 kjecyrillic;045C klinebelow;1E35 klsquare;3398 kmcubedsquare;33A6 kmonospace;FF4B kmsquaredsquare;33A2 kohiragana;3053 kohmsquare;33C0 kokaithai;0E01 kokatakana;30B3 kokatakanahalfwidth;FF7A kooposquare;331E koppacyrillic;0481 koreanstandardsymbol;327F koroniscmb;0343 kparen;24A6 kpasquare;33AA ksicyrillic;046F ktsquare;33CF kturned;029E kuhiragana;304F kukatakana;30AF kukatakanahalfwidth;FF78 kvsquare;33B8 kwsquare;33BE l;006C labengali;09B2 lacute;013A ladeva;0932 lagujarati;0AB2 lagurmukhi;0A32 lakkhangyaothai;0E45 lamaleffinalarabic;FEFC lamalefhamzaabovefinalarabic;FEF8 lamalefhamzaaboveisolatedarabic;FEF7 lamalefhamzabelowfinalarabic;FEFA lamalefhamzabelowisolatedarabic;FEF9 lamalefisolatedarabic;FEFB lamalefmaddaabovefinalarabic;FEF6 lamalefmaddaaboveisolatedarabic;FEF5 lamarabic;0644 lambda;03BB lambdastroke;019B lamed;05DC lameddagesh;FB3C lameddageshhebrew;FB3C lamedhebrew;05DC lamedholam;05DC 05B9 lamedholamdagesh;05DC 05B9 05BC lamedholamdageshhebrew;05DC 05B9 05BC lamedholamhebrew;05DC 05B9 lamfinalarabic;FEDE lamhahinitialarabic;FCCA laminitialarabic;FEDF lamjeeminitialarabic;FCC9 lamkhahinitialarabic;FCCB lamlamhehisolatedarabic;FDF2 lammedialarabic;FEE0 lammeemhahinitialarabic;FD88 lammeeminitialarabic;FCCC lammeemjeeminitialarabic;FEDF FEE4 FEA0 lammeemkhahinitialarabic;FEDF FEE4 FEA8 largecircle;25EF lbar;019A lbelt;026C lbopomofo;310C lcaron;013E lcedilla;013C lcircle;24DB lcircumflexbelow;1E3D lcommaaccent;013C ldot;0140 ldotaccent;0140 ldotbelow;1E37 ldotbelowmacron;1E39 leftangleabovecmb;031A lefttackbelowcmb;0318 less;003C lessequal;2264 lessequalorgreater;22DA lessmonospace;FF1C lessorequivalent;2272 lessorgreater;2276 lessoverequal;2266 lesssmall;FE64 lezh;026E lfblock;258C lhookretroflex;026D lira;20A4 liwnarmenian;056C lj;01C9 ljecyrillic;0459 ll;F6C0 lladeva;0933 llagujarati;0AB3 llinebelow;1E3B llladeva;0934 llvocalicbengali;09E1 llvocalicdeva;0961 llvocalicvowelsignbengali;09E3 llvocalicvowelsigndeva;0963 lmiddletilde;026B lmonospace;FF4C lmsquare;33D0 lochulathai;0E2C logicaland;2227 logicalnot;00AC logicalnotreversed;2310 logicalor;2228 lolingthai;0E25 longs;017F lowlinecenterline;FE4E lowlinecmb;0332 lowlinedashed;FE4D lozenge;25CA lparen;24A7 lslash;0142 lsquare;2113 lsuperior;F6EE ltshade;2591 luthai;0E26 lvocalicbengali;098C lvocalicdeva;090C lvocalicvowelsignbengali;09E2 lvocalicvowelsigndeva;0962 lxsquare;33D3 m;006D mabengali;09AE macron;00AF macronbelowcmb;0331 macroncmb;0304 macronlowmod;02CD macronmonospace;FFE3 macute;1E3F madeva;092E magujarati;0AAE magurmukhi;0A2E mahapakhhebrew;05A4 mahapakhlefthebrew;05A4 mahiragana;307E maichattawalowleftthai;F895 maichattawalowrightthai;F894 maichattawathai;0E4B maichattawaupperleftthai;F893 maieklowleftthai;F88C maieklowrightthai;F88B maiekthai;0E48 maiekupperleftthai;F88A maihanakatleftthai;F884 maihanakatthai;0E31 maitaikhuleftthai;F889 maitaikhuthai;0E47 maitholowleftthai;F88F maitholowrightthai;F88E maithothai;0E49 maithoupperleftthai;F88D maitrilowleftthai;F892 maitrilowrightthai;F891 maitrithai;0E4A maitriupperleftthai;F890 maiyamokthai;0E46 makatakana;30DE makatakanahalfwidth;FF8F male;2642 mansyonsquare;3347 maqafhebrew;05BE mars;2642 masoracirclehebrew;05AF masquare;3383 mbopomofo;3107 mbsquare;33D4 mcircle;24DC mcubedsquare;33A5 mdotaccent;1E41 mdotbelow;1E43 meemarabic;0645 meemfinalarabic;FEE2 meeminitialarabic;FEE3 meemmedialarabic;FEE4 meemmeeminitialarabic;FCD1 meemmeemisolatedarabic;FC48 meetorusquare;334D mehiragana;3081 meizierasquare;337E mekatakana;30E1 mekatakanahalfwidth;FF92 mem;05DE memdagesh;FB3E memdageshhebrew;FB3E memhebrew;05DE menarmenian;0574 merkhahebrew;05A5 merkhakefulahebrew;05A6 merkhakefulalefthebrew;05A6 merkhalefthebrew;05A5 mhook;0271 mhzsquare;3392 middledotkatakanahalfwidth;FF65 middot;00B7 mieumacirclekorean;3272 mieumaparenkorean;3212 mieumcirclekorean;3264 mieumkorean;3141 mieumpansioskorean;3170 mieumparenkorean;3204 mieumpieupkorean;316E mieumsioskorean;316F mihiragana;307F mikatakana;30DF mikatakanahalfwidth;FF90 minus;2212 minusbelowcmb;0320 minuscircle;2296 minusmod;02D7 minusplus;2213 minute;2032 miribaarusquare;334A mirisquare;3349 mlonglegturned;0270 mlsquare;3396 mmcubedsquare;33A3 mmonospace;FF4D mmsquaredsquare;339F mohiragana;3082 mohmsquare;33C1 mokatakana;30E2 mokatakanahalfwidth;FF93 molsquare;33D6 momathai;0E21 moverssquare;33A7 moverssquaredsquare;33A8 mparen;24A8 mpasquare;33AB mssquare;33B3 msuperior;F6EF mturned;026F mu1;00B5 mu;00B5 muasquare;3382 muchgreater;226B muchless;226A mufsquare;338C mugreek;03BC mugsquare;338D muhiragana;3080 mukatakana;30E0 mukatakanahalfwidth;FF91 mulsquare;3395 multiply;00D7 mumsquare;339B munahhebrew;05A3 munahlefthebrew;05A3 musicalnote;266A musicalnotedbl;266B musicflatsign;266D musicsharpsign;266F mussquare;33B2 muvsquare;33B6 muwsquare;33BC mvmegasquare;33B9 mvsquare;33B7 mwmegasquare;33BF mwsquare;33BD n;006E nabengali;09A8 nabla;2207 nacute;0144 nadeva;0928 nagujarati;0AA8 nagurmukhi;0A28 nahiragana;306A nakatakana;30CA nakatakanahalfwidth;FF85 napostrophe;0149 nasquare;3381 nbopomofo;310B nbspace;00A0 ncaron;0148 ncedilla;0146 ncircle;24DD ncircumflexbelow;1E4B ncommaaccent;0146 ndotaccent;1E45 ndotbelow;1E47 nehiragana;306D nekatakana;30CD nekatakanahalfwidth;FF88 newsheqelsign;20AA nfsquare;338B ngabengali;0999 ngadeva;0919 ngagujarati;0A99 ngagurmukhi;0A19 ngonguthai;0E07 nhiragana;3093 nhookleft;0272 nhookretroflex;0273 nieunacirclekorean;326F nieunaparenkorean;320F nieuncieuckorean;3135 nieuncirclekorean;3261 nieunhieuhkorean;3136 nieunkorean;3134 nieunpansioskorean;3168 nieunparenkorean;3201 nieunsioskorean;3167 nieuntikeutkorean;3166 nihiragana;306B nikatakana;30CB nikatakanahalfwidth;FF86 nikhahitleftthai;F899 nikhahitthai;0E4D nine;0039 ninearabic;0669 ninebengali;09EF ninecircle;2468 ninecircleinversesansserif;2792 ninedeva;096F ninegujarati;0AEF ninegurmukhi;0A6F ninehackarabic;0669 ninehangzhou;3029 nineideographicparen;3228 nineinferior;2089 ninemonospace;FF19 nineoldstyle;F739 nineparen;247C nineperiod;2490 ninepersian;06F9 nineroman;2178 ninesuperior;2079 nineteencircle;2472 nineteenparen;2486 nineteenperiod;249A ninethai;0E59 nj;01CC njecyrillic;045A nkatakana;30F3 nkatakanahalfwidth;FF9D nlegrightlong;019E nlinebelow;1E49 nmonospace;FF4E nmsquare;339A nnabengali;09A3 nnadeva;0923 nnagujarati;0AA3 nnagurmukhi;0A23 nnnadeva;0929 nohiragana;306E nokatakana;30CE nokatakanahalfwidth;FF89 nonbreakingspace;00A0 nonenthai;0E13 nonuthai;0E19 noonarabic;0646 noonfinalarabic;FEE6 noonghunnaarabic;06BA noonghunnafinalarabic;FB9F noonhehinitialarabic;FEE7 FEEC nooninitialarabic;FEE7 noonjeeminitialarabic;FCD2 noonjeemisolatedarabic;FC4B noonmedialarabic;FEE8 noonmeeminitialarabic;FCD5 noonmeemisolatedarabic;FC4E noonnoonfinalarabic;FC8D notcontains;220C notelement;2209 notelementof;2209 notequal;2260 notgreater;226F notgreaternorequal;2271 notgreaternorless;2279 notidentical;2262 notless;226E notlessnorequal;2270 notparallel;2226 notprecedes;2280 notsubset;2284 notsucceeds;2281 notsuperset;2285 nowarmenian;0576 nparen;24A9 nssquare;33B1 nsuperior;207F ntilde;00F1 nu;03BD nuhiragana;306C nukatakana;30CC nukatakanahalfwidth;FF87 nuktabengali;09BC nuktadeva;093C nuktagujarati;0ABC nuktagurmukhi;0A3C numbersign;0023 numbersignmonospace;FF03 numbersignsmall;FE5F numeralsigngreek;0374 numeralsignlowergreek;0375 numero;2116 nun;05E0 nundagesh;FB40 nundageshhebrew;FB40 nunhebrew;05E0 nvsquare;33B5 nwsquare;33BB nyabengali;099E nyadeva;091E nyagujarati;0A9E nyagurmukhi;0A1E o;006F oacute;00F3 oangthai;0E2D obarred;0275 obarredcyrillic;04E9 obarreddieresiscyrillic;04EB obengali;0993 obopomofo;311B obreve;014F ocandradeva;0911 ocandragujarati;0A91 ocandravowelsigndeva;0949 ocandravowelsigngujarati;0AC9 ocaron;01D2 ocircle;24DE ocircumflex;00F4 ocircumflexacute;1ED1 ocircumflexdotbelow;1ED9 ocircumflexgrave;1ED3 ocircumflexhookabove;1ED5 ocircumflextilde;1ED7 ocyrillic;043E odblacute;0151 odblgrave;020D odeva;0913 odieresis;00F6 odieresiscyrillic;04E7 odotbelow;1ECD oe;0153 oekorean;315A ogonek;02DB ogonekcmb;0328 ograve;00F2 ogujarati;0A93 oharmenian;0585 ohiragana;304A ohookabove;1ECF ohorn;01A1 ohornacute;1EDB ohorndotbelow;1EE3 ohorngrave;1EDD ohornhookabove;1EDF ohorntilde;1EE1 ohungarumlaut;0151 oi;01A3 oinvertedbreve;020F okatakana;30AA okatakanahalfwidth;FF75 okorean;3157 olehebrew;05AB omacron;014D omacronacute;1E53 omacrongrave;1E51 omdeva;0950 omega;03C9 omega1;03D6 omegacyrillic;0461 omegalatinclosed;0277 omegaroundcyrillic;047B omegatitlocyrillic;047D omegatonos;03CE omgujarati;0AD0 omicron;03BF omicrontonos;03CC omonospace;FF4F one;0031 onearabic;0661 onebengali;09E7 onecircle;2460 onecircleinversesansserif;278A onedeva;0967 onedotenleader;2024 oneeighth;215B onefitted;F6DC onegujarati;0AE7 onegurmukhi;0A67 onehackarabic;0661 onehalf;00BD onehangzhou;3021 oneideographicparen;3220 oneinferior;2081 onemonospace;FF11 onenumeratorbengali;09F4 oneoldstyle;F731 oneparen;2474 oneperiod;2488 onepersian;06F1 onequarter;00BC oneroman;2170 onesuperior;00B9 onethai;0E51 onethird;2153 oogonek;01EB oogonekmacron;01ED oogurmukhi;0A13 oomatragurmukhi;0A4B oopen;0254 oparen;24AA openbullet;25E6 option;2325 ordfeminine;00AA ordmasculine;00BA orthogonal;221F oshortdeva;0912 oshortvowelsigndeva;094A oslash;00F8 oslashacute;01FF osmallhiragana;3049 osmallkatakana;30A9 osmallkatakanahalfwidth;FF6B ostrokeacute;01FF osuperior;F6F0 otcyrillic;047F otilde;00F5 otildeacute;1E4D otildedieresis;1E4F oubopomofo;3121 overline;203E overlinecenterline;FE4A overlinecmb;0305 overlinedashed;FE49 overlinedblwavy;FE4C overlinewavy;FE4B overscore;00AF ovowelsignbengali;09CB ovowelsigndeva;094B ovowelsigngujarati;0ACB p;0070 paampssquare;3380 paasentosquare;332B pabengali;09AA pacute;1E55 padeva;092A pagedown;21DF pageup;21DE pagujarati;0AAA pagurmukhi;0A2A pahiragana;3071 paiyannoithai;0E2F pakatakana;30D1 palatalizationcyrilliccmb;0484 palochkacyrillic;04C0 pansioskorean;317F paragraph;00B6 parallel;2225 parenleft;0028 parenleftaltonearabic;FD3E parenleftbt;F8ED parenleftex;F8EC parenleftinferior;208D parenleftmonospace;FF08 parenleftsmall;FE59 parenleftsuperior;207D parenlefttp;F8EB parenleftvertical;FE35 parenright;0029 parenrightaltonearabic;FD3F parenrightbt;F8F8 parenrightex;F8F7 parenrightinferior;208E parenrightmonospace;FF09 parenrightsmall;FE5A parenrightsuperior;207E parenrighttp;F8F6 parenrightvertical;FE36 partialdiff;2202 paseqhebrew;05C0 pashtahebrew;0599 pasquare;33A9 patah;05B7 patah11;05B7 patah1d;05B7 patah2a;05B7 patahhebrew;05B7 patahnarrowhebrew;05B7 patahquarterhebrew;05B7 patahwidehebrew;05B7 pazerhebrew;05A1 pbopomofo;3106 pcircle;24DF pdotaccent;1E57 pe;05E4 pecyrillic;043F pedagesh;FB44 pedageshhebrew;FB44 peezisquare;333B pefinaldageshhebrew;FB43 peharabic;067E peharmenian;057A pehebrew;05E4 pehfinalarabic;FB57 pehinitialarabic;FB58 pehiragana;307A pehmedialarabic;FB59 pekatakana;30DA pemiddlehookcyrillic;04A7 perafehebrew;FB4E percent;0025 percentarabic;066A percentmonospace;FF05 percentsmall;FE6A period;002E periodarmenian;0589 periodcentered;00B7 periodhalfwidth;FF61 periodinferior;F6E7 periodmonospace;FF0E periodsmall;FE52 periodsuperior;F6E8 perispomenigreekcmb;0342 perpendicular;22A5 perthousand;2030 peseta;20A7 pfsquare;338A phabengali;09AB phadeva;092B phagujarati;0AAB phagurmukhi;0A2B phi;03C6 phi1;03D5 phieuphacirclekorean;327A phieuphaparenkorean;321A phieuphcirclekorean;326C phieuphkorean;314D phieuphparenkorean;320C philatin;0278 phinthuthai;0E3A phisymbolgreek;03D5 phook;01A5 phophanthai;0E1E phophungthai;0E1C phosamphaothai;0E20 pi;03C0 pieupacirclekorean;3273 pieupaparenkorean;3213 pieupcieuckorean;3176 pieupcirclekorean;3265 pieupkiyeokkorean;3172 pieupkorean;3142 pieupparenkorean;3205 pieupsioskiyeokkorean;3174 pieupsioskorean;3144 pieupsiostikeutkorean;3175 pieupthieuthkorean;3177 pieuptikeutkorean;3173 pihiragana;3074 pikatakana;30D4 pisymbolgreek;03D6 piwrarmenian;0583 plus;002B plusbelowcmb;031F pluscircle;2295 plusminus;00B1 plusmod;02D6 plusmonospace;FF0B plussmall;FE62 plussuperior;207A pmonospace;FF50 pmsquare;33D8 pohiragana;307D pointingindexdownwhite;261F pointingindexleftwhite;261C pointingindexrightwhite;261E pointingindexupwhite;261D pokatakana;30DD poplathai;0E1B postalmark;3012 postalmarkface;3020 pparen;24AB precedes;227A prescription;211E primemod;02B9 primereversed;2035 product;220F projective;2305 prolongedkana;30FC propellor;2318 propersubset;2282 propersuperset;2283 proportion;2237 proportional;221D psi;03C8 psicyrillic;0471 psilipneumatacyrilliccmb;0486 pssquare;33B0 puhiragana;3077 pukatakana;30D7 pvsquare;33B4 pwsquare;33BA q;0071 qadeva;0958 qadmahebrew;05A8 qafarabic;0642 qaffinalarabic;FED6 qafinitialarabic;FED7 qafmedialarabic;FED8 qamats;05B8 qamats10;05B8 qamats1a;05B8 qamats1c;05B8 qamats27;05B8 qamats29;05B8 qamats33;05B8 qamatsde;05B8 qamatshebrew;05B8 qamatsnarrowhebrew;05B8 qamatsqatanhebrew;05B8 qamatsqatannarrowhebrew;05B8 qamatsqatanquarterhebrew;05B8 qamatsqatanwidehebrew;05B8 qamatsquarterhebrew;05B8 qamatswidehebrew;05B8 qarneyparahebrew;059F qbopomofo;3111 qcircle;24E0 qhook;02A0 qmonospace;FF51 qof;05E7 qofdagesh;FB47 qofdageshhebrew;FB47 qofhatafpatah;05E7 05B2 qofhatafpatahhebrew;05E7 05B2 qofhatafsegol;05E7 05B1 qofhatafsegolhebrew;05E7 05B1 qofhebrew;05E7 qofhiriq;05E7 05B4 qofhiriqhebrew;05E7 05B4 qofholam;05E7 05B9 qofholamhebrew;05E7 05B9 qofpatah;05E7 05B7 qofpatahhebrew;05E7 05B7 qofqamats;05E7 05B8 qofqamatshebrew;05E7 05B8 qofqubuts;05E7 05BB qofqubutshebrew;05E7 05BB qofsegol;05E7 05B6 qofsegolhebrew;05E7 05B6 qofsheva;05E7 05B0 qofshevahebrew;05E7 05B0 qoftsere;05E7 05B5 qoftserehebrew;05E7 05B5 qparen;24AC quarternote;2669 qubuts;05BB qubuts18;05BB qubuts25;05BB qubuts31;05BB qubutshebrew;05BB qubutsnarrowhebrew;05BB qubutsquarterhebrew;05BB qubutswidehebrew;05BB question;003F questionarabic;061F questionarmenian;055E questiondown;00BF questiondownsmall;F7BF questiongreek;037E questionmonospace;FF1F questionsmall;F73F quotedbl;0022 quotedblbase;201E quotedblleft;201C quotedblmonospace;FF02 quotedblprime;301E quotedblprimereversed;301D quotedblright;201D quoteleft;2018 quoteleftreversed;201B quotereversed;201B quoteright;2019 quoterightn;0149 quotesinglbase;201A quotesingle;0027 quotesinglemonospace;FF07 r;0072 raarmenian;057C rabengali;09B0 racute;0155 radeva;0930 radical;221A radicalex;F8E5 radoverssquare;33AE radoverssquaredsquare;33AF radsquare;33AD rafe;05BF rafehebrew;05BF ragujarati;0AB0 ragurmukhi;0A30 rahiragana;3089 rakatakana;30E9 rakatakanahalfwidth;FF97 ralowerdiagonalbengali;09F1 ramiddlediagonalbengali;09F0 ramshorn;0264 ratio;2236 rbopomofo;3116 rcaron;0159 rcedilla;0157 rcircle;24E1 rcommaaccent;0157 rdblgrave;0211 rdotaccent;1E59 rdotbelow;1E5B rdotbelowmacron;1E5D referencemark;203B reflexsubset;2286 reflexsuperset;2287 registered;00AE registersans;F8E8 registerserif;F6DA reharabic;0631 reharmenian;0580 rehfinalarabic;FEAE rehiragana;308C rehyehaleflamarabic;0631 FEF3 FE8E 0644 rekatakana;30EC rekatakanahalfwidth;FF9A resh;05E8 reshdageshhebrew;FB48 reshhatafpatah;05E8 05B2 reshhatafpatahhebrew;05E8 05B2 reshhatafsegol;05E8 05B1 reshhatafsegolhebrew;05E8 05B1 reshhebrew;05E8 reshhiriq;05E8 05B4 reshhiriqhebrew;05E8 05B4 reshholam;05E8 05B9 reshholamhebrew;05E8 05B9 reshpatah;05E8 05B7 reshpatahhebrew;05E8 05B7 reshqamats;05E8 05B8 reshqamatshebrew;05E8 05B8 reshqubuts;05E8 05BB reshqubutshebrew;05E8 05BB reshsegol;05E8 05B6 reshsegolhebrew;05E8 05B6 reshsheva;05E8 05B0 reshshevahebrew;05E8 05B0 reshtsere;05E8 05B5 reshtserehebrew;05E8 05B5 reversedtilde;223D reviahebrew;0597 reviamugrashhebrew;0597 revlogicalnot;2310 rfishhook;027E rfishhookreversed;027F rhabengali;09DD rhadeva;095D rho;03C1 rhook;027D rhookturned;027B rhookturnedsuperior;02B5 rhosymbolgreek;03F1 rhotichookmod;02DE rieulacirclekorean;3271 rieulaparenkorean;3211 rieulcirclekorean;3263 rieulhieuhkorean;3140 rieulkiyeokkorean;313A rieulkiyeoksioskorean;3169 rieulkorean;3139 rieulmieumkorean;313B rieulpansioskorean;316C rieulparenkorean;3203 rieulphieuphkorean;313F rieulpieupkorean;313C rieulpieupsioskorean;316B rieulsioskorean;313D rieulthieuthkorean;313E rieultikeutkorean;316A rieulyeorinhieuhkorean;316D rightangle;221F righttackbelowcmb;0319 righttriangle;22BF rihiragana;308A rikatakana;30EA rikatakanahalfwidth;FF98 ring;02DA ringbelowcmb;0325 ringcmb;030A ringhalfleft;02BF ringhalfleftarmenian;0559 ringhalfleftbelowcmb;031C ringhalfleftcentered;02D3 ringhalfright;02BE ringhalfrightbelowcmb;0339 ringhalfrightcentered;02D2 rinvertedbreve;0213 rittorusquare;3351 rlinebelow;1E5F rlongleg;027C rlonglegturned;027A rmonospace;FF52 rohiragana;308D rokatakana;30ED rokatakanahalfwidth;FF9B roruathai;0E23 rparen;24AD rrabengali;09DC rradeva;0931 rragurmukhi;0A5C rreharabic;0691 rrehfinalarabic;FB8D rrvocalicbengali;09E0 rrvocalicdeva;0960 rrvocalicgujarati;0AE0 rrvocalicvowelsignbengali;09C4 rrvocalicvowelsigndeva;0944 rrvocalicvowelsigngujarati;0AC4 rsuperior;F6F1 rtblock;2590 rturned;0279 rturnedsuperior;02B4 ruhiragana;308B rukatakana;30EB rukatakanahalfwidth;FF99 rupeemarkbengali;09F2 rupeesignbengali;09F3 rupiah;F6DD ruthai;0E24 rvocalicbengali;098B rvocalicdeva;090B rvocalicgujarati;0A8B rvocalicvowelsignbengali;09C3 rvocalicvowelsigndeva;0943 rvocalicvowelsigngujarati;0AC3 s;0073 sabengali;09B8 sacute;015B sacutedotaccent;1E65 sadarabic;0635 sadeva;0938 sadfinalarabic;FEBA sadinitialarabic;FEBB sadmedialarabic;FEBC sagujarati;0AB8 sagurmukhi;0A38 sahiragana;3055 sakatakana;30B5 sakatakanahalfwidth;FF7B sallallahoualayhewasallamarabic;FDFA samekh;05E1 samekhdagesh;FB41 samekhdageshhebrew;FB41 samekhhebrew;05E1 saraaathai;0E32 saraaethai;0E41 saraaimaimalaithai;0E44 saraaimaimuanthai;0E43 saraamthai;0E33 saraathai;0E30 saraethai;0E40 saraiileftthai;F886 saraiithai;0E35 saraileftthai;F885 saraithai;0E34 saraothai;0E42 saraueeleftthai;F888 saraueethai;0E37 saraueleftthai;F887 sarauethai;0E36 sarauthai;0E38 sarauuthai;0E39 sbopomofo;3119 scaron;0161 scarondotaccent;1E67 scedilla;015F schwa;0259 schwacyrillic;04D9 schwadieresiscyrillic;04DB schwahook;025A scircle;24E2 scircumflex;015D scommaaccent;0219 sdotaccent;1E61 sdotbelow;1E63 sdotbelowdotaccent;1E69 seagullbelowcmb;033C second;2033 secondtonechinese;02CA section;00A7 seenarabic;0633 seenfinalarabic;FEB2 seeninitialarabic;FEB3 seenmedialarabic;FEB4 segol;05B6 segol13;05B6 segol1f;05B6 segol2c;05B6 segolhebrew;05B6 segolnarrowhebrew;05B6 segolquarterhebrew;05B6 segoltahebrew;0592 segolwidehebrew;05B6 seharmenian;057D sehiragana;305B sekatakana;30BB sekatakanahalfwidth;FF7E semicolon;003B semicolonarabic;061B semicolonmonospace;FF1B semicolonsmall;FE54 semivoicedmarkkana;309C semivoicedmarkkanahalfwidth;FF9F sentisquare;3322 sentosquare;3323 seven;0037 sevenarabic;0667 sevenbengali;09ED sevencircle;2466 sevencircleinversesansserif;2790 sevendeva;096D seveneighths;215E sevengujarati;0AED sevengurmukhi;0A6D sevenhackarabic;0667 sevenhangzhou;3027 sevenideographicparen;3226 seveninferior;2087 sevenmonospace;FF17 sevenoldstyle;F737 sevenparen;247A sevenperiod;248E sevenpersian;06F7 sevenroman;2176 sevensuperior;2077 seventeencircle;2470 seventeenparen;2484 seventeenperiod;2498 seventhai;0E57 sfthyphen;00AD shaarmenian;0577 shabengali;09B6 shacyrillic;0448 shaddaarabic;0651 shaddadammaarabic;FC61 shaddadammatanarabic;FC5E shaddafathaarabic;FC60 shaddafathatanarabic;0651 064B shaddakasraarabic;FC62 shaddakasratanarabic;FC5F shade;2592 shadedark;2593 shadelight;2591 shademedium;2592 shadeva;0936 shagujarati;0AB6 shagurmukhi;0A36 shalshelethebrew;0593 shbopomofo;3115 shchacyrillic;0449 sheenarabic;0634 sheenfinalarabic;FEB6 sheeninitialarabic;FEB7 sheenmedialarabic;FEB8 sheicoptic;03E3 sheqel;20AA sheqelhebrew;20AA sheva;05B0 sheva115;05B0 sheva15;05B0 sheva22;05B0 sheva2e;05B0 shevahebrew;05B0 shevanarrowhebrew;05B0 shevaquarterhebrew;05B0 shevawidehebrew;05B0 shhacyrillic;04BB shimacoptic;03ED shin;05E9 shindagesh;FB49 shindageshhebrew;FB49 shindageshshindot;FB2C shindageshshindothebrew;FB2C shindageshsindot;FB2D shindageshsindothebrew;FB2D shindothebrew;05C1 shinhebrew;05E9 shinshindot;FB2A shinshindothebrew;FB2A shinsindot;FB2B shinsindothebrew;FB2B shook;0282 sigma;03C3 sigma1;03C2 sigmafinal;03C2 sigmalunatesymbolgreek;03F2 sihiragana;3057 sikatakana;30B7 sikatakanahalfwidth;FF7C siluqhebrew;05BD siluqlefthebrew;05BD similar;223C sindothebrew;05C2 siosacirclekorean;3274 siosaparenkorean;3214 sioscieuckorean;317E sioscirclekorean;3266 sioskiyeokkorean;317A sioskorean;3145 siosnieunkorean;317B siosparenkorean;3206 siospieupkorean;317D siostikeutkorean;317C six;0036 sixarabic;0666 sixbengali;09EC sixcircle;2465 sixcircleinversesansserif;278F sixdeva;096C sixgujarati;0AEC sixgurmukhi;0A6C sixhackarabic;0666 sixhangzhou;3026 sixideographicparen;3225 sixinferior;2086 sixmonospace;FF16 sixoldstyle;F736 sixparen;2479 sixperiod;248D sixpersian;06F6 sixroman;2175 sixsuperior;2076 sixteencircle;246F sixteencurrencydenominatorbengali;09F9 sixteenparen;2483 sixteenperiod;2497 sixthai;0E56 slash;002F slashmonospace;FF0F slong;017F slongdotaccent;1E9B smileface;263A smonospace;FF53 sofpasuqhebrew;05C3 softhyphen;00AD softsigncyrillic;044C sohiragana;305D sokatakana;30BD sokatakanahalfwidth;FF7F soliduslongoverlaycmb;0338 solidusshortoverlaycmb;0337 sorusithai;0E29 sosalathai;0E28 sosothai;0E0B sosuathai;0E2A space;0020 spacehackarabic;0020 spade;2660 spadesuitblack;2660 spadesuitwhite;2664 sparen;24AE squarebelowcmb;033B squarecc;33C4 squarecm;339D squarediagonalcrosshatchfill;25A9 squarehorizontalfill;25A4 squarekg;338F squarekm;339E squarekmcapital;33CE squareln;33D1 squarelog;33D2 squaremg;338E squaremil;33D5 squaremm;339C squaremsquared;33A1 squareorthogonalcrosshatchfill;25A6 squareupperlefttolowerrightfill;25A7 squareupperrighttolowerleftfill;25A8 squareverticalfill;25A5 squarewhitewithsmallblack;25A3 srsquare;33DB ssabengali;09B7 ssadeva;0937 ssagujarati;0AB7 ssangcieuckorean;3149 ssanghieuhkorean;3185 ssangieungkorean;3180 ssangkiyeokkorean;3132 ssangnieunkorean;3165 ssangpieupkorean;3143 ssangsioskorean;3146 ssangtikeutkorean;3138 ssuperior;F6F2 sterling;00A3 sterlingmonospace;FFE1 strokelongoverlaycmb;0336 strokeshortoverlaycmb;0335 subset;2282 subsetnotequal;228A subsetorequal;2286 succeeds;227B suchthat;220B suhiragana;3059 sukatakana;30B9 sukatakanahalfwidth;FF7D sukunarabic;0652 summation;2211 sun;263C superset;2283 supersetnotequal;228B supersetorequal;2287 svsquare;33DC syouwaerasquare;337C t;0074 tabengali;09A4 tackdown;22A4 tackleft;22A3 tadeva;0924 tagujarati;0AA4 tagurmukhi;0A24 taharabic;0637 tahfinalarabic;FEC2 tahinitialarabic;FEC3 tahiragana;305F tahmedialarabic;FEC4 taisyouerasquare;337D takatakana;30BF takatakanahalfwidth;FF80 tatweelarabic;0640 tau;03C4 tav;05EA tavdages;FB4A tavdagesh;FB4A tavdageshhebrew;FB4A tavhebrew;05EA tbar;0167 tbopomofo;310A tcaron;0165 tccurl;02A8 tcedilla;0163 tcheharabic;0686 tchehfinalarabic;FB7B tchehinitialarabic;FB7C tchehmedialarabic;FB7D tchehmeeminitialarabic;FB7C FEE4 tcircle;24E3 tcircumflexbelow;1E71 tcommaaccent;0163 tdieresis;1E97 tdotaccent;1E6B tdotbelow;1E6D tecyrillic;0442 tedescendercyrillic;04AD teharabic;062A tehfinalarabic;FE96 tehhahinitialarabic;FCA2 tehhahisolatedarabic;FC0C tehinitialarabic;FE97 tehiragana;3066 tehjeeminitialarabic;FCA1 tehjeemisolatedarabic;FC0B tehmarbutaarabic;0629 tehmarbutafinalarabic;FE94 tehmedialarabic;FE98 tehmeeminitialarabic;FCA4 tehmeemisolatedarabic;FC0E tehnoonfinalarabic;FC73 tekatakana;30C6 tekatakanahalfwidth;FF83 telephone;2121 telephoneblack;260E telishagedolahebrew;05A0 telishaqetanahebrew;05A9 tencircle;2469 tenideographicparen;3229 tenparen;247D tenperiod;2491 tenroman;2179 tesh;02A7 tet;05D8 tetdagesh;FB38 tetdageshhebrew;FB38 tethebrew;05D8 tetsecyrillic;04B5 tevirhebrew;059B tevirlefthebrew;059B thabengali;09A5 thadeva;0925 thagujarati;0AA5 thagurmukhi;0A25 thalarabic;0630 thalfinalarabic;FEAC thanthakhatlowleftthai;F898 thanthakhatlowrightthai;F897 thanthakhatthai;0E4C thanthakhatupperleftthai;F896 theharabic;062B thehfinalarabic;FE9A thehinitialarabic;FE9B thehmedialarabic;FE9C thereexists;2203 therefore;2234 theta;03B8 theta1;03D1 thetasymbolgreek;03D1 thieuthacirclekorean;3279 thieuthaparenkorean;3219 thieuthcirclekorean;326B thieuthkorean;314C thieuthparenkorean;320B thirteencircle;246C thirteenparen;2480 thirteenperiod;2494 thonangmonthothai;0E11 thook;01AD thophuthaothai;0E12 thorn;00FE thothahanthai;0E17 thothanthai;0E10 thothongthai;0E18 thothungthai;0E16 thousandcyrillic;0482 thousandsseparatorarabic;066C thousandsseparatorpersian;066C three;0033 threearabic;0663 threebengali;09E9 threecircle;2462 threecircleinversesansserif;278C threedeva;0969 threeeighths;215C threegujarati;0AE9 threegurmukhi;0A69 threehackarabic;0663 threehangzhou;3023 threeideographicparen;3222 threeinferior;2083 threemonospace;FF13 threenumeratorbengali;09F6 threeoldstyle;F733 threeparen;2476 threeperiod;248A threepersian;06F3 threequarters;00BE threequartersemdash;F6DE threeroman;2172 threesuperior;00B3 threethai;0E53 thzsquare;3394 tihiragana;3061 tikatakana;30C1 tikatakanahalfwidth;FF81 tikeutacirclekorean;3270 tikeutaparenkorean;3210 tikeutcirclekorean;3262 tikeutkorean;3137 tikeutparenkorean;3202 tilde;02DC tildebelowcmb;0330 tildecmb;0303 tildecomb;0303 tildedoublecmb;0360 tildeoperator;223C tildeoverlaycmb;0334 tildeverticalcmb;033E timescircle;2297 tipehahebrew;0596 tipehalefthebrew;0596 tippigurmukhi;0A70 titlocyrilliccmb;0483 tiwnarmenian;057F tlinebelow;1E6F tmonospace;FF54 toarmenian;0569 tohiragana;3068 tokatakana;30C8 tokatakanahalfwidth;FF84 tonebarextrahighmod;02E5 tonebarextralowmod;02E9 tonebarhighmod;02E6 tonebarlowmod;02E8 tonebarmidmod;02E7 tonefive;01BD tonesix;0185 tonetwo;01A8 tonos;0384 tonsquare;3327 topatakthai;0E0F tortoiseshellbracketleft;3014 tortoiseshellbracketleftsmall;FE5D tortoiseshellbracketleftvertical;FE39 tortoiseshellbracketright;3015 tortoiseshellbracketrightsmall;FE5E tortoiseshellbracketrightvertical;FE3A totaothai;0E15 tpalatalhook;01AB tparen;24AF trademark;2122 trademarksans;F8EA trademarkserif;F6DB tretroflexhook;0288 triagdn;25BC triaglf;25C4 triagrt;25BA triagup;25B2 ts;02A6 tsadi;05E6 tsadidagesh;FB46 tsadidageshhebrew;FB46 tsadihebrew;05E6 tsecyrillic;0446 tsere;05B5 tsere12;05B5 tsere1e;05B5 tsere2b;05B5 tserehebrew;05B5 tserenarrowhebrew;05B5 tserequarterhebrew;05B5 tserewidehebrew;05B5 tshecyrillic;045B tsuperior;F6F3 ttabengali;099F ttadeva;091F ttagujarati;0A9F ttagurmukhi;0A1F tteharabic;0679 ttehfinalarabic;FB67 ttehinitialarabic;FB68 ttehmedialarabic;FB69 tthabengali;09A0 tthadeva;0920 tthagujarati;0AA0 tthagurmukhi;0A20 tturned;0287 tuhiragana;3064 tukatakana;30C4 tukatakanahalfwidth;FF82 tusmallhiragana;3063 tusmallkatakana;30C3 tusmallkatakanahalfwidth;FF6F twelvecircle;246B twelveparen;247F twelveperiod;2493 twelveroman;217B twentycircle;2473 twentyhangzhou;5344 twentyparen;2487 twentyperiod;249B two;0032 twoarabic;0662 twobengali;09E8 twocircle;2461 twocircleinversesansserif;278B twodeva;0968 twodotenleader;2025 twodotleader;2025 twodotleadervertical;FE30 twogujarati;0AE8 twogurmukhi;0A68 twohackarabic;0662 twohangzhou;3022 twoideographicparen;3221 twoinferior;2082 twomonospace;FF12 twonumeratorbengali;09F5 twooldstyle;F732 twoparen;2475 twoperiod;2489 twopersian;06F2 tworoman;2171 twostroke;01BB twosuperior;00B2 twothai;0E52 twothirds;2154 u;0075 uacute;00FA ubar;0289 ubengali;0989 ubopomofo;3128 ubreve;016D ucaron;01D4 ucircle;24E4 ucircumflex;00FB ucircumflexbelow;1E77 ucyrillic;0443 udattadeva;0951 udblacute;0171 udblgrave;0215 udeva;0909 udieresis;00FC udieresisacute;01D8 udieresisbelow;1E73 udieresiscaron;01DA udieresiscyrillic;04F1 udieresisgrave;01DC udieresismacron;01D6 udotbelow;1EE5 ugrave;00F9 ugujarati;0A89 ugurmukhi;0A09 uhiragana;3046 uhookabove;1EE7 uhorn;01B0 uhornacute;1EE9 uhorndotbelow;1EF1 uhorngrave;1EEB uhornhookabove;1EED uhorntilde;1EEF uhungarumlaut;0171 uhungarumlautcyrillic;04F3 uinvertedbreve;0217 ukatakana;30A6 ukatakanahalfwidth;FF73 ukcyrillic;0479 ukorean;315C umacron;016B umacroncyrillic;04EF umacrondieresis;1E7B umatragurmukhi;0A41 umonospace;FF55 underscore;005F underscoredbl;2017 underscoremonospace;FF3F underscorevertical;FE33 underscorewavy;FE4F union;222A universal;2200 uogonek;0173 uparen;24B0 upblock;2580 upperdothebrew;05C4 upsilon;03C5 upsilondieresis;03CB upsilondieresistonos;03B0 upsilonlatin;028A upsilontonos;03CD uptackbelowcmb;031D uptackmod;02D4 uragurmukhi;0A73 uring;016F ushortcyrillic;045E usmallhiragana;3045 usmallkatakana;30A5 usmallkatakanahalfwidth;FF69 ustraightcyrillic;04AF ustraightstrokecyrillic;04B1 utilde;0169 utildeacute;1E79 utildebelow;1E75 uubengali;098A uudeva;090A uugujarati;0A8A uugurmukhi;0A0A uumatragurmukhi;0A42 uuvowelsignbengali;09C2 uuvowelsigndeva;0942 uuvowelsigngujarati;0AC2 uvowelsignbengali;09C1 uvowelsigndeva;0941 uvowelsigngujarati;0AC1 v;0076 vadeva;0935 vagujarati;0AB5 vagurmukhi;0A35 vakatakana;30F7 vav;05D5 vavdagesh;FB35 vavdagesh65;FB35 vavdageshhebrew;FB35 vavhebrew;05D5 vavholam;FB4B vavholamhebrew;FB4B vavvavhebrew;05F0 vavyodhebrew;05F1 vcircle;24E5 vdotbelow;1E7F vecyrillic;0432 veharabic;06A4 vehfinalarabic;FB6B vehinitialarabic;FB6C vehmedialarabic;FB6D vekatakana;30F9 venus;2640 verticalbar;007C verticallineabovecmb;030D verticallinebelowcmb;0329 verticallinelowmod;02CC verticallinemod;02C8 vewarmenian;057E vhook;028B vikatakana;30F8 viramabengali;09CD viramadeva;094D viramagujarati;0ACD visargabengali;0983 visargadeva;0903 visargagujarati;0A83 vmonospace;FF56 voarmenian;0578 voicediterationhiragana;309E voicediterationkatakana;30FE voicedmarkkana;309B voicedmarkkanahalfwidth;FF9E vokatakana;30FA vparen;24B1 vtilde;1E7D vturned;028C vuhiragana;3094 vukatakana;30F4 w;0077 wacute;1E83 waekorean;3159 wahiragana;308F wakatakana;30EF wakatakanahalfwidth;FF9C wakorean;3158 wasmallhiragana;308E wasmallkatakana;30EE wattosquare;3357 wavedash;301C wavyunderscorevertical;FE34 wawarabic;0648 wawfinalarabic;FEEE wawhamzaabovearabic;0624 wawhamzaabovefinalarabic;FE86 wbsquare;33DD wcircle;24E6 wcircumflex;0175 wdieresis;1E85 wdotaccent;1E87 wdotbelow;1E89 wehiragana;3091 weierstrass;2118 wekatakana;30F1 wekorean;315E weokorean;315D wgrave;1E81 whitebullet;25E6 whitecircle;25CB whitecircleinverse;25D9 whitecornerbracketleft;300E whitecornerbracketleftvertical;FE43 whitecornerbracketright;300F whitecornerbracketrightvertical;FE44 whitediamond;25C7 whitediamondcontainingblacksmalldiamond;25C8 whitedownpointingsmalltriangle;25BF whitedownpointingtriangle;25BD whiteleftpointingsmalltriangle;25C3 whiteleftpointingtriangle;25C1 whitelenticularbracketleft;3016 whitelenticularbracketright;3017 whiterightpointingsmalltriangle;25B9 whiterightpointingtriangle;25B7 whitesmallsquare;25AB whitesmilingface;263A whitesquare;25A1 whitestar;2606 whitetelephone;260F whitetortoiseshellbracketleft;3018 whitetortoiseshellbracketright;3019 whiteuppointingsmalltriangle;25B5 whiteuppointingtriangle;25B3 wihiragana;3090 wikatakana;30F0 wikorean;315F wmonospace;FF57 wohiragana;3092 wokatakana;30F2 wokatakanahalfwidth;FF66 won;20A9 wonmonospace;FFE6 wowaenthai;0E27 wparen;24B2 wring;1E98 wsuperior;02B7 wturned;028D wynn;01BF x;0078 xabovecmb;033D xbopomofo;3112 xcircle;24E7 xdieresis;1E8D xdotaccent;1E8B xeharmenian;056D xi;03BE xmonospace;FF58 xparen;24B3 xsuperior;02E3 y;0079 yaadosquare;334E yabengali;09AF yacute;00FD yadeva;092F yaekorean;3152 yagujarati;0AAF yagurmukhi;0A2F yahiragana;3084 yakatakana;30E4 yakatakanahalfwidth;FF94 yakorean;3151 yamakkanthai;0E4E yasmallhiragana;3083 yasmallkatakana;30E3 yasmallkatakanahalfwidth;FF6C yatcyrillic;0463 ycircle;24E8 ycircumflex;0177 ydieresis;00FF ydotaccent;1E8F ydotbelow;1EF5 yeharabic;064A yehbarreearabic;06D2 yehbarreefinalarabic;FBAF yehfinalarabic;FEF2 yehhamzaabovearabic;0626 yehhamzaabovefinalarabic;FE8A yehhamzaaboveinitialarabic;FE8B yehhamzaabovemedialarabic;FE8C yehinitialarabic;FEF3 yehmedialarabic;FEF4 yehmeeminitialarabic;FCDD yehmeemisolatedarabic;FC58 yehnoonfinalarabic;FC94 yehthreedotsbelowarabic;06D1 yekorean;3156 yen;00A5 yenmonospace;FFE5 yeokorean;3155 yeorinhieuhkorean;3186 yerahbenyomohebrew;05AA yerahbenyomolefthebrew;05AA yericyrillic;044B yerudieresiscyrillic;04F9 yesieungkorean;3181 yesieungpansioskorean;3183 yesieungsioskorean;3182 yetivhebrew;059A ygrave;1EF3 yhook;01B4 yhookabove;1EF7 yiarmenian;0575 yicyrillic;0457 yikorean;3162 yinyang;262F yiwnarmenian;0582 ymonospace;FF59 yod;05D9 yoddagesh;FB39 yoddageshhebrew;FB39 yodhebrew;05D9 yodyodhebrew;05F2 yodyodpatahhebrew;FB1F yohiragana;3088 yoikorean;3189 yokatakana;30E8 yokatakanahalfwidth;FF96 yokorean;315B yosmallhiragana;3087 yosmallkatakana;30E7 yosmallkatakanahalfwidth;FF6E yotgreek;03F3 yoyaekorean;3188 yoyakorean;3187 yoyakthai;0E22 yoyingthai;0E0D yparen;24B4 ypogegrammeni;037A ypogegrammenigreekcmb;0345 yr;01A6 yring;1E99 ysuperior;02B8 ytilde;1EF9 yturned;028E yuhiragana;3086 yuikorean;318C yukatakana;30E6 yukatakanahalfwidth;FF95 yukorean;3160 yusbigcyrillic;046B yusbigiotifiedcyrillic;046D yuslittlecyrillic;0467 yuslittleiotifiedcyrillic;0469 yusmallhiragana;3085 yusmallkatakana;30E5 yusmallkatakanahalfwidth;FF6D yuyekorean;318B yuyeokorean;318A yyabengali;09DF yyadeva;095F z;007A zaarmenian;0566 zacute;017A zadeva;095B zagurmukhi;0A5B zaharabic;0638 zahfinalarabic;FEC6 zahinitialarabic;FEC7 zahiragana;3056 zahmedialarabic;FEC8 zainarabic;0632 zainfinalarabic;FEB0 zakatakana;30B6 zaqefgadolhebrew;0595 zaqefqatanhebrew;0594 zarqahebrew;0598 zayin;05D6 zayindagesh;FB36 zayindageshhebrew;FB36 zayinhebrew;05D6 zbopomofo;3117 zcaron;017E zcircle;24E9 zcircumflex;1E91 zcurl;0291 zdot;017C zdotaccent;017C zdotbelow;1E93 zecyrillic;0437 zedescendercyrillic;0499 zedieresiscyrillic;04DF zehiragana;305C zekatakana;30BC zero;0030 zeroarabic;0660 zerobengali;09E6 zerodeva;0966 zerogujarati;0AE6 zerogurmukhi;0A66 zerohackarabic;0660 zeroinferior;2080 zeromonospace;FF10 zerooldstyle;F730 zeropersian;06F0 zerosuperior;2070 zerothai;0E50 zerowidthjoiner;FEFF zerowidthnonjoiner;200C zerowidthspace;200B zeta;03B6 zhbopomofo;3113 zhearmenian;056A zhebrevecyrillic;04C2 zhecyrillic;0436 zhedescendercyrillic;0497 zhedieresiscyrillic;04DD zihiragana;3058 zikatakana;30B8 zinorhebrew;05AE zlinebelow;1E95 zmonospace;FF5A zohiragana;305E zokatakana;30BE zparen;24B5 zretroflexhook;0290 zstroke;01B6 zuhiragana;305A zukatakana;30BA #--end # # Name: Adobe Glyph List # Table version: 1.2 # Date: 22 Oct 1998 # # Description: # # The Adobe Glyph List (AGL) list relates Unicode values (UVs) to glyph # names, and should be used only as described in the document "Unicode and # Glyph Names," at # http://partners.adobe.com/asn/developer/typeforum/unicodegn.html . # # The glyph name to UV relation is one to many. 12 glyph names are mapped to # two UVs each; each UV has a separate entry. All other glyph names are # mapped to one UV each. # # The Unicode Standard version 2.1 is used for all UVs outside of the Private # Use area, except for 4 entries (see Revision History for 1.2 below). # # There are 1051 entries in this list, 171 of which are in the Corporate Use # subarea (CUS). Refer to the document "Unicode Corporate Use Subarea as used # by Adobe Systems," at # http://partners.adobe.com/asn/developer/typeforum/corporateuse.txt # for compatibility decompositions for these characters, and to the document # "Unicode and Glyph Names" for more information the CUS. # # Format: Semicolon-delimited fields: # # (1) Standard UV or CUS UV. (4 uppercase hexadecimal digits) # # (2) Glyph name. (upper- and lowercase letters, digits) # # (3) Character names: Unicode character names for standard UVs, and # descriptive names for CUS UVs. (uppercase letters, hyphen, space) # # (4) [optional] Comment. A comment of "Duplicate" indicates one of two # UVs of a double-mapping. It is the UV that may be given a uni # override, or the UV that is in the CUS, as described in the document # "Unicode and Glyph Names." # # The entries are sorted by glyph name in increasing ASCII order; entries # with the same glyph name are sorted in decreasing priority order. # # Lines starting with "#" are comments; blank lines should be ignored. # # Revision History: # # 1.2 [22 Oct 1998] # # Some Central European glyph names were remapped and the glyph "dotlessj" # was added. Some entries in the table below have not changed but are # included to provide a complete context for other glyphs that have been # remapped or double-mapped. "-" means that the entry for that UV does not # exist in the AGL. # # -------- ---------------------- ---------------- -------------- # UV Character name AGL 1.1 AGL 1.2 # (shortened) glyph name glyph name # -------- ---------------------- ---------------- -------------- # 015E/F S/s with cedilla S/scommaaccent S/scedilla # 0162/3 T/t with cedilla T/tcommaaccent T/tcommaaccent # 0218/9 S/s with comma below - S/scommaaccent # 021A/B T/t with comma below - T/tcommaaccent # 1E9E/F S/s with comma below S/scedilla - # F6C1/2 S/s with cedilla S/scedilla S/scedilla # F6BE dotless j - dotlessj # -------- ---------------------- ---------------- -------------- # # The characters at U+1E9E/F in AGL 1.1, LATIN CAPITAL/SMALL LETTER S WITH # COMMA BELOW, which are proposed new characters (see (b) in the notes for # AGL 1.1 below), have since been reassigned by the Unicode Standard to new # proposed values of U+0218/9. These characters, as well as U+021A/B, LATIN # CAPITAL/SMALL LETTER T WITH COMMA BELOW, are not in the Unicode Standard # 2.1. # # Entries with the same glyph name are now sorted in decreasing priority # order instead of in increasing UV order. # # 1.1 [24 Nov 1997] # # a. The "Euro" glyph's UV assignment is changed from U+20A0 (EURO-CURRENCY # SIGN) to U+20AC (EURO SIGN). While U+20AC is not defined in the # Unicode Standard 2.0, it has been accepted by the Unicode Technical # Committee for the next version of the Standard; it has not yet passed # the ISO approval process as of 7 November '97. # # b. Glyphs "Scedilla" and "scedilla", which were assigned in the Corporate # Use Subarea in AGL 1.0, are now additionally mapped to U+1E9E and # U+1E9F respectively. These two UVs share the same Unicode approval # status as the Euro glyph (see a. above). # # c. The "fraction" glyph is now additionally mapped to U+2215, to match # Windows Glyph List 4. # # d. The descriptive name for glyph "onefitted", in the Corporate Use # subarea, is changed from "TABULAR DIGIT ONE" to "PROPORTIONAL DIGIT # ONE". # # 1.0 [17 Jul 1997] Original version # A;0041 AE;00C6 AEacute;01FC AEsmall;F7E6 Aacute;00C1 Aacutesmall;F7E1 Abreve;0102 Acircumflex;00C2 Acircumflexsmall;F7E2 Acute;F6C9 Acutesmall;F7B4 Adieresis;00C4 Adieresissmall;F7E4 Agrave;00C0 Agravesmall;F7E0 Alpha;0391 Alphatonos;0386 Amacron;0100 Aogonek;0104 Aring;00C5 Aringacute;01FA Aringsmall;F7E5 Asmall;F761 Atilde;00C3 Atildesmall;F7E3 B;0042 Beta;0392 Brevesmall;F6F4 Bsmall;F762 C;0043 Cacute;0106 Caron;F6CA Caronsmall;F6F5 Ccaron;010C Ccedilla;00C7 Ccedillasmall;F7E7 Ccircumflex;0108 Cdotaccent;010A Cedillasmall;F7B8 Chi;03A7 Circumflexsmall;F6F6 Csmall;F763 D;0044 Dcaron;010E Dcroat;0110 Delta;0394 Dieresis;F6CB DieresisAcute;F6CC DieresisGrave;F6CD Dieresissmall;F7A8 Dotaccentsmall;F6F7 Dsmall;F764 E;0045 Eacute;00C9 Eacutesmall;F7E9 Ebreve;0114 Ecaron;011A Ecircumflex;00CA Ecircumflexsmall;F7EA Edieresis;00CB Edieresissmall;F7EB Edotaccent;0116 Egrave;00C8 Egravesmall;F7E8 Emacron;0112 Eng;014A Eogonek;0118 Epsilon;0395 Epsilontonos;0388 Esmall;F765 Eta;0397 Etatonos;0389 Eth;00D0 Ethsmall;F7F0 Euro;20AC F;0046 Fsmall;F766 G;0047 Gamma;0393 Gbreve;011E Gcaron;01E6 Gcircumflex;011C Gcommaaccent;0122 Gdotaccent;0120 Grave;F6CE Gravesmall;F760 Gsmall;F767 H;0048 H18533;25CF H18543;25AA H18551;25AB H22073;25A1 Hbar;0126 Hcircumflex;0124 Hsmall;F768 Hungarumlaut;F6CF Hungarumlautsmall;F6F8 I;0049 IJ;0132 Iacute;00CD Iacutesmall;F7ED Ibreve;012C Icircumflex;00CE Icircumflexsmall;F7EE Idieresis;00CF Idieresissmall;F7EF Idotaccent;0130 Ifraktur;2111 Igrave;00CC Igravesmall;F7EC Imacron;012A Iogonek;012E Iota;0399 Iotadieresis;03AA Iotatonos;038A Ismall;F769 Itilde;0128 J;004A Jcircumflex;0134 Jsmall;F76A K;004B Kappa;039A Kcommaaccent;0136 Ksmall;F76B L;004C LL;F6BF Lacute;0139 Lambda;039B Lcaron;013D Lcommaaccent;013B Ldot;013F Lslash;0141 Lslashsmall;F6F9 Lsmall;F76C M;004D Macron;F6D0 Macronsmall;F7AF Msmall;F76D Mu;039C N;004E Nacute;0143 Ncaron;0147 Ncommaaccent;0145 Nsmall;F76E Ntilde;00D1 Ntildesmall;F7F1 Nu;039D O;004F OE;0152 OEsmall;F6FA Oacute;00D3 Oacutesmall;F7F3 Obreve;014E Ocircumflex;00D4 Ocircumflexsmall;F7F4 Odieresis;00D6 Odieresissmall;F7F6 Ogoneksmall;F6FB Ograve;00D2 Ogravesmall;F7F2 Ohorn;01A0 Ohungarumlaut;0150 Omacron;014C Omega;03A9 Omegatonos;038F Omicron;039F Omicrontonos;038C Oslash;00D8 Oslashacute;01FE Oslashsmall;F7F8 Osmall;F76F Otilde;00D5 Otildesmall;F7F5 P;0050 Phi;03A6 Pi;03A0 Psi;03A8 Psmall;F770 Q;0051 Qsmall;F771 R;0052 Racute;0154 Rcaron;0158 Rcommaaccent;0156 Rfraktur;211C Rho;03A1 Ringsmall;F6FC Rsmall;F772 S;0053 SF010000;250C SF020000;2514 SF030000;2510 SF040000;2518 SF050000;253C SF060000;252C SF070000;2534 SF080000;251C SF090000;2524 SF100000;2500 SF110000;2502 SF190000;2561 SF200000;2562 SF210000;2556 SF220000;2555 SF230000;2563 SF240000;2551 SF250000;2557 SF260000;255D SF270000;255C SF280000;255B SF360000;255E SF370000;255F SF380000;255A SF390000;2554 SF400000;2569 SF410000;2566 SF420000;2560 SF430000;2550 SF440000;256C SF450000;2567 SF460000;2568 SF470000;2564 SF480000;2565 SF490000;2559 SF500000;2558 SF510000;2552 SF520000;2553 SF530000;256B SF540000;256A Sacute;015A Scaron;0160 Scaronsmall;F6FD Scedilla;015E Scircumflex;015C Scommaaccent;0218 Sigma;03A3 Ssmall;F773 T;0054 Tau;03A4 Tbar;0166 Tcaron;0164 Tcommaaccent;0162 Theta;0398 Thorn;00DE Thornsmall;F7FE Tildesmall;F6FE Tsmall;F774 U;0055 Uacute;00DA Uacutesmall;F7FA Ubreve;016C Ucircumflex;00DB Ucircumflexsmall;F7FB Udieresis;00DC Udieresissmall;F7FC Ugrave;00D9 Ugravesmall;F7F9 Uhorn;01AF Uhungarumlaut;0170 Umacron;016A Uogonek;0172 Upsilon;03A5 Upsilon1;03D2 Upsilondieresis;03AB Upsilontonos;038E Uring;016E Usmall;F775 Utilde;0168 V;0056 Vsmall;F776 W;0057 Wacute;1E82 Wcircumflex;0174 Wdieresis;1E84 Wgrave;1E80 Wsmall;F777 X;0058 Xi;039E Xsmall;F778 Y;0059 Yacute;00DD Yacutesmall;F7FD Ycircumflex;0176 Ydieresis;0178 Ydieresissmall;F7FF Ygrave;1EF2 Ysmall;F779 Z;005A Zacute;0179 Zcaron;017D Zcaronsmall;F6FF Zdotaccent;017B Zeta;0396 Zsmall;F77A a;0061 aacute;00E1 abreve;0103 acircumflex;00E2 acute;00B4 acutecomb;0301 adieresis;00E4 ae;00E6 aeacute;01FD afii00208;2015 afii10017;0410 afii10018;0411 afii10019;0412 afii10020;0413 afii10021;0414 afii10022;0415 afii10023;0401 afii10024;0416 afii10025;0417 afii10026;0418 afii10027;0419 afii10028;041A afii10029;041B afii10030;041C afii10031;041D afii10032;041E afii10033;041F afii10034;0420 afii10035;0421 afii10036;0422 afii10037;0423 afii10038;0424 afii10039;0425 afii10040;0426 afii10041;0427 afii10042;0428 afii10043;0429 afii10044;042A afii10045;042B afii10046;042C afii10047;042D afii10048;042E afii10049;042F afii10050;0490 afii10051;0402 afii10052;0403 afii10053;0404 afii10054;0405 afii10055;0406 afii10056;0407 afii10057;0408 afii10058;0409 afii10059;040A afii10060;040B afii10061;040C afii10062;040E afii10063;F6C4 afii10064;F6C5 afii10065;0430 afii10066;0431 afii10067;0432 afii10068;0433 afii10069;0434 afii10070;0435 afii10071;0451 afii10072;0436 afii10073;0437 afii10074;0438 afii10075;0439 afii10076;043A afii10077;043B afii10078;043C afii10079;043D afii10080;043E afii10081;043F afii10082;0440 afii10083;0441 afii10084;0442 afii10085;0443 afii10086;0444 afii10087;0445 afii10088;0446 afii10089;0447 afii10090;0448 afii10091;0449 afii10092;044A afii10093;044B afii10094;044C afii10095;044D afii10096;044E afii10097;044F afii10098;0491 afii10099;0452 afii10100;0453 afii10101;0454 afii10102;0455 afii10103;0456 afii10104;0457 afii10105;0458 afii10106;0459 afii10107;045A afii10108;045B afii10109;045C afii10110;045E afii10145;040F afii10146;0462 afii10147;0472 afii10148;0474 afii10192;F6C6 afii10193;045F afii10194;0463 afii10195;0473 afii10196;0475 afii10831;F6C7 afii10832;F6C8 afii10846;04D9 afii299;200E afii300;200F afii301;200D afii57381;066A afii57388;060C afii57392;0660 afii57393;0661 afii57394;0662 afii57395;0663 afii57396;0664 afii57397;0665 afii57398;0666 afii57399;0667 afii57400;0668 afii57401;0669 afii57403;061B afii57407;061F afii57409;0621 afii57410;0622 afii57411;0623 afii57412;0624 afii57413;0625 afii57414;0626 afii57415;0627 afii57416;0628 afii57417;0629 afii57418;062A afii57419;062B afii57420;062C afii57421;062D afii57422;062E afii57423;062F afii57424;0630 afii57425;0631 afii57426;0632 afii57427;0633 afii57428;0634 afii57429;0635 afii57430;0636 afii57431;0637 afii57432;0638 afii57433;0639 afii57434;063A afii57440;0640 afii57441;0641 afii57442;0642 afii57443;0643 afii57444;0644 afii57445;0645 afii57446;0646 afii57448;0648 afii57449;0649 afii57450;064A afii57451;064B afii57452;064C afii57453;064D afii57454;064E afii57455;064F afii57456;0650 afii57457;0651 afii57458;0652 afii57470;0647 afii57505;06A4 afii57506;067E afii57507;0686 afii57508;0698 afii57509;06AF afii57511;0679 afii57512;0688 afii57513;0691 afii57514;06BA afii57519;06D2 afii57534;06D5 afii57636;20AA afii57645;05BE afii57658;05C3 afii57664;05D0 afii57665;05D1 afii57666;05D2 afii57667;05D3 afii57668;05D4 afii57669;05D5 afii57670;05D6 afii57671;05D7 afii57672;05D8 afii57673;05D9 afii57674;05DA afii57675;05DB afii57676;05DC afii57677;05DD afii57678;05DE afii57679;05DF afii57680;05E0 afii57681;05E1 afii57682;05E2 afii57683;05E3 afii57684;05E4 afii57685;05E5 afii57686;05E6 afii57687;05E7 afii57688;05E8 afii57689;05E9 afii57690;05EA afii57694;FB2A afii57695;FB2B afii57700;FB4B afii57705;FB1F afii57716;05F0 afii57717;05F1 afii57718;05F2 afii57723;FB35 afii57793;05B4 afii57794;05B5 afii57795;05B6 afii57796;05BB afii57797;05B8 afii57798;05B7 afii57799;05B0 afii57800;05B2 afii57801;05B1 afii57802;05B3 afii57803;05C2 afii57804;05C1 afii57806;05B9 afii57807;05BC afii57839;05BD afii57841;05BF afii57842;05C0 afii57929;02BC afii61248;2105 afii61289;2113 afii61352;2116 afii61573;202C afii61574;202D afii61575;202E afii61664;200C afii63167;066D afii64937;02BD agrave;00E0 aleph;2135 alpha;03B1 alphatonos;03AC amacron;0101 ampersand;0026 ampersandsmall;F726 angle;2220 angleleft;2329 angleright;232A anoteleia;0387 aogonek;0105 approxequal;2248 aring;00E5 aringacute;01FB arrowboth;2194 arrowdblboth;21D4 arrowdbldown;21D3 arrowdblleft;21D0 arrowdblright;21D2 arrowdblup;21D1 arrowdown;2193 arrowhorizex;F8E7 arrowleft;2190 arrowright;2192 arrowup;2191 arrowupdn;2195 arrowupdnbse;21A8 arrowvertex;F8E6 asciicircum;005E asciitilde;007E asterisk;002A asteriskmath;2217 asuperior;F6E9 at;0040 atilde;00E3 b;0062 backslash;005C bar;007C beta;03B2 block;2588 braceex;F8F4 braceleft;007B braceleftbt;F8F3 braceleftmid;F8F2 bracelefttp;F8F1 braceright;007D bracerightbt;F8FE bracerightmid;F8FD bracerighttp;F8FC bracketleft;005B bracketleftbt;F8F0 bracketleftex;F8EF bracketlefttp;F8EE bracketright;005D bracketrightbt;F8FB bracketrightex;F8FA bracketrighttp;F8F9 breve;02D8 brokenbar;00A6 bsuperior;F6EA bullet;2022 c;0063 cacute;0107 caron;02C7 carriagereturn;21B5 ccaron;010D ccedilla;00E7 ccircumflex;0109 cdotaccent;010B cedilla;00B8 cent;00A2 centinferior;F6DF centoldstyle;F7A2 centsuperior;F6E0 chi;03C7 circle;25CB circlemultiply;2297 circleplus;2295 circumflex;02C6 club;2663 colon;003A colonmonetary;20A1 comma;002C commaaccent;F6C3 commainferior;F6E1 commasuperior;F6E2 congruent;2245 copyright;00A9 copyrightsans;F8E9 copyrightserif;F6D9 currency;00A4 cyrBreve;F6D1 cyrFlex;F6D2 cyrbreve;F6D4 cyrflex;F6D5 d;0064 dagger;2020 daggerdbl;2021 dblGrave;F6D3 dblgrave;F6D6 dcaron;010F dcroat;0111 degree;00B0 delta;03B4 diamond;2666 dieresis;00A8 dieresisacute;F6D7 dieresisgrave;F6D8 dieresistonos;0385 divide;00F7 dkshade;2593 dnblock;2584 dollar;0024 dollarinferior;F6E3 dollaroldstyle;F724 dollarsuperior;F6E4 dong;20AB dotaccent;02D9 dotbelowcomb;0323 dotlessi;0131 dotlessj;F6BE dotmath;22C5 dsuperior;F6EB e;0065 eacute;00E9 ebreve;0115 ecaron;011B ecircumflex;00EA edieresis;00EB edotaccent;0117 egrave;00E8 eight;0038 eightinferior;2088 eightoldstyle;F738 eightsuperior;2078 element;2208 ellipsis;2026 emacron;0113 emdash;2014 emptyset;2205 endash;2013 eng;014B eogonek;0119 epsilon;03B5 epsilontonos;03AD equal;003D equivalence;2261 estimated;212E esuperior;F6EC eta;03B7 etatonos;03AE eth;00F0 exclam;0021 exclamdbl;203C exclamdown;00A1 exclamdownsmall;F7A1 exclamsmall;F721 existential;2203 f;0066 female;2640 ff;FB00 ffi;FB03 ffl;FB04 fi;FB01 figuredash;2012 filledbox;25A0 filledrect;25AC five;0035 fiveeighths;215D fiveinferior;2085 fiveoldstyle;F735 fivesuperior;2075 fl;FB02 florin;0192 four;0034 fourinferior;2084 fouroldstyle;F734 foursuperior;2074 fraction;2044 franc;20A3 g;0067 gamma;03B3 gbreve;011F gcaron;01E7 gcircumflex;011D gcommaaccent;0123 gdotaccent;0121 germandbls;00DF gradient;2207 grave;0060 gravecomb;0300 greater;003E greaterequal;2265 guillemotleft;00AB guillemotright;00BB guilsinglleft;2039 guilsinglright;203A h;0068 hbar;0127 hcircumflex;0125 heart;2665 hookabovecomb;0309 house;2302 hungarumlaut;02DD hyphen;002D hypheninferior;F6E5 hyphensuperior;F6E6 i;0069 iacute;00ED ibreve;012D icircumflex;00EE idieresis;00EF igrave;00EC ij;0133 imacron;012B infinity;221E integral;222B integralbt;2321 integralex;F8F5 integraltp;2320 intersection;2229 invbullet;25D8 invcircle;25D9 invsmileface;263B iogonek;012F iota;03B9 iotadieresis;03CA iotadieresistonos;0390 iotatonos;03AF isuperior;F6ED itilde;0129 j;006A jcircumflex;0135 k;006B kappa;03BA kcommaaccent;0137 kgreenlandic;0138 l;006C lacute;013A lambda;03BB lcaron;013E lcommaaccent;013C ldot;0140 less;003C lessequal;2264 lfblock;258C lira;20A4 ll;F6C0 logicaland;2227 logicalnot;00AC logicalor;2228 longs;017F lozenge;25CA lslash;0142 lsuperior;F6EE ltshade;2591 m;006D macron;00AF male;2642 minus;2212 minute;2032 msuperior;F6EF mu;03BC multiply;00D7 musicalnote;266A musicalnotedbl;266B n;006E nacute;0144 napostrophe;0149 ncaron;0148 ncommaaccent;0146 nine;0039 nineinferior;2089 nineoldstyle;F739 ninesuperior;2079 notelement;2209 notequal;2260 notsubset;2284 nsuperior;207F ntilde;00F1 nu;03BD numbersign;0023 o;006F oacute;00F3 obreve;014F ocircumflex;00F4 odieresis;00F6 oe;0153 ogonek;02DB ograve;00F2 ohorn;01A1 ohungarumlaut;0151 omacron;014D omega;03C9 omega1;03D6 omegatonos;03CE omicron;03BF omicrontonos;03CC one;0031 onedotenleader;2024 oneeighth;215B onefitted;F6DC onehalf;00BD oneinferior;2081 oneoldstyle;F731 onequarter;00BC onesuperior;00B9 onethird;2153 openbullet;25E6 ordfeminine;00AA ordmasculine;00BA orthogonal;221F oslash;00F8 oslashacute;01FF osuperior;F6F0 otilde;00F5 p;0070 paragraph;00B6 parenleft;0028 parenleftbt;F8ED parenleftex;F8EC parenleftinferior;208D parenleftsuperior;207D parenlefttp;F8EB parenright;0029 parenrightbt;F8F8 parenrightex;F8F7 parenrightinferior;208E parenrightsuperior;207E parenrighttp;F8F6 partialdiff;2202 percent;0025 period;002E periodcentered;00B7 periodinferior;F6E7 periodsuperior;F6E8 perpendicular;22A5 perthousand;2030 peseta;20A7 phi;03C6 phi1;03D5 pi;03C0 plus;002B plusminus;00B1 prescription;211E product;220F propersubset;2282 propersuperset;2283 proportional;221D psi;03C8 q;0071 question;003F questiondown;00BF questiondownsmall;F7BF questionsmall;F73F quotedbl;0022 quotedblbase;201E quotedblleft;201C quotedblright;201D quoteleft;2018 quotereversed;201B quoteright;2019 quotesinglbase;201A quotesingle;0027 r;0072 racute;0155 radical;221A radicalex;F8E5 rcaron;0159 rcommaaccent;0157 reflexsubset;2286 reflexsuperset;2287 registered;00AE registersans;F8E8 registerserif;F6DA revlogicalnot;2310 rho;03C1 ring;02DA rsuperior;F6F1 rtblock;2590 rupiah;F6DD s;0073 sacute;015B scaron;0161 scedilla;015F scircumflex;015D scommaaccent;0219 second;2033 section;00A7 semicolon;003B seven;0037 seveneighths;215E seveninferior;2087 sevenoldstyle;F737 sevensuperior;2077 shade;2592 sigma;03C3 sigma1;03C2 similar;223C six;0036 sixinferior;2086 sixoldstyle;F736 sixsuperior;2076 slash;002F smileface;263A space;0020 spade;2660 ssuperior;F6F2 sterling;00A3 suchthat;220B summation;2211 sun;263C t;0074 tau;03C4 tbar;0167 tcaron;0165 tcommaaccent;0163 therefore;2234 theta;03B8 theta1;03D1 thorn;00FE three;0033 threeeighths;215C threeinferior;2083 threeoldstyle;F733 threequarters;00BE threequartersemdash;F6DE threesuperior;00B3 tilde;02DC tildecomb;0303 tonos;0384 trademark;2122 trademarksans;F8EA trademarkserif;F6DB triagdn;25BC triaglf;25C4 triagrt;25BA triagup;25B2 tsuperior;F6F3 two;0032 twodotenleader;2025 twoinferior;2082 twooldstyle;F732 twosuperior;00B2 twothirds;2154 u;0075 uacute;00FA ubreve;016D ucircumflex;00FB udieresis;00FC ugrave;00F9 uhorn;01B0 uhungarumlaut;0171 umacron;016B underscore;005F underscoredbl;2017 union;222A universal;2200 uogonek;0173 upblock;2580 upsilon;03C5 upsilondieresis;03CB upsilondieresistonos;03B0 upsilontonos;03CD uring;016F utilde;0169 v;0076 w;0077 wacute;1E83 wcircumflex;0175 wdieresis;1E85 weierstrass;2118 wgrave;1E81 x;0078 xi;03BE y;0079 yacute;00FD ycircumflex;0177 ydieresis;00FF yen;00A5 ygrave;1EF3 z;007A zacute;017A zcaron;017E zdotaccent;017C zero;0030 zeroinferior;2080 zerooldstyle;F730 zerosuperior;2070 zeta;03B6 src/core/com/lowagie/text/pdf/fonts/mustRead.html100644 0 0 1645 11000354125 17466 0ustar 0 0 Core 14 AFM Files - ReadMe or
    This file and the 14 PostScript(R) AFM files it accompanies may be used, copied, and distributed for any purpose and without charge, with or without modification, provided that all copyright notices are retained; that the AFM files are not distributed without this file; that all modifications to this file or any of the AFM files are prominently noted in the modified file(s); and that this paragraph is not modified. Adobe Systems has no responsibility or obligation to support the use of the AFM files. Col
    src/core/com/lowagie/text/pdf/hyphenation/ByteVector.java100644 0 0 5521 11000354034 21136 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.io.Serializable; /** * This class implements a simple byte vector with access to the * underlying array. * * @author Carlos Villegas */ public class ByteVector implements Serializable { private static final long serialVersionUID = -1096301185375029343L; /** * Capacity increment size */ private static final int DEFAULT_BLOCK_SIZE = 2048; private int blockSize; /** * The encapsulated array */ private byte[] array; /** * Points to next free item */ private int n; public ByteVector() { this(DEFAULT_BLOCK_SIZE); } public ByteVector(int capacity) { if (capacity > 0) { blockSize = capacity; } else { blockSize = DEFAULT_BLOCK_SIZE; } array = new byte[blockSize]; n = 0; } public ByteVector(byte[] a) { blockSize = DEFAULT_BLOCK_SIZE; array = a; n = 0; } public ByteVector(byte[] a, int capacity) { if (capacity > 0) { blockSize = capacity; } else { blockSize = DEFAULT_BLOCK_SIZE; } array = a; n = 0; } public byte[] getArray() { return array; } /** * return number of items in array */ public int length() { return n; } /** * returns current capacity of array */ public int capacity() { return array.length; } public void put(int index, byte val) { array[index] = val; } public byte get(int index) { return array[index]; } /** * This is to implement memory allocation in the array. Like malloc(). */ public int alloc(int size) { int index = n; int len = array.length; if (n + size >= len) { byte[] aux = new byte[len + blockSize]; System.arraycopy(array, 0, aux, 0, len); array = aux; } n += size; return index; } public void trimToSize() { if (n < array.length) { byte[] aux = new byte[n]; System.arraycopy(array, 0, aux, 0, n); array = aux; } } } src/core/com/lowagie/text/pdf/hyphenation/CharVector.java100644 0 0 6035 11000354034 21111 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.io.Serializable; /** * This class implements a simple char vector with access to the * underlying array. * * @author Carlos Villegas */ public class CharVector implements Cloneable, Serializable { private static final long serialVersionUID = -4875768298308363544L; /** * Capacity increment size */ private static final int DEFAULT_BLOCK_SIZE = 2048; private int blockSize; /** * The encapsulated array */ private char[] array; /** * Points to next free item */ private int n; public CharVector() { this(DEFAULT_BLOCK_SIZE); } public CharVector(int capacity) { if (capacity > 0) { blockSize = capacity; } else { blockSize = DEFAULT_BLOCK_SIZE; } array = new char[blockSize]; n = 0; } public CharVector(char[] a) { blockSize = DEFAULT_BLOCK_SIZE; array = a; n = a.length; } public CharVector(char[] a, int capacity) { if (capacity > 0) { blockSize = capacity; } else { blockSize = DEFAULT_BLOCK_SIZE; } array = a; n = a.length; } /** * Reset Vector but don't resize or clear elements */ public void clear() { n = 0; } public Object clone() { CharVector cv = new CharVector((char[])array.clone(), blockSize); cv.n = this.n; return cv; } public char[] getArray() { return array; } /** * return number of items in array */ public int length() { return n; } /** * returns current capacity of array */ public int capacity() { return array.length; } public void put(int index, char val) { array[index] = val; } public char get(int index) { return array[index]; } public int alloc(int size) { int index = n; int len = array.length; if (n + size >= len) { char[] aux = new char[len + blockSize]; System.arraycopy(array, 0, aux, 0, len); array = aux; } n += size; return index; } public void trimToSize() { if (n < array.length) { char[] aux = new char[n]; System.arraycopy(array, 0, aux, 0, n); array = aux; } } } src/core/com/lowagie/text/pdf/hyphenation/Hyphen.java100644 0 0 4253 11000354034 20304 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.io.Serializable; /** * This class represents a hyphen. A 'full' hyphen is made of 3 parts: * the pre-break text, post-break text and no-break. If no line-break * is generated at this position, the no-break text is used, otherwise, * pre-break and post-break are used. Typically, pre-break is equal to * the hyphen character and the others are empty. However, this general * scheme allows support for cases in some languages where words change * spelling if they're split across lines, like german's 'backen' which * hyphenates 'bak-ken'. BTW, this comes from TeX. * * @author Carlos Villegas */ public class Hyphen implements Serializable { private static final long serialVersionUID = -7666138517324763063L; public String preBreak; public String noBreak; public String postBreak; Hyphen(String pre, String no, String post) { preBreak = pre; noBreak = no; postBreak = post; } Hyphen(String pre) { preBreak = pre; noBreak = null; postBreak = null; } public String toString() { if (noBreak == null && postBreak == null && preBreak != null && preBreak.equals("-")) { return "-"; } StringBuffer res = new StringBuffer("{"); res.append(preBreak); res.append("}{"); res.append(postBreak); res.append("}{"); res.append(noBreak); res.append('}'); return res.toString(); } } src/core/com/lowagie/text/pdf/hyphenation/Hyphenation.java100644 0 0 4145 11000354034 21337 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; /** * This class represents a hyphenated word. * * @author Carlos Villegas */ public class Hyphenation { private int[] hyphenPoints; private String word; /** * number of hyphenation points in word */ private int len; /** * rawWord as made of alternating strings and {@link Hyphen Hyphen} * instances */ Hyphenation(String word, int[] points) { this.word = word; hyphenPoints = points; len = points.length; } /** * @return the number of hyphenation points in the word */ public int length() { return len; } /** * @return the pre-break text, not including the hyphen character */ public String getPreHyphenText(int index) { return word.substring(0, hyphenPoints[index]); } /** * @return the post-break text */ public String getPostHyphenText(int index) { return word.substring(hyphenPoints[index]); } /** * @return the hyphenation points */ public int[] getHyphenationPoints() { return hyphenPoints; } public String toString() { StringBuffer str = new StringBuffer(); int start = 0; for (int i = 0; i < len; i++) { str.append(word.substring(start, hyphenPoints[i])).append('-'); start = hyphenPoints[i]; } str.append(word.substring(start)); return str.toString(); } } src/core/com/lowagie/text/pdf/hyphenation/HyphenationException.java100644 0 0 1633 11000354034 23215 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; /** * @author Carlos Villegas */ public class HyphenationException extends Exception { private static final long serialVersionUID = 4721513606846982325L; public HyphenationException(String msg) { super(msg); } } src/core/com/lowagie/text/pdf/hyphenation/HyphenationTree.java100644 0 0 37104 11000354034 22200 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* $Id: HyphenationTree.java 3117 2008-01-31 05:53:22Z xlv $ */ package com.lowagie.text.pdf.hyphenation; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; /** * This tree structure stores the hyphenation patterns in an efficient * way for fast lookup. It provides the provides the method to * hyphenate a word. * * @author Carlos Villegas */ public class HyphenationTree extends TernaryTree implements PatternConsumer { private static final long serialVersionUID = -7763254239309429432L; /** * value space: stores the interletter values */ protected ByteVector vspace; /** * This map stores hyphenation exceptions */ protected HashMap stoplist; /** * This map stores the character classes */ protected TernaryTree classmap; /** * Temporary map to store interletter values on pattern loading. */ private transient TernaryTree ivalues; public HyphenationTree() { stoplist = new HashMap(23); // usually a small table classmap = new TernaryTree(); vspace = new ByteVector(); vspace.alloc(1); // this reserves index 0, which we don't use } /** * Packs the values by storing them in 4 bits, two values into a byte * Values range is from 0 to 9. We use zero as terminator, * so we'll add 1 to the value. * @param values a string of digits from '0' to '9' representing the * interletter values. * @return the index into the vspace array where the packed values * are stored. */ protected int packValues(String values) { int i, n = values.length(); int m = (n & 1) == 1 ? (n >> 1) + 2 : (n >> 1) + 1; int offset = vspace.alloc(m); byte[] va = vspace.getArray(); for (i = 0; i < n; i++) { int j = i >> 1; byte v = (byte)((values.charAt(i) - '0' + 1) & 0x0f); if ((i & 1) == 1) { va[j + offset] = (byte)(va[j + offset] | v); } else { va[j + offset] = (byte)(v << 4); // big endian } } va[m - 1 + offset] = 0; // terminator return offset; } protected String unpackValues(int k) { StringBuffer buf = new StringBuffer(); byte v = vspace.get(k++); while (v != 0) { char c = (char)((v >>> 4) - 1 + '0'); buf.append(c); c = (char)(v & 0x0f); if (c == 0) { break; } c = (char)(c - 1 + '0'); buf.append(c); v = vspace.get(k++); } return buf.toString(); } public void loadSimplePatterns(InputStream stream) { SimplePatternParser pp = new SimplePatternParser(); ivalues = new TernaryTree(); pp.parse(stream, this); // patterns/values should be now in the tree // let's optimize a bit trimToSize(); vspace.trimToSize(); classmap.trimToSize(); // get rid of the auxiliary map ivalues = null; } public String findPattern(String pat) { int k = super.find(pat); if (k >= 0) { return unpackValues(k); } return ""; } /** * String compare, returns 0 if equal or * t is a substring of s */ protected int hstrcmp(char[] s, int si, char[] t, int ti) { for (; s[si] == t[ti]; si++, ti++) { if (s[si] == 0) { return 0; } } if (t[ti] == 0) { return 0; } return s[si] - t[ti]; } protected byte[] getValues(int k) { StringBuffer buf = new StringBuffer(); byte v = vspace.get(k++); while (v != 0) { char c = (char)((v >>> 4) - 1); buf.append(c); c = (char)(v & 0x0f); if (c == 0) { break; } c = (char)(c - 1); buf.append(c); v = vspace.get(k++); } byte[] res = new byte[buf.length()]; for (int i = 0; i < res.length; i++) { res[i] = (byte)buf.charAt(i); } return res; } /** *

    Search for all possible partial matches of word starting * at index an update interletter values. In other words, it * does something like:

    * * for(i=0; i *

    But it is done in an efficient way since the patterns are * stored in a ternary tree. In fact, this is the whole purpose * of having the tree: doing this search without having to test * every single pattern. The number of patterns for languages * such as English range from 4000 to 10000. Thus, doing thousands * of string comparisons for each word to hyphenate would be * really slow without the tree. The tradeoff is memory, but * using a ternary tree instead of a trie, almost halves the * the memory used by Lout or TeX. It's also faster than using * a hash table

    * @param word null terminated word to match * @param index start index from word * @param il interletter values array to update */ protected void searchPatterns(char[] word, int index, byte[] il) { byte[] values; int i = index; char p, q; char sp = word[i]; p = root; while (p > 0 && p < sc.length) { if (sc[p] == 0xFFFF) { if (hstrcmp(word, i, kv.getArray(), lo[p]) == 0) { values = getValues(eq[p]); // data pointer is in eq[] int j = index; for (int k = 0; k < values.length; k++) { if (j < il.length && values[k] > il[j]) { il[j] = values[k]; } j++; } } return; } int d = sp - sc[p]; if (d == 0) { if (sp == 0) { break; } sp = word[++i]; p = eq[p]; q = p; // look for a pattern ending at this position by searching for // the null char ( splitchar == 0 ) while (q > 0 && q < sc.length) { if (sc[q] == 0xFFFF) { // stop at compressed branch break; } if (sc[q] == 0) { values = getValues(eq[q]); int j = index; for (int k = 0; k < values.length; k++) { if (j < il.length && values[k] > il[j]) { il[j] = values[k]; } j++; } break; } else { q = lo[q]; /** * actually the code should be: * q = sc[q] < 0 ? hi[q] : lo[q]; * but java chars are unsigned */ } } } else { p = d < 0 ? lo[p] : hi[p]; } } } /** * Hyphenate word and return a Hyphenation object. * @param word the word to be hyphenated * @param remainCharCount Minimum number of characters allowed * before the hyphenation point. * @param pushCharCount Minimum number of characters allowed after * the hyphenation point. * @return a {@link Hyphenation Hyphenation} object representing * the hyphenated word or null if word is not hyphenated. */ public Hyphenation hyphenate(String word, int remainCharCount, int pushCharCount) { char[] w = word.toCharArray(); return hyphenate(w, 0, w.length, remainCharCount, pushCharCount); } /** * w = "****nnllllllnnn*****", * where n is a non-letter, l is a letter, * all n may be absent, the first n is at offset, * the first l is at offset + iIgnoreAtBeginning; * word = ".llllll.'\0'***", * where all l in w are copied into word. * In the first part of the routine len = w.length, * in the second part of the routine len = word.length. * Three indices are used: * index(w), the index in w, * index(word), the index in word, * letterindex(word), the index in the letter part of word. * The following relations exist: * index(w) = offset + i - 1 * index(word) = i - iIgnoreAtBeginning * letterindex(word) = index(word) - 1 * (see first loop). * It follows that: * index(w) - index(word) = offset - 1 + iIgnoreAtBeginning * index(w) = letterindex(word) + offset + iIgnoreAtBeginning */ /** * Hyphenate word and return an array of hyphenation points. * @param w char array that contains the word * @param offset Offset to first character in word * @param len Length of word * @param remainCharCount Minimum number of characters allowed * before the hyphenation point. * @param pushCharCount Minimum number of characters allowed after * the hyphenation point. * @return a {@link Hyphenation Hyphenation} object representing * the hyphenated word or null if word is not hyphenated. */ public Hyphenation hyphenate(char[] w, int offset, int len, int remainCharCount, int pushCharCount) { int i; char[] word = new char[len + 3]; // normalize word char[] c = new char[2]; int iIgnoreAtBeginning = 0; int iLength = len; boolean bEndOfLetters = false; for (i = 1; i <= len; i++) { c[0] = w[offset + i - 1]; int nc = classmap.find(c, 0); if (nc < 0) { // found a non-letter character ... if (i == (1 + iIgnoreAtBeginning)) { // ... before any letter character iIgnoreAtBeginning ++; } else { // ... after a letter character bEndOfLetters = true; } iLength --; } else { if (!bEndOfLetters) { word[i - iIgnoreAtBeginning] = (char)nc; } else { return null; } } } len = iLength; if (len < (remainCharCount + pushCharCount)) { // word is too short to be hyphenated return null; } int[] result = new int[len + 1]; int k = 0; // check exception list first String sw = new String(word, 1, len); if (stoplist.containsKey(sw)) { // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no = null) ArrayList hw = (ArrayList)stoplist.get(sw); int j = 0; for (i = 0; i < hw.size(); i++) { Object o = hw.get(i); // j = index(sw) = letterindex(word)? // result[k] = corresponding index(w) if (o instanceof String) { j += ((String)o).length(); if (j >= remainCharCount && j < (len - pushCharCount)) { result[k++] = j + iIgnoreAtBeginning; } } } } else { // use algorithm to get hyphenation points word[0] = '.'; // word start marker word[len + 1] = '.'; // word end marker word[len + 2] = 0; // null terminated byte[] il = new byte[len + 3]; // initialized to zero for (i = 0; i < len + 1; i++) { searchPatterns(word, i, il); } // hyphenation points are located where interletter value is odd // i is letterindex(word), // i + 1 is index(word), // result[k] = corresponding index(w) for (i = 0; i < len; i++) { if (((il[i + 1] & 1) == 1) && i >= remainCharCount && i <= (len - pushCharCount)) { result[k++] = i + iIgnoreAtBeginning; } } } if (k > 0) { // trim result array int[] res = new int[k]; System.arraycopy(result, 0, res, 0, k); return new Hyphenation(new String(w, offset, len), res); } else { return null; } } /** * Add a character class to the tree. It is used by * {@link SimplePatternParser SimplePatternParser} as callback to * add character classes. Character classes define the * valid word characters for hyphenation. If a word contains * a character not defined in any of the classes, it is not hyphenated. * It also defines a way to normalize the characters in order * to compare them with the stored patterns. Usually pattern * files use only lower case characters, in this case a class * for letter 'a', for example, should be defined as "aA", the first * character being the normalization char. */ public void addClass(String chargroup) { if (chargroup.length() > 0) { char equivChar = chargroup.charAt(0); char[] key = new char[2]; key[1] = 0; for (int i = 0; i < chargroup.length(); i++) { key[0] = chargroup.charAt(i); classmap.insert(key, 0, equivChar); } } } /** * Add an exception to the tree. It is used by * {@link SimplePatternParser SimplePatternParser} class as callback to * store the hyphenation exceptions. * @param word normalized word * @param hyphenatedword a vector of alternating strings and * {@link Hyphen hyphen} objects. */ public void addException(String word, ArrayList hyphenatedword) { stoplist.put(word, hyphenatedword); } /** * Add a pattern to the tree. Mainly, to be used by * {@link SimplePatternParser SimplePatternParser} class as callback to * add a pattern to the tree. * @param pattern the hyphenation pattern * @param ivalue interletter weight values indicating the * desirability and priority of hyphenating at a given point * within the pattern. It should contain only digit characters. * (i.e. '0' to '9'). */ public void addPattern(String pattern, String ivalue) { int k = ivalues.find(ivalue); if (k <= 0) { k = packValues(ivalue); ivalues.insert(ivalue, (char)k); } insert(pattern, (char)k); } public void printStats() { System.out.println("Value space size = " + Integer.toString(vspace.length())); super.printStats(); } } src/core/com/lowagie/text/pdf/hyphenation/Hyphenator.java100644 0 0 16022 11000354034 21207 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.Hashtable; import com.lowagie.text.pdf.BaseFont; /** * This class is the main entry point to the hyphenation package. * You can use only the static methods or create an instance. * * @author Carlos Villegas */ public class Hyphenator { /** TODO: Don't use statics */ private static Hashtable hyphenTrees = new Hashtable(); private HyphenationTree hyphenTree = null; private int remainCharCount = 2; private int pushCharCount = 2; private static final String defaultHyphLocation = "com/lowagie/text/pdf/hyphenation/hyph/"; /** Holds value of property hyphenDir. */ private static String hyphenDir = ""; /** * @param lang * @param country * @param leftMin * @param rightMin */ public Hyphenator(String lang, String country, int leftMin, int rightMin) { hyphenTree = getHyphenationTree(lang, country); remainCharCount = leftMin; pushCharCount = rightMin; } /** * @param lang * @param country * @return the hyphenation tree */ public static HyphenationTree getHyphenationTree(String lang, String country) { String key = lang; // check whether the country code has been used if (country != null && !country.equals("none")) { key += "_" + country; } // first try to find it in the cache if (hyphenTrees.containsKey(key)) { return (HyphenationTree)hyphenTrees.get(key); } if (hyphenTrees.containsKey(lang)) { return (HyphenationTree)hyphenTrees.get(lang); } HyphenationTree hTree = getResourceHyphenationTree(key); if (hTree == null) hTree = getFileHyphenationTree(key); // put it into the pattern cache if (hTree != null) { hyphenTrees.put(key, hTree); } return hTree; } /** * @param key * @return a hyphenation tree */ public static HyphenationTree getResourceHyphenationTree(String key) { try { InputStream stream = BaseFont.getResourceStream(defaultHyphLocation + key + ".xml"); if (stream == null && key.length() > 2) stream = BaseFont.getResourceStream(defaultHyphLocation + key.substring(0, 2) + ".xml"); if (stream == null) return null; HyphenationTree hTree = new HyphenationTree(); hTree.loadSimplePatterns(stream); return hTree; } catch (Exception e) { return null; } } /** * @param key * @return a hyphenation tree */ public static HyphenationTree getFileHyphenationTree(String key) { try { if (hyphenDir == null) return null; InputStream stream = null; File hyphenFile = new File(hyphenDir, key + ".xml"); if (hyphenFile.canRead()) stream = new FileInputStream(hyphenFile); if (stream == null && key.length() > 2) { hyphenFile = new File(hyphenDir, key.substring(0, 2) + ".xml"); if (hyphenFile.canRead()) stream = new FileInputStream(hyphenFile); } if (stream == null) return null; HyphenationTree hTree = new HyphenationTree(); hTree.loadSimplePatterns(stream); return hTree; } catch (Exception e) { return null; } } /** * @param lang * @param country * @param word * @param leftMin * @param rightMin * @return a hyphenation object */ public static Hyphenation hyphenate(String lang, String country, String word, int leftMin, int rightMin) { HyphenationTree hTree = getHyphenationTree(lang, country); if (hTree == null) { //log.error("Error building hyphenation tree for language " // + lang); return null; } return hTree.hyphenate(word, leftMin, rightMin); } /** * @param lang * @param country * @param word * @param offset * @param len * @param leftMin * @param rightMin * @return a hyphenation object */ public static Hyphenation hyphenate(String lang, String country, char[] word, int offset, int len, int leftMin, int rightMin) { HyphenationTree hTree = getHyphenationTree(lang, country); if (hTree == null) { //log.error("Error building hyphenation tree for language " // + lang); return null; } return hTree.hyphenate(word, offset, len, leftMin, rightMin); } /** * @param min */ public void setMinRemainCharCount(int min) { remainCharCount = min; } /** * @param min */ public void setMinPushCharCount(int min) { pushCharCount = min; } /** * @param lang * @param country */ public void setLanguage(String lang, String country) { hyphenTree = getHyphenationTree(lang, country); } /** * @param word * @param offset * @param len * @return a hyphenation object */ public Hyphenation hyphenate(char[] word, int offset, int len) { if (hyphenTree == null) { return null; } return hyphenTree.hyphenate(word, offset, len, remainCharCount, pushCharCount); } /** * @param word * @return a hyphenation object */ public Hyphenation hyphenate(String word) { if (hyphenTree == null) { return null; } return hyphenTree.hyphenate(word, remainCharCount, pushCharCount); } /** Getter for property hyphenDir. * @return Value of property hyphenDir. */ public static String getHyphenDir() { return hyphenDir; } /** Setter for property hyphenDir. * @param _hyphenDir New value of property hyphenDir. */ public static void setHyphenDir(String _hyphenDir) { hyphenDir = _hyphenDir; } } src/core/com/lowagie/text/pdf/hyphenation/PatternConsumer.java100644 0 0 3357 11000354034 22206 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.util.ArrayList; /** * This interface is used to connect the XML pattern file parser to * the hyphenation tree. * * @author Carlos Villegas */ public interface PatternConsumer { /** * Add a character class. * A character class defines characters that are considered * equivalent for the purpose of hyphenation (e.g. "aA"). It * usually means to ignore case. * @param chargroup character group */ void addClass(String chargroup); /** * Add a hyphenation exception. An exception replaces the * result obtained by the algorithm for cases for which this * fails or the user wants to provide his own hyphenation. * A hyphenatedword is a vector of alternating String's and * {@link Hyphen Hyphen} instances */ void addException(String word, ArrayList hyphenatedword); /** * Add hyphenation patterns. * @param pattern the pattern * @param values interletter values expressed as a string of * digit characters. */ void addPattern(String pattern, String values); } src/core/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java100644 0 0 20271 11036112744 23044 0ustar 0 0 /* * Copyright 2005 by Paulo Soares. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * Contributions by: * Lubos Strapko * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.hyphenation; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.StringTokenizer; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.html.HtmlTags; import com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler; import com.lowagie.text.xml.simpleparser.SimpleXMLParser; /** Parses the xml hyphenation pattern. * * @author Paulo Soares (psoares@consiste.pt) */ public class SimplePatternParser implements SimpleXMLDocHandler, PatternConsumer { int currElement; PatternConsumer consumer; StringBuffer token; ArrayList exception; char hyphenChar; SimpleXMLParser parser; static final int ELEM_CLASSES = 1; static final int ELEM_EXCEPTIONS = 2; static final int ELEM_PATTERNS = 3; static final int ELEM_HYPHEN = 4; /** Creates a new instance of PatternParser2 */ public SimplePatternParser() { token = new StringBuffer(); hyphenChar = '-'; // default } public void parse(InputStream stream, PatternConsumer consumer) { this.consumer = consumer; try { SimpleXMLParser.parse(this, stream); } catch (IOException e) { throw new ExceptionConverter(e); } finally { try { stream.close(); } catch (Exception e) { } } } protected static String getPattern(String word) { StringBuffer pat = new StringBuffer(); int len = word.length(); for (int i = 0; i < len; i++) { if (!Character.isDigit(word.charAt(i))) { pat.append(word.charAt(i)); } } return pat.toString(); } protected ArrayList normalizeException(ArrayList ex) { ArrayList res = new ArrayList(); for (int i = 0; i < ex.size(); i++) { Object item = ex.get(i); if (item instanceof String) { String str = (String) item; StringBuffer buf = new StringBuffer(); for (int j = 0; j < str.length(); j++) { char c = str.charAt(j); if (c != hyphenChar) { buf.append(c); } else { res.add(buf.toString()); buf.setLength(0); char[] h = new char[1]; h[0] = hyphenChar; // we use here hyphenChar which is not necessarily // the one to be printed res.add(new Hyphen(new String(h), null, null)); } } if (buf.length() > 0) { res.add(buf.toString()); } } else { res.add(item); } } return res; } protected String getExceptionWord(ArrayList ex) { StringBuffer res = new StringBuffer(); for (int i = 0; i < ex.size(); i++) { Object item = ex.get(i); if (item instanceof String) { res.append((String) item); } else { if (((Hyphen) item).noBreak != null) { res.append(((Hyphen) item).noBreak); } } } return res.toString(); } protected static String getInterletterValues(String pat) { StringBuffer il = new StringBuffer(); String word = pat + "a"; // add dummy letter to serve as sentinel int len = word.length(); for (int i = 0; i < len; i++) { char c = word.charAt(i); if (Character.isDigit(c)) { il.append(c); i++; } else { il.append('0'); } } return il.toString(); } public void endDocument() { } public void endElement(String tag) { if (token.length() > 0) { String word = token.toString(); switch (currElement) { case ELEM_CLASSES: consumer.addClass(word); break; case ELEM_EXCEPTIONS: exception.add(word); exception = normalizeException(exception); consumer.addException(getExceptionWord(exception), (ArrayList) exception.clone()); break; case ELEM_PATTERNS: consumer.addPattern(getPattern(word), getInterletterValues(word)); break; case ELEM_HYPHEN: // nothing to do break; } if (currElement != ELEM_HYPHEN) { token.setLength(0); } } if (currElement == ELEM_HYPHEN) { currElement = ELEM_EXCEPTIONS; } else { currElement = 0; } } public void startDocument() { } public void startElement(String tag, java.util.HashMap h) { if (tag.equals("hyphen-char")) { String hh = (String) h.get("value"); if (hh != null && hh.length() == 1) { hyphenChar = hh.charAt(0); } } else if (tag.equals("classes")) { currElement = ELEM_CLASSES; } else if (tag.equals("patterns")) { currElement = ELEM_PATTERNS; } else if (tag.equals("exceptions")) { currElement = ELEM_EXCEPTIONS; exception = new ArrayList(); } else if (tag.equals("hyphen")) { if (token.length() > 0) { exception.add(token.toString()); } exception.add(new Hyphen((String) h.get(HtmlTags.PRE), (String) h .get("no"), (String) h.get("post"))); currElement = ELEM_HYPHEN; } token.setLength(0); } public void text(String str) { StringTokenizer tk = new StringTokenizer(str); while (tk.hasMoreTokens()) { String word = tk.nextToken(); // System.out.println("\"" + word + "\""); switch (currElement) { case ELEM_CLASSES: consumer.addClass(word); break; case ELEM_EXCEPTIONS: exception.add(word); exception = normalizeException(exception); consumer.addException(getExceptionWord(exception), (ArrayList) exception.clone()); exception.clear(); break; case ELEM_PATTERNS: consumer.addPattern(getPattern(word), getInterletterValues(word)); break; } } } // PatternConsumer implementation for testing purposes public void addClass(String c) { System.out.println("class: " + c); } public void addException(String w, ArrayList e) { System.out.println("exception: " + w + " : " + e.toString()); } public void addPattern(String p, String v) { System.out.println("pattern: " + p + " : " + v); } public static void main(String[] args) throws Exception { try { if (args.length > 0) { SimplePatternParser pp = new SimplePatternParser(); pp.parse(new FileInputStream(args[0]), pp); } } catch (Exception e) { e.printStackTrace(); } } } src/core/com/lowagie/text/pdf/hyphenation/TernaryTree.java100644 0 0 47355 11036112744 21360 0ustar 0 0 /* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.pdf.hyphenation; import java.io.Serializable; import java.util.Enumeration; import java.util.Stack; /** *

    Ternary Search Tree.

    * *

    A ternary search tree is a hybrid between a binary tree and * a digital search tree (trie). Keys are limited to strings. * A data value of type char is stored in each leaf node. * It can be used as an index (or pointer) to the data. * Branches that only contain one key are compressed to one node * by storing a pointer to the trailer substring of the key. * This class is intended to serve as base class or helper class * to implement Dictionary collections or the like. Ternary trees * have some nice properties as the following: the tree can be * traversed in sorted order, partial matches (wildcard) can be * implemented, retrieval of all keys within a given distance * from the target, etc. The storage requirements are higher than * a binary tree but a lot less than a trie. Performance is * comparable with a hash table, sometimes it outperforms a hash * function (most of the time can determine a miss faster than a hash).

    * *

    The main purpose of this java port is to serve as a base for * implementing TeX's hyphenation algorithm (see The TeXBook, * appendix H). Each language requires from 5000 to 15000 hyphenation * patterns which will be keys in this tree. The strings patterns * are usually small (from 2 to 5 characters), but each char in the * tree is stored in a node. Thus memory usage is the main concern. * We will sacrifice 'elegance' to keep memory requirements to the * minimum. Using java's char type as pointer (yes, I know pointer * it is a forbidden word in java) we can keep the size of the node * to be just 8 bytes (3 pointers and the data char). This gives * room for about 65000 nodes. In my tests the English patterns * took 7694 nodes and the German patterns 10055 nodes, * so I think we are safe.

    * *

    All said, this is a map with strings as keys and char as value. * Pretty limited!. It can be extended to a general map by * using the string representation of an object and using the * char value as an index to an array that contains the object * values.

    * * @author cav@uniscope.co.jp */ public class TernaryTree implements Cloneable, Serializable { /** * We use 4 arrays to represent a node. I guess I should have created * a proper node class, but somehow Knuth's pascal code made me forget * we now have a portable language with virtual memory management and * automatic garbage collection! And now is kind of late, furthermore, * if it ain't broken, don't fix it. */ private static final long serialVersionUID = 5313366505322983510L; /** * Pointer to low branch and to rest of the key when it is * stored directly in this node, we don't have unions in java! */ protected char[] lo; /** * Pointer to high branch. */ protected char[] hi; /** * Pointer to equal branch and to data when this node is a string terminator. */ protected char[] eq; /** *

    The character stored in this node: splitchar. * Two special values are reserved:

    *
    • 0x0000 as string terminator
    • *
    • 0xFFFF to indicate that the branch starting at * this node is compressed
    *

    This shouldn't be a problem if we give the usual semantics to * strings since 0xFFFF is guaranteed not to be an Unicode character.

    */ protected char[] sc; /** * This vector holds the trailing of the keys when the branch is compressed. */ protected CharVector kv; protected char root; protected char freenode; protected int length; // number of items in tree protected static final int BLOCK_SIZE = 2048; // allocation size for arrays TernaryTree() { init(); } protected void init() { root = 0; freenode = 1; length = 0; lo = new char[BLOCK_SIZE]; hi = new char[BLOCK_SIZE]; eq = new char[BLOCK_SIZE]; sc = new char[BLOCK_SIZE]; kv = new CharVector(); } /** * Branches are initially compressed, needing * one node per key plus the size of the string * key. They are decompressed as needed when * another key with same prefix * is inserted. This saves a lot of space, * specially for long keys. */ public void insert(String key, char val) { // make sure we have enough room in the arrays int len = key.length() + 1; // maximum number of nodes that may be generated if (freenode + len > eq.length) { redimNodeArrays(eq.length + BLOCK_SIZE); } char strkey[] = new char[len--]; key.getChars(0, len, strkey, 0); strkey[len] = 0; root = insert(root, strkey, 0, val); } public void insert(char[] key, int start, char val) { int len = strlen(key) + 1; if (freenode + len > eq.length) { redimNodeArrays(eq.length + BLOCK_SIZE); } root = insert(root, key, start, val); } /** * The actual insertion function, recursive version. */ private char insert(char p, char[] key, int start, char val) { int len = strlen(key, start); if (p == 0) { // this means there is no branch, this node will start a new branch. // Instead of doing that, we store the key somewhere else and create // only one node with a pointer to the key p = freenode++; eq[p] = val; // holds data length++; hi[p] = 0; if (len > 0) { sc[p] = 0xFFFF; // indicates branch is compressed lo[p] = (char)kv.alloc(len + 1); // use 'lo' to hold pointer to key strcpy(kv.getArray(), lo[p], key, start); } else { sc[p] = 0; lo[p] = 0; } return p; } if (sc[p] == 0xFFFF) { // branch is compressed: need to decompress // this will generate garbage in the external key array // but we can do some garbage collection later char pp = freenode++; lo[pp] = lo[p]; // previous pointer to key eq[pp] = eq[p]; // previous pointer to data lo[p] = 0; if (len > 0) { sc[p] = kv.get(lo[pp]); eq[p] = pp; lo[pp]++; if (kv.get(lo[pp]) == 0) { // key completely decompressed leaving garbage in key array lo[pp] = 0; sc[pp] = 0; hi[pp] = 0; } else { // we only got first char of key, rest is still there sc[pp] = 0xFFFF; } } else { // In this case we can save a node by swapping the new node // with the compressed node sc[pp] = 0xFFFF; hi[p] = pp; sc[p] = 0; eq[p] = val; length++; return p; } } char s = key[start]; if (s < sc[p]) { lo[p] = insert(lo[p], key, start, val); } else if (s == sc[p]) { if (s != 0) { eq[p] = insert(eq[p], key, start + 1, val); } else { // key already in tree, overwrite data eq[p] = val; } } else { hi[p] = insert(hi[p], key, start, val); } return p; } /** * Compares 2 null terminated char arrays */ public static int strcmp(char[] a, int startA, char[] b, int startB) { for (; a[startA] == b[startB]; startA++, startB++) { if (a[startA] == 0) { return 0; } } return a[startA] - b[startB]; } /** * Compares a string with null terminated char array */ public static int strcmp(String str, char[] a, int start) { int i, d, len = str.length(); for (i = 0; i < len; i++) { d = str.charAt(i) - a[start + i]; if (d != 0) { return d; } if (a[start + i] == 0) { return d; } } if (a[start + i] != 0) { return -a[start + i]; } return 0; } public static void strcpy(char[] dst, int di, char[] src, int si) { while (src[si] != 0) { dst[di++] = src[si++]; } dst[di] = 0; } public static int strlen(char[] a, int start) { int len = 0; for (int i = start; i < a.length && a[i] != 0; i++) { len++; } return len; } public static int strlen(char[] a) { return strlen(a, 0); } public int find(String key) { int len = key.length(); char strkey[] = new char[len + 1]; key.getChars(0, len, strkey, 0); strkey[len] = 0; return find(strkey, 0); } public int find(char[] key, int start) { int d; char p = root; int i = start; char c; while (p != 0) { if (sc[p] == 0xFFFF) { if (strcmp(key, i, kv.getArray(), lo[p]) == 0) { return eq[p]; } else { return -1; } } c = key[i]; d = c - sc[p]; if (d == 0) { if (c == 0) { return eq[p]; } i++; p = eq[p]; } else if (d < 0) { p = lo[p]; } else { p = hi[p]; } } return -1; } public boolean knows(String key) { return (find(key) >= 0); } // redimension the arrays private void redimNodeArrays(int newsize) { int len = newsize < lo.length ? newsize : lo.length; char[] na = new char[newsize]; System.arraycopy(lo, 0, na, 0, len); lo = na; na = new char[newsize]; System.arraycopy(hi, 0, na, 0, len); hi = na; na = new char[newsize]; System.arraycopy(eq, 0, na, 0, len); eq = na; na = new char[newsize]; System.arraycopy(sc, 0, na, 0, len); sc = na; } public int size() { return length; } public Object clone() { TernaryTree t = new TernaryTree(); t.lo = (char[])this.lo.clone(); t.hi = (char[])this.hi.clone(); t.eq = (char[])this.eq.clone(); t.sc = (char[])this.sc.clone(); t.kv = (CharVector)this.kv.clone(); t.root = this.root; t.freenode = this.freenode; t.length = this.length; return t; } /** * Recursively insert the median first and then the median of the * lower and upper halves, and so on in order to get a balanced * tree. The array of keys is assumed to be sorted in ascending * order. */ protected void insertBalanced(String[] k, char[] v, int offset, int n) { int m; if (n < 1) { return; } m = n >> 1; insert(k[m + offset], v[m + offset]); insertBalanced(k, v, offset, m); insertBalanced(k, v, offset + m + 1, n - m - 1); } /** * Balance the tree for best search performance */ public void balance() { // System.out.print("Before root splitchar = "); System.out.println(sc[root]); int i = 0, n = length; String[] k = new String[n]; char[] v = new char[n]; Iterator iter = new Iterator(); while (iter.hasMoreElements()) { v[i] = iter.getValue(); k[i++] = (String)iter.nextElement(); } init(); insertBalanced(k, v, 0, n); // With uniform letter distribution sc[root] should be around 'm' // System.out.print("After root splitchar = "); System.out.println(sc[root]); } /** * Each node stores a character (splitchar) which is part of * some key(s). In a compressed branch (one that only contain * a single string key) the trailer of the key which is not * already in nodes is stored externally in the kv array. * As items are inserted, key substrings decrease. * Some substrings may completely disappear when the whole * branch is totally decompressed. * The tree is traversed to find the key substrings actually * used. In addition, duplicate substrings are removed using * a map (implemented with a TernaryTree!). * */ public void trimToSize() { // first balance the tree for best performance balance(); // redimension the node arrays redimNodeArrays(freenode); // ok, compact kv array CharVector kx = new CharVector(); kx.alloc(1); TernaryTree map = new TernaryTree(); compact(kx, map, root); kv = kx; kv.trimToSize(); } private void compact(CharVector kx, TernaryTree map, char p) { int k; if (p == 0) { return; } if (sc[p] == 0xFFFF) { k = map.find(kv.getArray(), lo[p]); if (k < 0) { k = kx.alloc(strlen(kv.getArray(), lo[p]) + 1); strcpy(kx.getArray(), k, kv.getArray(), lo[p]); map.insert(kx.getArray(), k, (char)k); } lo[p] = (char)k; } else { compact(kx, map, lo[p]); if (sc[p] != 0) { compact(kx, map, eq[p]); } compact(kx, map, hi[p]); } } public Enumeration keys() { return new Iterator(); } public class Iterator implements Enumeration { /** * current node index */ int cur; /** * current key */ String curkey; private class Item implements Cloneable { char parent; char child; public Item() { parent = 0; child = 0; } public Item(char p, char c) { parent = p; child = c; } public Object clone() { return new Item(parent, child); } } /** * Node stack */ Stack ns; /** * key stack implemented with a StringBuffer */ StringBuffer ks; public Iterator() { cur = -1; ns = new Stack(); ks = new StringBuffer(); rewind(); } public void rewind() { ns.removeAllElements(); ks.setLength(0); cur = root; run(); } public Object nextElement() { String res = curkey; cur = up(); run(); return res; } public char getValue() { if (cur >= 0) { return eq[cur]; } return 0; } public boolean hasMoreElements() { return (cur != -1); } /** * traverse upwards */ private int up() { Item i = new Item(); int res = 0; if (ns.empty()) { return -1; } if (cur != 0 && sc[cur] == 0) { return lo[cur]; } boolean climb = true; while (climb) { i = (Item)ns.pop(); i.child++; switch (i.child) { case 1: if (sc[i.parent] != 0) { res = eq[i.parent]; ns.push(i.clone()); ks.append(sc[i.parent]); } else { i.child++; ns.push(i.clone()); res = hi[i.parent]; } climb = false; break; case 2: res = hi[i.parent]; ns.push(i.clone()); if (ks.length() > 0) { ks.setLength(ks.length() - 1); // pop } climb = false; break; default: if (ns.empty()) { return -1; } climb = true; break; } } return res; } /** * traverse the tree to find next key */ private int run() { if (cur == -1) { return -1; } boolean leaf = false; while (true) { // first go down on low branch until leaf or compressed branch while (cur != 0) { if (sc[cur] == 0xFFFF) { leaf = true; break; } ns.push(new Item((char)cur, '\u0000')); if (sc[cur] == 0) { leaf = true; break; } cur = lo[cur]; } if (leaf) { break; } // nothing found, go up one node and try again cur = up(); if (cur == -1) { return -1; } } // The current node should be a data node and // the key should be in the key stack (at least partially) StringBuffer buf = new StringBuffer(ks.toString()); if (sc[cur] == 0xFFFF) { int p = lo[cur]; while (kv.get(p) != 0) { buf.append(kv.get(p++)); } } curkey = buf.toString(); return 0; } } public void printStats() { System.out.println("Number of keys = " + Integer.toString(length)); System.out.println("Node count = " + Integer.toString(freenode)); // System.out.println("Array length = " + Integer.toString(eq.length)); System.out.println("Key Array length = " + Integer.toString(kv.length())); /* * for(int i=0; iPdfAnnotation
    or a PdfFormField * to the document. Only the top parent of a PdfFormField * needs to be added. * @param annot the PdfAnnotation or the PdfFormField to add */ public void addAnnotation(PdfAnnotation annot); /** * Use this method to adds the PdfAnnotation * to the calculation order array. * @param annot the PdfAnnotation to be added */ public void addCalculationOrder(PdfFormField annot); /** * Use this method to set the signature flags. * @param f the flags. This flags are ORed with current ones */ public void setSigFlags(int f); } src/core/com/lowagie/text/pdf/interfaces/PdfDocumentActions.java100644 0 0 7333 11000354036 22403 0ustar 0 0 /* * $Id: PdfDocumentActions.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfAction; import com.lowagie.text.pdf.PdfName; /** * A PDF document can have an open action and other additional actions. */ public interface PdfDocumentActions { /** * When the document opens it will jump to the destination with * this name. * @param name the name of the destination to jump to */ public void setOpenAction(String name); /** * When the document opens this action will be * invoked. * @param action the action to be invoked */ public void setOpenAction(PdfAction action); /** * Additional-actions defining the actions to be taken in * response to various trigger events affecting the document * as a whole. The actions types allowed are: DOCUMENT_CLOSE, * WILL_SAVE, DID_SAVE, WILL_PRINT * and DID_PRINT. * * @param actionType the action type * @param action the action to execute in response to the trigger * @throws DocumentException on invalid action type */ public void setAdditionalAction(PdfName actionType, PdfAction action) throws DocumentException; }src/core/com/lowagie/text/pdf/interfaces/PdfEncryptionSettings.java100644 0 0 12123 11000354036 23170 0ustar 0 0 /* * $Id: PdfEncryptionSettings.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; import java.security.cert.Certificate; import com.lowagie.text.DocumentException; /** * Encryption settings are described in section 3.5 (more specifically * section 3.5.2) of the PDF Reference 1.7. * They are explained in section 3.3.3 of the book 'iText in Action'. * The values of the different preferences were originally stored * in class PdfWriter, but they have been moved to this separate interface * for reasons of convenience. */ public interface PdfEncryptionSettings { /** * Sets the encryption options for this document. The userPassword and the * ownerPassword can be null or have zero length. In this case the ownerPassword * is replaced by a random string. The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * @param userPassword the user password. Can be null or empty * @param ownerPassword the owner password. Can be null or empty * @param permissions the user permissions * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @throws DocumentException if the document is already open */ public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, int encryptionType) throws DocumentException; /** * Sets the certificate encryption options for this document. An array of one or more public certificates * must be provided together with an array of the same size for the permissions for each certificate. * The open permissions for the document can be * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. * The permissions can be combined by ORing them. * Optionally DO_NOT_ENCRYPT_METADATA can be ored to output the metadata in cleartext * @param certs the public certificates to be used for the encryption * @param permissions the user permissions for each of the certificates * @param encryptionType the type of encryption. It can be one of STANDARD_ENCRYPTION_40, STANDARD_ENCRYPTION_128 or ENCRYPTION_AES128. * @throws DocumentException if the document is already open */ public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException; }src/core/com/lowagie/text/pdf/interfaces/PdfPageActions.java100644 0 0 6762 11000354036 21506 0ustar 0 0 /* * $Id: PdfPageActions.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfAction; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfTransition; /** * A PDF page can have an open and/or close action. */ public interface PdfPageActions { /** * Sets the open and close page additional action. * @param actionType the action type. It can be PdfWriter.PAGE_OPEN * or PdfWriter.PAGE_CLOSE * @param action the action to perform * @throws DocumentException if the action type is invalid */ public void setPageAction(PdfName actionType, PdfAction action) throws DocumentException; /** * Sets the display duration for the page (for presentations) * @param seconds the number of seconds to display the page */ public void setDuration(int seconds); /** * Sets the transition for the page * @param transition the Transition object */ public void setTransition(PdfTransition transition); } src/core/com/lowagie/text/pdf/interfaces/PdfRunDirection.java100644 0 0 5544 11000354036 21713 0ustar 0 0 /* * $Id: PdfRunDirection.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; public interface PdfRunDirection { /** Sets the run direction. This is only used as a placeholder * as it does not affect anything. * @param runDirection the run direction */ public void setRunDirection(int runDirection); /** Gets the run direction. * @return the run direction */ public int getRunDirection(); } src/core/com/lowagie/text/pdf/interfaces/PdfVersion.java100644 0 0 10400 11213370070 20740 0ustar 0 0 /* * $Id: PdfVersion.java 3811 2009-03-23 18:15:13Z blowagie $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; import com.lowagie.text.pdf.PdfDeveloperExtension; import com.lowagie.text.pdf.PdfName; /** * The PDF version is described in the PDF Reference 1.7 p92 * (about the PDF Header) and page 139 (the version entry in * the Catalog). You'll also find info about setting the version * in the book 'iText in Action' sections 2.1.3 (PDF Header) * and 3.3 (Version history). */ public interface PdfVersion { /** * If the PDF Header hasn't been written yet, * this changes the version as it will appear in the PDF Header. * If the PDF header was already written to the OutputStream, * this changes the version as it will appear in the Catalog. * @param version a character representing the PDF version */ public void setPdfVersion(char version); /** * If the PDF Header hasn't been written yet, * this changes the version as it will appear in the PDF Header, * but only if the parameter refers to a higher version. * If the PDF header was already written to the OutputStream, * this changes the version as it will appear in the Catalog. * @param version a character representing the PDF version */ public void setAtLeastPdfVersion(char version); /** * Sets the PDF version as it will appear in the Catalog. * Note that this only has effect if you use a later version * than the one that appears in the header; this method * ignores the parameter if you try to set a lower version. * @param version the PDF name that will be used for the Version key in the catalog */ public void setPdfVersion(PdfName version); /** * Adds a developer extension to the Extensions dictionary * in the Catalog. * @param de an object that contains the extensions prefix and dictionary * @since 2.1.6 */ public void addDeveloperExtension(PdfDeveloperExtension de); }src/core/com/lowagie/text/pdf/interfaces/PdfViewerPreferences.java100644 0 0 22602 11012562267 22755 0ustar 0 0 /* * $Id: PdfViewerPreferences.java 3305 2008-05-01 18:18:28Z blowagie $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; /** * Viewer preferences are described in section 3.6.1 and 8.1 of the * PDF Reference 1.7 (Table 3.25 on p139-142 and Table 8.1 on p579-581). * They are explained in section 13.1 of the book 'iText in Action'. * The values of the different preferences were originally stored * in class PdfWriter, but they have been moved to this separate interface * for reasons of convenience. */ public interface PdfViewerPreferences { /** * Sets the page layout and page mode preferences by ORing one or two of these constants. *

    *

      *
    • The page layout to be used when the document is opened (choose one). *
        *
      • PAGE_LAYOUT_SINGLE_PAGE - Display one page at a time. (default) *
      • PAGE_LAYOUT_ONE_COLUMN - Display the pages in one column. *
      • PAGE_LAYOUT_TWO_COLUMN_LEFT - Display the pages in two columns, with * oddnumbered pages on the left. *
      • PAGE_LAYOUT_TWO_COLUMN_RIGHT - Display the pages in two columns, with * oddnumbered pages on the right. *
      • PAGE_LAYOUT_TWO_PAGE_LEFT - Display the pages two at a time, with * oddnumbered pages on the left. *
      • PAGE_LAYOUT_TWO_PAGE_RIGHT - Display the pages two at a time, with * oddnumbered pages on the right. *
      *
    • The page mode how the document should be displayed * when opened (choose one). *
        *
      • PAGE_MODE_USE_NONE - Neither document outline nor thumbnail images visible. (default) *
      • PAGE_MODE_USE_OUTLINES - Document outline visible. *
      • PAGE_MODE_USE_THUMBS - Thumbnail images visible. *
      • PAGE_MODE_FULL_SCREEN - Full-screen mode, with no menu bar, window * controls, or any other window visible. *
      • PAGE_MODE_USE_OC - Optional content group panel visible *
      • PAGE_MODE_USE_ATTACHMENTS - Attachments panel visible *
      *
    * For backward compatibility these values are also supported, * but it's better to use method addViewerPreference(key, value) * if you want to change the following preferences: *
      *
    • HIDE_TOOLBAR - A flag specifying whether to hide the viewer application's tool * bars when the document is active. *
    • HIDE_MENUBAR - A flag specifying whether to hide the viewer application's * menu bar when the document is active. *
    • HIDE_WINDOW_UI - A flag specifying whether to hide user interface elements in * the document's window (such as scroll bars and navigation controls), * leaving only the document's contents displayed. *
    • FIT_WINDOW - A flag specifying whether to resize the document's window to * fit the size of the first displayed page. *
    • CENTER_WINDOW - A flag specifying whether to position the document's window * in the center of the screen. *
    • DISPLAY_DOC_TITLE - A flag specifying whether to display the document's title * in the top bar. *
    • The predominant reading order for text. This entry has no direct effect on the * document's contents or page numbering, but can be used to determine the relative * positioning of pages when displayed side by side or printed n-up (choose one). *
        *
      • DIRECTION_L2R - Left to right *
      • DIRECTION_R2L - Right to left (including vertical writing systems such as * Chinese, Japanese, and Korean) *
      *
    • The document's page mode, specifying how to display the * document on exiting full-screen mode. It is meaningful only * if the page mode is PageModeFullScreen (choose one). *
        *
      • NON_FULL_SCREEN_PAGE_MODE_USE_NONE - Neither document outline nor thumbnail images * visible *
      • NON_FULL_SCREEN_PAGE_MODE_USE_OUTLINES - Document outline visible *
      • NON_FULL_SCREEN_PAGE_MODE_USE_THUMBS - Thumbnail images visible *
      • NON_FULL_SCREEN_PAGE_MODE_USE_OC - Optional content group panel visible *
      *
    • PRINT_SCALING_NONE - Indicates that the print dialog should reflect no page scaling. *
    * @param preferences the viewer preferences * @see PdfViewerPreferences#addViewerPreference */ public void setViewerPreferences(int preferences); /** * Adds a viewer preference. *
      *
    • In case the key is one of these values: *
        *
      • PdfName.HIDETOOLBAR *
      • PdfName.HIDEMENUBAR *
      • PdfName.HIDEWINDOWUI *
      • PdfName.FITWINDOW *
      • PdfName.CENTERWINDOW *
      • PdfName.DISPLAYDOCTITLE *
      * The value must be a of type PdfBoolean (true or false). *
    • In case the key is PdfName.NONFULLSCREENPAGEMODE, * the value must be one of these names: *
        *
      • PdfName.USENONE *
      • PdfName.USEOUTLINES *
      • PdfName.USETHUMBS *
      • PdfName.USEOC *
      *
    • In case the key is PdfName.DIRECTION, * the value must be one of these names: *
        *
      • PdfName.L2R *
      • PdfName.R2L *
      *
    • In case the key is one of these values: *
        *
      • PdfName.VIEWAREA *
      • PdfName.VIEWCLIP *
      • PdfName.PRINTAREA *
      • PdfName.PRINTCLIP *
      * The value must be one of these names: *
        *
      • PdfName.MEDIABOX *
      • PdfName.CROPBOX *
      • PdfName.BLEEDBOX *
      • PdfName.TRIMBOX *
      • PdfName.ARTBOX *
      *
    • In case the key is PdfName.PRINTSCALING, the value can be *
        *
      • PdfName.APPDEFAULT *
      • PdfName.NONE *
      *
    • In case the key is PdfName.DUPLEX, the value can be: *
        *
      • PdfName.SIMPLEX *
      • PdfName.DUPLEXFLIPSHORTEDGE *
      • PdfName.DUPLEXFLIPLONGEDGE *
      *
    • In case the key is PdfName.PICKTRAYBYPDFSIZE, the value must be of type PdfBoolean. *
    • In case the key is PdfName.PRINTPAGERANGE, the value must be of type PdfArray. *
    • In case the key is PdfName.NUMCOPIES, the value must be of type PdfNumber. *
        *
      * @param key the name of the viewer preference * @param value the value of the viewer preference * @see PdfViewerPreferences#setViewerPreferences */ public void addViewerPreference(PdfName key, PdfObject value); }src/core/com/lowagie/text/pdf/interfaces/PdfXConformance.java100644 0 0 6170 11000354036 21664 0ustar 0 0 /* * $Id: PdfXConformance.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.interfaces; public interface PdfXConformance { /** * Sets the PDF/X conformance level. * Allowed values are PDFX1A2001, PDFX32002, PDFA1A and PDFA1B. * It must be called before opening the document. * @param pdfxConformance the conformance level */ public void setPDFXConformance(int pdfxConformance); /** * Getter for the PDF/X Conformance value. * @return the pdfxConformance */ public int getPDFXConformance(); /** * Checks if the PDF/X Conformance is necessary. * @return true if the PDF has to be in conformance with any of the PDF/X specifications */ public boolean isPdfX(); } src/core/com/lowagie/text/pdf/internal/PdfAnnotationsImp.java100644 0 0 24553 11213370067 21773 0ustar 0 0 /* * $Id: PdfAnnotationsImp.java 3912 2009-04-26 08:38:15Z blowagie $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import com.lowagie.text.Annotation; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfAcroForm; import com.lowagie.text.pdf.PdfAction; import com.lowagie.text.pdf.PdfAnnotation; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfFileSpecification; import com.lowagie.text.pdf.PdfFormField; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfRectangle; import com.lowagie.text.pdf.PdfString; import com.lowagie.text.pdf.PdfWriter; public class PdfAnnotationsImp { /** * This is the AcroForm object for the complete document. */ protected PdfAcroForm acroForm; /** * This is the array containing the references to annotations * that were added to the document. */ protected ArrayList annotations; /** * This is an array containing references to some delayed annotations * (that were added for a page that doesn't exist yet). */ protected ArrayList delayedAnnotations = new ArrayList(); public PdfAnnotationsImp(PdfWriter writer) { acroForm = new PdfAcroForm(writer); } /** * Checks if the AcroForm is valid. */ public boolean hasValidAcroForm() { return acroForm.isValid(); } /** * Gets the AcroForm object. * @return the PdfAcroform object of the PdfDocument */ public PdfAcroForm getAcroForm() { return acroForm; } public void setSigFlags(int f) { acroForm.setSigFlags(f); } public void addCalculationOrder(PdfFormField formField) { acroForm.addCalculationOrder(formField); } public void addAnnotation(PdfAnnotation annot) { if (annot.isForm()) { PdfFormField field = (PdfFormField)annot; if (field.getParent() == null) addFormFieldRaw(field); } else annotations.add(annot); } public void addPlainAnnotation(PdfAnnotation annot) { annotations.add(annot); } void addFormFieldRaw(PdfFormField field) { annotations.add(field); ArrayList kids = field.getKids(); if (kids != null) { for (int k = 0; k < kids.size(); ++k) addFormFieldRaw((PdfFormField)kids.get(k)); } } public boolean hasUnusedAnnotations() { return !annotations.isEmpty(); } public void resetAnnotations() { annotations = delayedAnnotations; delayedAnnotations = new ArrayList(); } public PdfArray rotateAnnotations(PdfWriter writer, Rectangle pageSize) { PdfArray array = new PdfArray(); int rotation = pageSize.getRotation() % 360; int currentPage = writer.getCurrentPageNumber(); for (int k = 0; k < annotations.size(); ++k) { PdfAnnotation dic = (PdfAnnotation)annotations.get(k); int page = dic.getPlaceInPage(); if (page > currentPage) { delayedAnnotations.add(dic); continue; } if (dic.isForm()) { if (!dic.isUsed()) { HashMap templates = dic.getTemplates(); if (templates != null) acroForm.addFieldTemplates(templates); } PdfFormField field = (PdfFormField)dic; if (field.getParent() == null) acroForm.addDocumentField(field.getIndirectReference()); } if (dic.isAnnotation()) { array.add(dic.getIndirectReference()); if (!dic.isUsed()) { PdfRectangle rect = (PdfRectangle)dic.get(PdfName.RECT); if (rect != null) { switch (rotation) { case 90: dic.put(PdfName.RECT, new PdfRectangle( pageSize.getTop() - rect.bottom(), rect.left(), pageSize.getTop() - rect.top(), rect.right())); break; case 180: dic.put(PdfName.RECT, new PdfRectangle( pageSize.getRight() - rect.left(), pageSize.getTop() - rect.bottom(), pageSize.getRight() - rect.right(), pageSize.getTop() - rect.top())); break; case 270: dic.put(PdfName.RECT, new PdfRectangle( rect.bottom(), pageSize.getRight() - rect.left(), rect.top(), pageSize.getRight() - rect.right())); break; } } } } if (!dic.isUsed()) { dic.setUsed(); try { writer.addToBody(dic, dic.getIndirectReference()); } catch (IOException e) { throw new ExceptionConverter(e); } } } return array; } public static PdfAnnotation convertAnnotation(PdfWriter writer, Annotation annot, Rectangle defaultRect) throws IOException { switch(annot.annotationType()) { case Annotation.URL_NET: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((URL) annot.attributes().get(Annotation.URL))); case Annotation.URL_AS_STRING: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE))); case Annotation.FILE_DEST: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE), (String) annot.attributes().get(Annotation.DESTINATION))); case Annotation.SCREEN: boolean sparams[] = (boolean[])annot.attributes().get(Annotation.PARAMETERS); String fname = (String) annot.attributes().get(Annotation.FILE); String mimetype = (String) annot.attributes().get(Annotation.MIMETYPE); PdfFileSpecification fs; if (sparams[0]) fs = PdfFileSpecification.fileEmbedded(writer, fname, fname, null); else fs = PdfFileSpecification.fileExtern(writer, fname); PdfAnnotation ann = PdfAnnotation.createScreen(writer, new Rectangle(annot.llx(), annot.lly(), annot.urx(), annot.ury()), fname, fs, mimetype, sparams[1]); return ann; case Annotation.FILE_PAGE: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE), ((Integer) annot.attributes().get(Annotation.PAGE)).intValue())); case Annotation.NAMED_DEST: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction(((Integer) annot.attributes().get(Annotation.NAMED)).intValue())); case Annotation.LAUNCH: return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.APPLICATION),(String) annot.attributes().get(Annotation.PARAMETERS),(String) annot.attributes().get(Annotation.OPERATION),(String) annot.attributes().get(Annotation.DEFAULTDIR))); default: return new PdfAnnotation(writer, defaultRect.getLeft(), defaultRect.getBottom(), defaultRect.getRight(), defaultRect.getTop(), new PdfString(annot.title(), PdfObject.TEXT_UNICODE), new PdfString(annot.content(), PdfObject.TEXT_UNICODE)); } } } src/core/com/lowagie/text/pdf/internal/PdfVersionImp.java100644 0 0 15346 11213370067 21123 0ustar 0 0 /* * $Id: PdfVersionImp.java 3811 2009-03-23 18:15:13Z blowagie $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import java.io.IOException; import com.lowagie.text.DocWriter; import com.lowagie.text.pdf.OutputStreamCounter; import com.lowagie.text.pdf.PdfDeveloperExtension; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.interfaces.PdfVersion; /** * Stores the PDF version information, * knows how to write a PDF Header, * and how to add the version to the catalog (if necessary). */ public class PdfVersionImp implements PdfVersion { /** Contains different strings that are part of the header. */ public static final byte[][] HEADER = { DocWriter.getISOBytes("\n"), DocWriter.getISOBytes("%PDF-"), DocWriter.getISOBytes("\n%\u00e2\u00e3\u00cf\u00d3\n") }; /** Indicates if the header was already written. */ protected boolean headerWasWritten = false; /** Indicates if we are working in append mode. */ protected boolean appendmode = false; /** The version that was or will be written to the header. */ protected char header_version = PdfWriter.VERSION_1_4; /** The version that will be written to the catalog. */ protected PdfName catalog_version = null; /** * The extensions dictionary. * @since 2.1.6 */ protected PdfDictionary extensions = null; /** * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(char) */ public void setPdfVersion(char version) { if (headerWasWritten || appendmode) { setPdfVersion(getVersionAsName(version)); } else { this.header_version = version; } } /** * @see com.lowagie.text.pdf.interfaces.PdfVersion#setAtLeastPdfVersion(char) */ public void setAtLeastPdfVersion(char version) { if (version > header_version) { setPdfVersion(version); } } /** * @see com.lowagie.text.pdf.interfaces.PdfVersion#setPdfVersion(com.lowagie.text.pdf.PdfName) */ public void setPdfVersion(PdfName version) { if (catalog_version == null || catalog_version.compareTo(version) < 0) { this.catalog_version = version; } } /** * Sets the append mode. */ public void setAppendmode(boolean appendmode) { this.appendmode = appendmode; } /** * Writes the header to the OutputStreamCounter. * @throws IOException */ public void writeHeader(OutputStreamCounter os) throws IOException { if (appendmode) { os.write(HEADER[0]); } else { os.write(HEADER[1]); os.write(getVersionAsByteArray(header_version)); os.write(HEADER[2]); headerWasWritten = true; } } /** * Returns the PDF version as a name. * @param version the version character. */ public PdfName getVersionAsName(char version) { switch(version) { case PdfWriter.VERSION_1_2: return PdfWriter.PDF_VERSION_1_2; case PdfWriter.VERSION_1_3: return PdfWriter.PDF_VERSION_1_3; case PdfWriter.VERSION_1_4: return PdfWriter.PDF_VERSION_1_4; case PdfWriter.VERSION_1_5: return PdfWriter.PDF_VERSION_1_5; case PdfWriter.VERSION_1_6: return PdfWriter.PDF_VERSION_1_6; case PdfWriter.VERSION_1_7: return PdfWriter.PDF_VERSION_1_7; default: return PdfWriter.PDF_VERSION_1_4; } } /** * Returns the version as a byte[]. * @param version the version character */ public byte[] getVersionAsByteArray(char version) { return DocWriter.getISOBytes(getVersionAsName(version).toString().substring(1)); } /** Adds the version to the Catalog dictionary. */ public void addToCatalog(PdfDictionary catalog) { if(catalog_version != null) { catalog.put(PdfName.VERSION, catalog_version); } if (extensions != null) { catalog.put(PdfName.EXTENSIONS, extensions); } } /** * @see com.lowagie.text.pdf.interfaces.PdfVersion#addDeveloperExtension(com.lowagie.text.pdf.PdfDeveloperExtension) * @since 2.1.6 */ public void addDeveloperExtension(PdfDeveloperExtension de) { if (extensions == null) { extensions = new PdfDictionary(); } else { PdfDictionary extension = extensions.getAsDict(de.getPrefix()); if (extension != null) { int diff = de.getBaseversion().compareTo(extension.getAsName(PdfName.BASEVERSION)); if (diff < 0) return; diff = de.getExtensionLevel() - extension.getAsNumber(PdfName.EXTENSIONLEVEL).intValue(); if (diff <= 0) return; } } extensions.put(de.getPrefix(), de.getDeveloperExtensions()); } }src/core/com/lowagie/text/pdf/internal/PdfViewerPreferencesImp.java100644 0 0 33150 11213370067 23112 0ustar 0 0 /* * $Id: PdfViewerPreferencesImp.java 3867 2009-04-17 17:49:57Z blowagie $ * * Copyright 2006 Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfBoolean; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.interfaces.PdfViewerPreferences; /** * Stores the information concerning viewer preferences, * and contains the business logic that allows you to set viewer preferences. */ public class PdfViewerPreferencesImp implements PdfViewerPreferences { public static final PdfName[] VIEWER_PREFERENCES = { PdfName.HIDETOOLBAR, // 0 PdfName.HIDEMENUBAR, // 1 PdfName.HIDEWINDOWUI, // 2 PdfName.FITWINDOW, // 3 PdfName.CENTERWINDOW, // 4 PdfName.DISPLAYDOCTITLE, // 5 PdfName.NONFULLSCREENPAGEMODE, // 6 PdfName.DIRECTION, // 7 PdfName.VIEWAREA, // 8 PdfName.VIEWCLIP, // 9 PdfName.PRINTAREA, // 10 PdfName.PRINTCLIP, // 11 PdfName.PRINTSCALING, // 12 PdfName.DUPLEX, // 13 PdfName.PICKTRAYBYPDFSIZE, // 14 PdfName.PRINTPAGERANGE, // 15 PdfName.NUMCOPIES // 16 }; /** A series of viewer preferences. */ public static final PdfName NONFULLSCREENPAGEMODE_PREFERENCES[] = { PdfName.USENONE, PdfName.USEOUTLINES, PdfName.USETHUMBS, PdfName.USEOC }; /** A series of viewer preferences. */ public static final PdfName DIRECTION_PREFERENCES[] = { PdfName.L2R, PdfName.R2L }; /** A series of viewer preferences. */ public static final PdfName PAGE_BOUNDARIES[] = { PdfName.MEDIABOX, PdfName.CROPBOX, PdfName.BLEEDBOX, PdfName.TRIMBOX, PdfName.ARTBOX }; /** A series of viewer preferences */ public static final PdfName PRINTSCALING_PREFERENCES[] = { PdfName.APPDEFAULT, PdfName.NONE }; /** A series of viewer preferences. */ public static final PdfName DUPLEX_PREFERENCES[] = { PdfName.SIMPLEX, PdfName.DUPLEXFLIPSHORTEDGE, PdfName.DUPLEXFLIPLONGEDGE }; /** This value will hold the viewer preferences for the page layout and page mode. */ private int pageLayoutAndMode = 0; /** This dictionary holds the viewer preferences (other than page layout and page mode). */ private PdfDictionary viewerPreferences = new PdfDictionary(); /** The mask to decide if a ViewerPreferences dictionary is needed */ private static final int viewerPreferencesMask = 0xfff000; /** * Returns the page layout and page mode value. */ public int getPageLayoutAndMode() { return pageLayoutAndMode; } /** * Returns the viewer preferences. */ public PdfDictionary getViewerPreferences() { return viewerPreferences; } /** * Sets the viewer preferences as the sum of several constants. * * @param preferences * the viewer preferences * @see PdfViewerPreferences#setViewerPreferences */ public void setViewerPreferences(int preferences) { this.pageLayoutAndMode |= preferences; // for backwards compatibility, it is also possible // to set the following viewer preferences with this method: if ((preferences & viewerPreferencesMask) != 0) { pageLayoutAndMode = ~viewerPreferencesMask & pageLayoutAndMode; if ((preferences & PdfWriter.HideToolbar) != 0) viewerPreferences.put(PdfName.HIDETOOLBAR, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.HideMenubar) != 0) viewerPreferences.put(PdfName.HIDEMENUBAR, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.HideWindowUI) != 0) viewerPreferences.put(PdfName.HIDEWINDOWUI, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.FitWindow) != 0) viewerPreferences.put(PdfName.FITWINDOW, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.CenterWindow) != 0) viewerPreferences.put(PdfName.CENTERWINDOW, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.DisplayDocTitle) != 0) viewerPreferences.put(PdfName.DISPLAYDOCTITLE, PdfBoolean.PDFTRUE); if ((preferences & PdfWriter.NonFullScreenPageModeUseNone) != 0) viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USENONE); else if ((preferences & PdfWriter.NonFullScreenPageModeUseOutlines) != 0) viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOUTLINES); else if ((preferences & PdfWriter.NonFullScreenPageModeUseThumbs) != 0) viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USETHUMBS); else if ((preferences & PdfWriter.NonFullScreenPageModeUseOC) != 0) viewerPreferences.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOC); if ((preferences & PdfWriter.DirectionL2R) != 0) viewerPreferences.put(PdfName.DIRECTION, PdfName.L2R); else if ((preferences & PdfWriter.DirectionR2L) != 0) viewerPreferences.put(PdfName.DIRECTION, PdfName.R2L); if ((preferences & PdfWriter.PrintScalingNone) != 0) viewerPreferences.put(PdfName.PRINTSCALING, PdfName.NONE); } } /** * Given a key for a viewer preference (a PdfName object), * this method returns the index in the VIEWER_PREFERENCES array. * @param key a PdfName referring to a viewer preference * @return an index in the VIEWER_PREFERENCES array */ private int getIndex(PdfName key) { for (int i = 0; i < VIEWER_PREFERENCES.length; i++) { if (VIEWER_PREFERENCES[i].equals(key)) return i; } return -1; } /** * Checks if some value is valid for a certain key. */ private boolean isPossibleValue(PdfName value, PdfName[] accepted) { for (int i = 0; i < accepted.length; i++) { if (accepted[i].equals(value)) { return true; } } return false; } /** * Sets the viewer preferences for printing. */ public void addViewerPreference(PdfName key, PdfObject value) { switch(getIndex(key)) { case 0: // HIDETOOLBAR case 1: // HIDEMENUBAR case 2: // HIDEWINDOWUI case 3: // FITWINDOW case 4: // CENTERWINDOW case 5: // DISPLAYDOCTITLE case 14: // PICKTRAYBYPDFSIZE if (value instanceof PdfBoolean) { viewerPreferences.put(key, value); } break; case 6: // NONFULLSCREENPAGEMODE if (value instanceof PdfName && isPossibleValue((PdfName)value, NONFULLSCREENPAGEMODE_PREFERENCES)) { viewerPreferences.put(key, value); } break; case 7: // DIRECTION if (value instanceof PdfName && isPossibleValue((PdfName)value, DIRECTION_PREFERENCES)) { viewerPreferences.put(key, value); } break; case 8: // VIEWAREA case 9: // VIEWCLIP case 10: // PRINTAREA case 11: // PRINTCLIP if (value instanceof PdfName && isPossibleValue((PdfName)value, PAGE_BOUNDARIES)) { viewerPreferences.put(key, value); } break; case 12: // PRINTSCALING if (value instanceof PdfName && isPossibleValue((PdfName)value, PRINTSCALING_PREFERENCES)) { viewerPreferences.put(key, value); } break; case 13: // DUPLEX if (value instanceof PdfName && isPossibleValue((PdfName)value, DUPLEX_PREFERENCES)) { viewerPreferences.put(key, value); } break; case 15: // PRINTPAGERANGE if (value instanceof PdfArray) { viewerPreferences.put(key, value); } break; case 16: // NUMCOPIES if (value instanceof PdfNumber) { viewerPreferences.put(key, value); } break; } } /** * Adds the viewer preferences defined in the preferences parameter to a * PdfDictionary (more specifically the root or catalog of a PDF file). * * @param catalog */ public void addToCatalog(PdfDictionary catalog) { // Page Layout catalog.remove(PdfName.PAGELAYOUT); if ((pageLayoutAndMode & PdfWriter.PageLayoutSinglePage) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.SINGLEPAGE); else if ((pageLayoutAndMode & PdfWriter.PageLayoutOneColumn) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.ONECOLUMN); else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnLeft) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNLEFT); else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoColumnRight) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNRIGHT); else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageLeft) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGELEFT); else if ((pageLayoutAndMode & PdfWriter.PageLayoutTwoPageRight) != 0) catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGERIGHT); // Page Mode catalog.remove(PdfName.PAGEMODE); if ((pageLayoutAndMode & PdfWriter.PageModeUseNone) != 0) catalog.put(PdfName.PAGEMODE, PdfName.USENONE); else if ((pageLayoutAndMode & PdfWriter.PageModeUseOutlines) != 0) catalog.put(PdfName.PAGEMODE, PdfName.USEOUTLINES); else if ((pageLayoutAndMode & PdfWriter.PageModeUseThumbs) != 0) catalog.put(PdfName.PAGEMODE, PdfName.USETHUMBS); else if ((pageLayoutAndMode & PdfWriter.PageModeFullScreen) != 0) catalog.put(PdfName.PAGEMODE, PdfName.FULLSCREEN); else if ((pageLayoutAndMode & PdfWriter.PageModeUseOC) != 0) catalog.put(PdfName.PAGEMODE, PdfName.USEOC); else if ((pageLayoutAndMode & PdfWriter.PageModeUseAttachments) != 0) catalog.put(PdfName.PAGEMODE, PdfName.USEATTACHMENTS); // viewer preferences (Table 8.1 of the PDF Reference) catalog.remove(PdfName.VIEWERPREFERENCES); if (viewerPreferences.size() > 0) { catalog.put(PdfName.VIEWERPREFERENCES, viewerPreferences); } } public static PdfViewerPreferencesImp getViewerPreferences(PdfDictionary catalog) { PdfViewerPreferencesImp preferences = new PdfViewerPreferencesImp(); int prefs = 0; PdfName name = null; // page layout PdfObject obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.PAGELAYOUT)); if (obj != null && obj.isName()) { name = (PdfName) obj; if (name.equals(PdfName.SINGLEPAGE)) prefs |= PdfWriter.PageLayoutSinglePage; else if (name.equals(PdfName.ONECOLUMN)) prefs |= PdfWriter.PageLayoutOneColumn; else if (name.equals(PdfName.TWOCOLUMNLEFT)) prefs |= PdfWriter.PageLayoutTwoColumnLeft; else if (name.equals(PdfName.TWOCOLUMNRIGHT)) prefs |= PdfWriter.PageLayoutTwoColumnRight; else if (name.equals(PdfName.TWOPAGELEFT)) prefs |= PdfWriter.PageLayoutTwoPageLeft; else if (name.equals(PdfName.TWOPAGERIGHT)) prefs |= PdfWriter.PageLayoutTwoPageRight; } // page mode obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.PAGEMODE)); if (obj != null && obj.isName()) { name = (PdfName) obj; if (name.equals(PdfName.USENONE)) prefs |= PdfWriter.PageModeUseNone; else if (name.equals(PdfName.USEOUTLINES)) prefs |= PdfWriter.PageModeUseOutlines; else if (name.equals(PdfName.USETHUMBS)) prefs |= PdfWriter.PageModeUseThumbs; else if (name.equals(PdfName.FULLSCREEN)) prefs |= PdfWriter.PageModeFullScreen; else if (name.equals(PdfName.USEOC)) prefs |= PdfWriter.PageModeUseOC; else if (name.equals(PdfName.USEATTACHMENTS)) prefs |= PdfWriter.PageModeUseAttachments; } // set page layout and page mode preferences preferences.setViewerPreferences(prefs); // other preferences obj = PdfReader.getPdfObjectRelease(catalog .get(PdfName.VIEWERPREFERENCES)); if (obj != null && obj.isDictionary()) { PdfDictionary vp = (PdfDictionary) obj; for (int i = 0; i < VIEWER_PREFERENCES.length; i++) { obj = PdfReader.getPdfObjectRelease(vp.get(VIEWER_PREFERENCES[i])); preferences.addViewerPreference(VIEWER_PREFERENCES[i], obj); } } return preferences; } }src/core/com/lowagie/text/pdf/internal/PdfXConformanceImp.java100644 0 0 30442 11213370067 22052 0ustar 0 0 /* * $Id: PdfXConformanceImp.java 3829 2009-04-01 15:50:47Z blowagie $ * * Copyright 2006 Bruno Lowagie (based on code by Paulo Soares) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import java.awt.Color; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.ExtendedColor; import com.lowagie.text.pdf.PatternColor; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfGState; import com.lowagie.text.pdf.PdfImage; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfString; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.PdfXConformanceException; import com.lowagie.text.pdf.ShadingColor; import com.lowagie.text.pdf.SpotColor; import com.lowagie.text.pdf.interfaces.PdfXConformance; public class PdfXConformanceImp implements PdfXConformance { /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_COLOR = 1; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_CMYK = 2; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_RGB = 3; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_FONT = 4; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_IMAGE = 5; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_GSTATE = 6; /** A key for an aspect that can be checked for PDF/X Conformance. */ public static final int PDFXKEY_LAYER = 7; /** * The value indicating if the PDF has to be in conformance with PDF/X. */ protected int pdfxConformance = PdfWriter.PDFXNONE; /** * @see com.lowagie.text.pdf.interfaces.PdfXConformance#setPDFXConformance(int) */ public void setPDFXConformance(int pdfxConformance) { this.pdfxConformance = pdfxConformance; } /** * @see com.lowagie.text.pdf.interfaces.PdfXConformance#getPDFXConformance() */ public int getPDFXConformance() { return pdfxConformance; } /** * Checks if the PDF/X Conformance is necessary. * @return true if the PDF has to be in conformance with any of the PDF/X specifications */ public boolean isPdfX() { return pdfxConformance != PdfWriter.PDFXNONE; } /** * Checks if the PDF has to be in conformance with PDF/X-1a:2001 * @return true of the PDF has to be in conformance with PDF/X-1a:2001 */ public boolean isPdfX1A2001() { return pdfxConformance == PdfWriter.PDFX1A2001; } /** * Checks if the PDF has to be in conformance with PDF/X-3:2002 * @return true of the PDF has to be in conformance with PDF/X-3:2002 */ public boolean isPdfX32002() { return pdfxConformance == PdfWriter.PDFX32002; } /** * Checks if the PDF has to be in conformance with PDFA1 * @return true of the PDF has to be in conformance with PDFA1 */ public boolean isPdfA1() { return pdfxConformance == PdfWriter.PDFA1A || pdfxConformance == PdfWriter.PDFA1B; } /** * Checks if the PDF has to be in conformance with PDFA1A * @return true of the PDF has to be in conformance with PDFA1A */ public boolean isPdfA1A() { return pdfxConformance == PdfWriter.PDFA1A; } public void completeInfoDictionary(PdfDictionary info) { if (isPdfX() && !isPdfA1()) { if (info.get(PdfName.GTS_PDFXVERSION) == null) { if (isPdfX1A2001()) { info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-1:2001")); info.put(new PdfName("GTS_PDFXConformance"), new PdfString("PDF/X-1a:2001")); } else if (isPdfX32002()) info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-3:2002")); } if (info.get(PdfName.TITLE) == null) { info.put(PdfName.TITLE, new PdfString("Pdf document")); } if (info.get(PdfName.CREATOR) == null) { info.put(PdfName.CREATOR, new PdfString("Unknown")); } if (info.get(PdfName.TRAPPED) == null) { info.put(PdfName.TRAPPED, new PdfName("False")); } } } public void completeExtraCatalog(PdfDictionary extraCatalog) { if (isPdfX() && !isPdfA1()) { if (extraCatalog.get(PdfName.OUTPUTINTENTS) == null) { PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT); out.put(PdfName.OUTPUTCONDITION, new PdfString("SWOP CGATS TR 001-1995")); out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("CGATS TR 001")); out.put(PdfName.REGISTRYNAME, new PdfString("http://www.color.org")); out.put(PdfName.INFO, new PdfString("")); out.put(PdfName.S, PdfName.GTS_PDFX); extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out)); } } } /** * Business logic that checks if a certain object is in conformance with PDF/X. * @param writer the writer that is supposed to write the PDF/X file * @param key the type of PDF/X conformance that has to be checked * @param obj1 the object that is checked for conformance */ public static void checkPDFXConformance(PdfWriter writer, int key, Object obj1) { if (writer == null || !writer.isPdfX()) return; int conf = writer.getPDFXConformance(); switch (key) { case PDFXKEY_COLOR: switch (conf) { case PdfWriter.PDFX1A2001: if (obj1 instanceof ExtendedColor) { ExtendedColor ec = (ExtendedColor)obj1; switch (ec.getType()) { case ExtendedColor.TYPE_CMYK: case ExtendedColor.TYPE_GRAY: return; case ExtendedColor.TYPE_RGB: throw new PdfXConformanceException("Colorspace RGB is not allowed."); case ExtendedColor.TYPE_SEPARATION: SpotColor sc = (SpotColor)ec; checkPDFXConformance(writer, PDFXKEY_COLOR, sc.getPdfSpotColor().getAlternativeCS()); break; case ExtendedColor.TYPE_SHADING: ShadingColor xc = (ShadingColor)ec; checkPDFXConformance(writer, PDFXKEY_COLOR, xc.getPdfShadingPattern().getShading().getColorSpace()); break; case ExtendedColor.TYPE_PATTERN: PatternColor pc = (PatternColor)ec; checkPDFXConformance(writer, PDFXKEY_COLOR, pc.getPainter().getDefaultColor()); break; } } else if (obj1 instanceof Color) throw new PdfXConformanceException("Colorspace RGB is not allowed."); break; } break; case PDFXKEY_CMYK: break; case PDFXKEY_RGB: if (conf == PdfWriter.PDFX1A2001) throw new PdfXConformanceException("Colorspace RGB is not allowed."); break; case PDFXKEY_FONT: if (!((BaseFont)obj1).isEmbedded()) throw new PdfXConformanceException("All the fonts must be embedded. This one isn't: " + ((BaseFont)obj1).getPostscriptFontName()); break; case PDFXKEY_IMAGE: PdfImage image = (PdfImage)obj1; if (image.get(PdfName.SMASK) != null) throw new PdfXConformanceException("The /SMask key is not allowed in images."); switch (conf) { case PdfWriter.PDFX1A2001: PdfObject cs = image.get(PdfName.COLORSPACE); if (cs == null) return; if (cs.isName()) { if (PdfName.DEVICERGB.equals(cs)) throw new PdfXConformanceException("Colorspace RGB is not allowed."); } else if (cs.isArray()) { if (PdfName.CALRGB.equals(((PdfArray)cs).getPdfObject(0))) throw new PdfXConformanceException("Colorspace CalRGB is not allowed."); } break; } break; case PDFXKEY_GSTATE: PdfDictionary gs = (PdfDictionary)obj1; PdfObject obj = gs.get(PdfName.BM); if (obj != null && !PdfGState.BM_NORMAL.equals(obj) && !PdfGState.BM_COMPATIBLE.equals(obj)) throw new PdfXConformanceException("Blend mode " + obj.toString() + " not allowed."); obj = gs.get(PdfName.CA); double v = 0.0; if (obj != null && (v = ((PdfNumber)obj).doubleValue()) != 1.0) throw new PdfXConformanceException("Transparency is not allowed: /CA = " + v); obj = gs.get(PdfName.ca); v = 0.0; if (obj != null && (v = ((PdfNumber)obj).doubleValue()) != 1.0) throw new PdfXConformanceException("Transparency is not allowed: /ca = " + v); break; case PDFXKEY_LAYER: throw new PdfXConformanceException("Layers are not allowed."); } } } src/core/com/lowagie/text/pdf/internal/PolylineShape.java100644 0 0 14530 11000354027 21134 0ustar 0 0 /* * $Id: PolylineShape.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie and Wil * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import java.awt.Shape; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** * Class that defines a Polyline shape. * This class was originally written by wil - amristar.com.au * and integrated into iText by Bruno. */ public class PolylineShape implements Shape { /** All the X-values of the coordinates in the polyline. */ protected int[] x; /** All the Y-values of the coordinates in the polyline. */ protected int[] y; /** The total number of points. */ protected int np; /** Creates a PolylineShape. */ public PolylineShape(int[] x, int[] y, int nPoints) { // Should copy array (as done in Polygon) this.np = nPoints; // Take a copy. this.x = new int[np]; this.y = new int[np]; System.arraycopy(x, 0, this.x, 0, np); System.arraycopy(y, 0, this.y, 0, np); } /** * Returns the bounding box of this polyline. * * @return a {@link Rectangle2D} that is the high-precision * bounding box of this line. * @see java.awt.Shape#getBounds2D() */ public Rectangle2D getBounds2D() { int[] r = rect(); return r==null?null:new Rectangle2D.Double(r[0], r[1], r[2], r[3]); } /** * Returns the bounding box of this polyline. * @see java.awt.Shape#getBounds() */ public Rectangle getBounds() { return getBounds2D().getBounds(); } /** * Calculates the origin (X, Y) and the width and height * of a rectangle that contains all the segments of the * polyline. */ private int[] rect() { if(np==0)return null; int xMin = x[0], yMin=y[0], xMax=x[0],yMax=y[0]; for(int i=1;ixMax)xMax=x[i]; if(y[i]yMax)yMax=y[i]; } return new int[] { xMin, yMin, xMax-xMin, yMax-yMin }; } /** * A polyline can't contain a point. * @see java.awt.Shape#contains(double, double) */ public boolean contains(double x, double y) { return false; } /** * A polyline can't contain a point. * @see java.awt.Shape#contains(java.awt.geom.Point2D) */ public boolean contains(Point2D p) { return false; } /** * A polyline can't contain a point. * @see java.awt.Shape#contains(double, double, double, double) */ public boolean contains(double x, double y, double w, double h) { return false; } /** * A polyline can't contain a point. * @see java.awt.Shape#contains(java.awt.geom.Rectangle2D) */ public boolean contains(Rectangle2D r) { return false; } /** * Checks if one of the lines in the polyline intersects * with a given rectangle. * @see java.awt.Shape#intersects(double, double, double, double) */ public boolean intersects(double x, double y, double w, double h) { return intersects(new Rectangle2D.Double(x, y, w, h)); } /** * Checks if one of the lines in the polyline intersects * with a given rectangle. * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D) */ public boolean intersects(Rectangle2D r) { if(np==0)return false; Line2D line = new Line2D.Double(x[0],y[0],x[0],y[0]); for (int i = 1; i < np; i++) { line.setLine(x[i-1], y[i-1], x[i], y[i]); if(line.intersects(r))return true; } return false; } /** * Returns an iteration object that defines the boundary of the polyline. * @param at the specified {@link AffineTransform} * @return a {@link PathIterator} that defines the boundary of this polyline. * @see java.awt.Shape#intersects(java.awt.geom.Rectangle2D) */ public PathIterator getPathIterator(AffineTransform at) { return new PolylineShapeIterator(this, at); } /** * There's no difference with getPathIterator(AffineTransform at); * we just need this method to implement the Shape interface. */ public PathIterator getPathIterator(AffineTransform at, double flatness) { return new PolylineShapeIterator(this, at); } } src/core/com/lowagie/text/pdf/internal/PolylineShapeIterator.java100644 0 0 13754 11036112744 22664 0ustar 0 0 /* * $Id: PolylineShapeIterator.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2007 Bruno Lowagie and Wil * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.internal; import java.awt.geom.AffineTransform; import java.awt.geom.PathIterator; import java.util.NoSuchElementException; /** * PathIterator for PolylineShape. * This class was originally written by wil - amristar.com.au * and integrated into iText by Bruno. */ public class PolylineShapeIterator implements PathIterator { /** The polyline over which we are going to iterate. */ protected PolylineShape poly; /** an affine transformation to be performed on the polyline. */ protected AffineTransform affine; /** the index of the current segment in the iterator. */ protected int index; /** Creates a PolylineShapeIterator. */ PolylineShapeIterator(PolylineShape l, AffineTransform at) { this.poly = l; this.affine = at; } /** * Returns the coordinates and type of the current path segment in * the iteration. The return value is the path segment type: * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. * A double array of length 6 must be passed in and may be used to * store the coordinates of the point(s). * Each point is stored as a pair of double x,y coordinates. * SEG_MOVETO and SEG_LINETO types will return one point, * SEG_QUADTO will return two points, * SEG_CUBICTO will return 3 points * and SEG_CLOSE will not return any points. * @see #SEG_MOVETO * @see #SEG_LINETO * @see #SEG_QUADTO * @see #SEG_CUBICTO * @see #SEG_CLOSE * @see java.awt.geom.PathIterator#currentSegment(double[]) */ public int currentSegment(double[] coords) { if (isDone()) { throw new NoSuchElementException("line iterator out of bounds"); } int type = (index==0)?SEG_MOVETO:SEG_LINETO; coords[0] = poly.x[index]; coords[1] = poly.y[index]; if (affine != null) { affine.transform(coords, 0, coords, 0, 1); } return type; } /** * Returns the coordinates and type of the current path segment in * the iteration. The return value is the path segment type: * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE. * A double array of length 6 must be passed in and may be used to * store the coordinates of the point(s). * Each point is stored as a pair of double x,y coordinates. * SEG_MOVETO and SEG_LINETO types will return one point, * SEG_QUADTO will return two points, * SEG_CUBICTO will return 3 points * and SEG_CLOSE will not return any points. * @see #SEG_MOVETO * @see #SEG_LINETO * @see #SEG_QUADTO * @see #SEG_CUBICTO * @see #SEG_CLOSE * @see java.awt.geom.PathIterator#currentSegment(float[]) */ public int currentSegment(float[] coords) { if (isDone()) { throw new NoSuchElementException("line iterator out of bounds"); } int type = (index==0)?SEG_MOVETO:SEG_LINETO; coords[0] = poly.x[index]; coords[1] = poly.y[index]; if (affine != null) { affine.transform(coords, 0, coords, 0, 1); } return type; } /** * Return the winding rule for determining the insideness of the * path. * @see #WIND_EVEN_ODD * @see #WIND_NON_ZERO * @see java.awt.geom.PathIterator#getWindingRule() */ public int getWindingRule() { return WIND_NON_ZERO; } /** * Tests if there are more points to read. * @return true if there are more points to read * @see java.awt.geom.PathIterator#isDone() */ public boolean isDone() { return (index >= poly.np); } /** * Moves the iterator to the next segment of the path forwards * along the primary direction of traversal as long as there are * more points in that direction. * @see java.awt.geom.PathIterator#next() */ public void next() { index++; } } src/core/com/lowagie/text/pdf/parser/ContentOperator.java100644 0 0 5771 11154165265 21173 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import java.util.ArrayList; import com.lowagie.text.pdf.PdfLiteral; /** * Interface implemented by a series of content operators * @since 2.1.4 */ public interface ContentOperator { /** * Invokes a content operator. * @param processor the processor that is dealing with the PDF content * @param operator the literal PDF syntax of the operator * @param operands the operands that come with the operator */ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands); } src/core/com/lowagie/text/pdf/parser/GraphicsState.java100644 0 0 10377 11154165265 20624 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import com.lowagie.text.pdf.CMapAwareDocumentFont; /** * Keeps all the parameters of the graphics state. * @since 2.1.4 */ public class GraphicsState { /** The current transformation matrix. */ Matrix ctm; /** The current character spacing. */ float characterSpacing; /** The current word spacing. */ float wordSpacing; /** The current horizontal scaling */ float horizontalScaling; /** The current leading. */ float leading; /** The active font. */ CMapAwareDocumentFont font; /** The current font size. */ float fontSize; /** The current render mode. */ int renderMode; /** The current text rise */ float rise; /** The current knockout value. */ boolean knockout; /** * Constructs a new Graphics State object with the default values. */ public GraphicsState(){ ctm = new Matrix(); characterSpacing = 0; wordSpacing = 0; horizontalScaling = 1.0f; leading = 0; font = null; fontSize = 0; renderMode = 0; rise = 0; knockout = true; } /** * Copy constructor. * @param source another GraphicsState object */ public GraphicsState(GraphicsState source){ // note: all of the following are immutable, with the possible exception of font // so it is safe to copy them as-is ctm = source.ctm; characterSpacing = source.characterSpacing; wordSpacing = source.wordSpacing; horizontalScaling = source.horizontalScaling; leading = source.leading; font = source.font; fontSize = source.fontSize; renderMode = source.renderMode; rise = source.rise; knockout = source.knockout; } } src/core/com/lowagie/text/pdf/parser/Matrix.java100644 0 0 16204 11154165265 17322 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import java.util.Arrays; /** * Keeps all the values of a 3 by 3 matrix * and allows you to do some math with matrices. * @since 2.1.4 */ public class Matrix { /** an array position referring to a specific value in the matrix. */ public static final int I11 = 0; /** an array position referring to a specific value in the matrix. */ public static final int I12 = 1; /** an array position referring to a specific value in the matrix. */ public static final int I13 = 2; /** an array position referring to a specific value in the matrix. */ public static final int I21 = 3; /** an array position referring to a specific value in the matrix. */ public static final int I22 = 4; /** an array position referring to a specific value in the matrix. */ public static final int I23 = 5; /** an array position referring to a specific value in the matrix. */ public static final int I31 = 6; /** an array position referring to a specific value in the matrix. */ public static final int I32 = 7; /** an array position referring to a specific value in the matrix. */ public static final int I33 = 8; /** the values inside the matrix (the identity matrix by default). */ private final float[] vals = new float[]{ 1,0,0, 0,1,0, 0,0,1 }; /** * constructs a new Matrix with identity. */ public Matrix() { } /** * Constructs a matrix that represents translation * @param tx * @param ty */ public Matrix(float tx, float ty){ vals[I31] = tx; vals[I32] = ty; } /** * Creates a Matrix with 6 specified entries * @param a * @param b * @param c * @param d * @param e * @param f */ public Matrix(float a, float b, float c, float d, float e, float f){ vals[I11] = a; vals[I12] = b; vals[I13] = 0; vals[I21] = c; vals[I22] = d; vals[I23] = 0; vals[I31] = e; vals[I32] = f; vals[I33] = 1; } /** * Gets a specific value inside the matrix. * @param index an array index corresponding with a value inside the matrix * @return the value at that specific position. */ public float get(int index){ return vals[index]; } /** * multiplies this matrix by 'b' and returns the result * See http://en.wikipedia.org/wiki/Matrix_multiplication * @param by The matrix to multiply by * @return the resulting matrix */ public Matrix multiply(Matrix by){ Matrix rslt = new Matrix(); float[] a = vals; float[] b = by.vals; float[] c = rslt.vals; c[I11] = a[I11]*b[I11] + a[I12]*b[I21] + a[I13]*b[I31]; c[I12] = a[I11]*b[I12] + a[I12]*b[I22] + a[I13]*b[I32]; c[I13] = a[I11]*b[I13] + a[I12]*b[I23] + a[I13]*b[I33]; c[I21] = a[I21]*b[I11] + a[I22]*b[I21] + a[I23]*b[I31]; c[I22] = a[I21]*b[I12] + a[I22]*b[I22] + a[I23]*b[I32]; c[I23] = a[I21]*b[I13] + a[I22]*b[I23] + a[I23]*b[I33]; c[I31] = a[I31]*b[I11] + a[I32]*b[I21] + a[I33]*b[I31]; c[I32] = a[I31]*b[I12] + a[I32]*b[I22] + a[I33]*b[I32]; c[I33] = a[I31]*b[I13] + a[I32]*b[I23] + a[I33]*b[I33]; return rslt; } /** * Checks equality of matrices. * @param obj the other Matrix that needs to be compared with this matrix. * @return true if both matrices are equal * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (!(obj instanceof Matrix)) return false; return Arrays.equals(vals, ((Matrix)obj).vals); } /** * Generates a hash code for this object. * @return the hash code of this object * @see java.lang.Object#hashCode() */ public int hashCode() { //return Arrays.hashCode(vals); // JDK 5 code, replaced with the following int result = 1; for (int i = 0; i < vals.length; i++) result = 31 * result + Float.floatToIntBits(vals[i]); return result; } /** * Generates a String representating of the matrix. * @return the values, delimited with tabs and newlines. * @see java.lang.Object#toString() */ public String toString() { return vals[I11] + "\t" + vals[I12] + "\t" + vals[I13] + "\n" + vals[I21] + "\t" + vals[I22] + "\t" + vals[I13] + "\n" + vals[I31] + "\t" + vals[I32] + "\t" + vals[I33]; } } src/core/com/lowagie/text/pdf/parser/PdfContentReaderTool.java100644 0 0 22064 11154165265 22104 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * Tool that parses the content of a PDF document. * @since 2.1.4 */ public class PdfContentReaderTool { /** * Shows the detail of a dictionary. * This is similar to the PdfLister functionality. * @param dic the dictionary of which you want the detail * @return a String representation of the dictionary */ static public String getDictionaryDetail(PdfDictionary dic){ return getDictionaryDetail(dic, 0); } /** * Shows the detail of a dictionary. * @param dic the dictionary of which you want the detail * @param depth the depth of the current dictionary (for nested dictionaries) * @return a String representation of the dictionary */ static public String getDictionaryDetail(PdfDictionary dic, int depth){ StringBuffer builder = new StringBuffer(); builder.append('('); List subDictionaries = new ArrayList(); for (Iterator i = dic.getKeys().iterator(); i.hasNext(); ) { PdfName key = (PdfName)i.next(); PdfObject val = dic.getDirectObject(key); if (val.isDictionary()) subDictionaries.add(key); builder.append(key); builder.append('='); builder.append(val); builder.append(", "); } builder.setLength(builder.length()-2); builder.append(')'); PdfName pdfSubDictionaryName; for (Iterator it = subDictionaries.iterator(); it.hasNext(); ) { pdfSubDictionaryName = (PdfName)it.next(); builder.append('\n'); for(int i = 0; i < depth+1; i++){ builder.append('\t'); } builder.append("Subdictionary "); builder.append(pdfSubDictionaryName); builder.append(" = "); builder.append(getDictionaryDetail(dic.getAsDict(pdfSubDictionaryName), depth+1)); } return builder.toString(); } /** * Writes information about a specific page from PdfReader to the specified output stream. * @since 2.1.5 * @param reader the PdfReader to read the page content from * @param pageNum the page number to read * @param out the output stream to send the content to * @throws IOException */ static public void listContentStreamForPage(PdfReader reader, int pageNum, PrintWriter out) throws IOException { out.println("==============Page " + pageNum + "===================="); out.println("- - - - - Dictionary - - - - - -"); PdfDictionary pageDictionary = reader.getPageN(pageNum); out.println(getDictionaryDetail(pageDictionary)); out.println("- - - - - Content Stream - - - - - -"); RandomAccessFileOrArray f = reader.getSafeFile(); byte[] contentBytes = reader.getPageContent(pageNum, f); f.close(); InputStream is = new ByteArrayInputStream(contentBytes); int ch; while ((ch = is.read()) != -1){ out.print((char)ch); } out.println("- - - - - Text Extraction - - - - - -"); PdfTextExtractor extractor = new PdfTextExtractor(reader); String extractedText = extractor.getTextFromPage(pageNum); if (extractedText.length() != 0) out.println(extractedText); else out.println("No text found on page " + pageNum); out.println(); } /** * Writes information about each page in a PDF file to the specified output stream. * @since 2.1.5 * @param pdfFile a File instance referring to a PDF file * @param out the output stream to send the content to * @throws IOException */ static public void listContentStream(File pdfFile, PrintWriter out) throws IOException { PdfReader reader = new PdfReader(pdfFile.getCanonicalPath()); int maxPageNum = reader.getNumberOfPages(); for (int pageNum = 1; pageNum <= maxPageNum; pageNum++){ listContentStreamForPage(reader, pageNum, out); } } /** * Writes information about the specified page in a PDF file to the specified output stream. * @since 2.1.5 * @param pdfFile a File instance referring to a PDF file * @param pageNum the page number to read * @param out the output stream to send the content to * @throws IOException */ static public void listContentStream(File pdfFile, int pageNum, PrintWriter out) throws IOException { PdfReader reader = new PdfReader(pdfFile.getCanonicalPath()); listContentStreamForPage(reader, pageNum, out); } /** * Writes information about each page in a PDF file to the specified file, or System.out. * @param args */ public static void main(String[] args) { try{ if (args.length < 1 || args.length > 3){ System.out.println("Usage: PdfContentReaderTool [|stdout] []"); return; } PrintWriter writer = new PrintWriter(System.out); if (args.length >= 2){ if (args[1].compareToIgnoreCase("stdout") != 0){ System.out.println("Writing PDF content to " + args[1]); writer = new PrintWriter(new FileOutputStream(new File(args[1]))); } } int pageNum = -1; if (args.length >= 3){ pageNum = Integer.parseInt(args[2]); } if (pageNum == -1){ listContentStream(new File(args[0]), writer); } else { listContentStream(new File(args[0]), pageNum, writer); } writer.flush(); if (args.length >= 2){ writer.close(); System.out.println("Finished writing content to " + args[1]); } } catch (Exception e){ e.printStackTrace(System.err); } } } src/core/com/lowagie/text/pdf/parser/PdfContentStreamProcessor.java100644 0 0 51424 11224570760 23177 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Stack; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.pdf.CMapAwareDocumentFont; import com.lowagie.text.pdf.DocumentFont; import com.lowagie.text.pdf.PRIndirectReference; import com.lowagie.text.pdf.PRTokeniser; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfContentParser; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfLiteral; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNumber; import com.lowagie.text.pdf.PdfString; /** * Processor for a PDF content Stream. * @since 2.1.4 */ public abstract class PdfContentStreamProcessor { /** A map with all supported operators operators (PDF syntax). */ private Map operators; /** Resources for the content stream. */ private PdfDictionary resources; /** Stack keeping track of the graphics state. */ private Stack gsStack = new Stack(); /** Text matrix. */ private Matrix textMatrix; /** Text line matrix. */ private Matrix textLineMatrix; /** * Creates a new PDF Content Stream Processor. */ public PdfContentStreamProcessor() { populateOperators(); reset(); } /** * Loads all the supported graphics and text state operators in a map. */ private void populateOperators(){ operators = new HashMap(); operators.put("q", new PushGraphicsState()); operators.put("Q", new PopGraphicsState()); operators.put("cm", new ModifyCurrentTransformationMatrix()); operators.put("gs", new ProcessGraphicsStateResource()); operators.put("Tc", new SetTextCharacterSpacing()); operators.put("Tw", new SetTextWordSpacing()); operators.put("Tz", new SetTextHorizontalScaling()); operators.put("TL", new SetTextLeading()); operators.put("Tf", new SetTextFont()); operators.put("Tr", new SetTextRenderMode()); operators.put("Ts", new SetTextRise()); operators.put("BT", new BeginText()); operators.put("ET", new EndText()); operators.put("Td", new TextMoveStartNextLine()); operators.put("TD", new TextMoveStartNextLineWithLeading()); operators.put("Tm", new TextSetTextMatrix()); operators.put("T*", new TextMoveNextLine()); operators.put("Tj", new ShowText()); operators.put("'", new MoveNextLineAndShowText()); operators.put("\"", new MoveNextLineAndShowTextWithSpacing()); operators.put("TJ", new ShowTextArray()); } /** * Resets the graphics state stack, matrices and resources. */ public void reset(){ gsStack.removeAllElements(); gsStack.add(new GraphicsState()); textMatrix = null; textLineMatrix = null; resources = null; } /** * Returns the current graphics state. * @return the graphics state */ public GraphicsState gs(){ return (GraphicsState)gsStack.peek(); } /** * Returns the current text matrix. * @return the text matrix * @since 2.1.5 */ public Matrix getCurrentTextMatrix(){ return textMatrix; } /** * Returns the current line matrix. * @return the line matrix * @since 2.1.5 */ public Matrix getCurrentTextLineMatrix(){ return textLineMatrix; } /** * Invokes an operator. * @param operator the PDF Syntax of the operator * @param operands a list with operands */ public void invokeOperator(PdfLiteral operator, ArrayList operands){ ContentOperator op = (ContentOperator)operators.get(operator.toString()); if (op == null){ //System.out.println("Skipping operator " + operator); return; } op.invoke(this, operator, operands); } /** * Decodes a PdfString (which will contain glyph ids encoded in the font's encoding) * based on the active font, and determine the unicode equivalent * @param in the String that needs to be encoded * @return the encoded String * @since 2.1.7 */ private String decode(PdfString in){ byte[] bytes = in.getBytes(); return gs().font.decode(bytes, 0, bytes.length); } /** * Displays text. * @param text the text that needs to be displayed * @param nextTextMatrix a text matrix */ abstract public void displayText(String text, Matrix nextTextMatrix); /** * Gets the width of a String. * @param string the string that needs measuring * @param tj text adjustment * @return the width of a String */ public float getStringWidth(String string, float tj){ DocumentFont font = gs().font; char[] chars = string.toCharArray(); float totalWidth = 0; for (int i = 0; i < chars.length; i++) { float w = font.getWidth(chars[i]) / 1000.0f; float wordSpacing = chars[i] == 32 ? gs().wordSpacing : 0f; totalWidth += ((w - tj/1000f) * gs().fontSize + gs().characterSpacing + wordSpacing) * gs().horizontalScaling; } return totalWidth; } /** * Displays text. * @param string the text to display * @param tj the text adjustment */ public void displayPdfString(PdfString string, float tj){ String unicode = decode(string); float width = getStringWidth(unicode, tj); // this is width in unscaled units - we have to normalize by the Tm scaling Matrix nextTextMatrix = new Matrix(width, 0).multiply(textMatrix); displayText(unicode, nextTextMatrix); textMatrix = nextTextMatrix; } /** * Processes PDF syntax * @param contentBytes the bytes of a content stream * @param resources the resources that come with the content stream */ public void processContent(byte[] contentBytes, PdfDictionary resources){ reset(); this.resources = resources; try { PdfContentParser ps = new PdfContentParser(new PRTokeniser(contentBytes)); ArrayList operands = new ArrayList(); while (ps.parse(operands).size() > 0){ PdfLiteral operator = (PdfLiteral)operands.get(operands.size()-1); invokeOperator(operator, operands); } } catch (Exception e) { throw new ExceptionConverter(e); } } /** * A content operator implementation (TJ). */ private static class ShowTextArray implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfArray array = (PdfArray)operands.get(0); float tj = 0; for (Iterator i = array.listIterator(); i.hasNext(); ) { Object entryObj = i.next(); if (entryObj instanceof PdfString){ processor.displayPdfString((PdfString)entryObj, tj); tj = 0; } else { tj = ((PdfNumber)entryObj).floatValue(); } } } } /** * A content operator implementation ("). */ private static class MoveNextLineAndShowTextWithSpacing implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber aw = (PdfNumber)operands.get(0); PdfNumber ac = (PdfNumber)operands.get(1); PdfString string = (PdfString)operands.get(2); ArrayList twOperands = new ArrayList(1); twOperands.add(0, aw); processor.invokeOperator(new PdfLiteral("Tw"), twOperands); ArrayList tcOperands = new ArrayList(1); tcOperands.add(0, ac); processor.invokeOperator(new PdfLiteral("Tc"), tcOperands); ArrayList tickOperands = new ArrayList(1); tickOperands.add(0, string); processor.invokeOperator(new PdfLiteral("'"), tickOperands); } } /** * A content operator implementation ('). */ private static class MoveNextLineAndShowText implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { processor.invokeOperator(new PdfLiteral("T*"), new ArrayList(0)); processor.invokeOperator(new PdfLiteral("Tj"), operands); } } /** * A content operator implementation (Tj). */ private static class ShowText implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfString string = (PdfString)operands.get(0); processor.displayPdfString(string, 0); } } /** * A content operator implementation (T*). */ private static class TextMoveNextLine implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { ArrayList tdoperands = new ArrayList(2); tdoperands.add(0, new PdfNumber(0)); tdoperands.add(1, new PdfNumber(processor.gs().leading)); processor.invokeOperator(new PdfLiteral("Td"), tdoperands); } } /** * A content operator implementation (Tm). */ private static class TextSetTextMatrix implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { float a = ((PdfNumber)operands.get(0)).floatValue(); float b = ((PdfNumber)operands.get(1)).floatValue(); float c = ((PdfNumber)operands.get(2)).floatValue(); float d = ((PdfNumber)operands.get(3)).floatValue(); float e = ((PdfNumber)operands.get(4)).floatValue(); float f = ((PdfNumber)operands.get(5)).floatValue(); processor.textLineMatrix = new Matrix(a, b, c, d, e, f); processor.textMatrix = processor.textLineMatrix; } } /** * A content operator implementation (TD). */ private static class TextMoveStartNextLineWithLeading implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { float ty = ((PdfNumber)operands.get(1)).floatValue(); ArrayList tlOperands = new ArrayList(1); tlOperands.add(0, new PdfNumber(-ty)); processor.invokeOperator(new PdfLiteral("TL"), tlOperands); processor.invokeOperator(new PdfLiteral("Td"), operands); } } /** * A content operator implementation (Td). */ private static class TextMoveStartNextLine implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { float tx = ((PdfNumber)operands.get(0)).floatValue(); float ty = ((PdfNumber)operands.get(1)).floatValue(); Matrix translationMatrix = new Matrix(tx, ty); processor.textMatrix = translationMatrix.multiply(processor.textLineMatrix); processor.textLineMatrix = processor.textMatrix; } } /** * A content operator implementation (Tf). */ private static class SetTextFont implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfName fontResourceName = (PdfName)operands.get(0); float size = ((PdfNumber)operands.get(1)).floatValue(); PdfDictionary fontsDictionary = processor.resources.getAsDict(PdfName.FONT); CMapAwareDocumentFont font = new CMapAwareDocumentFont((PRIndirectReference)fontsDictionary.get(fontResourceName)); processor.gs().font = font; processor.gs().fontSize = size; } } /** * A content operator implementation (Tr). */ private static class SetTextRenderMode implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber render = (PdfNumber)operands.get(0); processor.gs().renderMode = render.intValue(); } } /** * A content operator implementation (Ts). */ private static class SetTextRise implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber rise = (PdfNumber)operands.get(0); processor.gs().rise = rise.floatValue(); } } /** * A content operator implementation (TL). */ private static class SetTextLeading implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber leading = (PdfNumber)operands.get(0); processor.gs().leading = leading.floatValue(); } } /** * A content operator implementation (Tz). */ private static class SetTextHorizontalScaling implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber scale = (PdfNumber)operands.get(0); processor.gs().horizontalScaling = scale.floatValue(); } } /** * A content operator implementation (Tc). */ private static class SetTextCharacterSpacing implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber charSpace = (PdfNumber)operands.get(0); processor.gs().characterSpacing = charSpace.floatValue(); } } /** * A content operator implementation (Tw). */ private static class SetTextWordSpacing implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfNumber wordSpace = (PdfNumber)operands.get(0); processor.gs().wordSpacing = wordSpace.floatValue(); } } /** * A content operator implementation (gs). */ private static class ProcessGraphicsStateResource implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { PdfName dictionaryName = (PdfName)operands.get(0); PdfDictionary extGState = processor.resources.getAsDict(PdfName.EXTGSTATE); if (extGState == null) throw new IllegalArgumentException("Resources do not contain ExtGState entry. Unable to process operator " + operator); PdfDictionary gsDic = extGState.getAsDict(dictionaryName); if (gsDic == null) throw new IllegalArgumentException(dictionaryName + " is an unknown graphics state dictionary"); // at this point, all we care about is the FONT entry in the GS dictionary PdfArray fontParameter = gsDic.getAsArray(PdfName.FONT); if (fontParameter != null){ CMapAwareDocumentFont font = new CMapAwareDocumentFont((PRIndirectReference)fontParameter.getPdfObject(0)); float size = fontParameter.getAsNumber(1).floatValue(); processor.gs().font = font; processor.gs().fontSize = size; } } } /** * A content operator implementation (q). */ private static class PushGraphicsState implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { GraphicsState gs = (GraphicsState) processor.gsStack.peek(); GraphicsState copy = new GraphicsState(gs); processor.gsStack.push(copy); } } /** * A content operator implementation (cm). */ private static class ModifyCurrentTransformationMatrix implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { float a = ((PdfNumber)operands.get(0)).floatValue(); float b = ((PdfNumber)operands.get(1)).floatValue(); float c = ((PdfNumber)operands.get(2)).floatValue(); float d = ((PdfNumber)operands.get(3)).floatValue(); float e = ((PdfNumber)operands.get(4)).floatValue(); float f = ((PdfNumber)operands.get(5)).floatValue(); Matrix matrix = new Matrix(a, b, c, d, e, f); GraphicsState gs = (GraphicsState)processor.gsStack.peek(); gs.ctm = gs.ctm.multiply(matrix); } } /** * A content operator implementation (Q). */ private static class PopGraphicsState implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { processor.gsStack.pop(); } } /** * A content operator implementation (BT). */ private static class BeginText implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { processor.textMatrix = new Matrix(); processor.textLineMatrix = processor.textMatrix; } } /** * A content operator implementation (ET). */ private static class EndText implements ContentOperator{ public void invoke(PdfContentStreamProcessor processor, PdfLiteral operator, ArrayList operands) { processor.textMatrix = null; processor.textLineMatrix = null; } } } src/core/com/lowagie/text/pdf/parser/PdfTextExtractor.java100644 0 0 10446 11154165265 21332 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; import java.io.IOException; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * Extracts text from a PDF file. * @since 2.1.4 */ public class PdfTextExtractor { /** The PdfReader that holds the PDF file. */ private final PdfReader reader; /** The processor that will extract the text. */ private final SimpleTextExtractingPdfContentStreamProcessor extractionProcessor; /** * Creates a new Text Extractor object. * @param reader the reader with the PDF */ public PdfTextExtractor(PdfReader reader) { this.reader = reader; extractionProcessor = new SimpleTextExtractingPdfContentStreamProcessor(); } /** * Gets the content stream of a page. * @param pageNum the page number of page you want get the content stream from * @return a byte array with the content stream of a page * @throws IOException */ private byte[] getContentBytesForPage(int pageNum) throws IOException { RandomAccessFileOrArray f = reader.getSafeFile(); byte[] contentBytes = reader.getPageContent(pageNum, f); f.close(); return contentBytes; } /** * Gets the text from a page. * @param page the page number of the page * @return a String with the content as plain text (without PDF syntax) * @throws IOException */ public String getTextFromPage(int page) throws IOException { PdfDictionary pageDic = reader.getPageN(page); PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES); extractionProcessor.processContent(getContentBytesForPage(page), resourcesDic); return extractionProcessor.getResultantText(); } } src/core/com/lowagie/text/pdf/parser/SimpleTextExtractingPdfContentStreamProcessor.java100644 0 0 13140 11154165265 27242 0ustar 0 0 /* * Copyright 2008 by Kevin Day. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2008 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.pdf.parser; /** * A simple text extraction processor. * @since 2.1.4 */ public class SimpleTextExtractingPdfContentStreamProcessor extends PdfContentStreamProcessor { /** keeps track of a text matrix. */ Matrix lastTextLineMatrix = null; /** keeps track of a text matrix. */ Matrix lastEndingTextMatrix = null; /** The StringBuffer used to write the resulting String. */ StringBuffer result = null; /** * Creates a new text extraction processor. */ public SimpleTextExtractingPdfContentStreamProcessor() { } public void reset() { super.reset(); lastTextLineMatrix = null; lastEndingTextMatrix = null; result = new StringBuffer(); } /** * Returns the result so far. * @return a String with the resulting text. */ public String getResultantText(){ return result.toString(); } /** * Writes text to the result. * @param text The text that needs to be displayed * @param endingTextMatrix a text matrix * @see com.lowagie.text.pdf.parser.PdfContentStreamProcessor#displayText(java.lang.String, com.lowagie.text.pdf.parser.Matrix) */ public void displayText(String text, Matrix endingTextMatrix){ boolean hardReturn = false; if (lastTextLineMatrix != null && lastTextLineMatrix.get(Matrix.I32) != getCurrentTextLineMatrix().get(Matrix.I32)){ //if (!textLineMatrix.equals(lastTextLineMatrix)){ hardReturn = true; } float currentX = getCurrentTextMatrix().get(Matrix.I31); if (hardReturn){ //System.out.println(""); result.append('\n'); } else if (lastEndingTextMatrix != null){ float lastEndX = lastEndingTextMatrix.get(Matrix.I31); //System.out.println("Displaying '" + text + "' :: lastX + lastWidth = " + lastEndX + " =?= currentX = " + currentX + " :: Delta is " + (currentX - lastEndX)); float spaceGlyphWidth = gs().font.getWidth(' ')/1000f; float spaceWidth = (spaceGlyphWidth * gs().fontSize + gs().characterSpacing + gs().wordSpacing) * gs().horizontalScaling; // this is unscaled!! Matrix scaled = new Matrix(spaceWidth, 0).multiply(getCurrentTextMatrix()); float scaledSpaceWidth = scaled.get(Matrix.I31) - getCurrentTextMatrix().get(Matrix.I31); if (currentX - lastEndX > scaledSpaceWidth/2f ){ //System.out.println(" lastEndX=" + lastEndX + ", currentX=" + currentX + ", spaceWidth=" + spaceWidth); result.append(' '); } } else { //System.out.println("Displaying first string of content '" + text + "' :: currentX = " + currentX); } //System.out.println("After displaying '" + text + "' :: Start at " + currentX + " end at " + endingTextMatrix.get(Matrix.I31)); result.append(text); lastTextLineMatrix = getCurrentTextLineMatrix(); lastEndingTextMatrix = endingTextMatrix; } } src/core/com/lowagie/text/xml/SAXiTextHandler.java100644 0 0 73167 11036112744 17564 0ustar 0 0 /* * $Id: SAXiTextHandler.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.EmptyStackException; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import java.util.Stack; import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; import com.lowagie.text.Anchor; import com.lowagie.text.Annotation; import com.lowagie.text.BadElementException; import com.lowagie.text.Cell; import com.lowagie.text.Chapter; import com.lowagie.text.Chunk; import com.lowagie.text.DocListener; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.ElementTags; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Font; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.Meta; import com.lowagie.text.PageSize; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; import com.lowagie.text.Section; import com.lowagie.text.Table; import com.lowagie.text.TextElementArray; import com.lowagie.text.factories.ElementFactory; import com.lowagie.text.html.HtmlTagMap; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.draw.LineSeparator; import com.lowagie.text.xml.simpleparser.EntitiesToSymbol; /** * This class is a Handler that controls the iText XML to PDF conversion. * Subclass it, if you want to change the way iText translates XML to PDF. */ public class SAXiTextHandler extends DefaultHandler { /** This is the resulting document. */ protected DocListener document; /** * This is a Stack of objects, waiting to be added to the * document. */ protected Stack stack; /** Counts the number of chapters in this document. */ protected int chapters = 0; /** This is the current chunk to which characters can be added. */ protected Chunk currentChunk = null; /** This is the current chunk to which characters can be added. */ protected boolean ignore = false; /** * This is a flag that can be set, if you want to open and close the * Document-object yourself. */ protected boolean controlOpenClose = true; /** current margin of a page. */ float topMargin = 36; /** current margin of a page. */ float rightMargin = 36; /** current margin of a page. */ float leftMargin = 36; /** current margin of a page. */ float bottomMargin = 36; /** * @param document */ public SAXiTextHandler(DocListener document) { super(); this.document = document; stack = new Stack(); } /** This hashmap contains all the custom keys and peers. */ protected HashMap myTags; /** * @param document * @param myTags */ public SAXiTextHandler(DocListener document, HtmlTagMap myTags) { this(document); this.myTags = myTags; } /** * @param document * @param myTags * @param bf */ public SAXiTextHandler(DocListener document, HtmlTagMap myTags, BaseFont bf){ this(document, myTags); this.bf = bf; } /** * @param document * @param myTags */ public SAXiTextHandler(DocListener document, HashMap myTags) { this(document); this.myTags = myTags; } /** * Sets the parameter that allows you to enable/disable the control over the * Document.open() and Document.close() method. *

      * If you set this parameter to true (= default), the parser will open the * Document object when the start-root-tag is encountered and close it when * the end-root-tag is met. If you set it to false, you have to open and * close the Document object yourself. * * @param controlOpenClose * set this to false if you plan to open/close the Document * yourself */ public void setControlOpenClose(boolean controlOpenClose) { this.controlOpenClose = controlOpenClose; } /** * This method gets called when a start tag is encountered. * * @param uri * the Uniform Resource Identifier * @param lname * the local name (without prefix), or the empty string if * Namespace processing is not being performed. * @param name * the name of the tag that is encountered * @param attrs * the list of attributes */ public void startElement(String uri, String lname, String name, Attributes attrs) { Properties attributes = new Properties(); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String attribute = attrs.getQName(i); attributes.setProperty(attribute, attrs.getValue(i)); } } handleStartingTags(name, attributes); } /** * This method deals with the starting tags. * * @param name * the name of the tag * @param attributes * the list of attributes */ public void handleStartingTags(String name, Properties attributes) { // System.err.println("Start: " + name); if (ignore || ElementTags.IGNORE.equals(name)) { ignore = true; return; } // maybe there is some meaningful data that wasn't between tags if (currentChunk != null) { TextElementArray current; try { current = (TextElementArray) stack.pop(); } catch (EmptyStackException ese) { if (bf == null) { current = new Paragraph("", new Font()); } else { current = new Paragraph("", new Font(this.bf)); } } current.add(currentChunk); stack.push(current); currentChunk = null; } // chunks if (ElementTags.CHUNK.equals(name)) { currentChunk = ElementFactory.getChunk(attributes); if (bf != null) { currentChunk.setFont(new Font(this.bf)); } return; } // symbols if (ElementTags.ENTITY.equals(name)) { Font f = new Font(); if (currentChunk != null) { handleEndingTags(ElementTags.CHUNK); f = currentChunk.getFont(); } currentChunk = EntitiesToSymbol.get(attributes.getProperty(ElementTags.ID), f); return; } // phrases if (ElementTags.PHRASE.equals(name)) { stack.push(ElementFactory.getPhrase(attributes)); return; } // anchors if (ElementTags.ANCHOR.equals(name)) { stack.push(ElementFactory.getAnchor(attributes)); return; } // paragraphs and titles if (ElementTags.PARAGRAPH.equals(name) || ElementTags.TITLE.equals(name)) { stack.push(ElementFactory.getParagraph(attributes)); return; } // lists if (ElementTags.LIST.equals(name)) { stack.push(ElementFactory.getList(attributes)); return; } // listitems if (ElementTags.LISTITEM.equals(name)) { stack.push(ElementFactory.getListItem(attributes)); return; } // cells if (ElementTags.CELL.equals(name)) { stack.push(ElementFactory.getCell(attributes)); return; } // tables if (ElementTags.TABLE.equals(name)) { Table table = ElementFactory.getTable(attributes); float widths[] = table.getProportionalWidths(); for (int i = 0; i < widths.length; i++) { if (widths[i] == 0) { widths[i] = 100.0f / widths.length; } } try { table.setWidths(widths); } catch (BadElementException bee) { // this shouldn't happen throw new ExceptionConverter(bee); } stack.push(table); return; } // sections if (ElementTags.SECTION.equals(name)) { Element previous = (Element) stack.pop(); Section section; try { section = ElementFactory.getSection((Section) previous, attributes); } catch (ClassCastException cce) { throw new ExceptionConverter(cce); } stack.push(previous); stack.push(section); return; } // chapters if (ElementTags.CHAPTER.equals(name)) { stack.push(ElementFactory.getChapter(attributes)); return; } // images if (ElementTags.IMAGE.equals(name)) { try { Image img = ElementFactory.getImage(attributes); try { addImage(img); return; } catch (EmptyStackException ese) { // if there is no element on the stack, the Image is added // to the document try { document.add(img); } catch (DocumentException de) { throw new ExceptionConverter(de); } return; } } catch (Exception e) { throw new ExceptionConverter(e); } } // annotations if (ElementTags.ANNOTATION.equals(name)) { Annotation annotation = ElementFactory.getAnnotation(attributes); TextElementArray current; try { try { current = (TextElementArray) stack.pop(); try { current.add(annotation); } catch (Exception e) { document.add(annotation); } stack.push(current); } catch (EmptyStackException ese) { document.add(annotation); } return; } catch (DocumentException de) { throw new ExceptionConverter(de); } } // newlines if (isNewline(name)) { TextElementArray current; try { current = (TextElementArray) stack.pop(); current.add(Chunk.NEWLINE); stack.push(current); } catch (EmptyStackException ese) { if (currentChunk == null) { try { document.add(Chunk.NEWLINE); } catch (DocumentException de) { throw new ExceptionConverter(de); } } else { currentChunk.append("\n"); } } return; } // newpage if (isNewpage(name)) { TextElementArray current; try { current = (TextElementArray) stack.pop(); Chunk newPage = new Chunk(""); newPage.setNewPage(); if (bf != null) { newPage.setFont(new Font(this.bf)); } current.add(newPage); stack.push(current); } catch (EmptyStackException ese) { document.newPage(); } return; } if (ElementTags.HORIZONTALRULE.equals(name)) { TextElementArray current; LineSeparator hr = new LineSeparator(1.0f, 100.0f, null, Element.ALIGN_CENTER, 0); try { current = (TextElementArray) stack.pop(); current.add(hr); stack.push(current); } catch (EmptyStackException ese) { try { document.add(hr); } catch (DocumentException de) { throw new ExceptionConverter(de); } } return; } // documentroot if (isDocumentRoot(name)) { String key; String value; // pagesize and orientation specific code suggested by Samuel Gabriel // Updated by Ricardo Coutinho. Only use if set in html! Rectangle pageSize = null; String orientation = null; for (Iterator i = attributes.keySet().iterator(); i.hasNext();) { key = (String) i.next(); value = attributes.getProperty(key); try { // margin specific code suggested by Reza Nasiri if (ElementTags.LEFT.equalsIgnoreCase(key)) leftMargin = Float.parseFloat(value + "f"); if (ElementTags.RIGHT.equalsIgnoreCase(key)) rightMargin = Float.parseFloat(value + "f"); if (ElementTags.TOP.equalsIgnoreCase(key)) topMargin = Float.parseFloat(value + "f"); if (ElementTags.BOTTOM.equalsIgnoreCase(key)) bottomMargin = Float.parseFloat(value + "f"); } catch (Exception ex) { throw new ExceptionConverter(ex); } if (ElementTags.PAGE_SIZE.equals(key)) { try { String pageSizeName = value; Field pageSizeField = PageSize.class .getField(pageSizeName); pageSize = (Rectangle) pageSizeField.get(null); } catch (Exception ex) { throw new ExceptionConverter(ex); } } else if (ElementTags.ORIENTATION.equals(key)) { try { if ("landscape".equals(value)) { orientation = "landscape"; } } catch (Exception ex) { throw new ExceptionConverter(ex); } } else { try { document.add(new Meta(key, value)); } catch (DocumentException de) { throw new ExceptionConverter(de); } } } if(pageSize != null) { if ("landscape".equals(orientation)) { pageSize = pageSize.rotate(); } document.setPageSize(pageSize); } document.setMargins(leftMargin, rightMargin, topMargin, bottomMargin); if (controlOpenClose) document.open(); } } protected void addImage(Image img) throws EmptyStackException { // if there is an element on the stack... Object current = stack.pop(); // ...and it's a Chapter or a Section, the Image can be // added directly if (current instanceof Chapter || current instanceof Section || current instanceof Cell) { ((TextElementArray) current).add(img); stack.push(current); return; } // ...if not, we need to to a lot of stuff else { Stack newStack = new Stack(); while (!(current instanceof Chapter || current instanceof Section || current instanceof Cell)) { newStack.push(current); if (current instanceof Anchor) { img.setAnnotation(new Annotation(0, 0, 0, 0, ((Anchor) current).getReference())); } current = stack.pop(); } ((TextElementArray) current).add(img); stack.push(current); while (!newStack.empty()) { stack.push(newStack.pop()); } return; } } /** * This method gets called when ignorable white space encountered. * * @param ch * an array of characters * @param start * the start position in the array * @param length * the number of characters to read from the array */ public void ignorableWhitespace(char[] ch, int start, int length) { characters(ch, start, length); } /** * This method gets called when characters are encountered. * * @param ch * an array of characters * @param start * the start position in the array * @param length * the number of characters to read from the array */ public void characters(char[] ch, int start, int length) { if (ignore) return; String content = new String(ch, start, length); // System.err.println("'" + content + "'"); if (content.trim().length() == 0 && content.indexOf(' ') < 0) { return; } StringBuffer buf = new StringBuffer(); int len = content.length(); char character; boolean newline = false; for (int i = 0; i < len; i++) { switch (character = content.charAt(i)) { case ' ': if (!newline) { buf.append(character); } break; case '\n': if (i > 0) { newline = true; buf.append(' '); } break; case '\r': break; case '\t': break; default: newline = false; buf.append(character); } } if (currentChunk == null) { if (bf == null) { currentChunk = new Chunk(buf.toString()); } else { currentChunk = new Chunk(buf.toString(), new Font(this.bf)); } } else { currentChunk.append(buf.toString()); } } private BaseFont bf = null; /** * Sets the font that has to be used. * @param bf */ public void setBaseFont(BaseFont bf) { this.bf = bf; } /** * This method gets called when an end tag is encountered. * * @param uri * the Uniform Resource Identifier * @param lname * the local name (without prefix), or the empty string if * Namespace processing is not being performed. * @param name * the name of the tag that ends */ public void endElement(String uri, String lname, String name) { handleEndingTags(name); } /** * This method deals with the starting tags. * * @param name * the name of the tag */ public void handleEndingTags(String name) { // System.err.println("Stop: " + name); if (ElementTags.IGNORE.equals(name)) { ignore = false; return; } if (ignore) return; // tags that don't have any content if (isNewpage(name) || ElementTags.ANNOTATION.equals(name) || ElementTags.IMAGE.equals(name) || isNewline(name)) { return; } try { // titles of sections and chapters if (ElementTags.TITLE.equals(name)) { Paragraph current = (Paragraph) stack.pop(); if (currentChunk != null) { current.add(currentChunk); currentChunk = null; } Section previous = (Section) stack.pop(); previous.setTitle(current); stack.push(previous); return; } // all other endtags if (currentChunk != null) { TextElementArray current; try { current = (TextElementArray) stack.pop(); } catch (EmptyStackException ese) { current = new Paragraph(); } current.add(currentChunk); stack.push(current); currentChunk = null; } // chunks if (ElementTags.CHUNK.equals(name)) { return; } // phrases, anchors, lists, tables if (ElementTags.PHRASE.equals(name) || ElementTags.ANCHOR.equals(name) || ElementTags.LIST.equals(name) || ElementTags.PARAGRAPH.equals(name)) { Element current = (Element) stack.pop(); try { TextElementArray previous = (TextElementArray) stack.pop(); previous.add(current); stack.push(previous); } catch (EmptyStackException ese) { document.add(current); } return; } // listitems if (ElementTags.LISTITEM.equals(name)) { ListItem listItem = (ListItem) stack.pop(); List list = (List) stack.pop(); list.add(listItem); stack.push(list); } // tables if (ElementTags.TABLE.equals(name)) { Table table = (Table) stack.pop(); try { TextElementArray previous = (TextElementArray) stack.pop(); previous.add(table); stack.push(previous); } catch (EmptyStackException ese) { document.add(table); } return; } // rows if (ElementTags.ROW.equals(name)) { ArrayList cells = new ArrayList(); int columns = 0; Table table; Cell cell; while (true) { Element element = (Element) stack.pop(); if (element.type() == Element.CELL) { cell = (Cell) element; columns += cell.getColspan(); cells.add(cell); } else { table = (Table) element; break; } } if (table.getColumns() < columns) { table.addColumns(columns - table.getColumns()); } Collections.reverse(cells); String width; float[] cellWidths = new float[columns]; boolean[] cellNulls = new boolean[columns]; for (int i = 0; i < columns; i++) { cellWidths[i] = 0; cellNulls[i] = true; } float total = 0; int j = 0; for (Iterator i = cells.iterator(); i.hasNext();) { cell = (Cell) i.next(); width = cell.getWidthAsString(); if (cell.getWidth() == 0) { if (cell.getColspan() == 1 && cellWidths[j] == 0) { try { cellWidths[j] = 100f / columns; total += cellWidths[j]; } catch (Exception e) { // empty on purpose } } else if (cell.getColspan() == 1) { cellNulls[j] = false; } } else if (cell.getColspan() == 1 && width.endsWith("%")) { try { cellWidths[j] = Float.parseFloat( width.substring(0, width.length() - 1) + "f"); total += cellWidths[j]; } catch (Exception e) { // empty on purpose } } j += cell.getColspan(); table.addCell(cell); } float widths[] = table.getProportionalWidths(); if (widths.length == columns) { float left = 0.0f; for (int i = 0; i < columns; i++) { if (cellNulls[i] && widths[i] != 0) { left += widths[i]; cellWidths[i] = widths[i]; } } if (100.0 >= total) { for (int i = 0; i < widths.length; i++) { if (cellWidths[i] == 0 && widths[i] != 0) { cellWidths[i] = (widths[i] / left) * (100.0f - total); } } } table.setWidths(cellWidths); } stack.push(table); } // cells if (ElementTags.CELL.equals(name)) { return; } // sections if (ElementTags.SECTION.equals(name)) { stack.pop(); return; } // chapters if (ElementTags.CHAPTER.equals(name)) { document.add((Element) stack.pop()); return; } // the documentroot if (isDocumentRoot(name)) { try { while (true) { Element element = (Element) stack.pop(); try { TextElementArray previous = (TextElementArray) stack .pop(); previous.add(element); stack.push(previous); } catch (EmptyStackException es) { document.add(element); } } } catch (EmptyStackException ese) { // empty on purpose } if (controlOpenClose) document.close(); return; } } catch (DocumentException de) { throw new ExceptionConverter(de); } } /** * Checks if a certain tag corresponds with the newpage-tag. * * @param tag * a presumed tagname * @return true or false */ private boolean isNewpage(String tag) { return ElementTags.NEWPAGE.equals(tag); } /** * Checks if a certain tag corresponds with the newpage-tag. * * @param tag * a presumed tagname * @return true or false */ private boolean isNewline(String tag) { return ElementTags.NEWLINE.equals(tag); } /** * Checks if a certain tag corresponds with the roottag. * * @param tag * a presumed tagname * @return true if tag equals itext * ,false otherwise. */ protected boolean isDocumentRoot(String tag) { return ElementTags.ITEXT.equals(tag); } }src/core/com/lowagie/text/xml/SAXmyHandler.java100644 0 0 11266 11012562265 17105 0ustar 0 0 /* * $Id: SAXmyHandler.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml; import java.util.HashMap; import java.util.Properties; import org.xml.sax.Attributes; import com.lowagie.text.DocListener; /** * The Tags-class maps several XHTML-tags to iText-objects. */ public class SAXmyHandler extends SAXiTextHandler { /** * Constructs a new SAXiTextHandler that will translate all the events * triggered by the parser to actions on the Document-object. * * @param document this is the document on which events must be triggered * @param myTags a user defined tagmap */ public SAXmyHandler(DocListener document, HashMap myTags) { super(document, myTags); } /** * This method gets called when a start tag is encountered. * * @param uri the Uniform Resource Identifier * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed. * @param name the name of the tag that is encountered * @param attrs the list of attributes */ public void startElement(String uri, String lname, String name, Attributes attrs) { if (myTags.containsKey(name)) { XmlPeer peer = (XmlPeer) myTags.get(name); handleStartingTags(peer.getTag(), peer.getAttributes(attrs)); } else { Properties attributes = new Properties(); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String attribute = attrs.getQName(i); attributes.setProperty(attribute, attrs.getValue(i)); } } handleStartingTags(name, attributes); } } /** * This method gets called when an end tag is encountered. * * @param uri the Uniform Resource Identifier * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed. * @param name the name of the tag that ends */ public void endElement(String uri, String lname, String name) { if (myTags.containsKey(name)) { XmlPeer peer = (XmlPeer) myTags.get(name); handleEndingTags(peer.getTag()); } else { handleEndingTags(name); } } }src/core/com/lowagie/text/xml/TagMap.java100644 0 0 16534 11012562265 15762 0ustar 0 0 /* * $Id: TagMap.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.HashMap; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.helpers.DefaultHandler; import com.lowagie.text.ExceptionConverter; /** * The Tags-class maps several XHTML-tags to iText-objects. */ public class TagMap extends HashMap { private static final long serialVersionUID = -6809383366554350820L; class AttributeHandler extends DefaultHandler { /** This is a tag */ public static final String TAG = "tag"; /** This is a tag */ public static final String ATTRIBUTE = "attribute"; /** This is an attribute */ public static final String NAME = "name"; /** This is an attribute */ public static final String ALIAS = "alias"; /** This is an attribute */ public static final String VALUE = "value"; /** This is an attribute */ public static final String CONTENT = "content"; /** This is the tagmap using the AttributeHandler */ private HashMap tagMap; /** This is the current peer. */ private XmlPeer currentPeer; /** * Constructs a new SAXiTextHandler that will translate all the events * triggered by the parser to actions on the Document-object. * * @param tagMap A Hashmap containing XmlPeer-objects */ public AttributeHandler(HashMap tagMap) { super(); this.tagMap = tagMap; } /** * This method gets called when a start tag is encountered. * * @param uri the Uniform Resource Identifier * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed. * @param tag the name of the tag that is encountered * @param attrs the list of attributes */ public void startElement(String uri, String lname, String tag, Attributes attrs) { String name = attrs.getValue(NAME); String alias = attrs.getValue(ALIAS); String value = attrs.getValue(VALUE); if (name != null) { if(TAG.equals(tag)) { currentPeer = new XmlPeer(name, alias); } else if (ATTRIBUTE.equals(tag)) { if (alias != null) { currentPeer.addAlias(name, alias); } if (value != null) { currentPeer.addValue(name, value); } } } value = attrs.getValue(CONTENT); if (value != null) { currentPeer.setContent(value); } } /** * This method gets called when ignorable white space encountered. * * @param ch an array of characters * @param start the start position in the array * @param length the number of characters to read from the array */ public void ignorableWhitespace(char[] ch, int start, int length) { // do nothing } /** * This method gets called when characters are encountered. * * @param ch an array of characters * @param start the start position in the array * @param length the number of characters to read from the array */ public void characters(char[] ch, int start, int length) { // do nothing } /** * This method gets called when an end tag is encountered. * * @param uri the Uniform Resource Identifier * @param lname the local name (without prefix), or the empty string if Namespace processing is not being performed. * @param tag the name of the tag that ends */ public void endElement(String uri, String lname, String tag) { if (TAG.equals(tag)) tagMap.put(currentPeer.getAlias(), currentPeer); } } /** * Constructs a TagMap * @param tagfile the path to an XML file with the tagmap */ public TagMap(String tagfile) { super(); try { init(TagMap.class.getClassLoader().getResourceAsStream(tagfile)); }catch(Exception e) { try { init(new FileInputStream(tagfile)); } catch (FileNotFoundException fnfe) { throw new ExceptionConverter(fnfe); } } } /** * Constructs a TagMap. * @param in An InputStream with the tagmap xml */ public TagMap(InputStream in) { super(); init(in); } protected void init(InputStream in) { try { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(new InputSource(in), new AttributeHandler(this)); } catch(Exception e) { throw new ExceptionConverter(e); } } } src/core/com/lowagie/text/xml/XmlDomWriter.java100644 0 0 27117 11000354017 17174 0ustar 0 0 /* * Copyright 1999-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.xml; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * * @author psoares */ public class XmlDomWriter { /** Print writer. */ protected PrintWriter fOut; /** Canonical output. */ protected boolean fCanonical; /** Processing XML 1.1 document. */ protected boolean fXML11; // // Constructors // /** Default constructor. */ public XmlDomWriter() { } // () public XmlDomWriter(boolean canonical) { fCanonical = canonical; } // (boolean) // // Public methods // /** Sets whether output is canonical. */ public void setCanonical(boolean canonical) { fCanonical = canonical; } // setCanonical(boolean) /** Sets the output stream for printing. */ public void setOutput(OutputStream stream, String encoding) throws UnsupportedEncodingException { if (encoding == null) { encoding = "UTF8"; } java.io.Writer writer = new OutputStreamWriter(stream, encoding); fOut = new PrintWriter(writer); } // setOutput(OutputStream,String) /** Sets the output writer. */ public void setOutput(java.io.Writer writer) { fOut = writer instanceof PrintWriter ? (PrintWriter)writer : new PrintWriter(writer); } // setOutput(java.io.Writer) /** Writes the specified node, recursively. */ public void write(Node node) { // is there anything to do? if (node == null) { return; } short type = node.getNodeType(); switch (type) { case Node.DOCUMENT_NODE: { Document document = (Document)node; fXML11 = false; //"1.1".equals(getVersion(document)); if (!fCanonical) { if (fXML11) { fOut.println(""); } else { fOut.println(""); } fOut.flush(); write(document.getDoctype()); } write(document.getDocumentElement()); break; } case Node.DOCUMENT_TYPE_NODE: { DocumentType doctype = (DocumentType)node; fOut.print("'); break; } case Node.ELEMENT_NODE: { fOut.print('<'); fOut.print(node.getNodeName()); Attr attrs[] = sortAttributes(node.getAttributes()); for (int i = 0; i < attrs.length; i++) { Attr attr = attrs[i]; fOut.print(' '); fOut.print(attr.getNodeName()); fOut.print("=\""); normalizeAndPrint(attr.getNodeValue(), true); fOut.print('"'); } fOut.print('>'); fOut.flush(); Node child = node.getFirstChild(); while (child != null) { write(child); child = child.getNextSibling(); } break; } case Node.ENTITY_REFERENCE_NODE: { if (fCanonical) { Node child = node.getFirstChild(); while (child != null) { write(child); child = child.getNextSibling(); } } else { fOut.print('&'); fOut.print(node.getNodeName()); fOut.print(';'); fOut.flush(); } break; } case Node.CDATA_SECTION_NODE: { if (fCanonical) { normalizeAndPrint(node.getNodeValue(), false); } else { fOut.print(""); } fOut.flush(); break; } case Node.TEXT_NODE: { normalizeAndPrint(node.getNodeValue(), false); fOut.flush(); break; } case Node.PROCESSING_INSTRUCTION_NODE: { fOut.print(" 0) { fOut.print(' '); fOut.print(data); } fOut.print("?>"); fOut.flush(); break; } case Node.COMMENT_NODE: { if (!fCanonical) { fOut.print(""); fOut.flush(); } } } if (type == Node.ELEMENT_NODE) { fOut.print("'); fOut.flush(); } } // write(Node) /** Returns a sorted list of attributes. */ protected Attr[] sortAttributes(NamedNodeMap attrs) { int len = (attrs != null) ? attrs.getLength() : 0; Attr array[] = new Attr[len]; for (int i = 0; i < len; i++) { array[i] = (Attr)attrs.item(i); } for (int i = 0; i < len - 1; i++) { String name = array[i].getNodeName(); int index = i; for (int j = i + 1; j < len; j++) { String curName = array[j].getNodeName(); if (curName.compareTo(name) < 0) { name = curName; index = j; } } if (index != i) { Attr temp = array[i]; array[i] = array[index]; array[index] = temp; } } return array; } // sortAttributes(NamedNodeMap):Attr[] // // Protected methods // /** Normalizes and prints the given string. */ protected void normalizeAndPrint(String s, boolean isAttValue) { int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char c = s.charAt(i); normalizeAndPrint(c, isAttValue); } } // normalizeAndPrint(String,boolean) /** Normalizes and print the given character. */ protected void normalizeAndPrint(char c, boolean isAttValue) { switch (c) { case '<': { fOut.print("<"); break; } case '>': { fOut.print(">"); break; } case '&': { fOut.print("&"); break; } case '"': { // A '"' that appears in character data // does not need to be escaped. if (isAttValue) { fOut.print("""); } else { fOut.print("\""); } break; } case '\r': { // If CR is part of the document's content, it // must not be printed as a literal otherwise // it would be normalized to LF when the document // is reparsed. fOut.print(" "); break; } case '\n': { if (fCanonical) { fOut.print(" "); break; } // else, default print char } default: { // In XML 1.1, control chars in the ranges [#x1-#x1F, #x7F-#x9F] must be escaped. // // Escape space characters that would be normalized to #x20 in attribute values // when the document is reparsed. // // Escape NEL (0x85) and LSEP (0x2028) that appear in content // if the document is XML 1.1, since they would be normalized to LF // when the document is reparsed. if (fXML11 && ((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A) || (c >= 0x7F && c <= 0x9F) || c == 0x2028) || isAttValue && (c == 0x09 || c == 0x0A)) { fOut.print("&#x"); fOut.print(Integer.toHexString(c).toUpperCase()); fOut.print(";"); } else { fOut.print(c); } } } } // normalizeAndPrint(char,boolean) /** Extracts the XML version from the Document. */ // protected String getVersion(Document document) { // if (document == null) { // return null; // } // String version = null; // Method getXMLVersion = null; // try { // getXMLVersion = document.getClass().getMethod("getXmlVersion", new Class[]{}); // // If Document class implements DOM L3, this method will exist. // if (getXMLVersion != null) { // version = (String) getXMLVersion.invoke(document, (Object[]) null); // } // } catch (Exception e) { // // Either this locator object doesn't have // // this method, or we're on an old JDK. // } // return version; // } // getVersion(Document) } src/core/com/lowagie/text/xml/XmlParser.java100644 0 0 27631 11012562265 16526 0ustar 0 0 /* * $Id: XmlParser.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.HashMap; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.lowagie.text.DocListener; import com.lowagie.text.ExceptionConverter; /** * This class can be used to parse an XML file. */ public class XmlParser { /** This is the instance of the parser. */ protected SAXParser parser; /** * Constructs an XmlParser. */ public XmlParser() { try { parser = SAXParserFactory.newInstance().newSAXParser(); } catch(ParserConfigurationException pce) { throw new ExceptionConverter(pce); } catch(SAXException se) { throw new ExceptionConverter(se); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param is The InputStream with the contents */ public void go(DocListener document, InputSource is) { try { parser.parse(is, new SAXiTextHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param is The inputsource with the content * @param tagmap A user defined tagmap */ public void go(DocListener document, InputSource is, String tagmap) { try { parser.parse(is, new SAXmyHandler(document, new TagMap(tagmap))); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param is the inputsource with the content * @param tagmap an inputstream to a user defined tagmap */ public void go(DocListener document, InputSource is, InputStream tagmap) { try { parser.parse(is, new SAXmyHandler(document, new TagMap(tagmap))); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param is the inputsource with the content * @param tagmap a user defined tagmap */ public void go(DocListener document, InputSource is, HashMap tagmap) { try { parser.parse(is, new SAXmyHandler(document, tagmap)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param file The path to a file with the content */ public void go(DocListener document, String file) { try { parser.parse(file, new SAXiTextHandler(document)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document the document that will listen to the parser * @param file the path to a file with the content * @param tagmap a user defined tagmap */ public void go(DocListener document, String file, String tagmap) { try { parser.parse(file, new SAXmyHandler(document, new TagMap(tagmap))); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file. * @param document The document that will listen to the parser * @param file the path to a file with the content * @param tagmap a user defined tagmap */ public void go(DocListener document, String file, HashMap tagmap) { try { parser.parse(file, new SAXmyHandler(document, tagmap)); } catch(SAXException se) { throw new ExceptionConverter(se); } catch(IOException ioe) { throw new ExceptionConverter(ioe); } } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is the inputsource with the content */ public static void parse(DocListener document, InputSource is) { XmlParser p = new XmlParser(); p.go(document, is); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is The inputsource with the content * @param tagmap a user defined tagmap */ public static void parse(DocListener document, InputSource is, String tagmap) { XmlParser p = new XmlParser(); p.go(document, is, tagmap); } /** * Parses a given file and writes the content to a document, using a certain tagmap. * @param document The document that will listen to the parser * @param is The inputsource with the content * @param tagmap a user defined tagmap */ public static void parse(DocListener document, InputSource is, HashMap tagmap) { XmlParser p = new XmlParser(); p.go(document, is, tagmap); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param file The path to a file with the content */ public static void parse(DocListener document, String file) { XmlParser p = new XmlParser(); p.go(document, file); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param file The path to a file with the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, String file, String tagmap) { XmlParser p = new XmlParser(); p.go(document, file, tagmap); } /** * Parses a given file and writes the content to a document, using a certain tagmap. * @param document The document that will listen to the parser * @param file The path to a file with the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, String file, HashMap tagmap) { XmlParser p = new XmlParser(); p.go(document, file, tagmap); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is The inputsource with the content */ public static void parse(DocListener document, InputStream is) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is)); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is The inputstream with the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, InputStream is, String tagmap) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is), tagmap); } /** * Parses a given file and writes the content to a document, using a certain tagmap. * @param document The document that will listen to the parser * @param is The InputStream with the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, InputStream is, HashMap tagmap) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is), tagmap); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is The reader that reads the content */ public static void parse(DocListener document, Reader is) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is)); } /** * Parses a given file that validates with the iText DTD and writes the content to a document. * @param document The document that will listen to the parser * @param is The reader that reads the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, Reader is, String tagmap) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is), tagmap); } /** * Parses a given file and writes the content to a document, using a certain tagmap. * @param document The document that will listen to the parser * @param is The reader that reads the content * @param tagmap A user defined tagmap */ public static void parse(DocListener document, Reader is, HashMap tagmap) { XmlParser p = new XmlParser(); p.go(document, new InputSource(is), tagmap); } }src/core/com/lowagie/text/xml/XmlPeer.java100644 0 0 13141 11012562265 16154 0ustar 0 0 /* * $Id: XmlPeer.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml; import java.util.Properties; import org.xml.sax.Attributes; import com.lowagie.text.ElementTags; /** * This interface is implemented by the peer of all the iText objects. */ public class XmlPeer { /** This is the name of the alias. */ protected String tagname; /** This is the name of the alias. */ protected String customTagname; /** This is the Map that contains the aliases of the attributes. */ protected Properties attributeAliases = new Properties(); /** This is the Map that contains the default values of the attributes. */ protected Properties attributeValues = new Properties(); /** This is String that contains the default content of the attributes. */ protected String defaultContent = null; /** * Creates a XmlPeer. * @param name the iText name of a tag * @param alias the user defined name of a tag */ public XmlPeer(String name, String alias) { this.tagname = name; this.customTagname = alias; } /** * Gets the tagname of the peer. * @return the iText name of a tag */ public String getTag() { return tagname; } /** * Gets the tagname of the peer. * @return the user defined tagname */ public String getAlias() { return customTagname; } /** Gets the list of attributes of the peer. * @param attrs the user defined set of attributes * @return the set of attributes translated to iText attributes */ public Properties getAttributes(Attributes attrs) { Properties attributes = new Properties(); attributes.putAll(attributeValues); if (defaultContent != null) { attributes.put(ElementTags.ITEXT, defaultContent); } if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { String attribute = getName(attrs.getQName(i)); attributes.setProperty(attribute, attrs.getValue(i)); } } return attributes; } /** * Sets an alias for an attribute. * * @param name the iText tagname * @param alias the custom tagname */ public void addAlias(String name, String alias) { attributeAliases.put(alias, name); } /** * Sets a value for an attribute. * * @param name the iText tagname * @param value the default value for this tag */ public void addValue(String name, String value) { attributeValues.put(name, value); } /** * Sets the default content. * * @param content the default content */ public void setContent(String content) { this.defaultContent = content; } /** * Returns the iText attribute name. * * @param name the custom attribute name * @return iText translated attribute name */ public String getName(String name) { String value; if ((value = attributeAliases.getProperty(name)) != null) { return value; } return name; } /** * Returns the default values. * @return A set of default (user defined) values */ public Properties getDefaultValues() { return attributeValues; } }src/core/com/lowagie/text/xml/simpleparser/EntitiesToSymbol.java100644 0 0 44177 11012562265 22600 0ustar 0 0 /* * $Id: EntitiesToSymbol.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.simpleparser; import java.util.HashMap; import com.lowagie.text.Chunk; import com.lowagie.text.Font; /** * This class contains entities that can be used in an entity tag. */ public class EntitiesToSymbol { /** * This is a map that contains all possible id values of the entity tag * that can be translated to a character in font Symbol. */ public static final HashMap map; static { map = new HashMap(); map.put("169", new Character((char)227)); map.put("172", new Character((char)216)); map.put("174", new Character((char)210)); map.put("177", new Character((char)177)); map.put("215", new Character((char)180)); map.put("247", new Character((char)184)); map.put("8230", new Character((char)188)); map.put("8242", new Character((char)162)); map.put("8243", new Character((char)178)); map.put("8260", new Character((char)164)); map.put("8364", new Character((char)240)); map.put("8465", new Character((char)193)); map.put("8472", new Character((char)195)); map.put("8476", new Character((char)194)); map.put("8482", new Character((char)212)); map.put("8501", new Character((char)192)); map.put("8592", new Character((char)172)); map.put("8593", new Character((char)173)); map.put("8594", new Character((char)174)); map.put("8595", new Character((char)175)); map.put("8596", new Character((char)171)); map.put("8629", new Character((char)191)); map.put("8656", new Character((char)220)); map.put("8657", new Character((char)221)); map.put("8658", new Character((char)222)); map.put("8659", new Character((char)223)); map.put("8660", new Character((char)219)); map.put("8704", new Character((char)34)); map.put("8706", new Character((char)182)); map.put("8707", new Character((char)36)); map.put("8709", new Character((char)198)); map.put("8711", new Character((char)209)); map.put("8712", new Character((char)206)); map.put("8713", new Character((char)207)); map.put("8717", new Character((char)39)); map.put("8719", new Character((char)213)); map.put("8721", new Character((char)229)); map.put("8722", new Character((char)45)); map.put("8727", new Character((char)42)); map.put("8729", new Character((char)183)); map.put("8730", new Character((char)214)); map.put("8733", new Character((char)181)); map.put("8734", new Character((char)165)); map.put("8736", new Character((char)208)); map.put("8743", new Character((char)217)); map.put("8744", new Character((char)218)); map.put("8745", new Character((char)199)); map.put("8746", new Character((char)200)); map.put("8747", new Character((char)242)); map.put("8756", new Character((char)92)); map.put("8764", new Character((char)126)); map.put("8773", new Character((char)64)); map.put("8776", new Character((char)187)); map.put("8800", new Character((char)185)); map.put("8801", new Character((char)186)); map.put("8804", new Character((char)163)); map.put("8805", new Character((char)179)); map.put("8834", new Character((char)204)); map.put("8835", new Character((char)201)); map.put("8836", new Character((char)203)); map.put("8838", new Character((char)205)); map.put("8839", new Character((char)202)); map.put("8853", new Character((char)197)); map.put("8855", new Character((char)196)); map.put("8869", new Character((char)94)); map.put("8901", new Character((char)215)); map.put("8992", new Character((char)243)); map.put("8993", new Character((char)245)); map.put("9001", new Character((char)225)); map.put("9002", new Character((char)241)); map.put("913", new Character((char)65)); map.put("914", new Character((char)66)); map.put("915", new Character((char)71)); map.put("916", new Character((char)68)); map.put("917", new Character((char)69)); map.put("918", new Character((char)90)); map.put("919", new Character((char)72)); map.put("920", new Character((char)81)); map.put("921", new Character((char)73)); map.put("922", new Character((char)75)); map.put("923", new Character((char)76)); map.put("924", new Character((char)77)); map.put("925", new Character((char)78)); map.put("926", new Character((char)88)); map.put("927", new Character((char)79)); map.put("928", new Character((char)80)); map.put("929", new Character((char)82)); map.put("931", new Character((char)83)); map.put("932", new Character((char)84)); map.put("933", new Character((char)85)); map.put("934", new Character((char)70)); map.put("935", new Character((char)67)); map.put("936", new Character((char)89)); map.put("937", new Character((char)87)); map.put("945", new Character((char)97)); map.put("946", new Character((char)98)); map.put("947", new Character((char)103)); map.put("948", new Character((char)100)); map.put("949", new Character((char)101)); map.put("950", new Character((char)122)); map.put("951", new Character((char)104)); map.put("952", new Character((char)113)); map.put("953", new Character((char)105)); map.put("954", new Character((char)107)); map.put("955", new Character((char)108)); map.put("956", new Character((char)109)); map.put("957", new Character((char)110)); map.put("958", new Character((char)120)); map.put("959", new Character((char)111)); map.put("960", new Character((char)112)); map.put("961", new Character((char)114)); map.put("962", new Character((char)86)); map.put("963", new Character((char)115)); map.put("964", new Character((char)116)); map.put("965", new Character((char)117)); map.put("966", new Character((char)102)); map.put("967", new Character((char)99)); map.put("9674", new Character((char)224)); map.put("968", new Character((char)121)); map.put("969", new Character((char)119)); map.put("977", new Character((char)74)); map.put("978", new Character((char)161)); map.put("981", new Character((char)106)); map.put("982", new Character((char)118)); map.put("9824", new Character((char)170)); map.put("9827", new Character((char)167)); map.put("9829", new Character((char)169)); map.put("9830", new Character((char)168)); map.put("Alpha", new Character((char)65)); map.put("Beta", new Character((char)66)); map.put("Chi", new Character((char)67)); map.put("Delta", new Character((char)68)); map.put("Epsilon", new Character((char)69)); map.put("Eta", new Character((char)72)); map.put("Gamma", new Character((char)71)); map.put("Iota", new Character((char)73)); map.put("Kappa", new Character((char)75)); map.put("Lambda", new Character((char)76)); map.put("Mu", new Character((char)77)); map.put("Nu", new Character((char)78)); map.put("Omega", new Character((char)87)); map.put("Omicron", new Character((char)79)); map.put("Phi", new Character((char)70)); map.put("Pi", new Character((char)80)); map.put("Prime", new Character((char)178)); map.put("Psi", new Character((char)89)); map.put("Rho", new Character((char)82)); map.put("Sigma", new Character((char)83)); map.put("Tau", new Character((char)84)); map.put("Theta", new Character((char)81)); map.put("Upsilon", new Character((char)85)); map.put("Xi", new Character((char)88)); map.put("Zeta", new Character((char)90)); map.put("alefsym", new Character((char)192)); map.put("alpha", new Character((char)97)); map.put("and", new Character((char)217)); map.put("ang", new Character((char)208)); map.put("asymp", new Character((char)187)); map.put("beta", new Character((char)98)); map.put("cap", new Character((char)199)); map.put("chi", new Character((char)99)); map.put("clubs", new Character((char)167)); map.put("cong", new Character((char)64)); map.put("copy", new Character((char)211)); map.put("crarr", new Character((char)191)); map.put("cup", new Character((char)200)); map.put("dArr", new Character((char)223)); map.put("darr", new Character((char)175)); map.put("delta", new Character((char)100)); map.put("diams", new Character((char)168)); map.put("divide", new Character((char)184)); map.put("empty", new Character((char)198)); map.put("epsilon", new Character((char)101)); map.put("equiv", new Character((char)186)); map.put("eta", new Character((char)104)); map.put("euro", new Character((char)240)); map.put("exist", new Character((char)36)); map.put("forall", new Character((char)34)); map.put("frasl", new Character((char)164)); map.put("gamma", new Character((char)103)); map.put("ge", new Character((char)179)); map.put("hArr", new Character((char)219)); map.put("harr", new Character((char)171)); map.put("hearts", new Character((char)169)); map.put("hellip", new Character((char)188)); map.put("horizontal arrow extender", new Character((char)190)); map.put("image", new Character((char)193)); map.put("infin", new Character((char)165)); map.put("int", new Character((char)242)); map.put("iota", new Character((char)105)); map.put("isin", new Character((char)206)); map.put("kappa", new Character((char)107)); map.put("lArr", new Character((char)220)); map.put("lambda", new Character((char)108)); map.put("lang", new Character((char)225)); map.put("large brace extender", new Character((char)239)); map.put("large integral extender", new Character((char)244)); map.put("large left brace (bottom)", new Character((char)238)); map.put("large left brace (middle)", new Character((char)237)); map.put("large left brace (top)", new Character((char)236)); map.put("large left bracket (bottom)", new Character((char)235)); map.put("large left bracket (extender)", new Character((char)234)); map.put("large left bracket (top)", new Character((char)233)); map.put("large left parenthesis (bottom)", new Character((char)232)); map.put("large left parenthesis (extender)", new Character((char)231)); map.put("large left parenthesis (top)", new Character((char)230)); map.put("large right brace (bottom)", new Character((char)254)); map.put("large right brace (middle)", new Character((char)253)); map.put("large right brace (top)", new Character((char)252)); map.put("large right bracket (bottom)", new Character((char)251)); map.put("large right bracket (extender)", new Character((char)250)); map.put("large right bracket (top)", new Character((char)249)); map.put("large right parenthesis (bottom)", new Character((char)248)); map.put("large right parenthesis (extender)", new Character((char)247)); map.put("large right parenthesis (top)", new Character((char)246)); map.put("larr", new Character((char)172)); map.put("le", new Character((char)163)); map.put("lowast", new Character((char)42)); map.put("loz", new Character((char)224)); map.put("minus", new Character((char)45)); map.put("mu", new Character((char)109)); map.put("nabla", new Character((char)209)); map.put("ne", new Character((char)185)); map.put("not", new Character((char)216)); map.put("notin", new Character((char)207)); map.put("nsub", new Character((char)203)); map.put("nu", new Character((char)110)); map.put("omega", new Character((char)119)); map.put("omicron", new Character((char)111)); map.put("oplus", new Character((char)197)); map.put("or", new Character((char)218)); map.put("otimes", new Character((char)196)); map.put("part", new Character((char)182)); map.put("perp", new Character((char)94)); map.put("phi", new Character((char)102)); map.put("pi", new Character((char)112)); map.put("piv", new Character((char)118)); map.put("plusmn", new Character((char)177)); map.put("prime", new Character((char)162)); map.put("prod", new Character((char)213)); map.put("prop", new Character((char)181)); map.put("psi", new Character((char)121)); map.put("rArr", new Character((char)222)); map.put("radic", new Character((char)214)); map.put("radical extender", new Character((char)96)); map.put("rang", new Character((char)241)); map.put("rarr", new Character((char)174)); map.put("real", new Character((char)194)); map.put("reg", new Character((char)210)); map.put("rho", new Character((char)114)); map.put("sdot", new Character((char)215)); map.put("sigma", new Character((char)115)); map.put("sigmaf", new Character((char)86)); map.put("sim", new Character((char)126)); map.put("spades", new Character((char)170)); map.put("sub", new Character((char)204)); map.put("sube", new Character((char)205)); map.put("sum", new Character((char)229)); map.put("sup", new Character((char)201)); map.put("supe", new Character((char)202)); map.put("tau", new Character((char)116)); map.put("there4", new Character((char)92)); map.put("theta", new Character((char)113)); map.put("thetasym", new Character((char)74)); map.put("times", new Character((char)180)); map.put("trade", new Character((char)212)); map.put("uArr", new Character((char)221)); map.put("uarr", new Character((char)173)); map.put("upsih", new Character((char)161)); map.put("upsilon", new Character((char)117)); map.put("vertical arrow extender", new Character((char)189)); map.put("weierp", new Character((char)195)); map.put("xi", new Character((char)120)); map.put("zeta", new Character((char)122)); } /** * Gets a chunk with a symbol character. * @param e a symbol value (see Entities class: alfa is greek alfa,...) * @param font the font if the symbol isn't found (otherwise Font.SYMBOL) * @return a Chunk */ public static Chunk get(String e, Font font) { char s = getCorrespondingSymbol(e); if (s == (char)0) { try { return new Chunk(String.valueOf((char)Integer.parseInt(e)), font); } catch(Exception exception) { return new Chunk(e, font); } } Font symbol = new Font(Font.SYMBOL, font.getSize(), font.getStyle(), font.getColor()); return new Chunk(String.valueOf(s), symbol); } /** * Looks for the corresponding symbol in the font Symbol. * * @param name the name of the entity * @return the corresponding character in font Symbol */ public static char getCorrespondingSymbol(String name) { Character symbol = (Character) map.get(name); if (symbol == null) { return (char)0; } return symbol.charValue(); } } src/core/com/lowagie/text/xml/simpleparser/EntitiesToUnicode.java100644 0 0 76025 11012562265 22716 0ustar 0 0 /* * $Id: EntitiesToUnicode.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2003-2007 Paulo Soares and Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.simpleparser; import java.util.HashMap; /** * This class contains entities that can be used in an entity tag. */ public class EntitiesToUnicode { /** * This is a map that contains the names of entities and their unicode value. */ public static final HashMap map = new HashMap(); static { map.put("nbsp", new Character('\u00a0')); // no-break space = non-breaking space, U+00A0 ISOnum map.put("iexcl", new Character('\u00a1')); // inverted exclamation mark, U+00A1 ISOnum map.put("cent", new Character('\u00a2')); // cent sign, U+00A2 ISOnum map.put("pound", new Character('\u00a3')); // pound sign, U+00A3 ISOnum map.put("curren", new Character('\u00a4')); // currency sign, U+00A4 ISOnum map.put("yen", new Character('\u00a5')); // yen sign = yuan sign, U+00A5 ISOnum map.put("brvbar", new Character('\u00a6')); // broken bar = broken vertical bar, U+00A6 ISOnum map.put("sect", new Character('\u00a7')); // section sign, U+00A7 ISOnum map.put("uml", new Character('\u00a8')); // diaeresis = spacing diaeresis, U+00A8 ISOdia map.put("copy", new Character('\u00a9')); // copyright sign, U+00A9 ISOnum map.put("ordf", new Character('\u00aa')); // feminine ordinal indicator, U+00AA ISOnum map.put("laquo", new Character('\u00ab')); // left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum map.put("not", new Character('\u00ac')); // not sign, U+00AC ISOnum map.put("shy", new Character('\u00ad')); // soft hyphen = discretionary hyphen, U+00AD ISOnum map.put("reg", new Character('\u00ae')); // registered sign = registered trade mark sign, U+00AE ISOnum map.put("macr", new Character('\u00af')); // macron = spacing macron = overline = APL overbar, U+00AF ISOdia map.put("deg", new Character('\u00b0')); // degree sign, U+00B0 ISOnum map.put("plusmn", new Character('\u00b1')); // plus-minus sign = plus-or-minus sign, U+00B1 ISOnum map.put("sup2", new Character('\u00b2')); // superscript two = superscript digit two = squared, U+00B2 ISOnum map.put("sup3", new Character('\u00b3')); // superscript three = superscript digit three = cubed, U+00B3 ISOnum map.put("acute", new Character('\u00b4')); // acute accent = spacing acute, U+00B4 ISOdia map.put("micro", new Character('\u00b5')); // micro sign, U+00B5 ISOnum map.put("para", new Character('\u00b6')); // pilcrow sign = paragraph sign, U+00B6 ISOnum map.put("middot", new Character('\u00b7')); // middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum map.put("cedil", new Character('\u00b8')); // cedilla = spacing cedilla, U+00B8 ISOdia map.put("sup1", new Character('\u00b9')); // superscript one = superscript digit one, U+00B9 ISOnum map.put("ordm", new Character('\u00ba')); // masculine ordinal indicator, U+00BA ISOnum map.put("raquo", new Character('\u00bb')); // right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum map.put("frac14", new Character('\u00bc')); // vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum map.put("frac12", new Character('\u00bd')); // vulgar fraction one half = fraction one half, U+00BD ISOnum map.put("frac34", new Character('\u00be')); // vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum map.put("iquest", new Character('\u00bf')); // inverted question mark = turned question mark, U+00BF ISOnum map.put("Agrave", new Character('\u00c0')); // latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 map.put("Aacute", new Character('\u00c1')); // latin capital letter A with acute, U+00C1 ISOlat1 map.put("Acirc", new Character('\u00c2')); // latin capital letter A with circumflex, U+00C2 ISOlat1 map.put("Atilde", new Character('\u00c3')); // latin capital letter A with tilde, U+00C3 ISOlat1 map.put("Auml", new Character('\u00c4')); // latin capital letter A with diaeresis, U+00C4 ISOlat1 map.put("Aring", new Character('\u00c5')); // latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 map.put("AElig", new Character('\u00c6')); // latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 map.put("Ccedil", new Character('\u00c7')); // latin capital letter C with cedilla, U+00C7 ISOlat1 map.put("Egrave", new Character('\u00c8')); // latin capital letter E with grave, U+00C8 ISOlat1 map.put("Eacute", new Character('\u00c9')); // latin capital letter E with acute, U+00C9 ISOlat1 map.put("Ecirc", new Character('\u00ca')); // latin capital letter E with circumflex, U+00CA ISOlat1 map.put("Euml", new Character('\u00cb')); // latin capital letter E with diaeresis, U+00CB ISOlat1 map.put("Igrave", new Character('\u00cc')); // latin capital letter I with grave, U+00CC ISOlat1 map.put("Iacute", new Character('\u00cd')); // latin capital letter I with acute, U+00CD ISOlat1 map.put("Icirc", new Character('\u00ce')); // latin capital letter I with circumflex, U+00CE ISOlat1 map.put("Iuml", new Character('\u00cf')); // latin capital letter I with diaeresis, U+00CF ISOlat1 map.put("ETH", new Character('\u00d0')); // latin capital letter ETH, U+00D0 ISOlat1 map.put("Ntilde", new Character('\u00d1')); // latin capital letter N with tilde, U+00D1 ISOlat1 map.put("Ograve", new Character('\u00d2')); // latin capital letter O with grave, U+00D2 ISOlat1 map.put("Oacute", new Character('\u00d3')); // latin capital letter O with acute, U+00D3 ISOlat1 map.put("Ocirc", new Character('\u00d4')); // latin capital letter O with circumflex, U+00D4 ISOlat1 map.put("Otilde", new Character('\u00d5')); // latin capital letter O with tilde, U+00D5 ISOlat1 map.put("Ouml", new Character('\u00d6')); // latin capital letter O with diaeresis, U+00D6 ISOlat1 map.put("times", new Character('\u00d7')); // multiplication sign, U+00D7 ISOnum map.put("Oslash", new Character('\u00d8')); // latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 map.put("Ugrave", new Character('\u00d9')); // latin capital letter U with grave, U+00D9 ISOlat1 map.put("Uacute", new Character('\u00da')); // latin capital letter U with acute, U+00DA ISOlat1 map.put("Ucirc", new Character('\u00db')); // latin capital letter U with circumflex, U+00DB ISOlat1 map.put("Uuml", new Character('\u00dc')); // latin capital letter U with diaeresis, U+00DC ISOlat1 map.put("Yacute", new Character('\u00dd')); // latin capital letter Y with acute, U+00DD ISOlat1 map.put("THORN", new Character('\u00de')); // latin capital letter THORN, U+00DE ISOlat1 map.put("szlig", new Character('\u00df')); // latin small letter sharp s = ess-zed, U+00DF ISOlat1 map.put("agrave", new Character('\u00e0')); // latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 map.put("aacute", new Character('\u00e1')); // latin small letter a with acute, U+00E1 ISOlat1 map.put("acirc", new Character('\u00e2')); // latin small letter a with circumflex, U+00E2 ISOlat1 map.put("atilde", new Character('\u00e3')); // latin small letter a with tilde, U+00E3 ISOlat1 map.put("auml", new Character('\u00e4')); // latin small letter a with diaeresis, U+00E4 ISOlat1 map.put("aring", new Character('\u00e5')); // latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 map.put("aelig", new Character('\u00e6')); // latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 map.put("ccedil", new Character('\u00e7')); // latin small letter c with cedilla, U+00E7 ISOlat1 map.put("egrave", new Character('\u00e8')); // latin small letter e with grave, U+00E8 ISOlat1 map.put("eacute", new Character('\u00e9')); // latin small letter e with acute, U+00E9 ISOlat1 map.put("ecirc", new Character('\u00ea')); // latin small letter e with circumflex, U+00EA ISOlat1 map.put("euml", new Character('\u00eb')); // latin small letter e with diaeresis, U+00EB ISOlat1 map.put("igrave", new Character('\u00ec')); // latin small letter i with grave, U+00EC ISOlat1 map.put("iacute", new Character('\u00ed')); // latin small letter i with acute, U+00ED ISOlat1 map.put("icirc", new Character('\u00ee')); // latin small letter i with circumflex, U+00EE ISOlat1 map.put("iuml", new Character('\u00ef')); // latin small letter i with diaeresis, U+00EF ISOlat1 map.put("eth", new Character('\u00f0')); // latin small letter eth, U+00F0 ISOlat1 map.put("ntilde", new Character('\u00f1')); // latin small letter n with tilde, U+00F1 ISOlat1 map.put("ograve", new Character('\u00f2')); // latin small letter o with grave, U+00F2 ISOlat1 map.put("oacute", new Character('\u00f3')); // latin small letter o with acute, U+00F3 ISOlat1 map.put("ocirc", new Character('\u00f4')); // latin small letter o with circumflex, U+00F4 ISOlat1 map.put("otilde", new Character('\u00f5')); // latin small letter o with tilde, U+00F5 ISOlat1 map.put("ouml", new Character('\u00f6')); // latin small letter o with diaeresis, U+00F6 ISOlat1 map.put("divide", new Character('\u00f7')); // division sign, U+00F7 ISOnum map.put("oslash", new Character('\u00f8')); // latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 map.put("ugrave", new Character('\u00f9')); // latin small letter u with grave, U+00F9 ISOlat1 map.put("uacute", new Character('\u00fa')); // latin small letter u with acute, U+00FA ISOlat1 map.put("ucirc", new Character('\u00fb')); // latin small letter u with circumflex, U+00FB ISOlat1 map.put("uuml", new Character('\u00fc')); // latin small letter u with diaeresis, U+00FC ISOlat1 map.put("yacute", new Character('\u00fd')); // latin small letter y with acute, U+00FD ISOlat1 map.put("thorn", new Character('\u00fe')); // latin small letter thorn, U+00FE ISOlat1 map.put("yuml", new Character('\u00ff')); // latin small letter y with diaeresis, U+00FF ISOlat1 // Latin Extended-B map.put("fnof", new Character('\u0192')); // latin small f with hook = function = florin, U+0192 ISOtech // Greek map.put("Alpha", new Character('\u0391')); // greek capital letter alpha, U+0391 map.put("Beta", new Character('\u0392')); // greek capital letter beta, U+0392 map.put("Gamma", new Character('\u0393')); // greek capital letter gamma, U+0393 ISOgrk3 map.put("Delta", new Character('\u0394')); // greek capital letter delta, U+0394 ISOgrk3 map.put("Epsilon", new Character('\u0395')); // greek capital letter epsilon, U+0395 map.put("Zeta", new Character('\u0396')); // greek capital letter zeta, U+0396 map.put("Eta", new Character('\u0397')); // greek capital letter eta, U+0397 map.put("Theta", new Character('\u0398')); // greek capital letter theta, U+0398 ISOgrk3 map.put("Iota", new Character('\u0399')); // greek capital letter iota, U+0399 map.put("Kappa", new Character('\u039a')); // greek capital letter kappa, U+039A map.put("Lambda", new Character('\u039b')); // greek capital letter lambda, U+039B ISOgrk3 map.put("Mu", new Character('\u039c')); // greek capital letter mu, U+039C map.put("Nu", new Character('\u039d')); // greek capital letter nu, U+039D map.put("Xi", new Character('\u039e')); // greek capital letter xi, U+039E ISOgrk3 map.put("Omicron", new Character('\u039f')); // greek capital letter omicron, U+039F map.put("Pi", new Character('\u03a0')); // greek capital letter pi, U+03A0 ISOgrk3 map.put("Rho", new Character('\u03a1')); // greek capital letter rho, U+03A1 // there is no Sigmaf, and no U+03A2 character either map.put("Sigma", new Character('\u03a3')); // greek capital letter sigma, U+03A3 ISOgrk3 map.put("Tau", new Character('\u03a4')); // greek capital letter tau, U+03A4 map.put("Upsilon", new Character('\u03a5')); // greek capital letter upsilon, U+03A5 ISOgrk3 map.put("Phi", new Character('\u03a6')); // greek capital letter phi, U+03A6 ISOgrk3 map.put("Chi", new Character('\u03a7')); // greek capital letter chi, U+03A7 map.put("Psi", new Character('\u03a8')); // greek capital letter psi, U+03A8 ISOgrk3 map.put("Omega", new Character('\u03a9')); // greek capital letter omega, U+03A9 ISOgrk3 map.put("alpha", new Character('\u03b1')); // greek small letter alpha, U+03B1 ISOgrk3 map.put("beta", new Character('\u03b2')); // greek small letter beta, U+03B2 ISOgrk3 map.put("gamma", new Character('\u03b3')); // greek small letter gamma, U+03B3 ISOgrk3 map.put("delta", new Character('\u03b4')); // greek small letter delta, U+03B4 ISOgrk3 map.put("epsilon", new Character('\u03b5')); // greek small letter epsilon, U+03B5 ISOgrk3 map.put("zeta", new Character('\u03b6')); // greek small letter zeta, U+03B6 ISOgrk3 map.put("eta", new Character('\u03b7')); // greek small letter eta, U+03B7 ISOgrk3 map.put("theta", new Character('\u03b8')); // greek small letter theta, U+03B8 ISOgrk3 map.put("iota", new Character('\u03b9')); // greek small letter iota, U+03B9 ISOgrk3 map.put("kappa", new Character('\u03ba')); // greek small letter kappa, U+03BA ISOgrk3 map.put("lambda", new Character('\u03bb')); // greek small letter lambda, U+03BB ISOgrk3 map.put("mu", new Character('\u03bc')); // greek small letter mu, U+03BC ISOgrk3 map.put("nu", new Character('\u03bd')); // greek small letter nu, U+03BD ISOgrk3 map.put("xi", new Character('\u03be')); // greek small letter xi, U+03BE ISOgrk3 map.put("omicron", new Character('\u03bf')); // greek small letter omicron, U+03BF NEW map.put("pi", new Character('\u03c0')); // greek small letter pi, U+03C0 ISOgrk3 map.put("rho", new Character('\u03c1')); // greek small letter rho, U+03C1 ISOgrk3 map.put("sigmaf", new Character('\u03c2')); // greek small letter final sigma, U+03C2 ISOgrk3 map.put("sigma", new Character('\u03c3')); // greek small letter sigma, U+03C3 ISOgrk3 map.put("tau", new Character('\u03c4')); // greek small letter tau, U+03C4 ISOgrk3 map.put("upsilon", new Character('\u03c5')); // greek small letter upsilon, U+03C5 ISOgrk3 map.put("phi", new Character('\u03c6')); // greek small letter phi, U+03C6 ISOgrk3 map.put("chi", new Character('\u03c7')); // greek small letter chi, U+03C7 ISOgrk3 map.put("psi", new Character('\u03c8')); // greek small letter psi, U+03C8 ISOgrk3 map.put("omega", new Character('\u03c9')); // greek small letter omega, U+03C9 ISOgrk3 map.put("thetasym", new Character('\u03d1')); // greek small letter theta symbol, U+03D1 NEW map.put("upsih", new Character('\u03d2')); // greek upsilon with hook symbol, U+03D2 NEW map.put("piv", new Character('\u03d6')); // greek pi symbol, U+03D6 ISOgrk3 // General Punctuation map.put("bull", new Character('\u2022')); // bullet = black small circle, U+2022 ISOpub // bullet is NOT the same as bullet operator, U+2219 map.put("hellip", new Character('\u2026')); // horizontal ellipsis = three dot leader, U+2026 ISOpub map.put("prime", new Character('\u2032')); // prime = minutes = feet, U+2032 ISOtech map.put("Prime", new Character('\u2033')); // double prime = seconds = inches, U+2033 ISOtech map.put("oline", new Character('\u203e')); // overline = spacing overscore, U+203E NEW map.put("frasl", new Character('\u2044')); // fraction slash, U+2044 NEW // Letterlike Symbols map.put("weierp", new Character('\u2118')); // script capital P = power set = Weierstrass p, U+2118 ISOamso map.put("image", new Character('\u2111')); // blackletter capital I = imaginary part, U+2111 ISOamso map.put("real", new Character('\u211c')); // blackletter capital R = real part symbol, U+211C ISOamso map.put("trade", new Character('\u2122')); // trade mark sign, U+2122 ISOnum map.put("alefsym", new Character('\u2135')); // alef symbol = first transfinite cardinal, U+2135 NEW // alef symbol is NOT the same as hebrew letter alef, // U+05D0 although the same glyph could be used to depict both characters // Arrows map.put("larr", new Character('\u2190')); // leftwards arrow, U+2190 ISOnum map.put("uarr", new Character('\u2191')); // upwards arrow, U+2191 ISOnum map.put("rarr", new Character('\u2192')); // rightwards arrow, U+2192 ISOnum map.put("darr", new Character('\u2193')); // downwards arrow, U+2193 ISOnum map.put("harr", new Character('\u2194')); // left right arrow, U+2194 ISOamsa map.put("crarr", new Character('\u21b5')); // downwards arrow with corner leftwards = carriage return, U+21B5 NEW map.put("lArr", new Character('\u21d0')); // leftwards double arrow, U+21D0 ISOtech // ISO 10646 does not say that lArr is the same as the 'is implied by' arrow // but also does not have any other character for that function. So ? lArr can // be used for 'is implied by' as ISOtech suggests map.put("uArr", new Character('\u21d1')); // upwards double arrow, U+21D1 ISOamsa map.put("rArr", new Character('\u21d2')); // rightwards double arrow, U+21D2 ISOtech // ISO 10646 does not say this is the 'implies' character but does not have // another character with this function so ? // rArr can be used for 'implies' as ISOtech suggests map.put("dArr", new Character('\u21d3')); // downwards double arrow, U+21D3 ISOamsa map.put("hArr", new Character('\u21d4')); // left right double arrow, U+21D4 ISOamsa // Mathematical Operators map.put("forall", new Character('\u2200')); // for all, U+2200 ISOtech map.put("part", new Character('\u2202')); // partial differential, U+2202 ISOtech map.put("exist", new Character('\u2203')); // there exists, U+2203 ISOtech map.put("empty", new Character('\u2205')); // empty set = null set = diameter, U+2205 ISOamso map.put("nabla", new Character('\u2207')); // nabla = backward difference, U+2207 ISOtech map.put("isin", new Character('\u2208')); // element of, U+2208 ISOtech map.put("notin", new Character('\u2209')); // not an element of, U+2209 ISOtech map.put("ni", new Character('\u220b')); // contains as member, U+220B ISOtech // should there be a more memorable name than 'ni'? map.put("prod", new Character('\u220f')); // n-ary product = product sign, U+220F ISOamsb // prod is NOT the same character as U+03A0 'greek capital letter pi' though // the same glyph might be used for both map.put("sum", new Character('\u2211')); // n-ary sumation, U+2211 ISOamsb // sum is NOT the same character as U+03A3 'greek capital letter sigma' // though the same glyph might be used for both map.put("minus", new Character('\u2212')); // minus sign, U+2212 ISOtech map.put("lowast", new Character('\u2217')); // asterisk operator, U+2217 ISOtech map.put("radic", new Character('\u221a')); // square root = radical sign, U+221A ISOtech map.put("prop", new Character('\u221d')); // proportional to, U+221D ISOtech map.put("infin", new Character('\u221e')); // infinity, U+221E ISOtech map.put("ang", new Character('\u2220')); // angle, U+2220 ISOamso map.put("and", new Character('\u2227')); // logical and = wedge, U+2227 ISOtech map.put("or", new Character('\u2228')); // logical or = vee, U+2228 ISOtech map.put("cap", new Character('\u2229')); // intersection = cap, U+2229 ISOtech map.put("cup", new Character('\u222a')); // union = cup, U+222A ISOtech map.put("int", new Character('\u222b')); // integral, U+222B ISOtech map.put("there4", new Character('\u2234')); // therefore, U+2234 ISOtech map.put("sim", new Character('\u223c')); // tilde operator = varies with = similar to, U+223C ISOtech // tilde operator is NOT the same character as the tilde, U+007E, // although the same glyph might be used to represent both map.put("cong", new Character('\u2245')); // approximately equal to, U+2245 ISOtech map.put("asymp", new Character('\u2248')); // almost equal to = asymptotic to, U+2248 ISOamsr map.put("ne", new Character('\u2260')); // not equal to, U+2260 ISOtech map.put("equiv", new Character('\u2261')); // identical to, U+2261 ISOtech map.put("le", new Character('\u2264')); // less-than or equal to, U+2264 ISOtech map.put("ge", new Character('\u2265')); // greater-than or equal to, U+2265 ISOtech map.put("sub", new Character('\u2282')); // subset of, U+2282 ISOtech map.put("sup", new Character('\u2283')); // superset of, U+2283 ISOtech // note that nsup, 'not a superset of, U+2283' is not covered by the Symbol // font encoding and is not included. Should it be, for symmetry? // It is in ISOamsn map.put("nsub", new Character('\u2284')); // not a subset of, U+2284 ISOamsn map.put("sube", new Character('\u2286')); // subset of or equal to, U+2286 ISOtech map.put("supe", new Character('\u2287')); // superset of or equal to, U+2287 ISOtech map.put("oplus", new Character('\u2295')); // circled plus = direct sum, U+2295 ISOamsb map.put("otimes", new Character('\u2297')); // circled times = vector product, U+2297 ISOamsb map.put("perp", new Character('\u22a5')); // up tack = orthogonal to = perpendicular, U+22A5 ISOtech map.put("sdot", new Character('\u22c5')); // dot operator, U+22C5 ISOamsb // dot operator is NOT the same character as U+00B7 middle dot // Miscellaneous Technical map.put("lceil", new Character('\u2308')); // left ceiling = apl upstile, U+2308 ISOamsc map.put("rceil", new Character('\u2309')); // right ceiling, U+2309 ISOamsc map.put("lfloor", new Character('\u230a')); // left floor = apl downstile, U+230A ISOamsc map.put("rfloor", new Character('\u230b')); // right floor, U+230B ISOamsc map.put("lang", new Character('\u2329')); // left-pointing angle bracket = bra, U+2329 ISOtech // lang is NOT the same character as U+003C 'less than' // or U+2039 'single left-pointing angle quotation mark' map.put("rang", new Character('\u232a')); // right-pointing angle bracket = ket, U+232A ISOtech // rang is NOT the same character as U+003E 'greater than' // or U+203A 'single right-pointing angle quotation mark' // Geometric Shapes map.put("loz", new Character('\u25ca')); // lozenge, U+25CA ISOpub // Miscellaneous Symbols map.put("spades", new Character('\u2660')); // black spade suit, U+2660 ISOpub // black here seems to mean filled as opposed to hollow map.put("clubs", new Character('\u2663')); // black club suit = shamrock, U+2663 ISOpub map.put("hearts", new Character('\u2665')); // black heart suit = valentine, U+2665 ISOpub map.put("diams", new Character('\u2666')); // black diamond suit, U+2666 ISOpub // C0 Controls and Basic Latin map.put("quot", new Character('\u0022')); // quotation mark = APL quote, U+0022 ISOnum map.put("amp", new Character('\u0026')); // ampersand, U+0026 ISOnum map.put("apos", new Character('\'')); map.put("lt", new Character('\u003c')); // less-than sign, U+003C ISOnum map.put("gt", new Character('\u003e')); // greater-than sign, U+003E ISOnum // Latin Extended-A map.put("OElig", new Character('\u0152')); // latin capital ligature OE, U+0152 ISOlat2 map.put("oelig", new Character('\u0153')); // latin small ligature oe, U+0153 ISOlat2 // ligature is a misnomer, this is a separate character in some languages map.put("Scaron", new Character('\u0160')); // latin capital letter S with caron, U+0160 ISOlat2 map.put("scaron", new Character('\u0161')); // latin small letter s with caron, U+0161 ISOlat2 map.put("Yuml", new Character('\u0178')); // latin capital letter Y with diaeresis, U+0178 ISOlat2 // Spacing Modifier Letters map.put("circ", new Character('\u02c6')); // modifier letter circumflex accent, U+02C6 ISOpub map.put("tilde", new Character('\u02dc')); // small tilde, U+02DC ISOdia // General Punctuation map.put("ensp", new Character('\u2002')); // en space, U+2002 ISOpub map.put("emsp", new Character('\u2003')); // em space, U+2003 ISOpub map.put("thinsp", new Character('\u2009')); // thin space, U+2009 ISOpub map.put("zwnj", new Character('\u200c')); // zero width non-joiner, U+200C NEW RFC 2070 map.put("zwj", new Character('\u200d')); // zero width joiner, U+200D NEW RFC 2070 map.put("lrm", new Character('\u200e')); // left-to-right mark, U+200E NEW RFC 2070 map.put("rlm", new Character('\u200f')); // right-to-left mark, U+200F NEW RFC 2070 map.put("ndash", new Character('\u2013')); // en dash, U+2013 ISOpub map.put("mdash", new Character('\u2014')); // em dash, U+2014 ISOpub map.put("lsquo", new Character('\u2018')); // left single quotation mark, U+2018 ISOnum map.put("rsquo", new Character('\u2019')); // right single quotation mark, U+2019 ISOnum map.put("sbquo", new Character('\u201a')); // single low-9 quotation mark, U+201A NEW map.put("ldquo", new Character('\u201c')); // left double quotation mark, U+201C ISOnum map.put("rdquo", new Character('\u201d')); // right double quotation mark, U+201D ISOnum map.put("bdquo", new Character('\u201e')); // double low-9 quotation mark, U+201E NEW map.put("dagger", new Character('\u2020')); // dagger, U+2020 ISOpub map.put("Dagger", new Character('\u2021')); // double dagger, U+2021 ISOpub map.put("permil", new Character('\u2030')); // per mille sign, U+2030 ISOtech map.put("lsaquo", new Character('\u2039')); // single left-pointing angle quotation mark, U+2039 ISO proposed // lsaquo is proposed but not yet ISO standardized map.put("rsaquo", new Character('\u203a')); // single right-pointing angle quotation mark, U+203A ISO proposed // rsaquo is proposed but not yet ISO standardized map.put("euro", new Character('\u20ac')); // euro sign, U+20AC NEW } /** * Translates an entity to a unicode character. * * @param name the name of the entity * @return the corresponding unicode character */ public static char decodeEntity(String name) { if (name.startsWith("#x")) { try { return (char)Integer.parseInt(name.substring(2),16); } catch(NumberFormatException nfe) { return '\0'; } } if (name.startsWith("#")) { try { return (char)Integer.parseInt(name.substring(1)); } catch(NumberFormatException nfe) { return '\0'; } } Character c = (Character)map.get(name); if (c == null) return '\0'; else return c.charValue(); } /** * Translates a String with entities (&...;) to a String without entities, * replacing the entity with the right (unicode) character. */ public static String decodeString(String s) { int pos_amp = s.indexOf('&'); if (pos_amp == -1) return s; int pos_sc; int pos_a; StringBuffer buf = new StringBuffer(s.substring(0, pos_amp)); char replace; while (true) { pos_sc = s.indexOf(';', pos_amp); if (pos_sc == -1) { buf.append(s.substring(pos_amp)); return buf.toString(); } pos_a = s.indexOf('&', pos_amp + 1); while (pos_a != -1 && pos_a < pos_sc) { buf.append(s.substring(pos_amp, pos_a)); pos_amp = pos_a; pos_a = s.indexOf('&', pos_amp + 1); } replace = decodeEntity(s.substring(pos_amp + 1, pos_sc)); if (s.length() < pos_sc + 1) { return buf.toString(); } if (replace == '\0') { buf.append(s.substring(pos_amp, pos_sc + 1)); } else { buf.append(replace); } pos_amp = s.indexOf('&', pos_sc); if (pos_amp == -1) { buf.append(s.substring(pos_sc + 1)); return buf.toString(); } else { buf.append(s.substring(pos_sc + 1, pos_amp)); } } } }src/core/com/lowagie/text/xml/simpleparser/IanaEncodings.java100644 0 0 26666 11012562265 22030 0ustar 0 0 /* * $Id: IanaEncodings.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2003-2007 Paulo Soares and Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * The values used in this class are based on class org.apache.xercis.util.EncodingMap * http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xerces/util/EncodingMap.java?view=markup * This class was originally published under the following license: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lowagie.text.xml.simpleparser; import java.util.HashMap; /** * Translates a IANA encoding name to a Java encoding. */ public class IanaEncodings { /** The object that maps IANA to Java encodings. */ private static final HashMap map = new HashMap(); static { // add IANA to Java encoding mappings. map.put("BIG5", "Big5"); map.put("CSBIG5", "Big5"); map.put("CP037", "CP037"); map.put("IBM037", "CP037"); map.put("CSIBM037", "CP037"); map.put("EBCDIC-CP-US", "CP037"); map.put("EBCDIC-CP-CA", "CP037"); map.put("EBCDIC-CP-NL", "CP037"); map.put("EBCDIC-CP-WT", "CP037"); map.put("IBM277", "CP277"); map.put("CP277", "CP277"); map.put("CSIBM277", "CP277"); map.put("EBCDIC-CP-DK", "CP277"); map.put("EBCDIC-CP-NO", "CP277"); map.put("IBM278", "CP278"); map.put("CP278", "CP278"); map.put("CSIBM278", "CP278"); map.put("EBCDIC-CP-FI", "CP278"); map.put("EBCDIC-CP-SE", "CP278"); map.put("IBM280", "CP280"); map.put("CP280", "CP280"); map.put("CSIBM280", "CP280"); map.put("EBCDIC-CP-IT", "CP280"); map.put("IBM284", "CP284"); map.put("CP284", "CP284"); map.put("CSIBM284", "CP284"); map.put("EBCDIC-CP-ES", "CP284"); map.put("EBCDIC-CP-GB", "CP285"); map.put("IBM285", "CP285"); map.put("CP285", "CP285"); map.put("CSIBM285", "CP285"); map.put("EBCDIC-CP-FR", "CP297"); map.put("IBM297", "CP297"); map.put("CP297", "CP297"); map.put("CSIBM297", "CP297"); map.put("EBCDIC-CP-AR1", "CP420"); map.put("IBM420", "CP420"); map.put("CP420", "CP420"); map.put("CSIBM420", "CP420"); map.put("EBCDIC-CP-HE", "CP424"); map.put("IBM424", "CP424"); map.put("CP424", "CP424"); map.put("CSIBM424", "CP424"); map.put("EBCDIC-CP-CH", "CP500"); map.put("IBM500", "CP500"); map.put("CP500", "CP500"); map.put("CSIBM500", "CP500"); map.put("EBCDIC-CP-CH", "CP500"); map.put("EBCDIC-CP-BE", "CP500"); map.put("IBM868", "CP868"); map.put("CP868", "CP868"); map.put("CSIBM868", "CP868"); map.put("CP-AR", "CP868"); map.put("IBM869", "CP869"); map.put("CP869", "CP869"); map.put("CSIBM869", "CP869"); map.put("CP-GR", "CP869"); map.put("IBM870", "CP870"); map.put("CP870", "CP870"); map.put("CSIBM870", "CP870"); map.put("EBCDIC-CP-ROECE", "CP870"); map.put("EBCDIC-CP-YU", "CP870"); map.put("IBM871", "CP871"); map.put("CP871", "CP871"); map.put("CSIBM871", "CP871"); map.put("EBCDIC-CP-IS", "CP871"); map.put("IBM918", "CP918"); map.put("CP918", "CP918"); map.put("CSIBM918", "CP918"); map.put("EBCDIC-CP-AR2", "CP918"); map.put("EUC-JP", "EUCJIS"); map.put("CSEUCPkdFmtJapanese", "EUCJIS"); map.put("EUC-KR", "KSC5601"); map.put("GB2312", "GB2312"); map.put("CSGB2312", "GB2312"); map.put("ISO-2022-JP", "JIS"); map.put("CSISO2022JP", "JIS"); map.put("ISO-2022-KR", "ISO2022KR"); map.put("CSISO2022KR", "ISO2022KR"); map.put("ISO-2022-CN", "ISO2022CN"); map.put("X0201", "JIS0201"); map.put("CSISO13JISC6220JP", "JIS0201"); map.put("X0208", "JIS0208"); map.put("ISO-IR-87", "JIS0208"); map.put("X0208dbiJIS_X0208-1983", "JIS0208"); map.put("CSISO87JISX0208", "JIS0208"); map.put("X0212", "JIS0212"); map.put("ISO-IR-159", "JIS0212"); map.put("CSISO159JISX02121990", "JIS0212"); map.put("SHIFT_JIS", "SJIS"); map.put("CSSHIFT_JIS", "SJIS"); map.put("MS_Kanji", "SJIS"); // Add support for Cp1252 and its friends map.put("WINDOWS-1250", "Cp1250"); map.put("WINDOWS-1251", "Cp1251"); map.put("WINDOWS-1252", "Cp1252"); map.put("WINDOWS-1253", "Cp1253"); map.put("WINDOWS-1254", "Cp1254"); map.put("WINDOWS-1255", "Cp1255"); map.put("WINDOWS-1256", "Cp1256"); map.put("WINDOWS-1257", "Cp1257"); map.put("WINDOWS-1258", "Cp1258"); map.put("TIS-620", "TIS620"); map.put("ISO-8859-1", "ISO8859_1"); map.put("ISO-IR-100", "ISO8859_1"); map.put("ISO_8859-1", "ISO8859_1"); map.put("LATIN1", "ISO8859_1"); map.put("CSISOLATIN1", "ISO8859_1"); map.put("L1", "ISO8859_1"); map.put("IBM819", "ISO8859_1"); map.put("CP819", "ISO8859_1"); map.put("ISO-8859-2", "ISO8859_2"); map.put("ISO-IR-101", "ISO8859_2"); map.put("ISO_8859-2", "ISO8859_2"); map.put("LATIN2", "ISO8859_2"); map.put("CSISOLATIN2", "ISO8859_2"); map.put("L2", "ISO8859_2"); map.put("ISO-8859-3", "ISO8859_3"); map.put("ISO-IR-109", "ISO8859_3"); map.put("ISO_8859-3", "ISO8859_3"); map.put("LATIN3", "ISO8859_3"); map.put("CSISOLATIN3", "ISO8859_3"); map.put("L3", "ISO8859_3"); map.put("ISO-8859-4", "ISO8859_4"); map.put("ISO-IR-110", "ISO8859_4"); map.put("ISO_8859-4", "ISO8859_4"); map.put("LATIN4", "ISO8859_4"); map.put("CSISOLATIN4", "ISO8859_4"); map.put("L4", "ISO8859_4"); map.put("ISO-8859-5", "ISO8859_5"); map.put("ISO-IR-144", "ISO8859_5"); map.put("ISO_8859-5", "ISO8859_5"); map.put("CYRILLIC", "ISO8859_5"); map.put("CSISOLATINCYRILLIC", "ISO8859_5"); map.put("ISO-8859-6", "ISO8859_6"); map.put("ISO-IR-127", "ISO8859_6"); map.put("ISO_8859-6", "ISO8859_6"); map.put("ECMA-114", "ISO8859_6"); map.put("ASMO-708", "ISO8859_6"); map.put("ARABIC", "ISO8859_6"); map.put("CSISOLATINARABIC", "ISO8859_6"); map.put("ISO-8859-7", "ISO8859_7"); map.put("ISO-IR-126", "ISO8859_7"); map.put("ISO_8859-7", "ISO8859_7"); map.put("ELOT_928", "ISO8859_7"); map.put("ECMA-118", "ISO8859_7"); map.put("GREEK", "ISO8859_7"); map.put("CSISOLATINGREEK", "ISO8859_7"); map.put("GREEK8", "ISO8859_7"); map.put("ISO-8859-8", "ISO8859_8"); map.put("ISO-8859-8-I", "ISO8859_8"); // added since this encoding only differs w.r.t. presentation map.put("ISO-IR-138", "ISO8859_8"); map.put("ISO_8859-8", "ISO8859_8"); map.put("HEBREW", "ISO8859_8"); map.put("CSISOLATINHEBREW", "ISO8859_8"); map.put("ISO-8859-9", "ISO8859_9"); map.put("ISO-IR-148", "ISO8859_9"); map.put("ISO_8859-9", "ISO8859_9"); map.put("LATIN5", "ISO8859_9"); map.put("CSISOLATIN5", "ISO8859_9"); map.put("L5", "ISO8859_9"); map.put("KOI8-R", "KOI8_R"); map.put("CSKOI8-R", "KOI8_R"); map.put("US-ASCII", "ASCII"); map.put("ISO-IR-6", "ASCII"); map.put("ANSI_X3.4-1986", "ASCII"); map.put("ISO_646.IRV:1991", "ASCII"); map.put("ASCII", "ASCII"); map.put("CSASCII", "ASCII"); map.put("ISO646-US", "ASCII"); map.put("US", "ASCII"); map.put("IBM367", "ASCII"); map.put("CP367", "ASCII"); map.put("UTF-8", "UTF8"); map.put("UTF-16", "Unicode"); map.put("UTF-16BE", "UnicodeBig"); map.put("UTF-16LE", "UnicodeLittle"); } /** * Gets the java encoding from the IANA encoding. If the encoding cannot be found * it returns the input. * @param iana the IANA encoding * @return the java encoding */ public static String getJavaEncoding(String iana) { String IANA = iana.toUpperCase(); String jdec = (String)map.get(IANA); if (jdec == null) jdec = iana; return jdec; } } src/core/com/lowagie/text/xml/simpleparser/SimpleXMLDocHandler.java100644 0 0 6413 11000354016 23016 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.simpleparser; import java.util.HashMap; /** * The handler for the events fired by SimpleXMLParser. * @author Paulo Soares (psoares@consiste.pt) */ public interface SimpleXMLDocHandler { /** * Called when a start tag is found. * @param tag the tag name * @param h the tag's attributes */ public void startElement(String tag, HashMap h); /** * Called when an end tag is found. * @param tag the tag name */ public void endElement(String tag); /** * Called when the document starts to be parsed. */ public void startDocument(); /** * Called after the document is parsed. */ public void endDocument(); /** * Called when a text element is found. * @param str the text element, probably a fragment. */ public void text(String str); }src/core/com/lowagie/text/xml/simpleparser/SimpleXMLDocHandlerComment.java100644 0 0 5337 11000354016 24345 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.simpleparser; /** * The handler for the events fired by SimpleXMLParser. * @author Paulo Soares (psoares@consiste.pt) */ public interface SimpleXMLDocHandlerComment { /** * Called when a comment is found. * @param text the comment text */ public void comment(String text); }src/core/com/lowagie/text/xml/simpleparser/SimpleXMLParser.java100644 0 0 66514 11213370067 22311 0ustar 0 0 /* * Copyright 2003 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ * * The code to recognize the encoding in this class and in the convenience class IanaEncodings was taken from Apache Xerces published under the following license: * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Part of this code is based on the Quick-and-Dirty XML parser by Steven Brandt. * The code for the Quick-and-Dirty parser was published in JavaWorld (java tip 128). * Steven Brandt and JavaWorld gave permission to use the code for free. * (Bruno Lowagie and Paulo Soares chose to use it under the MPL/LGPL in * conformance with the rest of the code). * The original code can be found on this url: http://www.javaworld.com/javatips/jw-javatip128_p.html. * It was substantially refactored by Bruno Lowagie. * * The method 'private static String getEncodingName(byte[] b4)' was found * in org.apache.xerces.impl.XMLEntityManager, originaly published by the * Apache Software Foundation under the Apache Software License; now being * used in iText under the MPL. */ package com.lowagie.text.xml.simpleparser; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.HashMap; import java.util.Stack; /** * A simple XML and HTML parser. This parser is, like the SAX parser, * an event based parser, but with much less functionality. *

      * The parser can: *

      *

        *
      • It recognizes the encoding used *
      • It recognizes all the elements' start tags and end tags *
      • It lists attributes, where attribute values can be enclosed in single or double quotes *
      • It recognizes the <[CDATA[ ... ]]> construct *
      • It recognizes the standard entities: &amp;, &lt;, &gt;, &quot;, and &apos;, as well as numeric entities *
      • It maps lines ending in \r\n and \r to \n on input, in accordance with the XML Specification, Section 2.11 *
      *

      */ public final class SimpleXMLParser { /** possible states */ private final static int UNKNOWN = 0; private final static int TEXT = 1; private final static int TAG_ENCOUNTERED = 2; private final static int EXAMIN_TAG = 3; private final static int TAG_EXAMINED = 4; private final static int IN_CLOSETAG = 5; private final static int SINGLE_TAG = 6; private final static int CDATA = 7; private final static int COMMENT = 8; private final static int PI = 9; private final static int ENTITY = 10; private final static int QUOTE = 11; private final static int ATTRIBUTE_KEY = 12; private final static int ATTRIBUTE_EQUAL = 13; private final static int ATTRIBUTE_VALUE = 14; /** the state stack */ Stack stack; /** The current character. */ int character = 0; /** The previous character. */ int previousCharacter = -1; /** the line we are currently reading */ int lines = 1; /** the column where the current character occurs */ int columns = 0; /** was the last character equivalent to a newline? */ boolean eol = false; /** * A boolean indicating if the next character should be taken into account * if it's a space character. When nospace is false, the previous character * wasn't whitespace. * @since 2.1.5 */ boolean nowhite = false; /** the current state */ int state; /** Are we parsing HTML? */ boolean html; /** current text (whatever is encountered between tags) */ StringBuffer text = new StringBuffer(); /** current entity (whatever is encountered between & and ;) */ StringBuffer entity = new StringBuffer(); /** current tagname */ String tag = null; /** current attributes */ HashMap attributes = null; /** The handler to which we are going to forward document content */ SimpleXMLDocHandler doc; /** The handler to which we are going to forward comments. */ SimpleXMLDocHandlerComment comment; /** Keeps track of the number of tags that are open. */ int nested = 0; /** the quote character that was used to open the quote. */ int quoteCharacter = '"'; /** the attribute key. */ String attributekey = null; /** the attribute value. */ String attributevalue = null; /** * Creates a Simple XML parser object. * Call go(BufferedReader) immediately after creation. */ private SimpleXMLParser(SimpleXMLDocHandler doc, SimpleXMLDocHandlerComment comment, boolean html) { this.doc = doc; this.comment = comment; this.html = html; stack = new Stack(); state = html ? TEXT : UNKNOWN; } /** * Does the actual parsing. Perform this immediately * after creating the parser object. */ private void go(Reader r) throws IOException { BufferedReader reader; if (r instanceof BufferedReader) reader = (BufferedReader)r; else reader = new BufferedReader(r); doc.startDocument(); while(true) { // read a new character if (previousCharacter == -1) { character = reader.read(); } // or re-examine the previous character else { character = previousCharacter; previousCharacter = -1; } // the end of the file was reached if (character == -1) { if (html) { if (html && state == TEXT) flush(); doc.endDocument(); } else { throwException("Missing end tag"); } return; } // dealing with \n and \r if (character == '\n' && eol) { eol = false; continue; } else if (eol) { eol = false; } else if (character == '\n') { lines++; columns = 0; } else if (character == '\r') { eol = true; character = '\n'; lines++; columns = 0; } else { columns++; } switch(state) { // we are in an unknown state before there's actual content case UNKNOWN: if(character == '<') { saveState(TEXT); state = TAG_ENCOUNTERED; } break; // we can encounter any content case TEXT: if(character == '<') { flush(); saveState(state); state = TAG_ENCOUNTERED; } else if(character == '&') { saveState(state); entity.setLength(0); state = ENTITY; } else if (Character.isWhitespace((char)character)) { if (nowhite) text.append((char)character); nowhite = false; } else { text.append((char)character); nowhite = true; } break; // we have just seen a < and are wondering what we are looking at // , , , etc. case TAG_ENCOUNTERED: initTag(); if(character == '/') { state = IN_CLOSETAG; } else if (character == '?') { restoreState(); state = PI; } else { text.append((char)character); state = EXAMIN_TAG; } break; // we are processing something like this . // It could still be a or something. case EXAMIN_TAG: if(character == '>') { doTag(); processTag(true); initTag(); state = restoreState(); } else if(character == '/') { state = SINGLE_TAG; } else if(character == '-' && text.toString().equals("!-")) { flush(); state = COMMENT; } else if(character == '[' && text.toString().equals("![CDATA")) { flush(); state = CDATA; } else if(character == 'E' && text.toString().equals("!DOCTYP")) { flush(); state = PI; } else if(Character.isWhitespace((char)character)) { doTag(); state = TAG_EXAMINED; } else { text.append((char)character); } break; // we know the name of the tag now. case TAG_EXAMINED: if(character == '>') { processTag(true); initTag(); state = restoreState(); } else if(character == '/') { state = SINGLE_TAG; } else if(Character.isWhitespace((char)character)) { // empty } else { text.append((char)character); state = ATTRIBUTE_KEY; } break; // we are processing a closing tag: e.g. case IN_CLOSETAG: if(character == '>') { doTag(); processTag(false); if(!html && nested==0) return; state = restoreState(); } else { if (!Character.isWhitespace((char)character)) text.append((char)character); } break; // we have just seen something like this: . case SINGLE_TAG: if(character != '>') throwException("Expected > for tag: <"+tag+"/>"); doTag(); processTag(true); processTag(false); initTag(); if(!html && nested==0) { doc.endDocument(); return; } state = restoreState(); break; // we are processing CDATA case CDATA: if(character == '>' && text.toString().endsWith("]]")) { text.setLength(text.length()-2); flush(); state = restoreState(); } else text.append((char)character); break; // we are processing a comment. We are inside // the looking for the -->. case COMMENT: if(character == '>' && text.toString().endsWith("--")) { text.setLength(text.length() - 2); flush(); state = restoreState(); } else text.append((char)character); break; // We are inside one of these or one of these case PI: if(character == '>') { state = restoreState(); if(state == TEXT) state = UNKNOWN; } break; // we are processing an entity, e.g. <, », etc. case ENTITY: if(character == ';') { state = restoreState(); String cent = entity.toString(); entity.setLength(0); char ce = EntitiesToUnicode.decodeEntity(cent); if (ce == '\0') text.append('&').append(cent).append(';'); else text.append(ce); } else if ((character != '#' && (character < '0' || character > '9') && (character < 'a' || character > 'z') && (character < 'A' || character > 'Z')) || entity.length() >= 7) { state = restoreState(); previousCharacter = character; text.append('&').append(entity.toString()); entity.setLength(0); } else { entity.append((char)character); } break; // We are processing the quoted right-hand side of an element's attribute. case QUOTE: if (html && quoteCharacter == ' ' && character == '>') { flush(); processTag(true); initTag(); state = restoreState(); } else if (html && quoteCharacter == ' ' && Character.isWhitespace((char)character)) { flush(); state = TAG_EXAMINED; } else if (html && quoteCharacter == ' ') { text.append((char)character); } else if(character == quoteCharacter) { flush(); state = TAG_EXAMINED; } else if(" \r\n\u0009".indexOf(character)>=0) { text.append(' '); } else if(character == '&') { saveState(state); state = ENTITY; entity.setLength(0); } else { text.append((char)character); } break; case ATTRIBUTE_KEY: if(Character.isWhitespace((char)character)) { flush(); state = ATTRIBUTE_EQUAL; } else if(character == '=') { flush(); state = ATTRIBUTE_VALUE; } else if (html && character == '>') { text.setLength(0); processTag(true); initTag(); state = restoreState(); } else { text.append((char)character); } break; case ATTRIBUTE_EQUAL: if(character == '=') { state = ATTRIBUTE_VALUE; } else if(Character.isWhitespace((char)character)) { // empty } else if (html && character == '>') { text.setLength(0); processTag(true); initTag(); state = restoreState(); } else if (html && character == '/') { flush(); state = SINGLE_TAG; } else if (html) { flush(); text.append((char)character); state = ATTRIBUTE_KEY; } else { throwException("Error in attribute processing."); } break; case ATTRIBUTE_VALUE: if(character == '"' || character == '\'') { quoteCharacter = character; state = QUOTE; } else if(Character.isWhitespace((char)character)) { // empty } else if (html && character == '>') { flush(); processTag(true); initTag(); state = restoreState(); } else if (html) { text.append((char)character); quoteCharacter = ' '; state = QUOTE; } else { throwException("Error in attribute processing"); } break; } } } /** * Gets a state from the stack * @return the previous state */ private int restoreState() { if(!stack.empty()) return ((Integer)stack.pop()).intValue(); else return UNKNOWN; } /** * Adds a state to the stack. * @param s a state to add to the stack */ private void saveState(int s) { stack.push(new Integer(s)); } /** * Flushes the text that is currently in the buffer. * The text can be ignored, added to the document * as content or as comment,... depending on the current state. */ private void flush() { switch(state){ case TEXT: case CDATA: if(text.length() > 0) { doc.text(text.toString()); } break; case COMMENT: if (comment != null) { comment.comment(text.toString()); } break; case ATTRIBUTE_KEY: attributekey = text.toString(); if (html) attributekey = attributekey.toLowerCase(); break; case QUOTE: case ATTRIBUTE_VALUE: attributevalue = text.toString(); attributes.put(attributekey,attributevalue); break; default: // do nothing } text.setLength(0); } /** * Initialized the tag name and attributes. */ private void initTag() { tag = null; attributes = new HashMap(); } /** Sets the name of the tag. */ private void doTag() { if(tag == null) tag = text.toString(); if (html) tag = tag.toLowerCase(); text.setLength(0); } /** * processes the tag. * @param start if true we are dealing with a tag that has just been opened; if false we are closing a tag. */ private void processTag(boolean start) { if (start) { nested++; doc.startElement(tag,attributes); } else { nested--; doc.endElement(tag); } } /** Throws an exception */ private void throwException(String s) throws IOException { throw new IOException(s+" near line " + lines + ", column " + columns); } /** * Parses the XML document firing the events to the handler. * @param doc the document handler * @param r the document. The encoding is already resolved. The reader is not closed * @throws IOException on error */ public static void parse(SimpleXMLDocHandler doc, SimpleXMLDocHandlerComment comment, Reader r, boolean html) throws IOException { SimpleXMLParser parser = new SimpleXMLParser(doc, comment, html); parser.go(r); } /** * Parses the XML document firing the events to the handler. * @param doc the document handler * @param in the document. The encoding is deduced from the stream. The stream is not closed * @throws IOException on error */ public static void parse(SimpleXMLDocHandler doc, InputStream in) throws IOException { byte b4[] = new byte[4]; int count = in.read(b4); if (count != 4) throw new IOException("Insufficient length."); String encoding = getEncodingName(b4); String decl = null; if (encoding.equals("UTF-8")) { StringBuffer sb = new StringBuffer(); int c; while ((c = in.read()) != -1) { if (c == '>') break; sb.append((char)c); } decl = sb.toString(); } else if (encoding.equals("CP037")) { ByteArrayOutputStream bi = new ByteArrayOutputStream(); int c; while ((c = in.read()) != -1) { if (c == 0x6e) // that's '>' in ebcdic break; bi.write(c); } decl = new String(bi.toByteArray(), "CP037"); } if (decl != null) { decl = getDeclaredEncoding(decl); if (decl != null) encoding = decl; } parse(doc, new InputStreamReader(in, IanaEncodings.getJavaEncoding(encoding))); } private static String getDeclaredEncoding(String decl) { if (decl == null) return null; int idx = decl.indexOf("encoding"); if (idx < 0) return null; int idx1 = decl.indexOf('"', idx); int idx2 = decl.indexOf('\'', idx); if (idx1 == idx2) return null; if ((idx1 < 0 && idx2 > 0) || (idx2 > 0 && idx2 < idx1)) { int idx3 = decl.indexOf('\'', idx2 + 1); if (idx3 < 0) return null; return decl.substring(idx2 + 1, idx3); } if ((idx2 < 0 && idx1 > 0) || (idx1 > 0 && idx1 < idx2)) { int idx3 = decl.indexOf('"', idx1 + 1); if (idx3 < 0) return null; return decl.substring(idx1 + 1, idx3); } return null; } public static void parse(SimpleXMLDocHandler doc,Reader r) throws IOException { parse(doc, null, r, false); } /** * Escapes a string with the appropriated XML codes. * @param s the string to be escaped * @param onlyASCII codes above 127 will always be escaped with &#nn; if true * @return the escaped string */ public static String escapeXML(String s, boolean onlyASCII) { char cc[] = s.toCharArray(); int len = cc.length; StringBuffer sb = new StringBuffer(); for (int k = 0; k < len; ++k) { int c = cc[k]; switch (c) { case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("""); break; case '\'': sb.append("'"); break; default: if ((c == 0x9) || (c == 0xA) || (c == 0xD) || ((c >= 0x20) && (c <= 0xD7FF)) || ((c >= 0xE000) && (c <= 0xFFFD)) || ((c >= 0x10000) && (c <= 0x10FFFF))) { if (onlyASCII && c > 127) sb.append("&#").append(c).append(';'); else sb.append((char)c); } } } return sb.toString(); } /** * Returns the IANA encoding name that is auto-detected from * the bytes specified, with the endian-ness of that encoding where appropriate. * (method found in org.apache.xerces.impl.XMLEntityManager, originally published * by the Apache Software Foundation under the Apache Software License; now being * used in iText under the MPL) * @param b4 The first four bytes of the input. * @return an IANA-encoding string */ private static String getEncodingName(byte[] b4) { // UTF-16, with BOM int b0 = b4[0] & 0xFF; int b1 = b4[1] & 0xFF; if (b0 == 0xFE && b1 == 0xFF) { // UTF-16, big-endian return "UTF-16BE"; } if (b0 == 0xFF && b1 == 0xFE) { // UTF-16, little-endian return "UTF-16LE"; } // UTF-8 with a BOM int b2 = b4[2] & 0xFF; if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { return "UTF-8"; } // other encodings int b3 = b4[3] & 0xFF; if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) { // UCS-4, big endian (1234) return "ISO-10646-UCS-4"; } if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) { // UCS-4, little endian (4321) return "ISO-10646-UCS-4"; } if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) { // UCS-4, unusual octet order (2143) // REVISIT: What should this be? return "ISO-10646-UCS-4"; } if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) { // UCS-4, unusual octet order (3412) // REVISIT: What should this be? return "ISO-10646-UCS-4"; } if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { // UTF-16, big-endian, no BOM // (or could turn out to be UCS-2... // REVISIT: What should this be? return "UTF-16BE"; } if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { // UTF-16, little-endian, no BOM // (or could turn out to be UCS-2... return "UTF-16LE"; } if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) { // EBCDIC // a la xerces1, return CP037 instead of EBCDIC here return "CP037"; } // default encoding return "UTF-8"; } }src/core/com/lowagie/text/xml/xmp/DublinCoreSchema.java100644 0 0 15333 11106243444 20557 0ustar 0 0 /* * $Id: DublinCoreSchema.java 3596 2008-10-10 11:37:58Z psoares33 $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; /** * An implementation of an XmpSchema. */ public class DublinCoreSchema extends XmpSchema { private static final long serialVersionUID = -4551741356374797330L; /** default namespace identifier*/ public static final String DEFAULT_XPATH_ID = "dc"; /** default namespace uri*/ public static final String DEFAULT_XPATH_URI = "http://purl.org/dc/elements/1.1/"; /** External Contributors to the resource (other than the authors). */ public static final String CONTRIBUTOR = "dc:contributor"; /** The extent or scope of the resource. */ public static final String COVERAGE = "dc:coverage"; /** The authors of the resource (listed in order of precedence, if significant). */ public static final String CREATOR = "dc:creator"; /** Date(s) that something interesting happened to the resource. */ public static final String DATE = "dc:date"; /** A textual description of the content of the resource. Multiple values may be present for different languages. */ public static final String DESCRIPTION = "dc:description"; /** The file format used when saving the resource. Tools and applications should set this property to the save format of the data. It may include appropriate qualifiers. */ public static final String FORMAT = "dc:format"; /** Unique identifier of the resource. */ public static final String IDENTIFIER = "dc:identifier"; /** An unordered array specifying the languages used in the resource. */ public static final String LANGUAGE = "dc:language"; /** Publishers. */ public static final String PUBLISHER = "dc:publisher"; /** Relationships to other documents. */ public static final String RELATION = "dc:relation"; /** Informal rights statement, selected by language. */ public static final String RIGHTS = "dc:rights"; /** Unique identifier of the work from which this resource was derived. */ public static final String SOURCE = "dc:source"; /** An unordered array of descriptive phrases or keywords that specify the topic of the content of the resource. */ public static final String SUBJECT = "dc:subject"; /** The title of the document, or the name given to the resource. Typically, it will be a name by which the resource is formally known. */ public static final String TITLE = "dc:title"; /** A document type; for example, novel, poem, or working paper. */ public static final String TYPE = "dc:type"; public DublinCoreSchema() { super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\""); setProperty(FORMAT, "application/pdf"); } /** * Adds a title. * @param title */ public void addTitle(String title) { XmpArray array = new XmpArray(XmpArray.ALTERNATIVE); array.add(title); setProperty(TITLE, array); } /** * Adds a description. * @param desc */ public void addDescription(String desc) { XmpArray array = new XmpArray(XmpArray.ALTERNATIVE); array.add(desc); setProperty(DESCRIPTION, array); } /** * Adds a subject. * @param subject */ public void addSubject(String subject) { XmpArray array = new XmpArray(XmpArray.UNORDERED); array.add(subject); setProperty(SUBJECT, array); } /** * Adds a subject. * @param subject array of subjects */ public void addSubject(String[] subject) { XmpArray array = new XmpArray(XmpArray.UNORDERED); for (int i = 0; i < subject.length; i++) { array.add(subject[i]); } setProperty(SUBJECT, array); } /** * Adds a single author. * @param author */ public void addAuthor(String author) { XmpArray array = new XmpArray(XmpArray.ORDERED); array.add(author); setProperty(CREATOR, array); } /** * Adds an array of authors. * @param author */ public void addAuthor(String[] author) { XmpArray array = new XmpArray(XmpArray.ORDERED); for (int i = 0; i < author.length; i++) { array.add(author[i]); } setProperty(CREATOR, array); } /** * Adds a single publisher. * @param publisher */ public void addPublisher(String publisher) { XmpArray array = new XmpArray(XmpArray.ORDERED); array.add(publisher); setProperty(PUBLISHER, array); } /** * Adds an array of publishers. * @param publisher */ public void addPublisher(String[] publisher) { XmpArray array = new XmpArray(XmpArray.ORDERED); for (int i = 0; i < publisher.length; i++) { array.add(publisher[i]); } setProperty(PUBLISHER, array); } } src/core/com/lowagie/text/xml/xmp/LangAlt.java100644 0 0 7312 11012562265 16711 0ustar 0 0 /* * $Id: LangAlt.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Armin Haberling * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import java.util.Enumeration; import java.util.Properties; public class LangAlt extends Properties { /** A serial version id. */ private static final long serialVersionUID = 4396971487200843099L; /** Key for the default language. */ public static final String DEFAULT = "x-default"; /** Creates a Properties object that stores languages for use in an XmpSchema */ public LangAlt(String defaultValue) { super(); addLanguage(DEFAULT, defaultValue); } /** Creates a Properties object that stores languages for use in an XmpSchema */ public LangAlt() { super(); } /** * Add a language. */ public void addLanguage(String language, String value) { setProperty(language, XmpSchema.escape(value)); } /** * Process a property. */ protected void process(StringBuffer buf, Object lang) { buf.append(""); buf.append(get(lang)); buf.append(""); } /** * Creates a String that can be used in an XmpSchema. */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append(""); for (Enumeration e = this.propertyNames(); e.hasMoreElements();) { process(sb, e.nextElement()); } sb.append(""); return sb.toString(); } }src/core/com/lowagie/text/xml/xmp/PdfA1Schema.java100644 0 0 7055 11012562265 17407 0ustar 0 0 /* * $Id: PdfA1Schema.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; /** * An implementation of an XmpSchema. */ public class PdfA1Schema extends XmpSchema { private static final long serialVersionUID = 5300646133692948168L; /** default namespace identifier*/ public static final String DEFAULT_XPATH_ID = "pdfaid"; /** default namespace uri*/ public static final String DEFAULT_XPATH_URI = "http://www.aiim.org/pdfa/ns/id/"; /** Part, always 1. */ public static final String PART = "pdfaid:part"; /** Conformance, A or B. */ public static final String CONFORMANCE = "pdfaid:conformance"; public PdfA1Schema() { super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\""); addPart("1"); } /** * Adds part. * @param part */ public void addPart(String part) { setProperty(PART, part); } /** * Adds the conformance. * @param conformance */ public void addConformance(String conformance) { setProperty(CONFORMANCE, conformance); } }src/core/com/lowagie/text/xml/xmp/PdfSchema.java100644 0 0 7216 11154165264 17231 0ustar 0 0 /* * $Id: PdfSchema.java 3676 2009-02-04 09:50:07Z blowagie $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import com.lowagie.text.Document; /** * An implementation of an XmpSchema. */ public class PdfSchema extends XmpSchema { private static final long serialVersionUID = -1541148669123992185L; /** default namespace identifier*/ public static final String DEFAULT_XPATH_ID = "pdf"; /** default namespace uri*/ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/pdf/1.3/"; /** Keywords. */ public static final String KEYWORDS = "pdf:keywords"; /** The PDF file version (for example: 1.0, 1.3, and so on). */ public static final String VERSION = "pdf:PDFVersion"; /** The Producer. */ public static final String PRODUCER = "pdf:Producer"; public PdfSchema() { super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\""); addProducer(Document.getVersion()); } /** * Adds keywords. * @param keywords */ public void addKeywords(String keywords) { setProperty(KEYWORDS, keywords); } /** * Adds the producer. * @param producer */ public void addProducer(String producer) { setProperty(PRODUCER, producer); } /** * Adds the version. * @param version */ public void addVersion(String version) { setProperty(VERSION, version); } } src/core/com/lowagie/text/xml/xmp/XmpArray.java100644 0 0 7152 11012562265 17134 0ustar 0 0 /* * $Id: XmpArray.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import java.util.ArrayList; import java.util.Iterator; /** * StringBuffer to construct an XMP array. */ public class XmpArray extends ArrayList { private static final long serialVersionUID = 5722854116328732742L; /** An array that is unordered. */ public static final String UNORDERED = "rdf:Bag"; /** An array that is ordered. */ public static final String ORDERED = "rdf:Seq"; /** An array with alternatives. */ public static final String ALTERNATIVE = "rdf:Alt"; /** the type of array. */ protected String type; /** * Creates an XmpArray. * @param type the type of array: UNORDERED, ORDERED or ALTERNATIVE. */ public XmpArray(String type) { this.type = type; } /** * Returns the String representation of the XmpArray. * @return a String representation */ public String toString() { StringBuffer buf = new StringBuffer("<"); buf.append(type); buf.append('>'); String s; for (Iterator i = iterator(); i.hasNext(); ) { s = (String) i.next(); buf.append(""); buf.append(XmpSchema.escape(s)); buf.append(""); } buf.append("'); return buf.toString(); } }src/core/com/lowagie/text/xml/xmp/XmpBasicSchema.java100644 0 0 13042 11012562265 20233 0ustar 0 0 /* * $Id: XmpBasicSchema.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; /** * An implementation of an XmpSchema. */ public class XmpBasicSchema extends XmpSchema { private static final long serialVersionUID = -2416613941622479298L; /** default namespace identifier*/ public static final String DEFAULT_XPATH_ID = "xmp"; /** default namespace uri*/ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/xap/1.0/"; /** An unordered array specifying properties that were edited outside the authoring application. Each item should contain a single namespace and XPath separated by one ASCII space (U+0020). */ public static final String ADVISORY = "xmp:Advisory"; /** The base URL for relative URLs in the document content. If this document contains Internet links, and those links are relative, they are relative to this base URL. This property provides a standard way for embedded relative URLs to be interpreted by tools. Web authoring tools should set the value based on their notion of where URLs will be interpreted. */ public static final String BASEURL = "xmp:BaseURL"; /** The date and time the resource was originally created. */ public static final String CREATEDATE = "xmp:CreateDate"; /** The name of the first known tool used to create the resource. If history is present in the metadata, this value should be equivalent to that of xmpMM:History's softwareAgent property. */ public static final String CREATORTOOL = "xmp:CreatorTool"; /** An unordered array of text strings that unambiguously identify the resource within a given context. */ public static final String IDENTIFIER = "xmp:Identifier"; /** The date and time that any metadata for this resource was last changed. */ public static final String METADATADATE = "xmp:MetadataDate"; /** The date and time the resource was last modified. */ public static final String MODIFYDATE = "xmp:ModifyDate"; /** A short informal name for the resource. */ public static final String NICKNAME = "xmp:Nickname"; /** An alternative array of thumbnail images for a file, which can differ in characteristics such as size or image encoding. */ public static final String THUMBNAILS = "xmp:Thumbnails"; public XmpBasicSchema() { super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\""); } /** * Adds the creatortool. * @param creator */ public void addCreatorTool(String creator) { setProperty(CREATORTOOL, creator); } /** * Adds the creation date. * @param date */ public void addCreateDate(String date) { setProperty(CREATEDATE, date); } /** * Adds the modification date. * @param date */ public void addModDate(String date) { setProperty(MODIFYDATE, date); } /** * Adds the meta data date. * @param date */ public void addMetaDataDate(String date) { setProperty(METADATADATE, date); } /** Adds the identifier. * @param id */ public void addIdentifiers(String[] id) { XmpArray array = new XmpArray(XmpArray.UNORDERED); for (int i = 0; i < id.length; i++) { array.add(id[i]); } setProperty(IDENTIFIER, array); } /** Adds the nickname. * @param name */ public void addNickname(String name) { setProperty(NICKNAME, name); } } src/core/com/lowagie/text/xml/xmp/XmpMMSchema.java100644 0 0 13045 11012562265 17526 0ustar 0 0 /* * $Id: XmpMMSchema.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; /** * An implementation of an XmpSchema. */ public class XmpMMSchema extends XmpSchema { private static final long serialVersionUID = 1408509596611634862L; /** default namespace identifier*/ public static final String DEFAULT_XPATH_ID = "xmpMM"; /** default namespace uri*/ public static final String DEFAULT_XPATH_URI = "http://ns.adobe.com/xap/1.0/mm/"; /** A reference to the original document from which this one is derived. It is a minimal reference; missing components can be assumed to be unchanged. For example, a new version might only need to specify the instance ID and version number of the previous version, or a rendition might only need to specify the instance ID and rendition class of the original. */ public static final String DERIVEDFROM = "xmpMM:DerivedFrom"; /** The common identifier for all versions and renditions of a document. */ public static final String DOCUMENTID = "xmpMM:DocumentID"; /** An ordered array of high-level user actions that resulted in this resource. It is intended to give human readers a general indication of the steps taken to make the changes from the previous version to this one. The list should be at an abstract level; it is not intended to be an exhaustive keystroke or other detailed history. */ public static final String HISTORY = "xmpMM:History"; /** A reference to the document as it was prior to becoming managed. It is set when a managed document is introduced to an asset management system that does not currently own it. It may or may not include references to different management systems. */ public static final String MANAGEDFROM = "xmpMM:ManagedFrom"; /** The name of the asset management system that manages this resource. */ public static final String MANAGER = "xmpMM:Manager"; /** A URI identifying the managed resource to the asset management system; the presence of this property is the formal indication that this resource is managed. The form and content of this URI is private to the asset management system. */ public static final String MANAGETO = "xmpMM:ManageTo"; /** A URI that can be used to access information about the managed resource through a web browser. It might require a custom browser plugin. */ public static final String MANAGEUI = "xmpMM:ManageUI"; /** Specifies a particular variant of the asset management system. The format of this property is private to the specific asset management system. */ public static final String MANAGERVARIANT = "xmpMM:ManagerVariant"; /** The rendition class name for this resource.*/ public static final String RENDITIONCLASS = "xmpMM:RenditionClass"; /** Can be used to provide additional rendition parameters that are too complex or verbose to encode in xmpMM: RenditionClass. */ public static final String RENDITIONPARAMS = "xmpMM:RenditionParams"; /** The document version identifier for this resource. */ public static final String VERSIONID = "xmpMM:VersionID"; /** The version history associated with this resource.*/ public static final String VERSIONS = "xmpMM:Versions"; public XmpMMSchema() { super("xmlns:" + DEFAULT_XPATH_ID + "=\"" + DEFAULT_XPATH_URI + "\""); } } src/core/com/lowagie/text/xml/xmp/XmpReader.java100644 0 0 15336 11213370067 17303 0ustar 0 0 /* * Copyright 2008 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2008 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.xml.XmlDomWriter; /** * Reads an XMP stream into an org.w3c.dom.Document objects. * Allows you to replace the contents of a specific tag. * @since 2.1.3 */ public class XmpReader { private Document domDocument; /** * Constructs an XMP reader * @param bytes the XMP content * @throws ExceptionConverter * @throws IOException * @throws SAXException */ public XmpReader(byte[] bytes) throws SAXException, IOException { try { DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance(); fact.setNamespaceAware(true); DocumentBuilder db = fact.newDocumentBuilder(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); domDocument = db.parse(bais); } catch (ParserConfigurationException e) { throw new ExceptionConverter(e); } } /** * Replaces the content of a tag. * @param namespaceURI the URI of the namespace * @param localName the tag name * @param value the new content for the tag * @return true if the content was successfully replaced * @since 2.1.6 the return type has changed from void to boolean */ public boolean replace(String namespaceURI, String localName, String value) { NodeList nodes = domDocument.getElementsByTagNameNS(namespaceURI, localName); Node node; if (nodes.getLength() == 0) return false; for (int i = 0; i < nodes.getLength(); i++) { node = nodes.item(i); setNodeText(domDocument, node, value); } return true; } /** * Adds a tag. * @param namespaceURI the URI of the namespace * @param parent the tag name of the parent * @param localName the name of the tag to add * @param value the new content for the tag * @return true if the content was successfully added * @since 2.1.6 */ public boolean add(String parent, String namespaceURI, String localName, String value) { NodeList nodes = domDocument.getElementsByTagName(parent); if (nodes.getLength() == 0) return false; Node pNode; Node node; for (int i = 0; i < nodes.getLength(); i++) { pNode = nodes.item(i); NamedNodeMap attrs = pNode.getAttributes(); for (int j = 0; j < attrs.getLength(); j++) { node = attrs.item(j); if (namespaceURI.equals(node.getNodeValue())) { node = domDocument.createElement(localName); node.appendChild(domDocument.createTextNode(value)); pNode.appendChild(node); return true; } } } return false; } /** * Sets the text of this node. All the child's node are deleted and a new * child text node is created. * @param domDocument the Document that contains the node * @param n the Node to add the text to * @param value the text to add */ public boolean setNodeText(Document domDocument, Node n, String value) { if (n == null) return false; Node nc = null; while ((nc = n.getFirstChild()) != null) { n.removeChild(nc); } n.appendChild(domDocument.createTextNode(value)); return true; } /** * Writes the document to a byte array. */ public byte[] serializeDoc() throws IOException { XmlDomWriter xw = new XmlDomWriter(); ByteArrayOutputStream fout = new ByteArrayOutputStream(); xw.setOutput(fout, null); fout.write(XmpWriter.XPACKET_PI_BEGIN.getBytes("UTF-8")); fout.flush(); NodeList xmpmeta = domDocument.getElementsByTagName("x:xmpmeta"); xw.write(xmpmeta.item(0)); fout.flush(); for (int i = 0; i < 20; i++) { fout.write(XmpWriter.EXTRASPACE.getBytes()); } fout.write(XmpWriter.XPACKET_PI_END_W.getBytes()); fout.close(); return fout.toByteArray(); } } src/core/com/lowagie/text/xml/xmp/XmpSchema.java100644 0 0 12027 11036112744 17272 0ustar 0 0 /* * $Id: XmpSchema.java 3543 2008-07-10 17:37:37Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import java.util.Enumeration; import java.util.Properties; /** * Abstract superclass of the XmpSchemas supported by iText. */ public abstract class XmpSchema extends Properties { private static final long serialVersionUID = -176374295948945272L; /** the namesspace */ protected String xmlns; /** Constructs an XMP schema. * @param xmlns */ public XmpSchema(String xmlns) { super(); this.xmlns = xmlns; } /** * The String representation of the contents. * @return a String representation. */ public String toString() { StringBuffer buf = new StringBuffer(); for (Enumeration e = this.propertyNames(); e.hasMoreElements(); ) { process(buf, e.nextElement()); } return buf.toString(); } /** * Processes a property * @param buf * @param p */ protected void process(StringBuffer buf, Object p) { buf.append('<'); buf.append(p); buf.append('>'); buf.append(this.get(p)); buf.append("'); } /** * @return Returns the xmlns. */ public String getXmlns() { return xmlns; } /** * @param key * @param value * @return the previous property (null if there wasn't one) */ public Object addProperty(String key, String value) { return this.setProperty(key, value); } /** * @see java.util.Properties#setProperty(java.lang.String, java.lang.String) */ public Object setProperty(String key, String value) { return super.setProperty(key, escape(value)); } /** * @see java.util.Properties#setProperty(java.lang.String, java.lang.String) * * @param key * @param value * @return the previous property (null if there wasn't one) */ public Object setProperty(String key, XmpArray value) { return super.setProperty(key, value.toString()); } /** * @see java.util.Properties#setProperty(java.lang.String, java.lang.String) * * @param key * @param value * @return the previous property (null if there wasn't one) */ public Object setProperty(String key, LangAlt value) { return super.setProperty(key, value.toString()); } /** * @param content * @return an escaped string */ public static String escape(String content) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < content.length(); i++) { switch(content.charAt(i)) { case '<': buf.append("<"); break; case '>': buf.append(">"); break; case '\'': buf.append("'"); break; case '\"': buf.append("""); break; case '&': buf.append("&"); break; default: buf.append(content.charAt(i)); } } return buf.toString(); } } src/core/com/lowagie/text/xml/xmp/XmpWriter.java100644 0 0 24273 11213370067 17355 0ustar 0 0 /* * $Id: XmpWriter.java 3949 2009-06-03 15:19:04Z blowagie $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 LIBRARY GENERAL PUBLIC LICENSE for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.xml.xmp; import com.lowagie.text.pdf.PdfWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Iterator; import java.util.Map; import com.lowagie.text.pdf.PdfDate; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfString; /** * With this class you can create an Xmp Stream that can be used for adding * Metadata to a PDF Dictionary. Remark that this class doesn't cover the * complete XMP specification. */ public class XmpWriter { /** A possible charset for the XMP. */ public static final String UTF8 = "UTF-8"; /** A possible charset for the XMP. */ public static final String UTF16 = "UTF-16"; /** A possible charset for the XMP. */ public static final String UTF16BE = "UTF-16BE"; /** A possible charset for the XMP. */ public static final String UTF16LE = "UTF-16LE"; /** String used to fill the extra space. */ public static final String EXTRASPACE = " \n"; /** You can add some extra space in the XMP packet; 1 unit in this variable represents 100 spaces and a newline. */ protected int extraSpace; /** The writer to which you can write bytes for the XMP stream. */ protected OutputStreamWriter writer; /** The about string that goes into the rdf:Description tags. */ protected String about; /** * Processing Instruction required at the start of an XMP stream * @since iText 2.1.6 */ public static final String XPACKET_PI_BEGIN = "\n"; /** * Processing Instruction required at the end of an XMP stream for XMP streams that can be updated * @since iText 2.1.6 */ public static final String XPACKET_PI_END_W = ""; /** * Processing Instruction required at the end of an XMP stream for XMP streams that are read only * @since iText 2.1.6 */ public static final String XPACKET_PI_END_R = ""; /** The end attribute. */ protected char end = 'w'; /** * Creates an XmpWriter. * @param os * @param utfEncoding * @param extraSpace * @throws IOException */ public XmpWriter(OutputStream os, String utfEncoding, int extraSpace) throws IOException { this.extraSpace = extraSpace; writer = new OutputStreamWriter(os, utfEncoding); writer.write(XPACKET_PI_BEGIN); writer.write("\n"); writer.write("\n"); about = ""; } /** * Creates an XmpWriter. * @param os * @throws IOException */ public XmpWriter(OutputStream os) throws IOException { this(os, UTF8, 20); } /** Sets the XMP to read-only */ public void setReadOnly() { end = 'r'; } /** * @param about The about to set. */ public void setAbout(String about) { this.about = about; } /** * Adds an rdf:Description. * @param xmlns * @param content * @throws IOException */ public void addRdfDescription(String xmlns, String content) throws IOException { writer.write(""); writer.write(content); writer.write("\n"); } /** * Adds an rdf:Description. * @param s * @throws IOException */ public void addRdfDescription(XmpSchema s) throws IOException { writer.write(""); writer.write(s.toString()); writer.write("\n"); } /** * Flushes and closes the XmpWriter. * @throws IOException */ public void close() throws IOException { writer.write(""); writer.write("\n"); for (int i = 0; i < extraSpace; i++) { writer.write(EXTRASPACE); } writer.write(end == 'r' ? XPACKET_PI_END_R : XPACKET_PI_END_W); writer.flush(); writer.close(); } /** * @param os * @param info * @throws IOException */ public XmpWriter(OutputStream os, PdfDictionary info, int PdfXConformance) throws IOException { this(os); if (info != null) { DublinCoreSchema dc = new DublinCoreSchema(); PdfSchema p = new PdfSchema(); XmpBasicSchema basic = new XmpBasicSchema(); PdfName key; PdfObject obj; for (Iterator it = info.getKeys().iterator(); it.hasNext();) { key = (PdfName)it.next(); obj = info.get(key); if (obj == null) continue; if (PdfName.TITLE.equals(key)) { dc.addTitle(((PdfString)obj).toUnicodeString()); } if (PdfName.AUTHOR.equals(key)) { dc.addAuthor(((PdfString)obj).toUnicodeString()); } if (PdfName.SUBJECT.equals(key)) { dc.addSubject(((PdfString)obj).toUnicodeString()); dc.addDescription(((PdfString)obj).toUnicodeString()); } if (PdfName.KEYWORDS.equals(key)) { p.addKeywords(((PdfString)obj).toUnicodeString()); } if (PdfName.CREATOR.equals(key)) { basic.addCreatorTool(((PdfString)obj).toUnicodeString()); } if (PdfName.PRODUCER.equals(key)) { p.addProducer(((PdfString)obj).toUnicodeString()); } if (PdfName.CREATIONDATE.equals(key)) { basic.addCreateDate(((PdfDate)obj).getW3CDate()); } if (PdfName.MODDATE.equals(key)) { basic.addModDate(((PdfDate)obj).getW3CDate()); } } if (dc.size() > 0) addRdfDescription(dc); if (p.size() > 0) addRdfDescription(p); if (basic.size() > 0) addRdfDescription(basic); if (PdfXConformance == PdfWriter.PDFA1A || PdfXConformance == PdfWriter.PDFA1B) { PdfA1Schema a1 = new PdfA1Schema(); if (PdfXConformance == PdfWriter.PDFA1A) a1.addConformance("A"); else a1.addConformance("B"); addRdfDescription(a1); } } } /** * @param os * @param info * @throws IOException */ public XmpWriter(OutputStream os, Map info) throws IOException { this(os); if (info != null) { DublinCoreSchema dc = new DublinCoreSchema(); PdfSchema p = new PdfSchema(); XmpBasicSchema basic = new XmpBasicSchema(); String key; String value; for (Iterator it = info.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); key = (String) entry.getKey(); value = (String) entry.getValue(); if (value == null) continue; if ("Title".equals(key)) { dc.addTitle(value); } if ("Author".equals(key)) { dc.addAuthor(value); } if ("Subject".equals(key)) { dc.addSubject(value); dc.addDescription(value); } if ("Keywords".equals(key)) { p.addKeywords(value); } if ("Creator".equals(key)) { basic.addCreatorTool(value); } if ("Producer".equals(key)) { p.addProducer(value); } if ("CreationDate".equals(key)) { basic.addCreateDate(PdfDate.getW3CDate(value)); } if ("ModDate".equals(key)) { basic.addModDate(PdfDate.getW3CDate(value)); } } if (dc.size() > 0) addRdfDescription(dc); if (p.size() > 0) addRdfDescription(p); if (basic.size() > 0) addRdfDescription(basic); } } }src/core/com/lowagie/tools/BuildTutorial.java100644 0 0 17322 11012562263 16742 0ustar 0 0 /* * $Id: BuildTutorial.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; /** * This class can be used to build the iText website. * * @author Bruno Lowagie */ public class BuildTutorial { static String root; static FileWriter build; //~ Methods // ---------------------------------------------------------------- /** * Main method so you can call the convert method from the command line. * @param args 4 arguments are expected: *

      • a sourcedirectory (root of the tutorial xml-files), *
      • a destination directory (where the html and build.xml files will be generated), *
      • an xsl to transform the index.xml into a build.xml *
      • an xsl to transform the index.xml into am index.html
      */ public static void main(String[] args) { if (args.length == 4) { File srcdir = new File(args[0]); File destdir = new File(args[1]); File xsl_examples = new File(srcdir, args[2]); File xsl_site = new File(srcdir, args[3]); try { System.out.print("Building tutorial: "); root = new File(args[1], srcdir.getName()).getCanonicalPath(); System.out.println(root); build = new FileWriter(new File(root, "build.xml")); build.write("\n"); build.write("\n"); action(srcdir, destdir, xsl_examples, xsl_site); build.write("\n"); build.flush(); build.close(); } catch(IOException ioe) { ioe.printStackTrace(); } } else { System.err .println("Wrong number of parameters.\nUsage: BuildSite srcdr destdir xsl_examples xsl_site"); } } /** * Inspects a file or directory that is given and performs the necessary actions on it (transformation or recursion). * @param source a sourcedirectory (possibly with a tutorial xml-file) * @param destination a destination directory (where the html and build.xml file will be generated, if necessary) * @param xsl_examples an xsl to transform the index.xml into a build.xml * @param xsl_site an xsl to transform the index.xml into am index.html * @throws IOException when something goes wrong while reading or creating a file or directory */ public static void action(File source, File destination, File xsl_examples, File xsl_site) throws IOException { if (".svn".equals(source.getName())) return; System.out.print(source.getName()); if (source.isDirectory()) { System.out.print(" "); System.out.println(source.getCanonicalPath()); File dest = new File(destination, source.getName()); dest.mkdir(); File current; File[] xmlFiles = source.listFiles(); if (xmlFiles != null) { for (int i = 0; i < xmlFiles.length; i++) { current = xmlFiles[i]; action(current, dest, xsl_examples, xsl_site); } } else { System.out.println("... skipped"); } } else if (source.getName().equals("index.xml")) { System.out.println("... transformed"); convert(source, xsl_site, new File(destination, "index.php")); File buildfile = new File(destination, "build.xml"); String path = buildfile.getCanonicalPath().substring(root.length()); path = path.replace(File.separatorChar, '/'); if ("/build.xml".equals(path)) return; convert(source, xsl_examples, buildfile); build.write("\t\n"); } else { System.out.println("... skipped"); } } /** * Converts an infile, using an xslfile to an * outfile. * * @param infile * the path to an XML file * @param xslfile * the path to the XSL file * @param outfile * the path for the output file */ public static void convert(File infile, File xslfile, File outfile) { try { // Create transformer factory TransformerFactory factory = TransformerFactory.newInstance(); // Use the factory to create a template containing the xsl file Templates template = factory.newTemplates(new StreamSource( new FileInputStream(xslfile))); // Use the template to create a transformer Transformer xformer = template.newTransformer(); // passing 2 parameters String branch = outfile.getParentFile().getCanonicalPath().substring(root.length()); branch = branch.replace(File.separatorChar, '/'); StringBuffer path = new StringBuffer(); for (int i = 0; i < branch.length(); i++) { if (branch.charAt(i) == '/') path.append("/.."); } xformer.setParameter("branch", branch); xformer.setParameter("root", path.toString()); // Prepare the input and output files Source source = new StreamSource(new FileInputStream(infile)); Result result = new StreamResult(new FileOutputStream(outfile)); // Apply the xsl file to the source file and write the result to the // output file xformer.transform(source, result); } catch (Exception e) { e.printStackTrace(); } } } //The End src/core/com/lowagie/tools/ConcatPdf.java100644 0 0 12735 11012562263 16023 0ustar 0 0 /* * $Id: ConcatPdf.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2002 by Mark Thompson * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; /** * Tool that can be used to concatenate existing PDF files. * @since 2.1.1 (renamed to follow Java naming conventions) */ public class ConcatPdf { /** * This class can be used to concatenate existing PDF files. * (This was an example known as PdfCopy.java) * @param args the command line arguments */ public static void main(String args[]) { if (args.length < 2) { System.err.println("arguments: file1 [file2 ...] destfile"); } else { try { int pageOffset = 0; ArrayList master = new ArrayList(); int f = 0; String outFile = args[args.length-1]; Document document = null; PdfCopy writer = null; while (f < args.length-1) { // we create a reader for a certain document PdfReader reader = new PdfReader(args[f]); reader.consolidateNamedDestinations(); // we retrieve the total number of pages int n = reader.getNumberOfPages(); List bookmarks = SimpleBookmark.getBookmark(reader); if (bookmarks != null) { if (pageOffset != 0) SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null); master.addAll(bookmarks); } pageOffset += n; System.out.println("There are " + n + " pages in " + args[f]); if (f == 0) { // step 1: creation of a document-object document = new Document(reader.getPageSizeWithRotation(1)); // step 2: we create a writer that listens to the document writer = new PdfCopy(document, new FileOutputStream(outFile)); // step 3: we open the document document.open(); } // step 4: we add content PdfImportedPage page; for (int i = 0; i < n; ) { ++i; page = writer.getImportedPage(reader, i); writer.addPage(page); System.out.println("Processed page " + i); } writer.freeReader(reader); f++; } if (!master.isEmpty()) writer.setOutlines(master); // step 5: we close the document document.close(); } catch(Exception e) { e.printStackTrace(); } } } } src/core/com/lowagie/tools/EncryptPdf.java100644 0 0 13127 11012562263 16234 0ustar 0 0 /* * $Id: EncryptPdf.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2002 by Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.FileOutputStream; import java.util.HashMap; import com.lowagie.text.pdf.PdfEncryptor; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; /** * Encrypts a PDF document. It needs iText (http://www.lowagie.com/iText). * @author Paulo Soares (psoares@consiste.pt) * @since 2.1.1 (renamed to follow Java naming conventions) */ public class EncryptPdf { private final static int INPUT_FILE = 0; private final static int OUTPUT_FILE = 1; private final static int USER_PASSWORD = 2; private final static int OWNER_PASSWORD = 3; private final static int PERMISSIONS = 4; private final static int STRENGTH = 5; private final static int MOREINFO = 6; private final static int permit[] = { PdfWriter.ALLOW_PRINTING, PdfWriter.ALLOW_MODIFY_CONTENTS, PdfWriter.ALLOW_COPY, PdfWriter.ALLOW_MODIFY_ANNOTATIONS, PdfWriter.ALLOW_FILL_IN, PdfWriter.ALLOW_SCREENREADERS, PdfWriter.ALLOW_ASSEMBLY, PdfWriter.ALLOW_DEGRADED_PRINTING}; private static void usage() { System.out.println("usage: input_file output_file user_password owner_password permissions 128|40 [new info string pairs]"); System.out.println("permissions is 8 digit long 0 or 1. Each digit has a particular security function:"); System.out.println(); System.out.println("AllowPrinting"); System.out.println("AllowModifyContents"); System.out.println("AllowCopy"); System.out.println("AllowModifyAnnotations"); System.out.println("AllowFillIn (128 bit only)"); System.out.println("AllowScreenReaders (128 bit only)"); System.out.println("AllowAssembly (128 bit only)"); System.out.println("AllowDegradedPrinting (128 bit only)"); System.out.println("Example permissions to copy and print would be: 10100000"); } /** * Encrypts a PDF document. * * @param args input_file output_file user_password owner_password permissions 128|40 [new info string pairs] */ public static void main (String args[]) { System.out.println("PDF document encryptor"); if (args.length <= STRENGTH || args[PERMISSIONS].length() != 8) { usage(); return; } try { int permissions = 0; String p = args[PERMISSIONS]; for (int k = 0; k < p.length(); ++k) { permissions |= (p.charAt(k) == '0' ? 0 : permit[k]); } System.out.println("Reading " + args[INPUT_FILE]); PdfReader reader = new PdfReader(args[INPUT_FILE]); System.out.println("Writing " + args[OUTPUT_FILE]); HashMap moreInfo = new HashMap(); for (int k = MOREINFO; k < args.length - 1; k += 2) moreInfo.put(args[k], args[k + 1]); PdfEncryptor.encrypt(reader, new FileOutputStream(args[OUTPUT_FILE]), args[USER_PASSWORD].getBytes(), args[OWNER_PASSWORD].getBytes(), permissions, args[STRENGTH].equals("128"), moreInfo); System.out.println("Done."); } catch (Exception e) { e.printStackTrace(); } } }src/core/com/lowagie/tools/Executable.java100644 0 0 22724 11012562263 16242 0ustar 0 0 /* * $Id: Executable.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie / Roger Mistelli * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; /** * This class enables you to call an executable that will show a PDF file. */ public class Executable { /** * The path to Acrobat Reader. */ public static String acroread = null; /** * Performs an action on a PDF document. * @param fileName * @param parameters * @param waitForTermination * @return a process * @throws IOException */ private static Process action(final String fileName, String parameters, boolean waitForTermination) throws IOException { Process process = null; if (parameters.trim().length() > 0) { parameters = " " + parameters.trim(); } else { parameters = ""; } if (acroread != null) { process = Runtime.getRuntime().exec( acroread + parameters + " \"" + fileName + "\""); } else if (isWindows()) { if (isWindows9X()) { process = Runtime.getRuntime().exec( "command.com /C start acrord32" + parameters + " \"" + fileName + "\""); } else { process = Runtime.getRuntime().exec( "cmd /c start acrord32" + parameters + " \"" + fileName + "\""); } } else if (isMac()) { if (parameters.trim().length() == 0) { process = Runtime.getRuntime().exec( new String[] { "/usr/bin/open", fileName }); } else { process = Runtime.getRuntime().exec( new String[] { "/usr/bin/open", parameters.trim(), fileName }); } } try { if (process != null && waitForTermination) process.waitFor(); } catch (InterruptedException ie) { } return process; } /** * Opens a PDF document. * @param fileName * @param waitForTermination * @return a process * @throws IOException */ public static final Process openDocument(String fileName, boolean waitForTermination) throws IOException { return action(fileName, "", waitForTermination); } /** * Opens a PDF document. * @param file * @param waitForTermination * @return a process * @throws IOException */ public static final Process openDocument(File file, boolean waitForTermination) throws IOException { return openDocument(file.getAbsolutePath(), waitForTermination); } /** * Opens a PDF document. * @param fileName * @return a process * @throws IOException */ public static final Process openDocument(String fileName) throws IOException { return openDocument(fileName, false); } /** * Opens a PDF document. * @param file * @return a process * @throws IOException */ public static final Process openDocument(File file) throws IOException { return openDocument(file, false); } /** * Prints a PDF document. * @param fileName * @param waitForTermination * @return a process * @throws IOException */ public static final Process printDocument(String fileName, boolean waitForTermination) throws IOException { return action(fileName, "/p", waitForTermination); } /** * Prints a PDF document. * @param file * @param waitForTermination * @return a process * @throws IOException */ public static final Process printDocument(File file, boolean waitForTermination) throws IOException { return printDocument(file.getAbsolutePath(), waitForTermination); } /** * Prints a PDF document. * @param fileName * @return a process * @throws IOException */ public static final Process printDocument(String fileName) throws IOException { return printDocument(fileName, false); } /** * Prints a PDF document. * @param file * @return a process * @throws IOException */ public static final Process printDocument(File file) throws IOException { return printDocument(file, false); } /** * Prints a PDF document without opening a Dialog box. * @param fileName * @param waitForTermination * @return a process * @throws IOException */ public static final Process printDocumentSilent(String fileName, boolean waitForTermination) throws IOException { return action(fileName, "/p /h", waitForTermination); } /** * Prints a PDF document without opening a Dialog box. * @param file * @param waitForTermination * @return a process * @throws IOException */ public static final Process printDocumentSilent(File file, boolean waitForTermination) throws IOException { return printDocumentSilent(file.getAbsolutePath(), waitForTermination); } /** * Prints a PDF document without opening a Dialog box. * @param fileName * @return a process * @throws IOException */ public static final Process printDocumentSilent(String fileName) throws IOException { return printDocumentSilent(fileName, false); } /** * Prints a PDF document without opening a Dialog box. * @param file * @return a process * @throws IOException */ public static final Process printDocumentSilent(File file) throws IOException { return printDocumentSilent(file, false); } /** * Launches a browser opening an URL. * * @param url the URL you want to open in the browser * @throws IOException */ public static final void launchBrowser(String url) throws IOException { try { if (isMac()) { Class macUtils = Class.forName("com.apple.mrj.MRJFileUtils"); Method openURL = macUtils.getDeclaredMethod("openURL", new Class[] {String.class}); openURL.invoke(null, new Object[] {url}); } else if (isWindows()) Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url); else { //assume Unix or Linux String[] browsers = { "firefox", "opera", "konqueror", "mozilla", "netscape" }; String browser = null; for (int count = 0; count < browsers.length && browser == null; count++) if (Runtime.getRuntime().exec(new String[] {"which", browsers[count]}).waitFor() == 0) browser = browsers[count]; if (browser == null) throw new Exception("Could not find web browser."); else Runtime.getRuntime().exec(new String[] {browser, url}); } } catch (Exception e) { throw new IOException("Error attempting to launch web browser"); } } /** * Checks the Operating System. * * @return true if the current os is Windows */ public static boolean isWindows() { String os = System.getProperty("os.name").toLowerCase(); return os.indexOf("windows") != -1 || os.indexOf("nt") != -1; } /** * Checks the Operating System. * * @return true if the current os is Windows */ public static boolean isWindows9X() { String os = System.getProperty("os.name").toLowerCase(); return os.equals("windows 95") || os.equals("windows 98"); } /** * Checks the Operating System. * * @return true if the current os is Apple */ public static boolean isMac() { String os = System.getProperty("os.name").toLowerCase(); return os.indexOf("mac") != -1; } /** * Checks the Operating System. * * @return true if the current os is Linux */ public static boolean isLinux() { String os = System.getProperty("os.name").toLowerCase(); return os.indexOf("linux") != -1; } }src/core/com/lowagie/tools/HandoutPdf.java100644 0 0 13665 11012562263 16221 0ustar 0 0 /* * $Id: HandoutPdf.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2002 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.FileOutputStream; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.PageSize; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; /** * Takes an existing PDF file and makes handouts. * @since 2.1.1 (renamed to follow Java naming conventions) */ public class HandoutPdf extends java.lang.Object { /** * Makes handouts based on an existing PDF file. * @param args the command line arguments */ public static void main (String args[]) { if (args.length != 3) { System.err.println("arguments: srcfile destfile pages"); } else { try { int pages = Integer.parseInt(args[2]); if (pages < 2 || pages > 8) { throw new DocumentException("You can't have " + pages + " pages on one page (minimum 2; maximum 8)."); } float x1 = 30f; float x2 = 280f; float x3 = 320f; float x4 = 565f; float[] y1 = new float[pages]; float[] y2 = new float[pages]; float height = (778f - (20f * (pages - 1))) / pages; y1[0] = 812f; y2[0] = 812f - height; for (int i = 1; i < pages; i++) { y1[i] = y2[i - 1] - 20f; y2[i] = y1[i] - height; } // we create a reader for a certain document PdfReader reader = new PdfReader(args[0]); // we retrieve the total number of pages int n = reader.getNumberOfPages(); System.out.println("There are " + n + " pages in the original file."); // step 1: creation of a document-object Document document = new Document(PageSize.A4); // step 2: we create a writer that listens to the document PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(args[1])); // step 3: we open the document document.open(); PdfContentByte cb = writer.getDirectContent(); PdfImportedPage page; int rotation; int i = 0; int p = 0; // step 4: we add content while (i < n) { i++; Rectangle rect = reader.getPageSizeWithRotation(i); float factorx = (x2 - x1) / rect.getWidth(); float factory = (y1[p] - y2[p]) / rect.getHeight(); float factor = (factorx < factory ? factorx : factory); float dx = (factorx == factor ? 0f : ((x2 - x1) - rect.getWidth() * factor) / 2f); float dy = (factory == factor ? 0f : ((y1[p] - y2[p]) - rect.getHeight() * factor) / 2f); page = writer.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb.addTemplate(page, 0, -factor, factor, 0, x1 + dx, y2[p] + dy + rect.getHeight() * factor); } else { cb.addTemplate(page, factor, 0, 0, factor, x1 + dx, y2[p] + dy); } cb.setRGBColorStroke(0xC0, 0xC0, 0xC0); cb.rectangle(x3 - 5f, y2[p] - 5f, x4 - x3 + 10f, y1[p] - y2[p] + 10f); for (float l = y1[p] - 19; l > y2[p]; l -= 16) { cb.moveTo(x3, l); cb.lineTo(x4, l); } cb.rectangle(x1 + dx, y2[p] + dy, rect.getWidth() * factor, rect.getHeight() * factor); cb.stroke(); System.out.println("Processed page " + i); p++; if (p == pages) { p = 0; document.newPage(); } } // step 5: we close the document document.close(); } catch(Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } } }src/core/com/lowagie/tools/SplitPdf.java100644 0 0 13067 11012562263 15706 0ustar 0 0 /* * $Id: SplitPdf.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2002 by Bruno Lowagie * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.io.FileOutputStream; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; /** * This class demonstrates how to split a PDF file using iText. * @author Bruno Lowagie * @since 2.1.1 (renamed to follow Java naming conventions) */ public class SplitPdf extends java.lang.Object { /** * This class can be used to split an existing PDF file. * @param args the command line arguments */ public static void main(String args[]) { if (args.length != 4) { System.err.println("arguments: srcfile destfile1 destfile2 pagenumber"); } else { try { int pagenumber = Integer.parseInt(args[3]); // we create a reader for a certain document PdfReader reader = new PdfReader(args[0]); // we retrieve the total number of pages int n = reader.getNumberOfPages(); System.out.println("There are " + n + " pages in the original file."); if (pagenumber < 2 || pagenumber > n) { throw new DocumentException("You can't split this document at page " + pagenumber + "; there is no such page."); } // step 1: creation of a document-object Document document1 = new Document(reader.getPageSizeWithRotation(1)); Document document2 = new Document(reader.getPageSizeWithRotation(pagenumber)); // step 2: we create a writer that listens to the document PdfWriter writer1 = PdfWriter.getInstance(document1, new FileOutputStream(args[1])); PdfWriter writer2 = PdfWriter.getInstance(document2, new FileOutputStream(args[2])); // step 3: we open the document document1.open(); PdfContentByte cb1 = writer1.getDirectContent(); document2.open(); PdfContentByte cb2 = writer2.getDirectContent(); PdfImportedPage page; int rotation; int i = 0; // step 4: we add content while (i < pagenumber - 1) { i++; document1.setPageSize(reader.getPageSizeWithRotation(i)); document1.newPage(); page = writer1.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb1.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(i).getHeight()); } else { cb1.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } } while (i < n) { i++; document2.setPageSize(reader.getPageSizeWithRotation(i)); document2.newPage(); page = writer2.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb2.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(i).getHeight()); } else { cb2.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } System.out.println("Processed page " + i); } // step 5: we close the document document1.close(); document2.close(); } catch(Exception e) { e.printStackTrace(); } } } } src/core/com/lowagie/tools/ToolboxAvailable.java100644 0 0 6601 11012562263 17364 0ustar 0 0 /* * $Id: ToolboxAvailable.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.tools; import java.awt.GraphicsEnvironment; import java.lang.reflect.Method; import javax.swing.JOptionPane; import com.lowagie.text.Document; public class ToolboxAvailable { /** * Checks if the toolbox if available. * If it is, the toolbox is started. * If it isn't, an error message is shown. */ public static void main(String[] args) { if (GraphicsEnvironment.isHeadless()) { System.out.println(Document.getVersion() + " Toolbox error: headless display"); } else try { Class c = Class.forName("com.lowagie.toolbox.Toolbox"); Method toolboxMain = c.getMethod("main", new Class[] {args.getClass()}); toolboxMain.invoke(null, new Object[] {args} ); } catch (Exception e) { JOptionPane.showMessageDialog(null, "You need the iText-toolbox.jar with class com.lowagie.toolbox.Toolbox to use the iText Toolbox.", Document.getVersion() + " Toolbox error", JOptionPane.ERROR_MESSAGE); } } }src/rtf/com/lowagie/text/rtf/RtfAddableElement.java100644 0 0 11655 11106243445 17750 0ustar 0 0 /* * $Id:RtfAddableElement.java 3126 2008-02-07 20:30:46Z hallm $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are * Copyright (C) 2006 by Mark Hall. All Rights Reserved * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfAddableElement is the superclass for all rtf specific elements * that need to be added to an iText document. It is an extension of Chunk * and it also implements RtfBasicElement. It is an abstract class thus it * cannot be instantiated itself and has to be subclassed to be used. * * @version $Id:RtfAddableElement.java 3126 2008-02-07 20:30:46Z hallm $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public abstract class RtfAddableElement extends Chunk implements RtfBasicElement { /** * The RtfDocument this RtfAddableElement belongs to. */ protected RtfDocument doc = null; /** * Whether this RtfAddableElement is contained in a table. */ protected boolean inTable = false; /** * Whether this RtfAddableElement is contained in a header. */ protected boolean inHeader = false; /** * Constructs a new RtfAddableElement. The Chunk content is * set to an empty string and the font to the default Font(). */ public RtfAddableElement() { super("", new Font()); } /** * Writes the element content to the given output stream. */ public abstract void writeContent(OutputStream out) throws IOException; /** * Sets the RtfDocument this RtfAddableElement belongs to. */ public void setRtfDocument(RtfDocument doc) { this.doc = doc; } /** * Sets whether this RtfAddableElement is contained in a table. */ public void setInTable(boolean inTable) { this.inTable = inTable; } /** * Sets whether this RtfAddableElement is contained in a header/footer. */ public void setInHeader(boolean inHeader) { this.inHeader = inHeader; } /** * Transforms an integer into its String representation and then returns the bytes * of that string. * * @param i The integer to convert * @return A byte array representing the integer */ public byte[] intToByteArray(int i) { return DocWriter.getISOBytes(Integer.toString(i)); } /** * RtfAddableElement subclasses are never assumed to be empty. */ public boolean isEmpty() { return false; } } src/rtf/com/lowagie/text/rtf/RtfBasicElement.java100644 0 0 11023 11106243445 17442 0ustar 0 0 /* * $Id: RtfBasicElement.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.RtfElementInterface; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfBasicElement interface defines the interface for elements that can * be added to the RtfWriter. * * @version $Id: RtfBasicElement.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public interface RtfBasicElement extends RtfElementInterface { /** * Constant for the beginning of a rtf group */ public static final byte[] OPEN_GROUP = DocWriter.getISOBytes("{"); /** * Constant for the end of an rtf group */ public static final byte[] CLOSE_GROUP = DocWriter.getISOBytes("}"); /** * Constant for a delimiter in rtf */ public static final byte[] DELIMITER = DocWriter.getISOBytes(" "); /** * Constant for a comma delimiter in rtf */ public static final byte[] COMMA_DELIMITER = DocWriter.getISOBytes(";"); /** * The factor to use for translating from iText to rtf measurements */ public static final double TWIPS_FACTOR = 20; /** * Writes the element content to the given output stream. * * @param out The OutputStream to write the content to */ public void writeContent(OutputStream out) throws IOException; /** * Sets the RtfDocument this RtfElement belongs to * * @param doc The @link{com.lowagie.text.rtf.document.RtfDocument} this RtfElement belongs to */ public void setRtfDocument(RtfDocument doc); /** * Sets whether this RtfBasicElement is in a table * * @param inTable Whether this RtfBasicElement is in a table */ public void setInTable(boolean inTable); /** * Sets whether this RtfBasicElement is in a header * * @param inHeader Whether this RtfBasicElement is in a header */ public void setInHeader(boolean inHeader); } src/rtf/com/lowagie/text/rtf/RtfElement.java100644 0 0 11612 11106243445 16504 0ustar 0 0 /* * $Id:RtfElement.java 3126 2008-02-07 20:30:46Z hallm $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.document.RtfDocument; /** * RtfElement is the base class for all RTF Element classes * * @version $Id:RtfElement.java 3126 2008-02-07 20:30:46Z hallm $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public abstract class RtfElement implements RtfBasicElement { /** * The RtfDocument this RtfElement belongs to */ protected RtfDocument document = null; /** * Whether this RtfElement is in a table */ protected boolean inTable = false; /** * Whether this RtfElement is in a header */ protected boolean inHeader = false; /** * Constructs a RtfElement belonging to the specified RtfDocument. * * @param doc The RtfDocument this RtfElement belongs to */ public RtfElement(RtfDocument doc) { super(); this.document = doc; } /** * Transforms an integer into its String representation and then returns the bytes * of that string. * * @param i The integer to convert * @return A byte array representing the integer */ public byte[] intToByteArray(int i) { return DocWriter.getISOBytes(Integer.toString(i)); } /** * Writes the element content to the given output stream. */ public abstract void writeContent(final OutputStream out) throws IOException; /** * Sets the RtfDocument this RtfElement belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; } /** * Gets whether this RtfElement is in a table * * @return Whether this RtfElement is in a table */ public boolean isInTable() { return inTable; } /** * Sets whether this RtfElement is in a table * * @param inTable True if this RtfElement is in a table, false otherwise */ public void setInTable(boolean inTable) { this.inTable = inTable; } /** * Sets whether this RtfElement is in a header * * @param inHeader True if this RtfElement is in a header, false otherwise */ public void setInHeader(boolean inHeader) { this.inHeader = inHeader; } } src/rtf/com/lowagie/text/rtf/RtfExtendedElement.java100644 0 0 6207 11012562274 20151 0ustar 0 0 /* * $Id: RtfExtendedElement.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.io.IOException; import java.io.OutputStream; /** * The RtfExtendedElement interface is to be used for elements that also * write data into the definition part of the rtf document * * @version $Id: RtfExtendedElement.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public interface RtfExtendedElement extends RtfBasicElement { /** * Write the definition part of the element * * @param out The OutputStream to write the element definition to */ public void writeDefinition(OutputStream out) throws IOException; } src/rtf/com/lowagie/text/rtf/RtfMapper.java100644 0 0 17736 11213370070 16346 0ustar 0 0 /* * $Id:RtfMapper.java 3126 2008-02-07 20:30:46Z hallm $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.util.ArrayList; import com.lowagie.text.Anchor; import com.lowagie.text.Annotation; import com.lowagie.text.Chapter; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.Meta; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Section; import com.lowagie.text.SimpleTable; import com.lowagie.text.Table; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.document.RtfInfoElement; import com.lowagie.text.rtf.field.RtfAnchor; import com.lowagie.text.rtf.graphic.RtfImage; import com.lowagie.text.rtf.list.RtfList; import com.lowagie.text.rtf.list.RtfListItem; import com.lowagie.text.rtf.table.RtfTable; import com.lowagie.text.rtf.text.RtfAnnotation; import com.lowagie.text.rtf.text.RtfChapter; import com.lowagie.text.rtf.text.RtfChunk; import com.lowagie.text.rtf.text.RtfNewPage; import com.lowagie.text.rtf.text.RtfParagraph; import com.lowagie.text.rtf.text.RtfPhrase; import com.lowagie.text.rtf.text.RtfSection; import com.lowagie.text.rtf.text.RtfTab; /** * The RtfMapper provides mappings between com.lowagie.text.* classes * and the corresponding com.lowagie.text.rtf.** classes. * * @version $Revision: 3868 $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) */ public class RtfMapper { /** * The RtfDocument this RtfMapper belongs to */ RtfDocument rtfDoc; /** * Constructs a RtfMapper for a RtfDocument * * @param doc The RtfDocument this RtfMapper belongs to */ public RtfMapper(RtfDocument doc) { this.rtfDoc = doc; } /** * Takes an Element subclass and returns an array of RtfBasicElement * subclasses, that contained the mapped RTF equivalent to the Element * passed in. * * @param element The Element to wrap * @return An array of RtfBasicElement wrapping the Element * @throws DocumentException */ public RtfBasicElement[] mapElement(Element element) throws DocumentException { ArrayList rtfElements = new ArrayList(); if(element instanceof RtfBasicElement) { RtfBasicElement rtfElement = (RtfBasicElement) element; rtfElement.setRtfDocument(this.rtfDoc); return new RtfBasicElement[]{rtfElement}; } switch(element.type()) { case Element.CHUNK: Chunk chunk = (Chunk) element; if(chunk.hasAttributes()) { if(chunk.getAttributes().containsKey(Chunk.IMAGE)) { rtfElements.add(new RtfImage(rtfDoc, chunk.getImage())); } else if(chunk.getAttributes().containsKey(Chunk.NEWPAGE)) { rtfElements.add(new RtfNewPage(rtfDoc)); } else if(chunk.getAttributes().containsKey(Chunk.TAB)) { Float tabPos = (Float) ((Object[]) chunk.getAttributes().get(Chunk.TAB))[1]; RtfTab tab = new RtfTab(tabPos.floatValue(), RtfTab.TAB_LEFT_ALIGN); tab.setRtfDocument(rtfDoc); rtfElements.add(tab); rtfElements.add(new RtfChunk(rtfDoc, new Chunk("\t"))); } else { rtfElements.add(new RtfChunk(rtfDoc, (Chunk) element)); } } else { rtfElements.add(new RtfChunk(rtfDoc, (Chunk) element)); } break; case Element.PHRASE: rtfElements.add(new RtfPhrase(rtfDoc, (Phrase) element)); break; case Element.PARAGRAPH: rtfElements.add(new RtfParagraph(rtfDoc, (Paragraph) element)); break; case Element.ANCHOR: rtfElements.add(new RtfAnchor(rtfDoc, (Anchor) element)); break; case Element.ANNOTATION: rtfElements.add(new RtfAnnotation(rtfDoc, (Annotation) element)); break; case Element.IMGRAW: case Element.IMGTEMPLATE: case Element.JPEG: rtfElements.add(new RtfImage(rtfDoc, (Image) element)); break; case Element.AUTHOR: case Element.SUBJECT: case Element.KEYWORDS: case Element.TITLE: case Element.PRODUCER: case Element.CREATIONDATE: rtfElements.add(new RtfInfoElement(rtfDoc, (Meta) element)); break; case Element.LIST: rtfElements.add(new RtfList(rtfDoc, (List) element)); // TODO: Testing break; case Element.LISTITEM: rtfElements.add(new RtfListItem(rtfDoc, (ListItem) element)); // TODO: Testing break; case Element.SECTION: rtfElements.add(new RtfSection(rtfDoc, (Section) element)); break; case Element.CHAPTER: rtfElements.add(new RtfChapter(rtfDoc, (Chapter) element)); break; case Element.TABLE: try { rtfElements.add(new RtfTable(rtfDoc, (Table) element)); } catch(ClassCastException e) { rtfElements.add(new RtfTable(rtfDoc, ((SimpleTable) element).createTable())); } break; case Element.PTABLE: try { rtfElements.add(new RtfTable(rtfDoc, (PdfPTable) element)); } catch(ClassCastException e) { rtfElements.add(new RtfTable(rtfDoc, ((SimpleTable) element).createTable())); } break; } return (RtfBasicElement[]) rtfElements.toArray(new RtfBasicElement[rtfElements.size()]); } } src/rtf/com/lowagie/text/rtf/RtfWriter2.java100644 0 0 33757 11106243445 16467 0ustar 0 0 /* * $Id: RtfWriter2.java 3583 2008-08-12 00:00:09Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.EventListener; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Rectangle; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.document.RtfDocumentSettings; import com.lowagie.text.rtf.parser.RtfImportMappings; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.text.RtfNewPage; /** * The RtfWriter allows the creation of rtf documents via the iText system * * Version: $Id: RtfWriter2.java 3583 2008-08-12 00:00:09Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) */ public class RtfWriter2 extends DocWriter { /** * The RtfDocument this RtfWriter is creating */ private RtfDocument rtfDoc = null; /** * Constructs a new RtfWriter that listens to the specified Document and * writes its output to the OutputStream. * * @param doc The Document that this RtfWriter listens to * @param os The OutputStream to write to */ protected RtfWriter2(Document doc, OutputStream os) { super(doc, os); doc.addDocListener(this); rtfDoc = new RtfDocument(); } /** * Static method to generate RtfWriters * * @param doc The Document that this RtfWriter listens to * @param os The OutputStream to write to * @return The new RtfWriter */ public static RtfWriter2 getInstance(Document doc, OutputStream os) { return new RtfWriter2(doc, os); } /** * Sets the header to use * * @param hf The HeaderFooter to use */ public void setHeader(HeaderFooter hf) { this.rtfDoc.getDocumentHeader().setHeader(hf); } /** * Resets the header */ public void resetHeader() { this.rtfDoc.getDocumentHeader().setHeader(null); } /** * Sets the footer to use * * @param hf The HeaderFooter to use */ public void setFooter(HeaderFooter hf) { this.rtfDoc.getDocumentHeader().setFooter(hf); } /** * Resets the footer */ public void resetFooter() { this.rtfDoc.getDocumentHeader().setFooter(null); } /** * This method is not supported in the RtfWriter * @param i Unused */ public void setPageCount(int i) {} /** * This method is not supported in the RtfWriter */ public void resetPageCount() {} /** * This method is not supported in the RtfWriter */ public void clearTextWrap() {} /** * Opens the RtfDocument */ public void open() { super.open(); this.rtfDoc.open(); } /** * Closes the RtfDocument. This causes the document to be written * to the specified OutputStream */ public void close() { if (open) { rtfDoc.writeDocument(os); super.close(); this.rtfDoc = new RtfDocument(); } } /** * Adds an Element to the Document * * @param element The element to be added * @return false * @throws DocumentException */ public boolean add(Element element) throws DocumentException { if (pause) { return false; } RtfBasicElement[] rtfElements = rtfDoc.getMapper().mapElement(element); if(rtfElements.length != 0) { for(int i = 0; i < rtfElements.length; i++) { if(rtfElements[i] != null) { rtfDoc.add(rtfElements[i]); } } return true; } else { return false; } } /** * Adds a page break * * @return false */ public boolean newPage() { rtfDoc.add(new RtfNewPage(rtfDoc)); return true; } /** * Sets the page margins * * @param left The left margin * @param right The right margin * @param top The top margin * @param bottom The bottom margin * @return false */ public boolean setMargins(float left, float right, float top, float bottom) { rtfDoc.getDocumentHeader().getPageSetting().setMarginLeft((int) (left * RtfElement.TWIPS_FACTOR)); rtfDoc.getDocumentHeader().getPageSetting().setMarginRight((int) (right * RtfElement.TWIPS_FACTOR)); rtfDoc.getDocumentHeader().getPageSetting().setMarginTop((int) (top * RtfElement.TWIPS_FACTOR)); rtfDoc.getDocumentHeader().getPageSetting().setMarginBottom((int) (bottom * RtfElement.TWIPS_FACTOR)); return true; } /** * Sets the size of the page * * @param rect A Rectangle representing the page * @return false */ public boolean setPageSize(Rectangle rect) { rtfDoc.getDocumentHeader().getPageSetting().setPageSize(rect); return true; } /** * Whether to automagically generate table of contents entries when * adding Chapters or Sections. * * @param autogenerate Whether to automatically generate TOC entries */ public void setAutogenerateTOCEntries(boolean autogenerate) { this.rtfDoc.setAutogenerateTOCEntries(autogenerate); } /** * Gets the RtfDocumentSettings that specify how the rtf document is generated. * * @return The current RtfDocumentSettings. */ public RtfDocumentSettings getDocumentSettings() { return this.rtfDoc.getDocumentSettings(); } /** * Adds the complete RTF document to the current RTF document being generated. * It will parse the font and color tables and correct the font and color references * so that the imported RTF document retains its formattings. * * @param documentSource The Reader to read the RTF document from. * @throws IOException On errors reading the RTF document. * @throws DocumentException On errors adding to this RTF document. * @since 2.1.0 */ public void importRtfDocument(FileInputStream documentSource) throws IOException, DocumentException { importRtfDocument(documentSource, null); } /** * Adds the complete RTF document to the current RTF document being generated. * It will parse the font and color tables and correct the font and color references * so that the imported RTF document retains its formattings. * Uses new RtfParser object. * * (author: Howard Shank) * * @param documentSource The InputStream to read the RTF document from. * @param events The array of event listeners. May be null * @throws IOException * @throws DocumentException * * @see RtfParser * @see RtfParser#importRtfDocument(InputStream, RtfDocument) * @since 2.0.8 */ public void importRtfDocument(InputStream documentSource, EventListener[] events ) throws IOException, DocumentException { if(!this.open) { throw new DocumentException("The document must be open to import RTF documents."); } RtfParser rtfImport = new RtfParser(this.document); if(events != null) { for(int idx=0;idx
      * * For convenience the RtfDirectContent provides a DIRECT_SOFT_LINEBREAK * constant that makes it possible to easily add soft line-breaks anywhere in * the RTF document. * * @version $Id: RtfDirectContent.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfDirectContent extends RtfAddableElement { /** * Add the DIRECT_SOFT_LINEBREAK to the Document to insert * a soft line-break at that position. */ public static final RtfDirectContent DIRECT_SOFT_LINEBREAK = new RtfDirectContent("\\line"); /** * The direct content to add. */ private String directContent = ""; /** * Constructs a new RtfDirectContent with the content to add. * * @param directContent The content to add. */ public RtfDirectContent(String directContent) { this.directContent = directContent; } /** * Writes the element content to the given output stream. */ public void writeContent(final OutputStream out) throws IOException { final byte[] contentBytes = DocWriter.getISOBytes(this.directContent); out.write(contentBytes); } } src/rtf/com/lowagie/text/rtf/document/RtfCodePage.java100644 0 0 7625 11106243445 20371 0ustar 0 0 /* * $Id:RtfCodePage.java 3126 2008-02-07 20:30:46Z hallm $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; /** * The RtfCodePage class allows different code pages to be used in the rtf document. * Currently always ansi / ansicpg1252 * * @version $Id:RtfCodePage.java 3126 2008-02-07 20:30:46Z hallm $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfCodePage extends RtfElement implements RtfExtendedElement { /** * Constant for ansi encoded rtf documents */ private static final byte[] ANSI = DocWriter.getISOBytes("\\ansi"); /** * Constant for the ansi codepage */ private static final byte[] ANSI_CODEPAGE = DocWriter.getISOBytes("\\ansicpg"); /** * Construct an RtfCodePage * * @param doc The RtfDocument this RtfCodePage belongs to */ public RtfCodePage(RtfDocument doc) { super(doc); } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Writes the selected codepage */ public void writeDefinition(final OutputStream result) throws IOException { result.write(ANSI); result.write(ANSI_CODEPAGE); result.write(intToByteArray(1252)); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/document/RtfDocument.java100644 0 0 32517 11106243445 20516 0ustar 0 0 /* * $Id: RtfDocument.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2003, 2004, 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfMapper; import com.lowagie.text.rtf.document.output.RtfDataCache; import com.lowagie.text.rtf.document.output.RtfDiskCache; import com.lowagie.text.rtf.document.output.RtfEfficientMemoryCache; import com.lowagie.text.rtf.document.output.RtfMemoryCache; import com.lowagie.text.rtf.graphic.RtfImage; /** * The RtfDocument stores all document related data and also the main data stream. * INTERNAL CLASS - NOT TO BE USED DIRECTLY * * @version $Id: RtfDocument.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Todd Bush [Tab support] * @author Thomas Bickel (tmb99@inode.at) * @since 1.x */ public class RtfDocument extends RtfElement { /** * Stores the actual document data */ private RtfDataCache data = null; /** * The RtfMapper to use in this RtfDocument */ private RtfMapper mapper = null; /** * The RtfDocumentHeader that handles all document header methods */ private RtfDocumentHeader documentHeader = null; /** * Stores integers that have been generated as unique random numbers */ private ArrayList previousRandomInts = null; /** * Whether to automatically generate TOC entries for Chapters and Sections. Defaults to false */ private boolean autogenerateTOCEntries = false; /** * The RtfDocumentSettings for this RtfDocument. */ private RtfDocumentSettings documentSettings = null; /** * The last RtfBasicElement that was added directly to the RtfDocument. */ private RtfBasicElement lastElementWritten = null; /** * Constant for the Rtf document start */ private static final byte[] RTF_DOCUMENT = DocWriter.getISOBytes("\\rtf1"); private final static byte[] FSC_LINE = DocWriter.getISOBytes("\\line "); private final static byte[] FSC_PAR = DocWriter.getISOBytes("\\par "); private final static byte[] FSC_TAB = DocWriter.getISOBytes("\\tab "); private final static byte[] FSC_PAGE_PAR = DocWriter.getISOBytes("\\page\\par "); private final static byte[] FSC_NEWPAGE = DocWriter.getISOBytes("$newpage$"); private final static byte[] FSC_BACKSLASH = DocWriter.getISOBytes("\\"); private final static byte[] FSC_HEX_PREFIX = DocWriter.getISOBytes("\\\'"); private final static byte[] FSC_UNI_PREFIX = DocWriter.getISOBytes("\\u"); /** * The default constructor for a RtfDocument */ public RtfDocument() { super(null); this.data = new RtfMemoryCache(); this.mapper = new RtfMapper(this); this.documentHeader = new RtfDocumentHeader(this); this.documentHeader.init(); this.previousRandomInts = new ArrayList(); this.documentSettings = new RtfDocumentSettings(this); } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Writes the document * * @param out The OutputStream to write the RTF document to. */ public void writeDocument(OutputStream out) { try { out.write(OPEN_GROUP); out.write(RtfDocument.RTF_DOCUMENT); this.documentHeader.writeContent(out); this.data.writeTo(out); out.write(CLOSE_GROUP); } catch(IOException ioe) { ioe.printStackTrace(); } } /** * Opens the RtfDocument and initializes the data cache. If the data cache is * set to CACHE_DISK, but the cache cannot be initialized then the memory cache * is used. */ public void open() { try { switch(this.documentSettings.getDataCacheStyle()) { case RtfDataCache.CACHE_MEMORY_EFFICIENT: this.data = new RtfEfficientMemoryCache(); break; case RtfDataCache.CACHE_MEMORY: this.data = new RtfMemoryCache(); break; case RtfDataCache.CACHE_DISK: this.data = new RtfDiskCache(); break; default: throw new RuntimeException("unknown"); } } catch(IOException ioe) { System.err.println("Could not initialize disk cache. Using memory cache."); ioe.printStackTrace(); this.data = new RtfMemoryCache(); } } /** * Adds an element to the rtf document * * @param element The element to add */ public void add(RtfBasicElement element) { try { if(element instanceof RtfInfoElement) { this.documentHeader.addInfoElement((RtfInfoElement) element); } else { if(element instanceof RtfImage) { ((RtfImage) element).setTopLevelElement(true); } element.writeContent( this.data.getOutputStream() ); this.lastElementWritten = element; } } catch(IOException ioe) { ioe.printStackTrace(); } } /** * Gets the RtfMapper object of this RtfDocument * * @return The RtfMapper */ public RtfMapper getMapper() { return this.mapper; } /** * Generates a random integer that is unique with respect to the document. * Will not return a number between -1 and -5 because some values in that range are invalid. * @return A random int */ public int getRandomInt() { Integer newInt = null; do { // do { newInt = new Integer((int) (Math.random() * Integer.MAX_VALUE)); // } while(newInt.intValue() <= -1 && newInt.intValue() >= -5); } while(this.previousRandomInts.contains(newInt)); this.previousRandomInts.add(newInt); return newInt.intValue(); } /** * Gets the RtfDocumentHeader of this RtfDocument * * @return The RtfDocumentHeader of this RtfDocument */ public RtfDocumentHeader getDocumentHeader() { return this.documentHeader; } /** * Writes the given string to the given {@link OutputStream} encoding the string characters. * * @param out destination OutputStream * @param str string to write * @param useHex if true hex encoding characters is preferred to unicode encoding if possible * @param softLineBreaks if true return characters are written as soft line breaks * * @throws IOException */ public void filterSpecialChar(final OutputStream out, final String str, final boolean useHex, final boolean softLineBreaks) throws IOException { if(out == null) { throw new NullPointerException("null OutpuStream"); } final boolean alwaysUseUniCode = this.documentSettings.isAlwaysUseUnicode(); if(str == null) { return; } final int len = str.length(); if(len == 0) { return; } for(int k = 0; k < len; k++) { final char c = str.charAt(k); if(c < 0x20) { //allow return and tab only if(c == '\n') { out.write(softLineBreaks ? FSC_LINE : FSC_PAR); } else if(c == '\t') { out.write(FSC_TAB); } else { out.write('?'); } } else if((c == '\\') || (c == '{') || (c == '}')) { //escape out.write(FSC_BACKSLASH); out.write(c); } else if((c == '$') && (len-k >= FSC_NEWPAGE.length) && subMatch(str, k, FSC_NEWPAGE)) { out.write(FSC_PAGE_PAR); k += FSC_NEWPAGE.length-1; } else { if((c > 0xff) || ((c > 'z') && alwaysUseUniCode)) { if(useHex && (c <= 0xff)) { //encode as 2 char hex string out.write(FSC_HEX_PREFIX); out.write(RtfImage.byte2charLUT, c*2, 2); } else { //encode as decimal, signed short value out.write(FSC_UNI_PREFIX); String s = Short.toString((short)c); for(int x = 0; x < s.length(); x++) { out.write(s.charAt(x)); } out.write('?'); } } else { out.write(c); } } } } /** * Returns true if m.length characters in str, starting at offset soff * match the bytes in the given array m. * * @param str the string to search for a match * @param soff the starting offset in str * @param m the array to match * @return true if there is match */ private static boolean subMatch(final String str, int soff, final byte[] m) { for(int k = 0; k < m.length; k++) { if(str.charAt(soff++) != m[k]) { return false; } } return true; } /** * Whether to automagically generate table of contents entries when * adding Chapters or Sections. * * @param autogenerate Whether to automatically generate TOC entries */ public void setAutogenerateTOCEntries(boolean autogenerate) { this.autogenerateTOCEntries = autogenerate; } /** * Get whether to automatically generate table of contents entries * * @return Whether to automatically generate TOC entries */ public boolean getAutogenerateTOCEntries() { return this.autogenerateTOCEntries; } /** * Gets the RtfDocumentSettings that specify how the rtf document is generated. * * @return The current RtfDocumentSettings. */ public RtfDocumentSettings getDocumentSettings() { return this.documentSettings; } /** * Gets the last RtfBasicElement that was directly added to the RtfDocument. * * @return The last RtfBasicElement that was directly added to the RtfDocument. */ public RtfBasicElement getLastElementWritten() { return this.lastElementWritten; } /** * Helper method outputs linebreak in document if debugging is turned on. * @param result the OutputStream to write the linebreak to. * @throws IOException * @since 2.1.3 */ final public void outputDebugLinebreak(final OutputStream result) throws IOException { if(this.getDocumentSettings().isOutputDebugLineBreaks()) { result.write('\n'); } } }src/rtf/com/lowagie/text/rtf/document/RtfDocumentHeader.java100644 0 0 27665 11106243445 21637 0ustar 0 0 /* * $Id: RtfDocumentHeader.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.HeaderFooter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.output.RtfNilOutputStream; import com.lowagie.text.rtf.headerfooter.RtfHeaderFooter; import com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup; import com.lowagie.text.rtf.list.RtfList; import com.lowagie.text.rtf.list.RtfListTable; import com.lowagie.text.rtf.style.RtfColor; import com.lowagie.text.rtf.style.RtfColorList; import com.lowagie.text.rtf.style.RtfFont; import com.lowagie.text.rtf.style.RtfFontList; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.style.RtfStylesheetList; /** * The RtfDocumentHeader contains all classes required for the generation of * the document header area. * * @version $Id: RtfDocumentHeader.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) * @author Howard Shank (hgshank@yahoo.com) */ public class RtfDocumentHeader extends RtfElement { /** * Constant for the title page */ private static final byte[] TITLE_PAGE = DocWriter.getISOBytes("\\titlepg"); /** * Constant for facing pages */ private static final byte[] FACING_PAGES = DocWriter.getISOBytes("\\facingp"); /** * The code page to use */ private RtfCodePage codePage = null; /** * Stores all the colors used in the document */ private RtfColorList colorList = null; /** * Stores all the fonts used in the document */ private RtfFontList fontList = null; /** * Manages List tables */ private RtfListTable listTable = null; /** * Stores all paragraph styles used in the document. */ private RtfStylesheetList stylesheetList = null; /** * Generator string in document */ private RtfGenerator generator = null; /** * The information group with author/subject/keywords/title/producer/creationdate data */ private RtfInfoGroup infoGroup = null; /** * The protection settings * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private RtfProtectionSetting protectionSetting = null; /** * The page settings */ private RtfPageSetting pageSetting = null; /** * The current RtfHeaderFooterGroup for the header */ private HeaderFooter header = null; /** * The current RtfHeaderFooterGroup for the footer */ private HeaderFooter footer = null; /** * Constructs a RtfDocumentHeader for a RtfDocument * * @param doc The RtfDocument this RtfDocumentHeader belongs to */ protected RtfDocumentHeader(RtfDocument doc) { super(doc); } /** * initializes the RtfDocumentHeader. */ protected void init() { this.codePage = new RtfCodePage(this.document); this.colorList = new RtfColorList(this.document); this.fontList = new RtfFontList(this.document); this.listTable = new RtfListTable(this.document); this.stylesheetList = new RtfStylesheetList(this.document); this.infoGroup = new RtfInfoGroup(this.document); this.protectionSetting = new RtfProtectionSetting(this.document); this.pageSetting = new RtfPageSetting(this.document); this.header = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_HEADER); this.footer = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_FOOTER); this.generator = new RtfGenerator(this.document); } /** * Writes the contents of the document header area. */ public void writeContent(final OutputStream result) throws IOException { try { // This is so that all color, font and similar information is processed once, before // the header section is written. writeSectionDefinition(new RtfNilOutputStream()); this.codePage.writeDefinition(result); this.fontList.writeDefinition(result); this.colorList.writeDefinition(result); this.stylesheetList.writeDefinition(result); this.listTable.writeDefinition(result); this.generator.writeContent(result); this.infoGroup.writeContent(result); this.protectionSetting.writeDefinition(result); this.pageSetting.writeDefinition(result); writeSectionDefinition(result); } catch(IOException ioe) { ioe.printStackTrace(); } } /** * Writes the section definition data * @param result */ public void writeSectionDefinition(final OutputStream result) { try { RtfHeaderFooterGroup header = convertHeaderFooter(this.header, RtfHeaderFooter.TYPE_HEADER); RtfHeaderFooterGroup footer = convertHeaderFooter(this.footer, RtfHeaderFooter.TYPE_FOOTER); if(header.hasTitlePage() || footer.hasTitlePage()) { result.write(TITLE_PAGE); header.setHasTitlePage(); footer.setHasTitlePage(); } if(header.hasFacingPages() || footer.hasFacingPages()) { result.write(FACING_PAGES); header.setHasFacingPages(); footer.setHasFacingPages(); } footer.writeContent(result); header.writeContent(result); pageSetting.writeSectionDefinition(result); } catch(IOException ioe) { ioe.printStackTrace(); } } /** * Gets the number of the specified RtfFont * * @param font The RtfFont for which to get the number * @return The number of the font */ public int getFontNumber(RtfFont font) { return this.fontList.getFontNumber(font); } /** * Gets the number of the specified RtfColor * * @param color The RtfColor for which to get the number * @return The number of the color */ public int getColorNumber(RtfColor color) { return this.colorList.getColorNumber(color); } /** * Gets the number of the specified RtfList * * @param list The RtfList for which to get the number * @return The number of the list */ public int getListNumber(RtfList list) { return this.listTable.getListNumber(list); } /** * Gets the RtfParagraphStyle with the given style name. * * @param styleName The style name of the RtfParagraphStyle to get. * @return The RtfParagraphStyle with the given style name or null. */ public RtfParagraphStyle getRtfParagraphStyle(String styleName) { return this.stylesheetList.getRtfParagraphStyle(styleName); } /** * Removes a RtfList from the list table * * @param list The RtfList to remove */ public void freeListNumber(RtfList list) { this.listTable.freeListNumber(list); } /** * Gets the RtfPageSetting object of this RtfDocument * * @return The RtfPageSetting object */ public RtfPageSetting getPageSetting() { return this.pageSetting; } /** * Adds an RtfInfoElement to the list of RtfInfoElements * * @param rtfInfoElement The RtfInfoElement to add */ public void addInfoElement(RtfInfoElement rtfInfoElement) { this.infoGroup.add(rtfInfoElement); } /** * Sets the current header to use * * @param header The HeaderFooter to use as header */ public void setHeader(HeaderFooter header) { this.header = header; } /** * Sets the current footer to use * * @param footer The HeaderFooter to use as footer */ public void setFooter(HeaderFooter footer) { this.footer = footer; } /** * Registers the RtfParagraphStyle for further use in the document. * * @param rtfParagraphStyle The RtfParagraphStyle to register. */ public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { this.stylesheetList.registerParagraphStyle(rtfParagraphStyle); } /** * Converts a HeaderFooter into a RtfHeaderFooterGroup. Depending on which class * the HeaderFooter is, the correct RtfHeaderFooterGroup is created. * * @param hf The HeaderFooter to convert. * @param type Whether the conversion is being done on a footer or header * @return The converted RtfHeaderFooterGroup. * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooter * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup */ private RtfHeaderFooterGroup convertHeaderFooter(HeaderFooter hf, int type) { if(hf != null) { if(hf instanceof RtfHeaderFooterGroup) { return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooterGroup) hf, type); } else if(hf instanceof RtfHeaderFooter) { return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooter) hf, type); } else { return new RtfHeaderFooterGroup(this.document, hf, type); } } else { return new RtfHeaderFooterGroup(this.document, type); } } /** * Get the RtfListTable object. * * @return the ListTable object. * @since 2.1.3 */ public RtfListTable getListTable() { return this.listTable; } } src/rtf/com/lowagie/text/rtf/document/RtfDocumentSettings.java100644 0 0 46262 11106243445 22241 0ustar 0 0 /* * $Id: RtfDocumentSettings.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2003, 2004, 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.document.output.RtfDataCache; import com.lowagie.text.rtf.style.RtfParagraphStyle; /** * The RtfDocumentSettings contains output specific settings. These settings modify * how the actual document is then generated and some settings may mean that some * RTF readers can't read the document or render it wrongly. * * @version $Id: RtfDocumentSettings.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) * @author Howard Shank (hgshank@yahoo.com) */ public class RtfDocumentSettings { /** * The RtfDocument this RtfDocumentSettings belongs to. */ private RtfDocument document = null; /** * Whether to also output the table row definition after the cell content. */ private boolean outputTableRowDefinitionAfter = true; /** * Whether to output the line breaks that make the rtf document source more readable. */ private boolean outputDebugLineBreaks = false; /** * Whether to always generate soft linebreaks for \n in Chunks. */ private boolean alwaysGenerateSoftLinebreaks = false; /** * Whether to always translate characters past 'z' into unicode representations. */ private boolean alwaysUseUnicode = true; /** * How to cache the document during generation. Defaults to RtfDataCache.CACHE_MEMORY; */ private int dataCacheStyle = RtfDataCache.CACHE_MEMORY; /** * Whether to write image scaling information. This is required for Word 2000, 97 and Word for Mac */ private boolean writeImageScalingInformation = false; /** * Whether images should be written in order to mimick the PDF output. */ private boolean imagePDFConformance = true; /** * Document protection level. * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private int protectionLevel = RtfProtection.LEVEL_NONE; /** * Document protection level password hash. * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private String protectionHash = null; /** * Document read password hash. * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private String writereservhash = null; //\*\writereservhash - not implemented /** * Document recommended to be opened in read only mode. * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private boolean readOnlyRecommended = false; /** * Images are written as binary data and not hex encoded. * Author: Mark Hall (Mark.Hall@mail.room3b.eu) * @since 2.1.1 */ private boolean imageWrittenAsBinary = true; /** * Constructs a new RtfDocumentSettings object. * * @param document The RtfDocument this RtfDocumentSettings belong to. */ public RtfDocumentSettings(RtfDocument document) { this.document = document; } /** * Gets whether to output the line breaks for increased rtf document readability. * * @return Whether to output line breaks. */ public boolean isOutputDebugLineBreaks() { return outputDebugLineBreaks; } /** * Sets whether to output the line breaks for increased rtf document readability. * Some line breaks may be added where the rtf specification demands it. * * @param outputDebugLineBreaks The outputDebugLineBreaks to set. */ public void setOutputDebugLineBreaks(boolean outputDebugLineBreaks) { this.outputDebugLineBreaks = outputDebugLineBreaks; } /** * Gets whether the table row definition should also be written after the cell content. * * @return Returns the outputTableRowDefinitionAfter. */ public boolean isOutputTableRowDefinitionAfter() { return outputTableRowDefinitionAfter; } /** * Sets whether the table row definition should also be written after the cell content. * This is recommended to be set to true if you need Word2000 compatiblity and * false if the document should be opened in OpenOffice.org Writer. * * @param outputTableRowDefinitionAfter The outputTableRowDefinitionAfter to set. */ public void setOutputTableRowDefinitionAfter( boolean outputTableRowDefinitionAfter) { this.outputTableRowDefinitionAfter = outputTableRowDefinitionAfter; } /** * Gets whether all linebreaks inside Chunks are generated as soft linebreaks. * * @return True if soft linebreaks are generated, false for hard linebreaks. */ public boolean isAlwaysGenerateSoftLinebreaks() { return this.alwaysGenerateSoftLinebreaks; } /** * Sets whether to always generate soft linebreaks. * * @param alwaysGenerateSoftLinebreaks Whether to always generate soft linebreaks. */ public void setAlwaysGenerateSoftLinebreaks(boolean alwaysGenerateSoftLinebreaks) { this.alwaysGenerateSoftLinebreaks = alwaysGenerateSoftLinebreaks; } /** * Gets whether all characters bigger than 'z' are represented as unicode. * * @return True if unicode representation is used, false otherwise. */ public boolean isAlwaysUseUnicode() { return this.alwaysUseUnicode; } /** * Sets whether to represent all characters bigger than 'z' as unicode. * * @param alwaysUseUnicode True to use unicode representation, false otherwise. */ public void setAlwaysUseUnicode(boolean alwaysUseUnicode) { this.alwaysUseUnicode = alwaysUseUnicode; } /** * Registers the RtfParagraphStyle for further use in the document. This does not need to be * done for the default styles in the RtfParagraphStyle object. Those are added automatically. * * @param rtfParagraphStyle The RtfParagraphStyle to register. */ public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { this.document.getDocumentHeader().registerParagraphStyle(rtfParagraphStyle); } /** * Sets the data cache style. This controls where the document is cached during * generation. Two cache styles are supported: *
        *
      • RtfDataCache.CACHE_MEMORY: The document is cached in memory. This is fast, * but places a limit on how big the document can get before causing * OutOfMemoryExceptions.
      • *
      • RtfDataCache.CACHE_DISK: The document is cached on disk. This is slower * than the CACHE_MEMORY setting, but the document size is now only constrained * by the amount of free disk space.
      • *
      * * @param dataCacheStyle The data cache style to set. Valid constants can be found * in RtfDataCache. * @see com.lowagie.text.rtf.document.output.RtfDataCache */ public void setDataCacheStyle(int dataCacheStyle) { switch(dataCacheStyle) { case RtfDataCache.CACHE_MEMORY_EFFICIENT: this.dataCacheStyle = RtfDataCache.CACHE_MEMORY_EFFICIENT; break; case RtfDataCache.CACHE_DISK: this.dataCacheStyle = RtfDataCache.CACHE_DISK; break; default: case RtfDataCache.CACHE_MEMORY: this.dataCacheStyle = RtfDataCache.CACHE_MEMORY; break; } } /** * Gets the current data cache style. * * @return The current data cache style. */ public int getDataCacheStyle() { return this.dataCacheStyle; } /** * Gets the current setting on image PDF conformance. * * @return The current image PDF conformance. */ public boolean isImagePDFConformance() { return this.imagePDFConformance; } /** * Sets the image PDF conformance setting. By default images will be added * as if they were displayed with 72dpi. Set this to false * if images should be generated with the Word default DPI setting. * * @param imagePDFConformance True if PDF equivalence is desired, false * for the default Word display. */ public void setImagePDFConformance(boolean imagePDFConformance) { this.imagePDFConformance = imagePDFConformance; } /** * Gets whether to write scaling information for images. * * @return Whether to write scaling information for images. */ public boolean isWriteImageScalingInformation() { return this.writeImageScalingInformation; } /** * Sets whether image scaling information should be written. This needs to be set to true * MS Word 2000, MS Word 97 and Word for Mac. * * @param writeImageScalingInformation Whether to write image scaling information. */ public void setWriteImageScalingInformation(boolean writeImageScalingInformation) { this.writeImageScalingInformation = writeImageScalingInformation; } /** * Set the options required for RTF documents to display correctly in MS Word 2000 * and MS Word 97. * Sets outputTableRowDefinitionAfter = true and writeImageScalingInformation = true. */ public void setOptionsForMSWord2000And97() { this.setOutputTableRowDefinitionAfter(true); this.setWriteImageScalingInformation(true); } /** * Set the options required for RTF documents to display correctly in MS Word for Mac. * Sets writeImageScalingInformation = true. */ public void setOptionsForMSWordForMac() { this.setWriteImageScalingInformation(true); } /** * Set the options required for RTF documents to display correctly in MS Word XP (2002). * Sets writeImageScalingInformation = false. */ public void setOptionsForMSWordXP() { this.setWriteImageScalingInformation(false); } /** * Set the options required for RTF documents to display correctly in OpenOffice.Org * Writer. * Sets outputTableRowDefinitionAfter = false. */ public void setOptionsForOpenOfficeOrg() { this.setOutputTableRowDefinitionAfter(false); } /** * Author: Howard Shank (hgshank@yahoo.com) * @param level Document protecton level * @param pwd Document password - clear text * @since 2.1.1 */ public boolean setProtection(int level, String pwd) { boolean result = false; if(this.protectionHash == null) { if(!setProtectionLevel(level)) { result = false; } else { protectionHash = RtfProtection.generateHash(pwd); result = true; } } else { if(this.protectionHash.equals(RtfProtection.generateHash(pwd))) { if(!setProtectionLevel(level)) { result = false; } else { protectionHash = RtfProtection.generateHash(pwd); result = true; } } } return result; } /** * Author: Howard Shank (hgshank@yahoo.com) * @param pwd Document password - clear text * @return true if document unprotected, false if protection is not removed. * @since 2.1.1 */ public boolean unprotectDocument(String pwd) { boolean result = false; if (this.protectionHash.equals(RtfProtection.generateHash(pwd))) { this.protectionLevel = RtfProtection.LEVEL_NONE; this.protectionHash = null; result = true; } return result; } /** * Author: Howard Shank (hgshank@yahoo.com) * @param level Document protection level * @since 2.1.1 */ public boolean setProtectionLevel(int level) { boolean result = false; switch(level) { case RtfProtection.LEVEL_NONE: if(this.protectionHash == null) { break; } case RtfProtection.LEVEL_ANNOTPROT: case RtfProtection.LEVEL_FORMPROT: case RtfProtection.LEVEL_REVPROT: case RtfProtection.LEVEL_READPROT: this.protectionLevel = level; result = true; break; default: } return result; } /** * This function is not intended for general use. Please see 'public boolean setProtection(int level, String pwd)'. * Author: Howard Shank (hgshank@yahoo.com) * @param pwd Password HASH to set the document password hash to. * @since 2.1.1 */ public void setPasswordHash(String pwd) { if(pwd != null && pwd.length() != 8) return; this.protectionHash = pwd; } /** * Converts protection level from internal bitmap value to protlevel output value. * Author: Howard Shank (hgshank@yahoo.com) * @return
           * 0 = Revision protection
           * 1 = Annotation/Comment protection
           * 2 = Form protection
           * 3 = Read only protection
           * 
      * @since 2.1.1 */ private int convertProtectionLevel() { int level = 0; switch(this.protectionLevel) { case RtfProtection.LEVEL_NONE: break; case RtfProtection.LEVEL_REVPROT: level = 0; break; case RtfProtection.LEVEL_ANNOTPROT: level = 1; break; case RtfProtection.LEVEL_FORMPROT: level = 2; break; case RtfProtection.LEVEL_READPROT: level = 3; break; } return level; } /** * Author: Howard Shank (hgshank@yahoo.com) * @return RTF document protection level * @since 2.1.1 */ public int getProtectionLevelRaw() { return this.protectionLevel; } /** * Author: Howard Shank (hgshank@yahoo.com) * @return RTF document protection level * @since 2.1.1 */ public int getProtectionLevel() { return convertProtectionLevel(); } /** * Author: Howard Shank (hgshank@yahoo.com) * @return RTF document protection level as a byte array (byte[]) * @since 2.1.1 */ public byte[] getProtectionLevelBytes() { return DocWriter.getISOBytes(Integer.toString(convertProtectionLevel())); } /** * Author: Howard Shank (hgshank@yahoo.com) * @param oldPwd Old password - clear text * @param newPwd New password - clear text * @return true if password set, false if password not set * @since 2.1.1 */ public boolean setNewPassword(String oldPwd, String newPwd) { boolean result = false; if (this.protectionHash.equals(RtfProtection.generateHash(oldPwd))) { this.protectionHash = RtfProtection.generateHash(newPwd); result = true; } return result; } /** * Set the RTF flag that recommends the document be opened in read only mode. * Author: Howard Shank (hgshank@yahoo.com) * @param value true if the flag is to be set, false if it is NOT to be set * @since 2.1.1 */ public void setReadOnlyRecommended(boolean value) { this.readOnlyRecommended = value; } /** * Get the RTF flag that recommends if the the document should be opened in read only mode. * Author: Howard Shank (hgshank@yahoo.com) * @return true if flag is set, false if it is not set * @since 2.1.1 */ public boolean getReadOnlyRecommended() { return this.readOnlyRecommended; } /** * Determine if document has protection enabled. * Author: Howard Shank (hgshank@yahoo.com) * @return true if protection is enabled, false if it is not enabled * @since 2.1.1 */ public boolean isDocumentProtected() { return !(this.protectionHash == null); } /** * Obtain the password has as a byte array. * Author: Howard Shank (hgshank@yahoo.com) * @return The bytes of the password hash as a byte array (byte[]) * @since 2.1.1 */ public byte[] getProtectionHashBytes() { return DocWriter.getISOBytes(this.protectionHash); } /** * Set whether images are written as binary data or are hex encoded. * Author: Mark Hall (Mark.Hall@mail.room3b.eu) * @param imageWrittenAsBinary True to write images as binary data, false for hex encoding. * @since 2.1.1 */ public void setImageWrittenAsBinary(boolean imageWrittenAsBinary) { this.imageWrittenAsBinary = imageWrittenAsBinary; } /** * Gets whether images are written as binary data or are hex encoded. Defaults to true. * Author: Mark Hall (Mark.Hall@mail.room3b.eu) * @since 2.1.1 * @return True if images are written as binary data, false if hex encoded. */ public boolean isImageWrittenAsBinary() { return this.imageWrittenAsBinary; } } src/rtf/com/lowagie/text/rtf/document/RtfGenerator.java100644 0 0 7256 11106243445 20650 0ustar 0 0 /* * $Id: RtfGenerator.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2007 by Howard Shank * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Document; import com.lowagie.text.rtf.RtfElement; /** * The RtfGenerator creates the (\*\generator ...} element. * * @version $Id: RtfGenerator.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfGenerator extends RtfElement { /** * Generator group starting tag */ private static final byte[] GENERATOR = DocWriter.getISOBytes("\\*\\generator"); /** * Constructs a RtfGenerator belonging to a RtfDocument * * @param doc The RtfDocument this RtfGenerator belongs to */ public RtfGenerator(RtfDocument doc) { super(doc); } /** * Writes the RTF generator group. */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(GENERATOR); result.write(DELIMITER); result.write(DocWriter.getISOBytes(Document.getVersion())); result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/document/RtfInfoElement.java100644 0 0 14623 11106243445 21143 0ustar 0 0 /* * $Id: RtfInfoElement.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import com.lowagie.text.DocWriter; import com.lowagie.text.Meta; import com.lowagie.text.rtf.RtfElement; /** * Stores one information group element. Valid elements are * author, title, subject, keywords, producer and creationdate. * * @version $Id: RtfInfoElement.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfInfoElement extends RtfElement { /** * Constant for the author element */ private static final byte[] INFO_AUTHOR = DocWriter.getISOBytes("\\author"); /** * Constant for the subject element */ private static final byte[] INFO_SUBJECT = DocWriter.getISOBytes("\\subject"); /** * Constant for the keywords element */ private static final byte[] INFO_KEYWORDS = DocWriter.getISOBytes("\\keywords"); /** * Constant for the title element */ private static final byte[] INFO_TITLE = DocWriter.getISOBytes("\\title"); /** * Constant for the producer element */ private static final byte[] INFO_PRODUCER = DocWriter.getISOBytes("\\operator"); /** * Constant for the creationdate element */ private static final byte[] INFO_CREATION_DATE =DocWriter.getISOBytes( "\\creationdate"); /** * The type of this RtfInfoElement. The values from Element.INFO_ELEMENT_NAME are used. */ private int infoType = -1; /** * The content of this RtfInfoElement */ private String content = ""; /** * Constructs a RtfInfoElement based on the given Meta object * * @param doc The RtfDocument this RtfInfoElement belongs to * @param meta The Meta object this RtfInfoElement is based on */ public RtfInfoElement(RtfDocument doc, Meta meta) { super(doc); infoType = meta.type(); content = meta.getContent(); } /** * Writes the content of one RTF information element. */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); switch(infoType) { case Meta.AUTHOR: result.write(INFO_AUTHOR); break; case Meta.SUBJECT: result.write(INFO_SUBJECT); break; case Meta.KEYWORDS: result.write(INFO_KEYWORDS); break; case Meta.TITLE: result.write(INFO_TITLE); break; case Meta.PRODUCER: result.write(INFO_PRODUCER); break; case Meta.CREATIONDATE: result.write(INFO_CREATION_DATE); break; default: result.write(INFO_AUTHOR); break; } result.write(DELIMITER); if(infoType == Meta.CREATIONDATE) { result.write(DocWriter.getISOBytes(convertDate(content))); } else { document.filterSpecialChar(result, content, false, false); } result.write(CLOSE_GROUP); } /** * Converts a date from the format used by iText to the format required by * rtf.
      iText: EEE MMM dd HH:mm:ss zzz yyyy - rtf: \\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss * * @param date The date formated by iText * @return The date formated for rtf */ private String convertDate(String date) { SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); try { Date creationDate = sdf.parse(date); sdf = new SimpleDateFormat("\\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss"); return sdf.format(creationDate); } catch(ParseException pe) { pe.printStackTrace(); return ""; } } } src/rtf/com/lowagie/text/rtf/document/RtfInfoGroup.java100644 0 0 11242 11106243445 20640 0ustar 0 0 /* * $Id: RtfInfoGroup.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; /** * The RtfInfoGroup stores information group elements. * * @version $Id: RtfInfoGroup.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) * @author Howard Shank (hgshank@yahoo.com) */ public class RtfInfoGroup extends RtfElement { /** * Information group starting tag */ private static final byte[] INFO_GROUP = DocWriter.getISOBytes("\\info"); /** * Constant for the password element. * Author: Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ private static final byte[] INFO_PASSWORD = DocWriter.getISOBytes("\\*\\password"); /** * The RtfInfoElements that belong to this RtfInfoGroup */ ArrayList infoElements = null; /** * Constructs a RtfInfoGroup belonging to a RtfDocument * * @param doc The RtfDocument this RtfInfoGroup belongs to */ public RtfInfoGroup(RtfDocument doc) { super(doc); infoElements = new ArrayList(); } /** * Adds an RtfInfoElement to the RtfInfoGroup * * @param infoElement The RtfInfoElement to add */ public void add(RtfInfoElement infoElement) { this.infoElements.add(infoElement); } /** * Writes the RTF information group and its elements. */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(INFO_GROUP); for(int i = 0; i < infoElements.size(); i++) { RtfInfoElement infoElement = (RtfInfoElement) infoElements.get(i); infoElement.writeContent(result); } // handle document protection if(document.getDocumentSettings().isDocumentProtected()) { result.write(OPEN_GROUP); result.write(INFO_PASSWORD); result.write(DELIMITER); result.write(document.getDocumentSettings().getProtectionHashBytes()); result.write(CLOSE_GROUP); } result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/document/RtfPageSetting.java100644 0 0 33054 11106243445 21147 0ustar 0 0 /* * $Id:RtfPageSetting.java 3126 2008-02-07 20:30:46Z hallm $ * * Copyright 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.PageSize; import com.lowagie.text.Rectangle; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; /** * The RtfPageSetting stores the page size / page margins for a RtfDocument. * INTERNAL CLASS - NOT TO BE USED DIRECTLY * * @version $Id:RtfPageSetting.java 3126 2008-02-07 20:30:46Z hallm $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfPageSetting extends RtfElement implements RtfExtendedElement { /** * Constant for the page height */ private static final byte[] PAGE_WIDTH = DocWriter.getISOBytes("\\paperw"); /** * Constant for the page width */ private static final byte[] PAGE_HEIGHT = DocWriter.getISOBytes("\\paperh"); /** * Constant for the left margin */ private static final byte[] MARGIN_LEFT = DocWriter.getISOBytes("\\margl"); /** * Constant for the right margin */ private static final byte[] MARGIN_RIGHT = DocWriter.getISOBytes("\\margr"); /** * Constant for the top margin */ private static final byte[] MARGIN_TOP = DocWriter.getISOBytes("\\margt"); /** * Constant for the bottom margin */ private static final byte[] MARGIN_BOTTOM = DocWriter.getISOBytes("\\margb"); /** * Constant for landscape */ private static final byte[] LANDSCAPE = DocWriter.getISOBytes("\\lndscpsxn"); /** * Constant for the section page width */ private static final byte[] SECTION_PAGE_WIDTH = DocWriter.getISOBytes("\\pgwsxn"); /** * Constant for the section page height */ private static final byte[] SECTION_PAGE_HEIGHT = DocWriter.getISOBytes("\\pghsxn"); /** * Constant for the section left margin */ private static final byte[] SECTION_MARGIN_LEFT = DocWriter.getISOBytes("\\marglsxn"); /** * Constant for the section right margin */ private static final byte[] SECTION_MARGIN_RIGHT = DocWriter.getISOBytes("\\margrsxn"); /** * Constant for the section top margin */ private static final byte[] SECTION_MARGIN_TOP = DocWriter.getISOBytes("\\margtsxn"); /** * Constant for the section bottom margin */ private static final byte[] SECTION_MARGIN_BOTTOM = DocWriter.getISOBytes("\\margbsxn"); /** * The page width to use */ private int pageWidth = 11906; /** * The page height to use */ private int pageHeight = 16840; /** * The left margin to use */ private int marginLeft = 1800; /** * The right margin to use */ private int marginRight = 1800; /** * The top margin to use */ private int marginTop = 1440; /** * The bottom margin to use */ private int marginBottom = 1440; /** * Whether the page is portrait or landscape */ private boolean landscape = false; /** * Constructs a new RtfPageSetting object belonging to a RtfDocument. * * @param doc The RtfDocument this RtfPageSetting belongs to */ public RtfPageSetting(RtfDocument doc) { super(doc); } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Writes the page size / page margin definition */ public void writeDefinition(final OutputStream result) throws IOException { result.write(PAGE_WIDTH); result.write(intToByteArray(pageWidth)); result.write(PAGE_HEIGHT); result.write(intToByteArray(pageHeight)); result.write(MARGIN_LEFT); result.write(intToByteArray(marginLeft)); result.write(MARGIN_RIGHT); result.write(intToByteArray(marginRight)); result.write(MARGIN_TOP); result.write(intToByteArray(marginTop)); result.write(MARGIN_BOTTOM); result.write(intToByteArray(marginBottom)); this.document.outputDebugLinebreak(result); } /** * Writes the definition part for a new section */ public void writeSectionDefinition(final OutputStream result) throws IOException { if(landscape) { result.write(LANDSCAPE); result.write(SECTION_PAGE_WIDTH); result.write(intToByteArray(pageWidth)); result.write(SECTION_PAGE_HEIGHT); result.write(intToByteArray(pageHeight)); this.document.outputDebugLinebreak(result); } else { result.write(SECTION_PAGE_WIDTH); result.write(intToByteArray(pageWidth)); result.write(SECTION_PAGE_HEIGHT); result.write(intToByteArray(pageHeight)); this.document.outputDebugLinebreak(result); } result.write(SECTION_MARGIN_LEFT); result.write(intToByteArray(marginLeft)); result.write(SECTION_MARGIN_RIGHT); result.write(intToByteArray(marginRight)); result.write(SECTION_MARGIN_TOP); result.write(intToByteArray(marginTop)); result.write(SECTION_MARGIN_BOTTOM); result.write(intToByteArray(marginBottom)); } /** * Gets the bottom margin * * @return Returns the bottom margin */ public int getMarginBottom() { return marginBottom; } /** * Sets the bottom margin * * @param marginBottom The bottom margin to use */ public void setMarginBottom(int marginBottom) { this.marginBottom = marginBottom; } /** * Gets the left margin * * @return Returns the left margin */ public int getMarginLeft() { return marginLeft; } /** * Sets the left margin to use * * @param marginLeft The left margin to use */ public void setMarginLeft(int marginLeft) { this.marginLeft = marginLeft; } /** * Gets the right margin * * @return Returns the right margin */ public int getMarginRight() { return marginRight; } /** * Sets the right margin to use * * @param marginRight The right margin to use */ public void setMarginRight(int marginRight) { this.marginRight = marginRight; } /** * Gets the top margin * * @return Returns the top margin */ public int getMarginTop() { return marginTop; } /** * Sets the top margin to use * * @param marginTop The top margin to use */ public void setMarginTop(int marginTop) { this.marginTop = marginTop; } /** * Gets the page height * * @return Returns the page height */ public int getPageHeight() { return pageHeight; } /** * Sets the page height to use * * @param pageHeight The page height to use */ public void setPageHeight(int pageHeight) { this.pageHeight = pageHeight; } /** * Gets the page width * * @return Returns the page width */ public int getPageWidth() { return pageWidth; } /** * Sets the page width to use * * @param pageWidth The page width to use */ public void setPageWidth(int pageWidth) { this.pageWidth = pageWidth; } /** * Set the page size to use. This method will use guessFormat to try to guess the correct * page format. If no format could be guessed, the sizes from the pageSize are used and * the landscape setting is determined by comparing width and height; * * @param pageSize The pageSize to use */ public void setPageSize(Rectangle pageSize) { if(!guessFormat(pageSize, false)) { this.pageWidth = (int) (pageSize.getWidth() * RtfElement.TWIPS_FACTOR); this.pageHeight = (int) (pageSize.getHeight() * RtfElement.TWIPS_FACTOR); this.landscape = pageWidth > pageHeight; } } /** * This method tries to fit the Rectangle pageSize to one of the predefined PageSize rectangles. * If a match is found the pageWidth and pageHeight will be set according to values determined from files * generated by MS Word2000 and OpenOffice 641. If no match is found the method will try to match the rotated * Rectangle by calling itself with the parameter rotate set to true. * * @param pageSize the page size for which to guess the correct format * @param rotate Whether we should try to rotate the size befor guessing the format * @return True if the format was guessed, false/ otherwise */ private boolean guessFormat(Rectangle pageSize, boolean rotate) { if (rotate) { pageSize = pageSize.rotate(); } if (rectEquals(pageSize, PageSize.A3)) { pageWidth = 16837; pageHeight = 23811; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.A4)) { pageWidth = 11907; pageHeight = 16840; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.A5)) { pageWidth = 8391; pageHeight = 11907; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.A6)) { pageWidth = 5959; pageHeight = 8420; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.B4)) { pageWidth = 14570; pageHeight = 20636; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.B5)) { pageWidth = 10319; pageHeight = 14572; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.HALFLETTER)) { pageWidth = 7927; pageHeight = 12247; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.LETTER)) { pageWidth = 12242; pageHeight = 15842; landscape = rotate; return true; } if (rectEquals(pageSize, PageSize.LEGAL)) { pageWidth = 12252; pageHeight = 20163; landscape = rotate; return true; } if (!rotate && guessFormat(pageSize, true)) { int x = pageWidth; pageWidth = pageHeight; pageHeight = x; return true; } return false; } /** * This method compares to Rectangles. They are considered equal if width and height are the same * * @param rect1 The first Rectangle to compare * @param rect2 The second Rectangle to compare * @return True if the Rectangles equal, false otherwise */ private boolean rectEquals(Rectangle rect1, Rectangle rect2) { return (rect1.getWidth() == rect2.getWidth()) && (rect1.getHeight() == rect2.getHeight()); } } src/rtf/com/lowagie/text/rtf/document/RtfProtection.java100644 0 0 22363 11012562274 21064 0ustar 0 0 /* * $Id: RtfProtection.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2008 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; /** * RtfProtection *
       * See ECMA Specification for WordprocessingML documentProtection element.
       * 
       * Reference:
       * Standard ECMA-376 1st Edition / December 2006
       * Office Open XML File Formats
       * 
      * @since 2.1.1 * @author Howard Shank (hgshank@yahoo.com) */ public final class RtfProtection { /** * Default for protection level. * @since 2.1.1 */ static final public int LEVEL_NONE = 0x0000; /** * REVPROT * Mutually exclusive * This document is protected for revisions. The user can edit the document, * but revision marking cannot be disabled. * @since 2.1.1 */ static final public int LEVEL_REVPROT = 0x0001; // protlevel0 /** * ANNNOTPROT * Mutually exclusive * This document is protected for comments (annotations). * The user cannot edit the document but can insert comments (annotations). * @since 2.1.1 */ static final public int LEVEL_ANNOTPROT = 0x0002; // protlevel1 /** * FORMPROT * Mutually exclusive * Document is protected for forms. * see also \allprot (forms controlword) * @since 2.1.1 */ static final public int LEVEL_FORMPROT = 0x0004; // protlevel2 /** * READPROT * Mutually exclusive but can be combined with ANNOTPROT for backward compatibility * Document is protected for editing, except areas marked as exceptions by \protstart and\protend * @since 2.1.1 */ static final public int LEVEL_READPROT = 0x0008; // protlevel3 /** * STYLELOCK * * The document contains styles and formatting restrictions. * @since 2.1.1 */ static final public int STYLELOCK = 0x0001; /** * STYLELOCKENFORCED * * The styles and formatting restrictions are being enforced. * @since 2.1.1 */ static final public int STYLELOCKENFORCED = 0x0002; /** * STYLELOCKBACKCOMP * * Style lockdown backward compatibility flag, indicating we emitted protection * keywords to get documents with styles and formatting restrictions to behave * in a reasonable way when opened by older versions. * @since 2.1.1 */ static final public int STYLELOCKBACKCOMP = 0x0004; /** * STYLELOCKBACKCOMP * * Allow AutoFormat to override styles and formatting restrictions. When style * protection is on, the user cannot add direct formatting. This setting allows * AutoFormat actions to apply direct formatting when needed. * @since 2.1.1 */ static final public int AUTOFMTOVERRIDE = 0x0008; /** * initialCodeArray Table from ECMA-376 Specification * @since 2.1.1 */ static final private int initialCodeArray[] = { 0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, 0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, 0x4EC3 }; /** * encryptionMatrix Table from ECMA-376 Specification * @since 2.1.1 */ static final private int encryptionMatrix [][] = { /* bit1 bit2 bit3 bit4 bit5 bit6 bit7 **bit8 is ignored** */ /* char 1 */ {0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4}, /* char 2 */ {0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC}, /* char 3 */ {0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD}, /* char 4 */ {0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C}, /* char 5 */ {0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168}, /* char 6 */ {0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10}, /* char 7 */ {0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC}, /* char 8 */ {0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0}, /* char 9 */ {0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9}, /* char 10 */ {0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A}, /* char 11 */ {0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5}, /* char 12 */ {0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40}, /* char 13 */ {0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0}, /* char 14 */ {0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF}, /* char 15 */ {0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09} }; /** * generateHash generates the password hash from a clear text string. * * @param pwd Clear text string input * @return hex encoded password hash * * @since 2.1.1 */ static final public String generateHash(String pwd) { String encryptedPwd="00000000"; String password = pwd; // if there is no password or the length is 0, then skip this and return "00000000" as default // otherwise process the password if(password != null && password.length() > 0) { int hi=0; // hi order word int lo=0; // lo order word // Truncate the password to 15 characters. if(password.length() > 15) { password = password.substring(0,15); } // compute key's high-order word // initialize to table value hi = initialCodeArray[password.length()-1]; int idxF = 0; // forward index int idxR = password.length()-1; // reverse index // process each character left to right. // check each bit and if it is set, xor the hi word with // the table entry for the position in password and bit position. for(; idxF= 0; idxF--) { int ch = password.charAt(idxF); lo = (((lo >> 14) & 0x001) | (( lo << 1) & 0x7fff)) ^ ch; } // finally incorporate the password length into the low word and use value from formula lo = (((lo >> 14) & 0x001) | (( lo << 1) & 0x7fff)) ^ password.length() ^ 0xCE4B; // correct for little-endian - // Java always uses big-endian. According to tests - RTF wants little-endian but is not documented encryptedPwd = Integer.toHexString(lo).substring(2,4) + Integer.toHexString(lo).substring(0,2); encryptedPwd += Integer.toHexString(hi).substring(2,4) + Integer.toHexString(hi).substring(0,2); } return encryptedPwd; } } src/rtf/com/lowagie/text/rtf/document/RtfProtectionSetting.java100644 0 0 15032 11106243445 22415 0ustar 0 0 /* * $Id: RtfProtectionSetting.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2008 by Howard Shank * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; /** * The RtfProtectionSetting handles document protection elements * * @version $Id: RtfProtectionSetting.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.1 */ public class RtfProtectionSetting extends RtfElement { /** * Constant for Form protection controlword * Mutually exclusive * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT * @since 2.1.1 */ private static final byte[] FORMPROT = DocWriter.getISOBytes("\\formprot"); /** * Constant for Revision protection controlword * Mutually exclusive * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT * @since 2.1.1 */ private static final byte[] REVPROT = DocWriter.getISOBytes("\\revprot"); /** * Constant for Annotation/Comment protection controlword * Mutually exclusive * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT * @since 2.1.1 */ private static final byte[] ANNOTPROT = DocWriter.getISOBytes("\\annotprot"); /** * Constant for read only rotection controlword * Mutually exclusive - exception, can be combined with ANNOTPROT * for backwards compatibility * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT * @since 2.1.1 */ private static final byte[] READPROT = DocWriter.getISOBytes("\\readprot"); /** * Constant for protlevel controlword * @since 2.1.1 */ private static final byte[] PROTLEVEL = DocWriter.getISOBytes("\\protlevel"); /** * Constant for enforceprot controlword * @since 2.1.1 */ private static final byte[] ENFORCEPROT = DocWriter.getISOBytes("\\enforceprot"); /** * Constant for enforceprot controlword. * Implemented in Microsoft Word 2007. * * @since 2.1.1 */ private static final byte[] READONLYRECOMMENDED = DocWriter.getISOBytes("\\readonlyrecommended"); /** * Constructs a RtfProtectionSetting belonging to a RtfDocument * * @param doc The RtfDocument this RtfProtectionSetting belongs to * @since 2.1.1 */ public RtfProtectionSetting(RtfDocument doc) { super(doc); } /** * Writes the RTF protection control words * @since 2.1.1 */ public void writeContent(final OutputStream result) throws IOException { } /** * Writes the RTF protection control words * @since 2.1.1 */ public void writeDefinition(final OutputStream result) throws IOException { if(document.getDocumentSettings().isDocumentProtected()) { switch(document.getDocumentSettings().getProtectionLevelRaw()) { case RtfProtection.LEVEL_FORMPROT: result.write(FORMPROT); break; case RtfProtection.LEVEL_ANNOTPROT: result.write(ANNOTPROT); break; case RtfProtection.LEVEL_REVPROT: result.write(REVPROT); break; case RtfProtection.LEVEL_READPROT: result.write(ANNOTPROT); result.write(READPROT); break; } result.write(ENFORCEPROT); // assumes one of the above protection keywords was output. result.write((byte)'1'); result.write(PROTLEVEL); result.write(document.getDocumentSettings().getProtectionLevelBytes()); } if(document.getDocumentSettings().getReadOnlyRecommended()) { result.write(READONLYRECOMMENDED); result.write(DELIMITER); } } } src/rtf/com/lowagie/text/rtf/document/output/RtfByteArrayBuffer.java100644 0 0 20376 11036112747 23336 0ustar 0 0 /* * Copyright 2007 Thomas Bickel * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * A RtfByteArrayBuffer works much like {@link ByteArrayOutputStream} but is cheaper and faster in most cases * (exception: large writes when reusing buffers). * * @version $Id: RtfByteArrayBuffer.java 3433 2008-05-24 19:32:11Z xlv $ * @author Thomas Bickel (tmb99@inode.at) */ public final class RtfByteArrayBuffer extends OutputStream { private final java.util.List arrays = new java.util.ArrayList(); private byte[] buffer; private int pos = 0; private int size = 0; /** * Constructs a new buffer with a default initial size of 128 bytes. */ public RtfByteArrayBuffer() { this(256); } /** * Creates a new buffer with the given initial size. * * @param bufferSize desired initial size in bytes */ public RtfByteArrayBuffer(final int bufferSize) { if((bufferSize <= 0) || (bufferSize > 1<<30)) throw new IllegalArgumentException("bufferSize "+bufferSize); int n = 1<<5; while(n < bufferSize) { n <<= 1; } buffer = new byte[n]; } public String toString() { return("RtfByteArrayBuffer: size="+size()+" #arrays="+arrays.size()+" pos="+pos); } /** * Resets this buffer. */ public void reset() { arrays.clear(); pos = 0; size = 0; } /** * Returns the number of bytes that have been written to this buffer so far. * * @return number of bytes written to this buffer */ public long size() { return size; } private void flushBuffer() { flushBuffer(1); } private void flushBuffer(final int reqSize) { if(reqSize < 0) throw new IllegalArgumentException(); if(pos == 0) return; if(pos == buffer.length) { //add old buffer, alloc new (possibly larger) buffer arrays.add(buffer); int newSize = buffer.length; buffer = null; final int MAX = Math.max(1, size>>24) << 16; while(newSize < MAX) { newSize <<= 1; if(newSize >= reqSize) break; } buffer = new byte[newSize]; } else { //copy buffer contents to newly allocated buffer final byte[] c = new byte[pos]; System.arraycopy(buffer, 0, c, 0, pos); arrays.add(c); } pos = 0; } /** * Copies the given byte to the internal buffer. * * @param b */ public void write(final int b) { buffer[pos] = (byte)b; size++; if(++pos == buffer.length) flushBuffer(); } /** * Copies the given array to the internal buffer. * * @param src */ public void write(final byte[] src) { if(src == null) throw new NullPointerException(); if(src.length < buffer.length - pos) { System.arraycopy(src, 0, buffer, pos, src.length); pos += src.length; size += src.length; return; } writeLoop(src, 0, src.length); } /** * Copies len bytes starting at position off from the array src to the internal buffer. * * @param src * @param off * @param len */ public void write(final byte[] src, int off, int len) { if(src == null) throw new NullPointerException(); if((off < 0) || (off > src.length) || (len < 0) || ((off + len) > src.length) || ((off + len) < 0)) throw new IndexOutOfBoundsException(); writeLoop(src, off, len); } private void writeLoop(final byte[] src, int off, int len) { while(len > 0) { final int room = buffer.length - pos; final int n = len > room ? room : len; System.arraycopy(src, off, buffer, pos, n); len -= n; off += n; pos += n; size += n; if(pos == buffer.length) flushBuffer(len); } } /** * Writes all bytes available in the given inputstream to this buffer. * * @param in * @return number of bytes written * @throws IOException */ public long write(final InputStream in) throws IOException { if(in == null) throw new NullPointerException(); final long sizeStart = size; while(true) { final int n = in.read(buffer, pos, buffer.length - pos); if(n < 0) break; pos += n; size += n; if(pos == buffer.length) flushBuffer(); } return(size - sizeStart); } /** * Appends the given array to this buffer without copying (if possible). * * @param a */ public void append(final byte[] a) { if(a == null) throw new NullPointerException(); if(a.length == 0) return; if(a.length <= 8) { write(a, 0, a.length); } else if((a.length <= 16) && (pos > 0) && ((buffer.length - pos) > a.length)) { write(a, 0, a.length); } else { flushBuffer(); arrays.add(a); size += a.length; } } /** * Appends all arrays to this buffer without copying (if possible). * * @param a */ public void append(final byte[][] a) { if(a == null) throw new NullPointerException(); for(int k = 0; k < a.length; k++) { append(a[k]); } } /** * Returns the internal list of byte array buffers without copying the buffer contents. * * @return number of bytes written */ public byte[][] toByteArrayArray() { flushBuffer(); return(byte[][])arrays.toArray(new byte[arrays.size()][]); } /** * Allocates a new array and copies all data that has been written to this buffer to the newly allocated array. * * @return a new byte array */ public byte[] toByteArray() { final byte[] r = new byte[size]; int off = 0; final int n = arrays.size(); for(int k = 0; k < n; k++) { byte[] src = (byte[])arrays.get(k); System.arraycopy(src, 0, r, off, src.length); off += src.length; } if(pos > 0) System.arraycopy(buffer, 0, r, off, pos); return r; } /** * Writes all data that has been written to this buffer to the given output stream. * * @param out * @throws IOException */ public void writeTo(final OutputStream out) throws IOException { if(out == null) throw new NullPointerException(); final int n = arrays.size(); for(int k = 0; k < n; k++) { byte[] src = (byte[])arrays.get(k); out.write(src); } if(pos > 0) out.write(buffer, 0, pos); } } src/rtf/com/lowagie/text/rtf/document/output/RtfDataCache.java100644 0 0 7220 11012562274 22046 0ustar 0 0 /* * $Id: RtfDataCache.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.IOException; import java.io.OutputStream; /** * The RtfDataCache interface must be implemented by classes wishing to * act as caches for the rtf document data. * * @version $Id: RtfDataCache.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public interface RtfDataCache { /** * Constant for caching efficiently into memory. */ public static final int CACHE_MEMORY_EFFICIENT = 3; /** * Constant for caching into memory. */ public static final int CACHE_MEMORY = 2; /** * Constant for caching to the disk. */ public static final int CACHE_DISK = 1; /** * Get the OutputStream that the RtfDocument can write to. * * @return The OutputStream the RtfDocument can use. */ public OutputStream getOutputStream(); /** * Write the content of the cache into the OutputStream. * * @param target The OutputStream to write the content into. * @throws IOException If an error occurs reading/writing. */ public void writeTo(OutputStream target) throws IOException; } src/rtf/com/lowagie/text/rtf/document/output/RtfDiskCache.java100644 0 0 10321 11012562274 22103 0ustar 0 0 /* * $Id: RtfDiskCache.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; /** * The RtfFileCache is a RtfDataCache that uses a temporary file * to store the rtf document data. Not so fast, but doesn't use any * memory (just disk space). * * @version $Revision: 3373 $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) */ public class RtfDiskCache implements RtfDataCache { /** * The BufferedOutputStream that stores the cache data. */ private BufferedOutputStream data = null; /** * The temporary file to store the data in. */ private File tempFile = null; /** * Constructs a RtfFileCache. Creates the temp file. * * @throws IOException If the temporary file could not be created. */ public RtfDiskCache() throws IOException { this.tempFile = File.createTempFile("iText", null); this.data = new BufferedOutputStream(new FileOutputStream(tempFile)); } /** * Gets the BufferedOutputStream to write to. */ public OutputStream getOutputStream() { return this.data; } /** * Writes the content of the temporary file into the OutputStream. */ public void writeTo(OutputStream target) throws IOException { this.data.close(); BufferedInputStream tempIn = new BufferedInputStream(new FileInputStream(this.tempFile)); byte[] buffer = new byte[8192]; int bytesRead = -1; while((bytesRead = tempIn.read(buffer)) >= 0) { target.write(buffer, 0, bytesRead); } tempIn.close(); this.tempFile.delete(); } } src/rtf/com/lowagie/text/rtf/document/output/RtfEfficientMemoryCache.java100644 0 0 6577 11006315535 24277 0ustar 0 0 /* * Copyright 2007 by Thomas Bickel * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.IOException; import java.io.OutputStream; /** * The RtfEfficientMemoryCache is an RtfDataCache that keeps the whole rtf document * data in memory. * More efficient than {@link RtfMemoryCache}. * * @version $Id: RtfEfficientMemoryCache.java 3255 2008-04-14 18:33:30Z xlv $ * @author Thomas Bickel (tmb99@inode.at) */ public class RtfEfficientMemoryCache implements RtfDataCache { /** * The buffer for the rtf document data. */ private final RtfByteArrayBuffer bab; /** * Constructs a RtfMemoryCache. */ public RtfEfficientMemoryCache() { bab = new RtfByteArrayBuffer(); } /** * Gets the OutputStream. */ public OutputStream getOutputStream() { return bab; } /** * Writes the content of the buffer into the OutputStream. */ public void writeTo(OutputStream target) throws IOException { bab.writeTo(target); } } src/rtf/com/lowagie/text/rtf/document/output/RtfMemoryCache.java100644 0 0 6775 11012562274 22463 0ustar 0 0 /* * $Id: RtfMemoryCache.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; /** * The RtfMemoryCache is an RtfDataCache that keeps the whole rtf document * data in memory. Fast but memory intensive. * * @version $Id: RtfMemoryCache.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfMemoryCache implements RtfDataCache { /** * The buffer for the rtf document data. */ private ByteArrayOutputStream data = null; /** * Constructs a RtfMemoryCache. */ public RtfMemoryCache() { this.data = new ByteArrayOutputStream(); } /** * Gets the ByteArrayOutputStream. */ public OutputStream getOutputStream() { return this.data; } /** * Writes the content of the ByteArrayOutputStream into the OutputStream. */ public void writeTo(OutputStream target) throws IOException { this.data.writeTo(target); } } src/rtf/com/lowagie/text/rtf/document/output/RtfNilOutputStream.java100644 0 0 7677 11012562274 23410 0ustar 0 0 /* * Copyright 2007 Thomas Bickel * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.document.output; import java.io.OutputStream; /** * The RtfNilOutputStream is a dummy output stream that sends all * bytes to the big byte bucket in the sky. It is used to improve * speed in those situations where processing is required, but * the results are not needed. * * @version $Id: RtfNilOutputStream.java 3361 2008-05-11 12:28:57Z hallm $ * @author Thomas Bickel (tmb99@inode.at) * @author Mark Hall (Mark.Hall@mail.room3b.eu) */ public final class RtfNilOutputStream extends OutputStream { /** * The number of bytes theoretically written is stored. */ private long size = 0; /** * Constructs a new RtfNilOutputStream. */ public RtfNilOutputStream() { } /** * Gets the number of bytes that were written. * * @return The number of bytes that were written. */ public long getSize() { return size; } /** * Write an int. The size is incremented, but the actual data is thrown away. */ public void write(int b) { size++; } /** * Write a byte[]. The size is incremented, but the actual data is thrown away. */ public void write(byte[] b, int off, int len) { if (b == null) { throw new NullPointerException(); } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) { throw new IndexOutOfBoundsException(); } size += len; } }src/rtf/com/lowagie/text/rtf/field/RtfAnchor.java100644 0 0 11017 11106243445 17407 0ustar 0 0 /* * $Id: RtfAnchor.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Anchor; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.text.RtfPhrase; /** * The RtfAnchor is the RTF representation of an Anchor object. * * @version $Id: RtfAnchor.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Werner Daehn (Werner.Daehn@BusinessObjects.com) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfAnchor extends RtfField { /** * Constant for a hyperlink */ private static final byte[] HYPERLINK = DocWriter.getISOBytes("HYPERLINK"); /** * The url of this RtfAnchor */ private String url = ""; /** * The RtfPhrase to display for the url */ private RtfPhrase content = null; /** * Constructs a RtfAnchor based on a RtfField * * @param doc The RtfDocument this RtfAnchor belongs to * @param anchor The Anchor this RtfAnchor is based on */ public RtfAnchor(RtfDocument doc, Anchor anchor) { super(doc); this.url = anchor.getReference(); this.content = new RtfPhrase(doc, anchor); } /** * Write the field instructions for this RtfAnchor. Sets the field * type to HYPERLINK and then writes the url. * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldInstContent(OutputStream result) throws IOException { result.write(HYPERLINK); result.write(DELIMITER); this.document.filterSpecialChar(result, url, true, true); } /** * Write the field result for this RtfAnchor. Writes the content * of the RtfPhrase. * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldResultContent(OutputStream result) throws IOException { content.writeContent(result); } } src/rtf/com/lowagie/text/rtf/field/RtfField.java100644 0 0 32205 11106243445 17222 0ustar 0 0 /* * $Id: RtfField.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2004 by Mark Hall * Uses code Copyright 2002 * SMB * Dirk Weigenand (Dirk.Weigenand@smb-tec.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfFont; /** * The RtfField class is an abstract base class for all rtf field functionality. * Subclasses only need to implement the two abstract methods writeFieldInstContent * and writeFieldResultContent. All other field functionality is handled by the * RtfField class. * * @version $Id: RtfField.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Dirk Weigenand (Dirk.Weigenand@smb-tec.com) * @author Thomas Bickel (tmb99@inode.at) */ public abstract class RtfField extends Chunk implements RtfBasicElement { /** * Constant for a rtf field */ private static final byte[] FIELD = DocWriter.getISOBytes("\\field"); /** * Constant for a dirty field */ private static final byte[] FIELD_DIRTY = DocWriter.getISOBytes("\\flddirty"); /** * Constant for a private field */ private static final byte[] FIELD_PRIVATE = DocWriter.getISOBytes("\\fldpriv"); /** * Constant for a locked field */ private static final byte[] FIELD_LOCKED = DocWriter.getISOBytes("\\fldlock"); /** * Constant for a edited field */ private static final byte[] FIELD_EDIT = DocWriter.getISOBytes("\\fldedit"); /** * Constant for an alt field */ private static final byte[] FIELD_ALT = DocWriter.getISOBytes("\\fldalt"); /** * Constant for the field instructions */ private static final byte[] FIELD_INSTRUCTIONS = DocWriter.getISOBytes("\\*\\fldinst"); /** * Constant for the field result */ private static final byte[] FIELD_RESULT = DocWriter.getISOBytes("\\fldrslt"); /** * Is the field dirty */ private boolean fieldDirty = false; /** * Is the field edited */ private boolean fieldEdit = false; /** * Is the field locked */ private boolean fieldLocked = false; /** * Is the field private */ private boolean fieldPrivate = false; /** * Is it an alt field */ private boolean fieldAlt = false; /** * Whether this RtfField is in a table */ private boolean inTable = false; /** * Whether this RtfElement is in a header */ private boolean inHeader = false; /** * The RtfDocument this RtfField belongs to */ protected RtfDocument document = null; /** * The RtfFont of this RtfField */ private RtfFont font = null; /** * Constructs a RtfField for a RtfDocument. This is not very useful, * since the RtfField by itself does not do anything. Use one of the * subclasses instead. * * @param doc The RtfDocument this RtfField belongs to. */ protected RtfField(RtfDocument doc) { this(doc, new Font()); } /** * Constructs a RtfField for a RtfDocument. This is not very useful, * since the RtfField by itself does not do anything. Use one of the * subclasses instead. * * @param doc The RtfDocument this RtfField belongs to. * @param font The Font this RtfField should use */ protected RtfField(RtfDocument doc, Font font) { super("", font); this.document = doc; this.font = new RtfFont(this.document, font); } /** * Sets the RtfDocument this RtfElement belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; this.font.setRtfDocument(this.document); } /** * Writes the field beginning. Also writes field properties. * * @param result The OutputStream to write to. * @throws IOException */ private void writeFieldBegin(OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(FIELD); if(fieldDirty) result.write(FIELD_DIRTY); if(fieldEdit) result.write(FIELD_EDIT); if(fieldLocked) result.write(FIELD_LOCKED); if(fieldPrivate) result.write(FIELD_PRIVATE); } /** * Writes the beginning of the field instruction area. * * @param result The OutputStream to write to. * @throws IOException */ private void writeFieldInstBegin(OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(FIELD_INSTRUCTIONS); result.write(DELIMITER); } /** * Writes the content of the field instruction area. Override this * method in your subclasses. * * @param result The OutputStream to write to. */ protected abstract void writeFieldInstContent(OutputStream result) throws IOException; /** * Writes the end of the field instruction area. * * @param result The OutputStream to write to. */ private void writeFieldInstEnd(OutputStream result) throws IOException { if(fieldAlt) { result.write(DELIMITER); result.write(FIELD_ALT); } result.write(CLOSE_GROUP); } /** * Writes the beginning of the field result area * * @param result The OutputStream to write to. */ private void writeFieldResultBegin(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(FIELD_RESULT); result.write(DELIMITER); } /** * Writes the content of the pre-calculated field result. Override this * method in your subclasses. * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected abstract void writeFieldResultContent(OutputStream result) throws IOException; /** * Writes the end of the field result area * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ private void writeFieldResultEnd(final OutputStream result) throws IOException { result.write(DELIMITER); result.write(CLOSE_GROUP); } /** * Writes the end of the field * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ private void writeFieldEnd(OutputStream result) throws IOException { result.write(CLOSE_GROUP); } /** * Writes the field to the OutputStream. * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ public void writeContent(final OutputStream result) throws IOException { this.font.writeBegin(result); writeFieldBegin(result); writeFieldInstBegin(result); writeFieldInstContent(result); writeFieldInstEnd(result); writeFieldResultBegin(result); writeFieldResultContent(result); writeFieldResultEnd(result); writeFieldEnd(result); this.font.writeEnd(result); } /** * Get whether this field is an alt field * * @return Returns whether this field is an alt field */ public boolean isFieldAlt() { return fieldAlt; } /** * Set whether this field is an alt field * * @param fieldAlt The value to use */ public void setFieldAlt(boolean fieldAlt) { this.fieldAlt = fieldAlt; } /** * Get whether this field is dirty * * @return Returns whether this field is dirty */ public boolean isFieldDirty() { return fieldDirty; } /** * Set whether this field is dirty * * @param fieldDirty The value to use */ public void setFieldDirty(boolean fieldDirty) { this.fieldDirty = fieldDirty; } /** * Get whether this field is edited * * @return Returns whether this field is edited */ public boolean isFieldEdit() { return fieldEdit; } /** * Set whether this field is edited. * * @param fieldEdit The value to use */ public void setFieldEdit(boolean fieldEdit) { this.fieldEdit = fieldEdit; } /** * Get whether this field is locked * * @return Returns the fieldLocked. */ public boolean isFieldLocked() { return fieldLocked; } /** * Set whether this field is locked * @param fieldLocked The value to use */ public void setFieldLocked(boolean fieldLocked) { this.fieldLocked = fieldLocked; } /** * Get whether this field is private * * @return Returns the fieldPrivate. */ public boolean isFieldPrivate() { return fieldPrivate; } /** * Set whether this field is private * * @param fieldPrivate The value to use */ public void setFieldPrivate(boolean fieldPrivate) { this.fieldPrivate = fieldPrivate; } /** * Sets whether this RtfField is in a table * * @param inTable True if this RtfField is in a table, false otherwise */ public void setInTable(boolean inTable) { this.inTable = inTable; } /** * Gets whether this RtfField is in a table. * * @return True if this RtfField is in a table, false otherwise * @since 2.1.0 */ public boolean isInTable() { return this.inTable; } /** * Sets whether this RtfField is in a header * * @param inHeader True if this RtfField is in a header, false otherwise */ public void setInHeader(boolean inHeader) { this.inHeader = inHeader; } /** * Gets whether this RtfField is in a header. * * @return True if this RtfField is in a header, false otherwise * @since 2.1.0 */ public boolean isInHeader() { return this.inHeader; } /** * An RtfField is never empty. */ public boolean isEmpty() { return false; } /** * Override setFont to perform the correct font handling. */ public void setFont(Font font) { super.setFont(font); this.font = new RtfFont(this.document, font); } } src/rtf/com/lowagie/text/rtf/field/RtfPageNumber.java100644 0 0 11115 11106243445 20221 0ustar 0 0 /* * $Id: RtfPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfPageNumber provides the page number field in rtf documents. * * @version $Id: RtfPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfPageNumber extends RtfField { /** * Constant for the page number */ private static final byte[] PAGE_NUMBER = DocWriter.getISOBytes("PAGE"); /** * Constructs a RtfPageNumber. This can be added anywhere to add a page number field. */ public RtfPageNumber() { super(null); } /** * Constructs a RtfPageNumber with a specified Font. This can be added anywhere to * add a page number field. * @param font */ public RtfPageNumber(Font font) { super(null, font); } /** * Constructs a RtfPageNumber object. * * @param doc The RtfDocument this RtfPageNumber belongs to */ public RtfPageNumber(RtfDocument doc) { super(doc); } /** * Constructs a RtfPageNumber object with a specific font. * * @param doc The RtfDocument this RtfPageNumber belongs to * @param font The Font to use */ public RtfPageNumber(RtfDocument doc, Font font) { super(doc, font); } /** * Writes the field instruction content * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldInstContent(final OutputStream result) throws IOException { result.write(PAGE_NUMBER); } /** * Writes the field result content * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldResultContent(final OutputStream result) throws IOException { } } src/rtf/com/lowagie/text/rtf/field/RtfTOCEntry.java100644 0 0 12675 11106243445 17657 0ustar 0 0 /* * $Id: RtfTOCEntry.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2004 by Mark Hall * Uses code Copyright 2002 * Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; /** * The RtfTOCEntry is used together with the RtfTableOfContents to generate a table of * contents. Add the RtfTOCEntry in those locations in the document where table of * contents entries should link to * * @version $Id: RtfTOCEntry.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTOCEntry extends RtfField { /** * Constant for the beginning of hidden text */ private static final byte[] TEXT_HIDDEN_ON = DocWriter.getISOBytes("\\v"); /** * Constant for the end of hidden text */ private static final byte[] TEXT_HIDDEN_OFF = DocWriter.getISOBytes("\\v0"); /** * Constant for a TOC entry with page numbers */ private static final byte[] TOC_ENTRY_PAGE_NUMBER = DocWriter.getISOBytes("\\tc"); /** * Constant for a TOC entry without page numbers */ private static final byte[] TOC_ENTRY_NO_PAGE_NUMBER = DocWriter.getISOBytes("\\tcn"); /** * The entry text of this RtfTOCEntry */ private String entry = ""; /** * Whether to show page numbers in the table of contents */ private boolean showPageNumber = true; /** * Constructs a RtfTOCEntry with a certain entry text. * * @param entry The entry text to display */ public RtfTOCEntry(String entry) { super(null, new Font()); if(entry != null) { this.entry = entry; } } /** * Writes the content of the RtfTOCEntry. * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ public void writeContent(final OutputStream result) throws IOException { result.write(TEXT_HIDDEN_ON); result.write(OPEN_GROUP); if(this.showPageNumber) { result.write(TOC_ENTRY_PAGE_NUMBER); } else { result.write(TOC_ENTRY_NO_PAGE_NUMBER); } result.write(DELIMITER); this.document.filterSpecialChar(result, this.entry, true, false); result.write(CLOSE_GROUP); result.write(TEXT_HIDDEN_OFF); } /** * Sets whether to display a page number in the table of contents, or not * * @param showPageNumber Whether to display a page number or not */ public void setShowPageNumber(boolean showPageNumber) { this.showPageNumber = showPageNumber; } /** * unused */ protected void writeFieldInstContent(OutputStream out) throws IOException { } /** * unused */ protected void writeFieldResultContent(OutputStream out) throws IOException { } } src/rtf/com/lowagie/text/rtf/field/RtfTableOfContents.java100644 0 0 10751 11106243445 21233 0ustar 0 0 /* * $Id: RtfTableOfContents.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2004 by Mark Hall * Uses code Copyright 2002 * Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; /** * The RtfTableOfContents together with multiple RtfTOCEntry objects generates a table * of contents. The table of contents will display no entries in the viewing program * and the user will have to update it first. A text to inform the user of this is * displayed instead. * * @version $Id: RtfTableOfContents.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTableOfContents extends RtfField { /** * field inst content */ private final static String FIELD_INST = "TOC \\\\f \\\\h \\\\u \\\\o \"1-5\" "; /** * The default text to display */ private String defaultText = "Table of Contents - Click to update"; /** * Constructs a RtfTableOfContents. The default text is the text that is displayed * before the user updates the table of contents * * @param defaultText The default text to display */ public RtfTableOfContents(String defaultText) { super(null, new Font()); this.defaultText = defaultText; } /** * Writes the field instruction content * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldInstContent(final OutputStream result) throws IOException { result.write(DocWriter.getISOBytes(FIELD_INST)); } /** * Writes the field result content * * @param out The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldResultContent(final OutputStream out) throws IOException { document.filterSpecialChar(out, defaultText, true, true); } } src/rtf/com/lowagie/text/rtf/field/RtfTotalPageNumber.java100644 0 0 11553 11106243445 21233 0ustar 0 0 /* * $Id: RtfTotalPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2005 Jose Hurtado jose.hurtado@gft.com * Parts Copyright 2005 Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.field; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfTotalPageNumber provides the total number of pages field in rtf documents. * * @version $Id: RtfTotalPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Jose Hurtado (jose.hurtado@gft.com) * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTotalPageNumber extends RtfField { /** * Constant for arabic total page numbers. */ private static final byte[] ARABIC_TOTAL_PAGES = DocWriter.getISOBytes("NUMPAGES \\\\* Arabic"); /** * Constructs a RtfTotalPageNumber. This can be added anywhere to add a total number of pages field. */ public RtfTotalPageNumber() { super(null); } /** * Constructs a RtfTotalPageNumber with a specified Font. This can be added anywhere * to add a total number of pages field. * @param font */ public RtfTotalPageNumber(Font font) { super(null, font); } /** * Constructs a RtfTotalPageNumber object. * * @param doc The RtfDocument this RtfTotalPageNumber belongs to */ public RtfTotalPageNumber(RtfDocument doc) { super(doc); } /** * Constructs a RtfTotalPageNumber object with a specific font. * * @param doc The RtfDocument this RtfTotalPageNumber belongs to * @param font The Font to use */ public RtfTotalPageNumber(RtfDocument doc, Font font) { super(doc, font); } /** * Writes the field NUMPAGES instruction with Arabic format: "NUMPAGES \\\\* Arabic". * * @param result The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldInstContent(OutputStream result) throws IOException { result.write(ARABIC_TOTAL_PAGES); } /** * Writes the field result content "1". * * @param out The OutputStream to write to. * @throws IOException on i/o errors. */ protected void writeFieldResultContent(final OutputStream out) throws IOException { out.write(DocWriter.getISOBytes("1")); } } src/rtf/com/lowagie/text/rtf/graphic/RtfImage.java100644 0 0 33763 11106243445 17565 0ustar 0 0 /* * $Id: RtfImage.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.graphic; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Image; import com.lowagie.text.pdf.codec.wmf.MetaDo; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.document.output.RtfByteArrayBuffer; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp. * * @version $Id: RtfImage.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Paulo Soares * @author Thomas Bickel (tmb99@inode.at) */ public class RtfImage extends RtfElement { /** * Constant for the shape/picture group */ private static final byte[] PICTURE_GROUP = DocWriter.getISOBytes("\\*\\shppict"); /** * Constant for a picture */ private static final byte[] PICTURE = DocWriter.getISOBytes("\\pict"); /** * Constant for a jpeg image */ private static final byte[] PICTURE_JPEG = DocWriter.getISOBytes("\\jpegblip"); /** * Constant for a png image */ private static final byte[] PICTURE_PNG = DocWriter.getISOBytes("\\pngblip"); /** * Constant for a wmf image */ private static final byte[] PICTURE_WMF = DocWriter.getISOBytes("\\wmetafile8"); /** * Constant for the picture width */ private static final byte[] PICTURE_WIDTH = DocWriter.getISOBytes("\\picw"); /** * Constant for the picture height */ private static final byte[] PICTURE_HEIGHT = DocWriter.getISOBytes("\\pich"); /** * Constant for the picture width scale */ private static final byte[] PICTURE_SCALED_WIDTH = DocWriter.getISOBytes("\\picwgoal"); /** * Constant for the picture height scale */ private static final byte[] PICTURE_SCALED_HEIGHT = DocWriter.getISOBytes("\\pichgoal"); /** * Constant for horizontal picture scaling */ private static final byte[] PICTURE_SCALE_X = DocWriter.getISOBytes("\\picscalex"); /** * Constant for vertical picture scaling */ private static final byte[] PICTURE_SCALE_Y = DocWriter.getISOBytes("\\picscaley"); /** * "\bin" constant */ private static final byte[] PICTURE_BINARY_DATA = DocWriter.getISOBytes("\\bin"); /** * Constant for converting pixels to twips */ private static final int PIXEL_TWIPS_FACTOR = 15; /** * The type of image this is. */ private final int imageType; /** * Binary image data. */ private final byte[][] imageData; /** * The alignment of this picture */ private int alignment = Element.ALIGN_LEFT; /** * The width of this picture */ private float width = 0; /** * The height of this picture */ private float height = 0; /** * The intended display width of this picture */ private float plainWidth = 0; /** * The intended display height of this picture */ private float plainHeight = 0; /** * Whether this RtfImage is a top level element and should * be an extra paragraph. */ private boolean topLevelElement = false; /** * Constructs a RtfImage for an Image. * * @param doc The RtfDocument this RtfImage belongs to * @param image The Image that this RtfImage wraps * @throws DocumentException If an error occurred accessing the image content */ public RtfImage(RtfDocument doc, Image image) throws DocumentException { super(doc); imageType = image.getOriginalType(); if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) { throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer"); } alignment = image.getAlignment(); width = image.getWidth(); height = image.getHeight(); plainWidth = image.getPlainWidth(); plainHeight = image.getPlainHeight(); this.imageData = getImageData(image); } /** * Extracts the image data from the Image. * * @param image The image for which to extract the content * @return The raw image data, not formated * @throws DocumentException If an error occurs accessing the image content */ private byte[][] getImageData(Image image) throws DocumentException { final int WMF_PLACEABLE_HEADER_SIZE = 22; final RtfByteArrayBuffer bab = new RtfByteArrayBuffer(); try { if(imageType == Image.ORIGINAL_BMP) { bab.append(MetaDo.wrapBMP(image)); } else { final byte[] iod = image.getOriginalData(); if(iod == null) { final InputStream imageIn = image.getUrl().openStream(); if(imageType == Image.ORIGINAL_WMF) { //remove the placeable header first for(int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) { if(imageIn.read() < 0) throw new EOFException("while removing wmf placeable header"); } } bab.write(imageIn); imageIn.close(); } else { if(imageType == Image.ORIGINAL_WMF) { //remove the placeable header bab.write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.length - WMF_PLACEABLE_HEADER_SIZE); } else { bab.append(iod); } } } return bab.toByteArrayArray(); } catch(IOException ioe) { throw new DocumentException(ioe.getMessage()); } } /** * lookup table used for converting bytes to hex chars. * TODO Should probably be refactored into a helper class */ public final static byte[] byte2charLUT = new byte[512]; //'0001020304050607 ... fafbfcfdfeff' static { char c = '0'; for(int k = 0; k < 16; k++) { for(int x = 0; x < 16; x++) { byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c; } if(++c == ':') c = 'a'; } } /** * Writes the image data to the given buffer as hex encoded text. * * @param bab * @throws IOException */ private void writeImageDataHexEncoded(final OutputStream bab) throws IOException { int cnt = 0; for(int k = 0; k < imageData.length; k++) { final byte[] chunk = imageData[k]; for(int x = 0; x < chunk.length; x++) { bab.write(byte2charLUT, (chunk[x]&0xff)*2, 2); if(++cnt == 64) { bab.write('\n'); cnt = 0; } } } if(cnt > 0) bab.write('\n'); } /** * Returns the image raw data size in bytes. * * @return the size in bytes */ private int imageDataSize() { int size = 0; for(int k = 0; k < imageData.length; k++) { size += imageData[k].length; } return size; } /** * Writes the RtfImage content */ public void writeContent(final OutputStream result) throws IOException { if(this.topLevelElement) { result.write(RtfParagraph.PARAGRAPH_DEFAULTS); switch(alignment) { case Element.ALIGN_LEFT: result.write(RtfParagraphStyle.ALIGN_LEFT); break; case Element.ALIGN_RIGHT: result.write(RtfParagraphStyle.ALIGN_RIGHT); break; case Element.ALIGN_CENTER: result.write(RtfParagraphStyle.ALIGN_CENTER); break; case Element.ALIGN_JUSTIFIED: result.write(RtfParagraphStyle.ALIGN_JUSTIFY); break; } } result.write(OPEN_GROUP); result.write(PICTURE_GROUP); result.write(OPEN_GROUP); result.write(PICTURE); switch(imageType) { case Image.ORIGINAL_JPEG: result.write(PICTURE_JPEG); break; case Image.ORIGINAL_PNG: case Image.ORIGINAL_GIF: result.write(PICTURE_PNG); break; case Image.ORIGINAL_WMF: case Image.ORIGINAL_BMP: result.write(PICTURE_WMF); break; } result.write(PICTURE_WIDTH); result.write(intToByteArray((int) width)); result.write(PICTURE_HEIGHT); result.write(intToByteArray((int) height)); if(this.document.getDocumentSettings().isWriteImageScalingInformation()) { result.write(PICTURE_SCALE_X); result.write(intToByteArray((int)(100 * plainWidth / width))); result.write(PICTURE_SCALE_Y); result.write(intToByteArray((int)(100 * plainHeight / height))); } if(this.document.getDocumentSettings().isImagePDFConformance()) { result.write(PICTURE_SCALED_WIDTH); result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR))); result.write(PICTURE_SCALED_HEIGHT); result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR))); } else { if(this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) { result.write(PICTURE_SCALED_WIDTH); result.write(intToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR))); } if(this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) { result.write(PICTURE_SCALED_HEIGHT); result.write(intToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR))); } } if(this.document.getDocumentSettings().isImageWrittenAsBinary()) { //binary result.write('\n'); result.write(PICTURE_BINARY_DATA); result.write(intToByteArray(imageDataSize())); result.write(DELIMITER); if(result instanceof RtfByteArrayBuffer) { ((RtfByteArrayBuffer)result).append(imageData); } else { for(int k = 0; k < imageData.length; k++) { result.write(imageData[k]); } } } else { //hex encoded result.write(DELIMITER); result.write('\n'); writeImageDataHexEncoded(result); } result.write(CLOSE_GROUP); result.write(CLOSE_GROUP); if(this.topLevelElement) { result.write(RtfParagraph.PARAGRAPH); result.write(RtfParagraph.PARAGRAPH); } result.write('\n'); } /** * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element. * * @param alignment The alignment to use. */ public void setAlignment(int alignment) { this.alignment = alignment; } /** * Set whether this RtfImage should behave like a top level element * and enclose itself in a paragraph. * * @param topLevelElement Whether to behave like a top level element. */ public void setTopLevelElement(boolean topLevelElement) { this.topLevelElement = topLevelElement; } } src/rtf/com/lowagie/text/rtf/graphic/RtfShape.java100644 0 0 23271 11106243445 17574 0ustar 0 0 package com.lowagie.text.rtf.graphic; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfAddableElement; /** * The RtfShape provides the interface for adding shapes to * the RTF document. This will only work for Word 97+, older * Word versions are not supported by this class.

      * * Only very simple shapes are directly supported by the RtfShape. * For more complex shapes you will have to read the RTF * specification (iText follows the 1.6 specification) and add * the desired properties via the RtfShapeProperty.

      * * One thing to keep in mind is that distances are not expressed * in the standard iText point, but in EMU where 1 inch = 914400 EMU * or 1 cm = 360000 EMU. * * @version $Id: RtfShape.java 3591 2008-08-27 17:19:27Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfShape extends RtfAddableElement { /** * Constant for a Picture Frame. */ public static final int SHAPE_PICTURE_FRAME = 75; /** * Constant for a free form shape. The shape verticies must * be specified with an array of Point objects in a * RtfShapeProperty with the name PROPERTY_VERTICIES. */ public static final int SHAPE_FREEFORM = 0; /** * Constant for a rectangle. */ public static final int SHAPE_RECTANGLE = 1; /** * Constant for a rounded rectangle. The roundness is * set via a RtfShapeProperty with the name PROPERTY_ADJUST_VALUE. */ public static final int SHAPE_ROUND_RECTANGLE = 2; /** * Constant for an ellipse. Use this to create circles. */ public static final int SHAPE_ELLIPSE = 3; /** * Constant for a diamond. */ public static final int SHAPE_DIAMOND = 4; /** * Constant for a isosceles triangle. */ public static final int SHAPE_TRIANGLE_ISOSCELES = 5; /** * Constant for a right triangle. */ public static final int SHAPE_TRIANGLE_RIGHT = 6; /** * Constant for a parallelogram. */ public static final int SHAPE_PARALLELOGRAM = 7; /** * Constant for a trapezoid. */ public static final int SHAPE_TRAPEZOID = 8; /** * Constant for a hexagon. */ public static final int SHAPE_HEXAGON = 9; /** * Constant for an ocatagon. */ public static final int SHAPE_OCTAGON = 10; /** * Constant for a star. */ public static final int SHAPE_STAR = 12; /** * Constant for an arrow. */ public static final int SHAPE_ARROW = 13; /** * Constant for a thick arrow. */ public static final int SHAPE_ARROR_THICK = 14; /** * Constant for a home plate style shape. */ public static final int SHAPE_HOME_PLATE = 15; /** * Constant for a cube shape. */ public static final int SHAPE_CUBE = 16; /** * Constant for a balloon shape. */ public static final int SHAPE_BALLOON = 17; /** * Constant for a seal shape. */ public static final int SHAPE_SEAL = 18; /** * Constant for an arc shape. */ public static final int SHAPE_ARC = 19; /** * Constant for a line shape. */ public static final int SHAPE_LINE = 20; /** * Constant for a can shape. */ public static final int SHAPE_CAN = 22; /** * Constant for a donut shape. */ public static final int SHAPE_DONUT = 23; /** * Text is not wrapped around the shape. */ public static final int SHAPE_WRAP_NONE = 0; /** * Text is wrapped to the top and bottom. */ public static final int SHAPE_WRAP_TOP_BOTTOM = 1; /** * Text is wrapped on the left and right side. */ public static final int SHAPE_WRAP_BOTH = 2; /** * Text is wrapped on the left side. */ public static final int SHAPE_WRAP_LEFT = 3; /** * Text is wrapped on the right side. */ public static final int SHAPE_WRAP_RIGHT = 4; /** * Text is wrapped on the largest side. */ public static final int SHAPE_WRAP_LARGEST = 5; /** * Text is tightly wrapped on the left and right side. */ public static final int SHAPE_WRAP_TIGHT_BOTH = 6; /** * Text is tightly wrapped on the left side. */ public static final int SHAPE_WRAP_TIGHT_LEFT = 7; /** * Text is tightly wrapped on the right side. */ public static final int SHAPE_WRAP_TIGHT_RIGHT = 8; /** * Text is tightly wrapped on the largest side. */ public static final int SHAPE_WRAP_TIGHT_LARGEST = 9; /** * Text is wrapped through the shape. */ public static final int SHAPE_WRAP_THROUGH = 10; /** * The shape nr is a random unique id. */ private int shapeNr = 0; /** * The shape type. */ private int type = 0; /** * The RtfShapePosition that defines position settings for this RtfShape. */ private RtfShapePosition position = null; /** * A HashMap with RtfShapePropertys that define further shape properties. */ private HashMap properties = null; /** * The wrapping mode. Defaults to SHAPE_WRAP_NONE; */ private int wrapping = SHAPE_WRAP_NONE; /** * Text that is contained in the shape. */ private String shapeText = ""; /** * Constructs a new RtfShape of a given shape at the given RtfShapePosition. * * @param type The type of shape to create. * @param position The RtfShapePosition to create this RtfShape at. */ public RtfShape(int type, RtfShapePosition position) { this.type = type; this.position = position; this.properties = new HashMap(); } /** * Sets a property. * * @param property The property to set for this RtfShape. */ public void setProperty(RtfShapeProperty property) { property.setRtfDocument(this.doc); this.properties.put(property.getName(), property); } /** * Sets the text to display in this RtfShape. * * @param shapeText The text to display. */ public void setShapeText(String shapeText) { this.shapeText = shapeText; } /** * Set the wrapping mode. * * @param wrapping The wrapping mode to use for this RtfShape. */ public void setWrapping(int wrapping) { this.wrapping = wrapping; } /** * Writes the RtfShape. Some settings are automatically translated into * or require other properties and these are set first. */ public void writeContent(final OutputStream result) throws IOException { this.shapeNr = this.doc.getRandomInt(); this.properties.put("ShapeType", new RtfShapeProperty("ShapeType", this.type)); if(this.position.isShapeBelowText()) { this.properties.put("fBehindDocument", new RtfShapeProperty("fBehindDocument", true)); } if(this.inTable) { this.properties.put("fLayoutInCell", new RtfShapeProperty("fLayoutInCell", true)); } if(this.properties.containsKey("posh")) { this.position.setIgnoreXRelative(true); } if(this.properties.containsKey("posv")) { this.position.setIgnoreYRelative(true); } result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\shp")); result.write(DocWriter.getISOBytes("\\shplid")); result.write(intToByteArray(this.shapeNr)); this.position.writeContent(result); switch(this.wrapping) { case SHAPE_WRAP_NONE: result.write(DocWriter.getISOBytes("\\shpwr3")); break; case SHAPE_WRAP_TOP_BOTTOM: result.write(DocWriter.getISOBytes("\\shpwr1")); break; case SHAPE_WRAP_BOTH: result.write(DocWriter.getISOBytes("\\shpwr2")); result.write(DocWriter.getISOBytes("\\shpwrk0")); break; case SHAPE_WRAP_LEFT: result.write(DocWriter.getISOBytes("\\shpwr2")); result.write(DocWriter.getISOBytes("\\shpwrk1")); break; case SHAPE_WRAP_RIGHT: result.write(DocWriter.getISOBytes("\\shpwr2")); result.write(DocWriter.getISOBytes("\\shpwrk2")); break; case SHAPE_WRAP_LARGEST: result.write(DocWriter.getISOBytes("\\shpwr2")); result.write(DocWriter.getISOBytes("\\shpwrk3")); break; case SHAPE_WRAP_TIGHT_BOTH: result.write(DocWriter.getISOBytes("\\shpwr4")); result.write(DocWriter.getISOBytes("\\shpwrk0")); break; case SHAPE_WRAP_TIGHT_LEFT: result.write(DocWriter.getISOBytes("\\shpwr4")); result.write(DocWriter.getISOBytes("\\shpwrk1")); break; case SHAPE_WRAP_TIGHT_RIGHT: result.write(DocWriter.getISOBytes("\\shpwr4")); result.write(DocWriter.getISOBytes("\\shpwrk2")); break; case SHAPE_WRAP_TIGHT_LARGEST: result.write(DocWriter.getISOBytes("\\shpwr4")); result.write(DocWriter.getISOBytes("\\shpwrk3")); break; case SHAPE_WRAP_THROUGH: result.write(DocWriter.getISOBytes("\\shpwr5")); break; default: result.write(DocWriter.getISOBytes("\\shpwr3")); } if(this.inHeader) { result.write(DocWriter.getISOBytes("\\shpfhdr1")); } this.doc.outputDebugLinebreak(result); result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\*\\shpinst")); Iterator it = this.properties.values().iterator(); while(it.hasNext()) { RtfShapeProperty rsp = (RtfShapeProperty) it.next(); rsp.setRtfDocument(this.doc); rsp.writeContent(result); } if(!this.shapeText.equals("")) { result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\shptxt")); result.write(DELIMITER); result.write(DocWriter.getISOBytes(this.shapeText)); result.write(CLOSE_GROUP); } result.write(CLOSE_GROUP); this.doc.outputDebugLinebreak(result); result.write(CLOSE_GROUP); } } src/rtf/com/lowagie/text/rtf/graphic/RtfShapePosition.java100644 0 0 14252 11106243445 21320 0ustar 0 0 package com.lowagie.text.rtf.graphic; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfAddableElement; /** * The RtfShapePosition stores position and ordering * information for one RtfShape. * * @version $Id: RtfShapePosition.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfShapePosition extends RtfAddableElement { /** * Constant for horizontal positioning relative to the page. */ public static final int POSITION_X_RELATIVE_PAGE = 0; /** * Constant for horizontal positioning relative to the margin. */ public static final int POSITION_X_RELATIVE_MARGIN = 1; /** * Constant for horizontal positioning relative to the column. */ public static final int POSITION_X_RELATIVE_COLUMN = 2; /** * Constant for vertical positioning relative to the page. */ public static final int POSITION_Y_RELATIVE_PAGE = 0; /** * Constant for vertical positioning relative to the margin. */ public static final int POSITION_Y_RELATIVE_MARGIN = 1; /** * Constant for vertical positioning relative to the paragraph. */ public static final int POSITION_Y_RELATIVE_PARAGRAPH = 2; /** * The top coordinate of this RtfShapePosition. */ private int top = 0; /** * The left coordinate of this RtfShapePosition. */ private int left = 0; /** * The right coordinate of this RtfShapePosition. */ private int right = 0; /** * The bottom coordinate of this RtfShapePosition. */ private int bottom = 0; /** * The z order of this RtfShapePosition. */ private int zOrder = 0; /** * The horizontal relative position. */ private int xRelativePos = POSITION_X_RELATIVE_PAGE; /** * The vertical relative position. */ private int yRelativePos = POSITION_Y_RELATIVE_PAGE; /** * Whether to ignore the horizontal relative position. */ private boolean ignoreXRelative = false; /** * Whether to ignore the vertical relative position. */ private boolean ignoreYRelative = false; /** * Whether the shape is below the text. */ private boolean shapeBelowText = false; /** * Constructs a new RtfShapePosition with the four bounding coordinates. * * @param top The top coordinate. * @param left The left coordinate. * @param right The right coordinate. * @param bottom The bottom coordinate. */ public RtfShapePosition(int top, int left, int right, int bottom) { this.top = top; this.left = left; this.right = right; this.bottom = bottom; } /** * Gets whether the shape is below the text. * * @return True if the shape is below, false if the text is below. */ public boolean isShapeBelowText() { return shapeBelowText; } /** * Sets whether the shape is below the text. * * @param shapeBelowText True if the shape is below, false if the text is below. */ public void setShapeBelowText(boolean shapeBelowText) { this.shapeBelowText = shapeBelowText; } /** * Sets the relative horizontal position. Use one of the constants * provided in this class. * * @param relativePos The relative horizontal position to use. */ public void setXRelativePos(int relativePos) { xRelativePos = relativePos; } /** * Sets the relative vertical position. Use one of the constants * provides in this class. * * @param relativePos The relative vertical position to use. */ public void setYRelativePos(int relativePos) { yRelativePos = relativePos; } /** * Sets the z order to use. * * @param order The z order to use. */ public void setZOrder(int order) { zOrder = order; } /** * Set whether to ignore the horizontal relative position. * * @param ignoreXRelative True to ignore the horizontal relative position, false otherwise. */ protected void setIgnoreXRelative(boolean ignoreXRelative) { this.ignoreXRelative = ignoreXRelative; } /** * Set whether to ignore the vertical relative position. * * @param ignoreYRelative True to ignore the vertical relative position, false otherwise. */ protected void setIgnoreYRelative(boolean ignoreYRelative) { this.ignoreYRelative = ignoreYRelative; } /** * Write this RtfShapePosition. */ public void writeContent(final OutputStream result) throws IOException { result.write(DocWriter.getISOBytes("\\shpleft")); result.write(intToByteArray(this.left)); result.write(DocWriter.getISOBytes("\\shptop")); result.write(intToByteArray(this.top)); result.write(DocWriter.getISOBytes("\\shpright")); result.write(intToByteArray(this.right)); result.write(DocWriter.getISOBytes("\\shpbottom")); result.write(intToByteArray(this.bottom)); result.write(DocWriter.getISOBytes("\\shpz")); result.write(intToByteArray(this.zOrder)); switch(this.xRelativePos) { case POSITION_X_RELATIVE_PAGE: result.write(DocWriter.getISOBytes("\\shpbxpage")); break; case POSITION_X_RELATIVE_MARGIN: result.write(DocWriter.getISOBytes("\\shpbxmargin")); break; case POSITION_X_RELATIVE_COLUMN: result.write(DocWriter.getISOBytes("\\shpbxcolumn")); break; } if(this.ignoreXRelative) { result.write(DocWriter.getISOBytes("\\shpbxignore")); } switch(this.yRelativePos) { case POSITION_Y_RELATIVE_PAGE: result.write(DocWriter.getISOBytes("\\shpbypage")); break; case POSITION_Y_RELATIVE_MARGIN: result.write(DocWriter.getISOBytes("\\shpbymargin")); break; case POSITION_Y_RELATIVE_PARAGRAPH: result.write(DocWriter.getISOBytes("\\shpbypara")); break; } if(this.ignoreYRelative) { result.write(DocWriter.getISOBytes("\\shpbyignore")); } if(this.shapeBelowText) { result.write(DocWriter.getISOBytes("\\shpfblwtxt1")); } else { result.write(DocWriter.getISOBytes("\\shpfblwtxt0")); } } } src/rtf/com/lowagie/text/rtf/graphic/RtfShapeProperty.java100644 0 0 23130 11106243445 21333 0ustar 0 0 package com.lowagie.text.rtf.graphic; import java.awt.Color; import java.awt.Point; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.ExceptionConverter; import com.lowagie.text.Image; import com.lowagie.text.rtf.RtfAddableElement; /** * The RtfShapeProperty stores all shape properties that are * not handled by the RtfShape and RtfShapePosition.

      * * There is a huge selection of properties that can be set. For * the most important properites there are constants for the * property name, for all others you must find the correct * property name in the RTF specification (version 1.6).

      * * The following types of property values are supported: *
        *
      • long
      • *
      • double
      • *
      • boolean
      • *
      • Color
      • *
      • int[]
      • *
      • Point[]
      • *
      * * @version $Id: RtfShapeProperty.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfShapeProperty extends RtfAddableElement { /** * Property for defining an image. */ public static final String PROPERTY_IMAGE = "pib"; /** * Property for defining vertices in freeform shapes. Requires a * Point array as the value. */ public static final String PROPERTY_VERTICIES = "pVerticies"; /** * Property for defining the minimum vertical coordinate that is * visible. Requires a long value. */ public static final String PROPERTY_GEO_TOP = "geoTop"; /** * Property for defining the minimum horizontal coordinate that is * visible. Requires a long value. */ public static final String PROPERTY_GEO_LEFT = "geoLeft"; /** * Property for defining the maximum horizontal coordinate that is * visible. Requires a long value. */ public static final String PROPERTY_GEO_RIGHT = "geoRight"; /** * Property for defining the maximum vertical coordinate that is * visible. Requires a long value. */ public static final String PROPERTY_GEO_BOTTOM = "geoBottom"; /** * Property for defining that the shape is in a table cell. Requires * a boolean value. */ public static final String PROPERTY_LAYOUT_IN_CELL = "fLayoutInCell"; /** * Property for signaling a vertical flip of the shape. Requires a * boolean value. */ public static final String PROPERTY_FLIP_V = "fFlipV"; /** * Property for signaling a horizontal flip of the shape. Requires a * boolean value. */ public static final String PROPERTY_FLIP_H = "fFlipH"; /** * Property for defining the fill color of the shape. Requires a * Color value. */ public static final String PROPERTY_FILL_COLOR = "fillColor"; /** * Property for defining the line color of the shape. Requires a * Color value. */ public static final String PROPERTY_LINE_COLOR = "lineColor"; /** * Property for defining the first adjust handle for shapes. Used * with the rounded rectangle. Requires a long value. */ public static final String PROPERTY_ADJUST_VALUE = "adjustValue"; /** * The stored value is a long. */ private static final int PROPERTY_TYPE_LONG = 1; /** * The stored value is boolean. */ private static final int PROPERTY_TYPE_BOOLEAN = 2; /** * The stored value is a double. */ private static final int PROPERTY_TYPE_DOUBLE = 3; /** * The stored value is a Color. */ private static final int PROPERTY_TYPE_COLOR = 4; /** * The stored value is either an int or a Point array. */ private static final int PROPERTY_TYPE_ARRAY = 5; /** * The stored value is an Image. */ private static final int PROPERTY_TYPE_IMAGE = 6; /** * The value type. */ private int type = 0; /** * The RtfShapeProperty name. */ private String name = ""; /** * The RtfShapeProperty value. */ private Object value = null; /** * Internally used to create the RtfShape. * * @param name The property name to use. * @param value The property value to use. */ private RtfShapeProperty(String name, Object value) { this.name = name; this.value = value; } /** * Constructs a RtfShapeProperty with a long value. * * @param name The property name to use. * @param value The long value to use. */ public RtfShapeProperty(String name, long value) { this(name, new Long(value)); this.type = PROPERTY_TYPE_LONG; } /** * Constructs a RtfShapeProperty with a double value. * * @param name The property name to use. * @param value The double value to use. */ public RtfShapeProperty(String name, double value) { this(name, new Double(value)); this.type = PROPERTY_TYPE_DOUBLE; } /** * Constructs a RtfShapeProperty with a boolean value. * * @param name The property name to use. * @param value The boolean value to use. */ public RtfShapeProperty(String name, boolean value) { this(name, Boolean.valueOf(value)); this.type = PROPERTY_TYPE_BOOLEAN; } /** * Constructs a RtfShapeProperty with a Color value. * * @param name The property name to use. * @param value The Color value to use. */ public RtfShapeProperty(String name, Color value) { this(name, (Object) value); this.type = PROPERTY_TYPE_COLOR; } /** * Constructs a RtfShapeProperty with an int array value. * * @param name The property name to use. * @param value The int array to use. */ public RtfShapeProperty(String name, int[] value) { this(name, (Object) value); this.type = PROPERTY_TYPE_ARRAY; } /** * Constructs a RtfShapeProperty with a Point array value. * * @param name The property name to use. * @param value The Point array to use. */ public RtfShapeProperty(String name, Point[] value) { this(name, (Object) value); this.type = PROPERTY_TYPE_ARRAY; } /** * Constructs a RtfShapeProperty with an Image value. * * @param name The property name to use. * @param value The Image to use. */ public RtfShapeProperty(String name, Image value) { this.name = name; this.value = value; this.type = PROPERTY_TYPE_IMAGE; } /** * Gets the name of this RtfShapeProperty. * * @return The name of this RtfShapeProperty. */ public String getName() { return this.name; } /** * Writes the property definition. How the property * is written depends on the property type. */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\sp")); result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\sn")); result.write(DELIMITER); result.write(DocWriter.getISOBytes(this.name)); result.write(CLOSE_GROUP); result.write(OPEN_GROUP); result.write(DocWriter.getISOBytes("\\sv")); result.write(DELIMITER); switch(this.type) { case PROPERTY_TYPE_LONG: case PROPERTY_TYPE_DOUBLE: result.write(DocWriter.getISOBytes(this.value.toString())); break; case PROPERTY_TYPE_BOOLEAN: if(((Boolean) this.value).booleanValue()) { result.write(DocWriter.getISOBytes("1")); } else { result.write(DocWriter.getISOBytes("0")); } break; case PROPERTY_TYPE_COLOR: Color color = (Color) this.value; result.write(intToByteArray(color.getRed() | (color.getGreen() << 8) | (color.getBlue() << 16))); break; case PROPERTY_TYPE_ARRAY: if(this.value instanceof int[]) { int[] values = (int[]) this.value; result.write(DocWriter.getISOBytes("4;")); result.write(intToByteArray(values.length)); result.write(COMMA_DELIMITER); for(int i = 0; i < values.length; i++) { result.write(intToByteArray(values[i])); if(i < values.length - 1) { result.write(COMMA_DELIMITER); } } } else if(this.value instanceof Point[]) { Point[] values = (Point[]) this.value; result.write(DocWriter.getISOBytes("8;")); result.write(intToByteArray(values.length)); result.write(COMMA_DELIMITER); for(int i = 0; i < values.length; i++) { result.write(DocWriter.getISOBytes("(")); result.write(intToByteArray(values[i].x)); result.write(DocWriter.getISOBytes(",")); result.write(intToByteArray(values[i].y)); result.write(DocWriter.getISOBytes(")")); if(i < values.length - 1) { result.write(COMMA_DELIMITER); } } } break; case PROPERTY_TYPE_IMAGE: Image image = (Image)this.value; RtfImage img = null; try { img = new RtfImage(this.doc, image); } catch (DocumentException de) { throw new ExceptionConverter(de); } img.setTopLevelElement(true); result.write(OPEN_GROUP); img.writeContent(result); result.write(CLOSE_GROUP); break; } result.write(CLOSE_GROUP); result.write(CLOSE_GROUP); } } src/rtf/com/lowagie/text/rtf/headerfooter/RtfHeaderFooter.java100644 0 0 33371 11106243445 22137 0ustar 0 0 /* * $Id: RtfHeaderFooter.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.headerfooter; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Image; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Table; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.field.RtfPageNumber; /** * The RtfHeaderFooter represents one header or footer. This class can be used * directly. * * @version $Id: RtfHeaderFooter.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfHeaderFooter extends HeaderFooter implements RtfBasicElement { /** * Constant for the header type */ public static final int TYPE_HEADER = 1; /** * Constant for the footer type */ public static final int TYPE_FOOTER = 2; /** * Constant for displaying the header/footer on the first page */ public static final int DISPLAY_FIRST_PAGE = 0; /** * Constant for displaying the header/footer on all pages */ public static final int DISPLAY_ALL_PAGES = 1; /** * Constant for displaying the header/footer on all left hand pages */ public static final int DISPLAY_LEFT_PAGES = 2; /** * Constant for displaying the header/footer on all right hand pages */ public static final int DISPLAY_RIGHT_PAGES = 4; /** * Constant for a header on all pages */ private static final byte[] HEADER_ALL = DocWriter.getISOBytes("\\header"); /** * Constant for a header on the first page */ private static final byte[] HEADER_FIRST = DocWriter.getISOBytes("\\headerf"); /** * Constant for a header on all left hand pages */ private static final byte[] HEADER_LEFT = DocWriter.getISOBytes("\\headerl"); /** * Constant for a header on all right hand pages */ private static final byte[] HEADER_RIGHT = DocWriter.getISOBytes("\\headerr"); /** * Constant for a footer on all pages */ private static final byte[] FOOTER_ALL = DocWriter.getISOBytes("\\footer"); /** * Constant for a footer on the first page */ private static final byte[] FOOTER_FIRST = DocWriter.getISOBytes("\\footerf"); /** * Constant for a footer on the left hand pages */ private static final byte[] FOOTER_LEFT = DocWriter.getISOBytes("\\footerl"); /** * Constant for a footer on the right hand pages */ private static final byte[] FOOTER_RIGHT = DocWriter.getISOBytes("\\footerr"); /** * The RtfDocument this RtfHeaderFooter belongs to */ private RtfDocument document = null; /** * The content of this RtfHeaderFooter */ private Object[] content = null; /** * The display type of this RtfHeaderFooter. TYPE_HEADER or TYPE_FOOTER */ private int type = TYPE_HEADER; /** * The display location of this RtfHeaderFooter. DISPLAY_FIRST_PAGE, * DISPLAY_LEFT_PAGES, DISPLAY_RIGHT_PAGES or DISPLAY_ALL_PAGES */ private int displayAt = DISPLAY_ALL_PAGES; /** * Constructs a RtfHeaderFooter based on a HeaderFooter with a certain type and displayAt * location. For internal use only. * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on * @param type The type of RtfHeaderFooter * @param displayAt The display location of this RtfHeaderFooter */ protected RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter, int type, int displayAt) { super(new Phrase(""), false); this.document = doc; this.type = type; this.displayAt = displayAt; Paragraph par = new Paragraph(); par.setAlignment(headerFooter.alignment()); if (headerFooter.getBefore() != null) { par.add(headerFooter.getBefore()); } if (headerFooter.isNumbered()) { par.add(new RtfPageNumber(this.document)); } if (headerFooter.getAfter() != null) { par.add(headerFooter.getAfter()); } try { this.content = new Object[1]; if(this.document != null) { this.content[0] = this.document.getMapper().mapElement(par)[0]; ((RtfBasicElement) this.content[0]).setInHeader(true); } else { this.content[0] = par; } } catch(DocumentException de) { de.printStackTrace(); } } /** * Constructs a RtfHeaderFooter as a copy of an existing RtfHeaderFooter. * For internal use only. * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The RtfHeaderFooter to copy * @param displayAt The display location of this RtfHeaderFooter */ protected RtfHeaderFooter(RtfDocument doc, RtfHeaderFooter headerFooter, int displayAt) { super(new Phrase(""), false); this.document = doc; this.content = headerFooter.getContent(); this.displayAt = displayAt; for(int i = 0; i < this.content.length; i++) { if(this.content[i] instanceof Element) { try { this.content[i] = this.document.getMapper().mapElement((Element) this.content[i])[0]; } catch(DocumentException de) { de.printStackTrace(); } } if(this.content[i] instanceof RtfBasicElement) { ((RtfBasicElement) this.content[i]).setInHeader(true); } } } /** * Constructs a RtfHeaderFooter for a HeaderFooter. * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The HeaderFooter to base this RtfHeaderFooter on */ protected RtfHeaderFooter(RtfDocument doc, HeaderFooter headerFooter) { super(new Phrase(""), false); this.document = doc; Paragraph par = new Paragraph(); par.setAlignment(headerFooter.alignment()); if (headerFooter.getBefore() != null) { par.add(headerFooter.getBefore()); } if (headerFooter.isNumbered()) { par.add(new RtfPageNumber(this.document)); } if (headerFooter.getAfter() != null) { par.add(headerFooter.getAfter()); } try { this.content = new Object[1]; this.content[0] = doc.getMapper().mapElement(par)[0]; ((RtfBasicElement) this.content[0]).setInHeader(true); } catch(DocumentException de) { de.printStackTrace(); } } /** * Constructs a RtfHeaderFooter for any Element. * * @param element The Element to display as content of this RtfHeaderFooter */ public RtfHeaderFooter(Element element) { this(new Element[]{element}); } /** * Constructs a RtfHeaderFooter for an array of Elements. * * @param elements The Elements to display as the content of this RtfHeaderFooter. */ public RtfHeaderFooter(Element[] elements) { super(new Phrase(""), false); this.content = new Object[elements.length]; for(int i = 0; i < elements.length; i++) { this.content[i] = elements[i]; } } /** * Sets the RtfDocument this RtfElement belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; if(this.document != null) { for(int i = 0; i < this.content.length; i++) { try { if(this.content[i] instanceof Element) { this.content[i] = this.document.getMapper().mapElement((Element) this.content[i])[0]; ((RtfBasicElement) this.content[i]).setInHeader(true); } else if(this.content[i] instanceof RtfBasicElement){ ((RtfBasicElement) this.content[i]).setRtfDocument(this.document); ((RtfBasicElement) this.content[i]).setInHeader(true); } } catch(DocumentException de) { de.printStackTrace(); } } } } /** * Writes the content of this RtfHeaderFooter */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); if(this.type == TYPE_HEADER) { if(this.displayAt == DISPLAY_ALL_PAGES) { result.write(HEADER_ALL); } else if(this.displayAt == DISPLAY_FIRST_PAGE) { result.write(HEADER_FIRST); } else if(this.displayAt == DISPLAY_LEFT_PAGES) { result.write(HEADER_LEFT); } else if(this.displayAt == DISPLAY_RIGHT_PAGES) { result.write(HEADER_RIGHT); } } else { if(this.displayAt == DISPLAY_ALL_PAGES) { result.write(FOOTER_ALL); } else if(this.displayAt == DISPLAY_FIRST_PAGE) { result.write(FOOTER_FIRST); } else if(this.displayAt == DISPLAY_LEFT_PAGES) { result.write(FOOTER_LEFT); } else if(this.displayAt == DISPLAY_RIGHT_PAGES) { result.write(FOOTER_RIGHT); } } result.write(DELIMITER); for(int i = 0; i < this.content.length; i++) { if(this.content[i] instanceof RtfBasicElement) { RtfBasicElement rbe = (RtfBasicElement)this.content[i]; rbe.writeContent(result); } } result.write(CLOSE_GROUP); } /** * Sets the display location of this RtfHeaderFooter * * @param displayAt The display location to use. */ public void setDisplayAt(int displayAt) { this.displayAt = displayAt; } /** * Sets the type of this RtfHeaderFooter * * @param type The type to use. */ public void setType(int type) { this.type = type; } /** * Gets the content of this RtfHeaderFooter * * @return The content of this RtfHeaderFooter */ private Object[] getContent() { return this.content; } /** * Unused * @param inTable */ public void setInTable(boolean inTable) { } /** * Unused * @param inHeader */ public void setInHeader(boolean inHeader) { } /** * Set the alignment of this RtfHeaderFooter. Passes the setting * on to the contained element. */ public void setAlignment(int alignment) { super.setAlignment(alignment); for(int i = 0; i < this.content.length; i++) { if(this.content[i] instanceof Paragraph) { ((Paragraph) this.content[i]).setAlignment(alignment); } else if(this.content[i] instanceof Table) { ((Table) this.content[i]).setAlignment(alignment); } else if(this.content[i] instanceof Image) { ((Image) this.content[i]).setAlignment(alignment); } } } } src/rtf/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java100644 0 0 36021 11012562274 23147 0ustar 0 0 /* * $Id: RtfHeaderFooterGroup.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.headerfooter; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.HeaderFooter; import com.lowagie.text.Phrase; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfHeaderFooterGroup holds 0 - 3 RtfHeaderFooters that create a group * of headers or footers. * * @version $Id: RtfHeaderFooterGroup.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfHeaderFooterGroup extends HeaderFooter implements RtfBasicElement { /** * This RtfHeaderFooterGroup contains no RtfHeaderFooter objects */ private static final int MODE_NONE = 0; /** * This RtfHeaderFooterGroup contains one RtfHeaderFooter object */ private static final int MODE_SINGLE = 1; /** * This RtfHeaderFooterGroup contains two or three RtfHeaderFooter objects */ private static final int MODE_MULTIPLE = 2; /** * The current mode of this RtfHeaderFooterGroup. Defaults to MODE_NONE */ private int mode = MODE_NONE; /** * The current type of this RtfHeaderFooterGroup. Defaults to RtfHeaderFooter.TYPE_HEADER */ private int type = RtfHeaderFooter.TYPE_HEADER; /** * The RtfHeaderFooter for all pages */ private RtfHeaderFooter headerAll = null; /** * The RtfHeaderFooter for the first page */ private RtfHeaderFooter headerFirst = null; /** * The RtfHeaderFooter for the left hand pages */ private RtfHeaderFooter headerLeft = null; /** * The RtfHeaderFooter for the right hand pages */ private RtfHeaderFooter headerRight = null; /** * The RtfDocument this RtfHeaderFooterGroup belongs to */ private RtfDocument document = null; /** * Constructs a RtfHeaderGroup to which you add headers/footers using * via the setHeaderFooter method. * */ public RtfHeaderFooterGroup() { super(new Phrase(""), false); this.mode = MODE_NONE; } /** * Constructs a certain type of RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER * and RtfHeaderFooter.TYPE_FOOTER are valid values for type. * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param type The type of RtfHeaderFooterGroup to create */ public RtfHeaderFooterGroup(RtfDocument doc, int type) { super(new Phrase(""), false); this.document = doc; this.type = type; } /** * Constructs a RtfHeaderFooterGroup by copying the content of the original * RtfHeaderFooterGroup * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The RtfHeaderFooterGroup to copy * @param type The type of RtfHeaderFooterGroup to create */ public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooterGroup headerFooter, int type) { super(new Phrase(""), false); this.document = doc; this.mode = headerFooter.getMode(); this.type = type; if(headerFooter.getHeaderAll() != null) { this.headerAll = new RtfHeaderFooter(this.document, headerFooter.getHeaderAll(), RtfHeaderFooter.DISPLAY_ALL_PAGES); } if(headerFooter.getHeaderFirst() != null) { this.headerFirst = new RtfHeaderFooter(this.document, headerFooter.getHeaderFirst(), RtfHeaderFooter.DISPLAY_FIRST_PAGE); } if(headerFooter.getHeaderLeft() != null) { this.headerLeft = new RtfHeaderFooter(this.document, headerFooter.getHeaderLeft(), RtfHeaderFooter.DISPLAY_LEFT_PAGES); } if(headerFooter.getHeaderRight() != null) { this.headerRight = new RtfHeaderFooter(this.document, headerFooter.getHeaderRight(), RtfHeaderFooter.DISPLAY_RIGHT_PAGES); } setType(this.type); } /** * Constructs a RtfHeaderFooterGroup for a certain RtfHeaderFooter. * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The RtfHeaderFooter to display * @param type The type of RtfHeaderFooterGroup to create */ public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooter headerFooter, int type) { super(new Phrase(""), false); this.document = doc; this.type = type; this.mode = MODE_SINGLE; headerAll = new RtfHeaderFooter(doc, headerFooter, RtfHeaderFooter.DISPLAY_ALL_PAGES); headerAll.setType(this.type); } /** * Constructs a RtfHeaderGroup for a certain HeaderFooter * * @param doc The RtfDocument this RtfHeaderFooter belongs to * @param headerFooter The HeaderFooter to display * @param type The type of RtfHeaderFooterGroup to create */ public RtfHeaderFooterGroup(RtfDocument doc, HeaderFooter headerFooter, int type) { super(new Phrase(""), false); this.document = doc; this.type = type; this.mode = MODE_SINGLE; headerAll = new RtfHeaderFooter(doc, headerFooter, type, RtfHeaderFooter.DISPLAY_ALL_PAGES); headerAll.setType(this.type); } /** * Sets the RtfDocument this RtfElement belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; if(headerAll != null) { headerAll.setRtfDocument(this.document); } if(headerFirst != null) { headerFirst.setRtfDocument(this.document); } if(headerLeft != null) { headerLeft.setRtfDocument(this.document); } if(headerRight != null) { headerRight.setRtfDocument(this.document); } } /** * Write the content of this RtfHeaderFooterGroup. */ public void writeContent(final OutputStream result) throws IOException { if(this.mode == MODE_SINGLE) { headerAll.writeContent(result); } else if(this.mode == MODE_MULTIPLE) { if(headerFirst != null) { headerFirst.writeContent(result); } if(headerLeft != null) { headerLeft.writeContent(result); } if(headerRight != null) { headerRight.writeContent(result); } if(headerAll != null) { headerAll.writeContent(result); } } } /** * Set a RtfHeaderFooter to be displayed at a certain position * * @param headerFooter The RtfHeaderFooter to display * @param displayAt The display location to use */ public void setHeaderFooter(RtfHeaderFooter headerFooter, int displayAt) { this.mode = MODE_MULTIPLE; headerFooter.setRtfDocument(this.document); headerFooter.setType(this.type); headerFooter.setDisplayAt(displayAt); switch(displayAt) { case RtfHeaderFooter.DISPLAY_ALL_PAGES: headerAll = headerFooter; break; case RtfHeaderFooter.DISPLAY_FIRST_PAGE: headerFirst = headerFooter; break; case RtfHeaderFooter.DISPLAY_LEFT_PAGES: headerLeft = headerFooter; break; case RtfHeaderFooter.DISPLAY_RIGHT_PAGES: headerRight = headerFooter; break; } } /** * Set a HeaderFooter to be displayed at a certain position * * @param headerFooter The HeaderFooter to set * @param displayAt The display location to use */ public void setHeaderFooter(HeaderFooter headerFooter, int displayAt) { this.mode = MODE_MULTIPLE; switch(displayAt) { case RtfHeaderFooter.DISPLAY_ALL_PAGES: headerAll = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); break; case RtfHeaderFooter.DISPLAY_FIRST_PAGE: headerFirst = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); break; case RtfHeaderFooter.DISPLAY_LEFT_PAGES: headerLeft = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); break; case RtfHeaderFooter.DISPLAY_RIGHT_PAGES: headerRight = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt); break; } } /** * Set that this RtfHeaderFooterGroup should have a title page. If only * a header / footer for all pages exists, then it will be copied to the * first page as well. */ public void setHasTitlePage() { if(this.mode == MODE_SINGLE) { this.mode = MODE_MULTIPLE; headerFirst = new RtfHeaderFooter(this.document, headerAll, RtfHeaderFooter.DISPLAY_FIRST_PAGE); headerFirst.setType(this.type); } } /** * Set that this RtfHeaderFooterGroup should have facing pages. If only * a header / footer for all pages exists, then it will be copied to the left * and right pages as well. */ public void setHasFacingPages() { if(this.mode == MODE_SINGLE) { this.mode = MODE_MULTIPLE; this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES); this.headerLeft.setType(this.type); this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES); this.headerRight.setType(this.type); this.headerAll = null; } else if(this.mode == MODE_MULTIPLE) { if(this.headerLeft == null && this.headerAll != null) { this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES); this.headerLeft.setType(this.type); } if(this.headerRight == null && this.headerAll != null) { this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES); this.headerRight.setType(this.type); } this.headerAll = null; } } /** * Get whether this RtfHeaderFooterGroup has a titlepage * * @return Whether this RtfHeaderFooterGroup has a titlepage */ public boolean hasTitlePage() { return (headerFirst != null); } /** * Get whether this RtfHeaderFooterGroup has facing pages * * @return Whether this RtfHeaderFooterGroup has facing pages */ public boolean hasFacingPages() { return (headerLeft != null || headerRight != null); } /** * Unused * @param inTable */ public void setInTable(boolean inTable) { } /** * Unused * @param inHeader */ public void setInHeader(boolean inHeader) { } /** * Set the type of this RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER * or RtfHeaderFooter.TYPE_FOOTER. Also sets the type for all RtfHeaderFooters * of this RtfHeaderFooterGroup. * * @param type The type to use */ public void setType(int type) { this.type = type; if(headerAll != null) { headerAll.setType(this.type); } if(headerFirst != null) { headerFirst.setType(this.type); } if(headerLeft != null) { headerLeft.setType(this.type); } if(headerRight != null) { headerRight.setType(this.type); } } /** * Gets the mode of this RtfHeaderFooterGroup * * @return The mode of this RtfHeaderFooterGroup */ protected int getMode() { return this.mode; } /** * Gets the RtfHeaderFooter for all pages * * @return The RtfHeaderFooter for all pages */ protected RtfHeaderFooter getHeaderAll() { return headerAll; } /** * Gets the RtfHeaderFooter for the title page * * @return The RtfHeaderFooter for the title page */ protected RtfHeaderFooter getHeaderFirst() { return headerFirst; } /** * Gets the RtfHeaderFooter for all left hand pages * * @return The RtfHeaderFooter for all left hand pages */ protected RtfHeaderFooter getHeaderLeft() { return headerLeft; } /** * Gets the RtfHeaderFooter for all right hand pages * * @return The RtfHeaderFooter for all right hand pages */ protected RtfHeaderFooter getHeaderRight() { return headerRight; } } src/rtf/com/lowagie/text/rtf/list/RtfList.java100644 0 0 56377 11224570760 17026 0ustar 0 0 /* * $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $ * * Copyright 2008 Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.list; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import java.security.InvalidParameterException; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.List; import com.lowagie.text.ListItem; import com.lowagie.text.RomanList; import com.lowagie.text.factories.RomanAlphabetFactory; import com.lowagie.text.factories.RomanNumberFactory; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfFont; import com.lowagie.text.rtf.style.RtfFontList; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfList stores one List. It also provides the methods to write the * list declaration and the list data. * * @version $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.3 */ public class RtfList extends RtfElement implements RtfExtendedElement { /** * Constant for the list number * @since 2.1.3 */ public static final byte[] LIST_NUMBER = DocWriter.getISOBytes("\\ls"); /** * Constant for the list */ private static final byte[] LIST = DocWriter.getISOBytes("\\list"); /** * Constant for the list id * @since 2.1.3 */ public static final byte[] LIST_ID = DocWriter.getISOBytes("\\listid"); /** * Constant for the list template id */ private static final byte[] LIST_TEMPLATE_ID = DocWriter.getISOBytes("\\listtemplateid"); /** * Constant for the simple list */ private static final byte[] LIST_SIMPLE = DocWriter.getISOBytes("\\listsimple"); /** * Constant for the hybrid list */ private static final byte[] LIST_HYBRID = DocWriter.getISOBytes("\\listhybrid"); /** * Constant to indicate if the list restarts at each section. Word 7 compatiblity */ private static final byte[] LIST_RESTARTHDN = DocWriter.getISOBytes("\\listrestarthdn"); /** * Constant for the name of this list */ private static final byte[] LIST_NAME = DocWriter.getISOBytes("\\listname"); /** * Constant for the identifier of the style of this list. Mutually exclusive with \\liststylename */ private static final byte[] LIST_STYLEID = DocWriter.getISOBytes("\\liststyleid"); /** * Constant for the identifier of the style of this list. Mutually exclusive with \\liststyleid */ private static final byte[] LIST_STYLENAME = DocWriter.getISOBytes("\\liststylename"); // character properties /** * Constant for the list level value * @since 2.1.3 */ public static final byte[] LIST_LEVEL_NUMBER = DocWriter.getISOBytes("\\ilvl"); /** * Constant for the old list text * @since 2.1.3 */ public static final byte[] LIST_TEXT = DocWriter.getISOBytes("\\listtext"); /** * Constant for the old list number end * @since 2.1.3 */ public static final byte[] LIST_NUMBER_END = DocWriter.getISOBytes("."); /** * Constant for a tab character * @since 2.1.3 */ public static final byte[] TAB = DocWriter.getISOBytes("\\tab"); /** * The subitems of this RtfList */ private ArrayList items; /** * The parent list if there is one. */ private RtfList parentList = null; /** * The list id */ private int listID = -1; /** * List type of NORMAL - no control word * @since 2.1.3 */ public static final int LIST_TYPE_NORMAL = 0; /* Normal list type */ /** * List type of listsimple * @since 2.1.3 */ public static final int LIST_TYPE_SIMPLE = 1; /* Simple list type */ /** * List type of listhybrid * @since 2.1.3 */ public static final int LIST_TYPE_HYBRID = 2; /* Hybrid list type */ /** * This RtfList type */ private int listType = LIST_TYPE_HYBRID; /** * The name of the list if it exists */ private String name = null; /** * The list number of this RtfList */ private int listNumber = -1; /** * The RtfList lists managed by this RtfListTable */ private ArrayList listLevels = null;; /** * Constructs an empty RtfList object. * @since 2.1.3 */ public RtfList() { super(null); createDefaultLevels(); } /** * Set the document. * @param doc The RtfDocument * @since 2.1.3 */ public void setDocument(RtfDocument doc) { this.document = doc; // get the list number or create a new one adding it to the table this.listNumber = document.getDocumentHeader().getListNumber(this); } /** * Constructs an empty RtfList object. * @param doc The RtfDocument this RtfList belongs to * @since 2.1.3 */ public RtfList(RtfDocument doc) { super(doc); createDefaultLevels(); // get the list number or create a new one adding it to the table this.listNumber = document.getDocumentHeader().getListNumber(this); } /** * Constructs a new RtfList for the specified List. * * @param doc The RtfDocument this RtfList belongs to * @param list The List this RtfList is based on * @since 2.1.3 */ public RtfList(RtfDocument doc, List list) { // setup the listlevels // Then, setup the list data below // setup 1 listlevel if it's a simple list // setup 9 if it's a regular list // setup 9 if it's a hybrid list (default) super(doc); createDefaultLevels(); this.items = new ArrayList(); // list content RtfListLevel ll = (RtfListLevel)this.listLevels.get(0); // get the list number or create a new one adding it to the table this.listNumber = document.getDocumentHeader().getListNumber(this); if(list.getSymbolIndent() > 0 && list.getIndentationLeft() > 0) { ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1)); ll.setLeftIndent((int) ((list.getIndentationLeft() + list.getSymbolIndent()) * RtfElement.TWIPS_FACTOR)); } else if(list.getSymbolIndent() > 0) { ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1)); ll.setLeftIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR)); } else if(list.getIndentationLeft() > 0) { ll.setFirstIndent(0); ll.setLeftIndent((int) (list.getIndentationLeft() * RtfElement.TWIPS_FACTOR)); } else { ll.setFirstIndent(0); ll.setLeftIndent(0); } ll.setRightIndent((int) (list.getIndentationRight() * RtfElement.TWIPS_FACTOR)); ll.setSymbolIndent((int) ((list.getSymbolIndent() + list.getIndentationLeft()) * RtfElement.TWIPS_FACTOR)); ll.correctIndentation(); ll.setTentative(false); if (list instanceof RomanList) { if (list.isLowercase()) { ll.setListType(RtfListLevel.LIST_TYPE_LOWER_ROMAN); } else { ll.setListType(RtfListLevel.LIST_TYPE_UPPER_ROMAN); } } else if (list.isNumbered()) { ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED); } else if (list.isLettered()) { if (list.isLowercase()) { ll.setListType(RtfListLevel.LIST_TYPE_LOWER_LETTERS); } else { ll.setListType(RtfListLevel.LIST_TYPE_UPPER_LETTERS); } } else { // Paragraph p = new Paragraph(); // p.add(new Chunk(list.getPreSymbol()) ); // p.add(list.getSymbol()); // p.add(new Chunk(list.getPostSymbol()) ); // ll.setBulletChunk(list.getSymbol()); ll.setBulletCharacter(list.getPreSymbol() + list.getSymbol().getContent() + list.getPostSymbol()); ll.setListType(RtfListLevel.LIST_TYPE_BULLET); } // now setup the actual list contents. for(int i = 0; i < list.getItems().size(); i++) { try { Element element = (Element) list.getItems().get(i); if(element.type() == Element.CHUNK) { element = new ListItem((Chunk) element); } if(element instanceof ListItem) { ll.setAlignment(((ListItem) element).getAlignment()); } RtfBasicElement[] rtfElements = doc.getMapper().mapElement(element); for(int j = 0; j < rtfElements.length; j++) { RtfBasicElement rtfElement = rtfElements[j]; if(rtfElement instanceof RtfList) { ((RtfList) rtfElement).setParentList(this); } else if(rtfElement instanceof RtfListItem) { ((RtfListItem) rtfElement).setParent(ll); } ll.setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))) ); if (list.getSymbol() != null && list.getSymbol().getFont() != null && !list.getSymbol().getContent().startsWith("-") && list.getSymbol().getContent().length() > 0) { // only set this to bullet symbol is not default ll.setBulletFont( list.getSymbol().getFont()); ll.setBulletCharacter(list.getSymbol().getContent().substring(0, 1)); } else if (list.getSymbol() != null && list.getSymbol().getFont() != null) { ll.setBulletFont(list.getSymbol().getFont()); } else { ll.setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0))); } items.add(rtfElement); } } catch(DocumentException de) { de.printStackTrace(); } } } /** * Writes the definition part of this list level * @param result * @throws IOException * @since 2.1.3 */ public void writeDefinition(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(LIST); result.write(LIST_TEMPLATE_ID); result.write(intToByteArray(document.getRandomInt())); int levelsToWrite = -1; switch(this.listType) { case LIST_TYPE_NORMAL: levelsToWrite = listLevels.size(); break; case LIST_TYPE_SIMPLE: result.write(LIST_SIMPLE); result.write(intToByteArray(1)); levelsToWrite = 1; break; case LIST_TYPE_HYBRID: result.write(LIST_HYBRID); levelsToWrite = listLevels.size(); break; default: break; } this.document.outputDebugLinebreak(result); // TODO: Figure out hybrid because multi-level hybrid does not work. // Seems hybrid is mixed type all single level - Simple = single level // SIMPLE1/HYRBID // 1. Line 1 // 2. Line 2 // MULTI-LEVEL LISTS Are Simple0 - 9 levels (0-8) all single digit // 1. Line 1 // 1.1. Line 1.1 // 1.2. Line 1.2 // 2. Line 2 // write the listlevels here for(int i = 0; i 0) { // TODO Fix no paragraph on last list item in tables result.write(RtfParagraph.PARAGRAPH); } this.document.outputDebugLinebreak(result); } else if(thisRtfElement instanceof RtfList) { ((RtfList)thisRtfElement).writeContent(result); // ((RtfList)thisRtfElement).writeListBeginning(result); writeListNumbers(result); this.document.outputDebugLinebreak(result); } } } if(!this.inTable) { result.write(CLOSE_GROUP); } result.write(RtfParagraph.PARAGRAPH_DEFAULTS); } /** * * @param result * @param itemNr * @param listLevel * @throws IOException * @since 2.1.3 */ protected void writeListTextBlock(final OutputStream result, int itemNr, RtfListLevel listLevel) throws IOException { result.write(OPEN_GROUP); result.write(RtfList.LIST_TEXT); result.write(RtfParagraph.PARAGRAPH_DEFAULTS); if(this.inTable) { result.write(RtfParagraph.IN_TABLE); } result.write(RtfFontList.FONT_NUMBER); if(listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) { result.write(intToByteArray(listLevel.getFontNumber().getFontNumber())); } else { result.write(intToByteArray(listLevel.getFontBullet().getFontNumber())); } listLevel.writeIndentation(result); result.write(DELIMITER); if(listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) { switch(listLevel.getListType()) { case RtfListLevel.LIST_TYPE_NUMBERED : result.write(intToByteArray(itemNr)); break; case RtfListLevel.LIST_TYPE_UPPER_LETTERS : result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getUpperCaseString(itemNr))); break; case RtfListLevel.LIST_TYPE_LOWER_LETTERS : result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getLowerCaseString(itemNr))); break; case RtfListLevel.LIST_TYPE_UPPER_ROMAN : result.write(DocWriter.getISOBytes(RomanNumberFactory.getUpperCaseString(itemNr))); break; case RtfListLevel.LIST_TYPE_LOWER_ROMAN : result.write(DocWriter.getISOBytes(RomanNumberFactory.getLowerCaseString(itemNr))); break; } result.write(LIST_NUMBER_END); } else { this.document.filterSpecialChar(result, listLevel.getBulletCharacter(), true, false); } result.write(TAB); result.write(CLOSE_GROUP); } /** * Writes only the list number and list level number. * * @param result The OutputStream to write to * @throws IOException On i/o errors. * @since 2.1.3 */ protected void writeListNumbers(final OutputStream result) throws IOException { result.write(RtfList.LIST_NUMBER); result.write(intToByteArray(listNumber)); } /** * Create a default set of listlevels * @since 2.1.3 */ protected void createDefaultLevels() { this.listLevels = new ArrayList(); // listlevels for(int i=0; i<=8; i++) { // create a list level RtfListLevel ll = new RtfListLevel(this.document); ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED); ll.setFirstIndent(0); ll.setLeftIndent(0); ll.setLevelTextNumber(i); ll.setTentative(true); ll.correctIndentation(); this.listLevels.add(ll); } } /** * Gets the id of this list * * @return Returns the list number. * @since 2.1.3 */ public int getListNumber() { return listNumber; } /** * Sets the id of this list * * @param listNumber The list number to set. * @since 2.1.3 */ public void setListNumber(int listNumber) { this.listNumber = listNumber; } /** * Sets whether this RtfList is in a table. Sets the correct inTable setting for all * child elements. * * @param inTable True if this RtfList is in a table, false otherwise * @since 2.1.3 */ public void setInTable(boolean inTable) { super.setInTable(inTable); for(int i = 0; i < this.items.size(); i++) { ((RtfBasicElement) this.items.get(i)).setInTable(inTable); } for(int i = 0; i < this.listLevels.size(); i++) { ((RtfListLevel) this.listLevels.get(i)).setInTable(inTable); } } /** * Sets whether this RtfList is in a header. Sets the correct inTable setting for all * child elements. * * @param inHeader True if this RtfList is in a header, false otherwise * @since 2.1.3 */ public void setInHeader(boolean inHeader) { super.setInHeader(inHeader); for(int i = 0; i < this.items.size(); i++) { ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader); } } /** * Correct the indentation of this RtfList by adding left/first line indentation * from the parent RtfList. Also calls correctIndentation on all child RtfLists. * @since 2.1.3 */ protected void correctIndentation() { // TODO: Fix // if(this.parentList != null) { // this.leftIndent = this.leftIndent + this.parentList.getLeftIndent() + this.parentList.getFirstIndent(); // } for(int i = 0; i < this.items.size(); i++) { if(this.items.get(i) instanceof RtfList) { ((RtfList) this.items.get(i)).correctIndentation(); } else if(this.items.get(i) instanceof RtfListItem) { ((RtfListItem) this.items.get(i)).correctIndentation(); } } } /** * Set the list ID number * @param id * @since 2.1.3 */ public void setID(int id) { this.listID = id; } /** * Get the list ID number * @return this list id * @since 2.1.3 */ public int getID() { return this.listID; } /** * @return the listType * @see RtfList#LIST_TYPE_NORMAL * @see RtfList#LIST_TYPE_SIMPLE * @see RtfList#LIST_TYPE_HYBRID * @since 2.1.3 */ public int getListType() { return listType; } /** * @param listType the listType to set * @see RtfList#LIST_TYPE_NORMAL * @see RtfList#LIST_TYPE_SIMPLE * @see RtfList#LIST_TYPE_HYBRID * @since 2.1.3 */ public void setListType(int listType) throws InvalidParameterException { if(listType == LIST_TYPE_NORMAL || listType == LIST_TYPE_SIMPLE || listType == LIST_TYPE_HYBRID ) { this.listType = listType; } else { throw new InvalidParameterException("Invalid listType value."); } } /** * @return the parentList * @since 2.1.3 */ public RtfList getParentList() { return parentList; } /** * @param parentList the parentList to set * @since 2.1.3 */ public void setParentList(RtfList parentList) { this.parentList = parentList; } /** * @return the name * @since 2.1.3 */ public String getName() { return name; } /** * @param name the name to set * @since 2.1.3 */ public void setName(String name) { this.name = name; } /** * @return the list at the index * @since 2.1.3 */ public RtfListLevel getListLevel(int index) { if(listLevels != null) { return (RtfListLevel)this.listLevels.get(index); } else return null; } } src/rtf/com/lowagie/text/rtf/list/RtfListItem.java100644 0 0 20652 11215636056 17631 0ustar 0 0 /* * $Id: RtfListItem.java 3969 2009-06-16 08:03:23Z blowagie $ * * Copyright 2008 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.list; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.ListItem; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.text.RtfChunk; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfListItem acts as a wrapper for a ListItem. * * @version $Id: RtfListItem.java 3969 2009-06-16 08:03:23Z blowagie $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.3 */ public class RtfListItem extends RtfParagraph { /** * The RtfList this RtfListItem belongs to. */ private RtfListLevel parentList = null; /** * Whether this RtfListItem contains further RtfLists. */ private boolean containsInnerList = false; /** * Constructs a RtfListItem for a ListItem belonging to a RtfDocument. * * @param doc The RtfDocument this RtfListItem belongs to. * @param listItem The ListItem this RtfListItem is based on. */ public RtfListItem(RtfDocument doc, ListItem listItem) { super(doc, listItem); } /** * Writes the content of this RtfListItem. */ public void writeContent(final OutputStream result) throws IOException { if(this.paragraphStyle.getSpacingBefore() > 0) { result.write(RtfParagraphStyle.SPACING_BEFORE); result.write(intToByteArray(paragraphStyle.getSpacingBefore())); } if(this.paragraphStyle.getSpacingAfter() > 0) { result.write(RtfParagraphStyle.SPACING_AFTER); result.write(intToByteArray(this.paragraphStyle.getSpacingAfter())); } if(this.paragraphStyle.getLineLeading() > 0) { result.write(RtfParagraph.LINE_SPACING); result.write(intToByteArray(this.paragraphStyle.getLineLeading())); } for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); if(rtfElement instanceof RtfChunk) { ((RtfChunk) rtfElement).setSoftLineBreaks(true); } else if(rtfElement instanceof RtfList) { result.write(RtfParagraph.PARAGRAPH); this.containsInnerList = true; } rtfElement.writeContent(result); if(rtfElement instanceof RtfList) { switch(this.parentList.getLevelFollowValue()) { case RtfListLevel.LIST_LEVEL_FOLLOW_NOTHING: break; case RtfListLevel.LIST_LEVEL_FOLLOW_TAB: this.parentList.writeListBeginning(result); result.write(RtfList.TAB); break; case RtfListLevel.LIST_LEVEL_FOLLOW_SPACE: this.parentList.writeListBeginning(result); result.write(DocWriter.getISOBytes(" ")); break; } } } } /** * Writes the definition of the first element in this RtfListItem that is * an instanceof {@link RtfList} to the given stream.
      * If this item does not contain a {@link RtfList} element nothing is written * and the method returns false. * * @param out destination stream * @return true if a RtfList definition was written, false otherwise * @throws IOException */ public boolean writeDefinition(OutputStream out) throws IOException { for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement)chunks.get(i); if(rtfElement instanceof RtfList) { RtfList rl = (RtfList)rtfElement; rl.writeDefinition(out); return true; } } return false; } private int level=0; /** * Inherit the list settings from the parent list to RtfLists that * are contained in this RtfListItem. * * @param listNumber The list number to inherit. * @param listLevel The list level to inherit. */ public void inheritListSettings(int listNumber, int listLevel) { for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); if(rtfElement instanceof RtfList) { ((RtfList) rtfElement).setListNumber(listNumber); setLevel(listLevel); // ((RtfList) rtfElement).setParent(this.parentList); } } } /** * Correct the indentation of RtfLists in this RtfListItem by adding left/first line indentation * from the parent RtfList. Also calls correctIndentation on all child RtfLists. */ protected void correctIndentation() { for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i); if(rtfElement instanceof RtfList) { ((RtfList) rtfElement).correctIndentation(); } } } /** * Set the parent RtfList. * * @param parentList The parent RtfList to use. */ public void setParent(RtfListLevel parentList) { this.parentList = parentList; } /** * Set the parent RtfList. * * @return The parent RtfList to use. * @since 2.1.3 */ public RtfListLevel getParent() { return this.parentList; } /** * Gets whether this RtfListItem contains further RtfLists. * * @return Whether this RtfListItem contains further RtfLists. */ public boolean isContainsInnerList() { return this.containsInnerList; } /** * @return the level * @since 2.1.3 */ public int getLevel() { return level; } /** * @param level the level to set * @since 2.1.3 */ public void setLevel(int level) { this.level = level; } } src/rtf/com/lowagie/text/rtf/list/RtfListLevel.java100644 0 0 71257 11106243445 20004 0ustar 0 0 /* * $Id: RtfListLevel.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2008 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.list; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfColor; import com.lowagie.text.rtf.style.RtfFont; import com.lowagie.text.rtf.style.RtfFontList; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfListLevel is a listlevel object in a list. * * @version $Id: RtfListLevel.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.3 */ public class RtfListLevel extends RtfElement implements RtfExtendedElement { /** * Constant for list level */ private static final byte[] LIST_LEVEL = DocWriter.getISOBytes("\\listlevel"); /** * Constant for list level */ private static final byte[] LIST_LEVEL_TEMPLATE_ID = DocWriter.getISOBytes("\\leveltemplateid"); /** * Constant for list level style old */ private static final byte[] LIST_LEVEL_TYPE = DocWriter.getISOBytes("\\levelnfc"); /** * Constant for list level style new */ private static final byte[] LIST_LEVEL_TYPE_NEW = DocWriter.getISOBytes("\\levelnfcn"); /** * Constant for list level alignment old */ private static final byte[] LIST_LEVEL_ALIGNMENT = DocWriter.getISOBytes("\\leveljc"); /** * Constant for list level alignment new */ private static final byte[] LIST_LEVEL_ALIGNMENT_NEW = DocWriter.getISOBytes("\\leveljcn"); /** * Constant for list level start at */ private static final byte[] LIST_LEVEL_START_AT = DocWriter.getISOBytes("\\levelstartat"); /** * Constant for list level text */ private static final byte[] LIST_LEVEL_TEXT = DocWriter.getISOBytes("\\leveltext"); /** * Constant for the beginning of the list level numbered style */ private static final byte[] LIST_LEVEL_STYLE_NUMBERED_BEGIN = DocWriter.getISOBytes("\\\'02\\\'"); /** * Constant for the end of the list level numbered style */ private static final byte[] LIST_LEVEL_STYLE_NUMBERED_END = DocWriter.getISOBytes(".;"); /** * Constant for the beginning of the list level bulleted style */ private static final byte[] LIST_LEVEL_STYLE_BULLETED_BEGIN = DocWriter.getISOBytes("\\\'01"); /** * Constant for the end of the list level bulleted style */ private static final byte[] LIST_LEVEL_STYLE_BULLETED_END = DocWriter.getISOBytes(";"); /** * Constant for the beginning of the list level numbers */ private static final byte[] LIST_LEVEL_NUMBERS_BEGIN = DocWriter.getISOBytes("\\levelnumbers"); /** * Constant which specifies which character follows the level text */ private static final byte[] LIST_LEVEL_FOLOW = DocWriter.getISOBytes("\\levelfollow"); /** * Constant which specifies the levelspace controlword */ private static final byte[] LIST_LEVEL_SPACE = DocWriter.getISOBytes("\\levelspace"); /** * Constant which specifies the levelindent control word */ private static final byte[] LIST_LEVEL_INDENT = DocWriter.getISOBytes("\\levelindent"); /** * Constant which specifies (1) if list numbers from previous levels should be converted * to Arabic numbers; (0) if they should be left with the format specified by their * own level's definition. */ private static final byte[] LIST_LEVEL_LEGAL = DocWriter.getISOBytes("\\levellegal"); /** * Constant which specifies * (1) if this level does/does not restart its count each time a super ordinate level is incremented * (0) if this level does not restart its count each time a super ordinate level is incremented. */ private static final byte[] LIST_LEVEL_NO_RESTART = DocWriter.getISOBytes("\\levelnorestart"); /** * Constant for the list level numbers */ private static final byte[] LIST_LEVEL_NUMBERS_NUMBERED = DocWriter.getISOBytes("\\\'01"); /** * Constant for the end of the list level numbers */ private static final byte[] LIST_LEVEL_NUMBERS_END = DocWriter.getISOBytes(";"); /** * Constant for the first indentation */ private static final byte[] LIST_LEVEL_FIRST_INDENT = DocWriter.getISOBytes("\\fi"); /** * Constant for the symbol indentation */ private static final byte[] LIST_LEVEL_SYMBOL_INDENT = DocWriter.getISOBytes("\\tx"); /** * Constant for the lvltentative control word */ private static final byte[] LIST_LEVEL_TENTATIVE = DocWriter.getISOBytes("\\lvltentative"); /** * Constant for the levelpictureN control word */ private static final byte[] LIST_LEVEL_PICTURE = DocWriter.getISOBytes("\\levelpicture"); public static final int LIST_TYPE_NUMBERED = 1; public static final int LIST_TYPE_UPPER_LETTERS = 2; public static final int LIST_TYPE_LOWER_LETTERS = 3; public static final int LIST_TYPE_UPPER_ROMAN = 4; public static final int LIST_TYPE_LOWER_ROMAN = 5; public static final int LIST_TYPE_UNKNOWN = -1; /* unknown type */ public static final int LIST_TYPE_BASE = 1000; /* BASE value to subtract to get RTF Value if above base*/ public static final int LIST_TYPE_ARABIC = 1000; /* 0 Arabic (1, 2, 3) */ public static final int LIST_TYPE_UPPERCASE_ROMAN_NUMERAL = 1001; /* 1 Uppercase Roman numeral (I, II, III) */ public static final int LIST_TYPE_LOWERCASE_ROMAN_NUMERAL = 1002; /* 2 Lowercase Roman numeral (i, ii, iii)*/ public static final int LIST_TYPE_UPPERCASE_LETTER = 1003; /* 3 Uppercase letter (A, B, C)*/ public static final int LIST_TYPE_LOWERCASE_LETTER = 1004; /* 4 Lowercase letter (a, b, c)*/ public static final int LIST_TYPE_ORDINAL_NUMBER = 1005; /* 5 Ordinal number (1st, 2nd, 3rd)*/ public static final int LIST_TYPE_CARDINAL_TEXT_NUMBER = 1006; /* 6 Cardinal text number (One, Two Three)*/ public static final int LIST_TYPE_ORDINAL_TEXT_NUMBER = 1007; /* 7 Ordinal text number (First, Second, Third)*/ public static final int LIST_TYPE_ARABIC_LEADING_ZERO = 1022; /* 22 Arabic with leading zero (01, 02, 03, ..., 10, 11)*/ public static final int LIST_TYPE_BULLET = 1023; /* 23 Bullet (no number at all)*/ public static final int LIST_TYPE_NO_NUMBER = 1255; /* 255 No number */ /* 10 Kanji numbering without the digit character (*dbnum1) 11 Kanji numbering with the digit character (*dbnum2) 12 46 phonetic katakana characters in "aiueo" order (*aiueo) 13 46 phonetic katakana characters in "iroha" order (*iroha) 14 Double-byte character 15 Single-byte character 16 Kanji numbering 3 (*dbnum3) 17 Kanji numbering 4 (*dbnum4) 18 Circle numbering (*circlenum) 19 Double-byte Arabic numbering 20 46 phonetic double-byte katakana characters (*aiueo*dbchar) 21 46 phonetic double-byte katakana characters (*iroha*dbchar) 22 Arabic with leading zero (01, 02, 03, ..., 10, 11) 24 Korean numbering 2 (*ganada) 25 Korean numbering 1 (*chosung) 26 Chinese numbering 1 (*gb1) 27 Chinese numbering 2 (*gb2) 28 Chinese numbering 3 (*gb3) 29 Chinese numbering 4 (*gb4) 30 Chinese Zodiac numbering 1 (* zodiac1) 31 Chinese Zodiac numbering 2 (* zodiac2) 32 Chinese Zodiac numbering 3 (* zodiac3) 33 Taiwanese double-byte numbering 1 34 Taiwanese double-byte numbering 2 35 Taiwanese double-byte numbering 3 36 Taiwanese double-byte numbering 4 37 Chinese double-byte numbering 1 38 Chinese double-byte numbering 2 39 Chinese double-byte numbering 3 40 Chinese double-byte numbering 4 41 Korean double-byte numbering 1 42 Korean double-byte numbering 2 43 Korean double-byte numbering 3 44 Korean double-byte numbering 4 45 Hebrew non-standard decimal 46 Arabic Alif Ba Tah 47 Hebrew Biblical standard 48 Arabic Abjad style 255 No number */ /** * Whether this RtfList is numbered */ private int listType = LIST_TYPE_UNKNOWN; /** * The text to use as the bullet character */ private String bulletCharacter = "\u00b7"; /** * @since 2.1.4 */ private Chunk bulletChunk = null; /** * The number to start counting at */ private int listStartAt = 1; /** * The level of this RtfListLevel */ private int listLevel = 0; /** * The first indentation of this RtfList */ private int firstIndent = 0; /** * The left indentation of this RtfList */ private int leftIndent = 0; /** * The right indentation of this RtfList */ private int rightIndent = 0; /** * The symbol indentation of this RtfList */ private int symbolIndent = 0; /** * Flag to indicate if the tentative control word should be emitted. */ private boolean isTentative = true; /** * Flag to indicate if the levellegal control word should be emitted. * true if any list numbers from previous levels should be converted to Arabic numbers; * false if they should be left with the format specified by their own level definition. */ private boolean isLegal = false; /** * Does the list restart numbering each time a super ordinate level is incremented */ private int listNoRestart = 0; public static final int LIST_LEVEL_FOLLOW_TAB = 0; public static final int LIST_LEVEL_FOLLOW_SPACE = 1; public static final int LIST_LEVEL_FOLLOW_NOTHING = 2; private int levelFollowValue = LIST_LEVEL_FOLLOW_TAB; /** * The alignment of this RtfList */ private int alignment = Element.ALIGN_LEFT; /** * Which picture bullet from the \listpicture destination should be applied */ private int levelPicture = -1; private int levelTextNumber = 0; /** * The RtfFont for numbered lists */ private RtfFont fontNumber; /** * The RtfFont for bulleted lists */ private RtfFont fontBullet; private int templateID = -1; private RtfListLevel listLevelParent = null; /** * Parent list object */ private RtfList parent = null; public RtfListLevel(RtfDocument doc) { super(doc); templateID = document.getRandomInt(); setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0)))); setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0))); } public RtfListLevel(RtfDocument doc, RtfList parent) { super(doc); this.parent = parent; templateID = document.getRandomInt(); setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0)))); setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0))); } public RtfListLevel(RtfListLevel ll) { super(ll.document); templateID = document.getRandomInt(); this.alignment = ll.alignment; this.bulletCharacter = ll.bulletCharacter; this.firstIndent = ll.firstIndent; this.fontBullet = ll.fontBullet; this.fontNumber = ll.fontNumber; this.inHeader = ll.inHeader; this.inTable = ll.inTable; this.leftIndent = ll.leftIndent; this.listLevel = ll.listLevel; this.listNoRestart = ll.listNoRestart; this.listStartAt = ll.listStartAt; this.listType = ll.listType; this.parent = ll.parent; this.rightIndent = ll.rightIndent; this.symbolIndent = ll.symbolIndent; } /** * @return the listNoRestart */ public int getListNoRestart() { return listNoRestart; } /** * @param listNoRestart the listNoRestart to set */ public void setListNoRestart(int listNoRestart) { this.listNoRestart = listNoRestart; } /** * @return the alignment */ public int getAlignment() { return alignment; } /** * @param alignment the alignment to set */ public void setAlignment(int alignment) { this.alignment = alignment; } public void writeDefinition(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(LIST_LEVEL); result.write(LIST_LEVEL_TYPE); switch(this.listType) { case LIST_TYPE_BULLET : result.write(intToByteArray(23)); break; case LIST_TYPE_NUMBERED : result.write(intToByteArray(0)); break; case LIST_TYPE_UPPER_LETTERS : result.write(intToByteArray(3)); break; case LIST_TYPE_LOWER_LETTERS : result.write(intToByteArray(4)); break; case LIST_TYPE_UPPER_ROMAN : result.write(intToByteArray(1)); break; case LIST_TYPE_LOWER_ROMAN : result.write(intToByteArray(2)); break; /* New types */ case LIST_TYPE_ARABIC : result.write(intToByteArray(0)); break; case LIST_TYPE_UPPERCASE_ROMAN_NUMERAL : result.write(intToByteArray(1)); break; case LIST_TYPE_LOWERCASE_ROMAN_NUMERAL : result.write(intToByteArray(2)); break; case LIST_TYPE_UPPERCASE_LETTER : result.write(intToByteArray(3)); break; case LIST_TYPE_ORDINAL_NUMBER : result.write(intToByteArray(4)); break; case LIST_TYPE_CARDINAL_TEXT_NUMBER : result.write(intToByteArray(5)); break; case LIST_TYPE_ORDINAL_TEXT_NUMBER : result.write(intToByteArray(6)); break; case LIST_TYPE_LOWERCASE_LETTER : result.write(intToByteArray(7)); break; case LIST_TYPE_ARABIC_LEADING_ZERO : result.write(intToByteArray(22)); break; case LIST_TYPE_NO_NUMBER : result.write(intToByteArray(255)); break; default: // catch all for other unsupported types if(this.listType >= RtfListLevel.LIST_TYPE_BASE) { result.write(intToByteArray(this.listType - RtfListLevel.LIST_TYPE_BASE)); } break; } result.write(LIST_LEVEL_TYPE_NEW); switch(this.listType) { case LIST_TYPE_BULLET : result.write(intToByteArray(23)); break; case LIST_TYPE_NUMBERED : result.write(intToByteArray(0)); break; case LIST_TYPE_UPPER_LETTERS : result.write(intToByteArray(3)); break; case LIST_TYPE_LOWER_LETTERS : result.write(intToByteArray(4)); break; case LIST_TYPE_UPPER_ROMAN : result.write(intToByteArray(1)); break; case LIST_TYPE_LOWER_ROMAN : result.write(intToByteArray(2)); break; /* New types */ case LIST_TYPE_ARABIC : result.write(intToByteArray(0)); break; case LIST_TYPE_UPPERCASE_ROMAN_NUMERAL : result.write(intToByteArray(1)); break; case LIST_TYPE_LOWERCASE_ROMAN_NUMERAL : result.write(intToByteArray(2)); break; case LIST_TYPE_UPPERCASE_LETTER : result.write(intToByteArray(3)); break; case LIST_TYPE_ORDINAL_NUMBER : result.write(intToByteArray(4)); break; case LIST_TYPE_CARDINAL_TEXT_NUMBER : result.write(intToByteArray(5)); break; case LIST_TYPE_ORDINAL_TEXT_NUMBER : result.write(intToByteArray(6)); break; case LIST_TYPE_LOWERCASE_LETTER : result.write(intToByteArray(7)); break; case LIST_TYPE_ARABIC_LEADING_ZERO : result.write(intToByteArray(22)); break; case LIST_TYPE_NO_NUMBER : result.write(intToByteArray(255)); break; default: // catch all for other unsupported types if(this.listType >= RtfListLevel.LIST_TYPE_BASE) { result.write(intToByteArray(this.listType - RtfListLevel.LIST_TYPE_BASE)); } break; } result.write(LIST_LEVEL_ALIGNMENT); result.write(intToByteArray(0)); result.write(LIST_LEVEL_ALIGNMENT_NEW); result.write(intToByteArray(0)); result.write(LIST_LEVEL_FOLOW); result.write(intToByteArray(levelFollowValue)); result.write(LIST_LEVEL_START_AT); result.write(intToByteArray(this.listStartAt)); if(this.isTentative) { result.write(LIST_LEVEL_TENTATIVE); } if(this.isLegal) { result.write(LIST_LEVEL_LEGAL); } result.write(LIST_LEVEL_SPACE); result.write(intToByteArray(0)); result.write(LIST_LEVEL_INDENT); result.write(intToByteArray(0)); if(levelPicture != -1) { result.write(LIST_LEVEL_PICTURE); result.write(intToByteArray(levelPicture)); } result.write(OPEN_GROUP); // { leveltext result.write(LIST_LEVEL_TEXT); result.write(LIST_LEVEL_TEMPLATE_ID); result.write(intToByteArray(this.templateID)); /* NEVER seperate the LEVELTEXT elements with a return in between * them or it will not fuction correctly! */ // TODO Needs to be rewritten to support 1-9 levels, not just simple single level if(this.listType != LIST_TYPE_BULLET) { result.write(LIST_LEVEL_STYLE_NUMBERED_BEGIN); if(this.levelTextNumber < 10) { result.write(intToByteArray(0)); } result.write(intToByteArray(this.levelTextNumber)); result.write(LIST_LEVEL_STYLE_NUMBERED_END); } else { result.write(LIST_LEVEL_STYLE_BULLETED_BEGIN); this.document.filterSpecialChar(result, this.bulletCharacter, false, false); result.write(LIST_LEVEL_STYLE_BULLETED_END); } result.write(CLOSE_GROUP); // } leveltext result.write(OPEN_GROUP); // { levelnumbers result.write(LIST_LEVEL_NUMBERS_BEGIN); if(this.listType != LIST_TYPE_BULLET) { result.write(LIST_LEVEL_NUMBERS_NUMBERED); } result.write(LIST_LEVEL_NUMBERS_END); result.write(CLOSE_GROUP);// { levelnumbers // write properties now result.write(RtfFontList.FONT_NUMBER); if(this.listType != LIST_TYPE_BULLET) { result.write(intToByteArray(fontNumber.getFontNumber())); } else { result.write(intToByteArray(fontBullet.getFontNumber())); } result.write(DocWriter.getISOBytes("\\cf")); // document.getDocumentHeader().getColorNumber(new RtfColor(this.document,this.getFontNumber().getColor())); result.write(intToByteArray(document.getDocumentHeader().getColorNumber(new RtfColor(this.document,this.getFontNumber().getColor())))); writeIndentation(result); result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } /** * unused */ public void writeContent(final OutputStream result) throws IOException { } /** * Writes only the list number and list level number. * * @param result The OutputStream to write to * @throws IOException On i/o errors. */ protected void writeListNumbers(final OutputStream result) throws IOException { if(listLevel > 0) { result.write(RtfList.LIST_LEVEL_NUMBER); result.write(intToByteArray(listLevel)); } } /** * Write the indentation values for this RtfList. * * @param result The OutputStream to write to. * @throws IOException On i/o errors. */ public void writeIndentation(final OutputStream result) throws IOException { result.write(LIST_LEVEL_FIRST_INDENT); result.write(intToByteArray(firstIndent)); result.write(RtfParagraphStyle.INDENT_LEFT); result.write(intToByteArray(leftIndent)); result.write(RtfParagraphStyle.INDENT_RIGHT); result.write(intToByteArray(rightIndent)); result.write(LIST_LEVEL_SYMBOL_INDENT); result.write(intToByteArray(this.leftIndent)); } /** * Writes the initialization part of the RtfList * * @param result The OutputStream to write to * @throws IOException On i/o errors. */ public void writeListBeginning(final OutputStream result) throws IOException { result.write(RtfParagraph.PARAGRAPH_DEFAULTS); if(this.inTable) { result.write(RtfParagraph.IN_TABLE); } switch (this.alignment) { case Element.ALIGN_LEFT: result.write(RtfParagraphStyle.ALIGN_LEFT); break; case Element.ALIGN_RIGHT: result.write(RtfParagraphStyle.ALIGN_RIGHT); break; case Element.ALIGN_CENTER: result.write(RtfParagraphStyle.ALIGN_CENTER); break; case Element.ALIGN_JUSTIFIED: case Element.ALIGN_JUSTIFIED_ALL: result.write(RtfParagraphStyle.ALIGN_JUSTIFY); break; } writeIndentation(result); result.write(RtfFont.FONT_SIZE); result.write(intToByteArray(fontNumber.getFontSize() * 2)); if(this.symbolIndent > 0) { result.write(LIST_LEVEL_SYMBOL_INDENT); result.write(intToByteArray(this.leftIndent)); } } /** * Correct the indentation of this level */ protected void correctIndentation() { if(this.listLevelParent != null) { this.leftIndent = this.leftIndent + this.listLevelParent.getLeftIndent() + this.listLevelParent.getFirstIndent(); } } /** * Gets the list level of this RtfList * * @return Returns the list level. */ public int getListLevel() { return listLevel; } /** * Sets the list level of this RtfList. * * @param listLevel The list level to set. */ public void setListLevel(int listLevel) { this.listLevel = listLevel; } public String getBulletCharacter() { return this.bulletCharacter; } /** * @return the listStartAt */ public int getListStartAt() { return listStartAt; } /** * @param listStartAt the listStartAt to set */ public void setListStartAt(int listStartAt) { this.listStartAt = listStartAt; } /** * @return the firstIndent */ public int getFirstIndent() { return firstIndent; } /** * @param firstIndent the firstIndent to set */ public void setFirstIndent(int firstIndent) { this.firstIndent = firstIndent; } /** * @return the leftIndent */ public int getLeftIndent() { return leftIndent; } /** * @param leftIndent the leftIndent to set */ public void setLeftIndent(int leftIndent) { this.leftIndent = leftIndent; } /** * @return the rightIndent */ public int getRightIndent() { return rightIndent; } /** * @param rightIndent the rightIndent to set */ public void setRightIndent(int rightIndent) { this.rightIndent = rightIndent; } /** * @return the symbolIndent */ public int getSymbolIndent() { return symbolIndent; } /** * @param symbolIndent the symbolIndent to set */ public void setSymbolIndent(int symbolIndent) { this.symbolIndent = symbolIndent; } /** * @return the parent */ public RtfList getParent() { return parent; } /** * @param parent the parent to set */ public void setParent(RtfList parent) { this.parent = parent; } /** * @param bulletCharacter the bulletCharacter to set */ public void setBulletCharacter(String bulletCharacter) { this.bulletCharacter = bulletCharacter; } /** * * @param bulletCharacter * @since 2.1.4 */ public void setBulletChunk(Chunk bulletCharacter) { this.bulletChunk = bulletCharacter; } /** * @return the listType */ public int getListType() { return listType; } /** * @param listType the listType to set */ public void setListType(int listType) { this.listType = listType; } /** * set the bullet font * @param f */ public void setBulletFont(Font f) { this.fontBullet = new RtfFont(document, f); } /** * @return the fontNumber */ public RtfFont getFontNumber() { return fontNumber; } /** * @param fontNumber the fontNumber to set */ public void setFontNumber(RtfFont fontNumber) { this.fontNumber = fontNumber; } /** * @return the fontBullet */ public RtfFont getFontBullet() { return fontBullet; } /** * @param fontBullet the fontBullet to set */ public void setFontBullet(RtfFont fontBullet) { this.fontBullet = fontBullet; } /** * @return the isTentative */ public boolean isTentative() { return isTentative; } /** * @param isTentative the isTentative to set */ public void setTentative(boolean isTentative) { this.isTentative = isTentative; } /** * @return the isLegal */ public boolean isLegal() { return isLegal; } /** * @param isLegal the isLegal to set */ public void setLegal(boolean isLegal) { this.isLegal = isLegal; } /** * @return the levelFollowValue */ public int getLevelFollowValue() { return levelFollowValue; } /** * @param levelFollowValue the levelFollowValue to set */ public void setLevelFollowValue(int levelFollowValue) { this.levelFollowValue = levelFollowValue; } /** * @return the levelTextNumber */ public int getLevelTextNumber() { return levelTextNumber; } /** * @param levelTextNumber the levelTextNumber to set */ public void setLevelTextNumber(int levelTextNumber) { this.levelTextNumber = levelTextNumber; } /** * @return the listLevelParent */ public RtfListLevel getListLevelParent() { return listLevelParent; } /** * @param listLevelParent the listLevelParent to set */ public void setListLevelParent(RtfListLevel listLevelParent) { this.listLevelParent = listLevelParent; } } src/rtf/com/lowagie/text/rtf/list/RtfListTable.java100644 0 0 15637 11106243445 17764 0ustar 0 0 /* * $Id: RtfListTable.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2008 Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.list; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfListTable manages all RtfList objects and list override table in one RtfDocument. * * @version $Id: RtfListTable.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) */ public class RtfListTable extends RtfElement implements RtfExtendedElement { /** * Constant for the list table */ private static final byte[] LIST_TABLE = DocWriter.getISOBytes("\\*\\listtable"); /** * Constant for the list override table */ private static final byte[] LIST_OVERRIDE_TABLE = DocWriter.getISOBytes("\\*\\listoverridetable"); /** * Constant for the list override */ private static final byte[] LIST_OVERRIDE = DocWriter.getISOBytes("\\listoverride"); /** * Constant for the list override count */ private static final byte[] LIST_OVERRIDE_COUNT = DocWriter.getISOBytes("\\listoverridecount"); /** * The RtfList lists managed by this RtfListTable */ private ArrayList lists; /** * The RtfPictureList lists managed by this RtfListTable */ private ArrayList picturelists; /** * Constructs a RtfListTable for a RtfDocument * * @param doc The RtfDocument this RtfListTable belongs to */ public RtfListTable(RtfDocument doc) { super(doc); this.lists = new ArrayList(); this.picturelists = new ArrayList(); } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Writes the list and list override tables. */ public void writeDefinition(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(LIST_TABLE); this.document.outputDebugLinebreak(result); for(int i = 0; i < picturelists.size(); i++) { RtfPictureList l = (RtfPictureList)picturelists.get(i); // l.setID(document.getRandomInt()); l.writeDefinition(result); this.document.outputDebugLinebreak(result); } for(int i = 0; i < lists.size(); i++) { RtfList l = (RtfList)lists.get(i); l.setID(document.getRandomInt()); l.writeDefinition(result); this.document.outputDebugLinebreak(result); } result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); result.write(OPEN_GROUP); result.write(LIST_OVERRIDE_TABLE); this.document.outputDebugLinebreak(result); // list override index values are 1-based, not 0. // valid list override index values \ls are 1 to 2000. // if there are more then 2000 lists, the result is undefined. for(int i = 0; i < lists.size(); i++) { result.write(OPEN_GROUP); result.write(LIST_OVERRIDE); result.write(RtfList.LIST_ID); result.write(intToByteArray( ((RtfList) lists.get(i)).getID() )); result.write(LIST_OVERRIDE_COUNT); result.write(intToByteArray(0)); // is this correct? Spec says valid values are 1 or 9. result.write(RtfList.LIST_NUMBER); result.write(intToByteArray( ((RtfList) lists.get(i)).getListNumber()) ); result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } /** * Gets the id of the specified RtfList. If the RtfList is not yet in the * list of RtfList, then it is added. * * @param list The RtfList for which to get the id. * @return The id of the RtfList. */ public int getListNumber(RtfList list) { if(lists.contains(list)) { return lists.indexOf(list); } else { lists.add(list); return lists.size(); } } /** * Remove a RtfList from the list of RtfList * * @param list The RtfList to remove. */ public void freeListNumber(RtfList list) { int i = lists.indexOf(list); if(i >= 0) { lists.remove(i); } } } src/rtf/com/lowagie/text/rtf/list/RtfPictureList.java100644 0 0 7711 11106243445 20322 0ustar 0 0 /* * $Id: RtfPictureList.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2008 Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.list; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfPictureList2 manages the pictures for lists. * * @version $Id: RtfPictureList.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.3 */ public class RtfPictureList extends RtfElement implements RtfExtendedElement { /** * Constant for determining which picture bullet from the \listpicture destination that should be applied. */ private static final byte[] LIST_LEVEL_PICTURE = DocWriter.getISOBytes("\\*\\listpicture"); public RtfPictureList(RtfDocument doc) { super(doc); } /* (non-Javadoc) * @see com.lowagie.text.rtf.RtfElement#writeContent(java.io.OutputStream) */ public void writeContent(OutputStream out) throws IOException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see com.lowagie.text.rtf.RtfExtendedElement#writeDefinition(java.io.OutputStream) */ public void writeDefinition(final OutputStream result) throws IOException { // TODO Auto-generated method stub result.write(OPEN_GROUP); result.write(LIST_LEVEL_PICTURE); // if there are elements, write the \shppictlist here result.write(CLOSE_GROUP); } } src/rtf/com/lowagie/text/rtf/parser/RtfImportMappings.java100644 0 0 12646 11036112746 21371 0ustar 0 0 /* * $Id: RtfImportMappings.java 3440 2008-05-25 18:16:48Z howard_s $ * * Copyright 2006 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser; import java.awt.Color; import java.util.HashMap; /** * The RtfImportMappings make it possible to define font * and color mappings when using the RtfWriter2.importRtfFragment * method. This is necessary, because a RTF fragment does not * contain font or color information, just references to the * font and color tables.

      * * The font mappings are fontNr -> fontName and the color * mappigns are colorNr -> Color. * * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.0 */ public class RtfImportMappings { /** * The fontNr to fontName mappings. */ private HashMap fontMappings = null; /** * The colorNr to Color mappings. */ private HashMap colorMappings = null; /** * The listNr to List mappings. */ private HashMap listMappings = null; /** * The sytlesheetListNr to Stylesheet mappings. */ private HashMap stylesheetListMappings = null; /** * Constructs a new RtfImportMappings initialising the mappings. */ public RtfImportMappings() { this.fontMappings = new HashMap(); this.colorMappings = new HashMap(); this.listMappings = new HashMap(); this.stylesheetListMappings = new HashMap(); } /** * Add a font to the list of mappings. * * @param fontNr The font number. * @param fontName The font name. */ public void addFont(String fontNr, String fontName) { this.fontMappings.put(fontNr, fontName); } /** * Add a color to the list of mappings. * * @param colorNr The color number. * @param color The Color. */ public void addColor(String colorNr, Color color) { this.colorMappings.put(colorNr, color); } /** * Add a List to the list of mappings. * * @param listNr The List number. * @param list The List. */ public void addList(String listNr, String list) { this.listMappings.put(listNr, list); } /** * Add a Stylesheet List to the list of mappings. * * @param stylesheetListNr The Stylesheet List number. * @param list The StylesheetList. */ public void addStylesheetList(String stylesheetListNr, String list) { this.stylesheetListMappings.put(stylesheetListNr, list); } /** * Gets the list of font mappings. String to String. * * @return The font mappings. */ public HashMap getFontMappings() { return this.fontMappings; } /** * Gets the list of color mappings. String to Color. * * @return The color mappings. */ public HashMap getColorMappings() { return this.colorMappings; } /** * Gets the list of List mappings. * * @return The List mappings. */ public HashMap getListMappings() { return this.listMappings; } /** * Gets the list of Stylesheet mappings. . * * @return The Stylesheet List mappings. */ public HashMap getStylesheetListMappings() { return this.stylesheetListMappings; } } src/rtf/com/lowagie/text/rtf/parser/RtfImportMgr.java100644 0 0 24432 11036112746 20334 0ustar 0 0 /* * $Id: RtfImportMgr.java 3456 2008-05-26 15:26:57Z howard_s $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser; import java.awt.Color; import java.util.HashMap; import com.lowagie.text.Document; import com.lowagie.text.List; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.list.RtfList; import com.lowagie.text.rtf.style.RtfColor; import com.lowagie.text.rtf.style.RtfFont; /** * The RtfImportHeader stores the document header information from * an RTF document that is being imported. Currently font and * color settings are stored. The RtfImportHeader maintains a mapping * from font and color numbers from the imported RTF document to * the RTF document that is the target of the import. This guarantees * that the merged document has the correct font and color settings. * It also handles other list based items that need mapping, for example * stylesheets and lists. * * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.0 */ public class RtfImportMgr { //TODO: Add list, stylesheet, info, etc. mappings /** * The HashMap storing the font number mappings. */ private HashMap importFontMapping = null; /** * The HashMap storing the color number mappings. */ private HashMap importColorMapping = null; /** * The HashMap storing the Stylesheet List number mappings. */ private HashMap importStylesheetListMapping = null; /** * The HashMap storing the List number mappings. */ private HashMap importListMapping = null; /** * The RtfDocument to get font and color numbers from. */ private RtfDocument rtfDoc = null; /** * The Document. * Used for conversions, but not imports. */ private Document doc = null; /** * Constructs a new RtfImportHeader. * * @param rtfDoc The RtfDocument to get font and color numbers from. */ public RtfImportMgr(RtfDocument rtfDoc, Document doc) { this.rtfDoc = rtfDoc; this.doc = doc; this.importFontMapping = new HashMap(); this.importColorMapping = new HashMap(); this.importStylesheetListMapping = new HashMap(); this.importListMapping = new HashMap(); } /** * Imports a font. The font name is looked up in the RtfDocumentHeader and * then the mapping from original font number to actual font number is added. * * @param fontNr The original font number. * @param fontName The font name to look up. */ public boolean importFont(String fontNr, String fontName) { RtfFont rtfFont = new RtfFont(fontName); rtfFont.setRtfDocument(this.rtfDoc); this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont))); return true; } /** * Imports a font. The font name is looked up in the RtfDocumentHeader and * then the mapping from original font number to actual font number is added. * * @param fontNr The original font number. * @param fontName The font name to look up. * @param charset The character set to use for the font. */ public boolean importFont(String fontNr, String fontName, int charset) { RtfFont rtfFont = new RtfFont(fontName); if(charset>= 0) rtfFont.setCharset(charset); rtfFont.setRtfDocument(this.rtfDoc); this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont))); return true; } /** * Imports a font. The font name is looked up in the RtfDocumentHeader and * then the mapping from original font number to actual font number is added. * * @param fontNr The original font number. * @param fontName The font name to look up. * @param charset The character set to use for the font. */ public boolean importFont(String fontNr, String fontName, String fontFamily, int charset) { RtfFont rtfFont = new RtfFont(fontName); if(charset>= 0) rtfFont.setCharset(charset); if(fontFamily != null && fontFamily.length() > 0) rtfFont.setFamily(fontFamily); rtfFont.setRtfDocument(this.rtfDoc); this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont))); return true; } /** * Performs the mapping from the original font number to the actual * font number in the resulting RTF document. If the font number was not * seen during import (thus no mapping) then 0 is returned, guaranteeing * that the font number is always valid. * * @param fontNr The font number to map. * @return The mapped font number. */ public String mapFontNr(String fontNr) { if(this.importFontMapping.containsKey(fontNr)) { return (String) this.importFontMapping.get(fontNr); } else { return "0"; } } /** * Imports a color value. The color number for the color defined * by its red, green and blue values is determined and then the * resulting mapping is added. * * @param colorNr The original color number. * @param color The color to import. */ public void importColor(String colorNr, Color color) { RtfColor rtfColor = new RtfColor(this.rtfDoc, color); this.importColorMapping.put(colorNr, Integer.toString(rtfColor.getColorNumber())); } /** * Performs the mapping from the original font number to the actual font * number used in the RTF document. If the color number was not * seen during import (thus no mapping) then 0 is returned, guaranteeing * that the color number is always valid. * * @param colorNr The color number to map. * @return The mapped color number */ public String mapColorNr(String colorNr) { if(this.importColorMapping.containsKey(colorNr)) { return (String) this.importColorMapping.get(colorNr); } else { return "0"; } } /** * Imports a List value. The List number for the List defined * is determined and then the resulting mapping is added. */ public void importList(String origListNr, String newListNr) { this.importListMapping.put(origListNr, newListNr); } /** * Performs the mapping from the original list number to the actual * list number in the resulting RTF document. If the list number was not * seen during import (thus no mapping) then null is returned. There is no * guarantee of a valid list number. */ public String mapListNr(String listNr) { if(this.importListMapping.containsKey(listNr)) { return (String) this.importListMapping.get(listNr); } else { return null; } } /** * Imports a stylesheet list value. The stylesheet number for the stylesheet defined * is determined and then the resulting mapping is added. */ public boolean importStylesheetList(String listNr, List listIn) { RtfList rtfList = new RtfList(this.rtfDoc, listIn); rtfList.setRtfDocument(this.rtfDoc); // TODO HGS - Finish implementation of import //this.importStylesheetListMapping.put(listNr, Integer.toString(this.rtfDoc.getDocumentHeader().getRtfParagraphStyle(styleName)(rtfList))); return true; } /** * Performs the mapping from the original stylesheet number to the actual * stylesheet number in the resulting RTF document. If the stylesheet number was not * seen during import (thus no mapping) then 0 is returned, guaranteeing * that the stylesheet number is always valid. */ public String mapStylesheetListNr(String listNr) { if(this.importStylesheetListMapping.containsKey(listNr)) { return (String) this.importStylesheetListMapping.get(listNr); } else { return "0"; } } } src/rtf/com/lowagie/text/rtf/parser/RtfParser.java100644 0 0 147153 11106243445 17675 0ustar 0 0 /* * $Id: RtfParser.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser; import java.awt.Color; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.EventListener; import java.util.Iterator; import java.util.Stack; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.List; import com.lowagie.text.rtf.direct.RtfDirectContent; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordListener; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordMgr; import com.lowagie.text.rtf.parser.destinations.RtfDestination; import com.lowagie.text.rtf.parser.destinations.RtfDestinationMgr; /** * The RtfParser allows the importing of RTF documents or * RTF document fragments. The RTF document or fragment is tokenised, * font and color definitions corrected and then added to * the document being written. * * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfParser { /** * Debugging flag. */ private static final boolean debugParser = false; // DEBUG Files are unlikely to be read by any reader! private String logFile = null; private boolean logging = false; private boolean logAppend = false; /** * The iText element to add the RTF document to. * @since 2.1.3 */ private Element elem = null; /** * The iText document to add the RTF document to. */ private Document document = null; /** * The RtfDocument to add the RTF document or fragment to. */ private RtfDocument rtfDoc = null; /** * The RtfKeywords that creates and handles keywords that are implemented. */ private RtfCtrlWordMgr rtfKeywordMgr = null; /** * The RtfImportHeader to store imported font and color mappings in. */ private RtfImportMgr importMgr = null; /** * The RtfDestinationMgr object to manage destinations. */ private RtfDestinationMgr destinationMgr = null; /** * Stack for saving states for groups */ private Stack stackState = null; /** * The current parser state. */ private RtfParserState currentState = null; /** * The pushback reader to read the input stream. */ private PushbackInputStream pbReader = null; /** * Conversion type. Identifies if we are doing in import or a convert. */ private int conversionType = TYPE_IMPORT_FULL; /* * Bitmapping: * * 0111 1111 1111 1111 = Unkown state * 0xxx xxxx xxxx xxxx = In Header * 1xxx xxxx xxxx xxxx = In Document * 2xxx xxxx xxxx xxxx = Reserved * 4xxx xxxx xxxx xxxx = Other * 8xxx xxxx xxxx xxxx = Errors */ /* * Header state values */ /** * Currently the RTF document header is being parsed. */ public static final int PARSER_IN_HEADER = (0x0 << 28) | 0x000000; /** * Currently the RTF charset is being parsed. */ public static final int PARSER_IN_CHARSET = PARSER_IN_HEADER | 0x000001; /** * Currently the RTF deffont is being parsed. */ public static final int PARSER_IN_DEFFONT = PARSER_IN_HEADER | 0x000002; /** * Currently the RTF font table is being parsed. */ public static final int PARSER_IN_FONT_TABLE = PARSER_IN_HEADER | 0x000003; /** * Currently a RTF font table info element is being parsed. */ public static final int PARSER_IN_FONT_TABLE_INFO = PARSER_IN_HEADER | 0x000004; /** * Currently the RTF filetbl is being parsed. */ public static final int PARSER_IN_FILE_TABLE = PARSER_IN_HEADER | 0x000005; /** * Currently the RTF color table is being parsed. */ public static final int PARSER_IN_COLOR_TABLE = PARSER_IN_HEADER | 0x000006; /** * Currently the RTF stylesheet is being parsed. */ public static final int PARSER_IN_STYLESHEET = PARSER_IN_HEADER | 0x000007; /** * Currently the RTF listtables is being parsed. */ public static final int PARSER_IN_LIST_TABLE = PARSER_IN_HEADER | 0x000008; /** * Currently the RTF listtable override is being parsed. */ public static final int PARSER_IN_LISTOVERRIDE_TABLE = PARSER_IN_HEADER | 0x000009; /** * Currently the RTF revtbl is being parsed. */ public static final int PARSER_IN_REV_TABLE = PARSER_IN_HEADER | 0x00000A; /** * Currently the RTF rsidtable is being parsed. */ public static final int PARSER_IN_RSID_TABLE = PARSER_IN_HEADER | 0x0000B; /** * Currently the RTF generator is being parsed. */ public static final int PARSER_IN_GENERATOR = PARSER_IN_HEADER | 0x00000C; /** * Currently the RTF Paragraph group properties Table (word 2002) */ public static final int PARSER_IN_PARAGRAPH_TABLE = PARSER_IN_HEADER | 0x00000E; /** * Currently the RTF Old Properties. */ public static final int PARSER_IN_OLDCPROPS = PARSER_IN_HEADER | 0x00000F; /** * Currently the RTF Old Properties. */ public static final int PARSER_IN_OLDPPROPS = PARSER_IN_HEADER | 0x000010; /** * Currently the RTF Old Properties. */ public static final int PARSER_IN_OLDTPROPS = PARSER_IN_HEADER | 0x000012; /** * Currently the RTF Old Properties. */ public static final int PARSER_IN_OLDSPROPS = PARSER_IN_HEADER | 0x000013; /** * Currently the RTF User Protection Information. */ public static final int PARSER_IN_PROT_USER_TABLE = PARSER_IN_HEADER | 0x000014; /** * Currently the Latent Style and Formatting usage restrictions */ public static final int PARSER_IN_LATENTSTYLES = PARSER_IN_HEADER | 0x000015; public static final int PARSER_IN_PARAGRAPH_GROUP_PROPERTIES =PARSER_IN_HEADER | 0x000016; /* * Document state values */ /** * Currently the RTF document content is being parsed. */ public static final int PARSER_IN_DOCUMENT = (0x2 << 28 ) | 0x000000; /** * Currently the RTF info group is being parsed. */ public static final int PARSER_IN_INFO_GROUP = PARSER_IN_DOCUMENT | 0x000001; public static final int PARSER_IN_UPR = PARSER_IN_DOCUMENT | 0x000002; /** * Currently a shppict control word is being parsed. */ public static final int PARSER_IN_SHPPICT = PARSER_IN_DOCUMENT | 0x000010; //16 /** * Currently a pict control word is being parsed. */ public static final int PARSER_IN_PICT = PARSER_IN_DOCUMENT | 0x000011; //17 /** * Currently a picprop control word is being parsed. */ public static final int PARSER_IN_PICPROP = PARSER_IN_DOCUMENT | 0x000012; //18 /** * Currently a blipuid control word is being parsed. */ public static final int PARSER_IN_BLIPUID = PARSER_IN_DOCUMENT | 0x000013; //19 /* other states */ /** * The parser is at the beginning or the end of the file. */ public static final int PARSER_STARTSTOP = (0x4 << 28)| 0x0001; /* ERRORS */ /** * Currently the parser is in an error state. */ public static final int PARSER_ERROR = (0x8 << 28) | 0x0000; /** * The parser reached the end of the file. */ public static final int PARSER_ERROR_EOF = PARSER_ERROR | 0x0001; /** * Currently the parser is in an unknown state. */ public static final int PARSER_IN_UNKNOWN = PARSER_ERROR | 0x0FFFFFFF; /** * Conversion type is unknown */ public static final int TYPE_UNIDENTIFIED = -1; /** * Conversion type is an import. Uses direct content to add everything. * This is what the original import does. */ public static final int TYPE_IMPORT_FULL = 0; /** * Conversion type is an import of a partial file/fragment. Uses direct content to add everything. */ public static final int TYPE_IMPORT_FRAGMENT = 1; /** * Conversion type is a conversion. This uses the document (not rtfDoc) to add * all the elements making it a different supported documents depending on the writer used. */ public static final int TYPE_CONVERT = 2; /** * Conversion type to import a document into an element. i.e. Chapter, Section, Table Cell, etc. * @since 2.1.4 */ public static final int TYPE_IMPORT_INTO_ELEMENT = 3; /** * Destination is normal. Text is processed. */ public static final int DESTINATION_NORMAL = 0; /** * Destination is skipping. Text is ignored. */ public static final int DESTINATION_SKIP = 1; //////////////////////////////////// TOKENISE VARIABLES /////////////////// /* * State flags use 4/28 bitmask. * First 4 bits (nibble) indicates major state. Used for unknown and error * Last 28 bits indicates the value; */ /** * The RtfTokeniser is in its ground state. Any token may follow. */ public static final int TOKENISER_NORMAL = 0x00000000; /** * The last token parsed was a slash. */ public static final int TOKENISER_SKIP_BYTES = 0x00000001; /** * The RtfTokeniser is currently tokenising a control word. */ public static final int TOKENISER_SKIP_GROUP = 0x00000002; /** * The RtfTokeniser is currently reading binary stream. */ public static final int TOKENISER_BINARY= 0x00000003; /** * The RtfTokeniser is currently reading hex data. */ public static final int TOKENISER_HEX= 0x00000004; /** * The RtfTokeniser ignore result */ public static final int TOKENISER_IGNORE_RESULT= 0x00000005; /** * The RtfTokeniser is currently in error state */ public static final int TOKENISER_STATE_IN_ERROR = 0x80000000; // 1000 0000 0000 0000 0000 0000 0000 0000 /** * The RtfTokeniser is currently in an unkown state */ public static final int TOKENISER_STATE_IN_UNKOWN = 0xFF000000; // 1111 0000 0000 0000 0000 0000 0000 0000 /** * The current group nesting level. */ private int groupLevel = 0; /** * The current document group nesting level. Used for fragments. */ private int docGroupLevel = 0; /** * When the tokeniser is Binary. */ private long binByteCount = 0; /** * When the tokeniser is set to skip bytes, binSkipByteCount is the number of bytes to skip. */ private long binSkipByteCount = 0; /** * When the tokeniser is set to skip to next group, this is the group indentifier to return to. */ private int skipGroupLevel = 0; //RTF parser error codes public static final int errOK =0; // Everything's fine! public static final int errStackUnderflow = -1; // Unmatched '}' public static final int errStackOverflow = -2; // Too many '{' -- memory exhausted public static final int errUnmatchedBrace = -3; // RTF ended during an open group. public static final int errInvalidHex = -4; // invalid hex character found in data public static final int errBadTable = -5; // RTF table (sym or prop) invalid public static final int errAssertion = -6; // Assertion failure public static final int errEndOfFile = -7; // End of file reached while reading RTF public static final int errCtrlWordNotFound = -8; // control word was not found //////////////////////////////////// TOKENISE VARIABLES /////////////////// //////////////////////////////////// STATS VARIABLES /////////////////// /** * Total bytes read. */ private long byteCount = 0; /** * Total control words processed. * * Contains both known and unknown. * * ctrlWordCount should equal * ctrlWrodHandlecCount + ctrlWordNotHandledCountctrlWordSkippedCount
      */ private long ctrlWordCount = 0; /** * Total { encountered as an open group token. */ private long openGroupCount = 0; /** * Total } encountered as a close group token. */ private long closeGroupCount = 0; /** * Total clear text characters processed. */ private long characterCount = 0; /** * Total control words recognized. */ private long ctrlWordHandledCount = 0; /** * Total control words not handled. */ private long ctrlWordNotHandledCount = 0; /** * Total control words skipped. */ private long ctrlWordSkippedCount = 0; /** * Total groups skipped. Includes { and } as a group. */ private long groupSkippedCount = 0; /** * Start time as a long. */ private long startTime = 0; /** * Stop time as a long. */ private long endTime = 0; /** * Start date as a date. */ private Date startDate = null; /** * End date as a date. */ private Date endDate = null; //////////////////////////////////// STATS VARIABLES /////////////////// /** * Last control word and parameter processed. */ private RtfCtrlWordData lastCtrlWordParam = null; /** The RtfCtrlWordListener. */ private ArrayList listeners = new ArrayList(); /** * Constructor * @param doc * @since 2.1.3 */ public RtfParser(Document doc) { this.document = doc; } /* ********* * READER * ***********/ /** * Imports a complete RTF document. * * @param readerIn * The Reader to read the RTF document from. * @param rtfDoc * The RtfDocument to add the imported document to. * @throws IOException On I/O errors. * @since 2.1.3 */ public void importRtfDocument(InputStream readerIn, RtfDocument rtfDoc) throws IOException { if(readerIn == null || rtfDoc == null) return; this.init(TYPE_IMPORT_FULL, rtfDoc, readerIn, this.document, null); this.setCurrentDestination(RtfDestinationMgr.DESTINATION_NULL); startDate = new Date(); startTime = System.currentTimeMillis(); this.groupLevel = 0; try { this.tokenise(); } catch (RuntimeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } endTime = System.currentTimeMillis(); endDate = new Date(); } /** * Imports a complete RTF document into an Element, i.e. Chapter, section, Table Cell, etc. * * @param elem The Element the document is to be imported into. * @param readerIn * The Reader to read the RTF document from. * @param rtfDoc * The RtfDocument to add the imported document to. * @throws IOException On I/O errors. * @since 2.1.4 */ public void importRtfDocumentIntoElement(Element elem, InputStream readerIn, RtfDocument rtfDoc) throws IOException { if(readerIn == null || rtfDoc == null || elem == null) return; this.init(TYPE_IMPORT_INTO_ELEMENT, rtfDoc, readerIn, this.document, elem); this.setCurrentDestination(RtfDestinationMgr.DESTINATION_NULL); startDate = new Date(); startTime = System.currentTimeMillis(); this.groupLevel = 0; try { this.tokenise(); } catch (RuntimeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } endTime = System.currentTimeMillis(); endDate = new Date(); } /** * Converts an RTF document to an iText document. * * Usage: Create a parser object and call this method with the input stream and the iText Document object * * @param readerIn * The Reader to read the RTF file from. * @param doc * The iText document that the RTF file is to be added to. * @throws IOException * On I/O errors. * @since 2.1.3 */ public void convertRtfDocument(InputStream readerIn, Document doc) throws IOException { if(readerIn == null || doc == null) return; this.init(TYPE_CONVERT, null, readerIn, doc, null); this.setCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT); startDate = new Date(); startTime = System.currentTimeMillis(); this.groupLevel = 0; this.tokenise(); endTime = System.currentTimeMillis(); endDate = new Date(); } /** * Imports an RTF fragment. * * @param readerIn * The Reader to read the RTF fragment from. * @param rtfDoc * The RTF document to add the RTF fragment to. * @param importMappings * The RtfImportMappings defining font and color mappings for the fragment. * @throws IOException * On I/O errors. * @since 2.1.3 */ public void importRtfFragment(InputStream readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) throws IOException { //public void importRtfFragment2(Reader readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) throws IOException { if(readerIn == null || rtfDoc == null || importMappings==null) return; this.init(TYPE_IMPORT_FRAGMENT, rtfDoc, readerIn, null, null); this.handleImportMappings(importMappings); this.setCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT); this.groupLevel = 1; setParserState(RtfParser.PARSER_IN_DOCUMENT); startDate = new Date(); startTime = System.currentTimeMillis(); this.tokenise(); endTime = System.currentTimeMillis(); endDate = new Date(); } // listener methods /** * Adds a EventListener to the RtfCtrlWordMgr. * * @param listener * the new EventListener. * @since 2.1.3 */ public void addListener(EventListener listener) { listeners.add(listener); } /** * Removes a EventListener from the RtfCtrlWordMgr. * * @param listener * the EventListener that has to be removed. * @since 2.1.3 */ public void removeListener(EventListener listener) { listeners.remove(listener); } /** * Initialize the parser object values. * * @param type Type of conversion or import * @param rtfDoc The RtfDocument * @param readerIn The input stream * @param doc The iText Document * @since 2.1.3 */ private void init(int type, RtfDocument rtfDoc, InputStream readerIn, Document doc, Element elem) { init_stats(); // initialize reader to a PushbackReader this.pbReader = init_Reader(readerIn); this.conversionType = type; this.rtfDoc = rtfDoc; this.document = doc; this.elem = elem; this.currentState = new RtfParserState(); this.stackState = new Stack(); this.setParserState(PARSER_STARTSTOP); this.importMgr = new RtfImportMgr(this.rtfDoc, this.document); // get destination Mgr this.destinationMgr = RtfDestinationMgr.getInstance(this); // set the parser RtfDestinationMgr.setParser(this); // DEBUG INFO for timing and memory usage of RtfCtrlWordMgr object // create multiple new RtfCtrlWordMgr objects to check timing and memory usage // System.gc(); // long endTime = 0; // Date endDate = null; // long endFree = 0; // DecimalFormat df = new DecimalFormat("#,##0"); // Date startDate = new Date(); // long startTime = System.currentTimeMillis(); // long startFree = Runtime.getRuntime().freeMemory(); // System.out.println("1:"); this.rtfKeywordMgr = new RtfCtrlWordMgr(this, this.pbReader);/////////DO NOT COMMENT OUT THIS LINE /////////// Object listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = iterator.next(); if(listener instanceof RtfCtrlWordListener) { this.rtfKeywordMgr.addRtfCtrlWordListener((RtfCtrlWordListener)listener); } } // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); // // System.gc(); // System.out.println("2:"); // startDate = new Date(); // startTime = System.currentTimeMillis(); // startFree = Runtime.getRuntime().freeMemory(); // RtfCtrlWordMgr rtfKeywordMgr2 = new RtfCtrlWordMgr(this, this.pbReader); // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); // // System.gc(); // System.out.println("3:"); // startDate = new Date(); // startTime = System.currentTimeMillis(); // startFree = Runtime.getRuntime().freeMemory(); // RtfCtrlWordMgr rtfKeywordMgr3 = new RtfCtrlWordMgr(this, this.pbReader); // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); // // System.gc(); // System.out.println("4:"); // startDate = new Date(); // startTime = System.currentTimeMillis(); // startFree = Runtime.getRuntime().freeMemory(); // RtfCtrlWordMgr rtfKeywordMgr4 = new RtfCtrlWordMgr(this, this.pbReader); // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); // // System.gc(); // System.out.println("5:"); // startDate = new Date(); // startTime = System.currentTimeMillis(); // startFree = Runtime.getRuntime().freeMemory(); // RtfCtrlWordMgr rtfKeywordMgr5 = new RtfCtrlWordMgr(this, this.pbReader); // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); // System.gc(); // System.out.println("At ed:"); // startDate = new Date(); // startTime = System.currentTimeMillis(); // startFree = Runtime.getRuntime().freeMemory(); // //RtfCtrlWordMgr rtfKeywordMgr6 = new RtfCtrlWordMgr(this, this.pbReader); // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); } /** * Initialize the statistics values. * @since 2.1.3 */ protected void init_stats() { byteCount = 0; ctrlWordCount = 0; openGroupCount = 0; closeGroupCount = 0; characterCount = 0; ctrlWordHandledCount = 0; ctrlWordNotHandledCount = 0; ctrlWordSkippedCount = 0; groupSkippedCount = 0; startTime = 0; endTime = 0; startDate = null; endDate = null; } /** * Casts the input reader to a PushbackReader or * creates a new PushbackReader from the Reader passed in. * The reader is also transformed into a BufferedReader if necessary. * * @param readerIn * The Reader object for the input file. * @return * PushbackReader object * @since 2.1.3 */ private PushbackInputStream init_Reader(InputStream readerIn) { // Reader newReader = readerIn; // // Initializing the reader as a BufferedReader // // cut test processing time by approximately 50% // // default uses 8192 character buffer // if(!(newReader instanceof BufferedReader)) { // newReader = new BufferedReader(newReader); // Since JDK1.1 // } // // Initializing the reader as a PushbackReader is // // a requirement of the parser to be able to put back // // read ahead characters. // if(!(newReader instanceof PushbackReader)) { // newReader = new PushbackReader(newReader); // Since JDK1.1 // } if(!(readerIn instanceof BufferedInputStream)) { readerIn = new BufferedInputStream(readerIn); } if(!(readerIn instanceof PushbackInputStream)) { readerIn = new PushbackInputStream(readerIn); } // return the proper reader object to the parser setup return (PushbackInputStream)readerIn; } /** * Imports the mappings defined in the RtfImportMappings into the * RtfImportHeader of this RtfParser2. * * @param importMappings * The RtfImportMappings to import. * @since 2.1.3 */ private void handleImportMappings(RtfImportMappings importMappings) { Iterator it = importMappings.getFontMappings().keySet().iterator(); while(it.hasNext()) { String fontNr = (String) it.next(); this.importMgr.importFont(fontNr, (String) importMappings.getFontMappings().get(fontNr)); } it = importMappings.getColorMappings().keySet().iterator(); while(it.hasNext()) { String colorNr = (String) it.next(); this.importMgr.importColor(colorNr, (Color) importMappings.getColorMappings().get(colorNr)); } it = importMappings.getListMappings().keySet().iterator(); while(it.hasNext()) { String listNr = (String) it.next(); this.importMgr.importList(listNr, (String)importMappings.getListMappings().get(listNr)); } it = importMappings.getStylesheetListMappings().keySet().iterator(); while(it.hasNext()) { String stylesheetListNr = (String) it.next(); this.importMgr.importStylesheetList(stylesheetListNr, (List) importMappings.getStylesheetListMappings().get(stylesheetListNr)); } } /* ***************************************** * DOCUMENT CONTROL METHODS * * Handles - * handleOpenGroup: Open groups - '{' * handleCloseGroup: Close groups - '}' * handleCtrlWord: Ctrl Words - '\...' * handleCharacter: Characters - Plain Text, etc. * */ /** * Handles open group tokens. ({) * * @return errOK if ok, other if an error occurred. * @since 2.1.3 */ public int handleOpenGroup() { int result = errOK; this.openGroupCount++; // stats this.groupLevel++; // current group level in tokeniser this.docGroupLevel++; // current group level in document if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { this.groupSkippedCount++; } RtfDestination dest = this.getCurrentDestination(); boolean handled = false; if(dest != null) { if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: before dest.handleOpeningSubGroup()"); RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.toString()); } handled = dest.handleOpeningSubGroup(); if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.handleOpeningSubGroup()"); } } this.stackState.push(this.currentState); this.currentState = new RtfParserState(this.currentState); // do not set this true until after the state is pushed // otherwise it inserts a { where one does not belong. this.currentState.newGroup = true; dest = this.getCurrentDestination(); if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleOpenGroup()"); if(this.lastCtrlWordParam != null) RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord); RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + Integer.toString(groupLevel)); RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.toString()); } if(dest != null) { handled = dest.handleOpenGroup(); } if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.handleOpenGroup(); handled=" + Boolean.toString(handled)); } return result; } public static void outputDebug(Object doc, int groupLevel, String str) { System.out.println(str); if(doc == null) return; if(groupLevel<0) groupLevel = 0; char[] a; Arrays.fill(a= new char[groupLevel*2], ' '); String spaces= new String(a); if(doc instanceof RtfDocument) { ((RtfDocument)doc).add(new RtfDirectContent("\n" + spaces + str)); } else if(doc instanceof Document) { try { ((Document)doc).add(new RtfDirectContent("\n" + spaces + str)); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * Handles close group tokens. (}) * * @return errOK if ok, other if an error occurred. * @since 2.1.3 */ public int handleCloseGroup() { int result = errOK; this.closeGroupCount++; // stats if (this.getTokeniserState() != TOKENISER_SKIP_GROUP) { if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleCloseGroup()"); if(this.lastCtrlWordParam != null) RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord); RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + Integer.toString(groupLevel)); RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + this.getCurrentDestination().toString()); RtfParser.outputDebug(this.rtfDoc, groupLevel, ""); } RtfDestination dest = this.getCurrentDestination(); boolean handled = false; if(dest != null) { handled = dest.handleCloseGroup(); } if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: After dest.handleCloseGroup(); handled = " + Boolean.toString(handled)); RtfParser.outputDebug(this.rtfDoc, groupLevel, ""); } } if(this.stackState.size() >0 ) { this.currentState = (RtfParserState)this.stackState.pop(); } else { result = errStackUnderflow; } this.docGroupLevel--; this.groupLevel--; if (this.getTokeniserState() == TOKENISER_SKIP_GROUP && this.groupLevel < this.skipGroupLevel) { this.setTokeniserState(TOKENISER_NORMAL); } return result; } /** * Handles control word tokens. Depending on the current * state a control word can lead to a state change. When * parsing the actual document contents, certain tabled * values are remapped. i.e. colors, fonts, styles, etc. * * @param ctrlWordData The control word to handle. * @return errOK if ok, other if an error occurred. * @since 2.1.3 */ public int handleCtrlWord(RtfCtrlWordData ctrlWordData) { int result = errOK; this.ctrlWordCount++; // stats if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleCtrlWord=" + ctrlWordData.ctrlWord + " param=[" + ctrlWordData.param + "]"); } if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { this.ctrlWordSkippedCount++; if(debugParser) { RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: SKIPPED"); } return result; } // RtfDestination dest = (RtfDestination)this.getCurrentDestination(); // boolean handled = false; // if(dest != null) { // handled = dest.handleControlWord(ctrlWordData); // } result = this.rtfKeywordMgr.handleKeyword(ctrlWordData, this.groupLevel); if( result == errOK){ this.ctrlWordHandledCount++; } else { this.ctrlWordNotHandledCount++; result = errOK; // hack for now. } return result; } /** * Handles text tokens. These are either handed on to the * appropriate destination handler. * * @param nextChar * The text token to handle. * @return errOK if ok, other if an error occurred. * @since 2.1.3 */ // public int handleCharacter(char[] nextChar) { public int handleCharacter(int nextChar) { this.characterCount++; // stats if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { return errOK; } boolean handled = false; RtfDestination dest = this.getCurrentDestination(); if(dest != null) { handled = dest.handleCharacter(nextChar); } return errOK; } /** * Get the state of the parser. * * @return * The current RtfParserState state object. * @since 2.1.3 */ public RtfParserState getState(){ return this.currentState; } /** * Get the current state of the parser. * * @return * The current state of the parser. * @since 2.1.3 */ public int getParserState(){ return this.currentState.parserState; } /** * Set the state value of the parser. * * @param newState * The new state for the parser * @return * The state of the parser. * @since 2.1.3 */ public int setParserState(int newState){ this.currentState.parserState = newState; return this.currentState.parserState; } /** * Get the conversion type. * * @return * The type of the conversion. Import or Convert. * @since 2.1.3 */ public int getConversionType() { return this.conversionType; } /** * Get the RTF Document object. * @return * Returns the object rtfDoc. * @since 2.1.3 */ public RtfDocument getRtfDocument() { return this.rtfDoc; } /** * Get the Document object. * @return * Returns the object rtfDoc. * @since 2.1.3 */ public Document getDocument() { return this.document; } /** * Get the RtfImportHeader object. * @return * Returns the object importHeader. * @since 2.1.3 */ public RtfImportMgr getImportManager() { return importMgr; } ///////////////////////////////////////////////////////////// // accessors for destinations /** * Set the current destination object for the current state. * @param destination The destination value to set. * @since 2.1.3 */ public boolean setCurrentDestination(String destination) { RtfDestination dest = RtfDestinationMgr.getDestination(destination); if(dest != null) { this.currentState.destination = dest; return false; } else { this.setTokeniserStateSkipGroup(); return false; } } /** * Get the current destination object. * * @return The current state destination * @since 2.1.3 */ public RtfDestination getCurrentDestination() { return this.currentState.destination; } /** * Get a destination from the map * * @param destination The string destination. * @return The destination object from the map * @since 2.1.3 */ public RtfDestination getDestination(String destination) { return RtfDestinationMgr.getDestination(destination); } /** * Helper method to determine if this is a new group. * * @return true if this is a new group, otherwise it returns false. * @since 2.1.3 */ public boolean isNewGroup() { return this.currentState.newGroup; } /** * Helper method to set the new group flag * @param value The boolean value to set the flag * @return The value of newGroup * @since 2.1.3 */ public boolean setNewGroup(boolean value) { this.currentState.newGroup = value; return this.currentState.newGroup; } /* ************ * TOKENISER * **************/ /** * Read through the input file and parse the data stream into tokens. * * @throws IOException on IO error. * @since 2.1.3 */ public void tokenise() throws IOException { int errorCode = errOK; // error code int nextChar = 0; // char[] nextChar = new char[1]; // input variable // nextChar[0]=0; // set to 0 this.setTokeniserState(TOKENISER_NORMAL); // set initial tokeniser state // while(this.pbReader.read(nextChar) != -1) { while((nextChar = this.pbReader.read()) != -1) { this.byteCount++; if (this.getTokeniserState() == TOKENISER_BINARY) // if we're parsing binary data, handle it directly { if ((errorCode = parseChar(nextChar)) != errOK) return; } else { // switch(nextChar[0]) { switch(nextChar) { case '{': // scope delimiter - Open this.handleOpenGroup(); break; case '}': // scope delimiter - Close this.handleCloseGroup(); break; case 0x0a: // noise character case 0x0d: // noise character // if(this.isImport()) { // this.rtfDoc.add(new RtfDirectContent(new String(nextChar))); // } break; case '\\': // Control word start delimiter if(parseCtrlWord(pbReader) != errOK) { // TODO: Indicate some type of error return; } break; default: if(groupLevel == 0) { // BOMs break; } if(this.getTokeniserState() == TOKENISER_HEX) { StringBuffer hexChars = new StringBuffer(); hexChars.append(nextChar); // if(pbReader.read(nextChar) == -1) { if((nextChar = pbReader.read()) == -1) { return; } this.byteCount++; hexChars.append(nextChar); try { // nextChar[0]=(char)Integer.parseInt(hexChars.toString(), 16); nextChar=Integer.parseInt(hexChars.toString(), 16); } catch (NumberFormatException e) { return; } this.setTokeniserState(TOKENISER_NORMAL); } if ((errorCode = parseChar(nextChar)) != errOK) { return; // some error occurred. we should send a // real error } break; } // switch(nextChar[0]) } // end if (this.getTokeniserState() == TOKENISER_BINARY) // if(groupLevel < 1 && this.isImportFragment()) return; //return errOK; // if(groupLevel < 0 && this.isImportFull()) return; //return errStackUnderflow; // if(groupLevel < 0 && this.isConvert()) return; //return errStackUnderflow; }// end while(reader.read(nextChar) != -1) RtfDestination dest = this.getCurrentDestination(); if(dest != null) { dest.closeDestination(); } } /** * Process the character and send it to the current destination. * @param nextChar * The character to process * @return * Returns an error code or errOK if no error. * @since 2.1.3 */ private int parseChar(int nextChar) { // figure out where to put the character // needs to handle group levels for parsing // examples /* * {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} * {\f7\fswiss\fcharset0\fprq2{\*\panose 020b0604020202030204}Helv{\*\falt Arial};} <- special case!!!! * {\f5\froman\fcharset0 Tahoma;} * {\f6\froman\fcharset0 Arial Black;} * {\info(\author name}{\company company name}} * ... document text ... */ if (this.getTokeniserState() == TOKENISER_BINARY && --binByteCount <= 0) this.setTokeniserStateNormal(); if (this.getTokeniserState() == TOKENISER_SKIP_BYTES && --binSkipByteCount <= 0) this.setTokeniserStateNormal(); return this.handleCharacter(nextChar); } /** * Parses a keyword and it's parameter if one exists * @param reader * This is a pushback reader for file input. * @return * Returns an error code or errOK if no error. * @throws IOException * Catch any file read problem. * @since 2.1.3 */ private int parseCtrlWord(PushbackInputStream reader) throws IOException { int nextChar = 0; int result = errOK; if((nextChar = reader.read()) == -1) { return errEndOfFile; } this.byteCount++; StringBuffer parsedCtrlWord = new StringBuffer(); StringBuffer parsedParam= new StringBuffer(); RtfCtrlWordData ctrlWordParam = new RtfCtrlWordData(); if(!Character.isLetterOrDigit((char)nextChar)) { parsedCtrlWord.append((char)nextChar); ctrlWordParam.ctrlWord = parsedCtrlWord.toString(); result = this.handleCtrlWord(ctrlWordParam); lastCtrlWordParam = ctrlWordParam; return result; } do { parsedCtrlWord.append((char)nextChar); //TODO: catch EOF nextChar = reader.read(); this.byteCount++; } while (Character.isLetter((char)nextChar)); ctrlWordParam.ctrlWord = parsedCtrlWord.toString(); if(nextChar == '-') { ctrlWordParam.isNeg = true; if((nextChar = reader.read()) == -1) { return errEndOfFile; } this.byteCount++; } if(Character.isDigit((char)nextChar)) { ctrlWordParam.hasParam = true; do { parsedParam.append((char)nextChar); //TODO: catch EOF nextChar = reader.read(); this.byteCount++; } while (Character.isDigit((char)nextChar)); ctrlWordParam.param = parsedParam.toString(); } // push this character back into the stream if(nextChar != ' ') { reader.unread(nextChar); } if(debugParser) { // // debug: insrsid6254399 // if(ctrlWordParam.ctrlWord.equals("proptype") && ctrlWordParam.param.equals("30")) { // System.out.print("Debug value found\n"); // } // if(ctrlWordParam.ctrlWord.equals("cf") ) { // System.out.print("Debug value found\n"); // } } result = this.handleCtrlWord(ctrlWordParam); lastCtrlWordParam = ctrlWordParam; return result; } /** * Set the current state of the tokeniser. * @param value The new state of the tokeniser. * @return The state of the tokeniser. * @since 2.1.3 */ public int setTokeniserState(int value) { this.currentState.tokeniserState = value; return this.currentState.tokeniserState; } /** * Get the current state of the tokeniser. * @return The current state of the tokeniser. * @since 2.1.3 */ public int getTokeniserState() { return this.currentState.tokeniserState; } /** * Gets the current group level * * @return * The current group level value. * @since 2.1.3 */ public int getLevel() { return this.groupLevel; } /** * Set the tokeniser state to skip to the end of the group. * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level. * @since 2.1.3 */ public void setTokeniserStateNormal() { this.setTokeniserState(TOKENISER_NORMAL); } /** * Set the tokeniser state to skip to the end of the group. * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level. * @since 2.1.3 */ public void setTokeniserStateSkipGroup() { this.setTokeniserState(TOKENISER_SKIP_GROUP); this.skipGroupLevel = this.groupLevel; } /** * Sets the number of bytes to skip and the state of the tokeniser. * * @param numberOfBytesToSkip * The numbere of bytes to skip in the file. * @since 2.1.3 */ public void setTokeniserSkipBytes(long numberOfBytesToSkip) { this.setTokeniserState(TOKENISER_SKIP_BYTES); this.binSkipByteCount = numberOfBytesToSkip; } /** * Sets the number of binary bytes. * * @param binaryCount * The number of binary bytes. * @since 2.1.3 */ public void setTokeniserStateBinary(int binaryCount) { this.setTokeniserState(TOKENISER_BINARY); this.binByteCount = binaryCount; } /** * Sets the number of binary bytes. * * @param binaryCount * The number of binary bytes. * @since 2.1.3 */ public void setTokeniserStateBinary(long binaryCount) { this.setTokeniserState(TOKENISER_BINARY); this.binByteCount = binaryCount; } /** * Helper method to determin if conversion is TYPE_CONVERT * @return true if TYPE_CONVERT, otherwise false * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_CONVERT * @since 2.1.3 */ public boolean isConvert() { return (this.getConversionType() == RtfParser.TYPE_CONVERT); } /** * Helper method to determin if conversion is TYPE_IMPORT_FULL or TYPE_IMPORT_FRAGMENT * @return true if TYPE_CONVERT, otherwise false * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT * @since 2.1.3 */ public boolean isImport() { return (isImportFull() || this.isImportFragment()); } /** * Helper method to determin if conversion is TYPE_IMPORT_FULL * @return true if TYPE_CONVERT, otherwise false * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL * @since 2.1.3 */ public boolean isImportFull() { return (this.getConversionType() == RtfParser.TYPE_IMPORT_FULL); } /** * Helper method to determin if conversion is TYPE_IMPORT_FRAGMENT * @return true if TYPE_CONVERT, otherwise false * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT * @since 2.1.3 */ public boolean isImportFragment() { return (this.getConversionType() == RtfParser.TYPE_IMPORT_FRAGMENT); } /** * Helper method to indicate if this control word was a \* control word. * @return true if it was a \* control word, otherwise false * @since 2.1.3 */ public boolean getExtendedDestination() { return this.currentState.isExtendedDestination; } /** * Helper method to set the extended control word flag. * @param value Boolean to set the value to. * @return isExtendedDestination. * @since 2.1.3 */ public boolean setExtendedDestination(boolean value) { this.currentState.isExtendedDestination = value; return this.currentState.isExtendedDestination; } /** * Get the logfile name. * * @return the logFile * @since 2.1.3 */ public String getLogFile() { return logFile; } /** * Set the logFile name * * @param logFile the logFile to set * @since 2.1.3 */ public void setLogFile(String logFile) { this.logFile = logFile; } /** * Set the logFile name * * @param logFile the logFile to set * @since 2.1.3 */ public void setLogFile(String logFile, boolean logAppend) { this.logFile = logFile; this.setLogAppend(logAppend); } /** * Get flag indicating if logging is on or off. * * @return the logging * @since 2.1.3 */ public boolean isLogging() { return logging; } /** * Set flag indicating if logging is on or off * @param logging true to turn on logging, false to turn off logging. * @since 2.1.3 */ public void setLogging(boolean logging) { this.logging = logging; } /** * @return the logAppend * @since 2.1.3 */ public boolean isLogAppend() { return logAppend; } /** * @param logAppend the logAppend to set * @since 2.1.3 */ public void setLogAppend(boolean logAppend) { this.logAppend = logAppend; } /* * Statistics * public void printStats(PrintStream out) { if(out == null) return; out.println(""); out.println("Parser statistics:"); out.println("Process start date: " + startDate.toLocaleString()); out.println("Process end date : " + endDate.toLocaleString()); out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); out.println("Total bytes read : " + Long.toString(byteCount)); out.println("Open group count : " + Long.toString(openGroupCount)); out.print("Close group count : " + Long.toString(closeGroupCount)); out.println(" (Groups Skipped): " + Long.toString(groupSkippedCount)); out.print("Control word count: " + Long.toString(ctrlWordCount)); out.print(" - Handled: " + Long.toString(ctrlWordHandledCount)); out.print(" Not Handled: " + Long.toString(ctrlWordNotHandledCount)); out.println(" Skipped: " + Long.toString(ctrlWordSkippedCount)); out.println("Plain text char count: " + Long.toString(characterCount)); }*/ } src/rtf/com/lowagie/text/rtf/parser/RtfParserState.java100644 0 0 11521 11012562273 20642 0ustar 0 0 /* * $Id: RtfParserState.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser; import java.util.Stack; import com.lowagie.text.rtf.parser.destinations.RtfDestination; import com.lowagie.text.rtf.parser.destinations.RtfDestinationNull; import com.lowagie.text.rtf.parser.properties.RtfProperty; /** * The RtfParserState contains the state information * for the parser. The current state object is pushed/popped in a stack * when a group change is made. * * When an open group is encountered, the current state is copied and * then pushed on the top of the stack * When a close group is encountered, the current state is overwritten with * the popped value from the top of the stack * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfParserState { /** * The parser state. */ public int parserState = RtfParser.PARSER_IN_UNKNOWN; /** * The tokeniser state. */ public int tokeniserState = RtfParser.TOKENISER_STATE_IN_UNKOWN; /** * The control word set as the group handler. */ public Object groupHandler = null; /** * The parsed value for the current group/control word. */ public StringBuffer text = null; /** * Stack containing control word handlers. There could be multiple * control words in a group. */ public Stack ctrlWordHandlers = null; /** * The current control word handler. */ public Object ctrlWordHandler = null; /** * The current destination. */ public RtfDestination destination = null; /** * Flag indicating if this is an extended destination \* control word */ public boolean isExtendedDestination = false; /** * Flag to indicate if last token was an open group token '{' */ public boolean newGroup = false; public RtfProperty properties = null; /** * Default constructor * */ public RtfParserState() { this.text = new StringBuffer(); this.ctrlWordHandlers = new Stack(); this.properties = new RtfProperty(); this.destination = RtfDestinationNull.getInstance(); this.newGroup = false; } /** * Copy constructor * @param orig The object to copy */ public RtfParserState(RtfParserState orig) { this.properties = orig.properties; this.parserState = orig.parserState; this.tokeniserState = orig.tokeniserState; this.groupHandler = null; this.destination = orig.destination; this.text = new StringBuffer(); this.ctrlWordHandlers = new Stack(); this.destination = orig.destination; this.newGroup = false; } } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordData.java100644 0 0 11652 11012562273 22767 0ustar 0 0 /* $Id: RtfCtrlWordData.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; /** * The control word and parameter information as parsed by the parser. * Contains the control word, * Flag indicating if there is a parameter. * The parameter value as a string. * Flag indicating the parameter is positive or negative. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfCtrlWordData implements Cloneable { public String prefix = ""; public String suffix = ""; /** * The control word found by the parser */ public String ctrlWord = ""; /** * Flag indicating if this keyword has a parameter. */ public boolean hasParam = false; /** * The parameter for the control word. */ public String param = ""; /** * Flag indicating if parameter is positive or negative. */ public boolean isNeg = false; /** * Flag indicating a new group */ public boolean newGroup = false; /** * Flag indicating if this object has been modified. */ public boolean modified = false; public int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED; public String specialHandler = ""; /** * Return the parameter value as an integer (int) value. * * @return * Returns the parameter value as an int vlaue. */ public int intValue() { int value; value = Integer.parseInt(this.param); if(this.isNeg) value = (-value); return value; } /** * Return the parameter value as an Integer object. * * @return * Returns the parameter value as an Integer object. */ public Integer toInteger() { Integer value; value = new Integer(this.isNeg ? Integer.parseInt(this.param)*-1 : Integer.parseInt(this.param)); return value; } /** * Return the parameter value as a long value * * @return * Returns the parameter value as a long value */ public long longValue() { long value; value = Long.parseLong(this.param); if(this.isNeg) value = (-value); return value; } /** * Return the parameter value as a Long object * * @return * Returns the parameter value as a Long object. */ public Long toLong() { Long value; value = new Long(this.isNeg ? Long.parseLong(this.param)*-1 : Long.parseLong(this.param)); return value; } public String toString() { String out = ""; out = this.prefix + this.ctrlWord; if(this.hasParam) { if(this.isNeg) out += "-"; out += this.param; } out += this.suffix; return out; } public Object clone() throws CloneNotSupportedException{ Object cl = (RtfCtrlWordData)super.clone(); return cl; } } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.java100644 0 0 30663 11036112746 23500 0ustar 0 0 /* $Id: RtfCtrlWordHandler.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.destinations.RtfDestination; import com.lowagie.text.rtf.parser.destinations.RtfDestinationMgr; /** * RtfCtrlWordBase is the base class for all * control word handlers to extend from. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfCtrlWordHandler implements Cloneable { /** * Debug flag - internal use * @since 2.0.8 */ private static final boolean debug = false; /** * Local variable referencing the parser object. * @since 2.0.8 */ protected RtfParser rtfParser = null; /** * The control word for this class. * @since 2.0.8 */ protected String ctrlWord = ""; /** * The default value for this control word. * Not all control words use a default parameter value. * @since 2.0.8 */ protected int defaultParameterValue = 0; /** * Does this control word use the default value? * @since 2.0.8 */ protected boolean passDefaultParameterValue = false; /** * Control Word type. Destination, toggle, value, etc. * @since 2.0.8 */ protected int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED; /** * Class, property, etc. * @since 2.0.8 */ protected String specialHandler = ""; /** * What version of the RTF spec the control word was introduced. * @since 2.0.8 */ protected float rtfVersionSupported = -1.0f; // -1.0 unknown. Each class should override this as implemented. /** * The control word as parsed by the parser. * @since 2.0.8 */ protected RtfCtrlWordData ctrlWordData = null; /** * String containing the value of "{" or "" (blank) depending on if this is the * first control word in a group. * @since 2.0.8 */ protected String groupPrefix = ""; /** * The prefix for all control words. * @since 2.0.8 */ protected String ctrlWordPrefix = "\\"; /** * The prefix for all control words. * @since 2.0.8 */ protected String ctrlWordSuffix = " "; /** * Hidden default constructor. Must use constructor with parameters. * @see com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordHandler#RtfCtrlWordHandler(RtfParser rtfParser, String ctrlWord, int defaultParameterValue, boolean passDefaultParameterValue, int ctrlWordType, String prefix, String suffix, String specialHandler) * @since 2.0.8 */ private RtfCtrlWordHandler(){}; /** * Constructor: * * @param rtfParser * The parser for this control word. * @param ctrlWord * The string value of this control word. * @param defaultParameterValue * The default value of this control word. Not all control words have values. * @param passDefaultParameterValue * Flag indicating if this control word should use the default value. * @param ctrlWordType * Indicator of the type of control word this is. DESTINATION|DESTINATION_EX|VALUE|FLAG|TOGGLE|SYMBOL * @param prefix * String to prefix the ctrl word with. "\" or "\*\" are the 2 used values. * @param suffix * String to add as suffix to the ctrl word. " " and "" are the 2 used values. * @param specialHandler * If TOGGLE then the property name as String (propertyGroup.propertyName format ex. "character.bold") * If FLAG then the property name as String (propertyGroup.propertyName format ex. "character.bold") * If VALUE then the property name as String (propertyGroup.propertyName format ex. "character.bold") * If SYMBOL then the character to use for substitution as String * If DESTINATION|DESTINATION_EX then the RtfDestination class name as String * * @since 2.0.8 */ public RtfCtrlWordHandler(RtfParser rtfParser, String ctrlWord, int defaultParameterValue, boolean passDefaultParameterValue, int ctrlWordType, String prefix, String suffix, String specialHandler) { super(); this.rtfParser = rtfParser; this.ctrlWord = ctrlWord; this.defaultParameterValue = defaultParameterValue; this.passDefaultParameterValue = passDefaultParameterValue; this.ctrlWordType = ctrlWordType; this.ctrlWordPrefix = prefix; this.ctrlWordSuffix = suffix; this.specialHandler = specialHandler; if(this.ctrlWordType == RtfCtrlWordType.DESTINATION || this.ctrlWordType == RtfCtrlWordType.DESTINATION_EX){ if(this.specialHandler == null) { this.specialHandler = "RtfDestinationNull"; } String arg1 = ""; // stylesheet value - S, CS, TS RtfDestinationMgr.addDestination(this.ctrlWord, new Object[] { this.specialHandler, arg1 }); } else { if(this.ctrlWordType == RtfCtrlWordType.SYMBOL){ } else { if(this.specialHandler == null) { this.specialHandler = this.ctrlWord; // if null, make the property the name of the ctrl word } else { if(this.specialHandler.length() > 1 && this.specialHandler.endsWith(".")) { this.specialHandler += this.ctrlWord; // if string length>1 and ends with a period, it's a group. Add ctrlWord } } } } } /** * The primary control word handler method. * Called by the parser once it has a control word and parameter if applicable. * * @param ctrlWordDataIn * The control word and associated parameter if applicable. * @return * true or false if the control word was handled. * @since 2.0.8 */ public final boolean handleControlword(RtfCtrlWordData ctrlWordDataIn){ boolean result = false; this.ctrlWordData = ctrlWordDataIn; RtfDestination dest = null; boolean handled = false; this.ctrlWordData.prefix = this.ctrlWordPrefix; this.ctrlWordData.suffix = this.ctrlWordSuffix; this.ctrlWordData.newGroup = this.rtfParser.getState().newGroup; this.ctrlWordData.ctrlWordType = this.ctrlWordType; this.ctrlWordData.specialHandler = this.specialHandler; if(!this.ctrlWordData.hasParam && this.passDefaultParameterValue) { this.ctrlWordData.hasParam = true; this.ctrlWordData.param = Integer.toString(this.defaultParameterValue); } if(debug) { printDebug("handleKeyword: [" + this.ctrlWordData.ctrlWord + "] param=" + ctrlWordDataIn.param); RtfParser.outputDebug(this.rtfParser.getRtfDocument(), this.rtfParser.getLevel()+1, "RtfCtrlWordHandler debug Start: " + this.ctrlWordData.ctrlWord + " "); } if(this.ctrlWordData.ctrlWord.equals("*")) { return true; } if(!beforeControlWord()) { return true; } switch(this.ctrlWordType) { case RtfCtrlWordType.FLAG: case RtfCtrlWordType.TOGGLE: case RtfCtrlWordType.VALUE: dest = this.rtfParser.getCurrentDestination(); if(dest != null) { handled = dest.handleControlWord(this.ctrlWordData); } break; case RtfCtrlWordType.SYMBOL: dest = this.rtfParser.getCurrentDestination(); if(dest != null) { String data = null; // if doing an import, then put the control word in the output stream through the character handler if(this.rtfParser.isImport()) { data = this.ctrlWordPrefix + this.ctrlWordData.ctrlWord + this.ctrlWordSuffix; } if(this.rtfParser.isConvert()) { data = this.specialHandler; } // If there is a substitute character, process the character. // If no substitute character, then provide special handling in the destination for the ctrl word. if(data != null) { for(int idx=0; idx< data.length(); idx++) { handled = dest.handleCharacter(data.charAt(idx)); } } else { handled = dest.handleControlWord(this.ctrlWordData); } } break; case RtfCtrlWordType.DESTINATION_EX: case RtfCtrlWordType.DESTINATION: // set the destination int x=0; if("shppict".equals(this.ctrlWord) || "nonshppict".equals(this.ctrlWord)) { x++; } handled = this.rtfParser.setCurrentDestination(this.ctrlWord); // let destination handle the ctrl word now. dest = this.rtfParser.getCurrentDestination(); if(dest != null) { if(dest.getNewTokeniserState() == RtfParser.TOKENISER_IGNORE_RESULT) { handled = dest.handleControlWord(this.ctrlWordData); } else { this.rtfParser.setTokeniserState(dest.getNewTokeniserState()); } } break; } afterControlWord(); if(debug) { RtfParser.outputDebug(this.rtfParser.getRtfDocument(), this.rtfParser.getLevel()+1, "RtfCtrlWordHandler debug End: " + this.ctrlWordData.ctrlWord + " "); } return result; } /** * Pre-processing before the control word. * * If return value is true, no further processing will be performed on * this control word. * * @return false = stop processing, true = continue processing * @since 2.0.8 */ //Primary purpose is for \* control word and event handling. protected boolean beforeControlWord() { if(debug) printDebug("beforeControlWord"); // TODO: This is where events would be triggered return true; } /** * Handle the control word. * * @return true if control word was handled, false if it was not handled. * @since 2.0.8 */ protected boolean onControlWord() { if(debug) printDebug("onCtrlWord"); // TODO: This is where events would be triggered return false; } /** * Post-processing after the control word. * * @return false = stop processing, true = continue processing * @since 2.0.8 */ protected boolean afterControlWord() { if(debug) printDebug("afterControlWord"); // TODO: This is where events would be triggered return true; } // public String ctrlWordString() { // //String out = ctrlWordPrefix + this.ctrlWord; // String out = ""; // if(this.bExtendedDestination) { // out += "\\*"; // } // out = ctrlWordPrefix + this.ctrlWordData.ctrlWord; // if(this.ctrlWordData.hasParam) { // if(this.ctrlWordData.isNeg) out += "-"; // out += this.ctrlWordData.param; // } else { // if(this.passDefaultParameterValue == true) { // out += Integer.toString(this.defaultParameterValue); // } // } // out += this.ctrlWordSuffix; // return out; // } /** * Debug function to print class/method * @param txt The String to output. * @since 2.0.8 */ private final void printDebug(final String txt) { System.out.println(this.getClass().getName() + " : " + txt); } } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordListener.java100644 0 0 6351 11012562273 23663 0ustar 0 0 /* * $Id: RtfCtrlWordListener.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; import java.util.EventListener; /** * RtfCtrlWordListener interface for handling events. * * @author Howard Shank (hgshank@yahoo.com) * * @since 2.0.8 */ public interface RtfCtrlWordListener extends EventListener { /** * * @return null or modified copy of the ctrlWordData object */ public RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData); /** * * @return null or modified copy of the ctrlWordData object */ public RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData); /** * * @return null or modified copy of the ctrlWordData object */ public RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData); } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMap.java100644 0 0 720617 11106243445 22664 0ustar 0 0 /* * $Id: RtfCtrlWordMap.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2007 by Howard Shank * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; import java.util.HashMap; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.properties.RtfProperty; /** * RtfCtrlWords handles the creation of the control word wiring. * It is a class containing the hash map of the control words (key) * and their associated class (value). * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ final class RtfCtrlWordMap { // 1810 control words in Spec v1.9. might be a few more for other apps that implement // additional control words such as exchange, outlook, etc. // 1810/.9(loadfactor) = 2011.111111... // set approximate initial size to initial count / load factor. // HashMap default size is 16. Load Factor .75 /** * Control Word HashMap mapping object. */ private HashMap ctrlWords = new HashMap(2012, .9f); /** * Get the HashMap object containing the control words. * Initializes the instance if this is the first instantiation * of RtfCtrlWords class. * @since 2.0.8 */ public RtfCtrlWordHandler getCtrlWordHandler(String ctrlWord) { try { RtfCtrlWordHandler handler = null; if(ctrlWord == "cf") { handler = null; } if(ctrlWords.containsKey(ctrlWord)) { // add 1 to known control words return (RtfCtrlWordHandler)ctrlWords.get(ctrlWord); } else { // add 1 to unknown control words return (RtfCtrlWordHandler)ctrlWords.get("unknown"); } } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * Constructor * @param rtfParser The parser object. * @since 2.0.8 */ public RtfCtrlWordMap(RtfParser rtfParser) { /* * Parameters: * RtfParser rtfParser * String ctrlWord * int defaultParameterValue * boolean passDefaultParameterValue * RtfCtrlWordType ctrlWordType * String prefix * String suffix * String specialHandler = * If TOGGLE then the property name as String * If FLAG then the property name as String * If VALUE then the property name as String * If SYMBOL then the character to use for substitution as String * If DESTINATION|DESTINATION_EX then the RtfDestination class name as String */ //starwriter ctrlWords.put("aftnnrlc", new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgdsctbl", new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("pgdsc", new RtfCtrlWordHandler(rtfParser, "pgdsc", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgdscuse", new RtfCtrlWordHandler(rtfParser, "pgdscuse", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgdscnxt", new RtfCtrlWordHandler(rtfParser, "pgdscnxt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgdscno", new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); //office ctrlWords.put("'", new RtfCtrlWordHandler(rtfParser, "'", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "'")); ctrlWords.put("*", new RtfCtrlWordHandler(rtfParser, "*", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "*")); ctrlWords.put("-", new RtfCtrlWordHandler(rtfParser, "-", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "-")); ctrlWords.put(":", new RtfCtrlWordHandler(rtfParser, ":", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", ":")); ctrlWords.put("ApplyBrkRules", new RtfCtrlWordHandler(rtfParser, "ApplyBrkRules", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));// "ApplyBrkRules", ctrlWords.put("\\", new RtfCtrlWordHandler(rtfParser, "\\", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "\\")); ctrlWords.put("_", new RtfCtrlWordHandler(rtfParser, "_", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "_")); ctrlWords.put("ab", new RtfCtrlWordHandler(rtfParser, "ab", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"ab", ctrlWords.put("absh", new RtfCtrlWordHandler(rtfParser, "absh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));//"absh", ctrlWords.put("abslock", new RtfCtrlWordHandler(rtfParser, "abslock", 0, false, RtfCtrlWordType.FLAG, "", " ", null));//"abslock", ctrlWords.put("absnoovrlp", new RtfCtrlWordHandler(rtfParser, "absnoovrlp", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"absnoovrlp", ctrlWords.put("absw", new RtfCtrlWordHandler(rtfParser, "absw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));//"absw", ctrlWords.put("acaps", new RtfCtrlWordHandler(rtfParser, "acaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"acaps", ctrlWords.put("acccircle", new RtfCtrlWordHandler(rtfParser, "acccircle", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"acccircle", ctrlWords.put("acccomma", new RtfCtrlWordHandler(rtfParser, "acccomma", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("accdot", new RtfCtrlWordHandler(rtfParser, "accdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("accnone", new RtfCtrlWordHandler(rtfParser, "accnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("accunderdot", new RtfCtrlWordHandler(rtfParser, "accunderdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("acf", new RtfCtrlWordHandler(rtfParser, "acf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("additive", new RtfCtrlWordHandler(rtfParser, "additive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("adeflang", new RtfCtrlWordHandler(rtfParser, "adeflang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("adjustright", new RtfCtrlWordHandler(rtfParser, "adjustright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("adn", new RtfCtrlWordHandler(rtfParser, "adn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("aenddoc", new RtfCtrlWordHandler(rtfParser, "aenddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aendnotes", new RtfCtrlWordHandler(rtfParser, "aendnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aexpnd", new RtfCtrlWordHandler(rtfParser, "aexpnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("af", new RtfCtrlWordHandler(rtfParser, "af", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("afelev", new RtfCtrlWordHandler(rtfParser, "afelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("affixed", new RtfCtrlWordHandler(rtfParser, "affixed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("afs", new RtfCtrlWordHandler(rtfParser, "afs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("aftnbj", new RtfCtrlWordHandler(rtfParser, "aftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftncn", new RtfCtrlWordHandler(rtfParser, "aftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("aftnnalc", new RtfCtrlWordHandler(rtfParser, "aftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnar", new RtfCtrlWordHandler(rtfParser, "aftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnauc", new RtfCtrlWordHandler(rtfParser, "aftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnchi", new RtfCtrlWordHandler(rtfParser, "aftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnchosung", new RtfCtrlWordHandler(rtfParser, "aftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnncnum", new RtfCtrlWordHandler(rtfParser, "aftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnndbar", new RtfCtrlWordHandler(rtfParser, "aftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnndbnum", new RtfCtrlWordHandler(rtfParser, "aftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnndbnumd", new RtfCtrlWordHandler(rtfParser, "aftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnndbnumk", new RtfCtrlWordHandler(rtfParser, "aftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnndbnumt", new RtfCtrlWordHandler(rtfParser, "aftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnganada", new RtfCtrlWordHandler(rtfParser, "aftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnngbnum", new RtfCtrlWordHandler(rtfParser, "aftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnngbnumd", new RtfCtrlWordHandler(rtfParser, "aftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnngbnumk", new RtfCtrlWordHandler(rtfParser, "aftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnngbnuml", new RtfCtrlWordHandler(rtfParser, "aftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnrlc", new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnruc", new RtfCtrlWordHandler(rtfParser, "aftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnzodiac", new RtfCtrlWordHandler(rtfParser, "aftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "aftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "aftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnrestart", new RtfCtrlWordHandler(rtfParser, "aftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnrstcont", new RtfCtrlWordHandler(rtfParser, "aftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aftnsep", new RtfCtrlWordHandler(rtfParser, "aftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("aftnsepc", new RtfCtrlWordHandler(rtfParser, "aftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("aftnstart", new RtfCtrlWordHandler(rtfParser, "aftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("aftntj", new RtfCtrlWordHandler(rtfParser, "aftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ai", new RtfCtrlWordHandler(rtfParser, "ai", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("alang", new RtfCtrlWordHandler(rtfParser, "alang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("allowfieldendsel", new RtfCtrlWordHandler(rtfParser, "allowfieldendsel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("allprot", new RtfCtrlWordHandler(rtfParser, "allprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("alntblind", new RtfCtrlWordHandler(rtfParser, "alntblind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("alt", new RtfCtrlWordHandler(rtfParser, "alt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("animtext", new RtfCtrlWordHandler(rtfParser, "animtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("annotation", new RtfCtrlWordHandler(rtfParser, "annotation", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("annotprot", new RtfCtrlWordHandler(rtfParser, "annotprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ansi", new RtfCtrlWordHandler(rtfParser, "ansi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ansicpg", new RtfCtrlWordHandler(rtfParser, "ansicpg", 1252, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("aoutl", new RtfCtrlWordHandler(rtfParser, "aoutl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ascaps", new RtfCtrlWordHandler(rtfParser, "ascaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ashad", new RtfCtrlWordHandler(rtfParser, "ashad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("asianbrkrule", new RtfCtrlWordHandler(rtfParser, "asianbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("aspalpha", new RtfCtrlWordHandler(rtfParser, "aspalpha", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("aspnum", new RtfCtrlWordHandler(rtfParser, "aspnum", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("astrike", new RtfCtrlWordHandler(rtfParser, "astrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("atnauthor", new RtfCtrlWordHandler(rtfParser, "atnauthor", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atndate", new RtfCtrlWordHandler(rtfParser, "atndate", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atnicn", new RtfCtrlWordHandler(rtfParser, "atnicn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atnid", new RtfCtrlWordHandler(rtfParser, "atnid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atnparent", new RtfCtrlWordHandler(rtfParser, "atnparent", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atnref", new RtfCtrlWordHandler(rtfParser, "atnref", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atntime", new RtfCtrlWordHandler(rtfParser, "atntime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atrfend", new RtfCtrlWordHandler(rtfParser, "atrfend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("atrfstart", new RtfCtrlWordHandler(rtfParser, "atrfstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("aul", new RtfCtrlWordHandler(rtfParser, "aul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("auld", new RtfCtrlWordHandler(rtfParser, "auld", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("auldb", new RtfCtrlWordHandler(rtfParser, "auldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("aulnone", new RtfCtrlWordHandler(rtfParser, "aulnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("aulw", new RtfCtrlWordHandler(rtfParser, "aulw", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("aup", new RtfCtrlWordHandler(rtfParser, "aup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("author", new RtfCtrlWordHandler(rtfParser, "author", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("autofmtoverride", new RtfCtrlWordHandler(rtfParser, "autofmtoverride", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("b", new RtfCtrlWordHandler(rtfParser, "b", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", RtfProperty.CHARACTER_BOLD)); ctrlWords.put("background", new RtfCtrlWordHandler(rtfParser, "background", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("bdbfhdr", new RtfCtrlWordHandler(rtfParser, "bdbfhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bdrrlswsix", new RtfCtrlWordHandler(rtfParser, "bdrrlswsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgbdiag", new RtfCtrlWordHandler(rtfParser, "bgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgcross", new RtfCtrlWordHandler(rtfParser, "bgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdcross", new RtfCtrlWordHandler(rtfParser, "bgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkbdiag", new RtfCtrlWordHandler(rtfParser, "bgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkcross", new RtfCtrlWordHandler(rtfParser, "bgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkdcross", new RtfCtrlWordHandler(rtfParser, "bgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkfdiag", new RtfCtrlWordHandler(rtfParser, "bgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkhoriz", new RtfCtrlWordHandler(rtfParser, "bgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgdkvert", new RtfCtrlWordHandler(rtfParser, "bgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgfdiag", new RtfCtrlWordHandler(rtfParser, "bgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bghoriz", new RtfCtrlWordHandler(rtfParser, "bghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bgvert", new RtfCtrlWordHandler(rtfParser, "bgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bin", new RtfCtrlWordHandler(rtfParser, "bin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("binfsxn", new RtfCtrlWordHandler(rtfParser, "binfsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("binsxn", new RtfCtrlWordHandler(rtfParser, "binsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("bkmkcolf", new RtfCtrlWordHandler(rtfParser, "bkmkcolf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("bkmkcoll", new RtfCtrlWordHandler(rtfParser, "bkmkcoll", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("bkmkend", new RtfCtrlWordHandler(rtfParser, "bkmkend", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("bkmkpub", new RtfCtrlWordHandler(rtfParser, "bkmkpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bkmkstart", new RtfCtrlWordHandler(rtfParser, "bkmkstart", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("bliptag", new RtfCtrlWordHandler(rtfParser, "bliptag", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("blipuid", new RtfCtrlWordHandler(rtfParser, "blipuid", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationBlipuid")); ctrlWords.put("blipupi", new RtfCtrlWordHandler(rtfParser, "blipupi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", "RtfDestinationShppict")); ctrlWords.put("blue", new RtfCtrlWordHandler(rtfParser, "blue", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("bookfold", new RtfCtrlWordHandler(rtfParser, "bookfold", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bookfoldrev", new RtfCtrlWordHandler(rtfParser, "bookfoldrev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("bookfoldsheets", new RtfCtrlWordHandler(rtfParser, "bookfoldsheets", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("box", new RtfCtrlWordHandler(rtfParser, "box", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrart", new RtfCtrlWordHandler(rtfParser, "brdrart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("brdrb", new RtfCtrlWordHandler(rtfParser, "brdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrbar", new RtfCtrlWordHandler(rtfParser, "brdrbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrbtw", new RtfCtrlWordHandler(rtfParser, "brdrbtw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrcf", new RtfCtrlWordHandler(rtfParser, "brdrcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("brdrdash", new RtfCtrlWordHandler(rtfParser, "brdrdash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdashd", new RtfCtrlWordHandler(rtfParser, "brdrdashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdashdd", new RtfCtrlWordHandler(rtfParser, "brdrdashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdashdotstr", new RtfCtrlWordHandler(rtfParser, "brdrdashdotstr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdashsm", new RtfCtrlWordHandler(rtfParser, "brdrdashsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdb", new RtfCtrlWordHandler(rtfParser, "brdrdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrdot", new RtfCtrlWordHandler(rtfParser, "brdrdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdremboss", new RtfCtrlWordHandler(rtfParser, "brdremboss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrengrave", new RtfCtrlWordHandler(rtfParser, "brdrengrave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrframe", new RtfCtrlWordHandler(rtfParser, "brdrframe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrhair", new RtfCtrlWordHandler(rtfParser, "brdrhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrinset", new RtfCtrlWordHandler(rtfParser, "brdrinset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrl", new RtfCtrlWordHandler(rtfParser, "brdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrnil", new RtfCtrlWordHandler(rtfParser, "brdrnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrnone", new RtfCtrlWordHandler(rtfParser, "brdrnone", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("brdroutset", new RtfCtrlWordHandler(rtfParser, "brdroutset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrr", new RtfCtrlWordHandler(rtfParser, "brdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrs", new RtfCtrlWordHandler(rtfParser, "brdrs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrsh", new RtfCtrlWordHandler(rtfParser, "brdrsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrt", new RtfCtrlWordHandler(rtfParser, "brdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtbl", new RtfCtrlWordHandler(rtfParser, "brdrtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrth", new RtfCtrlWordHandler(rtfParser, "brdrth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrthtnlg", new RtfCtrlWordHandler(rtfParser, "brdrthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrthtnmg", new RtfCtrlWordHandler(rtfParser, "brdrthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrthtnsg", new RtfCtrlWordHandler(rtfParser, "brdrthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthlg", new RtfCtrlWordHandler(rtfParser, "brdrtnthlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthmg", new RtfCtrlWordHandler(rtfParser, "brdrtnthmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthsg", new RtfCtrlWordHandler(rtfParser, "brdrtnthsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthtnlg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthtnmg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtnthtnsg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrtriple", new RtfCtrlWordHandler(rtfParser, "brdrtriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrw", new RtfCtrlWordHandler(rtfParser, "brdrw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("brdrwavy", new RtfCtrlWordHandler(rtfParser, "brdrwavy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brdrwavydb", new RtfCtrlWordHandler(rtfParser, "brdrwavydb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brkfrm", new RtfCtrlWordHandler(rtfParser, "brkfrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("brsp", new RtfCtrlWordHandler(rtfParser, "brsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("bullet", new RtfCtrlWordHandler(rtfParser, "bullet", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x149")); ctrlWords.put("buptim", new RtfCtrlWordHandler(rtfParser, "buptim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("bxe", new RtfCtrlWordHandler(rtfParser, "bxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccentfive", new RtfCtrlWordHandler(rtfParser, "caccentfive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccentfour", new RtfCtrlWordHandler(rtfParser, "caccentfour", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccentone", new RtfCtrlWordHandler(rtfParser, "caccentone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccentsix", new RtfCtrlWordHandler(rtfParser, "caccentsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccentthree", new RtfCtrlWordHandler(rtfParser, "caccentthree", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caccenttwo", new RtfCtrlWordHandler(rtfParser, "caccenttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cachedcolbal", new RtfCtrlWordHandler(rtfParser, "cachedcolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("caps", new RtfCtrlWordHandler(rtfParser, "caps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("category", new RtfCtrlWordHandler(rtfParser, "category", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("cb", new RtfCtrlWordHandler(rtfParser, "cb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cbackgroundone", new RtfCtrlWordHandler(rtfParser, "cbackgroundone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cbackgroundtwo", new RtfCtrlWordHandler(rtfParser, "cbackgroundtwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cbpat", new RtfCtrlWordHandler(rtfParser, "cbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cchs", new RtfCtrlWordHandler(rtfParser, "cchs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cell", new RtfCtrlWordHandler(rtfParser, "cell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("cellx", new RtfCtrlWordHandler(rtfParser, "cellx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cf", new RtfCtrlWordHandler(rtfParser, "cf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cfollowedhyperlink", new RtfCtrlWordHandler(rtfParser, "cfollowedhyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cfpat", new RtfCtrlWordHandler(rtfParser, "cfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cgrid", new RtfCtrlWordHandler(rtfParser, "cgrid", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("charrsid", new RtfCtrlWordHandler(rtfParser, "charrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("charscalex", new RtfCtrlWordHandler(rtfParser, "charscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("chatn", new RtfCtrlWordHandler(rtfParser, "chatn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chbgbdiag", new RtfCtrlWordHandler(rtfParser, "chbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgcross", new RtfCtrlWordHandler(rtfParser, "chbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdcross", new RtfCtrlWordHandler(rtfParser, "chbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "chbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkcross", new RtfCtrlWordHandler(rtfParser, "chbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkdcross", new RtfCtrlWordHandler(rtfParser, "chbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "chbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkhoriz", new RtfCtrlWordHandler(rtfParser, "chbgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgdkvert", new RtfCtrlWordHandler(rtfParser, "chbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgfdiag", new RtfCtrlWordHandler(rtfParser, "chbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbghoriz", new RtfCtrlWordHandler(rtfParser, "chbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbgvert", new RtfCtrlWordHandler(rtfParser, "chbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chbrdr", new RtfCtrlWordHandler(rtfParser, "chbrdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("chcbpat", new RtfCtrlWordHandler(rtfParser, "chcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("chcfpat", new RtfCtrlWordHandler(rtfParser, "chcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("chdate", new RtfCtrlWordHandler(rtfParser, "chdate", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chdpa", new RtfCtrlWordHandler(rtfParser, "chdpa", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chdpl", new RtfCtrlWordHandler(rtfParser, "chdpl", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chftn", new RtfCtrlWordHandler(rtfParser, "chftn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chftnsep", new RtfCtrlWordHandler(rtfParser, "chftnsep", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chftnsepc", new RtfCtrlWordHandler(rtfParser, "chftnsepc", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chpgn", new RtfCtrlWordHandler(rtfParser, "chpgn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chshdng", new RtfCtrlWordHandler(rtfParser, "chshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("chtime", new RtfCtrlWordHandler(rtfParser, "chtime", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("chyperlink", new RtfCtrlWordHandler(rtfParser, "chyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clFitText", new RtfCtrlWordHandler(rtfParser, "clFitText", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clNoWrap", new RtfCtrlWordHandler(rtfParser, "clNoWrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgbdiag", new RtfCtrlWordHandler(rtfParser, "clbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgcross", new RtfCtrlWordHandler(rtfParser, "clbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdcross", new RtfCtrlWordHandler(rtfParser, "clbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "clbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkcross", new RtfCtrlWordHandler(rtfParser, "clbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkdcross", new RtfCtrlWordHandler(rtfParser, "clbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "clbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkhor", new RtfCtrlWordHandler(rtfParser, "clbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgdkvert", new RtfCtrlWordHandler(rtfParser, "clbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgfdiag", new RtfCtrlWordHandler(rtfParser, "clbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbghoriz", new RtfCtrlWordHandler(rtfParser, "clbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbgvert", new RtfCtrlWordHandler(rtfParser, "clbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbrdrb", new RtfCtrlWordHandler(rtfParser, "clbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbrdrl", new RtfCtrlWordHandler(rtfParser, "clbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbrdrr", new RtfCtrlWordHandler(rtfParser, "clbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clbrdrt", new RtfCtrlWordHandler(rtfParser, "clbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clcbpat", new RtfCtrlWordHandler(rtfParser, "clcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clcbpatraw", new RtfCtrlWordHandler(rtfParser, "clcbpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clcfpat", new RtfCtrlWordHandler(rtfParser, "clcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clcfpatraw", new RtfCtrlWordHandler(rtfParser, "clcfpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cldel", new RtfCtrlWordHandler(rtfParser, "cldel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cldelauth", new RtfCtrlWordHandler(rtfParser, "cldelauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cldeldttm", new RtfCtrlWordHandler(rtfParser, "cldeldttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cldgll", new RtfCtrlWordHandler(rtfParser, "cldgll", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cldglu", new RtfCtrlWordHandler(rtfParser, "cldglu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clftsWidth", new RtfCtrlWordHandler(rtfParser, "clftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clhidemark", new RtfCtrlWordHandler(rtfParser, "clhidemark", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clins", new RtfCtrlWordHandler(rtfParser, "clins", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clinsauth", new RtfCtrlWordHandler(rtfParser, "clinsauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clinsdttm", new RtfCtrlWordHandler(rtfParser, "clinsdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clmgf", new RtfCtrlWordHandler(rtfParser, "clmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clmrg", new RtfCtrlWordHandler(rtfParser, "clmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clmrgd", new RtfCtrlWordHandler(rtfParser, "clmrgd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clmrgdauth", new RtfCtrlWordHandler(rtfParser, "clmrgdauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clmrgddttm", new RtfCtrlWordHandler(rtfParser, "clmrgddttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clmrgdr", new RtfCtrlWordHandler(rtfParser, "clmrgdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clpadb", new RtfCtrlWordHandler(rtfParser, "clpadb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadfb", new RtfCtrlWordHandler(rtfParser, "clpadfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadfl", new RtfCtrlWordHandler(rtfParser, "clpadfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadfr", new RtfCtrlWordHandler(rtfParser, "clpadfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadft", new RtfCtrlWordHandler(rtfParser, "clpadft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadl", new RtfCtrlWordHandler(rtfParser, "clpadl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadr", new RtfCtrlWordHandler(rtfParser, "clpadr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clpadt", new RtfCtrlWordHandler(rtfParser, "clpadt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clshdng", new RtfCtrlWordHandler(rtfParser, "clshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clshdngraw", new RtfCtrlWordHandler(rtfParser, "clshdngraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("clshdrawnil", new RtfCtrlWordHandler(rtfParser, "clshdrawnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clsplit", new RtfCtrlWordHandler(rtfParser, "clsplit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clsplitr", new RtfCtrlWordHandler(rtfParser, "clsplitr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cltxbtlr", new RtfCtrlWordHandler(rtfParser, "cltxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cltxlrtb", new RtfCtrlWordHandler(rtfParser, "cltxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cltxlrtbv", new RtfCtrlWordHandler(rtfParser, "cltxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cltxtbrl", new RtfCtrlWordHandler(rtfParser, "cltxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cltxtbrlv", new RtfCtrlWordHandler(rtfParser, "cltxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clvertalb", new RtfCtrlWordHandler(rtfParser, "clvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clvertalc", new RtfCtrlWordHandler(rtfParser, "clvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clvertalt", new RtfCtrlWordHandler(rtfParser, "clvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clvmgf", new RtfCtrlWordHandler(rtfParser, "clvmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clvmrg", new RtfCtrlWordHandler(rtfParser, "clvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("clwWidth", new RtfCtrlWordHandler(rtfParser, "clwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cmaindarkone", new RtfCtrlWordHandler(rtfParser, "cmaindarkone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cmaindarktwo", new RtfCtrlWordHandler(rtfParser, "cmaindarktwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cmainlightone", new RtfCtrlWordHandler(rtfParser, "cmainlightone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cmainlighttwo", new RtfCtrlWordHandler(rtfParser, "cmainlighttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("collapsed", new RtfCtrlWordHandler(rtfParser, "collapsed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("colno", new RtfCtrlWordHandler(rtfParser, "colno", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("colorschememapping", new RtfCtrlWordHandler(rtfParser, "colorschememapping", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null)); ctrlWords.put("colortbl", new RtfCtrlWordHandler(rtfParser, "colortbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationColorTable")); ctrlWords.put("cols", new RtfCtrlWordHandler(rtfParser, "cols", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("colsr", new RtfCtrlWordHandler(rtfParser, "colsr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("colsx", new RtfCtrlWordHandler(rtfParser, "colsx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("column", new RtfCtrlWordHandler(rtfParser, "column", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("colw", new RtfCtrlWordHandler(rtfParser, "colw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("comment", new RtfCtrlWordHandler(rtfParser, "comment", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("company", new RtfCtrlWordHandler(rtfParser, "company", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("contextualspace", new RtfCtrlWordHandler(rtfParser, "contextualspace", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cpg", new RtfCtrlWordHandler(rtfParser, "cpg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("crauth", new RtfCtrlWordHandler(rtfParser, "crauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("crdate", new RtfCtrlWordHandler(rtfParser, "crdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("creatim", new RtfCtrlWordHandler(rtfParser, "creatim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("cs", new RtfCtrlWordHandler(rtfParser, "cs", 0, true, RtfCtrlWordType.VALUE, "\\*\\", " ", null)); ctrlWords.put("cshade", new RtfCtrlWordHandler(rtfParser, "cshade", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ctextone", new RtfCtrlWordHandler(rtfParser, "ctextone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ctexttwo", new RtfCtrlWordHandler(rtfParser, "ctexttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ctint", new RtfCtrlWordHandler(rtfParser, "ctint", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ctrl", new RtfCtrlWordHandler(rtfParser, "ctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("cts", new RtfCtrlWordHandler(rtfParser, "cts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cufi", new RtfCtrlWordHandler(rtfParser, "cufi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("culi", new RtfCtrlWordHandler(rtfParser, "culi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("curi", new RtfCtrlWordHandler(rtfParser, "curi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("cvmme", new RtfCtrlWordHandler(rtfParser, "cvmme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("datafield", new RtfCtrlWordHandler(rtfParser, "datafield", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("datastore", new RtfCtrlWordHandler(rtfParser, "datastore", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("date", new RtfCtrlWordHandler(rtfParser, "date", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dbch", new RtfCtrlWordHandler(rtfParser, "dbch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("defchp", new RtfCtrlWordHandler(rtfParser, "defchp", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("deff", new RtfCtrlWordHandler(rtfParser, "deff", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("defformat", new RtfCtrlWordHandler(rtfParser, "defformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("deflang", new RtfCtrlWordHandler(rtfParser, "deflang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("deflangfe", new RtfCtrlWordHandler(rtfParser, "deflangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("defpap", new RtfCtrlWordHandler(rtfParser, "defpap", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("defshp", new RtfCtrlWordHandler(rtfParser, "defshp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("deftab", new RtfCtrlWordHandler(rtfParser, "deftab", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("deleted", new RtfCtrlWordHandler(rtfParser, "deleted", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("delrsid", new RtfCtrlWordHandler(rtfParser, "delrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrauth", new RtfCtrlWordHandler(rtfParser, "dfrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrdate", new RtfCtrlWordHandler(rtfParser, "dfrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrmtxtx", new RtfCtrlWordHandler(rtfParser, "dfrmtxtx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrmtxty", new RtfCtrlWordHandler(rtfParser, "dfrmtxty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrstart", new RtfCtrlWordHandler(rtfParser, "dfrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrstop", new RtfCtrlWordHandler(rtfParser, "dfrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dfrxst", new RtfCtrlWordHandler(rtfParser, "dfrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dghorigin", new RtfCtrlWordHandler(rtfParser, "dghorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dghshow", new RtfCtrlWordHandler(rtfParser, "dghshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dghspace", new RtfCtrlWordHandler(rtfParser, "dghspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dgmargin", new RtfCtrlWordHandler(rtfParser, "dgmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dgsnap", new RtfCtrlWordHandler(rtfParser, "dgsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dgvorigin", new RtfCtrlWordHandler(rtfParser, "dgvorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dgvshow", new RtfCtrlWordHandler(rtfParser, "dgvshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dgvspace", new RtfCtrlWordHandler(rtfParser, "dgvspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dibitmap", new RtfCtrlWordHandler(rtfParser, "dibitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dn", new RtfCtrlWordHandler(rtfParser, "dn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dntblnsbdb", new RtfCtrlWordHandler(rtfParser, "dntblnsbdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("do", new RtfCtrlWordHandler(rtfParser, "do", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("dobxcolumn", new RtfCtrlWordHandler(rtfParser, "dobxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dobxmargin", new RtfCtrlWordHandler(rtfParser, "dobxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dobxpage", new RtfCtrlWordHandler(rtfParser, "dobxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dobymargin", new RtfCtrlWordHandler(rtfParser, "dobymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dobypage", new RtfCtrlWordHandler(rtfParser, "dobypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dobypara", new RtfCtrlWordHandler(rtfParser, "dobypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("doccomm", new RtfCtrlWordHandler(rtfParser, "doccomm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("doctemp", new RtfCtrlWordHandler(rtfParser, "doctemp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("doctype", new RtfCtrlWordHandler(rtfParser, "doctype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("docvar", new RtfCtrlWordHandler(rtfParser, "docvar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("dodhgt", new RtfCtrlWordHandler(rtfParser, "dodhgt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dolock", new RtfCtrlWordHandler(rtfParser, "dolock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotembedlingdata", new RtfCtrlWordHandler(rtfParser, "donotembedlingdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotembedsysfont", new RtfCtrlWordHandler(rtfParser, "donotembedsysfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotshowcomments", new RtfCtrlWordHandler(rtfParser, "donotshowcomments", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotshowinsdel", new RtfCtrlWordHandler(rtfParser, "donotshowinsdel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotshowmarkup", new RtfCtrlWordHandler(rtfParser, "donotshowmarkup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("donotshowprops", new RtfCtrlWordHandler(rtfParser, "donotshowprops", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpaendhol", new RtfCtrlWordHandler(rtfParser, "dpaendhol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpaendl", new RtfCtrlWordHandler(rtfParser, "dpaendl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpaendsol", new RtfCtrlWordHandler(rtfParser, "dpaendsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpaendw", new RtfCtrlWordHandler(rtfParser, "dpaendw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dparc", new RtfCtrlWordHandler(rtfParser, "dparc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dparcflipx", new RtfCtrlWordHandler(rtfParser, "dparcflipx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dparcflipy", new RtfCtrlWordHandler(rtfParser, "dparcflipy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpastarthol", new RtfCtrlWordHandler(rtfParser, "dpastarthol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpastartl", new RtfCtrlWordHandler(rtfParser, "dpastartl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpastartsol", new RtfCtrlWordHandler(rtfParser, "dpastartsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpastartw", new RtfCtrlWordHandler(rtfParser, "dpastartw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcallout", new RtfCtrlWordHandler(rtfParser, "dpcallout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcoa", new RtfCtrlWordHandler(rtfParser, "dpcoa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcoaccent", new RtfCtrlWordHandler(rtfParser, "dpcoaccent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcobestfit", new RtfCtrlWordHandler(rtfParser, "dpcobestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcoborder", new RtfCtrlWordHandler(rtfParser, "dpcoborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcodabs", new RtfCtrlWordHandler(rtfParser, "dpcodabs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcodbottom", new RtfCtrlWordHandler(rtfParser, "dpcodbottom", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcodcenter", new RtfCtrlWordHandler(rtfParser, "dpcodcenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcodescent", new RtfCtrlWordHandler(rtfParser, "dpcodescent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcodtop", new RtfCtrlWordHandler(rtfParser, "dpcodtop", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcolength", new RtfCtrlWordHandler(rtfParser, "dpcolength", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcominusx", new RtfCtrlWordHandler(rtfParser, "dpcominusx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcominusy", new RtfCtrlWordHandler(rtfParser, "dpcominusy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcooffset", new RtfCtrlWordHandler(rtfParser, "dpcooffset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpcosmarta", new RtfCtrlWordHandler(rtfParser, "dpcosmarta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcotdouble", new RtfCtrlWordHandler(rtfParser, "dpcotdouble", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcotright", new RtfCtrlWordHandler(rtfParser, "dpcotright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcotsingle", new RtfCtrlWordHandler(rtfParser, "dpcotsingle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcottriple", new RtfCtrlWordHandler(rtfParser, "dpcottriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpcount", new RtfCtrlWordHandler(rtfParser, "dpcount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpellipse", new RtfCtrlWordHandler(rtfParser, "dpellipse", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpendgroup", new RtfCtrlWordHandler(rtfParser, "dpendgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpfillbgcb", new RtfCtrlWordHandler(rtfParser, "dpfillbgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillbgcg", new RtfCtrlWordHandler(rtfParser, "dpfillbgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillbgcr", new RtfCtrlWordHandler(rtfParser, "dpfillbgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillbggray", new RtfCtrlWordHandler(rtfParser, "dpfillbggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillbgpal", new RtfCtrlWordHandler(rtfParser, "dpfillbgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpfillfgcb", new RtfCtrlWordHandler(rtfParser, "dpfillfgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillfgcg", new RtfCtrlWordHandler(rtfParser, "dpfillfgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillfgcr", new RtfCtrlWordHandler(rtfParser, "dpfillfgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillfggray", new RtfCtrlWordHandler(rtfParser, "dpfillfggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpfillfgpal", new RtfCtrlWordHandler(rtfParser, "dpfillfgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpfillpat", new RtfCtrlWordHandler(rtfParser, "dpfillpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpgroup", new RtfCtrlWordHandler(rtfParser, "dpgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpline", new RtfCtrlWordHandler(rtfParser, "dpline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinecob", new RtfCtrlWordHandler(rtfParser, "dplinecob", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dplinecog", new RtfCtrlWordHandler(rtfParser, "dplinecog", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dplinecor", new RtfCtrlWordHandler(rtfParser, "dplinecor", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dplinedado", new RtfCtrlWordHandler(rtfParser, "dplinedado", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinedadodo", new RtfCtrlWordHandler(rtfParser, "dplinedadodo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinedash", new RtfCtrlWordHandler(rtfParser, "dplinedash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinedot", new RtfCtrlWordHandler(rtfParser, "dplinedot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinegray", new RtfCtrlWordHandler(rtfParser, "dplinegray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dplinehollow", new RtfCtrlWordHandler(rtfParser, "dplinehollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinepal", new RtfCtrlWordHandler(rtfParser, "dplinepal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinesolid", new RtfCtrlWordHandler(rtfParser, "dplinesolid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dplinew", new RtfCtrlWordHandler(rtfParser, "dplinew", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dppolycount", new RtfCtrlWordHandler(rtfParser, "dppolycount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dppolygon", new RtfCtrlWordHandler(rtfParser, "dppolygon", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dppolyline", new RtfCtrlWordHandler(rtfParser, "dppolyline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpptx", new RtfCtrlWordHandler(rtfParser, "dpptx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dppty", new RtfCtrlWordHandler(rtfParser, "dppty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dprect", new RtfCtrlWordHandler(rtfParser, "dprect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dproundr", new RtfCtrlWordHandler(rtfParser, "dproundr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpshadow", new RtfCtrlWordHandler(rtfParser, "dpshadow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpshadx", new RtfCtrlWordHandler(rtfParser, "dpshadx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpshady", new RtfCtrlWordHandler(rtfParser, "dpshady", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dptxbtlr", new RtfCtrlWordHandler(rtfParser, "dptxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dptxbx", new RtfCtrlWordHandler(rtfParser, "dptxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dptxbxmar", new RtfCtrlWordHandler(rtfParser, "dptxbxmar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dptxbxtext", new RtfCtrlWordHandler(rtfParser, "dptxbxtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("dptxlrtb", new RtfCtrlWordHandler(rtfParser, "dptxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dptxlrtbv", new RtfCtrlWordHandler(rtfParser, "dptxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dptxtbrl", new RtfCtrlWordHandler(rtfParser, "dptxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dptxtbrlv", new RtfCtrlWordHandler(rtfParser, "dptxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("dpx", new RtfCtrlWordHandler(rtfParser, "dpx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpxsize", new RtfCtrlWordHandler(rtfParser, "dpxsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpy", new RtfCtrlWordHandler(rtfParser, "dpy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dpysize", new RtfCtrlWordHandler(rtfParser, "dpysize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dropcapli", new RtfCtrlWordHandler(rtfParser, "dropcapli", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dropcapt", new RtfCtrlWordHandler(rtfParser, "dropcapt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ds", new RtfCtrlWordHandler(rtfParser, "ds", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dxfrtext", new RtfCtrlWordHandler(rtfParser, "dxfrtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("dy", new RtfCtrlWordHandler(rtfParser, "dy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ebcend", new RtfCtrlWordHandler(rtfParser, "ebcend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("ebcstart", new RtfCtrlWordHandler(rtfParser, "ebcstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("edmins", new RtfCtrlWordHandler(rtfParser, "edmins", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("embo", new RtfCtrlWordHandler(rtfParser, "embo", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("emdash", new RtfCtrlWordHandler(rtfParser, "emdash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x151")); ctrlWords.put("emfblip", new RtfCtrlWordHandler(rtfParser, "emfblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("emspace", new RtfCtrlWordHandler(rtfParser, "emspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("endash", new RtfCtrlWordHandler(rtfParser, "endash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x150")); ctrlWords.put("enddoc", new RtfCtrlWordHandler(rtfParser, "enddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("endnhere", new RtfCtrlWordHandler(rtfParser, "endnhere", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("endnotes", new RtfCtrlWordHandler(rtfParser, "endnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("enforceprot", new RtfCtrlWordHandler(rtfParser, "enforceprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("enspace", new RtfCtrlWordHandler(rtfParser, "enspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("expnd", new RtfCtrlWordHandler(rtfParser, "expnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("expndtw", new RtfCtrlWordHandler(rtfParser, "expndtw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("expshrtn", new RtfCtrlWordHandler(rtfParser, "expshrtn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("f", new RtfCtrlWordHandler(rtfParser, "f", 0, true, RtfCtrlWordType.VALUE, "\\", " ", RtfProperty.CHARACTER_FONT)); ctrlWords.put("faauto", new RtfCtrlWordHandler(rtfParser, "faauto", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("facenter", new RtfCtrlWordHandler(rtfParser, "facenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("facingp", new RtfCtrlWordHandler(rtfParser, "facingp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("factoidname", new RtfCtrlWordHandler(rtfParser, "factoidname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("fafixed", new RtfCtrlWordHandler(rtfParser, "fafixed", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fahang", new RtfCtrlWordHandler(rtfParser, "fahang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("falt", new RtfCtrlWordHandler(rtfParser, "falt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable")); //"RtfDestinationAlternateFont")); ctrlWords.put("faroman", new RtfCtrlWordHandler(rtfParser, "faroman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("favar", new RtfCtrlWordHandler(rtfParser, "favar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fbias", new RtfCtrlWordHandler(rtfParser, "fbias", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fbidi", new RtfCtrlWordHandler(rtfParser, "fbidi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fbimajor", new RtfCtrlWordHandler(rtfParser, "fbimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fbiminor", new RtfCtrlWordHandler(rtfParser, "fbiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fchars", new RtfCtrlWordHandler(rtfParser, "fchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null)); ctrlWords.put("fcharset", new RtfCtrlWordHandler(rtfParser, "fcharset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fdbmajor", new RtfCtrlWordHandler(rtfParser, "fdbmajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fdbminor", new RtfCtrlWordHandler(rtfParser, "fdbminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fdecor", new RtfCtrlWordHandler(rtfParser, "fdecor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("felnbrelev", new RtfCtrlWordHandler(rtfParser, "felnbrelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fet", new RtfCtrlWordHandler(rtfParser, "fet", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fetch", new RtfCtrlWordHandler(rtfParser, "fetch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ffdefres", new RtfCtrlWordHandler(rtfParser, "ffdefres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffdeftext", new RtfCtrlWordHandler(rtfParser, "ffdeftext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffentrymcr", new RtfCtrlWordHandler(rtfParser, "ffentrymcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffexitmcr", new RtfCtrlWordHandler(rtfParser, "ffexitmcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffformat", new RtfCtrlWordHandler(rtfParser, "ffformat", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffhaslistbox", new RtfCtrlWordHandler(rtfParser, "ffhaslistbox", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffhelptext", new RtfCtrlWordHandler(rtfParser, "ffhelptext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffhps", new RtfCtrlWordHandler(rtfParser, "ffhps", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffl", new RtfCtrlWordHandler(rtfParser, "ffl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffmaxlen", new RtfCtrlWordHandler(rtfParser, "ffmaxlen", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffname", new RtfCtrlWordHandler(rtfParser, "ffname", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("ffownhelp", new RtfCtrlWordHandler(rtfParser, "ffownhelp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffownstat", new RtfCtrlWordHandler(rtfParser, "ffownstat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffprot", new RtfCtrlWordHandler(rtfParser, "ffprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffrecalc", new RtfCtrlWordHandler(rtfParser, "ffrecalc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffres", new RtfCtrlWordHandler(rtfParser, "ffres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffsize", new RtfCtrlWordHandler(rtfParser, "ffsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ffstattext", new RtfCtrlWordHandler(rtfParser, "ffstattext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fftype", new RtfCtrlWordHandler(rtfParser, "fftype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fftypetxt", new RtfCtrlWordHandler(rtfParser, "fftypetxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fhimajor", new RtfCtrlWordHandler(rtfParser, "fhimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fhiminor", new RtfCtrlWordHandler(rtfParser, "fhiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fi", new RtfCtrlWordHandler(rtfParser, "fi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fid", new RtfCtrlWordHandler(rtfParser, "fid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("field", new RtfCtrlWordHandler(rtfParser, "field", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("file", new RtfCtrlWordHandler(rtfParser, "file", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("filetbl", new RtfCtrlWordHandler(rtfParser, "filetbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fittext", new RtfCtrlWordHandler(rtfParser, "fittext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fjgothic", new RtfCtrlWordHandler(rtfParser, "fjgothic", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fjminchou", new RtfCtrlWordHandler(rtfParser, "fjminchou", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fldalt", new RtfCtrlWordHandler(rtfParser, "fldalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("flddirty", new RtfCtrlWordHandler(rtfParser, "flddirty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fldedit", new RtfCtrlWordHandler(rtfParser, "fldedit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fldinst", new RtfCtrlWordHandler(rtfParser, "fldinst", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("fldlock", new RtfCtrlWordHandler(rtfParser, "fldlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fldpriv", new RtfCtrlWordHandler(rtfParser, "fldpriv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fldrslt", new RtfCtrlWordHandler(rtfParser, "fldrslt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fldtype", new RtfCtrlWordHandler(rtfParser, "fldtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("flomajor", new RtfCtrlWordHandler(rtfParser, "flomajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("flominor", new RtfCtrlWordHandler(rtfParser, "flominor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fmodern", new RtfCtrlWordHandler(rtfParser, "fmodern", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fn", new RtfCtrlWordHandler(rtfParser, "fn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fname", new RtfCtrlWordHandler(rtfParser, "fname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fnetwork", new RtfCtrlWordHandler(rtfParser, "fnetwork", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fnil", new RtfCtrlWordHandler(rtfParser, "fnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fnonfilesys", new RtfCtrlWordHandler(rtfParser, "fnonfilesys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fontemb", new RtfCtrlWordHandler(rtfParser, "fontemb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fontfile", new RtfCtrlWordHandler(rtfParser, "fontfile", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("fonttbl", new RtfCtrlWordHandler(rtfParser, "fonttbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable")); ctrlWords.put("footer", new RtfCtrlWordHandler(rtfParser, "footer", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("footerf", new RtfCtrlWordHandler(rtfParser, "footerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("footerl", new RtfCtrlWordHandler(rtfParser, "footerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("footerr", new RtfCtrlWordHandler(rtfParser, "footerr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("footery", new RtfCtrlWordHandler(rtfParser, "footery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("footnote", new RtfCtrlWordHandler(rtfParser, "footnote", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("forceupgrade", new RtfCtrlWordHandler(rtfParser, "forceupgrade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("formdisp", new RtfCtrlWordHandler(rtfParser, "formdisp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("formfield", new RtfCtrlWordHandler(rtfParser, "formfield", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("formprot", new RtfCtrlWordHandler(rtfParser, "formprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("formshade", new RtfCtrlWordHandler(rtfParser, "formshade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fosnum", new RtfCtrlWordHandler(rtfParser, "fosnum", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fprq", new RtfCtrlWordHandler(rtfParser, "fprq", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fracwidth", new RtfCtrlWordHandler(rtfParser, "fracwidth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("frelative", new RtfCtrlWordHandler(rtfParser, "frelative", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("frmtxbtlr", new RtfCtrlWordHandler(rtfParser, "frmtxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("frmtxlrtb", new RtfCtrlWordHandler(rtfParser, "frmtxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("frmtxlrtbv", new RtfCtrlWordHandler(rtfParser, "frmtxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("frmtxtbrl", new RtfCtrlWordHandler(rtfParser, "frmtxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("frmtxtbrlv", new RtfCtrlWordHandler(rtfParser, "frmtxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("froman", new RtfCtrlWordHandler(rtfParser, "froman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fromhtml", new RtfCtrlWordHandler(rtfParser, "fromhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fromtext", new RtfCtrlWordHandler(rtfParser, "fromtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fs", new RtfCtrlWordHandler(rtfParser, "fs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("fscript", new RtfCtrlWordHandler(rtfParser, "fscript", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fswiss", new RtfCtrlWordHandler(rtfParser, "fswiss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftech", new RtfCtrlWordHandler(rtfParser, "ftech", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnalt", new RtfCtrlWordHandler(rtfParser, "ftnalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnbj", new RtfCtrlWordHandler(rtfParser, "ftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftncn", new RtfCtrlWordHandler(rtfParser, "ftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ftnil", new RtfCtrlWordHandler(rtfParser, "ftnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnlytwnine", new RtfCtrlWordHandler(rtfParser, "ftnlytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnalc", new RtfCtrlWordHandler(rtfParser, "ftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnar", new RtfCtrlWordHandler(rtfParser, "ftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnauc", new RtfCtrlWordHandler(rtfParser, "ftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnchi", new RtfCtrlWordHandler(rtfParser, "ftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnchosung", new RtfCtrlWordHandler(rtfParser, "ftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnncnum", new RtfCtrlWordHandler(rtfParser, "ftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnndbar", new RtfCtrlWordHandler(rtfParser, "ftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnndbnum", new RtfCtrlWordHandler(rtfParser, "ftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnndbnumd", new RtfCtrlWordHandler(rtfParser, "ftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnndbnumk", new RtfCtrlWordHandler(rtfParser, "ftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnndbnumt", new RtfCtrlWordHandler(rtfParser, "ftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnganada", new RtfCtrlWordHandler(rtfParser, "ftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnngbnum", new RtfCtrlWordHandler(rtfParser, "ftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnngbnumd", new RtfCtrlWordHandler(rtfParser, "ftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnngbnumk", new RtfCtrlWordHandler(rtfParser, "ftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnngbnuml", new RtfCtrlWordHandler(rtfParser, "ftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnrlc", new RtfCtrlWordHandler(rtfParser, "ftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnruc", new RtfCtrlWordHandler(rtfParser, "ftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnzodiac", new RtfCtrlWordHandler(rtfParser, "ftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "ftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "ftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnrestart", new RtfCtrlWordHandler(rtfParser, "ftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnrstcont", new RtfCtrlWordHandler(rtfParser, "ftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnrstpg", new RtfCtrlWordHandler(rtfParser, "ftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ftnsep", new RtfCtrlWordHandler(rtfParser, "ftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("ftnsepc", new RtfCtrlWordHandler(rtfParser, "ftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("ftnstart", new RtfCtrlWordHandler(rtfParser, "ftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ftntj", new RtfCtrlWordHandler(rtfParser, "ftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fttruetype", new RtfCtrlWordHandler(rtfParser, "fttruetype", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fvaliddos", new RtfCtrlWordHandler(rtfParser, "fvaliddos", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fvalidhpfs", new RtfCtrlWordHandler(rtfParser, "fvalidhpfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fvalidmac", new RtfCtrlWordHandler(rtfParser, "fvalidmac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("fvalidntfs", new RtfCtrlWordHandler(rtfParser, "fvalidntfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("g", new RtfCtrlWordHandler(rtfParser, "g", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("gcw", new RtfCtrlWordHandler(rtfParser, "gcw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("generator", new RtfCtrlWordHandler(rtfParser, "generator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("green", new RtfCtrlWordHandler(rtfParser, "green", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("gridtbl", new RtfCtrlWordHandler(rtfParser, "gridtbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("gutter", new RtfCtrlWordHandler(rtfParser, "gutter", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("gutterprl", new RtfCtrlWordHandler(rtfParser, "gutterprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("guttersxn", new RtfCtrlWordHandler(rtfParser, "guttersxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("header", new RtfCtrlWordHandler(rtfParser, "header", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("headerf", new RtfCtrlWordHandler(rtfParser, "headerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("headerl", new RtfCtrlWordHandler(rtfParser, "headerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("headerr", new RtfCtrlWordHandler(rtfParser, "headerr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("headery", new RtfCtrlWordHandler(rtfParser, "headery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hich", new RtfCtrlWordHandler(rtfParser, "hich", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("highlight", new RtfCtrlWordHandler(rtfParser, "highlight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hlfr", new RtfCtrlWordHandler(rtfParser, "hlfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hlinkbase", new RtfCtrlWordHandler(rtfParser, "hlinkbase", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hlloc", new RtfCtrlWordHandler(rtfParser, "hlloc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hlsrc", new RtfCtrlWordHandler(rtfParser, "hlsrc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("horzdoc", new RtfCtrlWordHandler(rtfParser, "horzdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("horzsect", new RtfCtrlWordHandler(rtfParser, "horzsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("horzvert", new RtfCtrlWordHandler(rtfParser, "horzvert", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hr", new RtfCtrlWordHandler(rtfParser, "hr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hsv", new RtfCtrlWordHandler(rtfParser, "hsv", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("htmautsp", new RtfCtrlWordHandler(rtfParser, "htmautsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("htmlbase", new RtfCtrlWordHandler(rtfParser, "htmlbase", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("htmlrtf", new RtfCtrlWordHandler(rtfParser, "htmlrtf", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("htmltag", new RtfCtrlWordHandler(rtfParser, "htmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("hwelev", new RtfCtrlWordHandler(rtfParser, "hwelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("hyphauto", new RtfCtrlWordHandler(rtfParser, "hyphauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("hyphcaps", new RtfCtrlWordHandler(rtfParser, "hyphcaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("hyphconsec", new RtfCtrlWordHandler(rtfParser, "hyphconsec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hyphhotz", new RtfCtrlWordHandler(rtfParser, "hyphhotz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("hyphpar", new RtfCtrlWordHandler(rtfParser, "hyphpar", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("i", new RtfCtrlWordHandler(rtfParser, "i", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("id", new RtfCtrlWordHandler(rtfParser, "id", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ignoremixedcontent", new RtfCtrlWordHandler(rtfParser, "ignoremixedcontent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ilfomacatclnup", new RtfCtrlWordHandler(rtfParser, "ilfomacatclnup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ilvl", new RtfCtrlWordHandler(rtfParser, "ilvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("impr", new RtfCtrlWordHandler(rtfParser, "impr", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("indmirror", new RtfCtrlWordHandler(rtfParser, "indmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("indrlsweleven", new RtfCtrlWordHandler(rtfParser, "indrlsweleven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("info", new RtfCtrlWordHandler(rtfParser, "info", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("insrsid", new RtfCtrlWordHandler(rtfParser, "insrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("intbl", new RtfCtrlWordHandler(rtfParser, "intbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ipgp", new RtfCtrlWordHandler(rtfParser, "ipgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("irow", new RtfCtrlWordHandler(rtfParser, "irow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("irowband", new RtfCtrlWordHandler(rtfParser, "irowband", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("itap", new RtfCtrlWordHandler(rtfParser, "itap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ixe", new RtfCtrlWordHandler(rtfParser, "ixe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("jclisttab", new RtfCtrlWordHandler(rtfParser, "jclisttab", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("jcompress", new RtfCtrlWordHandler(rtfParser, "jcompress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("jexpand", new RtfCtrlWordHandler(rtfParser, "jexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("jis", new RtfCtrlWordHandler(rtfParser, "jis", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("jpegblip", new RtfCtrlWordHandler(rtfParser, "jpegblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("jsksu", new RtfCtrlWordHandler(rtfParser, "jsksu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("keep", new RtfCtrlWordHandler(rtfParser, "keep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("keepn", new RtfCtrlWordHandler(rtfParser, "keepn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("kerning", new RtfCtrlWordHandler(rtfParser, "kerning", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("keycode", new RtfCtrlWordHandler(rtfParser, "keycode", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("keywords", new RtfCtrlWordHandler(rtfParser, "keywords", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("krnprsnet", new RtfCtrlWordHandler(rtfParser, "krnprsnet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ksulang", new RtfCtrlWordHandler(rtfParser, "ksulang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("landscape", new RtfCtrlWordHandler(rtfParser, "landscape", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lang", new RtfCtrlWordHandler(rtfParser, "lang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("langfe", new RtfCtrlWordHandler(rtfParser, "langfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("langfenp", new RtfCtrlWordHandler(rtfParser, "langfenp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("langnp", new RtfCtrlWordHandler(rtfParser, "langnp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lastrow", new RtfCtrlWordHandler(rtfParser, "lastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("latentstyles", new RtfCtrlWordHandler(rtfParser, "latentstyles", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("lbr", new RtfCtrlWordHandler(rtfParser, "lbr", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("lchars", new RtfCtrlWordHandler(rtfParser, "lchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("ldblquote", new RtfCtrlWordHandler(rtfParser, "ldblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x147")); ctrlWords.put("level", new RtfCtrlWordHandler(rtfParser, "level", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelfollow", new RtfCtrlWordHandler(rtfParser, "levelfollow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelindent", new RtfCtrlWordHandler(rtfParser, "levelindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("leveljc", new RtfCtrlWordHandler(rtfParser, "leveljc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("leveljcn", new RtfCtrlWordHandler(rtfParser, "leveljcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levellegal", new RtfCtrlWordHandler(rtfParser, "levellegal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelnfc", new RtfCtrlWordHandler(rtfParser, "levelnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelnfcn", new RtfCtrlWordHandler(rtfParser, "levelnfcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelnorestart", new RtfCtrlWordHandler(rtfParser, "levelnorestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelnumbers", new RtfCtrlWordHandler(rtfParser, "levelnumbers", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); // ctrlWords.put("levelnumbers", new RtfCtrlWordHandler(rtfParser, "levelnumbers", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationListTable")); ctrlWords.put("levelold", new RtfCtrlWordHandler(rtfParser, "levelold", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelpicture", new RtfCtrlWordHandler(rtfParser, "levelpicture", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelprev", new RtfCtrlWordHandler(rtfParser, "levelprev", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelprevspace", new RtfCtrlWordHandler(rtfParser, "levelprevspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelspace", new RtfCtrlWordHandler(rtfParser, "levelspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("levelstartat", new RtfCtrlWordHandler(rtfParser, "levelstartat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("leveltemplateid", new RtfCtrlWordHandler(rtfParser, "leveltemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("leveltext", new RtfCtrlWordHandler(rtfParser, "leveltext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("li", new RtfCtrlWordHandler(rtfParser, "li", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lin", new RtfCtrlWordHandler(rtfParser, "lin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("line", new RtfCtrlWordHandler(rtfParser, "line", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("linebetcol", new RtfCtrlWordHandler(rtfParser, "linebetcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linecont", new RtfCtrlWordHandler(rtfParser, "linecont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linemod", new RtfCtrlWordHandler(rtfParser, "linemod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lineppage", new RtfCtrlWordHandler(rtfParser, "lineppage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linerestart", new RtfCtrlWordHandler(rtfParser, "linerestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linestart", new RtfCtrlWordHandler(rtfParser, "linestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("linestarts", new RtfCtrlWordHandler(rtfParser, "linestarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("linex", new RtfCtrlWordHandler(rtfParser, "linex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("linkself", new RtfCtrlWordHandler(rtfParser, "linkself", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linkstyles", new RtfCtrlWordHandler(rtfParser, "linkstyles", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("linktoquery", new RtfCtrlWordHandler(rtfParser, "linktoquery", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("linkval", new RtfCtrlWordHandler(rtfParser, "linkval", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lisa", new RtfCtrlWordHandler(rtfParser, "lisa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lisb", new RtfCtrlWordHandler(rtfParser, "lisb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("list", new RtfCtrlWordHandler(rtfParser, "list", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listlevel", new RtfCtrlWordHandler(rtfParser, "listlevel", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listhybrid", new RtfCtrlWordHandler(rtfParser, "listhybrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("listid", new RtfCtrlWordHandler(rtfParser, "listid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listname", new RtfCtrlWordHandler(rtfParser, "listname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("listoverride", new RtfCtrlWordHandler(rtfParser, "listoverride", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("listoverridecount", new RtfCtrlWordHandler(rtfParser, "listoverridecount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listoverrideformat", new RtfCtrlWordHandler(rtfParser, "listoverrideformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listoverridestart", new RtfCtrlWordHandler(rtfParser, "listoverridestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listoverridestartat", new RtfCtrlWordHandler(rtfParser, "listoverridestartat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("listoverridetable", new RtfCtrlWordHandler(rtfParser, "listoverridetable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull")); ctrlWords.put("listpicture", new RtfCtrlWordHandler(rtfParser, "listpicture", 0, true, RtfCtrlWordType.DESTINATION, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("listrestarthdn", new RtfCtrlWordHandler(rtfParser, "listrestarthdn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listsimple", new RtfCtrlWordHandler(rtfParser, "listsimple", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("liststyleid", new RtfCtrlWordHandler(rtfParser, "liststyleid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("liststylename", new RtfCtrlWordHandler(rtfParser, "liststylename", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listtable", new RtfCtrlWordHandler(rtfParser, "listtable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationListTable")); ctrlWords.put("listtemplateid", new RtfCtrlWordHandler(rtfParser, "listtemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("listtext", new RtfCtrlWordHandler(rtfParser, "listtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); // ignore this because we understand 97-2007 ctrlWords.put("lnbrkrule", new RtfCtrlWordHandler(rtfParser, "lnbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lndscpsxn", new RtfCtrlWordHandler(rtfParser, "lndscpsxn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lnongrid", new RtfCtrlWordHandler(rtfParser, "lnongrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("loch", new RtfCtrlWordHandler(rtfParser, "loch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lquote", new RtfCtrlWordHandler(rtfParser, "lquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x145")); ctrlWords.put("ls", new RtfCtrlWordHandler(rtfParser, "ls", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdlocked", new RtfCtrlWordHandler(rtfParser, "lsdlocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdlockeddef", new RtfCtrlWordHandler(rtfParser, "lsdlockeddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdlockedexcept", new RtfCtrlWordHandler(rtfParser, "lsdlockedexcept", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("lsdpriority", new RtfCtrlWordHandler(rtfParser, "lsdpriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdprioritydef", new RtfCtrlWordHandler(rtfParser, "lsdprioritydef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdqformat", new RtfCtrlWordHandler(rtfParser, "lsdqformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdqformatdef", new RtfCtrlWordHandler(rtfParser, "lsdqformatdef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdsemihidden", new RtfCtrlWordHandler(rtfParser, "lsdsemihidden", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdsemihiddendef", new RtfCtrlWordHandler(rtfParser, "lsdsemihiddendef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdstimax", new RtfCtrlWordHandler(rtfParser, "lsdstimax", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdunhideused", new RtfCtrlWordHandler(rtfParser, "lsdunhideused", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("lsdunhideuseddef", new RtfCtrlWordHandler(rtfParser, "lsdunhideuseddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ltrch", new RtfCtrlWordHandler(rtfParser, "ltrch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ltrdoc", new RtfCtrlWordHandler(rtfParser, "ltrdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ltrmark", new RtfCtrlWordHandler(rtfParser, "ltrmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("ltrpar", new RtfCtrlWordHandler(rtfParser, "ltrpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ltrrow", new RtfCtrlWordHandler(rtfParser, "ltrrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ltrsect", new RtfCtrlWordHandler(rtfParser, "ltrsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lvltentative", new RtfCtrlWordHandler(rtfParser, "lvltentative", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lytcalctblwd", new RtfCtrlWordHandler(rtfParser, "lytcalctblwd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lytexcttp", new RtfCtrlWordHandler(rtfParser, "lytexcttp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lytprtmet", new RtfCtrlWordHandler(rtfParser, "lytprtmet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("lyttblrtgr", new RtfCtrlWordHandler(rtfParser, "lyttblrtgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mac", new RtfCtrlWordHandler(rtfParser, "mac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("macc", new RtfCtrlWordHandler(rtfParser, "macc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("maccpr", new RtfCtrlWordHandler(rtfParser, "maccpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("macpict", new RtfCtrlWordHandler(rtfParser, "macpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mailmerge", new RtfCtrlWordHandler(rtfParser, "mailmerge", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("makebackup", new RtfCtrlWordHandler(rtfParser, "makebackup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("maln", new RtfCtrlWordHandler(rtfParser, "maln", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("malnscr", new RtfCtrlWordHandler(rtfParser, "malnscr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("manager", new RtfCtrlWordHandler(rtfParser, "manager", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("margb", new RtfCtrlWordHandler(rtfParser, "margb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margbsxn", new RtfCtrlWordHandler(rtfParser, "margbsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margl", new RtfCtrlWordHandler(rtfParser, "margl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("marglsxn", new RtfCtrlWordHandler(rtfParser, "marglsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margmirror", new RtfCtrlWordHandler(rtfParser, "margmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("margmirsxn", new RtfCtrlWordHandler(rtfParser, "margmirsxn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margpr", new RtfCtrlWordHandler(rtfParser, "margpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("margr", new RtfCtrlWordHandler(rtfParser, "margr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margrsxn", new RtfCtrlWordHandler(rtfParser, "margrsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margsz", new RtfCtrlWordHandler(rtfParser, "margsz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margt", new RtfCtrlWordHandler(rtfParser, "margt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("margtsxn", new RtfCtrlWordHandler(rtfParser, "margtsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mbar", new RtfCtrlWordHandler(rtfParser, "mbar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mbarpr", new RtfCtrlWordHandler(rtfParser, "mbarpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mbasejc", new RtfCtrlWordHandler(rtfParser, "mbasejc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mbegchr", new RtfCtrlWordHandler(rtfParser, "mbegchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mborderbox", new RtfCtrlWordHandler(rtfParser, "mborderbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mborderboxpr", new RtfCtrlWordHandler(rtfParser, "mborderboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mbox", new RtfCtrlWordHandler(rtfParser, "mbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mboxpr", new RtfCtrlWordHandler(rtfParser, "mboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mbrk", new RtfCtrlWordHandler(rtfParser, "mbrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mbrkbin", new RtfCtrlWordHandler(rtfParser, "mbrkbin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mbrkbinsub", new RtfCtrlWordHandler(rtfParser, "mbrkbinsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mcgp", new RtfCtrlWordHandler(rtfParser, "mcgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mcgprule", new RtfCtrlWordHandler(rtfParser, "mcgprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mchr", new RtfCtrlWordHandler(rtfParser, "mchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mcount", new RtfCtrlWordHandler(rtfParser, "mcount", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mcsp", new RtfCtrlWordHandler(rtfParser, "mcsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mctrlpr", new RtfCtrlWordHandler(rtfParser, "mctrlpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("md", new RtfCtrlWordHandler(rtfParser, "md", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mdefjc", new RtfCtrlWordHandler(rtfParser, "mdefjc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mdeg", new RtfCtrlWordHandler(rtfParser, "mdeg", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mdeghide", new RtfCtrlWordHandler(rtfParser, "mdeghide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mden", new RtfCtrlWordHandler(rtfParser, "mden", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mdiff", new RtfCtrlWordHandler(rtfParser, "mdiff", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mdispdef", new RtfCtrlWordHandler(rtfParser, "mdispdef", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mdpr", new RtfCtrlWordHandler(rtfParser, "mdpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("me", new RtfCtrlWordHandler(rtfParser, "me", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mendchr", new RtfCtrlWordHandler(rtfParser, "mendchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("meqarr", new RtfCtrlWordHandler(rtfParser, "meqarr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("meqarrpr", new RtfCtrlWordHandler(rtfParser, "meqarrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mf", new RtfCtrlWordHandler(rtfParser, "mf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mfname", new RtfCtrlWordHandler(rtfParser, "mfname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mfpr", new RtfCtrlWordHandler(rtfParser, "mfpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mfunc", new RtfCtrlWordHandler(rtfParser, "mfunc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mfuncpr", new RtfCtrlWordHandler(rtfParser, "mfuncpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mgroupchr", new RtfCtrlWordHandler(rtfParser, "mgroupchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mgroupchrpr", new RtfCtrlWordHandler(rtfParser, "mgroupchrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mgrow", new RtfCtrlWordHandler(rtfParser, "mgrow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mhidebot", new RtfCtrlWordHandler(rtfParser, "mhidebot", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mhideleft", new RtfCtrlWordHandler(rtfParser, "mhideleft", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mhideright", new RtfCtrlWordHandler(rtfParser, "mhideright", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mhidetop", new RtfCtrlWordHandler(rtfParser, "mhidetop", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mhtmltag", new RtfCtrlWordHandler(rtfParser, "mhtmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("min", new RtfCtrlWordHandler(rtfParser, "min", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mintersp", new RtfCtrlWordHandler(rtfParser, "mintersp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mintlim", new RtfCtrlWordHandler(rtfParser, "mintlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mintrasp", new RtfCtrlWordHandler(rtfParser, "mintrasp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mjc", new RtfCtrlWordHandler(rtfParser, "mjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlim", new RtfCtrlWordHandler(rtfParser, "mlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlimloc", new RtfCtrlWordHandler(rtfParser, "mlimloc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlimlow", new RtfCtrlWordHandler(rtfParser, "mlimlow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlimlowpr", new RtfCtrlWordHandler(rtfParser, "mlimlowpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlimupp", new RtfCtrlWordHandler(rtfParser, "mlimupp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlimupppr", new RtfCtrlWordHandler(rtfParser, "mlimupppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mlit", new RtfCtrlWordHandler(rtfParser, "mlit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mlmargin", new RtfCtrlWordHandler(rtfParser, "mlmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mm", new RtfCtrlWordHandler(rtfParser, "mm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmaddfieldname", new RtfCtrlWordHandler(rtfParser, "mmaddfieldname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmath", new RtfCtrlWordHandler(rtfParser, "mmath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmathfont", new RtfCtrlWordHandler(rtfParser, "mmathfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmathpara", new RtfCtrlWordHandler(rtfParser, "mmathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmathpict", new RtfCtrlWordHandler(rtfParser, "mmathpict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmathpr", new RtfCtrlWordHandler(rtfParser, "mmathpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmattach", new RtfCtrlWordHandler(rtfParser, "mmattach", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmaxdist", new RtfCtrlWordHandler(rtfParser, "mmaxdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmblanklines", new RtfCtrlWordHandler(rtfParser, "mmblanklines", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmblanklinks", new RtfCtrlWordHandler(rtfParser, "mmblanklinks", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmc", new RtfCtrlWordHandler(rtfParser, "mmc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmcjc", new RtfCtrlWordHandler(rtfParser, "mmcjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmconnectstrdata", new RtfCtrlWordHandler(rtfParser, "mmconnectstrdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null)); ctrlWords.put("mmcpr", new RtfCtrlWordHandler(rtfParser, "mmcpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmcs", new RtfCtrlWordHandler(rtfParser, "mmcs", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmdatasource", new RtfCtrlWordHandler(rtfParser, "mmdatasource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmdatatypeaccess", new RtfCtrlWordHandler(rtfParser, "mmdatatypeaccess", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdatatypeexcel", new RtfCtrlWordHandler(rtfParser, "mmdatatypeexcel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdatatypefile", new RtfCtrlWordHandler(rtfParser, "mmdatatypefile", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdatatypeodbc", new RtfCtrlWordHandler(rtfParser, "mmdatatypeodbc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdatatypeodso", new RtfCtrlWordHandler(rtfParser, "mmdatatypeodso", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdatatypeqt", new RtfCtrlWordHandler(rtfParser, "mmdatatypeqt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdefaultStructuredQueryLanguage", new RtfCtrlWordHandler(rtfParser, "mmdefaultStructuredQueryLanguage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdestemail", new RtfCtrlWordHandler(rtfParser, "mmdestemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdestfax", new RtfCtrlWordHandler(rtfParser, "mmdestfax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdestnewdoc", new RtfCtrlWordHandler(rtfParser, "mmdestnewdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmdestprinter", new RtfCtrlWordHandler(rtfParser, "mmdestprinter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmerrors", new RtfCtrlWordHandler(rtfParser, "mmerrors", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmfttypeaddress", new RtfCtrlWordHandler(rtfParser, "mmfttypeaddress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmfttypebarcode", new RtfCtrlWordHandler(rtfParser, "mmfttypebarcode", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmfttypedbcolumn", new RtfCtrlWordHandler(rtfParser, "mmfttypedbcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmfttypemapped", new RtfCtrlWordHandler(rtfParser, "mmfttypemapped", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmfttypenull", new RtfCtrlWordHandler(rtfParser, "mmfttypenull", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmfttypesalutation", new RtfCtrlWordHandler(rtfParser, "mmfttypesalutation", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmheadersource", new RtfCtrlWordHandler(rtfParser, "mmheadersource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmjdsotype", new RtfCtrlWordHandler(rtfParser, "mmjdsotype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmlinktoquery", new RtfCtrlWordHandler(rtfParser, "mmlinktoquery", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmailsubject", new RtfCtrlWordHandler(rtfParser, "mmmailsubject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmmaintypecatalog", new RtfCtrlWordHandler(rtfParser, "mmmaintypecatalog", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmaintypeemail", new RtfCtrlWordHandler(rtfParser, "mmmaintypeemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmaintypeenvelopes", new RtfCtrlWordHandler(rtfParser, "mmmaintypeenvelopes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmaintypefax", new RtfCtrlWordHandler(rtfParser, "mmmaintypefax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmaintypelabels", new RtfCtrlWordHandler(rtfParser, "mmmaintypelabels", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmmaintypeletters", new RtfCtrlWordHandler(rtfParser, "mmmaintypeletters", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mmodso", new RtfCtrlWordHandler(rtfParser, "mmodso", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsoactive", new RtfCtrlWordHandler(rtfParser, "mmodsoactive", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsocoldelim", new RtfCtrlWordHandler(rtfParser, "mmodsocoldelim", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsocolumn", new RtfCtrlWordHandler(rtfParser, "mmodsocolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsodynaddr", new RtfCtrlWordHandler(rtfParser, "mmodsodynaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsofhdr", new RtfCtrlWordHandler(rtfParser, "mmodsofhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsofilter", new RtfCtrlWordHandler(rtfParser, "mmodsofilter", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsofldmpdata", new RtfCtrlWordHandler(rtfParser, "mmodsofldmpdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsofmcolumn", new RtfCtrlWordHandler(rtfParser, "mmodsofmcolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsohash", new RtfCtrlWordHandler(rtfParser, "mmodsohash", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsolid", new RtfCtrlWordHandler(rtfParser, "mmodsolid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmodsomappedname", new RtfCtrlWordHandler(rtfParser, "mmodsomappedname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsoname", new RtfCtrlWordHandler(rtfParser, "mmodsoname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null)); ctrlWords.put("mmodsorecipdata", new RtfCtrlWordHandler(rtfParser, "mmodsorecipdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsosort", new RtfCtrlWordHandler(rtfParser, "mmodsosort", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsosrc", new RtfCtrlWordHandler(rtfParser, "mmodsosrc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsotable", new RtfCtrlWordHandler(rtfParser, "mmodsotable", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsoudldata", new RtfCtrlWordHandler(rtfParser, "mmodsoudldata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmodsouniquetag", new RtfCtrlWordHandler(rtfParser, "mmodsouniquetag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmpr", new RtfCtrlWordHandler(rtfParser, "mmpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmquery", new RtfCtrlWordHandler(rtfParser, "mmquery", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmr", new RtfCtrlWordHandler(rtfParser, "mmr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mmreccur", new RtfCtrlWordHandler(rtfParser, "mmreccur", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mmshowdata", new RtfCtrlWordHandler(rtfParser, "mmshowdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mnary", new RtfCtrlWordHandler(rtfParser, "mnary", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mnarylim", new RtfCtrlWordHandler(rtfParser, "mnarylim", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mnarypr", new RtfCtrlWordHandler(rtfParser, "mnarypr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mnobreak", new RtfCtrlWordHandler(rtfParser, "mnobreak", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mnor", new RtfCtrlWordHandler(rtfParser, "mnor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mnum", new RtfCtrlWordHandler(rtfParser, "mnum", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mo", new RtfCtrlWordHandler(rtfParser, "mo", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mobjdist", new RtfCtrlWordHandler(rtfParser, "mobjdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("momath", new RtfCtrlWordHandler(rtfParser, "momath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("momathpara", new RtfCtrlWordHandler(rtfParser, "momathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("momathparapr", new RtfCtrlWordHandler(rtfParser, "momathparapr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mopemu", new RtfCtrlWordHandler(rtfParser, "mopemu", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mphant", new RtfCtrlWordHandler(rtfParser, "mphant", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mphantpr", new RtfCtrlWordHandler(rtfParser, "mphantpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mplchide", new RtfCtrlWordHandler(rtfParser, "mplchide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mpos", new RtfCtrlWordHandler(rtfParser, "mpos", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mpostsp", new RtfCtrlWordHandler(rtfParser, "mpostsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mpresp", new RtfCtrlWordHandler(rtfParser, "mpresp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mr", new RtfCtrlWordHandler(rtfParser, "mr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mrad", new RtfCtrlWordHandler(rtfParser, "mrad", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mradpr", new RtfCtrlWordHandler(rtfParser, "mradpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mrmargin", new RtfCtrlWordHandler(rtfParser, "mrmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mrpr", new RtfCtrlWordHandler(rtfParser, "mrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mrsp", new RtfCtrlWordHandler(rtfParser, "mrsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mrsprule", new RtfCtrlWordHandler(rtfParser, "mrsprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mscr", new RtfCtrlWordHandler(rtfParser, "mscr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("msepchr", new RtfCtrlWordHandler(rtfParser, "msepchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mshow", new RtfCtrlWordHandler(rtfParser, "mshow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mshp", new RtfCtrlWordHandler(rtfParser, "mshp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msize", new RtfCtrlWordHandler(rtfParser, "msize", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msmallfrac", new RtfCtrlWordHandler(rtfParser, "msmallfrac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("msmcap", new RtfCtrlWordHandler(rtfParser, "msmcap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mspre", new RtfCtrlWordHandler(rtfParser, "mspre", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msprepr", new RtfCtrlWordHandler(rtfParser, "msprepr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssub", new RtfCtrlWordHandler(rtfParser, "mssub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssubpr", new RtfCtrlWordHandler(rtfParser, "mssubpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssubsup", new RtfCtrlWordHandler(rtfParser, "mssubsup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssubsuppr", new RtfCtrlWordHandler(rtfParser, "mssubsuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssup", new RtfCtrlWordHandler(rtfParser, "mssup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mssuppr", new RtfCtrlWordHandler(rtfParser, "mssuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mstrikebltr", new RtfCtrlWordHandler(rtfParser, "mstrikebltr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mstrikeh", new RtfCtrlWordHandler(rtfParser, "mstrikeh", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mstriketlbr", new RtfCtrlWordHandler(rtfParser, "mstriketlbr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mstrikev", new RtfCtrlWordHandler(rtfParser, "mstrikev", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msty", new RtfCtrlWordHandler(rtfParser, "msty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("msub", new RtfCtrlWordHandler(rtfParser, "msub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msubhide", new RtfCtrlWordHandler(rtfParser, "msubhide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msup", new RtfCtrlWordHandler(rtfParser, "msup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("msuphide", new RtfCtrlWordHandler(rtfParser, "msuphide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mt", new RtfCtrlWordHandler(rtfParser, "mt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mtext", new RtfCtrlWordHandler(rtfParser, "mtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mtransp", new RtfCtrlWordHandler(rtfParser, "mtransp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mtype", new RtfCtrlWordHandler(rtfParser, "mtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mvauth", new RtfCtrlWordHandler(rtfParser, "mvauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mvdate", new RtfCtrlWordHandler(rtfParser, "mvdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mvertjc", new RtfCtrlWordHandler(rtfParser, "mvertjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mvf", new RtfCtrlWordHandler(rtfParser, "mvf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mvfmf", new RtfCtrlWordHandler(rtfParser, "mvfmf", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mvfml", new RtfCtrlWordHandler(rtfParser, "mvfml", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mvt", new RtfCtrlWordHandler(rtfParser, "mvt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mvtof", new RtfCtrlWordHandler(rtfParser, "mvtof", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mvtol", new RtfCtrlWordHandler(rtfParser, "mvtol", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("mwrapindent", new RtfCtrlWordHandler(rtfParser, "mwrapindent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mwrapindet", new RtfCtrlWordHandler(rtfParser, "mwrapindet", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("mwrapright", new RtfCtrlWordHandler(rtfParser, "mwrapright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("mzeroasc", new RtfCtrlWordHandler(rtfParser, "mzeroasc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mzerodesc", new RtfCtrlWordHandler(rtfParser, "mzerodesc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("mzerowid", new RtfCtrlWordHandler(rtfParser, "mzerowid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("nestcell", new RtfCtrlWordHandler(rtfParser, "nestcell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("nestrow", new RtfCtrlWordHandler(rtfParser, "nestrow", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("nesttableprops", new RtfCtrlWordHandler(rtfParser, "nesttableprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("newtblstyruls", new RtfCtrlWordHandler(rtfParser, "newtblstyruls", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nextfile", new RtfCtrlWordHandler(rtfParser, "nextfile", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("noafcnsttbl", new RtfCtrlWordHandler(rtfParser, "noafcnsttbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nobrkwrptbl", new RtfCtrlWordHandler(rtfParser, "nobrkwrptbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nocolbal", new RtfCtrlWordHandler(rtfParser, "nocolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nocompatoptions", new RtfCtrlWordHandler(rtfParser, "nocompatoptions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nocwrap", new RtfCtrlWordHandler(rtfParser, "nocwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nocxsptable", new RtfCtrlWordHandler(rtfParser, "nocxsptable", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noextrasprl", new RtfCtrlWordHandler(rtfParser, "noextrasprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nofchars", new RtfCtrlWordHandler(rtfParser, "nofchars", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("nofcharsws", new RtfCtrlWordHandler(rtfParser, "nofcharsws", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("nofeaturethrottle", new RtfCtrlWordHandler(rtfParser, "nofeaturethrottle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nofpages", new RtfCtrlWordHandler(rtfParser, "nofpages", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("nofwords", new RtfCtrlWordHandler(rtfParser, "nofwords", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("nogrowautofit", new RtfCtrlWordHandler(rtfParser, "nogrowautofit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noindnmbrts", new RtfCtrlWordHandler(rtfParser, "noindnmbrts", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nojkernpunct", new RtfCtrlWordHandler(rtfParser, "nojkernpunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nolead", new RtfCtrlWordHandler(rtfParser, "nolead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noline", new RtfCtrlWordHandler(rtfParser, "noline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nolnhtadjtbl", new RtfCtrlWordHandler(rtfParser, "nolnhtadjtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nonesttables", new RtfCtrlWordHandler(rtfParser, "nonesttables", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); // new RtfCtrlWordHandler(rtfParser, "shppict", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationShppict")); ctrlWords.put("nonshppict", new RtfCtrlWordHandler(rtfParser, "nonshppict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));// "RtfDestinationShppict")); ctrlWords.put("nooverflow", new RtfCtrlWordHandler(rtfParser, "nooverflow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noproof", new RtfCtrlWordHandler(rtfParser, "noproof", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noqfpromote", new RtfCtrlWordHandler(rtfParser, "noqfpromote", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nosectexpand", new RtfCtrlWordHandler(rtfParser, "nosectexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nosnaplinegrid", new RtfCtrlWordHandler(rtfParser, "nosnaplinegrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nospaceforul", new RtfCtrlWordHandler(rtfParser, "nospaceforul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nosupersub", new RtfCtrlWordHandler(rtfParser, "nosupersub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("notabind", new RtfCtrlWordHandler(rtfParser, "notabind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("notbrkcnstfrctbl", new RtfCtrlWordHandler(rtfParser, "notbrkcnstfrctbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("notcvasp", new RtfCtrlWordHandler(rtfParser, "notcvasp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("notvatxbx", new RtfCtrlWordHandler(rtfParser, "notvatxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nouicompat", new RtfCtrlWordHandler(rtfParser, "nouicompat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noultrlspc", new RtfCtrlWordHandler(rtfParser, "noultrlspc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nowidctlpar", new RtfCtrlWordHandler(rtfParser, "nowidctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nowrap", new RtfCtrlWordHandler(rtfParser, "nowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("nowwrap", new RtfCtrlWordHandler(rtfParser, "nowwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("noxlattoyen", new RtfCtrlWordHandler(rtfParser, "noxlattoyen", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objalias", new RtfCtrlWordHandler(rtfParser, "objalias", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objalign", new RtfCtrlWordHandler(rtfParser, "objalign", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objattph", new RtfCtrlWordHandler(rtfParser, "objattph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objautlink", new RtfCtrlWordHandler(rtfParser, "objautlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objclass", new RtfCtrlWordHandler(rtfParser, "objclass", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objcropb", new RtfCtrlWordHandler(rtfParser, "objcropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objcropl", new RtfCtrlWordHandler(rtfParser, "objcropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objcropr", new RtfCtrlWordHandler(rtfParser, "objcropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objcropt", new RtfCtrlWordHandler(rtfParser, "objcropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objdata", new RtfCtrlWordHandler(rtfParser, "objdata", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("object", new RtfCtrlWordHandler(rtfParser, "object", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objemb", new RtfCtrlWordHandler(rtfParser, "objemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objh", new RtfCtrlWordHandler(rtfParser, "objh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objhtml", new RtfCtrlWordHandler(rtfParser, "objhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objicemb", new RtfCtrlWordHandler(rtfParser, "objicemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objlink", new RtfCtrlWordHandler(rtfParser, "objlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objlock", new RtfCtrlWordHandler(rtfParser, "objlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objname", new RtfCtrlWordHandler(rtfParser, "objname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objocx", new RtfCtrlWordHandler(rtfParser, "objocx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objpub", new RtfCtrlWordHandler(rtfParser, "objpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objscalex", new RtfCtrlWordHandler(rtfParser, "objscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objscaley", new RtfCtrlWordHandler(rtfParser, "objscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objsect", new RtfCtrlWordHandler(rtfParser, "objsect", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objsetsize", new RtfCtrlWordHandler(rtfParser, "objsetsize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objsub", new RtfCtrlWordHandler(rtfParser, "objsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objtime", new RtfCtrlWordHandler(rtfParser, "objtime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("objtransy", new RtfCtrlWordHandler(rtfParser, "objtransy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("objupdate", new RtfCtrlWordHandler(rtfParser, "objupdate", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("objw", new RtfCtrlWordHandler(rtfParser, "objw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("oldas", new RtfCtrlWordHandler(rtfParser, "oldas", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("oldcprops", new RtfCtrlWordHandler(rtfParser, "oldcprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("oldlinewrap", new RtfCtrlWordHandler(rtfParser, "oldlinewrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("oldpprops", new RtfCtrlWordHandler(rtfParser, "oldpprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("oldsprops", new RtfCtrlWordHandler(rtfParser, "oldsprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("oldtprops", new RtfCtrlWordHandler(rtfParser, "oldtprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("oleclsid", new RtfCtrlWordHandler(rtfParser, "oleclsid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("operator", new RtfCtrlWordHandler(rtfParser, "operator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("otblrul", new RtfCtrlWordHandler(rtfParser, "otblrul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("outl", new RtfCtrlWordHandler(rtfParser, "outl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("outlinelevel", new RtfCtrlWordHandler(rtfParser, "outlinelevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("overlay", new RtfCtrlWordHandler(rtfParser, "overlay", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("page", new RtfCtrlWordHandler(rtfParser, "page", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("pagebb", new RtfCtrlWordHandler(rtfParser, "pagebb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("panose", new RtfCtrlWordHandler(rtfParser, "panose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull")); ctrlWords.put("paperh", new RtfCtrlWordHandler(rtfParser, "paperh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("paperw", new RtfCtrlWordHandler(rtfParser, "paperw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("par", new RtfCtrlWordHandler(rtfParser, "par", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\n")); ctrlWords.put("pararsid", new RtfCtrlWordHandler(rtfParser, "pararsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pard", new RtfCtrlWordHandler(rtfParser, "pard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("passwordhash", new RtfCtrlWordHandler(rtfParser, "passwordhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("pc", new RtfCtrlWordHandler(rtfParser, "pc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pca", new RtfCtrlWordHandler(rtfParser, "pca", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrb", new RtfCtrlWordHandler(rtfParser, "pgbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrfoot", new RtfCtrlWordHandler(rtfParser, "pgbrdrfoot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrhead", new RtfCtrlWordHandler(rtfParser, "pgbrdrhead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrl", new RtfCtrlWordHandler(rtfParser, "pgbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdropt", new RtfCtrlWordHandler(rtfParser, "pgbrdropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgbrdrr", new RtfCtrlWordHandler(rtfParser, "pgbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrsnap", new RtfCtrlWordHandler(rtfParser, "pgbrdrsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgbrdrt", new RtfCtrlWordHandler(rtfParser, "pgbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pghsxn", new RtfCtrlWordHandler(rtfParser, "pghsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnbidia", new RtfCtrlWordHandler(rtfParser, "pgnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnbidib", new RtfCtrlWordHandler(rtfParser, "pgnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnchosung", new RtfCtrlWordHandler(rtfParser, "pgnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgncnum", new RtfCtrlWordHandler(rtfParser, "pgncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgncont", new RtfCtrlWordHandler(rtfParser, "pgncont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndbnum", new RtfCtrlWordHandler(rtfParser, "pgndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndbnumd", new RtfCtrlWordHandler(rtfParser, "pgndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndbnumk", new RtfCtrlWordHandler(rtfParser, "pgndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndbnumt", new RtfCtrlWordHandler(rtfParser, "pgndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndec", new RtfCtrlWordHandler(rtfParser, "pgndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgndecd", new RtfCtrlWordHandler(rtfParser, "pgndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnganada", new RtfCtrlWordHandler(rtfParser, "pgnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgngbnum", new RtfCtrlWordHandler(rtfParser, "pgngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgngbnumd", new RtfCtrlWordHandler(rtfParser, "pgngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgngbnumk", new RtfCtrlWordHandler(rtfParser, "pgngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgngbnuml", new RtfCtrlWordHandler(rtfParser, "pgngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhindia", new RtfCtrlWordHandler(rtfParser, "pgnhindia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhindib", new RtfCtrlWordHandler(rtfParser, "pgnhindib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhindic", new RtfCtrlWordHandler(rtfParser, "pgnhindic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhindid", new RtfCtrlWordHandler(rtfParser, "pgnhindid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhn", new RtfCtrlWordHandler(rtfParser, "pgnhn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnhnsc", new RtfCtrlWordHandler(rtfParser, "pgnhnsc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhnsh", new RtfCtrlWordHandler(rtfParser, "pgnhnsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhnsm", new RtfCtrlWordHandler(rtfParser, "pgnhnsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhnsn", new RtfCtrlWordHandler(rtfParser, "pgnhnsn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnhnsp", new RtfCtrlWordHandler(rtfParser, "pgnhnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnid", new RtfCtrlWordHandler(rtfParser, "pgnid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnlcltr", new RtfCtrlWordHandler(rtfParser, "pgnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnlcrm", new RtfCtrlWordHandler(rtfParser, "pgnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnrestart", new RtfCtrlWordHandler(rtfParser, "pgnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnstart", new RtfCtrlWordHandler(rtfParser, "pgnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnstarts", new RtfCtrlWordHandler(rtfParser, "pgnstarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnthaia", new RtfCtrlWordHandler(rtfParser, "pgnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnthaib", new RtfCtrlWordHandler(rtfParser, "pgnthaib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnthaic", new RtfCtrlWordHandler(rtfParser, "pgnthaic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnucltr", new RtfCtrlWordHandler(rtfParser, "pgnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnucrm", new RtfCtrlWordHandler(rtfParser, "pgnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnvieta", new RtfCtrlWordHandler(rtfParser, "pgnvieta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnx", new RtfCtrlWordHandler(rtfParser, "pgnx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgny", new RtfCtrlWordHandler(rtfParser, "pgny", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pgnzodiac", new RtfCtrlWordHandler(rtfParser, "pgnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnzodiacd", new RtfCtrlWordHandler(rtfParser, "pgnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgnzodiacl", new RtfCtrlWordHandler(rtfParser, "pgnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pgp", new RtfCtrlWordHandler(rtfParser, "pgp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("pgptbl", new RtfCtrlWordHandler(rtfParser, "pgptbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull")); ctrlWords.put("pgwsxn", new RtfCtrlWordHandler(rtfParser, "pgwsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("phcol", new RtfCtrlWordHandler(rtfParser, "phcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("phmrg", new RtfCtrlWordHandler(rtfParser, "phmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("phnthaia", new RtfCtrlWordHandler(rtfParser, "phnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("phpg", new RtfCtrlWordHandler(rtfParser, "phpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("picbmp", new RtfCtrlWordHandler(rtfParser, "picbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("picbpp", new RtfCtrlWordHandler(rtfParser, "picbpp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("piccropb", new RtfCtrlWordHandler(rtfParser, "piccropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("piccropl", new RtfCtrlWordHandler(rtfParser, "piccropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("piccropr", new RtfCtrlWordHandler(rtfParser, "piccropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("piccropt", new RtfCtrlWordHandler(rtfParser, "piccropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pich", new RtfCtrlWordHandler(rtfParser, "pich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pichgoal", new RtfCtrlWordHandler(rtfParser, "pichgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("picprop", new RtfCtrlWordHandler(rtfParser, "picprop", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" )); ctrlWords.put("picscaled", new RtfCtrlWordHandler(rtfParser, "picscaled", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("picscalex", new RtfCtrlWordHandler(rtfParser, "picscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("picscaley", new RtfCtrlWordHandler(rtfParser, "picscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pict", new RtfCtrlWordHandler(rtfParser, "pict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationShppict" )); ctrlWords.put("picw", new RtfCtrlWordHandler(rtfParser, "picw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("picwgoal", new RtfCtrlWordHandler(rtfParser, "picwgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pindtabqc", new RtfCtrlWordHandler(rtfParser, "pindtabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pindtabql", new RtfCtrlWordHandler(rtfParser, "pindtabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pindtabqr", new RtfCtrlWordHandler(rtfParser, "pindtabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("plain", new RtfCtrlWordHandler(rtfParser, "plain", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pmartabqc", new RtfCtrlWordHandler(rtfParser, "pmartabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pmartabql", new RtfCtrlWordHandler(rtfParser, "pmartabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pmartabqr", new RtfCtrlWordHandler(rtfParser, "pmartabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pmmetafile", new RtfCtrlWordHandler(rtfParser, "pmmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pn", new RtfCtrlWordHandler(rtfParser, "pn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("pnacross", new RtfCtrlWordHandler(rtfParser, "pnacross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnaiu", new RtfCtrlWordHandler(rtfParser, "pnaiu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnaiud", new RtfCtrlWordHandler(rtfParser, "pnaiud", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnaiueo", new RtfCtrlWordHandler(rtfParser, "pnaiueo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnaiueod", new RtfCtrlWordHandler(rtfParser, "pnaiueod", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnb", new RtfCtrlWordHandler(rtfParser, "pnb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pnbidia", new RtfCtrlWordHandler(rtfParser, "pnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnbidib", new RtfCtrlWordHandler(rtfParser, "pnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pncaps", new RtfCtrlWordHandler(rtfParser, "pncaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pncard", new RtfCtrlWordHandler(rtfParser, "pncard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pncf", new RtfCtrlWordHandler(rtfParser, "pncf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnchosung", new RtfCtrlWordHandler(rtfParser, "pnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pncnum", new RtfCtrlWordHandler(rtfParser, "pncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndbnum", new RtfCtrlWordHandler(rtfParser, "pndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndbnumd", new RtfCtrlWordHandler(rtfParser, "pndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndbnumk", new RtfCtrlWordHandler(rtfParser, "pndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndbnuml", new RtfCtrlWordHandler(rtfParser, "pndbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndbnumt", new RtfCtrlWordHandler(rtfParser, "pndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndec", new RtfCtrlWordHandler(rtfParser, "pndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pndecd", new RtfCtrlWordHandler(rtfParser, "pndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnf", new RtfCtrlWordHandler(rtfParser, "pnf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnfs", new RtfCtrlWordHandler(rtfParser, "pnfs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnganada", new RtfCtrlWordHandler(rtfParser, "pnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pngblip", new RtfCtrlWordHandler(rtfParser, "pngblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pngbnum", new RtfCtrlWordHandler(rtfParser, "pngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pngbnumd", new RtfCtrlWordHandler(rtfParser, "pngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pngbnumk", new RtfCtrlWordHandler(rtfParser, "pngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pngbnuml", new RtfCtrlWordHandler(rtfParser, "pngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnhang", new RtfCtrlWordHandler(rtfParser, "pnhang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pni", new RtfCtrlWordHandler(rtfParser, "pni", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pnindent", new RtfCtrlWordHandler(rtfParser, "pnindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pniroha", new RtfCtrlWordHandler(rtfParser, "pniroha", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnirohad", new RtfCtrlWordHandler(rtfParser, "pnirohad", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnlcltr", new RtfCtrlWordHandler(rtfParser, "pnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnlcrm", new RtfCtrlWordHandler(rtfParser, "pnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnlvl", new RtfCtrlWordHandler(rtfParser, "pnlvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnlvlblt", new RtfCtrlWordHandler(rtfParser, "pnlvlblt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnlvlbody", new RtfCtrlWordHandler(rtfParser, "pnlvlbody", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnlvlcont", new RtfCtrlWordHandler(rtfParser, "pnlvlcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnnumonce", new RtfCtrlWordHandler(rtfParser, "pnnumonce", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnord", new RtfCtrlWordHandler(rtfParser, "pnord", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnordt", new RtfCtrlWordHandler(rtfParser, "pnordt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnprev", new RtfCtrlWordHandler(rtfParser, "pnprev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnqc", new RtfCtrlWordHandler(rtfParser, "pnqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnql", new RtfCtrlWordHandler(rtfParser, "pnql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnqr", new RtfCtrlWordHandler(rtfParser, "pnqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnrauth", new RtfCtrlWordHandler(rtfParser, "pnrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrdate", new RtfCtrlWordHandler(rtfParser, "pnrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrestart", new RtfCtrlWordHandler(rtfParser, "pnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnrnfc", new RtfCtrlWordHandler(rtfParser, "pnrnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrnot", new RtfCtrlWordHandler(rtfParser, "pnrnot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnrpnbr", new RtfCtrlWordHandler(rtfParser, "pnrpnbr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrrgb", new RtfCtrlWordHandler(rtfParser, "pnrrgb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrstart", new RtfCtrlWordHandler(rtfParser, "pnrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrstop", new RtfCtrlWordHandler(rtfParser, "pnrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnrxst", new RtfCtrlWordHandler(rtfParser, "pnrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnscaps", new RtfCtrlWordHandler(rtfParser, "pnscaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pnseclvl", new RtfCtrlWordHandler(rtfParser, "pnseclvl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("pnsp", new RtfCtrlWordHandler(rtfParser, "pnsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnstart", new RtfCtrlWordHandler(rtfParser, "pnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("pnstrike", new RtfCtrlWordHandler(rtfParser, "pnstrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pntext", new RtfCtrlWordHandler(rtfParser, "pntext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("pntxta", new RtfCtrlWordHandler(rtfParser, "pntxta", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("pntxtb", new RtfCtrlWordHandler(rtfParser, "pntxtb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("pnucltr", new RtfCtrlWordHandler(rtfParser, "pnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnucrm", new RtfCtrlWordHandler(rtfParser, "pnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnul", new RtfCtrlWordHandler(rtfParser, "pnul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("pnuld", new RtfCtrlWordHandler(rtfParser, "pnuld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnuldash", new RtfCtrlWordHandler(rtfParser, "pnuldash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnuldashd", new RtfCtrlWordHandler(rtfParser, "pnuldashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnuldashdd", new RtfCtrlWordHandler(rtfParser, "pnuldashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnuldb", new RtfCtrlWordHandler(rtfParser, "pnuldb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnulhair", new RtfCtrlWordHandler(rtfParser, "pnulhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnulnone", new RtfCtrlWordHandler(rtfParser, "pnulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnulth", new RtfCtrlWordHandler(rtfParser, "pnulth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnulw", new RtfCtrlWordHandler(rtfParser, "pnulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnulwave", new RtfCtrlWordHandler(rtfParser, "pnulwave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnzodiac", new RtfCtrlWordHandler(rtfParser, "pnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnzodiacd", new RtfCtrlWordHandler(rtfParser, "pnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pnzodiacl", new RtfCtrlWordHandler(rtfParser, "pnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posnegx", new RtfCtrlWordHandler(rtfParser, "posnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("posnegy", new RtfCtrlWordHandler(rtfParser, "posnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("posx", new RtfCtrlWordHandler(rtfParser, "posx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("posxc", new RtfCtrlWordHandler(rtfParser, "posxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posxi", new RtfCtrlWordHandler(rtfParser, "posxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posxl", new RtfCtrlWordHandler(rtfParser, "posxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posxo", new RtfCtrlWordHandler(rtfParser, "posxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posxr", new RtfCtrlWordHandler(rtfParser, "posxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posy", new RtfCtrlWordHandler(rtfParser, "posy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("posyb", new RtfCtrlWordHandler(rtfParser, "posyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posyc", new RtfCtrlWordHandler(rtfParser, "posyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posyil", new RtfCtrlWordHandler(rtfParser, "posyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posyin", new RtfCtrlWordHandler(rtfParser, "posyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posyout", new RtfCtrlWordHandler(rtfParser, "posyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("posyt", new RtfCtrlWordHandler(rtfParser, "posyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("prcolbl", new RtfCtrlWordHandler(rtfParser, "prcolbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("printdata", new RtfCtrlWordHandler(rtfParser, "printdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("printim", new RtfCtrlWordHandler(rtfParser, "printim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("private", new RtfCtrlWordHandler(rtfParser, "private", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("propname", new RtfCtrlWordHandler(rtfParser, "propname", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("proptype", new RtfCtrlWordHandler(rtfParser, "proptype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("protend", new RtfCtrlWordHandler(rtfParser, "protend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("protlevel", new RtfCtrlWordHandler(rtfParser, "protlevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("protstart", new RtfCtrlWordHandler(rtfParser, "protstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("protusertbl", new RtfCtrlWordHandler(rtfParser, "protusertbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("psover", new RtfCtrlWordHandler(rtfParser, "psover", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("psz", new RtfCtrlWordHandler(rtfParser, "psz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ptabldot", new RtfCtrlWordHandler(rtfParser, "ptabldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ptablmdot", new RtfCtrlWordHandler(rtfParser, "ptablmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ptablminus", new RtfCtrlWordHandler(rtfParser, "ptablminus", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ptablnone", new RtfCtrlWordHandler(rtfParser, "ptablnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ptabluscore", new RtfCtrlWordHandler(rtfParser, "ptabluscore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pubauto", new RtfCtrlWordHandler(rtfParser, "pubauto", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pvmrg", new RtfCtrlWordHandler(rtfParser, "pvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pvpara", new RtfCtrlWordHandler(rtfParser, "pvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pvpg", new RtfCtrlWordHandler(rtfParser, "pvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("pwd", new RtfCtrlWordHandler(rtfParser, "pwd", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("pxe", new RtfCtrlWordHandler(rtfParser, "pxe", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("qc", new RtfCtrlWordHandler(rtfParser, "qc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("qd", new RtfCtrlWordHandler(rtfParser, "qd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("qj", new RtfCtrlWordHandler(rtfParser, "qj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("qk", new RtfCtrlWordHandler(rtfParser, "qk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ql", new RtfCtrlWordHandler(rtfParser, "ql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("qmspace", new RtfCtrlWordHandler(rtfParser, "qmspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("qr", new RtfCtrlWordHandler(rtfParser, "qr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("qt", new RtfCtrlWordHandler(rtfParser, "qt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "rawbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgbdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgcross", new RtfCtrlWordHandler(rtfParser, "rawclbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkdcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkhor", new RtfCtrlWordHandler(rtfParser, "rawclbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgdkvert", new RtfCtrlWordHandler(rtfParser, "rawclbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgfdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbghoriz", new RtfCtrlWordHandler(rtfParser, "rawclbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rawclbgvert", new RtfCtrlWordHandler(rtfParser, "rawclbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rdblquote", new RtfCtrlWordHandler(rtfParser, "rdblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x148")); ctrlWords.put("readonlyrecommended", new RtfCtrlWordHandler(rtfParser, "readonlyrecommended", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("readprot", new RtfCtrlWordHandler(rtfParser, "readprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("red", new RtfCtrlWordHandler(rtfParser, "red", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("relyonvml", new RtfCtrlWordHandler(rtfParser, "relyonvml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rempersonalinfo", new RtfCtrlWordHandler(rtfParser, "rempersonalinfo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("result", new RtfCtrlWordHandler(rtfParser, "result", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("revauth", new RtfCtrlWordHandler(rtfParser, "revauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revauthdel", new RtfCtrlWordHandler(rtfParser, "revauthdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revbar", new RtfCtrlWordHandler(rtfParser, "revbar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revdttm", new RtfCtrlWordHandler(rtfParser, "revdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revdttmdel", new RtfCtrlWordHandler(rtfParser, "revdttmdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revised", new RtfCtrlWordHandler(rtfParser, "revised", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("revisions", new RtfCtrlWordHandler(rtfParser, "revisions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("revprop", new RtfCtrlWordHandler(rtfParser, "revprop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("revprot", new RtfCtrlWordHandler(rtfParser, "revprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("revtbl", new RtfCtrlWordHandler(rtfParser, "revtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull")); ctrlWords.put("revtim", new RtfCtrlWordHandler(rtfParser, "revtim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("ri", new RtfCtrlWordHandler(rtfParser, "ri", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("rin", new RtfCtrlWordHandler(rtfParser, "rin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("row", new RtfCtrlWordHandler(rtfParser, "row", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("rquote", new RtfCtrlWordHandler(rtfParser, "rquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x146")); ctrlWords.put("rsid", new RtfCtrlWordHandler(rtfParser, "rsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("rsidroot", new RtfCtrlWordHandler(rtfParser, "rsidroot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("rsidtbl", new RtfCtrlWordHandler(rtfParser, "rsidtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull")); ctrlWords.put("rsltbmp", new RtfCtrlWordHandler(rtfParser, "rsltbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rslthtml", new RtfCtrlWordHandler(rtfParser, "rslthtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rsltmerge", new RtfCtrlWordHandler(rtfParser, "rsltmerge", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rsltpict", new RtfCtrlWordHandler(rtfParser, "rsltpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rsltrtf", new RtfCtrlWordHandler(rtfParser, "rsltrtf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rslttxt", new RtfCtrlWordHandler(rtfParser, "rslttxt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtf", new RtfCtrlWordHandler(rtfParser, "rtf", 1, true, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("rtlch", new RtfCtrlWordHandler(rtfParser, "rtlch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtldoc", new RtfCtrlWordHandler(rtfParser, "rtldoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtlgutter", new RtfCtrlWordHandler(rtfParser, "rtlgutter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtlmark", new RtfCtrlWordHandler(rtfParser, "rtlmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("rtlpar", new RtfCtrlWordHandler(rtfParser, "rtlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtlrow", new RtfCtrlWordHandler(rtfParser, "rtlrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rtlsect", new RtfCtrlWordHandler(rtfParser, "rtlsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("rxe", new RtfCtrlWordHandler(rtfParser, "rxe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("s", new RtfCtrlWordHandler(rtfParser, "s", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sa", new RtfCtrlWordHandler(rtfParser, "sa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("saauto", new RtfCtrlWordHandler(rtfParser, "saauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("saftnnalc", new RtfCtrlWordHandler(rtfParser, "saftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnar", new RtfCtrlWordHandler(rtfParser, "saftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnauc", new RtfCtrlWordHandler(rtfParser, "saftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnchi", new RtfCtrlWordHandler(rtfParser, "saftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnchosung", new RtfCtrlWordHandler(rtfParser, "saftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnncnum", new RtfCtrlWordHandler(rtfParser, "saftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnndbar", new RtfCtrlWordHandler(rtfParser, "saftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnndbnum", new RtfCtrlWordHandler(rtfParser, "saftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnndbnumd", new RtfCtrlWordHandler(rtfParser, "saftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnndbnumk", new RtfCtrlWordHandler(rtfParser, "saftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnndbnumt", new RtfCtrlWordHandler(rtfParser, "saftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnganada", new RtfCtrlWordHandler(rtfParser, "saftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnngbnum", new RtfCtrlWordHandler(rtfParser, "saftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnngbnumd", new RtfCtrlWordHandler(rtfParser, "saftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnngbnumk", new RtfCtrlWordHandler(rtfParser, "saftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnngbnuml", new RtfCtrlWordHandler(rtfParser, "saftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnrlc", new RtfCtrlWordHandler(rtfParser, "saftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnruc", new RtfCtrlWordHandler(rtfParser, "saftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnzodiac", new RtfCtrlWordHandler(rtfParser, "saftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "saftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "saftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnrestart", new RtfCtrlWordHandler(rtfParser, "saftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnrstcont", new RtfCtrlWordHandler(rtfParser, "saftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saftnstart", new RtfCtrlWordHandler(rtfParser, "saftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sautoupd", new RtfCtrlWordHandler(rtfParser, "sautoupd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saveinvalidxml", new RtfCtrlWordHandler(rtfParser, "saveinvalidxml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("saveprevpict", new RtfCtrlWordHandler(rtfParser, "saveprevpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sb", new RtfCtrlWordHandler(rtfParser, "sb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sbasedon", new RtfCtrlWordHandler(rtfParser, "sbasedon", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sbauto", new RtfCtrlWordHandler(rtfParser, "sbauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("sbkcol", new RtfCtrlWordHandler(rtfParser, "sbkcol", RtfProperty.SBK_COLUMN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE)); ctrlWords.put("sbkeven", new RtfCtrlWordHandler(rtfParser, "sbkeven", RtfProperty.SBK_EVEN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE)); ctrlWords.put("sbknone", new RtfCtrlWordHandler(rtfParser, "sbknone", RtfProperty.SBK_NONE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE)); ctrlWords.put("sbkodd", new RtfCtrlWordHandler(rtfParser, "sbkodd", RtfProperty.SBK_ODD, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE)); ctrlWords.put("sbkpage", new RtfCtrlWordHandler(rtfParser, "sbkpage", RtfProperty.SBK_PAGE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE)); ctrlWords.put("sbys", new RtfCtrlWordHandler(rtfParser, "sbys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("scaps", new RtfCtrlWordHandler(rtfParser, "scaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("scompose", new RtfCtrlWordHandler(rtfParser, "scompose", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sec", new RtfCtrlWordHandler(rtfParser, "sec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sect", new RtfCtrlWordHandler(rtfParser, "sect", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("sectd", new RtfCtrlWordHandler(rtfParser, "sectd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sectdefaultcl", new RtfCtrlWordHandler(rtfParser, "sectdefaultcl", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectexpand", new RtfCtrlWordHandler(rtfParser, "sectexpand", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectlinegrid", new RtfCtrlWordHandler(rtfParser, "sectlinegrid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectnum", new RtfCtrlWordHandler(rtfParser, "sectnum", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("sectrsid", new RtfCtrlWordHandler(rtfParser, "sectrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectspecifycl", new RtfCtrlWordHandler(rtfParser, "sectspecifycl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectspecifygen", new RtfCtrlWordHandler(rtfParser, "sectspecifygen", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectspecifyl", new RtfCtrlWordHandler(rtfParser, "sectspecifyl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sectunlocked", new RtfCtrlWordHandler(rtfParser, "sectunlocked", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnbj", new RtfCtrlWordHandler(rtfParser, "sftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnalc", new RtfCtrlWordHandler(rtfParser, "sftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnar", new RtfCtrlWordHandler(rtfParser, "sftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnauc", new RtfCtrlWordHandler(rtfParser, "sftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnchi", new RtfCtrlWordHandler(rtfParser, "sftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnchosung", new RtfCtrlWordHandler(rtfParser, "sftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnncnum", new RtfCtrlWordHandler(rtfParser, "sftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnndbar", new RtfCtrlWordHandler(rtfParser, "sftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnndbnum", new RtfCtrlWordHandler(rtfParser, "sftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnndbnumd", new RtfCtrlWordHandler(rtfParser, "sftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnndbnumk", new RtfCtrlWordHandler(rtfParser, "sftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnndbnumt", new RtfCtrlWordHandler(rtfParser, "sftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnganada", new RtfCtrlWordHandler(rtfParser, "sftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnngbnum", new RtfCtrlWordHandler(rtfParser, "sftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnngbnumd", new RtfCtrlWordHandler(rtfParser, "sftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnngbnumk", new RtfCtrlWordHandler(rtfParser, "sftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnngbnuml", new RtfCtrlWordHandler(rtfParser, "sftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnrlc", new RtfCtrlWordHandler(rtfParser, "sftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnruc", new RtfCtrlWordHandler(rtfParser, "sftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnzodiac", new RtfCtrlWordHandler(rtfParser, "sftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "sftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "sftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnrestart", new RtfCtrlWordHandler(rtfParser, "sftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnrstcont", new RtfCtrlWordHandler(rtfParser, "sftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnrstpg", new RtfCtrlWordHandler(rtfParser, "sftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftnstart", new RtfCtrlWordHandler(rtfParser, "sftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sftntj", new RtfCtrlWordHandler(rtfParser, "sftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shad", new RtfCtrlWordHandler(rtfParser, "shad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("shading", new RtfCtrlWordHandler(rtfParser, "shading", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shidden", new RtfCtrlWordHandler(rtfParser, "shidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shift", new RtfCtrlWordHandler(rtfParser, "shift", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("showplaceholdtext", new RtfCtrlWordHandler(rtfParser, "showplaceholdtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("showxmlerrors", new RtfCtrlWordHandler(rtfParser, "showxmlerrors", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shp", new RtfCtrlWordHandler(rtfParser, "shp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("shpbottom", new RtfCtrlWordHandler(rtfParser, "shpbottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpbxcolumn", new RtfCtrlWordHandler(rtfParser, "shpbxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbxignore", new RtfCtrlWordHandler(rtfParser, "shpbxignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbxmargin", new RtfCtrlWordHandler(rtfParser, "shpbxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbxpage", new RtfCtrlWordHandler(rtfParser, "shpbxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbyignore", new RtfCtrlWordHandler(rtfParser, "shpbyignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbymargin", new RtfCtrlWordHandler(rtfParser, "shpbymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbypage", new RtfCtrlWordHandler(rtfParser, "shpbypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpbypara", new RtfCtrlWordHandler(rtfParser, "shpbypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shpfblwtxt", new RtfCtrlWordHandler(rtfParser, "shpfblwtxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpfhdr", new RtfCtrlWordHandler(rtfParser, "shpfhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpgrp", new RtfCtrlWordHandler(rtfParser, "shpgrp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpinst", new RtfCtrlWordHandler(rtfParser, "shpinst", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("shpleft", new RtfCtrlWordHandler(rtfParser, "shpleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shplid", new RtfCtrlWordHandler(rtfParser, "shplid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shplockanchor", new RtfCtrlWordHandler(rtfParser, "shplockanchor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("shppict", new RtfCtrlWordHandler(rtfParser, "shppict", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationShppict")); ctrlWords.put("shpright", new RtfCtrlWordHandler(rtfParser, "shpright", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shprslt", new RtfCtrlWordHandler(rtfParser, "shprslt", 0, true, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull")); ctrlWords.put("shptop", new RtfCtrlWordHandler(rtfParser, "shptop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shptxt", new RtfCtrlWordHandler(rtfParser, "shptxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpwr", new RtfCtrlWordHandler(rtfParser, "shpwr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpwrk", new RtfCtrlWordHandler(rtfParser, "shpwrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("shpz", new RtfCtrlWordHandler(rtfParser, "shpz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sl", new RtfCtrlWordHandler(rtfParser, "sl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("slink", new RtfCtrlWordHandler(rtfParser, "slink", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("slmult", new RtfCtrlWordHandler(rtfParser, "slmult", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("slocked", new RtfCtrlWordHandler(rtfParser, "slocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sn", new RtfCtrlWordHandler(rtfParser, "sn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("snapgridtocell", new RtfCtrlWordHandler(rtfParser, "snapgridtocell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("snaptogridincell", new RtfCtrlWordHandler(rtfParser, "snaptogridincell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("snext", new RtfCtrlWordHandler(rtfParser, "snext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("softcol", new RtfCtrlWordHandler(rtfParser, "softcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("softlheight", new RtfCtrlWordHandler(rtfParser, "softlheight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("softline", new RtfCtrlWordHandler(rtfParser, "softline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("softpage", new RtfCtrlWordHandler(rtfParser, "softpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sp", new RtfCtrlWordHandler(rtfParser, "sp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("spersonal", new RtfCtrlWordHandler(rtfParser, "spersonal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("spltpgpar", new RtfCtrlWordHandler(rtfParser, "spltpgpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("splytwnine", new RtfCtrlWordHandler(rtfParser, "splytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("spp", new RtfCtrlWordHandler(rtfParser, "spp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("spriority", new RtfCtrlWordHandler(rtfParser, "spriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sprsbsp", new RtfCtrlWordHandler(rtfParser, "sprsbsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sprslnsp", new RtfCtrlWordHandler(rtfParser, "sprslnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sprsspbf", new RtfCtrlWordHandler(rtfParser, "sprsspbf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sprstsm", new RtfCtrlWordHandler(rtfParser, "sprstsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sprstsp", new RtfCtrlWordHandler(rtfParser, "sprstsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("spv", new RtfCtrlWordHandler(rtfParser, "spv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sqformat", new RtfCtrlWordHandler(rtfParser, "sqformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sreply", new RtfCtrlWordHandler(rtfParser, "sreply", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ssemihidden", new RtfCtrlWordHandler(rtfParser, "ssemihidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("staticval", new RtfCtrlWordHandler(rtfParser, "staticval", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("stextflow", new RtfCtrlWordHandler(rtfParser, "stextflow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("strike", new RtfCtrlWordHandler(rtfParser, "strike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("striked1", new RtfCtrlWordHandler(rtfParser, "striked1", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("stshfbi", new RtfCtrlWordHandler(rtfParser, "stshfbi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("stshfdbch", new RtfCtrlWordHandler(rtfParser, "stshfdbch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("stshfhich", new RtfCtrlWordHandler(rtfParser, "stshfhich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("stshfloch", new RtfCtrlWordHandler(rtfParser, "stshfloch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("stylelock", new RtfCtrlWordHandler(rtfParser, "stylelock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("stylelockbackcomp", new RtfCtrlWordHandler(rtfParser, "stylelockbackcomp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("stylelockenforced", new RtfCtrlWordHandler(rtfParser, "stylelockenforced", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("stylelockqfset", new RtfCtrlWordHandler(rtfParser, "stylelockqfset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("stylelocktheme", new RtfCtrlWordHandler(rtfParser, "stylelocktheme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("stylesheet", new RtfCtrlWordHandler(rtfParser, "stylesheet", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationStylesheetTable")); ctrlWords.put("stylesortmethod", new RtfCtrlWordHandler(rtfParser, "stylesortmethod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("styrsid", new RtfCtrlWordHandler(rtfParser, "styrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("sub", new RtfCtrlWordHandler(rtfParser, "sub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("subdocument", new RtfCtrlWordHandler(rtfParser, "subdocument", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("subfontbysize", new RtfCtrlWordHandler(rtfParser, "subfontbysize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("subject", new RtfCtrlWordHandler(rtfParser, "subject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("sunhideused", new RtfCtrlWordHandler(rtfParser, "sunhideused", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("super", new RtfCtrlWordHandler(rtfParser, "super", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("sv", new RtfCtrlWordHandler(rtfParser, "sv", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("svb", new RtfCtrlWordHandler(rtfParser, "svb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("swpbdr", new RtfCtrlWordHandler(rtfParser, "swpbdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tab", new RtfCtrlWordHandler(rtfParser, "tab", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("tabsnoovrlp", new RtfCtrlWordHandler(rtfParser, "tabsnoovrlp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("taprtl", new RtfCtrlWordHandler(rtfParser, "taprtl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tb", new RtfCtrlWordHandler(rtfParser, "tb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tblind", new RtfCtrlWordHandler(rtfParser, "tblind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tblindtype", new RtfCtrlWordHandler(rtfParser, "tblindtype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tbllkbestfit", new RtfCtrlWordHandler(rtfParser, "tbllkbestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkborder", new RtfCtrlWordHandler(rtfParser, "tbllkborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkcolor", new RtfCtrlWordHandler(rtfParser, "tbllkcolor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkfont", new RtfCtrlWordHandler(rtfParser, "tbllkfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkhdrcols", new RtfCtrlWordHandler(rtfParser, "tbllkhdrcols", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkhdrrows", new RtfCtrlWordHandler(rtfParser, "tbllkhdrrows", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllklastcol", new RtfCtrlWordHandler(rtfParser, "tbllklastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllklastrow", new RtfCtrlWordHandler(rtfParser, "tbllklastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllknocolband", new RtfCtrlWordHandler(rtfParser, "tbllknocolband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllknorowband", new RtfCtrlWordHandler(rtfParser, "tbllknorowband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tbllkshading", new RtfCtrlWordHandler(rtfParser, "tbllkshading", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tblrsid", new RtfCtrlWordHandler(rtfParser, "tblrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tc", new RtfCtrlWordHandler(rtfParser, "tc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("tcelld", new RtfCtrlWordHandler(rtfParser, "tcelld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tcf", new RtfCtrlWordHandler(rtfParser, "tcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tcl", new RtfCtrlWordHandler(rtfParser, "tcl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tcn", new RtfCtrlWordHandler(rtfParser, "tcn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tdfrmtxtBottom", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtBottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tdfrmtxtLeft", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtLeft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tdfrmtxtRight", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtRight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tdfrmtxtTop", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtTop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("template", new RtfCtrlWordHandler(rtfParser, "template", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("themedata", new RtfCtrlWordHandler(rtfParser, "themedata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("themelang", new RtfCtrlWordHandler(rtfParser, "themelang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("themelangcs", new RtfCtrlWordHandler(rtfParser, "themelangcs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("themelangfe", new RtfCtrlWordHandler(rtfParser, "themelangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("time", new RtfCtrlWordHandler(rtfParser, "time", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("title", new RtfCtrlWordHandler(rtfParser, "title", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo")); ctrlWords.put("titlepg", new RtfCtrlWordHandler(rtfParser, "titlepg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tldot", new RtfCtrlWordHandler(rtfParser, "tldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tleq", new RtfCtrlWordHandler(rtfParser, "tleq", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tlhyph", new RtfCtrlWordHandler(rtfParser, "tlhyph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tlmdot", new RtfCtrlWordHandler(rtfParser, "tlmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tlth", new RtfCtrlWordHandler(rtfParser, "tlth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tlul", new RtfCtrlWordHandler(rtfParser, "tlul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("toplinepunct", new RtfCtrlWordHandler(rtfParser, "toplinepunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tphcol", new RtfCtrlWordHandler(rtfParser, "tphcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tphmrg", new RtfCtrlWordHandler(rtfParser, "tphmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tphpg", new RtfCtrlWordHandler(rtfParser, "tphpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposnegx", new RtfCtrlWordHandler(rtfParser, "tposnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tposnegy", new RtfCtrlWordHandler(rtfParser, "tposnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tposx", new RtfCtrlWordHandler(rtfParser, "tposx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tposxc", new RtfCtrlWordHandler(rtfParser, "tposxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposxi", new RtfCtrlWordHandler(rtfParser, "tposxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposxl", new RtfCtrlWordHandler(rtfParser, "tposxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposxo", new RtfCtrlWordHandler(rtfParser, "tposxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposxr", new RtfCtrlWordHandler(rtfParser, "tposxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposy", new RtfCtrlWordHandler(rtfParser, "tposy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyb", new RtfCtrlWordHandler(rtfParser, "tposyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyc", new RtfCtrlWordHandler(rtfParser, "tposyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyil", new RtfCtrlWordHandler(rtfParser, "tposyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyin", new RtfCtrlWordHandler(rtfParser, "tposyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyout", new RtfCtrlWordHandler(rtfParser, "tposyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyoutv", new RtfCtrlWordHandler(rtfParser, "tposyoutv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tposyt", new RtfCtrlWordHandler(rtfParser, "tposyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tpvmrg", new RtfCtrlWordHandler(rtfParser, "tpvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tpvpara", new RtfCtrlWordHandler(rtfParser, "tpvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tpvpg", new RtfCtrlWordHandler(rtfParser, "tpvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tqc", new RtfCtrlWordHandler(rtfParser, "tqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tqdec", new RtfCtrlWordHandler(rtfParser, "tqdec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tqr", new RtfCtrlWordHandler(rtfParser, "tqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trackformatting", new RtfCtrlWordHandler(rtfParser, "trackformatting", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trackmoves", new RtfCtrlWordHandler(rtfParser, "trackmoves", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("transmf", new RtfCtrlWordHandler(rtfParser, "transmf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trauth", new RtfCtrlWordHandler(rtfParser, "trauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trautofit", new RtfCtrlWordHandler(rtfParser, "trautofit", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("trbgbdiag", new RtfCtrlWordHandler(rtfParser, "trbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgcross", new RtfCtrlWordHandler(rtfParser, "trbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdcross", new RtfCtrlWordHandler(rtfParser, "trbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "trbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkcross", new RtfCtrlWordHandler(rtfParser, "trbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkdcross", new RtfCtrlWordHandler(rtfParser, "trbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "trbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkhor", new RtfCtrlWordHandler(rtfParser, "trbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgdkvert", new RtfCtrlWordHandler(rtfParser, "trbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgfdiag", new RtfCtrlWordHandler(rtfParser, "trbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbghoriz", new RtfCtrlWordHandler(rtfParser, "trbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbgvert", new RtfCtrlWordHandler(rtfParser, "trbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrb", new RtfCtrlWordHandler(rtfParser, "trbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrh", new RtfCtrlWordHandler(rtfParser, "trbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrl", new RtfCtrlWordHandler(rtfParser, "trbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrr", new RtfCtrlWordHandler(rtfParser, "trbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrt", new RtfCtrlWordHandler(rtfParser, "trbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trbrdrv", new RtfCtrlWordHandler(rtfParser, "trbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trcbpat", new RtfCtrlWordHandler(rtfParser, "trcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trcfpat", new RtfCtrlWordHandler(rtfParser, "trcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trdate", new RtfCtrlWordHandler(rtfParser, "trdate", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trftsWidth", new RtfCtrlWordHandler(rtfParser, "trftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trftsWidthA", new RtfCtrlWordHandler(rtfParser, "trftsWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trftsWidthB", new RtfCtrlWordHandler(rtfParser, "trftsWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trgaph", new RtfCtrlWordHandler(rtfParser, "trgaph", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trhdr", new RtfCtrlWordHandler(rtfParser, "trhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trkeep", new RtfCtrlWordHandler(rtfParser, "trkeep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trkeepfollow", new RtfCtrlWordHandler(rtfParser, "trkeepfollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trleft", new RtfCtrlWordHandler(rtfParser, "trleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trowd", new RtfCtrlWordHandler(rtfParser, "trowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trpaddb", new RtfCtrlWordHandler(rtfParser, "trpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddfb", new RtfCtrlWordHandler(rtfParser, "trpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddfl", new RtfCtrlWordHandler(rtfParser, "trpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddfr", new RtfCtrlWordHandler(rtfParser, "trpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddft", new RtfCtrlWordHandler(rtfParser, "trpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddl", new RtfCtrlWordHandler(rtfParser, "trpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddr", new RtfCtrlWordHandler(rtfParser, "trpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpaddt", new RtfCtrlWordHandler(rtfParser, "trpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trpat", new RtfCtrlWordHandler(rtfParser, "trpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trqc", new RtfCtrlWordHandler(rtfParser, "trqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trql", new RtfCtrlWordHandler(rtfParser, "trql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trqr", new RtfCtrlWordHandler(rtfParser, "trqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trrh", new RtfCtrlWordHandler(rtfParser, "trrh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trshdng", new RtfCtrlWordHandler(rtfParser, "trshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdb", new RtfCtrlWordHandler(rtfParser, "trspdb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdfb", new RtfCtrlWordHandler(rtfParser, "trspdfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdfl", new RtfCtrlWordHandler(rtfParser, "trspdfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdfr", new RtfCtrlWordHandler(rtfParser, "trspdfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdft", new RtfCtrlWordHandler(rtfParser, "trspdft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdl", new RtfCtrlWordHandler(rtfParser, "trspdl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdr", new RtfCtrlWordHandler(rtfParser, "trspdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trspdt", new RtfCtrlWordHandler(rtfParser, "trspdt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("truncatefontheight", new RtfCtrlWordHandler(rtfParser, "truncatefontheight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("truncex", new RtfCtrlWordHandler(rtfParser, "truncex", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("trwWidth", new RtfCtrlWordHandler(rtfParser, "trwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trwWidthA", new RtfCtrlWordHandler(rtfParser, "trwWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("trwWidthB", new RtfCtrlWordHandler(rtfParser, "trwWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ts", new RtfCtrlWordHandler(rtfParser, "ts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tsbgbdiag", new RtfCtrlWordHandler(rtfParser, "tsbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgcross", new RtfCtrlWordHandler(rtfParser, "tsbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdcross", new RtfCtrlWordHandler(rtfParser, "tsbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "tsbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkcross", new RtfCtrlWordHandler(rtfParser, "tsbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkdcross", new RtfCtrlWordHandler(rtfParser, "tsbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "tsbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkhor", new RtfCtrlWordHandler(rtfParser, "tsbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgdkvert", new RtfCtrlWordHandler(rtfParser, "tsbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgfdiag", new RtfCtrlWordHandler(rtfParser, "tsbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbghoriz", new RtfCtrlWordHandler(rtfParser, "tsbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbgvert", new RtfCtrlWordHandler(rtfParser, "tsbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrb", new RtfCtrlWordHandler(rtfParser, "tsbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrdgl", new RtfCtrlWordHandler(rtfParser, "tsbrdrdgl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrdgr", new RtfCtrlWordHandler(rtfParser, "tsbrdrdgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrh", new RtfCtrlWordHandler(rtfParser, "tsbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrl", new RtfCtrlWordHandler(rtfParser, "tsbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrr", new RtfCtrlWordHandler(rtfParser, "tsbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrt", new RtfCtrlWordHandler(rtfParser, "tsbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsbrdrv", new RtfCtrlWordHandler(rtfParser, "tsbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscbandhorzeven", new RtfCtrlWordHandler(rtfParser, "tscbandhorzeven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscbandhorzodd", new RtfCtrlWordHandler(rtfParser, "tscbandhorzodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscbandsh", new RtfCtrlWordHandler(rtfParser, "tscbandsh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscbandsv", new RtfCtrlWordHandler(rtfParser, "tscbandsv", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscbandverteven", new RtfCtrlWordHandler(rtfParser, "tscbandverteven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscbandvertodd", new RtfCtrlWordHandler(rtfParser, "tscbandvertodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscellcbpat", new RtfCtrlWordHandler(rtfParser, "tscellcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellcfpat", new RtfCtrlWordHandler(rtfParser, "tscellcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddb", new RtfCtrlWordHandler(rtfParser, "tscellpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddfb", new RtfCtrlWordHandler(rtfParser, "tscellpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddfl", new RtfCtrlWordHandler(rtfParser, "tscellpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddfr", new RtfCtrlWordHandler(rtfParser, "tscellpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddft", new RtfCtrlWordHandler(rtfParser, "tscellpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddl", new RtfCtrlWordHandler(rtfParser, "tscellpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddr", new RtfCtrlWordHandler(rtfParser, "tscellpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpaddt", new RtfCtrlWordHandler(rtfParser, "tscellpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellpct", new RtfCtrlWordHandler(rtfParser, "tscellpct", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("tscellwidth", new RtfCtrlWordHandler(rtfParser, "tscellwidth", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscellwidthfts", new RtfCtrlWordHandler(rtfParser, "tscellwidthfts", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscfirstcol", new RtfCtrlWordHandler(rtfParser, "tscfirstcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscfirstrow", new RtfCtrlWordHandler(rtfParser, "tscfirstrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsclastcol", new RtfCtrlWordHandler(rtfParser, "tsclastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsclastrow", new RtfCtrlWordHandler(rtfParser, "tsclastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscnecell", new RtfCtrlWordHandler(rtfParser, "tscnecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscnwcell", new RtfCtrlWordHandler(rtfParser, "tscnwcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscsecell", new RtfCtrlWordHandler(rtfParser, "tscsecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tscswcell", new RtfCtrlWordHandler(rtfParser, "tscswcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsd", new RtfCtrlWordHandler(rtfParser, "tsd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsnowrap", new RtfCtrlWordHandler(rtfParser, "tsnowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsrowd", new RtfCtrlWordHandler(rtfParser, "tsrowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsvertalb", new RtfCtrlWordHandler(rtfParser, "tsvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsvertalc", new RtfCtrlWordHandler(rtfParser, "tsvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tsvertalt", new RtfCtrlWordHandler(rtfParser, "tsvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("twoonone", new RtfCtrlWordHandler(rtfParser, "twoonone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("tx", new RtfCtrlWordHandler(rtfParser, "tx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("txbxtwalways", new RtfCtrlWordHandler(rtfParser, "txbxtwalways", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("txbxtwfirst", new RtfCtrlWordHandler(rtfParser, "txbxtwfirst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("txbxtwfirstlast", new RtfCtrlWordHandler(rtfParser, "txbxtwfirstlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("txbxtwlast", new RtfCtrlWordHandler(rtfParser, "txbxtwlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("txbxtwno", new RtfCtrlWordHandler(rtfParser, "txbxtwno", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("txe", new RtfCtrlWordHandler(rtfParser, "txe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("u", new RtfCtrlWordHandler(rtfParser, "u", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("uc", new RtfCtrlWordHandler(rtfParser, "uc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("ud", new RtfCtrlWordHandler(rtfParser, "ud", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("ul", new RtfCtrlWordHandler(rtfParser, "ul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulc", new RtfCtrlWordHandler(rtfParser, "ulc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("uld", new RtfCtrlWordHandler(rtfParser, "uld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("uldash", new RtfCtrlWordHandler(rtfParser, "uldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("uldashd", new RtfCtrlWordHandler(rtfParser, "uldashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("uldashdd", new RtfCtrlWordHandler(rtfParser, "uldashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("uldb", new RtfCtrlWordHandler(rtfParser, "uldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulhair", new RtfCtrlWordHandler(rtfParser, "ulhair", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulhwave", new RtfCtrlWordHandler(rtfParser, "ulhwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulldash", new RtfCtrlWordHandler(rtfParser, "ulldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulnone", new RtfCtrlWordHandler(rtfParser, "ulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ulth", new RtfCtrlWordHandler(rtfParser, "ulth", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulthd", new RtfCtrlWordHandler(rtfParser, "ulthd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulthdash", new RtfCtrlWordHandler(rtfParser, "ulthdash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulthdashd", new RtfCtrlWordHandler(rtfParser, "ulthdashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulthdashdd", new RtfCtrlWordHandler(rtfParser, "ulthdashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulthldash", new RtfCtrlWordHandler(rtfParser, "ulthldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ululdbwave", new RtfCtrlWordHandler(rtfParser, "ululdbwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("ulw", new RtfCtrlWordHandler(rtfParser, "ulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("ulwave", new RtfCtrlWordHandler(rtfParser, "ulwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("up", new RtfCtrlWordHandler(rtfParser, "up", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("upr", new RtfCtrlWordHandler(rtfParser, "upr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("urtf", new RtfCtrlWordHandler(rtfParser, "urtf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("useltbaln", new RtfCtrlWordHandler(rtfParser, "useltbaln", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("usenormstyforlist", new RtfCtrlWordHandler(rtfParser, "usenormstyforlist", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("userprops", new RtfCtrlWordHandler(rtfParser, "userprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null)); ctrlWords.put("usexform", new RtfCtrlWordHandler(rtfParser, "usexform", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("utinl", new RtfCtrlWordHandler(rtfParser, "utinl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("v", new RtfCtrlWordHandler(rtfParser, "v", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null)); ctrlWords.put("validatexml", new RtfCtrlWordHandler(rtfParser, "validatexml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vern", new RtfCtrlWordHandler(rtfParser, "vern", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("version", new RtfCtrlWordHandler(rtfParser, "version", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("vertalb", new RtfCtrlWordHandler(rtfParser, "vertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vertalc", new RtfCtrlWordHandler(rtfParser, "vertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vertalj", new RtfCtrlWordHandler(rtfParser, "vertalj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vertalt", new RtfCtrlWordHandler(rtfParser, "vertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vertdoc", new RtfCtrlWordHandler(rtfParser, "vertdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("vertsect", new RtfCtrlWordHandler(rtfParser, "vertsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("viewbksp", new RtfCtrlWordHandler(rtfParser, "viewbksp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("viewkind", new RtfCtrlWordHandler(rtfParser, "viewkind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("viewnobound", new RtfCtrlWordHandler(rtfParser, "viewnobound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("viewscale", new RtfCtrlWordHandler(rtfParser, "viewscale", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("viewzk", new RtfCtrlWordHandler(rtfParser, "viewzk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wbitmap", new RtfCtrlWordHandler(rtfParser, "wbitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wbmbitspixel", new RtfCtrlWordHandler(rtfParser, "wbmbitspixel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wbmplanes", new RtfCtrlWordHandler(rtfParser, "wbmplanes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wbmwidthbytes", new RtfCtrlWordHandler(rtfParser, "wbmwidthbytes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("webhidden", new RtfCtrlWordHandler(rtfParser, "webhidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wgrffmtfilter", new RtfCtrlWordHandler(rtfParser, "wgrffmtfilter", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", null)); ctrlWords.put("widctlpar", new RtfCtrlWordHandler(rtfParser, "widctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("widowctrl", new RtfCtrlWordHandler(rtfParser, "widowctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("windowcaption", new RtfCtrlWordHandler(rtfParser, "windowcaption", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wmetafile", new RtfCtrlWordHandler(rtfParser, "wmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("wpeqn", new RtfCtrlWordHandler(rtfParser, "wpeqn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wpjst", new RtfCtrlWordHandler(rtfParser, "wpjst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wpsp", new RtfCtrlWordHandler(rtfParser, "wpsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wptab", new RtfCtrlWordHandler(rtfParser, "wptab", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wraparound", new RtfCtrlWordHandler(rtfParser, "wraparound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wrapdefault", new RtfCtrlWordHandler(rtfParser, "wrapdefault", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wrapthrough", new RtfCtrlWordHandler(rtfParser, "wrapthrough", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wraptight", new RtfCtrlWordHandler(rtfParser, "wraptight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("wraptrsp", new RtfCtrlWordHandler(rtfParser, "wraptrsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("writereservhash", new RtfCtrlWordHandler(rtfParser, "writereservhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null)); ctrlWords.put("wrppunct", new RtfCtrlWordHandler(rtfParser, "wrppunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xe", new RtfCtrlWordHandler(rtfParser, "xe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("xef", new RtfCtrlWordHandler(rtfParser, "xef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("xform", new RtfCtrlWordHandler(rtfParser, "xform", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlattr", new RtfCtrlWordHandler(rtfParser, "xmlattr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xmlattrname", new RtfCtrlWordHandler(rtfParser, "xmlattrname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlattrns", new RtfCtrlWordHandler(rtfParser, "xmlattrns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("xmlattrvalue", new RtfCtrlWordHandler(rtfParser, "xmlattrvalue", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlclose", new RtfCtrlWordHandler(rtfParser, "xmlclose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlname", new RtfCtrlWordHandler(rtfParser, "xmlname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlns", new RtfCtrlWordHandler(rtfParser, "xmlns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("xmlnstbl", new RtfCtrlWordHandler(rtfParser, "xmlnstbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlopen", new RtfCtrlWordHandler(rtfParser, "xmlopen", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument")); ctrlWords.put("xmlsdttcell", new RtfCtrlWordHandler(rtfParser, "xmlsdttcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xmlsdttpara", new RtfCtrlWordHandler(rtfParser, "xmlsdttpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xmlsdttregular", new RtfCtrlWordHandler(rtfParser, "xmlsdttregular", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xmlsdttrow", new RtfCtrlWordHandler(rtfParser, "xmlsdttrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("xmlsdttunknown", new RtfCtrlWordHandler(rtfParser, "xmlsdttunknown", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("yr", new RtfCtrlWordHandler(rtfParser, "yr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("yts", new RtfCtrlWordHandler(rtfParser, "yts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("yxe", new RtfCtrlWordHandler(rtfParser, "yxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null)); ctrlWords.put("zwbo", new RtfCtrlWordHandler(rtfParser, "zwbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("zwj", new RtfCtrlWordHandler(rtfParser, "zwj", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("zwnbo", new RtfCtrlWordHandler(rtfParser, "zwnbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null)); ctrlWords.put("zwnj", new RtfCtrlWordHandler(rtfParser, "zwnj", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null)); ctrlWords.put("{", new RtfCtrlWordHandler(rtfParser, "{", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "{")); ctrlWords.put("|", new RtfCtrlWordHandler(rtfParser, "|", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "|")); ctrlWords.put("}", new RtfCtrlWordHandler(rtfParser, "}", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "}")); ctrlWords.put("~", new RtfCtrlWordHandler(rtfParser, "~", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "~")); ctrlWords.put("unknown", new RtfCtrlWordHandler(rtfParser, "unknown", 0,false, RtfCtrlWordType.UNIDENTIFIED, "\\", " ", null)); } } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.java100644 0 0 17466 11012562273 22654 0ustar 0 0 /* * $Id: RtfCtrlWordMgr.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; import java.io.PushbackInputStream; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.rtf.parser.RtfParser; /** * RtfCtrlWordMgr handles the dispatching of control words from * the table of known control words. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfCtrlWordMgr { public static final boolean debug = false; public static final boolean debugFound = false; public static final boolean debugNotFound = true; private PushbackInputStream reader = null; private RtfParser rtfParser = null; private RtfCtrlWordMap ctrlWordMap = null; /** The RtfCtrlWordListener. */ private ArrayList listeners = new ArrayList(); // // TIMING DEBUG INFO // private long endTime = 0; // private Date endDate = null; // private long endFree = 0; // private DecimalFormat df = new DecimalFormat("#,##0"); // private Date startDate = new Date(); // private long startTime = System.currentTimeMillis(); // private long startFree = Runtime.getRuntime().freeMemory(); /** * Constructor * @param rtfParser The parser object this manager works with. * @param reader the PushbackReader from the tokeniser. */ public RtfCtrlWordMgr(RtfParser rtfParser, PushbackInputStream reader) { this.rtfParser = rtfParser; // set the parser this.reader = reader; // set the reader value ctrlWordMap = new RtfCtrlWordMap(rtfParser); // // TIMING DEBUG INFO // endFree = Runtime.getRuntime().freeMemory(); // endTime = System.currentTimeMillis(); // endDate = new Date(); // System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString()); // System.out.println("RtfCtrlWordMgr end date : " + endDate.toLocaleString()); // System.out.println(" Elapsed time : " + Long.toString(endTime - startTime) + " milliseconds."); // System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k"); // System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k"); // System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k"); } /** * Internal to control word manager class. * * @param ctrlWordData The RtfCtrlWordData object with control word and param * @param groupLevel The current document group parsing level * @return errOK if ok, otherwise an error code. */ public int handleKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) { //TODO: May be used for event handling. int result = RtfParser.errOK; // Call before handler event here beforeCtrlWord(ctrlWordData); result = dispatchKeyword(ctrlWordData, groupLevel); // call after handler event here afterCtrlWord(ctrlWordData); return result; } /** * Dispatch the token to the correct control word handling object. * * @param ctrlWordData The RtfCtrlWordData object with control word and param * @param groupLevel The current document group parsing level * @return errOK if ok, otherwise an error code. */ private int dispatchKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) { int result = RtfParser.errOK; if(ctrlWordData != null) { RtfCtrlWordHandler ctrlWord = ctrlWordMap.getCtrlWordHandler(ctrlWordData.ctrlWord); if(ctrlWord != null) { ctrlWord.handleControlword(ctrlWordData); if(debug && debugFound) { System.out.println("Keyword found:" + " New:" + ctrlWordData.ctrlWord + " Param:" + ctrlWordData.param + " bParam=" + ctrlWordData.hasParam); } } else { result = RtfParser.errCtrlWordNotFound; //result = RtfParser2.errAssertion; if(debug && debugNotFound) { System.out.println("Keyword unknown:" + " New:" + ctrlWordData.ctrlWord + " Param:" + ctrlWordData.param + " bParam=" + ctrlWordData.hasParam); } } } return result; } // listener methods /** * Adds a RtfCtrlWordListener to the RtfCtrlWordMgr. * * @param listener * the new RtfCtrlWordListener. */ public void addRtfCtrlWordListener(RtfCtrlWordListener listener) { listeners.add(listener); } /** * Removes a RtfCtrlWordListener from the RtfCtrlWordMgr. * * @param listener * the RtfCtrlWordListener that has to be removed. */ public void removeRtfCtrlWordListener(RtfCtrlWordListener listener) { listeners.remove(listener); } private boolean beforeCtrlWord(RtfCtrlWordData ctrlWordData) { RtfCtrlWordListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfCtrlWordListener) iterator.next(); listener.beforeCtrlWord(ctrlWordData); } return true; } private boolean onCtrlWord(RtfCtrlWordData ctrlWordData) { RtfCtrlWordListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfCtrlWordListener) iterator.next(); listener.onCtrlWord(ctrlWordData); } return true; } private boolean afterCtrlWord(RtfCtrlWordData ctrlWordData) { RtfCtrlWordListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfCtrlWordListener) iterator.next(); listener.afterCtrlWord(ctrlWordData); } return true; } } src/rtf/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordType.java100644 0 0 7244 11012562273 23021 0ustar 0 0 /* $Id: RtfCtrlWordType.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.ctrlwords; /** * RtfCtrlWordType indicates the type of control word. * * RTF control words are divided up into: * Destination, Flag, Value, Toggle, Symbol. * * Destination: The current destination for values and text to be sent. * Flag: 0/1 value types. Represents true/false, on/off value types. * Toggle: Flips a Flag value on/off. * Value: an Integer value data type. (Exception: Some control words this is a long data value type) * Symbol: Special RTF characters such as \{, \} and others. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfCtrlWordType { /** * Control word is unidentified. */ public static final int UNIDENTIFIED = -1; /** * Control word is a destination. */ public static final int DESTINATION = 0; /** * Control word is a newer destination. */ public static final int DESTINATION_EX = 1; /** * Control word is a flag. */ public static final int FLAG = 2; /** * Control word is a value. */ public static final int VALUE = 3; /** * Control word is a flag toggle. */ public static final int TOGGLE = 4; /** * Control word is a special symbol. */ public static final int SYMBOL = 5; } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestination.java100644 0 0 20216 11012562273 23373 0ustar 0 0 /* * $Id: RtfDestination.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestination is the base class for destinations according * to the RTF Specification. All destinations must extend from this class. * * @author Howard Shank (hgshank@yahoo.com * * @since 2.0.8 */ public abstract class RtfDestination { /** Parser object */ protected RtfParser rtfParser = null; /** Is data in destination modified? */ protected boolean modified = false; /** The last control word handled by this destination */ protected RtfCtrlWordData lastCtrlWord = null;; /** The RtfDestinationListener. */ private static ArrayList listeners = new ArrayList(); /** * Constructor. */ public RtfDestination() { rtfParser = null; } /** * Constructor * @param parser RtfParser object. */ public RtfDestination(RtfParser parser) { this.rtfParser = parser; } /** * Set the parser to use with the RtfDestination object. * * @param parser The RtfParser object. */ public void setParser(RtfParser parser) { if(this.rtfParser != null && this.rtfParser.equals(parser)) return; this.rtfParser = parser; } /** * Clean up when destination is closed. * @return true if handled, false if not handled */ public abstract boolean closeDestination(); /** * Handle a new subgroup contained within this group * @return true if handled, false if not handled */ public abstract boolean handleOpeningSubGroup(); /** * Clean up when group is closed. * @return true if handled, false if not handled */ public abstract boolean handleCloseGroup(); /** * Setup when group is opened. * @return true if handled, false if not handled */ public abstract boolean handleOpenGroup(); /** * Handle text for this destination * @return true if handled, false if not handled */ public abstract boolean handleCharacter(int ch); /** * Handle control word for this destination * @param ctrlWordData The control word and parameter information object * @return true if handled, false if not handled */ public abstract boolean handleControlWord(RtfCtrlWordData ctrlWordData); /** * Method to set this object to the default values. Must be implemented in child class. */ public abstract void setToDefaults(); /** * Method to indicate if data in this destination has changed. * @return true if modified, false if not modified. */ public boolean isModified() { return modified; } // listener methods /** * Adds a RtfDestinationListener to the RtfDestinationMgr. * * @param listener * the new RtfDestinationListener. */ public boolean addListener(RtfDestinationListener listener) { return listeners.add(listener); } /** * Removes a RtfDestinationListener from the RtfDestinationMgr. * * @param listener * the RtfCtrlWordListener that has to be removed. */ public boolean removeListener(RtfDestinationListener listener) { return listeners.remove(listener); } protected RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData) { RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.beforeCtrlWord(ctrlWordData); } return null; } /** * */ protected RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.onCtrlWord(ctrlWordData); } return null; } /** * */ protected RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.afterCtrlWord(ctrlWordData); } return null; } /** * */ protected int beforeCharacter(int ch){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.beforeCharacter(ch); } return 0; } /** * */ protected int onCharacter(int ch){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.onCharacter(ch); } return 0; } /** * */ protected int afterCharacter(int ch){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.afterCharacter(ch); } return 0; } /** * * @return true if all goes well */ protected boolean onOpenGroup(){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.onOpenGroup(); } return true; } /** * * @return true if all goes well */ protected boolean onCloseGroup(){ RtfDestinationListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfDestinationListener) iterator.next(); listener.onCloseGroup(); } return true; } public int getNewTokeniserState() { return RtfParser.TOKENISER_IGNORE_RESULT; } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationColorTable.java100644 0 0 25075 11012562273 25352 0ustar 0 0 /* * $Id: RtfDestinationColorTable.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.awt.Color; import java.util.HashMap; import com.lowagie.text.rtf.parser.RtfImportMgr; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; import com.lowagie.text.rtf.parser.enumerations.RtfColorThemes; /** * RtfDestinationColorTable handles data destined for the color table destination * * @author Howard Shank (hgshank@yahoo.com) * * @since 2.0.8 */ public class RtfDestinationColorTable extends RtfDestination { /** * The RtfImportHeader to add color mappings to. */ private RtfImportMgr importHeader = null; /** * The number of the current color being parsed. */ private int colorNr = 0; /** * The red component of the current color being parsed. */ private int red = -1; /** * The green component of the current color being parsed. */ private int green = -1; /** * The blue component of the current color being parsed. */ private int blue = -1; /* * Color themes - Introduced Word 2007 */ /** * Specifies the tint when specifying a theme color. * RTF control word ctint * * 0 - 255: 0 = full tint(white), 255 = no tint. * Default value: 255 * * If tint is specified and is less than 255, cshade must equal 255. * ctint/cshade are mutually exclusive * * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor */ private int ctint = 255; /** * Specifies the shade when specifying a theme color. * RTF control word cshade * * 0 - 255: 0 = full shade(black), 255 = no shade. * Default value: 255 * * If shade is specified and is less than 255, ctint must equal 255. * cshade/ctint are mutually exclusive * * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor */ private int cshade = 255; /** * Specifies the use of a theme color. * * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade */ private int themeColor = RtfColorThemes.THEME_UNDEFINED; /** * Color map object for conversions */ private HashMap colorMap = null; /** * Constructor. */ public RtfDestinationColorTable() { super(null); colorMap = new HashMap(); this.colorNr = 0; } /** * Constructs a new RtfColorTableParser. * * @param parser an RtfParser */ public RtfDestinationColorTable(RtfParser parser) { super(parser); colorMap = new HashMap(); this.colorNr = 0; this.importHeader = parser.getImportManager(); this.setToDefaults(); } public void setParser(RtfParser parser) { this.rtfParser = parser; colorMap = new HashMap(); this.colorNr = 0; this.importHeader = parser.getImportManager(); this.setToDefaults(); } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { return true; } public boolean closeDestination() { return true; } public boolean handleCloseGroup() { processColor(); return true; } public boolean handleOpenGroup() { return true; } public boolean handleCharacter(int ch) { // color elements end with a semicolon (;) if(ch == ';') { this.processColor(); } return true; } public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { if(ctrlWordData.ctrlWord.equals("blue")) this.setBlue(ctrlWordData.intValue()); if(ctrlWordData.ctrlWord.equals("red")) this.setRed(ctrlWordData.intValue()); if(ctrlWordData.ctrlWord.equals("green")) this.setGreen(ctrlWordData.intValue()); if(ctrlWordData.ctrlWord.equals("cshade")) this.setShade(ctrlWordData.intValue()); if(ctrlWordData.ctrlWord.equals("ctint")) this.setTint(ctrlWordData.intValue()); //if(ctrlWordData.ctrlWord.equals("cmaindarkone")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cmainlightone")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cmaindarktwo")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cmainlighttwo")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccentone")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccenttwo")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccentthree")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccentfour")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccentfive")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("caccentsix")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("chyperlink")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cfollowedhyperlink")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cbackgroundone")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("ctextone")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("cbacgroundtwo")) this.setThemeColor(ctrlWordData.ctrlWord); //if(ctrlWordData.ctrlWord.equals("ctexttwo")) this.setThemeColor(ctrlWordData.ctrlWord); return true; } /** * Set default values. */ public void setToDefaults() { this.red = -1; this.green = -1; this.blue = -1; this.ctint = 255; this.cshade = 255; this.themeColor = RtfColorThemes.THEME_UNDEFINED; // do not reset colorNr } /** * Processes the color triplet parsed from the document. * Add it to the import mapping so colors can be mapped when encountered * in the RTF import or conversion. */ private void processColor() { if(red != -1 && green != -1 && blue != -1) { if(this.rtfParser.isImport()) { this.importHeader.importColor(Integer.toString(this.colorNr), new Color(this.red, this.green, this.blue)); } if(this.rtfParser.isConvert()) { colorMap.put(Integer.toString(this.colorNr), new Color(this.red, this.green, this.blue)); } } this.setToDefaults(); this.colorNr++; } /** * Set the red color to value. * @param value Value to set red to. */ private void setRed(int value) { if(value >= 0 && value <= 255) { this.red = value; } } /** * Set the green color value. * @param value Value to set green to. */ private void setGreen(int value) { if(value >= 0 && value <= 255) { this.green = value; } } /** * Set the blue color value. * @param value Value to set blue to. */ private void setBlue(int value) { if(value >= 0 && value <= 255) { this.blue = value; } } /** * Set the tint value * @param value Value to set the tint to * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint */ private void setTint(int value) { if(value >= 0 && value <= 255) { this.ctint = value; if(value >= 0 && value <255) { this.cshade = 255; } } } /** * Set the shade value * @param value Value to set the shade to * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade */ private void setShade(int value) { if(value >= 0 && value <= 255) { this.cshade = value; if(value >= 0 && value <255) { this.ctint = 255; } } } /** * Set the theme color value. * @param value Value to set the theme color to * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes */ private void setThemeColor(int value) { if(value >= RtfColorThemes.THEME_UNDEFINED && value <= RtfColorThemes.THEME_MAX) { this.themeColor = value; } else { this.themeColor = RtfColorThemes.THEME_UNDEFINED; } } // conversion functions /** * Get the Color object that is mapped to the key. * @param key The map number. * *@return Color object from the map. null if key does not exist. */ public Color getColor(String key) { return (Color)colorMap.get(key); } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationDocument.java100644 0 0 63224 11036112746 25102 0ustar 0 0 /* * $Id: RtfDestinationDocument.java 3456 2008-05-26 15:26:57Z howard_s $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.awt.Color; import java.util.Arrays; import java.util.HashMap; import java.util.List; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.Paragraph; import com.lowagie.text.rtf.direct.RtfDirectContent; import com.lowagie.text.rtf.document.*; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordType; import com.lowagie.text.rtf.parser.properties.RtfProperty; import com.lowagie.text.rtf.parser.properties.RtfPropertyListener; /** * RtfDestinationDocument handles data destined for the document destination * * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.0 */ public final class RtfDestinationDocument extends RtfDestination implements RtfPropertyListener { /** * The RtfDocument object. * * @see com.lowagie.text.rtf.document.RtfDocument */ private RtfDocument rtfDoc = null; /** * The iText Document object. * * @see com.lowagie.text.Document */ private Document doc = null; private StringBuffer buffer = null; /** * Indicates the parser action. Import or Conversion. * * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_UNIDENTIFIED * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_CONVERT * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL */ private int conversionType = 0; /** * Indicates the current table level being processed */ private int tableLevel = 0; private static final List IMPORT_IGNORED_CTRLWORDS = Arrays.asList(new String[]{ "rtf", "ansicpg", "deff", "ansi", "mac", "pca", "pc", "stshfdbch", "stshfloch", "stshfhich", "stshfbi", "deflang", "deflangfe", "adeflang", "adeflangfe"}); private static final List CONVERT_IGNORED_CTRLWORDS = Arrays.asList(new String[]{"rtf"}); private Paragraph iTextParagraph = null; public RtfDestinationDocument() { super(null); } /** * Constructs a new RtfDestinationDocument using * the parameters to initialize the object. * @param parser an RtfParser. */ public RtfDestinationDocument(RtfParser parser) { super(parser); this.rtfDoc = parser.getRtfDocument(); this.doc = parser.getDocument(); this.conversionType = parser.getConversionType(); setToDefaults(); if(this.rtfParser.isConvert()) { this.rtfParser.getState().properties.addRtfPropertyListener(this); } } /* (non-Javadoc) * @see java.lang.Object#finalize() */ protected void finalize() throws Throwable { // TODO Auto-generated method stub if(this.rtfParser.isConvert()) { this.rtfParser.getState().properties.removeRtfPropertyListener(this); } super.finalize(); } public void setParser(RtfParser parser) { this.rtfParser = parser; this.rtfDoc = parser.getRtfDocument(); this.doc = parser.getDocument(); this.conversionType = parser.getConversionType(); setToDefaults(); if(this.rtfParser.isConvert()) { this.rtfParser.getState().properties.addRtfPropertyListener(this); } } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { if(this.rtfParser.isImport()) { if(this.buffer.length()>0) { writeBuffer(); } } this.rtfParser.getState().properties.removeRtfPropertyListener(this); return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { this.onOpenGroup(); // event handler if(this.rtfParser.isImport()) { } if(this.rtfParser.isConvert()) { if(this.iTextParagraph == null) this.iTextParagraph = new Paragraph(); } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { if(this.rtfParser.isImport()) { if(this.buffer.length()>0) { writeBuffer(); } } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { this.onCloseGroup(); // event handler if(this.rtfParser.isImport()) { if(this.buffer.length()>0) { writeBuffer(); } writeText("}"); } if(this.rtfParser.isConvert()) { if(this.buffer.length() > 0 && this.iTextParagraph == null) { this.iTextParagraph = new Paragraph(); } if(this.buffer.length() > 0 ) { Chunk chunk = new Chunk(); chunk.append(this.buffer.toString()); this.iTextParagraph.add(chunk); } if(this.iTextParagraph != null) { addParagraphToDocument(); } } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int) */ public boolean handleCharacter(int ch) { boolean result = true; this.onCharacter(ch); // event handler if(this.rtfParser.isImport()) { if(buffer.length() > 254) { this.writeBuffer(); } buffer.append((char)ch); } if(this.rtfParser.isConvert()) { buffer.append((char)ch); } return result; } public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { boolean result = false; this.onCtrlWord(ctrlWordData); // event handler if(this.rtfParser.isImport()) { // map font information if(ctrlWordData.ctrlWord.equals("f")) { ctrlWordData.param = this.rtfParser.getImportManager().mapFontNr(ctrlWordData.param);} // map color information //colors if(ctrlWordData.ctrlWord.equals("cb")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} if(ctrlWordData.ctrlWord.equals("cf")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} //cells if(ctrlWordData.ctrlWord.equals("clcbpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} if(ctrlWordData.ctrlWord.equals("clcbpatraw")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} if(ctrlWordData.ctrlWord.equals("clcfpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} if(ctrlWordData.ctrlWord.equals("clcfpatraw")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} //table rows if(ctrlWordData.ctrlWord.equals("trcfpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} if(ctrlWordData.ctrlWord.equals("trcbpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} //paragraph border if(ctrlWordData.ctrlWord.equals("brdrcf")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);} // map lists if(ctrlWordData.ctrlWord.equals("ls")) { ctrlWordData.param = this.rtfParser.getImportManager().mapListNr(ctrlWordData.param);} } if(this.rtfParser.isConvert()) { if(ctrlWordData.ctrlWord.equals("par")) { addParagraphToDocument(); } // Set Font if(ctrlWordData.ctrlWord.equals("f")) {} // color information //colors if(ctrlWordData.ctrlWord.equals("cb")) {} if(ctrlWordData.ctrlWord.equals("cf")) {} //cells if(ctrlWordData.ctrlWord.equals("clcbpat")) {} if(ctrlWordData.ctrlWord.equals("clcbpatraw")) {} if(ctrlWordData.ctrlWord.equals("clcfpat")) {} if(ctrlWordData.ctrlWord.equals("clcfpatraw")) {} //table rows if(ctrlWordData.ctrlWord.equals("trcfpat")) {} if(ctrlWordData.ctrlWord.equals("trcbpat")) {} //paragraph border if(ctrlWordData.ctrlWord.equals("brdrcf")) {} /* TABLES */ if(ctrlWordData.ctrlWord.equals("trowd")) /*Beginning of row*/ { tableLevel++;} if(ctrlWordData.ctrlWord.equals("cell")) /*End of Cell Denotes the end of a table cell*/ { // String ctl = ctrlWordData.ctrlWord; // System.out.print("cell found"); } if(ctrlWordData.ctrlWord.equals("row")) /*End of row*/ { tableLevel++;} if(ctrlWordData.ctrlWord.equals("lastrow")) /*Last row of the table*/ {} if(ctrlWordData.ctrlWord.equals("row")) /*End of row*/ { tableLevel++;} if(ctrlWordData.ctrlWord.equals("irow")) /*param is the row index of this row.*/ {} if(ctrlWordData.ctrlWord.equals("irowband")) /*param is the row index of the row, adjusted to account for header rows. A header row has a value of -1.*/ {} if(ctrlWordData.ctrlWord.equals("tcelld")) /*Sets table cell defaults*/ {} if(ctrlWordData.ctrlWord.equals("nestcell")) /*Denotes the end of a nested cell.*/ {} if(ctrlWordData.ctrlWord.equals("nestrow")) /*Denotes the end of a nested row*/ {} if(ctrlWordData.ctrlWord.equals("nesttableprops")) /*Defines the properties of a nested table. This is a destination control word*/ {} if(ctrlWordData.ctrlWord.equals("nonesttables")) /*Contains text for readers that do not understand nested tables. This destination should be ignored by readers that support nested tables.*/ {} if(ctrlWordData.ctrlWord.equals("trgaph")) /*Half the space between the cells of a table row in twips.*/ {} if(ctrlWordData.ctrlWord.equals("cellx")) /*param Defines the right boundary of a table cell, including its half of the space between cells.*/ {} if(ctrlWordData.ctrlWord.equals("clmgf")) /*The first cell in a range of table cells to be merged.*/ {} if(ctrlWordData.ctrlWord.equals("clmrg")) /*Contents of the table cell are merged with those of the preceding cell*/ {} if(ctrlWordData.ctrlWord.equals("clvmgf")) /*The first cell in a range of table cells to be vertically merged.*/ {} if(ctrlWordData.ctrlWord.equals("clvmrg")) /*Contents of the table cell are vertically merged with those of the preceding cell*/ {} /* TABLE: table row revision tracking */ if(ctrlWordData.ctrlWord.equals("trauth")) /*With revision tracking enabled, this control word identifies the author of changes to a table row's properties. N refers to a value in the revision table*/ {} if(ctrlWordData.ctrlWord.equals("trdate")) /*With revision tracking enabled, this control word identifies the date of a revision*/ {} /* TABLE: Autoformatting flags */ if(ctrlWordData.ctrlWord.equals("tbllkborder")) /*Flag sets table autoformat to format borders*/ {} if(ctrlWordData.ctrlWord.equals("tbllkshading")) /*Flag sets table autoformat to affect shading.*/ {} if(ctrlWordData.ctrlWord.equals("tbllkfont")) /*Flag sets table autoformat to affect font*/ {} if(ctrlWordData.ctrlWord.equals("tbllkcolor")) /*Flag sets table autoformat to affect color*/ {} if(ctrlWordData.ctrlWord.equals("tbllkbestfit")) /*Flag sets table autoformat to apply best fit*/ {} if(ctrlWordData.ctrlWord.equals("tbllkhdrrows")) /*Flag sets table autoformat to format the first (header) row*/ {} if(ctrlWordData.ctrlWord.equals("tbllklastrow")) /*Flag sets table autoformat to format the last row.*/ {} if(ctrlWordData.ctrlWord.equals("tbllkhdrcols")) /*Flag sets table autoformat to format the first (header) column*/ {} if(ctrlWordData.ctrlWord.equals("tbllklastcol")) /*Flag sets table autoformat to format the last column*/ {} if(ctrlWordData.ctrlWord.equals("tbllknorowband")) /*Specifies row banding conditional formatting shall not be applied*/ {} if(ctrlWordData.ctrlWord.equals("tbllknocolband")) /*Specifies column banding conditional formatting shall not be applied.*/ {} /* TABLE: Row Formatting */ if(ctrlWordData.ctrlWord.equals("taprtl")) /*Table direction is right to left*/ {} if(ctrlWordData.ctrlWord.equals("trautofit")) /*param = AutoFit: 0 No AutoFit (default). 1 AutoFit is on for the row. Overridden by \clwWidthN and \trwWidthN in any table row. */ {} if(ctrlWordData.ctrlWord.equals("trhdr")) /*Table row header. This row should appear at the top of every page on which the current table appears*/ {} if(ctrlWordData.ctrlWord.equals("trkeep")) /*Keep table row together. This row cannot be split by a page break. This property is assumed to be off unless the control word is present*/ {} if(ctrlWordData.ctrlWord.equals("trkeepfollow")) /*Keep row in the same page as the following row.*/ {} if(ctrlWordData.ctrlWord.equals("trleft")) /*Position in twips of the leftmost edge of the table with respect to the left edge of its column.*/ {} if(ctrlWordData.ctrlWord.equals("trqc")) /*Centers a table row with respect to its containing column.*/ {} if(ctrlWordData.ctrlWord.equals("trql")) /*Left-justifies a table row with respect to its containing column.*/ {} if(ctrlWordData.ctrlWord.equals("trqr")) /*Right-justifies a table row with respect to its containing column*/ {} if(ctrlWordData.ctrlWord.equals("trrh")) /*Height of a table row in twips. When 0, the height is sufficient for all the text in the line; when positive, the height is guaranteed to be at least the specified height; when negative, the absolute value of the height is used, regardless of the height of the text in the line*/ {} if(ctrlWordData.ctrlWord.equals("trpaddb")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddl")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddr")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddt")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddfb")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddfl")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddfr")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpaddft")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdl")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdt")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdb")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdr")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdfl")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdft")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdfb")) /**/ {} if(ctrlWordData.ctrlWord.equals("trspdfr")) /**/ {} if(ctrlWordData.ctrlWord.equals("trwWidth")) /**/ {} if(ctrlWordData.ctrlWord.equals("trftsWidth")) /**/ {} if(ctrlWordData.ctrlWord.equals("trwWidthB")) /**/ {} if(ctrlWordData.ctrlWord.equals("trftsWidthB")) /**/ {} if(ctrlWordData.ctrlWord.equals("trftsWidthB")) /**/ {} if(ctrlWordData.ctrlWord.equals("trwWidthA")) /**/ {} if(ctrlWordData.ctrlWord.equals("trftsWidthA")) /**/ {} if(ctrlWordData.ctrlWord.equals("tblind")) /**/ {} if(ctrlWordData.ctrlWord.equals("tblindtype")) /**/ {} /*TABLE: Row shading and Background COlors*/ if(ctrlWordData.ctrlWord.equals("trcbpat")) /**/ {} if(ctrlWordData.ctrlWord.equals("trcfpat")) /**/ {} if(ctrlWordData.ctrlWord.equals("trpat")) /**/ {} if(ctrlWordData.ctrlWord.equals("trshdng")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgbdiag")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgcross")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdcross")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkbdiag")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkcross")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkdcross")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkfdiag")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkhor")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgdkvert")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgfdiag")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbghoriz")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbgvert")) /**/ {} /* TABLE: Cell Formatting*/ if(ctrlWordData.ctrlWord.equals("clFitText")) /**/ {} if(ctrlWordData.ctrlWord.equals("clNoWrap")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadl")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadt")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadb")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadr")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadfl")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadft")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadfb")) /**/ {} if(ctrlWordData.ctrlWord.equals("clpadfr")) /**/ {} if(ctrlWordData.ctrlWord.equals("clwWidth")) /**/ {} if(ctrlWordData.ctrlWord.equals("clftsWidth")) /**/ {} if(ctrlWordData.ctrlWord.equals("clhidemark")) /**/ {} /* TABLE: Compared Table Cells */ if(ctrlWordData.ctrlWord.equals("clins")) /**/ {} if(ctrlWordData.ctrlWord.equals("cldel")) /**/ {} if(ctrlWordData.ctrlWord.equals("clmrgd")) /**/ {} if(ctrlWordData.ctrlWord.equals("clmrgdr")) /**/ {} if(ctrlWordData.ctrlWord.equals("clsplit")) /**/ {} if(ctrlWordData.ctrlWord.equals("clsplitr")) /**/ {} if(ctrlWordData.ctrlWord.equals("clinsauth")) /**/ {} if(ctrlWordData.ctrlWord.equals("clinsdttm")) /**/ {} if(ctrlWordData.ctrlWord.equals("cldelauth")) /**/ {} if(ctrlWordData.ctrlWord.equals("cldeldttm")) /**/ {} if(ctrlWordData.ctrlWord.equals("clmrgdauth")) /**/ {} if(ctrlWordData.ctrlWord.equals("clmrgddttm")) /**/ {} /*TABLE: Position Wrapped Tables (The following properties must be the same for all rows in the table.)*/ if(ctrlWordData.ctrlWord.equals("tdfrmtxtLeft")) /**/ {} if(ctrlWordData.ctrlWord.equals("tdfrmtxtRight")) /**/ {} if(ctrlWordData.ctrlWord.equals("tdfrmtxtTop")) /**/ {} if(ctrlWordData.ctrlWord.equals("tdfrmtxtBottom")) /**/ {} if(ctrlWordData.ctrlWord.equals("tabsnoovrlp")) /**/ {} if(ctrlWordData.ctrlWord.equals("tphcol")) /**/ {} if(ctrlWordData.ctrlWord.equals("tphmrg")) /**/ {} if(ctrlWordData.ctrlWord.equals("tphpg")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposnegx")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposnegy")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposx")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposxc")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposxi")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposxl")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposxo")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposxr")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposy")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyb")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyc")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyil")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyin")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyout")) /**/ {} if(ctrlWordData.ctrlWord.equals("tposyt")) /**/ {} if(ctrlWordData.ctrlWord.equals("tpvmrg")) /**/ {} if(ctrlWordData.ctrlWord.equals("tpvpara")) /**/ {} if(ctrlWordData.ctrlWord.equals("tpvpg")) /**/ {} /* TABLE: Bidirectional Controls */ if(ctrlWordData.ctrlWord.equals("rtlrow")) /**/ {} if(ctrlWordData.ctrlWord.equals("ltrrow")) /**/ {} /* TABLE: Row Borders */ if(ctrlWordData.ctrlWord.equals("trbrdrt")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbrdrl")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbrdrb")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbrdrr")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbrdrh")) /**/ {} if(ctrlWordData.ctrlWord.equals("trbrdrv")) /**/ {} /* TABLE: Cell Borders */ if(ctrlWordData.ctrlWord.equals("brdrnil")) /**/ {} if(ctrlWordData.ctrlWord.equals("clbrdrb")) /**/ {} if(ctrlWordData.ctrlWord.equals("clbrdrt")) /**/ {} if(ctrlWordData.ctrlWord.equals("clbrdrl")) /**/ {} if(ctrlWordData.ctrlWord.equals("clbrdrr")) /**/ {} if(ctrlWordData.ctrlWord.equals("cldglu")) /**/ {} if(ctrlWordData.ctrlWord.equals("cldgll")) /**/ {} } if(ctrlWordData.ctrlWordType == RtfCtrlWordType.TOGGLE) { this.rtfParser.getState().properties.toggleProperty(ctrlWordData);//ctrlWordData.specialHandler); } if(ctrlWordData.ctrlWordType == RtfCtrlWordType.FLAG || ctrlWordData.ctrlWordType == RtfCtrlWordType.VALUE) { this.rtfParser.getState().properties.setProperty(ctrlWordData);//ctrlWordData.specialHandler, ctrlWordData.param); } switch(conversionType) { case RtfParser.TYPE_IMPORT_FULL: if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) { writeBuffer(); writeText(ctrlWordData.toString()); } result = true; break; case RtfParser.TYPE_IMPORT_FRAGMENT: if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) { writeBuffer(); writeText(ctrlWordData.toString()); } result = true; break; case RtfParser.TYPE_CONVERT: if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) { } result = true; break; default: // error because is should be an import or convert result = false; break; } return result; } /** * Write the accumulated buffer to the destination. * Used for direct content */ private void writeBuffer() { writeText(this.buffer.toString()); setToDefaults(); } /** * Write the string value to the destination. * Used for direct content * @param value */ private void writeText(String value) { if(this.rtfParser.isNewGroup()) { this.rtfDoc.add(new RtfDirectContent("{")); this.rtfParser.setNewGroup(false); } if(value.length() > 0) { this.rtfDoc.add(new RtfDirectContent(value)); } } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults() */ public void setToDefaults() { this.buffer = new StringBuffer(255); } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#afterChange(java.lang.String) */ public void afterPropertyChange(String propertyName) { if(propertyName.startsWith(RtfProperty.CHARACTER)) { } else { if(propertyName.startsWith(RtfProperty.PARAGRAPH)) { } else { if(propertyName.startsWith(RtfProperty.SECTION)) { } else { if(propertyName.startsWith(RtfProperty.DOCUMENT)) { } } } } } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#beforeChange(java.lang.String) */ public void beforePropertyChange(String propertyName) { // do we have any text to do anything with? // if not, then just return without action. if(this.buffer.length() == 0) return; if(propertyName.startsWith(RtfProperty.CHARACTER)) { // this is a character change, // add a new chunk to the current paragraph using current character settings. Chunk chunk = new Chunk(); chunk.append(this.buffer.toString()); this.buffer = new StringBuffer(255); HashMap charProperties = this.rtfParser.getState().properties.getProperties(RtfProperty.CHARACTER); String defFont = (String)charProperties.get(RtfProperty.CHARACTER_FONT); if(defFont == null) defFont = "0"; RtfDestinationFontTable fontTable = (RtfDestinationFontTable)this.rtfParser.getDestination("fonttbl"); Font currFont = fontTable.getFont(defFont); int fs = Font.NORMAL; if(charProperties.containsKey(RtfProperty.CHARACTER_BOLD)) fs |= Font.BOLD; if(charProperties.containsKey(RtfProperty.CHARACTER_ITALIC)) fs |= Font.ITALIC; if(charProperties.containsKey(RtfProperty.CHARACTER_UNDERLINE)) fs |= Font.UNDERLINE; Font useFont = FontFactory.getFont(currFont.getFamilyname(), 12, fs, new Color(0,0,0)); chunk.setFont(useFont); if(iTextParagraph == null) this.iTextParagraph = new Paragraph(); this.iTextParagraph.add(chunk); } else { if(propertyName.startsWith(RtfProperty.PARAGRAPH)) { // this is a paragraph change. what do we do? } else { if(propertyName.startsWith(RtfProperty.SECTION)) { } else { if(propertyName.startsWith(RtfProperty.DOCUMENT)) { } } } } } private void addParagraphToDocument() { if(this.iTextParagraph != null) { try { this.rtfParser.getDocument().add(this.iTextParagraph); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.iTextParagraph = null; } } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationFontTable.java100644 0 0 44013 11213370070 25166 0ustar 0 0 /* * $Id: RtfDestinationFontTable.java 3832 2009-04-04 13:18:12Z blowagie $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Properties; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.rtf.parser.RtfImportMgr; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationFontTable handles data destined for the font table destination * * @author Howard Shank (hgshank@yahoo.com) * * @since 2.0.8 */ public final class RtfDestinationFontTable extends RtfDestination { /** * The RtfImportHeader to add font mappings to. */ private RtfImportMgr importHeader = null; /** * The theme (Office 2007) */ private String themeFont = ""; /** * The number of the font being parsed. */ private String fontNr = ""; /** * The family of the font being parsed. */ private String fontFamily = ""; /** * The \charset value */ private String charset = ""; private static final String CHARSET_DEFAULT = "0"; /** * The \fprq */ private int fprq = 0; /** * The \*\panose font matching value if primary font is not available. */ private String panose = ""; /** * The \*\fname */ private String nontaggedname = ""; /** * The name of the font being parsed. */ private String fontName = ""; /** * The \falt alternate font if primary font is not available. */ private String falt = ""; /** * The \falt alternate font if primary font is not available. */ private String fontemb = ""; /** * The \falt alternate font if primary font is not available. */ private String fontType = ""; /** * The \falt alternate font if primary font is not available. */ private String fontFile = ""; /** * The \falt alternate font if primary font is not available. */ private String fontFileCpg = ""; /** * The \fbias value */ private int fbias = 0; /** * The \cpg value */ private String cpg = ""; /** * The \fnil, \fttruetype value */ private String trueType = ""; /** * state flag to handle different parsing of a font element */ private int state = 0; /* state values */ /** Normal */ private static final int SETTING_NORMAL = 0; /** \falt */ private static final int SETTING_ALTERNATE = 1; /** \fname */ private static final int SETTING_FONTNAME = 2; /** \panose */ private static final int SETTING_PANOSE = 3; /** \fontemb */ private static final int SETTING_FONT_EMBED = 4; /** \ffile */ private static final int SETTING_FONT_FILE = 5; /** * Convert font mapping to FontFactory font objects. */ private HashMap fontMap = null; /** * Constructor */ public RtfDestinationFontTable() { super(null); } /** * Constructs a new RtfFontTableParser. * * @param parser an RtfParser. * * @since 2.0.8 */ public RtfDestinationFontTable(RtfParser parser) { super(parser); this.init(true); } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setParser(com.lowagie.text.rtf.parser.RtfParser) * * @since 2.0.8 */ public void setParser(RtfParser parser) { if(this.rtfParser != null && this.rtfParser.equals(parser)) return; this.rtfParser = parser; this.init(true); } /** * Initialize the object. * * @param importFonts true to import the fonts into the FontFactory, false do not load fonts * * @since 2.0.8 */ private void init(boolean importFonts) { fontMap = new HashMap(); if(this.rtfParser != null) { this.importHeader = this.rtfParser.getImportManager(); } this.setToDefaults(); if(importFonts) { importSystemFonts(); } } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() * * @since 2.0.8 */ public boolean handleOpeningSubGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() * * @since 2.0.8 */ public boolean closeDestination() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() * * @since 2.0.8 */ public boolean handleCloseGroup() { if(this.state == SETTING_NORMAL) { processFont(); } this.state = SETTING_NORMAL; return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() * * @since 2.0.8 */ public boolean handleOpenGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[]) * * @since 2.0.8 */ public boolean handleCharacter(int ch) { switch(this.state) { case SETTING_NORMAL: this.fontName += (char)ch; break; case SETTING_ALTERNATE: this.falt += (char)ch; break; case SETTING_PANOSE: this.panose += (char)ch; break; case SETTING_FONT_EMBED: break; case SETTING_FONT_FILE: break; case SETTING_FONTNAME: break; } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData) * * @since 2.0.8 */ public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { boolean result = true; // just let fonttbl fall through and set last ctrl word object. if(ctrlWordData.ctrlWord.equals("f")) { this.setFontNumber(ctrlWordData.param); result=true;} if(ctrlWordData.ctrlWord.equals("fcharset")) { this.setCharset(ctrlWordData.param); result=true; } // font families if(ctrlWordData.ctrlWord.equals("fnil")) { this.setFontFamily("roman"); result=true; } if(ctrlWordData.ctrlWord.equals("froman")) { this.setFontFamily("roman"); result=true; } if(ctrlWordData.ctrlWord.equals("fswiss")) { this.setFontFamily("swiss"); result=true; } if(ctrlWordData.ctrlWord.equals("fmodern")) { this.setFontFamily("modern"); result=true; } if(ctrlWordData.ctrlWord.equals("fscript")) { this.setFontFamily("script"); result=true; } if(ctrlWordData.ctrlWord.equals("fdecor")) { this.setFontFamily("decor"); result=true; } if(ctrlWordData.ctrlWord.equals("ftech")) { this.setFontFamily("tech"); result=true; } if(ctrlWordData.ctrlWord.equals("fbidi")) { this.setFontFamily("bidi"); result=true; } // pitch if(ctrlWordData.ctrlWord.equals("fprq")) { this.setPitch(ctrlWordData.param); result=true; } // bias if(ctrlWordData.ctrlWord.equals("fbias")) { this.setBias(ctrlWordData.param); result=true; } // theme font information if(ctrlWordData.ctrlWord.equals("flomajor")) { this.setThemeFont("flomajor"); result= true; } if(ctrlWordData.ctrlWord.equals("fhimajor")) { this.setThemeFont("fhimajor"); result= true; } if(ctrlWordData.ctrlWord.equals("fdbmajor")) { this.setThemeFont("fdbmajor"); result= true; } if(ctrlWordData.ctrlWord.equals("fbimajor")) { this.setThemeFont("fbimajor"); result= true; } if(ctrlWordData.ctrlWord.equals("flominor")) { this.setThemeFont("flominor"); result= true; } if(ctrlWordData.ctrlWord.equals("fhiminor")) { this.setThemeFont("fhiminor"); result= true; } if(ctrlWordData.ctrlWord.equals("fdbminor")) { this.setThemeFont("fdbminor"); result= true; } if(ctrlWordData.ctrlWord.equals("fbiminor")) { this.setThemeFont("fbiminor"); result= true; } // panose if(ctrlWordData.ctrlWord.equals("panose")) {state = SETTING_PANOSE; result = true; } // \*\fname // #PCDATA if(ctrlWordData.ctrlWord.equals("fname")) {state = SETTING_FONTNAME; result = true; } // \*\falt if(ctrlWordData.ctrlWord.equals("falt")) { state = SETTING_ALTERNATE; result = true; } // \*\fontemb if(ctrlWordData.ctrlWord.equals("fontemb")) { state = SETTING_FONT_EMBED; result = true; } // font type if(ctrlWordData.ctrlWord.equals("ftnil")) { this.setTrueType("ftnil"); result= true; } if(ctrlWordData.ctrlWord.equals("fttruetype")) { this.setTrueType("fttruetype"); result= true; } // \*\fontfile if(ctrlWordData.ctrlWord.equals("fontemb")) { state = SETTING_FONT_FILE; result = true; } // codepage if(ctrlWordData.ctrlWord.equals("cpg")) { this.setCodePage(ctrlWordData.param); result= true; } this.lastCtrlWord = ctrlWordData; return result; } /** * Set the code page * @param value The code page value * * @since 2.0.8 */ public void setCodePage(String value) { this.cpg = value; } /** * Set the TrueTtype type * @param value The type * * @since 2.0.8 */ public void setTrueType(String value) { this.trueType = value; } /** * Set the font pitch * @param value Pitch value * * @since 2.0.8 */ public void setPitch(String value) { this.fprq = Integer.parseInt(value); } /** * Set the font bias * @param value Bias value * * @since 2.0.8 */ public void setBias(String value) { this.fbias = Integer.parseInt(value); } /** * Set the font theme * * @param themeFont Theme value * * @since 2.0.8 */ public void setThemeFont(String themeFont) { this.themeFont = themeFont; } /** * Set the font name to the parsed value. * * @param fontName The font name. * * @since 2.0.8 */ public void setFontName(String fontName) { this.fontName = fontName; } /** * Set the font family to the parsed value. * * @param fontFamily The font family. * * @since 2.0.8 */ public void setFontFamily(String fontFamily) { this.fontFamily = fontFamily; } /** * Set the font number to the parsed value. * This is used for mapping fonts to the new font numbers * * @param fontNr The font number. * * @since 2.0.8 */ public void setFontNumber(String fontNr) { this.fontNr = fontNr; } /** * Set the alternate font name. * * @param fontAlternate The falt font value * * @since 2.0.8 */ public void setFontAlternate(String fontAlternate) { this.falt = fontAlternate; } /** * Set the character-set to the parsed value. * * @param charset The charset value * * @since 2.0.8 */ public void setCharset(String charset) { if(charset.length() == 0) { charset = CHARSET_DEFAULT; } this.charset = charset; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults() * * @since 2.0.8 */ public void setToDefaults() { this.themeFont = ""; this.fontNr = ""; this.fontName = ""; this.fontFamily = ""; this.charset = ""; this.fprq = 0; this.panose = ""; this.nontaggedname = ""; this.falt = ""; this.fontemb = ""; this.fontType = ""; this.fontFile = ""; this.fontFileCpg = ""; this.fbias = 0; this.cpg = ""; this.trueType = ""; this.state = SETTING_NORMAL; } /** * Process the font information that was parsed from the input. * * @since 2.0.8 */ private void processFont() { this.fontName = this.fontName.trim(); if(fontName.length() == 0) return; if(fontNr.length() == 0) return; if(fontName.length()>0 && fontName.indexOf(';') >= 0) { fontName = fontName.substring(0,fontName.indexOf(';')); } if(this.rtfParser.isImport()) { //TODO: If primary font fails, use the alternate //TODO: Problem: RtfFont defaults family to \froman and doesn't allow any other family. // if you set the family, it changes the font name and not the family in the Font.java class. // if(this.fontFamily.length() > 0) { // if(this.importHeader.importFont(this.fontNr, this.fontName, this.fontFamily, Integer.parseInt(this.charset)) == false) { // if(this.falt.length() > 0) { // this.importHeader.importFont(this.fontNr, this.falt, this.fontFamily, Integer.parseInt(this.charset)); // } // } // } else { if(!this.importHeader.importFont(this.fontNr, this.fontName, Integer.parseInt("".equals(this.charset)?CHARSET_DEFAULT:this.charset))) { if(this.falt.length() > 0) { this.importHeader.importFont(this.fontNr, this.falt, Integer.parseInt("".equals(this.charset)?CHARSET_DEFAULT:this.charset)); } } // } } if(this.rtfParser.isConvert()) { // This could probably be written as a better font matching function String fName = this.fontName; // work variable for trimming name if needed. Font f1 = createfont(fName); if(f1.getBaseFont() == null && this.falt.length()>0) f1 = createfont(this.falt); if(f1.getBaseFont() == null) { // Did not find a font, let's try a substring of the first name. if(FontFactory.COURIER.indexOf(fName) > -1 ) { f1 = FontFactory.getFont(FontFactory.COURIER); } else if(FontFactory.HELVETICA.indexOf(fName) > -1 ) { f1 = FontFactory.getFont(FontFactory.HELVETICA); } else if(FontFactory.TIMES.indexOf(fName) > -1 ) { f1 = FontFactory.getFont(FontFactory.TIMES); } else if(FontFactory.SYMBOL.indexOf(fName) > -1 ) { f1 = FontFactory.getFont(FontFactory.SYMBOL); } else if(FontFactory.ZAPFDINGBATS.indexOf(fName) > -1 ) { f1 = FontFactory.getFont(FontFactory.ZAPFDINGBATS); } else { // we did not find a matching font in any form. // default to HELVETICA for now. f1 = FontFactory.getFont(FontFactory.HELVETICA); } } fontMap.put(this.fontNr, f1); //System.out.println(f1.getFamilyname()); } this.setToDefaults(); } /** * Create a font via the FontFactory * * @param fontName The font name to create * @return The created Font object * * @since 2.0.8 */ private Font createfont(String fontName) { Font f1 = null; int pos=-1; do { f1 = FontFactory.getFont(fontName); if(f1.getBaseFont() != null) break; // found a font, exit the do/while pos = fontName.lastIndexOf(' '); // find the last space if(pos>0) { fontName = fontName.substring(0, pos ); // truncate it to the last space } } while(pos>0); return f1; } /** * Get a Font object from the font map object * * @param key The font number to get * @return The mapped Font object. * * @since 2.0.8 */ public Font getFont(String key) { return (Font) fontMap.get(key); } /** * Load system fonts into the static FontFactory object * * @since 2.0.8 */ private void importSystemFonts() { Properties pr = null; try { pr = getEnvironmentVariables(); } catch (Throwable e) { } String systemRoot = pr.getProperty("SystemRoot"); Runtime runtime = Runtime.getRuntime(); String fileSeperator = System.getProperty("file.separator"); int r = FontFactory.registerDirectory(systemRoot + fileSeperator + "fonts"); } /** * Utility method to load the environment variables. * * @return Properties object with environment variable information * @throws Throwable * * @since 2.0.8 */ private Properties getEnvironmentVariables() throws Throwable { Properties environmentVariables = new Properties(); String operatingSystem = System.getProperty("os.name").toLowerCase(); Runtime runtime = Runtime.getRuntime(); Process process = null; if (operatingSystem.indexOf("windows 95") > -1 || operatingSystem.indexOf("windows 98") > -1 || operatingSystem.indexOf("me") > -1) { process = runtime.exec("command.com /c set"); } else if ((operatingSystem.indexOf("nt") > -1) || (operatingSystem.indexOf("windows 2000") > -1) || (operatingSystem.indexOf("windows xp") > -1) || (operatingSystem.indexOf("windows 2003") > -1) || (operatingSystem.indexOf("windows vista") > -1)) { process = runtime.exec("cmd.exe /c set"); } else { process = runtime.exec("env"); } BufferedReader environmentStream = new BufferedReader(new InputStreamReader(process.getInputStream())); String inputLine = ""; int idx = -1; while ((inputLine = environmentStream.readLine()) != null) { idx = inputLine.indexOf('='); environmentVariables.setProperty(inputLine.substring(0, idx), inputLine.substring(idx + 1)); } return environmentVariables; } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationInfo.java100644 0 0 13516 11012562273 24214 0ustar 0 0 /* * $Id: RtfDestinationInfo.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import com.lowagie.text.Document; import com.lowagie.text.Meta; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.document.RtfInfoElement; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationInfo handles data destined for the info destination * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfDestinationInfo extends RtfDestination { private String elementName = ""; private String text = ""; public RtfDestinationInfo() { super(null); } /** * Constructs a new RtfDestinationInfo. * * @param parser The RtfParser object. */ public RtfDestinationInfo(RtfParser parser, String elementname) { super(parser); setToDefaults(); this.elementName = elementname; } public void setParser(RtfParser parser) { this.rtfParser = parser; this.setToDefaults(); } public void setElementName(String value) { this.elementName = value; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { if (this.text.length() > 0) { Document doc = this.rtfParser.getDocument(); if(doc != null) { if(this.elementName.equals("author")){ doc.addAuthor(this.text); } if(this.elementName.equals("title")){ doc.addTitle(this.text); } if(this.elementName.equals("subject")){ doc.addSubject(this.text); } } else { RtfDocument rtfDoc = this.rtfParser.getRtfDocument(); if(rtfDoc != null) { if(this.elementName.equals("author")){ Meta meta = new Meta(this.elementName, this.text); RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta); rtfDoc.getDocumentHeader().addInfoElement(elem); } if(this.elementName.equals("title")){ Meta meta = new Meta(this.elementName, this.text); RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta); rtfDoc.getDocumentHeader().addInfoElement(elem); } if(this.elementName.equals("subject")){ Meta meta = new Meta(this.elementName, this.text); RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta); rtfDoc.getDocumentHeader().addInfoElement(elem); } } } this.setToDefaults(); } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[]) */ public boolean handleCharacter(int ch) { this.text += (char)ch; return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData) */ public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { elementName = ctrlWordData.ctrlWord; return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults() */ public void setToDefaults() { this.text = ""; } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationListTable.java100644 0 0 33462 11154165267 25217 0ustar 0 0 /* * $Id: RtfDestinationListTable.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import com.lowagie.text.Element; import com.lowagie.text.rtf.list.RtfList; import com.lowagie.text.rtf.list.RtfListLevel; import com.lowagie.text.rtf.parser.RtfImportMgr; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationListTable handles data destined for the List * Table destination * * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.0 */ public class RtfDestinationListTable extends RtfDestination { /** * The RtfImportHeader to add List mappings to. */ private RtfImportMgr importHeader = null; private RtfList newList = null; private int currentLevel = -1; private RtfListLevel currentListLevel = null; private int currentListMappingNumber = 0; private int currentSubGroupCount = 0; public RtfDestinationListTable() { super(null); } public RtfDestinationListTable(RtfParser parser) { super(parser); this.importHeader = parser.getImportManager(); } public void setParser(RtfParser parser) { this.rtfParser = parser; this.importHeader = parser.getImportManager(); this.setToDefaults(); } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { this.currentSubGroupCount++; return true; } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { // RtfListTable t = this.rtfParser.getRtfDocument().getDocumentHeader().getListTable(); // List newlist = new List(List.UNORDERED, List.NUMERICAL, 0xb7); // // newlist.set // newList = new RtfList(this.rtfParser.getRtfDocument(), newlist); // this.rtfParser.getRtfDocument().add(newList); // //newList.set // // mylist. // // this.rtfParser.setTokeniserStateSkipGroup(); // // may have to create an import mapping for lists because // there may be existing lists in the document with a duplicate ID. if (this.newList != null) { this.rtfParser.getRtfDocument().add(this.newList); } return true; } public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { boolean result = true; boolean skipCtrlWord = false; if (this.rtfParser.isImport()) { skipCtrlWord = true; if (ctrlWordData.ctrlWord.equals("listtable")) { result = true; this.currentListMappingNumber = 0; } else /* Picture info for icons/images for lists */ if (ctrlWordData.ctrlWord.equals("listpicture"))/* DESTINATION */{ skipCtrlWord = true; // this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else /* list */ if (ctrlWordData.ctrlWord.equals("list")) /* DESTINATION */{ skipCtrlWord = true; this.newList = new RtfList(this.rtfParser.getRtfDocument()); this.newList.setListType(RtfList.LIST_TYPE_NORMAL); // set default this.currentLevel = -1; this.currentListMappingNumber++; this.currentSubGroupCount = 0; result = true; } else if (ctrlWordData.ctrlWord.equals("listtemplateid")) /* // List item*/ { // ignore this because it gets regenerated in every document skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("listsimple")) /* // List item*/ { // is value 0 or 1 if(ctrlWordData.hasParam && ctrlWordData.param == "1") { this.newList.setListType(RtfList.LIST_TYPE_SIMPLE); } else { this.newList.setListType(RtfList.LIST_TYPE_NORMAL); } skipCtrlWord = true; result = true; // this gets set internally. Don't think it should be imported } else if (ctrlWordData.ctrlWord.equals("listhybrid")) /* // List item*/ { this.newList.setListType(RtfList.LIST_TYPE_HYBRID); skipCtrlWord = true; result = true; // this gets set internally. Don't think it should be imported } else if (ctrlWordData.ctrlWord.equals("listrestarthdn")) /* // List item*/ { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("listid")) { // List item cannot be between -1 and -5 // needs to be mapped for imports and is recreated // we have the new id and the old id. Just add it to the mapping table here. skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("listname"))/* // List item*/ { this.newList.setName(ctrlWordData.param); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("liststyleid"))/* // List item*/ { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("liststylename"))/* // List item*/ { skipCtrlWord = true; result = true; } else /* listlevel */ if (ctrlWordData.ctrlWord.equals("listlevel")) /* DESTINATION There are 1 or 9 listlevels per list */{ this.currentLevel++; this.currentListLevel = this.newList.getListLevel(this.currentLevel); this.currentListLevel.setTentative(false); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("leveljc")) { // listlevel item justify // this is the old number. Only use it if the current type is not set if( this.currentListLevel.getAlignment()== RtfListLevel.LIST_TYPE_UNKNOWN) { switch(ctrlWordData.intValue()) { case 0: this.currentListLevel.setAlignment(Element.ALIGN_LEFT); break; case 1: this.currentListLevel.setAlignment(Element.ALIGN_CENTER); break; case 2: this.currentListLevel.setAlignment(Element.ALIGN_RIGHT); break; } } skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("leveljcn")) { // listlevel item //justify // if this exists, use it and it overrides the old setting switch(ctrlWordData.intValue()) { case 0: this.currentListLevel.setAlignment(Element.ALIGN_LEFT); break; case 1: this.currentListLevel.setAlignment(Element.ALIGN_CENTER); break; case 2: this.currentListLevel.setAlignment(Element.ALIGN_RIGHT); break; } skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelstartat")) { this.currentListLevel.setListStartAt(ctrlWordData.intValue()); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("lvltentative")) { this.currentListLevel.setTentative(true); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelold")) { // old style. ignore skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelprev")) { // old style. ignore skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelprevspace")) { // old style. ignore skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelspace")) { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelindent")) { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("leveltext")) {/* FIX */ skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelfollow")) { this.currentListLevel.setLevelFollowValue(ctrlWordData.intValue()); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levellegal")) { this.currentListLevel.setLegal(ctrlWordData.param=="1"?true:false); skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelnorestart")) { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("chrfmt")) {/* FIX */ // set an attribute pair skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelpicture")) { skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("li")) { // set an attribute pair skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("fi")) { // set an attribute pair skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("jclisttab")) { // set an attribute pair skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("tx")) { // set an attribute pair skipCtrlWord = true; result = true; } else /* number */ if (ctrlWordData.ctrlWord.equals("levelnfc")) /* old style */ { if( this.currentListLevel.getListType()== RtfListLevel.LIST_TYPE_UNKNOWN) { this.currentListLevel.setListType(ctrlWordData.intValue()+RtfListLevel.LIST_TYPE_BASE); } skipCtrlWord = true; result = true; } else if (ctrlWordData.ctrlWord.equals("levelnfcn")) /* new style takes priority over levelnfc.*/ { this.currentListLevel.setListType(ctrlWordData.intValue()+RtfListLevel.LIST_TYPE_BASE); skipCtrlWord = true; result = true; } else /* level text */ if (ctrlWordData.ctrlWord.equals("leveltemplateid")) { // ignore. this value is regenerated in each document. skipCtrlWord = true; result = true; } else /* levelnumber */ if (ctrlWordData.ctrlWord.equals("levelnumbers")) { skipCtrlWord = true; result = true; } } if (this.rtfParser.isConvert()) { if (ctrlWordData.ctrlWord.equals("shppict")) { result = true; } if (ctrlWordData.ctrlWord.equals("nonshppict")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } } if (!skipCtrlWord) { switch (this.rtfParser.getConversionType()) { case RtfParser.TYPE_IMPORT_FULL: // writeBuffer(); // writeText(ctrlWordData.toString()); result = true; break; case RtfParser.TYPE_IMPORT_FRAGMENT: // writeBuffer(); // writeText(ctrlWordData.toString()); result = true; break; case RtfParser.TYPE_CONVERT: result = true; break; default: // error because is should be an import or convert result = false; break; } } return result; } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { this.currentSubGroupCount--; if(this.newList != null && this.currentSubGroupCount == 0) { this.importHeader.importList(Integer.toString(this.currentListMappingNumber), Integer.toString(this.newList.getListNumber())); this.rtfParser.getRtfDocument().add(this.newList); } return true; } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { // TODO Auto-generated method stub return true; } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int) */ public boolean handleCharacter(int ch) { // TODO Auto-generated method stub return true; } /* * (non-Javadoc) * * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults() */ public void setToDefaults() { // TODO Auto-generated method stub } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationListener.java100644 0 0 6717 11012562273 25073 0ustar 0 0 /* * $Id: RtfDestinationListener.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.util.EventListener; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationListener interface for handling events. * * @author Howard Shank (hgshank@yahoo.com) * * @since 2.0.8 */ public interface RtfDestinationListener extends EventListener { /** * */ public RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData); /** * */ public RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData); /** * */ public RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData); /** * */ public int beforeCharacter(int ch); /** * */ public int onCharacter(int ch); /** * */ public int afterCharacter(int ch); /** * * @return true if all went well */ public boolean onOpenGroup(); /** * * @return true if all went well */ public boolean onCloseGroup(); } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationMgr.java100644 0 0 17604 11012562273 24050 0ustar 0 0 /* * $Id: RtfDestinationMgr.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.util.HashMap; import com.lowagie.text.rtf.parser.RtfParser; /** * RtfDestinationMgr manages destination objects for the parser * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfDestinationMgr { /* * Destinations */ private static RtfDestinationMgr instance = null; private static Object lock = new Object(); /** * CtrlWord <-> Destination map object. * * Maps control words to their destinations objects. * Null destination is a special destination used for * discarding unwanted data. This is primarily used when * skipping groups, binary data or unwanted/unknown data. */ private static HashMap destinations = new HashMap(300, 0.95f); /** * Destination objects. * There is only one of each destination. */ private static HashMap destinationObjects = new HashMap(10, 0.95f); private static boolean ignoreUnknownDestinations = false; private static RtfParser rtfParser = null; /** * String representation of null destination. */ public static final String DESTINATION_NULL = "null"; /** * String representation of document destination. */ public static final String DESTINATION_DOCUMENT = "document"; /** * Hidden default constructor becuase */ private RtfDestinationMgr() { } public static void setParser(RtfParser parser) { rtfParser = parser; } public static RtfDestinationMgr getInstance() { synchronized(lock) { if(instance == null) { instance = new RtfDestinationMgr(); // 2 required destinations for all documents RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } ); RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } ); } return instance; } } public static RtfDestinationMgr getInstance(RtfParser parser) { synchronized(lock) { RtfDestinationMgr.setParser(parser); if(instance == null) { instance = new RtfDestinationMgr(); // 2 required destinations for all documents RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } ); RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } ); } return instance; } } public static RtfDestination getDestination(String destination) { RtfDestination dest = null; if(destinations.containsKey(destination)) { dest = (RtfDestination)destinations.get(destination); } else { if(ignoreUnknownDestinations) { dest = (RtfDestination)destinations.get(DESTINATION_NULL); } else { dest = (RtfDestination)destinations.get(DESTINATION_DOCUMENT); } } dest.setParser(RtfDestinationMgr.rtfParser); return dest; } public static boolean addDestination(String destination, Object[] args) { if(destinations.containsKey(destination)) { return true; } String thisClass = "com.lowagie.text.rtf.parser.destinations." + (String)args[0]; if(thisClass.indexOf("RtfDestinationNull") >= 0) { destinations.put(destination, RtfDestinationNull.getInstance()); return true; } Class value = null; try { value = Class.forName(thisClass); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); return false; } RtfDestination c = null; if(destinationObjects.containsKey(value.getName())) { c = (RtfDestination)destinationObjects.get(value.getName()); } else { try { c = (RtfDestination)value.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } } c.setParser(rtfParser); if(value.isInstance(RtfDestinationInfo.class)) { ((RtfDestinationInfo)c).setElementName(destination); } if(value.isInstance(RtfDestinationStylesheetTable.class)) { ((RtfDestinationStylesheetTable)c).setElementName(destination); ((RtfDestinationStylesheetTable)c).setType((String)args[1]); } destinations.put(destination, c); destinationObjects.put(value.getName(), c); return true; } // listener methods /** * Adds a RtfDestinationListener to the appropriate RtfDestination. * * @param destination the destination string for the listener * @param listener * the new RtfDestinationListener. */ public static boolean addListener(String destination, RtfDestinationListener listener) { RtfDestination dest = getDestination(destination); if(dest != null) { return dest.addListener(listener); } return false; } /** * Removes a RtfDestinationListener from the appropriate RtfDestination. * * @param destination the destination string for the listener * @param listener * the RtfCtrlWordListener that has to be removed. */ public static boolean removeListener(String destination, RtfDestinationListener listener) { RtfDestination dest = getDestination(destination); if(dest != null) { return dest.removeListener(listener); } return false; } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationNull.java100644 0 0 12177 11012562273 24235 0ustar 0 0 /* * $Id: RtfDestinationNull.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationNull is for discarded entries. They go nowhere. * If a control word destination is unknown or ignored, this is the destination * that should be set. * * All methods return true indicating they were handled. * * This is a unique destination in that it is a singleton. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfDestinationNull extends RtfDestination { private static RtfDestinationNull instance = null; private static Object lock = new Object(); /** * Constructs a new RtfDestinationNull. * * This constructor is hidden for internal use only. */ private RtfDestinationNull() { super(); } /** * Constructs a new RtfDestinationNull. * * This constructor is hidden for internal use only. * * @param parser Unused value */ private RtfDestinationNull(RtfParser parser) { super(null); } /** * Get the singleton instance of RtfDestinationNull object. */ static public RtfDestinationNull getInstance() { synchronized(lock) { if(instance == null) instance = new RtfDestinationNull(); return instance; } } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults() */ public void setToDefaults() { } // Interface definitions /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { //this.rtfParser.setTokeniserStateNormal(); return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { //this.rtfParser.setTokeniserStateSkipGroup(); return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[]) */ public boolean handleCharacter(int ch) { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData) */ public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { return true; } public static String getName() { return RtfDestinationNull.class.getName(); } public int getNewTokeniserState() { return RtfParser.TOKENISER_SKIP_GROUP; } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationShppict.java100644 0 0 47564 11036112746 24747 0ustar 0 0 /* * $Id: RtfDestinationShppict.java 3453 2008-05-26 03:02:41Z xlv $ * * Copyright 2007, 2008 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.MalformedURLException; import com.lowagie.text.BadElementException; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Image; import com.lowagie.text.rtf.direct.RtfDirectContent; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfDestinationShppict handles data destined for picture destinations * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfDestinationShppict extends RtfDestination { private StringBuffer hexChars = new StringBuffer(0); private StringBuffer buffer = new StringBuffer(); /* picttype */ private int pictureType = Image.ORIGINAL_NONE; // public static final int ORIGINAL_NONE = 0; // public static final int ORIGINAL_GIF = 3; // public static final int ORIGINAL_TIFF = 5; // public static final int ORIGINAL_PS = 7; // emfblip - EMF (enhanced metafile) - NOT HANDLED // pngblip int ORIGINAL_PNG = 2; // jpegblip Image.ORIGINAL_JPEG = 1; ORIGINAL_JPEG2000 = 8; // shppict - Destination // nonshpict - Destination - SKIP THIS // macpict - Mac QuickDraw- NOT HANDLED // pmmetafileN - OS/2 Metafile - NOT HANDLED // N * Meaning // 0x0004 PU_ARBITRARY // 0x0008 PU_PELS // 0x000C PU_LOMETRIC // 0x0010 PU_HIMETRIC // 0x0014 PU_LOENGLISH // 0x0018 PU_HIENGLISH // 0x001C PU_TWIPS private int pmmetafile = 0; // wmetafileN Image.RIGINAL_WMF = 6; // N * Type // 1 = MM_TEXT // 2 = M_LOMETRIC // 3 = MM_HIMETRIC // 4 = MM_LOENGLISH // 5 = MM_HIENGLISH // 6 = MM_TWIPS // 7 = MM_ISOTROPIC // 8 = MM_ANISOTROPIC // dibitmapN - DIB - Convert to BMP? // wbitmapN Image.ORIGINAL_BMP = 4; /* bitapinfo */ // wbmbitspixelN - number of bits per pixel - 1 monochrome, 4 16 color, 8 256 color, 24 RGB - Default 1 private Integer bitsPerPixel = new Integer(1); // wbmplanesN - number of color planes - must be 1 private Integer planes = new Integer(1); // wbmwidthbytesN - number of bytes in each raster line private Integer widthBytes = null; /* pictsize */ // picwN Ext field if the picture is a Windows metafile; picture width in pixels if the picture is a bitmap or // from quickdraw private Long width = null; // pichN private Long height = null; // picwgoalN private Long desiredWidth = null; // picgoalN private Long desiredHeight = null; // picscalexN private Integer scaleX = new Integer(100); // picscaleyN private Integer scaleY = new Integer(100); // picscaled - macpict setting private Boolean scaled = null; // picprop private Boolean inlinePicture = Boolean.FALSE; // defshp private Boolean wordArt = Boolean.FALSE; // piccroptN private Integer cropTop = new Integer(0); // piccropbN private Integer cropBottom = new Integer(0); // piccroplN private Integer cropLeft = new Integer(0); // piccroprN private Integer cropRight = new Integer(0); /* metafileinfo */ // picbmp private boolean bitmap = false; //picbppN - Valid 1,4,8,24 private int bbp = 1; /* data */ // binN // 0 = HEX, 1 = BINARY public static final int FORMAT_HEXADECIMAL = 0; public static final int FORMAT_BINARY = 1; private int dataFormat = FORMAT_HEXADECIMAL; private long binaryLength = 0; // blipupiN private Integer unitsPerInch = null; // bliptagN private String tag = ""; private static final int NORMAL = 0; private static final int BLIPUID = 1; private int state = NORMAL; /** * Constant for converting pixels to twips */ private static final int PIXEL_TWIPS_FACTOR = 15; // Image data for import and conversion functions. private ByteArrayOutputStream dataOS = null; public RtfDestinationShppict() { super(null); } /** * Constructs a new RtfDestinationShppict. */ public RtfDestinationShppict(RtfParser parser) { super(parser); } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { if (this.rtfParser.isImport()) { if (this.buffer.length() > 0) { writeBuffer(); } } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { this.onCloseGroup(); // event handler if (this.rtfParser.isImport()) { if (this.buffer.length() > 0) { writeBuffer(); } if (dataOS != null) { addImage(); dataOS = null; } this.writeText("}"); return true; } if (this.rtfParser.isConvert()) { if (dataOS != null) { addImage(); dataOS = null; } } return true; } private boolean addImage() { Image img = null; try { img = Image.getInstance(dataOS.toByteArray()); //data=null; } catch (BadElementException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { // log there was in unsupported image found. Continue to import/convert the document. e.printStackTrace(); } if (img != null) { // DEBUG: Write test file to see what is in Image object. // FileOutputStream out =null; // try { // out = new FileOutputStream("c:\\testOrig.png"); // out.write(dataOS.toByteArray()); // out.close(); // out = new FileOutputStream("c:\\testNew.png"); // out.write(img.getOriginalData()); // out.close(); // } catch (FileNotFoundException e1) { // e1.printStackTrace(); // } catch (IOException e1) { // e1.printStackTrace(); // } // set the image attributes img.scaleAbsolute(this.desiredWidth.floatValue() / PIXEL_TWIPS_FACTOR, this.desiredHeight.floatValue() / PIXEL_TWIPS_FACTOR); img.scaleAbsolute(this.width.floatValue() / PIXEL_TWIPS_FACTOR, this.height.floatValue() / PIXEL_TWIPS_FACTOR); img.scalePercent(this.scaleX.floatValue(), this.scaleY.floatValue()); // img.setBorder(value); try { if (this.rtfParser.isImport()) { Document doc = this.rtfParser.getDocument(); doc.add(img); // RtfDocument rtfDoc = this.rtfParser.getRtfDocument(); // RtfImage rtfImage = new RtfImage(rtfDoc, img); // rtfDoc.add(rtfImage); } if (this.rtfParser.isConvert()) { this.rtfParser.getDocument().add(img); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } dataFormat = FORMAT_HEXADECIMAL; return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { this.onOpenGroup(); // event handler if (this.rtfParser.isImport()) { } if (this.rtfParser.isConvert()) { } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { if (this.rtfParser.isImport()) { if (this.buffer.length() > 0) { writeBuffer(); } } return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int) */ public boolean handleCharacter(int ch) { if (this.rtfParser.isImport()) { if (buffer.length() > 254) writeBuffer(); } //if(data == null) data = new ByteBuffer(); if (dataOS == null) { dataOS = new ByteArrayOutputStream(); } switch (dataFormat) { case FORMAT_HEXADECIMAL: hexChars.append((char) ch); if (hexChars.length() == 2) { try { dataOS.write((char) Integer.parseInt(hexChars.toString(), 16)); } catch (NumberFormatException e) { e.printStackTrace(); } hexChars = new StringBuffer(); } break; case FORMAT_BINARY: if (dataOS == null) { dataOS = new ByteArrayOutputStream(); } // HGS - FIX ME IF PROBLEM! dataOS.write((char) (ch)); // PNG signature should be. // (decimal) 137 80 78 71 13 10 26 10 // (hexadecimal) 89 50 4e 47 0d 0a 1a 0a // (ASCII C notation) \211 P N G \r \n \032 \n binaryLength--; if (binaryLength == 0) { dataFormat = FORMAT_HEXADECIMAL; } break; } return true; } public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { boolean result = false; boolean skipCtrlWord = false; if (this.rtfParser.isImport()) { skipCtrlWord = true; if (ctrlWordData.ctrlWord.equals("shppict")) { result = true; } else if (ctrlWordData.ctrlWord.equals("nonshppict")) /* never gets here because this is a destination set to null */{ skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else if (ctrlWordData.ctrlWord.equals("blipuid")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else if (ctrlWordData.ctrlWord.equals("picprop")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else if (ctrlWordData.ctrlWord.equals("pict")) { result = true; } else if (ctrlWordData.ctrlWord.equals("emfblip")) { result = true; pictureType = Image.ORIGINAL_NONE; } else if (ctrlWordData.ctrlWord.equals("pngblip")) { result = true; pictureType = Image.ORIGINAL_PNG; } else if (ctrlWordData.ctrlWord.equals("jepgblip")) { result = true; pictureType = Image.ORIGINAL_JPEG; } else if (ctrlWordData.ctrlWord.equals("macpict")) { result = true; pictureType = Image.ORIGINAL_NONE; } else if (ctrlWordData.ctrlWord.equals("pmmetafile")) { result = true; pictureType = Image.ORIGINAL_NONE; } else if (ctrlWordData.ctrlWord.equals("wmetafile")) { result = true; pictureType = Image.ORIGINAL_WMF; } else if (ctrlWordData.ctrlWord.equals("dibitmap")) { result = true; pictureType = Image.ORIGINAL_NONE; } else if (ctrlWordData.ctrlWord.equals("wbitmap")) { result = true; pictureType = Image.ORIGINAL_BMP; } /* bitmap information */ else if (ctrlWordData.ctrlWord.equals("wbmbitspixel")) { result = true; } else if (ctrlWordData.ctrlWord.equals("wbmplanes")) { result = true; } else if (ctrlWordData.ctrlWord.equals("wbmwidthbytes")) { result = true; } else /* picture size, scaling and cropping */ if (ctrlWordData.ctrlWord.equals("picw")) { this.width = ctrlWordData.toLong(); result = true; } else if (ctrlWordData.ctrlWord.equals("pich")) { this.height = ctrlWordData.toLong(); result = true; } else if (ctrlWordData.ctrlWord.equals("picwgoal")) { this.desiredWidth = ctrlWordData.toLong(); result = true; } else if (ctrlWordData.ctrlWord.equals("pichgoal")) { this.desiredHeight = ctrlWordData.toLong(); result = true; } else if (ctrlWordData.ctrlWord.equals("picscalex")) { this.scaleX = ctrlWordData.toInteger(); result = true; } else if (ctrlWordData.ctrlWord.equals("picscaley")) { this.scaleY = ctrlWordData.toInteger(); result = true; } else if (ctrlWordData.ctrlWord.equals("picscaled")) { result = true; } else if (ctrlWordData.ctrlWord.equals("picprop")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else if (ctrlWordData.ctrlWord.equals("defshp")) { result = true; } else if (ctrlWordData.ctrlWord.equals("piccropt")) { this.cropTop = ctrlWordData.toInteger(); result = true; } else if (ctrlWordData.ctrlWord.equals("piccropb")) { this.cropBottom = ctrlWordData.toInteger(); result = true; } else if (ctrlWordData.ctrlWord.equals("piccropl")) { this.cropLeft = ctrlWordData.toInteger(); result = true; } else if (ctrlWordData.ctrlWord.equals("piccropr")) { this.cropRight = ctrlWordData.toInteger(); result = true; } else /* metafile information */ if (ctrlWordData.ctrlWord.equals("picbmp")) { result = true; } else if (ctrlWordData.ctrlWord.equals("picbpp")) { result = true; } else /* picture data */ if (ctrlWordData.ctrlWord.equals("bin")) { this.dataFormat = FORMAT_BINARY; // set length to param this.binaryLength = ctrlWordData.longValue(); this.rtfParser.setTokeniserStateBinary(binaryLength); result = true; } else if (ctrlWordData.ctrlWord.equals("blipupi")) { result = true; } else if (ctrlWordData.ctrlWord.equals("blipuid")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } else if (ctrlWordData.ctrlWord.equals("bliptag")) { result = true; } } if (this.rtfParser.isConvert()) { if (ctrlWordData.ctrlWord.equals("shppict")) { result = true; } if (ctrlWordData.ctrlWord.equals("nonshppict")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } if (ctrlWordData.ctrlWord.equals("blipuid")) { result = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } if (ctrlWordData.ctrlWord.equals("pict")) { result = true; } if (ctrlWordData.ctrlWord.equals("emfblip")) { result = true; } if (ctrlWordData.ctrlWord.equals("pngblip")) { result = true; } if (ctrlWordData.ctrlWord.equals("jepgblip")) { result = true; } if (ctrlWordData.ctrlWord.equals("macpict")) { result = true; } if (ctrlWordData.ctrlWord.equals("pmmetafile")) { result = true; } if (ctrlWordData.ctrlWord.equals("wmetafile")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } if (ctrlWordData.ctrlWord.equals("dibitmap")) { result = true; } if (ctrlWordData.ctrlWord.equals("wbitmap")) { result = true; } /* bitmap information */ if (ctrlWordData.ctrlWord.equals("wbmbitspixel")) { result = true; } if (ctrlWordData.ctrlWord.equals("wbmplanes")) { result = true; } if (ctrlWordData.ctrlWord.equals("wbmwidthbytes")) { result = true; } /* picture size, scaling and cropping */ if (ctrlWordData.ctrlWord.equals("picw")) { this.width = ctrlWordData.toLong(); result = true; } if (ctrlWordData.ctrlWord.equals("pich")) { this.height = ctrlWordData.toLong(); result = true; } if (ctrlWordData.ctrlWord.equals("picwgoal")) { this.desiredWidth = ctrlWordData.toLong(); result = true; } if (ctrlWordData.ctrlWord.equals("pichgoal")) { this.desiredHeight = ctrlWordData.toLong(); result = true; } if (ctrlWordData.ctrlWord.equals("picscalex")) { this.scaleX = ctrlWordData.toInteger(); result = true; } if (ctrlWordData.ctrlWord.equals("picscaley")) { this.scaleY = ctrlWordData.toInteger(); result = true; } if (ctrlWordData.ctrlWord.equals("picscaled")) { result = true; } if (ctrlWordData.ctrlWord.equals("picprop")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } if (ctrlWordData.ctrlWord.equals("defshp")) { result = true; } if (ctrlWordData.ctrlWord.equals("piccropt")) { this.cropTop = ctrlWordData.toInteger(); result = true; } if (ctrlWordData.ctrlWord.equals("piccropb")) { this.cropBottom = ctrlWordData.toInteger(); result = true; } if (ctrlWordData.ctrlWord.equals("piccropl")) { this.cropLeft = ctrlWordData.toInteger(); result = true; } if (ctrlWordData.ctrlWord.equals("piccropr")) { this.cropRight = ctrlWordData.toInteger(); result = true; } /* metafile information */ if (ctrlWordData.ctrlWord.equals("picbmp")) { result = true; } if (ctrlWordData.ctrlWord.equals("picbpp")) { result = true; } /* picture data */ if (ctrlWordData.ctrlWord.equals("bin")) { dataFormat = FORMAT_BINARY; result = true; } if (ctrlWordData.ctrlWord.equals("blipupi")) { result = true; } if (ctrlWordData.ctrlWord.equals("blipuid")) { skipCtrlWord = true; this.rtfParser.setTokeniserStateSkipGroup(); result = true; } if (ctrlWordData.ctrlWord.equals("bliptag")) { result = true; } } if (!skipCtrlWord) { switch (this.rtfParser.getConversionType()) { case RtfParser.TYPE_IMPORT_FULL: writeBuffer(); writeText(ctrlWordData.toString()); result = true; break; case RtfParser.TYPE_IMPORT_FRAGMENT: writeBuffer(); writeText(ctrlWordData.toString()); result = true; break; case RtfParser.TYPE_CONVERT: result = true; break; default: // error because is should be an import or convert result = false; break; } } return result; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults() */ public void setToDefaults() { this.buffer = new StringBuffer(); //this.data = null; this.width = null; this.height = null; this.desiredWidth = null; this.desiredHeight = null; this.scaleX = new Integer(100); this.scaleY = new Integer(100); this.scaled = null; this.inlinePicture = Boolean.FALSE; this.wordArt = Boolean.FALSE; this.cropTop = new Integer(0); this.cropBottom = new Integer(0); this.cropLeft = new Integer(0); this.cropRight = new Integer(0); this.bitmap = false; this.bbp = 1; this.dataFormat = FORMAT_HEXADECIMAL; this.binaryLength = 0; this.unitsPerInch = null; this.tag = ""; } private void writeBuffer() { writeText(this.buffer.toString()); //setToDefaults(); } private void writeText(String value) { if (this.rtfParser.getState().newGroup) { this.rtfParser.getRtfDocument().add(new RtfDirectContent("{")); this.rtfParser.getState().newGroup = false; } if (value.length() > 0) { this.rtfParser.getRtfDocument().add(new RtfDirectContent(value)); } } } src/rtf/com/lowagie/text/rtf/parser/destinations/RtfDestinationStylesheetTable.java100644 0 0 41722 11106243445 26423 0ustar 0 0 /* * $Id: RtfDestinationStylesheetTable.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.destinations; import com.lowagie.text.Element; import com.lowagie.text.rtf.parser.RtfImportMgr; import com.lowagie.text.rtf.parser.RtfParser; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordType; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.style.RtfStyleTypes; /** * RtfDestinationStylesheetTable handles data destined for the * Stylesheet Table destination * * @author Howard Shank (hgshank@yahoo.com) * @since 2.1.0 */ public class RtfDestinationStylesheetTable extends RtfDestination { private String styleName = ""; /** * RtfParagraphStyle object for setting styleshee values * as they are parsed from the input. */ private RtfParagraphStyle rtfParagraphStyle = null; private String elementName = ""; /** * RTF Style number from stylesheet table. */ private int styleNr = 0; /** * What kind of style is this, Paragraph or Character or Table */ private int styleType = RtfStyleTypes.PARAGRAPH; // Alignment /** * Alignment - page 85 * \qc, \qj, \ql, \qr, \qd, \qkN, \qt */ private int alignment = Element.ALIGN_LEFT; /** * Percentage of line occupied by Kashida justification (0 � low, 10 � medium, 20 � high). * \qkN */ private int justificationPercentage = 0; // Indentation /** * First line indentation. */ private int firstLineIndent = 0; /** * Left indentation */ private int leftIndent = 0; /** * Right indentation */ private int rightIndent = 0; /** * Automatically adjust right indentation when docunent grid is defined */ private int adustRightIndent = 0; /** * Mirror indents? */ private int mirrorIndent = 0; // Document Foratting Properties /** * Override orphan/widow control. */ private int overrideWidowControl = -1; // Asian Typography /** * auto spacing betwee DBC and English */ private int AutoSpaceBetweenDBCEnglish = 0; /** * auto spacing betwee DBC and numbers */ private int AutoSpaceBetweenDBCNumbers = 0; /** * No Character wrapping */ private int noCharacterWrapping = 0; /** * No Word wrapping */ private int noWordWrapping = 0; /** * No overflow period and comma */ private int noOverflowPeriodComma = 0; ////////////////////////////////////////////////////// /** * The RtfImportHeader to add color mappings to. */ private RtfImportMgr importHeader = null; private String type = ""; public RtfDestinationStylesheetTable() { super(null); } public RtfDestinationStylesheetTable(RtfParser parser, String type) { super(parser); this.importHeader = parser.getImportManager(); this.type = type; } public void setParser(RtfParser parser) { this.rtfParser = parser; this.importHeader = parser.getImportManager(); } public void setType(String value) { this.type = value; } public void setElementName(String value) { this.elementName = value; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup() */ public boolean handleOpeningSubGroup() { // TODO Auto-generated method stub return false; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination() */ public boolean closeDestination() { return true; } public boolean handleControlWord(RtfCtrlWordData ctrlWordData) { boolean result = true; this.onCtrlWord(ctrlWordData); // event handler if(this.rtfParser.isImport()) { // information // start of a stylesheet element if(ctrlWordData.ctrlWord.equals("s")) { } if(ctrlWordData.ctrlWord.equals("cs")) {} if(ctrlWordData.ctrlWord.equals("ds")) {} if(ctrlWordData.ctrlWord.equals("ts")) {} if(ctrlWordData.ctrlWord.equals("tsrowd")) {} if(ctrlWordData.ctrlWord.equals("keycode")) {} if(ctrlWordData.ctrlWord.equals("shift")) { } if(ctrlWordData.ctrlWord.equals("ctrl")) { } if(ctrlWordData.ctrlWord.equals("alt")) { } //cells if(ctrlWordData.ctrlWord.equals("fn")) { } if(ctrlWordData.ctrlWord.equals("additive")) { } if(ctrlWordData.ctrlWord.equals("sbasedon")) { } if(ctrlWordData.ctrlWord.equals("snext")) { } if(ctrlWordData.ctrlWord.equals("sautoupd")) { } if(ctrlWordData.ctrlWord.equals("shidden")) { } if(ctrlWordData.ctrlWord.equals("slink")) { } if(ctrlWordData.ctrlWord.equals("slocked")) { } if(ctrlWordData.ctrlWord.equals("spersonal")) { } if(ctrlWordData.ctrlWord.equals("scompose")) { } if(ctrlWordData.ctrlWord.equals("sreply")) { } /* FORMATTING */ // brdrdef/parfmt/apoctl/tabdef/shading/chrfmt if(ctrlWordData.ctrlWord.equals("styrsid")) { } if(ctrlWordData.ctrlWord.equals("ssemihidden")) { } if(ctrlWordData.ctrlWord.equals("sqformat")) { } if(ctrlWordData.ctrlWord.equals("spriority")) { } if(ctrlWordData.ctrlWord.equals("sunhideused")) { } /* TABLE STYLES */ if(ctrlWordData.ctrlWord.equals("tscellwidth")) { } if(ctrlWordData.ctrlWord.equals("tscellwidthfts")) { } if(ctrlWordData.ctrlWord.equals("tscellpaddt")) { } if(ctrlWordData.ctrlWord.equals("tscellpaddl")) { } if(ctrlWordData.ctrlWord.equals("tscellpaddr")) { } if(ctrlWordData.ctrlWord.equals("tscellpaddb")) { } if(ctrlWordData.ctrlWord.equals("tscellpaddft"))/*0-auto, 3-twips*/ { } if(ctrlWordData.ctrlWord.equals("tscellpaddfl"))/*0-auto, 3-twips*/ { } if(ctrlWordData.ctrlWord.equals("tscellpaddfr"))/*0-auto, 3-twips*/ { } if(ctrlWordData.ctrlWord.equals("tscellpaddfb"))/*0-auto, 3-twips*/ { } if(ctrlWordData.ctrlWord.equals("tsvertalt")) { } if(ctrlWordData.ctrlWord.equals("tsvertalc")) { } if(ctrlWordData.ctrlWord.equals("tsvertalb")) { } if(ctrlWordData.ctrlWord.equals("tsnowrap")) { } if(ctrlWordData.ctrlWord.equals("tscellcfpat")) { } if(ctrlWordData.ctrlWord.equals("tscellcbpat")) { } if(ctrlWordData.ctrlWord.equals("tsbgbdiag")) { } if(ctrlWordData.ctrlWord.equals("tsbgfdiag")) { } if(ctrlWordData.ctrlWord.equals("tsbgcross")) { } if(ctrlWordData.ctrlWord.equals("tsbgdcross")) { } if(ctrlWordData.ctrlWord.equals("tsbgdkcross ")) { } if(ctrlWordData.ctrlWord.equals("tsbgdkdcross")) { } if(ctrlWordData.ctrlWord.equals("tsbghoriz")) { } if(ctrlWordData.ctrlWord.equals("tsbgvert")) { } if(ctrlWordData.ctrlWord.equals("tsbgdkhor")) { } if(ctrlWordData.ctrlWord.equals("tsbgdkvert")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrt")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrb")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrl")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrr")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrh")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrv")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrdgl")) { } if(ctrlWordData.ctrlWord.equals("tsbrdrdgr")) { } if(ctrlWordData.ctrlWord.equals("tscbandsh")) { } if(ctrlWordData.ctrlWord.equals("tscbandsv")) { } } if(ctrlWordData.ctrlWordType == RtfCtrlWordType.FLAG || ctrlWordData.ctrlWordType == RtfCtrlWordType.TOGGLE || ctrlWordData.ctrlWordType == RtfCtrlWordType.VALUE) { this.rtfParser.getState().properties.setProperty(ctrlWordData); } switch(this.rtfParser.getConversionType()) { case RtfParser.TYPE_IMPORT_FULL: result = true; break; case RtfParser.TYPE_IMPORT_FRAGMENT: result = true; break; case RtfParser.TYPE_CONVERT: result = true; break; default: // error because is should be an import or convert result = false; break; } return result; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd() */ public boolean handleCloseGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart() */ public boolean handleOpenGroup() { return true; } /* (non-Javadoc) * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int) */ public boolean handleCharacter(int ch) { styleName += (char)ch; return true; } public void createNewStyle() { //public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor) //this.rtfParagraphStyle = new RtfParagraphStyle(); } /** * Set the justification percentage from parsed value. * @param percent The justification percentage * @return The justification percentage */ public int setJustificationPercentage(int percent) { this.justificationPercentage = percent; return this.justificationPercentage; } /** * Get the justification percentage. * @return The justification percentage value. */ public int getJustificationPercentage() { return this.justificationPercentage; } /** * Set the alignment value from the parsed value. * @param alignment The alignment value. * @return The alignment value. */ public int setAlignment(int alignment) { this.alignment = alignment; return this.alignment; } /** * Get the alignment value. * @return The alignment value. */ public int getAlignment() { return this.alignment; } /** * Get the first line indent value. * * @return the firstLineIndent */ public int getFirstLineIndent() { return firstLineIndent; } /** * Set the first line indent value. * @param firstLineIndent the firstLineIndent to set */ public void setFirstLineIndent(int firstLineIndent) { this.firstLineIndent = firstLineIndent; } /** * Get the left indent value * @return the left indent */ public int getIndent() { return leftIndent; } /** * Set the left indent value from the value parsed. * @param indent the left indent value. */ public void setIndent(int indent) { this.leftIndent = indent; } /** * Get the right indent adjustment value * @return the adustRightIndent value */ public int getAdustRightIndent() { return adustRightIndent; } /** * Set the right indent adjustment value * @param adustRightIndent the adustRightIndent to set */ public void setAdustRightIndent(int adustRightIndent) { this.adustRightIndent = adustRightIndent; } /** * Get the left indent value * @return the leftIndent */ public int getLeftIndent() { return leftIndent; } /** * Set the left indent value * @param leftIndent the leftIndent to set */ public void setLeftIndent(int leftIndent) { this.leftIndent = leftIndent; } /** * Get the value indicating if document has mirrored indents. * * @return the mirrorIndent */ public int getMirrorIndent() { return mirrorIndent; } /** * Set the mirrored indent value from the parsed value. * * @param mirrorIndent the mirrorIndent to set */ public void setMirrorIndent(int mirrorIndent) { this.mirrorIndent = mirrorIndent; } /** * Get the right indent value. * * @return the rightIndent */ public int getRightIndent() { return rightIndent; } /** * Set the right indent value. * * @param rightIndent the rightIndent to set */ public void setRightIndent(int rightIndent) { this.rightIndent = rightIndent; } /** * Get the ovirride widow control value. * * @return the overrideWidowControl */ public int getOverrideWidowControl() { return overrideWidowControl; } /** * Set the override widow control. * * @param overrideWidowControl the overrideWidowControl to set */ public void setOverrideWidowControl(int overrideWidowControl) { this.overrideWidowControl = overrideWidowControl; } /** * Get the auto space between DBC and English indicator. * * @return the autoSpaceBetweenDBCEnglish */ public int getAutoSpaceBetweenDBCEnglish() { return AutoSpaceBetweenDBCEnglish; } /** * Set the auto space between DBC and English indicator. * * @param autoSpaceBetweenDBCEnglish the autoSpaceBetweenDBCEnglish to set */ public void setAutoSpaceBetweenDBCEnglish(int autoSpaceBetweenDBCEnglish) { AutoSpaceBetweenDBCEnglish = autoSpaceBetweenDBCEnglish; } /** * Get the auto space between DBC and Numbers indicator. * @return the autoSpaceBetweenDBCNumbers */ public int getAutoSpaceBetweenDBCNumbers() { return AutoSpaceBetweenDBCNumbers; } /** * Set the auto space between DBC and Numbers indicator. * @param autoSpaceBetweenDBCNumbers the autoSpaceBetweenDBCNumbers to set */ public void setAutoSpaceBetweenDBCNumbers(int autoSpaceBetweenDBCNumbers) { AutoSpaceBetweenDBCNumbers = autoSpaceBetweenDBCNumbers; } /** * Get no character wrapping indicator. * * @return the noCharacterWrapping */ public int getNoCharacterWrapping() { return noCharacterWrapping; } /** * Set the no character wrapping indicator from parsed value * * @param noCharacterWrapping the noCharacterWrapping to set */ public void setNoCharacterWrapping(int noCharacterWrapping) { this.noCharacterWrapping = noCharacterWrapping; } /** * Get the no overflow period comma indicator. * * @return the noOverflowPeriodComma */ public int getNoOverflowPeriodComma() { return noOverflowPeriodComma; } /** * Set the no overflow period comma indicator from the parsed value. * * @param noOverflowPeriodComma the noOverflowPeriodComma to set */ public void setNoOverflowPeriodComma(int noOverflowPeriodComma) { this.noOverflowPeriodComma = noOverflowPeriodComma; } /** * Get the no word wrapping indicator. * * @return the noWordWrapping */ public int getNoWordWrapping() { return noWordWrapping; } /** * Set the no word wrapping indicator from the parsed value. * * @param noWordWrapping the noWordWrapping to set */ public void setNoWordWrapping(int noWordWrapping) { this.noWordWrapping = noWordWrapping; } /** * Get this style number. * * @return the styleNr */ public int getStyleNr() { return styleNr; } /** * Set this style number from the parsed value. * * @param styleNr the styleNr to set */ public void setStyleNr(int styleNr) { this.styleNr = styleNr; } /** * Get this style type. * For example Style, Character Style, etc. * * @return the styleType */ public int getStyleType() { return styleType; } /** * Set the style type. * * @param styleType the styleType to set */ public void setStyleType(int styleType) { this.styleType = styleType; } /* (non-Javadoc) * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults() */ public void setToDefaults() { styleName = ""; styleNr = 0; alignment = Element.ALIGN_LEFT; justificationPercentage = 0; firstLineIndent = 0; leftIndent = 0; rightIndent = 0; adustRightIndent = 0; mirrorIndent = 0; overrideWidowControl = -1; AutoSpaceBetweenDBCEnglish = 0; AutoSpaceBetweenDBCNumbers = 0; noCharacterWrapping = 0; noWordWrapping = 0; noOverflowPeriodComma = 0; } } src/rtf/com/lowagie/text/rtf/parser/enumerations/RtfColorThemes.java100644 0 0 2122 11006315535 23317 0ustar 0 0 package com.lowagie.text.rtf.parser.enumerations; /** * Specifies the color theme values for use in Color Tables. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfColorThemes { public static final int THEME_UNDEFINED = -1; public static final int THEME_MAINDARKONE = 0; public static final int THEME_MAINDARKTWO = 1; public static final int THEME_MAINLIGHTONE = 2; public static final int THEME_MAINLIGHTTWO = 3; public static final int THEME_ACCENTONE = 4; public static final int THEME_ACCENTTWO = 5; public static final int THEME_ACCENTTHREE = 6; public static final int THEME_ACCENTFOUR = 7; public static final int THEME_ACCENTFIVE = 8; public static final int THEME_ACCENTSIX = 9; public static final int THEME_HYPERLINK = 10; public static final int THEME_FOLLOWEDHYPERLINK = 11; public static final int THEME_BACKGROUNDONE = 12; public static final int THEME_TEXTONE = 13; public static final int THEME_BACKGROUNDTWO = 14; public static final int THEME_TEXTTWO = 15; public static final int THEME_MAX = 15; } src/rtf/com/lowagie/text/rtf/parser/exceptions/RtfParserException.java100644 0 0 13242 11012562273 23703 0ustar 0 0 /* * $Id: RtfParserException.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.exceptions; /* * Signals that an error has occurred in a RtfParser. */ /** * RtfParserException is the exception object thrown by * the parser * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfParserException extends Exception { private static final long serialVersionUID = 2857489935812968235L; /** * Contained inner exception object. */ private Exception ex; /** * Creates a RtfParserException object. * @param ex an exception that has to be turned into a RtfParserException */ public RtfParserException(Exception ex) { this.ex = ex; } // constructors /** * Constructs a RtfParserException whithout a message. */ public RtfParserException() { super(); } /** * Constructs a RtfParserException with a message. * * @param message a message describing the exception */ public RtfParserException(String message) { super(message); } /** * We print the message of the checked exception * @return the error message */ public String getMessage() { if (ex == null) return super.getMessage(); else return ex.getMessage(); } /** * and make sure we also produce a localized version * @return a localized message */ public String getLocalizedMessage() { if (ex == null) return super.getLocalizedMessage(); else return ex.getLocalizedMessage(); } /** * The toString() is changed to be prefixed with ExceptionConverter * @return the String version of the exception */ public String toString() { if (ex == null) return super.toString(); else return split(getClass().getName()) + ": " + ex; } /** we have to override this as well */ public void printStackTrace() { printStackTrace(System.err); } /** * here we prefix, with s.print(), not s.println(), the stack * trace with "ExceptionConverter:" * @param s a printstream object */ public void printStackTrace(java.io.PrintStream s) { if (ex == null) super.printStackTrace(s); else { synchronized (s) { s.print(split(getClass().getName()) + ": "); ex.printStackTrace(s); } } } /** * Again, we prefix the stack trace with "ExceptionConverter:" * @param s A PrintWriter object */ public void printStackTrace(java.io.PrintWriter s) { if (ex == null) super.printStackTrace(s); else { synchronized (s) { s.print(split(getClass().getName()) + ": "); ex.printStackTrace(s); } } } /** * Removes everything in a String that comes before a '.' * @param s the original string * @return the part that comes after the dot */ private static String split(String s) { int i = s.lastIndexOf('.'); if (i < 0) return s; else return s.substring(i + 1); } } src/rtf/com/lowagie/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.java100644 0 0 751 11006315534 25527 0ustar 0 0 package com.lowagie.text.rtf.parser.exceptions; /** * @since 2.1.0 */ public class RtfUnknownCtrlWordException extends RtfParserException { /** * Generated serial version UID. */ private static final long serialVersionUID = 7243046509505727849L; // constructors /** * Constructs a RtfParserException whithout a message. */ public RtfUnknownCtrlWordException() { super("Unknown control word."); } } src/rtf/com/lowagie/text/rtf/parser/properties/RtfCtrlWordPropertyType.java100644 0 0 5411 11012562273 24731 0ustar 0 0 /* $Id: RtfCtrlWordPropertyType.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.properties; /** * @since 2.1.0 */ public class RtfCtrlWordPropertyType { public static final int UNIDENTIFIED = -1; public static final int PROPERTY = 0; public static final int CHARACTER = 1; public static final int SPECIAL = 2; public static final int DESTINATION = 3; } src/rtf/com/lowagie/text/rtf/parser/properties/RtfProperty.java100644 0 0 52600 11012562273 22430 0ustar 0 0 /* $Id: RtfProperty.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.properties; import java.awt.Color; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData; /** * RtfProperty handles document, paragraph, etc. property values * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public class RtfProperty { public static final int OFF = 0; public static final int ON = 1; /* property groups */ public static final String COLOR = "color."; public static final String CHARACTER = "character."; public static final String PARAGRAPH = "paragraph."; public static final String SECTION = "section."; public static final String DOCUMENT = "document."; /* color properties */ public static final String COLOR_FG = COLOR + "fg"; //Color Object public static final String COLOR_BG = COLOR + "bg"; //Color Object /* character properties */ public static final String CHARACTER_BOLD = CHARACTER + "bold"; public static final String CHARACTER_UNDERLINE = CHARACTER + "underline"; public static final String CHARACTER_ITALIC = CHARACTER + "italic"; public static final String CHARACTER_SIZE = CHARACTER + "size"; public static final String CHARACTER_FONT = CHARACTER + "font"; public static final String CHARACTER_STYLE = CHARACTER + "style"; /* paragraph properties */ /** Justify left */ public static final int JUSTIFY_LEFT = 0; /** Justify right */ public static final int JUSTIFY_RIGHT = 1; /** Justify center */ public static final int JUSTIFY_CENTER = 2; /** Justify full */ public static final int JUSTIFY_FULL = 3; public static final String PARAGRAPH_INDENT_LEFT = PARAGRAPH + "indentLeft"; // twips public static final String PARAGRAPH_INDENT_RIGHT = PARAGRAPH + "indentRight"; // twips public static final String PARAGRAPH_INDENT_FIRST_LINE = PARAGRAPH + "indentFirstLine"; // twips public static final String PARAGRAPH_JUSTIFICATION = PARAGRAPH + "justification"; public static final String PARAGRAPH_BORDER = PARAGRAPH + "border"; public static final String PARAGRAPH_BORDER_CELL = PARAGRAPH + "borderCell"; /** possible border settting */ public static final int PARAGRAPH_BORDER_NIL = 0; /** possible border settting */ public static final int PARAGRAPH_BORDER_BOTTOM = 1; /** possible border settting */ public static final int PARAGRAPH_BORDER_TOP = 2; /** possible border settting */ public static final int PARAGRAPH_BORDER_LEFT = 4; /** possible border settting */ public static final int PARAGRAPH_BORDER_RIGHT = 8; /** possible border settting */ public static final int PARAGRAPH_BORDER_DIAGONAL_UL_LR = 16; /** possible border settting */ public static final int PARAGRAPH_BORDER_DIAGONAL_UR_LL = 32; /** possible border settting */ public static final int PARAGRAPH_BORDER_TABLE_HORIZONTAL = 64; /** possible border settting */ public static final int PARAGRAPH_BORDER_TABLE_VERTICAL = 128; /* section properties */ /** Decimal number format */ public static final int PGN_DECIMAL = 0; /** Uppercase Roman Numeral */ public static final int PGN_ROMAN_NUMERAL_UPPERCASE = 1; /** Lowercase Roman Numeral */ public static final int PGN_ROMAN_NUMERAL_LOWERCASE = 2; /** Uppercase Letter */ public static final int PGN_LETTER_UPPERCASE = 3; /** Lowercase Letter */ public static final int PGN_LETTER_LOWERCASE = 4; /** Section Break None */ public static final int SBK_NONE = 0; /** Section Break Column break */ public static final int SBK_COLUMN = 1; /** Section Break Even page break */ public static final int SBK_EVEN = 2; /** Section Break Odd page break */ public static final int SBK_ODD = 3; /** Section Break Page break */ public static final int SBK_PAGE = 4; public static final String SECTION_NUMBER_OF_COLUMNS = SECTION + "numberOfColumns"; public static final String SECTION_BREAK_TYPE = SECTION + "SectionBreakType"; public static final String SECTION_PAGE_NUMBER_POSITION_X = SECTION + "pageNumberPositionX"; public static final String SECTION_PAGE_NUMBER_POSITION_Y = SECTION + "pageNumberPositionY"; public static final String SECTION_PAGE_NUMBER_FORMAT = SECTION + "pageNumberFormat"; /* document properties */ /** Portrait orientation */ public static final String PAGE_PORTRAIT = "0"; /** Landscape orientation */ public static final String PAGE_LANDSCAPE = "1"; public static final String DOCUMENT_PAGE_WIDTH_TWIPS = DOCUMENT + "pageWidthTwips"; public static final String DOCUMENT_PAGE_HEIGHT_TWIPS = DOCUMENT + "pageHeightTwips"; public static final String DOCUMENT_MARGIN_LEFT_TWIPS = DOCUMENT + "marginLeftTwips"; public static final String DOCUMENT_MARGIN_TOP_TWIPS = DOCUMENT + "marginTopTwips"; public static final String DOCUMENT_MARGIN_RIGHT_TWIPS = DOCUMENT + "marginRightTwips"; public static final String DOCUMENT_MARGIN_BOTTOM_TWIPS = DOCUMENT + "marginBottomTwips"; public static final String DOCUMENT_PAGE_NUMBER_START = DOCUMENT + "pageNumberStart"; public static final String DOCUMENT_ENABLE_FACING_PAGES = DOCUMENT + "enableFacingPages"; public static final String DOCUMENT_PAGE_ORIENTATION = DOCUMENT + "pageOrientation"; public static final String DOCUMENT_DEFAULT_FONT_NUMER = DOCUMENT + "defaultFontNumber"; /** Properties for this RtfProperty object */ protected HashMap properties = new HashMap(); private boolean modifiedCharacter = false; private boolean modifiedParagraph = false; private boolean modifiedSection = false; private boolean modifiedDocument = false; /** The RtfPropertyListener. */ private ArrayList listeners = new ArrayList(); /** * Set all property objects to default values. * @since 2.0.8 */ public void setToDefault() { setToDefault(COLOR); setToDefault(CHARACTER); setToDefault(PARAGRAPH); setToDefault(SECTION); setToDefault(DOCUMENT); } /** * Set individual property group to default values. * @param propertyGroup String name of the property group to set to default. * @since 2.0.8 */ public void setToDefault(String propertyGroup) { if(COLOR.equals(propertyGroup)) { setProperty(COLOR_FG, new Color(0,0,0)); setProperty(COLOR_BG, new Color(255,255,255)); return; } if(CHARACTER.equals(propertyGroup)) { setProperty(CHARACTER_BOLD, 0); setProperty(CHARACTER_UNDERLINE, 0); setProperty(CHARACTER_ITALIC, 0); setProperty(CHARACTER_SIZE, 24);// 1/2 pt sizes setProperty(CHARACTER_FONT, 0); return; } if(PARAGRAPH.equals(propertyGroup)) { setProperty(PARAGRAPH_INDENT_LEFT, 0); setProperty(PARAGRAPH_INDENT_RIGHT, 0); setProperty(PARAGRAPH_INDENT_FIRST_LINE, 0); setProperty(PARAGRAPH_JUSTIFICATION, JUSTIFY_LEFT); setProperty(PARAGRAPH_BORDER, PARAGRAPH_BORDER_NIL); setProperty(PARAGRAPH_BORDER_CELL, PARAGRAPH_BORDER_NIL); return; } if(SECTION.equals(propertyGroup)) { setProperty(SECTION_NUMBER_OF_COLUMNS, 0); setProperty(SECTION_BREAK_TYPE, SBK_NONE); setProperty(SECTION_PAGE_NUMBER_POSITION_X, 0); setProperty(SECTION_PAGE_NUMBER_POSITION_Y, 0); setProperty(SECTION_PAGE_NUMBER_FORMAT, PGN_DECIMAL); return; } if(DOCUMENT.equals(propertyGroup)) { setProperty(DOCUMENT_PAGE_WIDTH_TWIPS, 12240); setProperty(DOCUMENT_PAGE_HEIGHT_TWIPS, 15480); setProperty(DOCUMENT_MARGIN_LEFT_TWIPS, 1800); setProperty(DOCUMENT_MARGIN_TOP_TWIPS, 1440); setProperty(DOCUMENT_MARGIN_RIGHT_TWIPS, 1800); setProperty(DOCUMENT_MARGIN_BOTTOM_TWIPS, 1440); setProperty(DOCUMENT_PAGE_NUMBER_START, 1); setProperty(DOCUMENT_ENABLE_FACING_PAGES, 1); setProperty(DOCUMENT_PAGE_ORIENTATION, PAGE_PORTRAIT); setProperty(DOCUMENT_DEFAULT_FONT_NUMER, 0); return; } } /** * Toggle the value of the property identified by the RtfCtrlWordData.specialHandler parameter. * Toggle values are assumed to be integer values per the RTF spec with a value of 0=off or 1=on. * * @param ctrlWordData The property name to set * @return true for handled or false if propertyName is null or blank */ public boolean toggleProperty(RtfCtrlWordData ctrlWordData) { //String propertyName) { String propertyName = ctrlWordData.specialHandler; if(propertyName == null || propertyName.length() == 0) return false; Object propertyValue = getProperty(propertyName); if(propertyValue == null) { propertyValue = new Integer(RtfProperty.ON); } else { if(propertyValue instanceof Integer) { int value = ((Integer)propertyValue).intValue(); if(value != 0) { removeProperty(propertyName); } return true; } else { if(propertyValue instanceof Long) { long value = ((Long)propertyValue).intValue(); if(value != 0) { removeProperty(propertyName); } return true; } } } setProperty(propertyName, propertyValue); return true; } /** * Set the value of the property identified by the parameter. * * @param ctrlWordData The controlword with the name to set * @return true for handled or false if propertyName or propertyValue is null */ public boolean setProperty(RtfCtrlWordData ctrlWordData) { //String propertyName, Object propertyValueNew) { String propertyName = ctrlWordData.specialHandler; Object propertyValueNew = ctrlWordData.param; // depending on the control word, set mulitiple or reset settings, etc. //if pard then reset settings // setProperty(propertyName, propertyValueNew); return true; } /** * Set the value of the property identified by the parameter. * * @param propertyName The property name to set * @param propertyValueNew The object to set the property value to * @return true for handled or false if propertyName or propertyValue is null */ private boolean setProperty(String propertyName, Object propertyValueNew) { if(propertyName == null || propertyValueNew == null) return false; Object propertyValueOld = getProperty(propertyName); if(propertyValueOld instanceof Integer && propertyValueNew instanceof Integer) { int valueOld = ((Integer)propertyValueOld).intValue(); int valueNew = ((Integer)propertyValueNew).intValue(); if (valueOld==valueNew) return true; } else { if(propertyValueOld instanceof Long && propertyValueNew instanceof Long) { long valueOld = ((Long)propertyValueOld).intValue(); long valueNew = ((Long)propertyValueNew).intValue(); if (valueOld==valueNew) return true; } } beforeChange(propertyName); properties.put(propertyName, propertyValueNew); afterChange(propertyName); setModified(propertyName, true); return true; } /** * Set the value of the property identified by the parameter. * * @param propertyName The property name to set * @param propertyValueNew The object to set the property value to * @return true for handled or false if propertyName is null */ private boolean setProperty(String propertyName, int propertyValueNew) { if(propertyName == null) return false; Object propertyValueOld = getProperty(propertyName); if(propertyValueOld instanceof Integer) { int valueOld = ((Integer)propertyValueOld).intValue(); if (valueOld==propertyValueNew) return true; } beforeChange(propertyName); properties.put(propertyName, new Integer(propertyValueNew)); afterChange(propertyName); setModified(propertyName, true); return true; } /** * Add the value of the property identified by the parameter. * * @param propertyName The property name to set * @param propertyValue The object to set the property value to * @return true for handled or false if propertyName is null */ private boolean addToProperty(String propertyName, int propertyValue) { if(propertyName == null) return false; int value = ((Integer)properties.get(propertyName)).intValue(); if((value | propertyValue) == value) return true; value |= propertyValue; beforeChange(propertyName); properties.put(propertyName, new Integer(value)); afterChange(propertyName); setModified(propertyName, true); return true; } /** * Set the value of the property identified by the parameter. * * @param propertyName The property name to set * @param propertyValueNew The object to set the property value to * @return true for handled or false if propertyName is null */ private boolean setProperty(String propertyName, long propertyValueNew) { if(propertyName == null) return false; Object propertyValueOld = getProperty(propertyName); if(propertyValueOld instanceof Long) { long valueOld = ((Long)propertyValueOld).longValue(); if (valueOld==propertyValueNew) return true; } beforeChange(propertyName); properties.put(propertyName, new Long(propertyValueNew)); afterChange(propertyName); setModified(propertyName, true); return true; } /** * Add the value of the property identified by the parameter. * * @param propertyName The property name to set * @param propertyValue The object to set the property value to * @return true for handled or false if propertyName is null */ private boolean addToProperty(String propertyName, long propertyValue) { if(propertyName == null) return false; long value = ((Long)properties.get(propertyName)).longValue(); if((value | propertyValue) == value) return true; value |= propertyValue; beforeChange(propertyName); properties.put(propertyName, new Long(value)); afterChange(propertyName); setModified(propertyName, true); return true; } private boolean removeProperty(String propertyName) { if(propertyName == null) return false; if(properties.containsKey(propertyName)) { beforeChange(propertyName); properties.remove(propertyName); afterChange(propertyName); setModified(propertyName, true); } return true; } /** * Get the value of the property identified by the parameter. * * @param propertyName String containing the property name to get * @return Property Object requested or null if not found in map. */ public Object getProperty(String propertyName) { return properties.get(propertyName); } /** * Get a group of properties. * * @param propertyGroup The group name to obtain. * @return Properties object with requested values. */ public HashMap getProperties(String propertyGroup) { HashMap props = new HashMap(); if(!properties.isEmpty()) { //properties.get Iterator it = properties.keySet().iterator(); while(it.hasNext()) { String key = (String)it.next(); if(key.startsWith(propertyGroup)) { props.put(key, this.properties.get(key)); } } } return props; } /** * @return the modified */ public boolean isModified() { return modifiedCharacter || modifiedParagraph || modifiedSection || modifiedDocument; } /** * @param propertyName the propertyName that is modified * @param modified the modified to set */ public void setModified(String propertyName, boolean modified) { if(propertyName.startsWith(CHARACTER)) { this.setModifiedCharacter(modified); } else { if(propertyName.startsWith(PARAGRAPH)) { this.setModifiedParagraph(modified); } else { if(propertyName.startsWith(SECTION)) { this.setModifiedSection(modified); } else { if(propertyName.startsWith(DOCUMENT)) { this.setModifiedDocument(modified); } } } } } /** * @return the modifiedCharacter */ public boolean isModifiedCharacter() { return modifiedCharacter; } /** * @param modifiedCharacter the modifiedCharacter to set */ public void setModifiedCharacter(boolean modifiedCharacter) { this.modifiedCharacter = modifiedCharacter; } /** * @return the modifiedParagraph */ public boolean isModifiedParagraph() { return modifiedParagraph; } /** * @param modifiedParagraph the modifiedParagraph to set */ public void setModifiedParagraph(boolean modifiedParagraph) { this.modifiedParagraph = modifiedParagraph; } /** * @return the modifiedSection */ public boolean isModifiedSection() { return modifiedSection; } /** * @param modifiedSection the modifiedSection to set */ public void setModifiedSection(boolean modifiedSection) { this.modifiedSection = modifiedSection; } /** * @return the modifiedDocument */ public boolean isModifiedDocument() { return modifiedDocument; } /** * @param modifiedDocument the modifiedDocument to set */ public void setModifiedDocument(boolean modifiedDocument) { this.modifiedDocument = modifiedDocument; } /** * Adds a RtfPropertyListener to the RtfProperty. * * @param listener * the new RtfPropertyListener. */ public void addRtfPropertyListener(RtfPropertyListener listener) { listeners.add(listener); } /** * Removes a RtfPropertyListener from the RtfProperty. * * @param listener * the new RtfPropertyListener. */ public void removeRtfPropertyListener(RtfPropertyListener listener) { listeners.remove(listener); } public void beforeChange(String propertyName) { // call listener for all RtfPropertyListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfPropertyListener) iterator.next(); listener.beforePropertyChange(propertyName); } if(propertyName.startsWith(CHARACTER)) { // call listener for character chane } else { if(propertyName.startsWith(PARAGRAPH)) { // call listener for paragraph change } else { if(propertyName.startsWith(SECTION)) { // call listener for section change } else { if(propertyName.startsWith(DOCUMENT)) { // call listener for document change } } } } } public void afterChange(String propertyName) { // call listener for all RtfPropertyListener listener; for (Iterator iterator = listeners.iterator(); iterator.hasNext();) { listener = (RtfPropertyListener) iterator.next(); listener.afterPropertyChange(propertyName); } if(propertyName.startsWith(CHARACTER)) { // call listener for character chane } else { if(propertyName.startsWith(PARAGRAPH)) { // call listener for paragraph change } else { if(propertyName.startsWith(SECTION)) { // call listener for section change } else { if(propertyName.startsWith(DOCUMENT)) { // call listener for document change } } } } } } src/rtf/com/lowagie/text/rtf/parser/properties/RtfPropertyListener.java100644 0 0 5677 11012562273 24132 0ustar 0 0 /* * $Id: RtfPropertyListener.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.parser.properties; import java.util.EventListener; /** * RtfPropertyListener interface for handling events. * * @author Howard Shank (hgshank@yahoo.com) * * @since 2.0.8 */ public interface RtfPropertyListener extends EventListener { /** * */ public void beforePropertyChange(String propertyName); /** * */ public void afterPropertyChange(String propertyName); } src/rtf/com/lowagie/text/rtf/style/RtfColor.java100644 0 0 22036 11106243445 17333 0ustar 0 0 /* * $Id: RtfColor.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfColor stores one rtf color value for a rtf document * * @version $Id: RtfColor.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfColor extends RtfElement implements RtfExtendedElement { /** * Constant for RED value */ private static final byte[] COLOR_RED = DocWriter.getISOBytes("\\red"); /** * Constant for GREEN value */ private static final byte[] COLOR_GREEN = DocWriter.getISOBytes("\\green"); /** * Constant for BLUE value */ private static final byte[] COLOR_BLUE = DocWriter.getISOBytes("\\blue"); /** * Constant for the end of one color entry */ private static final byte COLON = (byte) ';'; /** * Constant for the number of the color in the list of colors */ private static final byte[] COLOR_NUMBER = DocWriter.getISOBytes("\\cf"); /** * The number of the color in the list of colors */ private int colorNumber = 0; /** * The red value */ private int red = 0; /** * The green value */ private int green = 0; /** * The blue value */ private int blue = 0; /** * Constructor only for use when initializing the RtfColorList * * @param doc The RtfDocument this RtfColor belongs to * @param red The red value to use * @param green The green value to use * @param blue The blue value to use * @param colorNumber The number of the color in the color list */ protected RtfColor(RtfDocument doc, int red, int green, int blue, int colorNumber) { super(doc); this.red = red; this.blue = blue; this.green = green; this.colorNumber = colorNumber; } /** * Constructs a RtfColor as a clone of an existing RtfColor * * @param doc The RtfDocument this RtfColor belongs to * @param col The RtfColor to use as a base */ public RtfColor(RtfDocument doc, RtfColor col) { super(doc); if(col != null) { this.red = col.getRed(); this.green = col.getGreen(); this.blue = col.getBlue(); } if(this.document != null) { this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); } } /** * Constructs a RtfColor based on the Color * * @param doc The RtfDocument this RtfColor belongs to * @param col The Color to base this RtfColor on */ public RtfColor(RtfDocument doc, Color col) { super(doc); if(col != null) { this.red = col.getRed(); this.blue = col.getBlue(); this.green = col.getGreen(); } if(this.document != null) { this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); } } /** * Constructs a RtfColor based on the red/green/blue values * * @param doc The RtfDocument this RtfColor belongs to * @param red The red value to use * @param green The green value to use * @param blue The blue value to use */ public RtfColor(RtfDocument doc, int red, int green, int blue) { super(doc); this.red = red; this.blue = blue; this.green = green; if(this.document != null) { this.colorNumber = this.document.getDocumentHeader().getColorNumber(this); } } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Write the definition part of this RtfColor. */ public void writeDefinition(final OutputStream result) throws IOException { result.write(COLOR_RED); result.write(intToByteArray(red)); result.write(COLOR_GREEN); result.write(intToByteArray(green)); result.write(COLOR_BLUE); result.write(intToByteArray(blue)); result.write(COLON); } /** * Writes the beginning of this RtfColor * */ public void writeBegin(final OutputStream result) { try { result.write(COLOR_NUMBER); result.write(intToByteArray(colorNumber)); } catch(IOException ioe) { ioe.printStackTrace(); } } /** * Unused * * @param result The OutputStream to which nothing will be written */ public void writeEnd(final OutputStream result) { } /** * Tests if this RtfColor is equal to another RtfColor. * * @param obj another RtfColor * @return True if red, green and blue values of the two colors match, * false otherwise. */ public boolean equals(Object obj) { if(!(obj instanceof RtfColor)) { return false; } RtfColor color = (RtfColor) obj; return (this.red == color.getRed() && this.green == color.getGreen() && this.blue == color.getBlue()); } /** * Returns the hash code of this RtfColor. The hash code is * an integer with the lowest three bytes containing the values * of red, green and blue. * * @return The hash code of this RtfColor */ public int hashCode() { return (this.red << 16) | (this.green << 8) | this.blue; } /** * Get the blue value of this RtfColor * * @return The blue value */ public int getBlue() { return blue; } /** * Get the green value of this RtfColor * * @return The green value */ public int getGreen() { return green; } /** * Get the red value of this RtfColor * * @return The red value */ public int getRed() { return red; } /** * Gets the number of this RtfColor in the list of colors * * @return Returns the colorNumber. */ public int getColorNumber() { return colorNumber; } /** * Sets the RtfDocument this RtfColor belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { super.setRtfDocument(doc); if(document != null) { this.colorNumber = document.getDocumentHeader().getColorNumber(this); } } } src/rtf/com/lowagie/text/rtf/style/RtfColorList.java100644 0 0 12100 11106243445 20156 0ustar 0 0 /* * $Id: RtfColorList.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfColorList stores all colors that appear in the document. Black * and White are always added * * @version $Id: RtfColorList.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfColorList extends RtfElement implements RtfExtendedElement { /** * Constant for the beginning of the color table */ private static final byte[] COLOR_TABLE = DocWriter.getISOBytes("\\colortbl"); /** * ArrayList containing all colors of this RtfColorList */ ArrayList colorList = new ArrayList(); /** * Constructs a new RtfColorList for the RtfDocument. Will add the default * black and white colors. * * @param doc The RtfDocument this RtfColorList belongs to */ public RtfColorList(RtfDocument doc) { super(doc); colorList.add(new RtfColor(doc, 0, 0, 0, 0)); colorList.add(new RtfColor(doc, 255, 255, 255, 1)); } /** * Returns the index of the given RtfColor in the color list. If the RtfColor * is not in the list of colors, then it is added. * * @param color The RtfColor for which to get the index * @return The index of the RtfColor */ public int getColorNumber(RtfColor color) { int colorIndex = -1; for(int i = 0; i < colorList.size(); i++) { if(colorList.get(i).equals(color)) { colorIndex = i; } } if(colorIndex == -1) { colorIndex = colorList.size(); colorList.add(color); } return colorIndex; } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Write the definition part of the color list. Calls the writeDefinition * methods of the RtfColors in the color list. */ public void writeDefinition(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(COLOR_TABLE); for(int i = 0; i < colorList.size(); i++) { RtfColor color = (RtfColor) colorList.get(i); color.writeDefinition(result); } result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/style/RtfFont.java100644 0 0 55731 11224572370 17176 0ustar 0 0 /* * $Id: RtfFont.java 4008 2009-07-07 09:56:52Z blowagie $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Font; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfFont class stores one font for an rtf document. It extends Font, * so can be set as a font, to allow adding of fonts with arbitrary names. * BaseFont fontname handling contributed by Craig Fleming. Various fixes * Renaud Michel, Werner Daehn. * * Version: $Id: RtfFont.java 4008 2009-07-07 09:56:52Z blowagie $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Craig Fleming (rythos@rhana.dhs.org) * @author Renaud Michel (r.michel@immedia.be) * @author Werner Daehn (Werner.Daehn@BusinessObjects.com) * @author Lidong Liu (tmslld@gmail.com) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfFont extends Font implements RtfExtendedElement { /** * Constant for the font family to use ("froman") */ private static final byte[] FONT_FAMILY = DocWriter.getISOBytes("\\froman"); /** * Constant for the charset */ private static final byte[] FONT_CHARSET = DocWriter.getISOBytes("\\fcharset"); /** * Constant for the font size */ public static final byte[] FONT_SIZE = DocWriter.getISOBytes("\\fs"); /** * Constant for the bold flag */ private static final byte[] FONT_BOLD = DocWriter.getISOBytes("\\b"); /** * Constant for the italic flag */ private static final byte[] FONT_ITALIC = DocWriter.getISOBytes("\\i"); /** * Constant for the underline flag */ private static final byte[] FONT_UNDERLINE = DocWriter.getISOBytes("\\ul"); /** * Constant for the strikethrough flag */ private static final byte[] FONT_STRIKETHROUGH = DocWriter.getISOBytes("\\strike"); /** * Constant for the double strikethrough flag */ private static final byte[] FONT_DOUBLE_STRIKETHROUGH = DocWriter.getISOBytes("\\striked"); /** * Constant for the shadow flag */ private static final byte[] FONT_SHADOW = DocWriter.getISOBytes("\\shad"); /** * Constant for the outline flag */ private static final byte[] FONT_OUTLINE = DocWriter.getISOBytes("\\outl"); /** * Constant for the embossed flag */ private static final byte[] FONT_EMBOSSED = DocWriter.getISOBytes("\\embo"); /** * Constant for the engraved flag */ private static final byte[] FONT_ENGRAVED = DocWriter.getISOBytes("\\impr"); /** * Constant for hidden text flag */ private static final byte[] FONT_HIDDEN = DocWriter.getISOBytes("\\v"); /** * Constant for a plain font */ public static final int STYLE_NONE = 0; /** * Constant for a bold font */ public static final int STYLE_BOLD = 1; /** * Constant for an italic font */ public static final int STYLE_ITALIC = 2; /** * Constant for an underlined font */ public static final int STYLE_UNDERLINE = 4; /** * Constant for a strikethrough font */ public static final int STYLE_STRIKETHROUGH = 8; /** * Constant for a double strikethrough font */ public static final int STYLE_DOUBLE_STRIKETHROUGH = 16; /** * Constant for a shadowed font */ public static final int STYLE_SHADOW = 32; /** * Constant for an outlined font */ public static final int STYLE_OUTLINE = 64; /** * Constant for an embossed font */ public static final int STYLE_EMBOSSED = 128; /** * Constant for an engraved font */ public static final int STYLE_ENGRAVED = 256; /** * Constant for a font that hides the actual text. */ public static final int STYLE_HIDDEN = 512; /** * Default font * @since 2.1.7 */ public static final String DEFAULT_FONT = "Times New Roman"; /** * The font name. Defaults to "Times New Roman" */ private String fontName = DEFAULT_FONT; /** * The font size. Defaults to 10 */ private int fontSize = 10; /** * The font style. Defaults to STYLE_NONE */ private int fontStyle = STYLE_NONE; /** * The number of this font */ private int fontNumber = 0; /** * The color of this font */ private RtfColor color = null; /** * The character set to use for this font */ private int charset = 0; /** * The RtfDocument this RtfFont belongs to. */ protected RtfDocument document = null; /** * Constructs a RtfFont with the given font name and all other properties * at their default values. * * @param fontName The font name to use */ public RtfFont(String fontName) { super(Font.UNDEFINED, Font.UNDEFINED, Font.UNDEFINED, null); this.fontName = fontName; } /** * Constructs a RtfFont with the given font name and font size and all other * properties at their default values. * * @param fontName The font name to use * @param size The font size to use */ public RtfFont(String fontName, float size) { super(Font.UNDEFINED, size, Font.UNDEFINED, null); this.fontName = fontName; } /** * Constructs a RtfFont with the given font name, font size and font style and the * default color. * * @param fontName The font name to use * @param size The font size to use * @param style The font style to use */ public RtfFont(String fontName, float size, int style) { super(Font.UNDEFINED, size, style, null); this.fontName = fontName; } /** * Constructs a RtfFont with the given font name, font size, font style and * color. * * @param fontName The font name to use * @param size the font size to use * @param style The font style to use * @param color The font color to use */ public RtfFont(String fontName, float size, int style, Color color) { super(Font.UNDEFINED, size, style, color); this.fontName = fontName; } /** * Constructs a RtfFont with the given font name, font size, font style, color * and charset. This can be used when generating non latin-1 text. * * @param fontName The font name to use * @param size the font size to use * @param style The font style to use * @param color The font color to use * @param charset The charset of the font content */ public RtfFont(String fontName, float size, int style, Color color, int charset) { this(fontName, size, style, color); this.charset = charset; } /** * Special constructor for the default font * * @param doc The RtfDocument this font appears in * @param fontNumber The id of this font */ protected RtfFont(RtfDocument doc, int fontNumber) { this.document = doc; this.fontNumber = fontNumber; color = new RtfColor(doc, 0, 0, 0); } /** * Constructs a RtfFont from a com.lowagie.text.Font * @param doc The RtfDocument this font appears in * @param font The Font to use as a base */ public RtfFont(RtfDocument doc, Font font) { this.document = doc; if(font != null) { if(font instanceof RtfFont) { this.fontName = ((RtfFont) font).getFontName(); this.charset = ((RtfFont) font).getCharset(); } else { setToDefaultFamily(font.getFamilyname()); } if(font.getBaseFont() != null) { String[][] fontNames = font.getBaseFont().getFullFontName(); for(int i = 0; i < fontNames.length; i++) { if(fontNames[i][2].equals("0")) { this.fontName = fontNames[i][3]; break; } else if(fontNames[i][2].equals("1033") || fontNames[i][2].equals("")) { this.fontName = fontNames[i][3]; } } } if(this.fontName.equalsIgnoreCase("unknown")) { this.fontName = DEFAULT_FONT; } setSize(font.getSize()); setStyle(font.getStyle()); setColor(font.getColor()); if(document != null) { this.fontNumber = document.getDocumentHeader().getFontNumber(this); } } if(document != null) { setRtfDocument(document); } } /** * Writes the font definition */ public void writeDefinition(final OutputStream result) throws IOException { result.write(FONT_FAMILY); result.write(FONT_CHARSET); result.write(intToByteArray(charset)); result.write(DELIMITER); document.filterSpecialChar(result, fontName, true, false); } /** * Writes the font beginning * * @param result The OutputStream to write to. * @throws IOException On i/o errors. */ public void writeBegin(final OutputStream result) throws IOException { if(this.fontNumber != Font.UNDEFINED) { result.write(RtfFontList.FONT_NUMBER); result.write(intToByteArray(fontNumber)); } if(this.fontSize != Font.UNDEFINED) { result.write(FONT_SIZE); result.write(intToByteArray(fontSize * 2)); } if(this.fontStyle != UNDEFINED) { if((fontStyle & STYLE_BOLD) == STYLE_BOLD) { result.write(FONT_BOLD); } if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) { result.write(FONT_ITALIC); } if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) { result.write(FONT_UNDERLINE); } if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) { result.write(FONT_STRIKETHROUGH); } if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) { result.write(FONT_HIDDEN); } if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) { result.write(FONT_DOUBLE_STRIKETHROUGH); result.write(intToByteArray(1)); } if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) { result.write(FONT_SHADOW); } if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) { result.write(FONT_OUTLINE); } if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) { result.write(FONT_EMBOSSED); } if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) { result.write(FONT_ENGRAVED); } } if(color != null) { color.writeBegin(result); } } /** * Write the font end * * @param result The OutputStream to write to. * @throws IOException On i/o errors. */ public void writeEnd(final OutputStream result) throws IOException{ if(this.fontStyle != UNDEFINED) { if((fontStyle & STYLE_BOLD) == STYLE_BOLD) { result.write(FONT_BOLD); result.write(intToByteArray(0)); } if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) { result.write(FONT_ITALIC); result.write(intToByteArray(0)); } if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) { result.write(FONT_UNDERLINE); result.write(intToByteArray(0)); } if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) { result.write(FONT_STRIKETHROUGH); result.write(intToByteArray(0)); } if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) { result.write(FONT_HIDDEN); result.write(intToByteArray(0)); } if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) { result.write(FONT_DOUBLE_STRIKETHROUGH); result.write(intToByteArray(0)); } if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) { result.write(FONT_SHADOW); result.write(intToByteArray(0)); } if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) { result.write(FONT_OUTLINE); result.write(intToByteArray(0)); } if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) { result.write(FONT_EMBOSSED); result.write(intToByteArray(0)); } if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) { result.write(FONT_ENGRAVED); result.write(intToByteArray(0)); } } } /** * unused */ public void writeContent(OutputStream out) throws IOException { } /** * Tests for equality of RtfFonts. RtfFonts are equal if their fontName, * fontSize, fontStyle and fontSuperSubscript are equal * * @param obj The RtfFont to compare with this RtfFont * @return True if the RtfFonts are equal, false otherwise */ public boolean equals(Object obj) { if(!(obj instanceof RtfFont)) { return false; } RtfFont font = (RtfFont) obj; boolean result = true; result = result & this.fontName.equals(font.getFontName()); return result; } /** * Returns the hash code of this RtfFont. The hash code is the hash code of the * string containing the font name + font size + "-" + the font style + "-" + the * font super/supscript value. * * @return The hash code of this RtfFont */ public int hashCode() { return (this.fontName + this.fontSize + "-" + this.fontStyle).hashCode(); } /** * Gets the font name of this RtfFont * * @return The font name */ public String getFontName() { return this.fontName; } /** * Sets the font name of this RtfFont. * * @param fontName The font name to use */ protected void setFontName(String fontName) { this.fontName = fontName; if(document != null) { this.fontNumber = document.getDocumentHeader().getFontNumber(this); } } /** * @see com.lowagie.text.Font#getFamilyname() */ public String getFamilyname() { return this.fontName; } /** * @see com.lowagie.text.Font#setFamily(String) */ public void setFamily(String family){ super.setFamily(family); setToDefaultFamily(family); } /** * Sets the correct font name from the family name. * * @param familyname The family name to set the name to. */ private void setToDefaultFamily(String familyname){ switch (Font.getFamilyIndex(familyname)) { case Font.COURIER: this.fontName = "Courier"; break; case Font.HELVETICA: this.fontName = "Arial"; break; case Font.SYMBOL: this.fontName = "Symbol"; this.charset = 2; break; case Font.TIMES_ROMAN: this.fontName = "Times New Roman"; break; case Font.ZAPFDINGBATS: this.fontName = "Windings"; break; default: this.fontName = familyname; } } /** * Gets the font size of this RtfFont * * @return The font size */ public int getFontSize() { return this.fontSize; } /** * @see com.lowagie.text.Font#setSize(float) */ public void setSize(float size){ super.setSize(size); this.fontSize = (int) getSize(); } /** * Gets the font style of this RtfFont * * @return The font style */ public int getFontStyle() { return this.fontStyle; } /** * @see com.lowagie.text.Font#setStyle(int) */ public void setStyle(int style){ super.setStyle(style); this.fontStyle = getStyle(); } /** * @see com.lowagie.text.Font#setStyle(String) */ public void setStyle(String style) { super.setStyle(style); fontStyle = getStyle(); } /** * Gets the charset used for constructing this RtfFont. * * @return The charset of this RtfFont. */ public int getCharset() { return charset; } /** * Sets the charset used for constructing this RtfFont. * * @param charset The charset to use. */ public void setCharset(int charset) { this.charset = charset; } /** * Gets the font number of this RtfFont * * @return The font number */ public int getFontNumber() { return fontNumber; } /** * Sets the RtfDocument this RtfFont belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; if(document != null) { this.fontNumber = document.getDocumentHeader().getFontNumber(this); } if(this.color != null) { this.color.setRtfDocument(this.document); } } /** * Unused * @param inTable */ public void setInTable(boolean inTable) { } /** * Unused * @param inHeader */ public void setInHeader(boolean inHeader) { } /** * @see com.lowagie.text.Font#setColor(Color) */ public void setColor(Color color) { super.setColor(color); if(color != null) { this.color = new RtfColor(document, color); } else { this.color = null; } } /** * @see com.lowagie.text.Font#setColor(int, int, int) */ public void setColor(int red, int green, int blue) { super.setColor(red,green,blue); this.color = new RtfColor(document, red, green, blue); } /** * Transforms an integer into its String representation and then returns the bytes * of that string. * * @param i The integer to convert * @return A byte array representing the integer */ protected byte[] intToByteArray(int i) { return DocWriter.getISOBytes(Integer.toString(i)); } /** * Replaces the attributes that are equal to null with * the attributes of a given font. * * @param font The surrounding font * @return A RtfFont */ public Font difference(Font font) { String dFamilyname = font.getFamilyname(); if(dFamilyname == null || dFamilyname.trim().equals("") || dFamilyname.trim().equalsIgnoreCase("unknown")) { dFamilyname = this.fontName; } float dSize = font.getSize(); if(dSize == Font.UNDEFINED) { dSize = this.getSize(); } int dStyle = Font.UNDEFINED; if(this.getStyle() != Font.UNDEFINED && font.getStyle() != Font.UNDEFINED) { dStyle = this.getStyle() | font.getStyle(); } else if(this.getStyle() != Font.UNDEFINED) { dStyle = this.getStyle(); } else if(font.getStyle() != Font.UNDEFINED) { dStyle = font.getStyle(); } Color dColor = font.getColor(); if(dColor == null) { dColor = this.getColor(); } int dCharset = this.charset; if(font instanceof RtfFont) { dCharset = ((RtfFont) font).getCharset(); } return new RtfFont(dFamilyname, dSize, dStyle, dColor, dCharset); } /** * The RtfFont is never a standard font. * * @since 2.1.0 */ public boolean isStandardFont() { return false; } /** * Compares this RtfFont to either a {@link com.lowagie.text.Font} or * an RtfFont. * * @since 2.1.0 */ public int compareTo(Object object) { if (object == null) { return -1; } if(object instanceof RtfFont) { if(this.getFontName().compareTo(((RtfFont) object).getFontName()) != 0) { return 1; } else { return super.compareTo(object); } } else if(object instanceof Font) { return super.compareTo(object); } else { return -3; } } } src/rtf/com/lowagie/text/rtf/style/RtfFontList.java100644 0 0 12566 11106243445 20026 0ustar 0 0 /* * $Id: RtfFontList.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfFontList stores the list of fonts used in the rtf document. It also * has methods for writing this list to the document * * Version: $Id: RtfFontList.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfFontList extends RtfElement implements RtfExtendedElement { /** * Constant for the default font */ private static final byte[] DEFAULT_FONT = DocWriter.getISOBytes("\\deff"); /** * Constant for the font table */ private static final byte[] FONT_TABLE = DocWriter.getISOBytes("\\fonttbl"); /** * Constant for the font number */ public static final byte[] FONT_NUMBER = DocWriter.getISOBytes("\\f"); /** * The list of fonts */ private ArrayList fontList = new ArrayList(); /** * Creates a RtfFontList * * @param doc The RtfDocument this RtfFontList belongs to */ public RtfFontList(RtfDocument doc) { super(doc); fontList.add(new RtfFont(document, 0)); } /** * unused */ public void writeContent(OutputStream out) throws IOException { } /** * Gets the index of the font in the list of fonts. If the font does not * exist in the list, it is added. * * @param font The font to get the id for * @return The index of the font */ public int getFontNumber(RtfFont font) { if(font instanceof RtfParagraphStyle) { font = new RtfFont(this.document, font); } int fontIndex = -1; for(int i = 0; i < fontList.size(); i++) { if(fontList.get(i).equals(font)) { fontIndex = i; } } if(fontIndex == -1) { fontIndex = fontList.size(); fontList.add(font); } return fontIndex; } /** * Writes the definition of the font list */ public void writeDefinition(final OutputStream result) throws IOException { result.write(DEFAULT_FONT); result.write(intToByteArray(0)); result.write(OPEN_GROUP); result.write(FONT_TABLE); for(int i = 0; i < fontList.size(); i++) { result.write(OPEN_GROUP); result.write(FONT_NUMBER); result.write(intToByteArray(i)); RtfFont rf = (RtfFont) fontList.get(i); rf.writeDefinition(result); result.write(COMMA_DELIMITER); result.write(CLOSE_GROUP); } result.write(CLOSE_GROUP); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/style/RtfParagraphStyle.java100644 0 0 62115 11106243445 21205 0ustar 0 0 /* * $Id: RtfParagraphStyle.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfParagraphStyle stores all style/formatting attributes of a RtfParagraph. * Additionally it also supports the style name system available in RTF. The RtfParagraphStyle * is a Font and can thus be used as such. To use the stylesheet functionality * it needs to be set as the font of a Paragraph. Otherwise it will work like a * RtfFont. It also supports inheritance of styles. * * @version $Id: RtfParagraphStyle.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfParagraphStyle extends RtfFont { /** * Constant for left alignment */ public static final byte[] ALIGN_LEFT = DocWriter.getISOBytes("\\ql"); /** * Constant for right alignment */ public static final byte[] ALIGN_RIGHT = DocWriter.getISOBytes("\\qr"); /** * Constant for center alignment */ public static final byte[] ALIGN_CENTER = DocWriter.getISOBytes("\\qc"); /** * Constant for justified alignment */ public static final byte[] ALIGN_JUSTIFY = DocWriter.getISOBytes("\\qj"); /** * Constant for the first line indentation */ public static final byte[] FIRST_LINE_INDENT = DocWriter.getISOBytes("\\fi"); /** * Constant for left indentation */ public static final byte[] INDENT_LEFT = DocWriter.getISOBytes("\\li"); /** * Constant for right indentation */ public static final byte[] INDENT_RIGHT = DocWriter.getISOBytes("\\ri"); /** * Constant for keeping the paragraph together on one page */ public static final byte[] KEEP_TOGETHER = DocWriter.getISOBytes("\\keep"); /** * Constant for keeping the paragraph together with the next one on one page */ public static final byte[] KEEP_TOGETHER_WITH_NEXT = DocWriter.getISOBytes("\\keepn"); /** * Constant for the space after the paragraph. */ public static final byte[] SPACING_AFTER = DocWriter.getISOBytes("\\sa"); /** * Constant for the space before the paragraph. */ public static final byte[] SPACING_BEFORE = DocWriter.getISOBytes("\\sb"); /** * The NORMAL/STANDARD style. */ public static final RtfParagraphStyle STYLE_NORMAL = new RtfParagraphStyle("Normal", "Arial", 12, Font.NORMAL, Color.black); /** * The style for level 1 headings. */ public static final RtfParagraphStyle STYLE_HEADING_1 = new RtfParagraphStyle("heading 1", "Normal"); /** * The style for level 2 headings. */ public static final RtfParagraphStyle STYLE_HEADING_2 = new RtfParagraphStyle("heading 2", "Normal"); /** * The style for level 3 headings. */ public static final RtfParagraphStyle STYLE_HEADING_3 = new RtfParagraphStyle("heading 3", "Normal"); /** * Initializes the properties of the styles. */ static { STYLE_HEADING_1.setSize(16); STYLE_HEADING_1.setStyle(Font.BOLD); STYLE_HEADING_2.setSize(14); STYLE_HEADING_2.setStyle(Font.BOLDITALIC); STYLE_HEADING_3.setSize(13); STYLE_HEADING_3.setStyle(Font.BOLD); } /** * No modification has taken place when compared to the RtfParagraphStyle this RtfParagraphStyle * is based on. These modification markers are used to determine what needs to be * inherited and what not from the parent RtfParagraphStyle. */ private static final int MODIFIED_NONE = 0; /** * The alignment has been modified. */ private static final int MODIFIED_ALIGNMENT = 1; /** * The left indentation has been modified. */ private static final int MODIFIED_INDENT_LEFT = 2; /** * The right indentation has been modified. */ private static final int MODIFIED_INDENT_RIGHT = 4; /** * The spacing before a paragraph has been modified. */ private static final int MODIFIED_SPACING_BEFORE = 8; /** * The spacing after a paragraph has been modified. */ private static final int MODIFIED_SPACING_AFTER = 16; /** * The font name has been modified. */ private static final int MODIFIED_FONT_NAME = 32; /** * The font style has been modified. */ private static final int MODIFIED_FONT_SIZE = 64; /** * The font size has been modified. */ private static final int MODIFIED_FONT_STYLE = 128; /** * The font color has been modified. */ private static final int MODIFIED_FONT_COLOR = 256; /** * The line leading has been modified. */ private static final int MODIFIED_LINE_LEADING = 512; /** * The paragraph keep together setting has been modified. */ private static final int MODIFIED_KEEP_TOGETHER = 1024; /** * The paragraph keep together with next setting has been modified. */ private static final int MODIFIED_KEEP_TOGETHER_WITH_NEXT = 2048; /** * The alignment of the paragraph. */ private int alignment = Element.ALIGN_LEFT; /** * The indentation for the first line */ private int firstLineIndent = 0; /** * The left indentation of the paragraph. */ private int indentLeft = 0; /** * The right indentation of the paragraph. */ private int indentRight = 0; /** * The spacing before a paragraph. */ private int spacingBefore = 0; /** * The spacing after a paragraph. */ private int spacingAfter = 0; /** * The line leading of the paragraph. */ private int lineLeading = 0; /** * Whether this RtfParagraph must stay on one page. */ private boolean keepTogether = false; /** * Whether this RtfParagraph must stay on the same page as the next paragraph. */ private boolean keepTogetherWithNext = false; /** * The name of this RtfParagraphStyle. */ private String styleName = ""; /** * The name of the RtfParagraphStyle this RtfParagraphStyle is based on. */ private String basedOnName = null; /** * The RtfParagraphStyle this RtfParagraphStyle is based on. */ private RtfParagraphStyle baseStyle = null; /** * Which properties have been modified when compared to the base style. */ private int modified = MODIFIED_NONE; /** * The number of this RtfParagraphStyle in the stylesheet list. */ private int styleNumber = -1; /** * Constructs a new RtfParagraphStyle with the given attributes. * * @param styleName The name of this RtfParagraphStyle. * @param fontName The name of the font to use for this RtfParagraphStyle. * @param fontSize The size of the font to use for this RtfParagraphStyle. * @param fontStyle The style of the font to use for this RtfParagraphStyle. * @param fontColor The color of the font to use for this RtfParagraphStyle. */ public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor) { super(null, new RtfFont(fontName, fontSize, fontStyle, fontColor)); this.styleName = styleName; } /** * Constructs a new RtfParagraphStyle that is based on an existing RtfParagraphStyle. * * @param styleName The name of this RtfParagraphStyle. * @param basedOnName The name of the RtfParagraphStyle this RtfParagraphStyle is based on. */ public RtfParagraphStyle(String styleName, String basedOnName) { super(null, new Font()); this.styleName = styleName; this.basedOnName = basedOnName; } /** * Constructs a RtfParagraphStyle from another RtfParagraphStyle. * * INTERNAL USE ONLY * * @param doc The RtfDocument this RtfParagraphStyle belongs to. * @param style The RtfParagraphStyle to copy settings from. */ public RtfParagraphStyle(RtfDocument doc, RtfParagraphStyle style) { super(doc, style); this.document = doc; this.styleName = style.getStyleName(); this.alignment = style.getAlignment(); this.firstLineIndent = (int)(style.getFirstLineIndent() * RtfBasicElement.TWIPS_FACTOR); this.indentLeft = (int) (style.getIndentLeft() * RtfBasicElement.TWIPS_FACTOR); this.indentRight = (int) (style.getIndentRight() * RtfBasicElement.TWIPS_FACTOR); this.spacingBefore = (int) (style.getSpacingBefore() * RtfBasicElement.TWIPS_FACTOR); this.spacingAfter = (int) (style.getSpacingAfter() * RtfBasicElement.TWIPS_FACTOR); this.lineLeading = (int) (style.getLineLeading() * RtfBasicElement.TWIPS_FACTOR); this.keepTogether = style.getKeepTogether(); this.keepTogetherWithNext = style.getKeepTogetherWithNext(); this.basedOnName = style.basedOnName; this.modified = style.modified; this.styleNumber = style.getStyleNumber(); if(this.document != null) { setRtfDocument(this.document); } } /** * Gets the name of this RtfParagraphStyle. * * @return The name of this RtfParagraphStyle. */ public String getStyleName() { return this.styleName; } /** * Gets the name of the RtfParagraphStyle this RtfParagraphStyle is based on. * * @return The name of the base RtfParagraphStyle. */ public String getBasedOnName() { return this.basedOnName; } /** * Gets the alignment of this RtfParagraphStyle. * * @return The alignment of this RtfParagraphStyle. */ public int getAlignment() { return this.alignment; } /** * Sets the alignment of this RtfParagraphStyle. * * @param alignment The alignment to use. */ public void setAlignment(int alignment) { this.modified = this.modified | MODIFIED_ALIGNMENT; this.alignment = alignment; } /** * Gets the first line indentation of this RtfParagraphStyle. * * @return The first line indentation of this RtfParagraphStyle. */ public int getFirstLineIndent() { return this.firstLineIndent; } /** * Sets the first line indentation of this RtfParagraphStyle. It * is relative to the left indentation. * * @param firstLineIndent The first line indentation to use. */ public void setFirstLineIndent(int firstLineIndent) { this.firstLineIndent = firstLineIndent; } /** * Gets the left indentation of this RtfParagraphStyle. * * @return The left indentation of this RtfParagraphStyle. */ public int getIndentLeft() { return this.indentLeft; } /** * Sets the left indentation of this RtfParagraphStyle. * * @param indentLeft The left indentation to use. */ public void setIndentLeft(int indentLeft) { this.modified = this.modified | MODIFIED_INDENT_LEFT; this.indentLeft = indentLeft; } /** * Gets the right indentation of this RtfParagraphStyle. * * @return The right indentation of this RtfParagraphStyle. */ public int getIndentRight() { return this.indentRight; } /** * Sets the right indentation of this RtfParagraphStyle. * * @param indentRight The right indentation to use. */ public void setIndentRight(int indentRight) { this.modified = this.modified | MODIFIED_INDENT_RIGHT; this.indentRight = indentRight; } /** * Gets the space before the paragraph of this RtfParagraphStyle.. * * @return The space before the paragraph. */ public int getSpacingBefore() { return this.spacingBefore; } /** * Sets the space before the paragraph of this RtfParagraphStyle. * * @param spacingBefore The space before to use. */ public void setSpacingBefore(int spacingBefore) { this.modified = this.modified | MODIFIED_SPACING_BEFORE; this.spacingBefore = spacingBefore; } /** * Gets the space after the paragraph of this RtfParagraphStyle. * * @return The space after the paragraph. */ public int getSpacingAfter() { return this.spacingAfter; } /** * Sets the space after the paragraph of this RtfParagraphStyle. * * @param spacingAfter The space after to use. */ public void setSpacingAfter(int spacingAfter) { this.modified = this.modified | MODIFIED_SPACING_AFTER; this.spacingAfter = spacingAfter; } /** * Sets the font name of this RtfParagraphStyle. * * @param fontName The font name to use */ public void setFontName(String fontName) { this.modified = this.modified | MODIFIED_FONT_NAME; super.setFontName(fontName); } /** * Sets the font size of this RtfParagraphStyle. * * @param fontSize The font size to use. */ public void setSize(float fontSize) { this.modified = this.modified | MODIFIED_FONT_SIZE; super.setSize(fontSize); } /** * Sets the font style of this RtfParagraphStyle. * * @param fontStyle The font style to use. */ public void setStyle(int fontStyle) { this.modified = this.modified | MODIFIED_FONT_STYLE; super.setStyle(fontStyle); } /** * Sets the color of this RtfParagraphStyle. * * @param color The Color to use. */ public void setColor(Color color) { this.modified = this.modified | MODIFIED_FONT_COLOR; super.setColor(color); } /** * Gets the line leading of this RtfParagraphStyle. * * @return The line leading of this RtfParagraphStyle. */ public int getLineLeading() { return this.lineLeading; } /** * Sets the line leading of this RtfParagraphStyle. * * @param lineLeading The line leading to use. */ public void setLineLeading(int lineLeading) { this.lineLeading = lineLeading; this.modified = this.modified | MODIFIED_LINE_LEADING; } /** * Gets whether the lines in the paragraph should be kept together in * this RtfParagraphStyle. * * @return Whether the lines in the paragraph should be kept together. */ public boolean getKeepTogether() { return this.keepTogether; } /** * Sets whether the lines in the paragraph should be kept together in * this RtfParagraphStyle. * * @param keepTogether Whether the lines in the paragraph should be kept together. */ public void setKeepTogether(boolean keepTogether) { this.keepTogether = keepTogether; this.modified = this.modified | MODIFIED_KEEP_TOGETHER; } /** * Gets whether the paragraph should be kept together with the next in * this RtfParagraphStyle. * * @return Whether the paragraph should be kept together with the next. */ public boolean getKeepTogetherWithNext() { return this.keepTogetherWithNext; } /** * Sets whether the paragraph should be kept together with the next in * this RtfParagraphStyle. * * @param keepTogetherWithNext Whether the paragraph should be kept together with the next. */ public void setKeepTogetherWithNext(boolean keepTogetherWithNext) { this.keepTogetherWithNext = keepTogetherWithNext; this.modified = this.modified | MODIFIED_KEEP_TOGETHER_WITH_NEXT; } /** * Handles the inheritance of paragraph style settings. All settings that * have not been modified will be inherited from the base RtfParagraphStyle. * If this RtfParagraphStyle is not based on another one, then nothing happens. */ public void handleInheritance() { if(this.basedOnName != null && this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName) != null) { this.baseStyle = this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName); this.baseStyle.handleInheritance(); if(!((this.modified & MODIFIED_ALIGNMENT) == MODIFIED_ALIGNMENT)) { this.alignment = this.baseStyle.getAlignment(); } if(!((this.modified & MODIFIED_INDENT_LEFT) == MODIFIED_INDENT_LEFT)) { this.indentLeft = this.baseStyle.getIndentLeft(); } if(!((this.modified & MODIFIED_INDENT_RIGHT) == MODIFIED_INDENT_RIGHT)) { this.indentRight = this.baseStyle.getIndentRight(); } if(!((this.modified & MODIFIED_SPACING_BEFORE) == MODIFIED_SPACING_BEFORE)) { this.spacingBefore = this.baseStyle.getSpacingBefore(); } if(!((this.modified & MODIFIED_SPACING_AFTER) == MODIFIED_SPACING_AFTER)) { this.spacingAfter = this.baseStyle.getSpacingAfter(); } if(!((this.modified & MODIFIED_FONT_NAME) == MODIFIED_FONT_NAME)) { setFontName(this.baseStyle.getFontName()); } if(!((this.modified & MODIFIED_FONT_SIZE) == MODIFIED_FONT_SIZE)) { setSize(this.baseStyle.getFontSize()); } if(!((this.modified & MODIFIED_FONT_STYLE) == MODIFIED_FONT_STYLE)) { setStyle(this.baseStyle.getFontStyle()); } if(!((this.modified & MODIFIED_FONT_COLOR) == MODIFIED_FONT_COLOR)) { setColor(this.baseStyle.getColor()); } if(!((this.modified & MODIFIED_LINE_LEADING) == MODIFIED_LINE_LEADING)) { setLineLeading(this.baseStyle.getLineLeading()); } if(!((this.modified & MODIFIED_KEEP_TOGETHER) == MODIFIED_KEEP_TOGETHER)) { setKeepTogether(this.baseStyle.getKeepTogether()); } if(!((this.modified & MODIFIED_KEEP_TOGETHER_WITH_NEXT) == MODIFIED_KEEP_TOGETHER_WITH_NEXT)) { setKeepTogetherWithNext(this.baseStyle.getKeepTogetherWithNext()); } } } /** * Writes the settings of this RtfParagraphStyle. * * @param result The OutputStream to write to. * @throws IOException On i/o errors. */ private void writeParagraphSettings(final OutputStream result) throws IOException { if(this.keepTogether) { result.write(RtfParagraphStyle.KEEP_TOGETHER); } if(this.keepTogetherWithNext) { result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT); } switch (alignment) { case Element.ALIGN_LEFT: result.write(RtfParagraphStyle.ALIGN_LEFT); break; case Element.ALIGN_RIGHT: result.write(RtfParagraphStyle.ALIGN_RIGHT); break; case Element.ALIGN_CENTER: result.write(RtfParagraphStyle.ALIGN_CENTER); break; case Element.ALIGN_JUSTIFIED: case Element.ALIGN_JUSTIFIED_ALL: result.write(RtfParagraphStyle.ALIGN_JUSTIFY); break; } result.write(FIRST_LINE_INDENT); result.write(intToByteArray(this.firstLineIndent)); result.write(RtfParagraphStyle.INDENT_LEFT); result.write(intToByteArray(indentLeft)); result.write(RtfParagraphStyle.INDENT_RIGHT); result.write(intToByteArray(indentRight)); if(this.spacingBefore > 0) { result.write(RtfParagraphStyle.SPACING_BEFORE); result.write(intToByteArray(this.spacingBefore)); } if(this.spacingAfter > 0) { result.write(RtfParagraphStyle.SPACING_AFTER); result.write(intToByteArray(this.spacingAfter)); } if(this.lineLeading > 0) { result.write(RtfParagraph.LINE_SPACING); result.write(intToByteArray(this.lineLeading)); } } /** * Writes the definition of this RtfParagraphStyle for the stylesheet list. */ public void writeDefinition(final OutputStream result) throws IOException { result.write(DocWriter.getISOBytes("{")); result.write(DocWriter.getISOBytes("\\style")); result.write(DocWriter.getISOBytes("\\s")); result.write(intToByteArray(this.styleNumber)); result.write(RtfBasicElement.DELIMITER); writeParagraphSettings(result); super.writeBegin(result); result.write(RtfBasicElement.DELIMITER); result.write(DocWriter.getISOBytes(this.styleName)); result.write(DocWriter.getISOBytes(";")); result.write(DocWriter.getISOBytes("}")); this.document.outputDebugLinebreak(result); } /** * Writes the start information of this RtfParagraphStyle. * * @param result The OutputStream to write to. * @throws IOException On i/o errors. */ public void writeBegin(final OutputStream result) throws IOException { result.write(DocWriter.getISOBytes("\\s")); result.write(intToByteArray(this.styleNumber)); writeParagraphSettings(result); } /** * Unused * * @param result The OutputStream that nothing is written to * @throws IOException On i/o errors. */ public void writeEnd(final OutputStream result) throws IOException { } /** * unused */ public void writeContent(final OutputStream out) throws IOException { } /** * Tests whether two RtfParagraphStyles are equal. Equality * is determined via the name. */ public boolean equals(Object o) { if(!(o instanceof RtfParagraphStyle)) { return false; } RtfParagraphStyle paragraphStyle = (RtfParagraphStyle) o; boolean result = this.getStyleName().equals(paragraphStyle.getStyleName()); return result; } /** * Gets the hash code of this RtfParagraphStyle. */ public int hashCode() { return this.styleName.hashCode(); } /** * Gets the number of this RtfParagraphStyle in the stylesheet list. * * @return The number of this RtfParagraphStyle in the stylesheet list. */ private int getStyleNumber() { return this.styleNumber; } /** * Sets the number of this RtfParagraphStyle in the stylesheet list. * * @param styleNumber The number to use. */ protected void setStyleNumber(int styleNumber) { this.styleNumber = styleNumber; } } src/rtf/com/lowagie/text/rtf/style/RtfStyleTypes.java100644 0 0 6252 11012562274 20364 0ustar 0 0 /* * $Id: RtfStyleTypes.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2007 by Howard Shank (hgshank@yahoo.com) * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; /** * RtfStyleTypes contains the different types of Stylesheet entries * that exist in RTF. * * @author Howard Shank (hgshank@yahoo.com) * @since 2.0.8 */ public final class RtfStyleTypes { /** * Indicates paragraph style. */ public final static int PARAGRAPH = 0; /** * Indicates character style. */ public final static int CHARACTER = 0; /** * Indicates section style. */ public final static int SECTION = 2; /** * Indicates Table style. */ public final static int TABLE = 3; /** * Indicates table definition style. */ public final static int TABLE_STYLE_DEFINITION = 4; } src/rtf/com/lowagie/text/rtf/style/RtfStylesheetList.java100644 0 0 14576 11106243445 21254 0ustar 0 0 /* * $Id: RtfStylesheetList.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.style; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Iterator; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfStylesheetList stores the RtfParagraphStyles that are used in the document. * * @version $Id: RtfStylesheetList.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfStylesheetList extends RtfElement implements RtfExtendedElement { /** * The HashMap containing the RtfParagraphStyles. */ private HashMap styleMap = null; /** * Whether the default settings have been loaded. */ private boolean defaultsLoaded = false; /** * Constructs a new RtfStylesheetList for the RtfDocument. * * @param doc The RtfDocument this RtfStylesheetList belongs to. */ public RtfStylesheetList(RtfDocument doc) { super(doc); this.styleMap = new HashMap(); } /** * unused */ public void writeContent(OutputStream out) throws IOException { } /** * Register a RtfParagraphStyle with this RtfStylesheetList. * * @param rtfParagraphStyle The RtfParagraphStyle to add. */ public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) { RtfParagraphStyle tempStyle = new RtfParagraphStyle(this.document, rtfParagraphStyle); tempStyle.handleInheritance(); tempStyle.setStyleNumber(this.styleMap.size()); this.styleMap.put(tempStyle.getStyleName(), tempStyle); } /** * Registers all default styles. If styles with the given name have already been registered, * then they are NOT overwritten. */ private void registerDefaultStyles() { defaultsLoaded = true; if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_NORMAL.getStyleName())) { registerParagraphStyle(RtfParagraphStyle.STYLE_NORMAL); } if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_1.getStyleName())) { registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_1); } if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_2.getStyleName())) { registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_2); } if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_3.getStyleName())) { registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_3); } } /** * Gets the RtfParagraphStyle with the given name. Makes sure that the defaults * have been loaded. * * @param styleName The name of the RtfParagraphStyle to get. * @return The RtfParagraphStyle with the given name or null. */ public RtfParagraphStyle getRtfParagraphStyle(String styleName) { if(!defaultsLoaded) { registerDefaultStyles(); } if(this.styleMap.containsKey(styleName)) { return (RtfParagraphStyle) this.styleMap.get(styleName); } else { return null; } } /** * Writes the definition of the stylesheet list. */ public void writeDefinition(final OutputStream result) throws IOException { result.write(DocWriter.getISOBytes("{")); result.write(DocWriter.getISOBytes("\\stylesheet")); result.write(RtfBasicElement.DELIMITER); this.document.outputDebugLinebreak(result); Iterator it = this.styleMap.values().iterator(); while(it.hasNext()) { RtfParagraphStyle rps = (RtfParagraphStyle)it.next(); rps.writeDefinition(result); } result.write(DocWriter.getISOBytes("}")); this.document.outputDebugLinebreak(result); } } src/rtf/com/lowagie/text/rtf/table/RtfBorder.java100644 0 0 47277 11106243445 17437 0ustar 0 0 /* * $Id: RtfBorder.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.table; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfColor; /** * The RtfBorder handle one row or cell border. * INTERNAL USE ONLY * * @version $Id: RtfBorder.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfBorder extends RtfElement { /** * Constant for the left row border */ protected static final byte[] ROW_BORDER_LEFT = DocWriter.getISOBytes("\\trbrdrl"); /** * Constant for the top row border */ protected static final byte[] ROW_BORDER_TOP = DocWriter.getISOBytes("\\trbrdrt"); /** * Constant for the right row border */ protected static final byte[] ROW_BORDER_RIGHT = DocWriter.getISOBytes("\\trbrdrr"); /** * Constant for the bottom row border */ protected static final byte[] ROW_BORDER_BOTTOM = DocWriter.getISOBytes("\\trbrdrb"); /** * Constant for the horizontal line */ protected static final byte[] ROW_BORDER_HORIZONTAL = DocWriter.getISOBytes("\\trbrdrh"); /** * Constant for the vertical line */ protected static final byte[] ROW_BORDER_VERTICAL = DocWriter.getISOBytes("\\trbrdrv"); /** * Constant for the left cell border */ protected static final byte[] CELL_BORDER_LEFT = DocWriter.getISOBytes("\\clbrdrl"); /** * Constant for the top cell border */ protected static final byte[] CELL_BORDER_TOP = DocWriter.getISOBytes("\\clbrdrt"); /** * Constant for the right cell border */ protected static final byte[] CELL_BORDER_RIGHT = DocWriter.getISOBytes("\\clbrdrr"); /** * Constant for the bottom cell border */ protected static final byte[] CELL_BORDER_BOTTOM = DocWriter.getISOBytes("\\clbrdrb"); /** * Constant for the border width */ protected static final byte[] BORDER_WIDTH = DocWriter.getISOBytes("\\brdrw"); /** * Constant for the border color number */ protected static final byte[] BORDER_COLOR_NUMBER = DocWriter.getISOBytes("\\brdrcf"); /** * Constant for the single border style */ protected static final byte[] BORDER_STYLE_SINGLE = DocWriter.getISOBytes("\\brdrs"); /** * Constant for the double thick border style */ protected static final byte[] BORDER_STYLE_DOUBLE_THICK = DocWriter.getISOBytes("\\brdrth"); /** * Constant for the shadowed border style */ protected static final byte[] BORDER_STYLE_SHADOWED = DocWriter.getISOBytes("\\brdrsh"); /** * Constant for the dotted border style */ protected static final byte[] BORDER_STYLE_DOTTED = DocWriter.getISOBytes("\\brdrdot"); /** * Constant for the dashed border style */ protected static final byte[] BORDER_STYLE_DASHED = DocWriter.getISOBytes("\\brdrdash"); /** * Constant for the hairline border style */ protected static final byte[] BORDER_STYLE_HAIRLINE = DocWriter.getISOBytes("\\brdrhair"); /** * Constant for the double border style */ protected static final byte[] BORDER_STYLE_DOUBLE = DocWriter.getISOBytes("\\brdrdb"); /** * Constant for the dot dash border style */ protected static final byte[] BORDER_STYLE_DOT_DASH = DocWriter.getISOBytes("\\brdrdashd"); /** * Constant for the dot dot dash border style */ protected static final byte[] BORDER_STYLE_DOT_DOT_DASH = DocWriter.getISOBytes("\\brdrdashdd"); /** * Constant for the triple border style */ protected static final byte[] BORDER_STYLE_TRIPLE = DocWriter.getISOBytes("\\brdrtriple"); /** * Constant for the thick thin border style */ protected static final byte[] BORDER_STYLE_THICK_THIN = DocWriter.getISOBytes("\\brdrtnthsg"); /** * Constant for the thin thick border style */ protected static final byte[] BORDER_STYLE_THIN_THICK = DocWriter.getISOBytes("\\brdrthtnsg"); /** * Constant for the thin thick thin border style */ protected static final byte[] BORDER_STYLE_THIN_THICK_THIN = DocWriter.getISOBytes("\\brdrtnthtnsg"); /** * Constant for the thick thin medium border style */ protected static final byte[] BORDER_STYLE_THICK_THIN_MED = DocWriter.getISOBytes("\\brdrtnthmg"); /** * Constant for the thin thick medium border style */ protected static final byte[] BORDER_STYLE_THIN_THICK_MED = DocWriter.getISOBytes("\\brdrthtnmg"); /** * Constant for the thin thick thin medium border style */ protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_MED = DocWriter.getISOBytes("\\brdrtnthtnmg"); /** * Constant for the thick thin large border style */ protected static final byte[] BORDER_STYLE_THICK_THIN_LARGE = DocWriter.getISOBytes("\\brdrtnthlg"); /** * Constant for the thin thick large border style */ protected static final byte[] BORDER_STYLE_THIN_THICK_LARGE = DocWriter.getISOBytes("\\brdrthtnlg"); /** * Constant for the thin thick thin large border style */ protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_LARGE = DocWriter.getISOBytes("\\brdrtnthtnlg"); /** * Constant for the wavy border style */ protected static final byte[] BORDER_STYLE_WAVY = DocWriter.getISOBytes("\\brdrwavy"); /** * Constant for the double wavy border style */ protected static final byte[] BORDER_STYLE_DOUBLE_WAVY = DocWriter.getISOBytes("\\brdrwavydb"); /** * Constant for the striped border style */ protected static final byte[] BORDER_STYLE_STRIPED = DocWriter.getISOBytes("\\brdrdashdotstr"); /** * Constant for the embossed border style */ protected static final byte[] BORDER_STYLE_EMBOSS = DocWriter.getISOBytes("\\brdremboss"); /** * Constant for the engraved border style */ protected static final byte[] BORDER_STYLE_ENGRAVE = DocWriter.getISOBytes("\\brdrengrave"); /** * Constant for a row border */ protected static final int ROW_BORDER = 1; /** * Constant for a cell border */ protected static final int CELL_BORDER = 2; /** * This border is no border :-) */ protected static final int NO_BORDER = 0; /** * Constant for a left border */ protected static final int LEFT_BORDER = 1; /** * Constant for a top border */ protected static final int TOP_BORDER = 2; /** * Constant for a right border */ protected static final int RIGHT_BORDER = 4; /** * Constant for a bottom border */ protected static final int BOTTOM_BORDER = 8; /** * Constant for a box (left, top, right, bottom) border */ protected static final int BOX_BORDER = 15; /** * Constant for a vertical line */ protected static final int VERTICAL_BORDER = 16; /** * Constant for a horizontal line */ protected static final int HORIZONTAL_BORDER = 32; /** * Constant for a border with no border */ public static final int BORDER_NONE = 0; /** * Constant for a single border */ public static final int BORDER_SINGLE = 1; /** * Constant for a double thick border */ public static final int BORDER_DOUBLE_THICK = 2; /** * Constant for a shadowed border */ public static final int BORDER_SHADOWED = 3; /** * Constant for a dotted border */ public static final int BORDER_DOTTED = 4; /** * Constant for a dashed border */ public static final int BORDER_DASHED = 5; /** * Constant for a hairline border */ public static final int BORDER_HAIRLINE = 6; /** * Constant for a double border */ public static final int BORDER_DOUBLE = 7; /** * Constant for a dot dash border */ public static final int BORDER_DOT_DASH = 8; /** * Constant for a dot dot dash border */ public static final int BORDER_DOT_DOT_DASH = 9; /** * Constant for a triple border */ public static final int BORDER_TRIPLE = 10; /** * Constant for a thick thin border */ public static final int BORDER_THICK_THIN = 11; /** * Constant for a thin thick border */ public static final int BORDER_THIN_THICK = 12; /** * Constant for a thin thick thin border */ public static final int BORDER_THIN_THICK_THIN = 13; /** * Constant for a thick thin medium border */ public static final int BORDER_THICK_THIN_MED = 14; /** * Constant for a thin thick medium border */ public static final int BORDER_THIN_THICK_MED = 15; /** * Constant for a thin thick thin medium border */ public static final int BORDER_THIN_THICK_THIN_MED = 16; /** * Constant for a thick thin large border */ public static final int BORDER_THICK_THIN_LARGE = 17; /** * Constant for a thin thick large border */ public static final int BORDER_THIN_THICK_LARGE = 18; /** * Constant for a thin thick thin large border */ public static final int BORDER_THIN_THICK_THIN_LARGE = 19; /** * Constant for a wavy border */ public static final int BORDER_WAVY = 20; /** * Constant for a double wavy border */ public static final int BORDER_DOUBLE_WAVY = 21; /** * Constant for a striped border */ public static final int BORDER_STRIPED = 22; /** * Constant for an embossed border */ public static final int BORDER_EMBOSS = 23; /** * Constant for an engraved border */ public static final int BORDER_ENGRAVE = 24; /** * The type of this RtfBorder */ private int borderType = ROW_BORDER; /** * The position of this RtfBorder */ private int borderPosition = NO_BORDER; /** * The style of this RtfBorder */ private int borderStyle = BORDER_NONE; /** * The width of this RtfBorder */ private int borderWidth = 20; /** * The color of this RtfBorder */ private RtfColor borderColor = null; /** * Makes a copy of the given RtfBorder * * @param doc The RtfDocument this RtfBorder belongs to * @param borderType The border type of this RtfBorder * @param border The RtfBorder to copy */ protected RtfBorder(RtfDocument doc, int borderType, RtfBorder border) { super(doc); this.borderType = borderType; this.borderPosition = border.getBorderPosition(); this.borderStyle = border.getBorderStyle(); this.borderWidth = border.getBorderWidth(); this.borderColor = new RtfColor(this.document, border.getBorderColor()); } /** * Constructs a RtfBorder * * @param doc The RtfDocument this RtfBorder belongs to * @param borderType The type of border this RtfBorder is * @param borderPosition The position of this RtfBorder * @param borderStyle The style of this RtfBorder * @param borderWidth The width of this RtfBorder * @param borderColor The color of this RtfBorder */ protected RtfBorder(RtfDocument doc, int borderType, int borderPosition, int borderStyle, float borderWidth, Color borderColor) { super(doc); this.borderType = borderType; this.borderPosition = borderPosition; this.borderStyle = borderStyle; this.borderWidth = (int) Math.min((borderWidth * TWIPS_FACTOR), 75); if(this.borderWidth == 0) { this.borderStyle = BORDER_NONE; } if(borderColor == null) { this.borderColor = new RtfColor(this.document, new Color(0, 0, 0)); } else { this.borderColor = new RtfColor(this.document, borderColor); } } /** * Writes the RtfBorder settings */ public void writeContent(final OutputStream result) throws IOException { if(this.borderStyle == BORDER_NONE || this.borderPosition == NO_BORDER || this.borderWidth == 0) { return; } if(this.borderType == ROW_BORDER) { switch(this.borderPosition) { case LEFT_BORDER: result.write(ROW_BORDER_LEFT); break; case TOP_BORDER: result.write(ROW_BORDER_TOP); break; case RIGHT_BORDER: result.write(ROW_BORDER_RIGHT); break; case BOTTOM_BORDER: result.write(ROW_BORDER_BOTTOM); break; case HORIZONTAL_BORDER: result.write(ROW_BORDER_HORIZONTAL); break; case VERTICAL_BORDER: result.write(ROW_BORDER_VERTICAL); break; default: return; } result.write(writeBorderStyle()); result.write(BORDER_WIDTH); result.write(intToByteArray(this.borderWidth)); result.write(BORDER_COLOR_NUMBER); result.write(intToByteArray(this.borderColor.getColorNumber())); this.document.outputDebugLinebreak(result); } else if(this.borderType == CELL_BORDER) { switch(this.borderPosition) { case LEFT_BORDER: result.write(CELL_BORDER_LEFT); break; case TOP_BORDER: result.write(CELL_BORDER_TOP); break; case RIGHT_BORDER: result.write(CELL_BORDER_RIGHT); break; case BOTTOM_BORDER: result.write(CELL_BORDER_BOTTOM); break; default: return; } result.write(writeBorderStyle()); result.write(BORDER_WIDTH); result.write(intToByteArray(this.borderWidth)); result.write(BORDER_COLOR_NUMBER); result.write(intToByteArray(this.borderColor.getColorNumber())); this.document.outputDebugLinebreak(result); } } /** * Writes the style of this RtfBorder * * @return A byte array containing the style of this RtfBorder */ private byte[] writeBorderStyle() { switch(this.borderStyle) { case BORDER_NONE : return new byte[0]; case BORDER_SINGLE : return BORDER_STYLE_SINGLE; case BORDER_DOUBLE_THICK : return BORDER_STYLE_DOUBLE_THICK; case BORDER_SHADOWED : return BORDER_STYLE_SHADOWED; case BORDER_DOTTED : return BORDER_STYLE_DOTTED; case BORDER_DASHED : return BORDER_STYLE_DASHED; case BORDER_HAIRLINE : return BORDER_STYLE_HAIRLINE; case BORDER_DOUBLE : return BORDER_STYLE_DOUBLE; case BORDER_DOT_DASH : return BORDER_STYLE_DOT_DASH; case BORDER_DOT_DOT_DASH : return BORDER_STYLE_DOT_DOT_DASH; case BORDER_TRIPLE : return BORDER_STYLE_TRIPLE; case BORDER_THICK_THIN : return BORDER_STYLE_THICK_THIN; case BORDER_THIN_THICK : return BORDER_STYLE_THIN_THICK; case BORDER_THIN_THICK_THIN : return BORDER_STYLE_THIN_THICK_THIN; case BORDER_THICK_THIN_MED : return BORDER_STYLE_THICK_THIN_MED; case BORDER_THIN_THICK_MED : return BORDER_STYLE_THIN_THICK_MED; case BORDER_THIN_THICK_THIN_MED : return BORDER_STYLE_THIN_THICK_THIN_MED; case BORDER_THICK_THIN_LARGE : return BORDER_STYLE_THICK_THIN_LARGE; case BORDER_THIN_THICK_LARGE : return BORDER_STYLE_THIN_THICK_LARGE; case BORDER_THIN_THICK_THIN_LARGE : return BORDER_STYLE_THIN_THICK_THIN_LARGE; case BORDER_WAVY : return BORDER_STYLE_WAVY; case BORDER_DOUBLE_WAVY : return BORDER_STYLE_DOUBLE_WAVY; case BORDER_STRIPED : return BORDER_STYLE_STRIPED; case BORDER_EMBOSS : return BORDER_STYLE_EMBOSS; case BORDER_ENGRAVE : return BORDER_STYLE_ENGRAVE; default : return BORDER_STYLE_SINGLE; } } /** * Gets the color of this RtfBorder * * @return Returns RtfColor of this RtfBorder */ protected RtfColor getBorderColor() { return borderColor; } /** * Gets the position of this RtfBorder * @return Returns the position of this RtfBorder */ protected int getBorderPosition() { return borderPosition; } /** * Gets the style of this RtfBorder * * @return Returns the style of this RtfBorder */ protected int getBorderStyle() { return borderStyle; } /** * Gets the type of this RtfBorder * * @return Returns the type of this RtfBorder */ protected int getBorderType() { return borderType; } /** * Gets the width of this RtfBorder * * @return Returns the width of this RtfBorder */ protected int getBorderWidth() { return borderWidth; } } src/rtf/com/lowagie/text/rtf/table/RtfBorderGroup.java100644 0 0 22356 11036112746 20444 0ustar 0 0 /* * $Id: RtfBorderGroup.java 3427 2008-05-24 18:32:31Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.table; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import com.lowagie.text.Rectangle; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfBorderGroup represents a collection of RtfBorders to use in a RtfCell * or RtfTable. * * @version $Id: RtfBorderGroup.java 3427 2008-05-24 18:32:31Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfBorderGroup extends RtfElement { /** * The type of borders this RtfBorderGroup contains. * RtfBorder.ROW_BORDER or RtfBorder.CELL_BORDER */ private int borderType = RtfBorder.ROW_BORDER; /** * The borders in this RtfBorderGroup */ private Hashtable borders = null; /** * Constructs an empty RtfBorderGroup. */ public RtfBorderGroup() { super(null); this.borders = new Hashtable(); } /** * Constructs a RtfBorderGroup with on border style for multiple borders. * * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) * @param borderStyle The style of border to add (from RtfBorder) * @param borderWidth The border width to use * @param borderColor The border color to use */ public RtfBorderGroup(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) { super(null); this.borders = new Hashtable(); addBorder(bordersToAdd, borderStyle, borderWidth, borderColor); } /** * Constructs a RtfBorderGroup based on another RtfBorderGroup. * * @param doc The RtfDocument this RtfBorderGroup belongs to * @param borderType The type of borders this RtfBorderGroup contains * @param borderGroup The RtfBorderGroup to use as a base */ protected RtfBorderGroup(RtfDocument doc, int borderType, RtfBorderGroup borderGroup) { super(doc); this.borders = new Hashtable(); this.borderType = borderType; if(borderGroup != null) { Iterator it = borderGroup.getBorders().entrySet().iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); this.borders.put(entry.getKey(), new RtfBorder(this.document, this.borderType, (RtfBorder) entry.getValue())); } } } /** * Constructs a RtfBorderGroup with certain borders * * @param doc The RtfDocument this RtfBorderGroup belongs to * @param borderType The type of borders this RtfBorderGroup contains * @param bordersToUse The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) * @param borderWidth The border width to use * @param borderColor The border color to use */ protected RtfBorderGroup(RtfDocument doc, int borderType, int bordersToUse, float borderWidth, Color borderColor) { super(doc); this.borderType = borderType; this.borders = new Hashtable(); addBorder(bordersToUse, RtfBorder.BORDER_SINGLE, borderWidth, borderColor); } /** * Sets a border in the Hashtable of borders * * @param borderPosition The position of this RtfBorder * @param borderStyle The type of borders this RtfBorderGroup contains * @param borderWidth The border width to use * @param borderColor The border color to use */ private void setBorder(int borderPosition, int borderStyle, float borderWidth, Color borderColor) { RtfBorder border = new RtfBorder(this.document, this.borderType, borderPosition, borderStyle, borderWidth, borderColor); this.borders.put(new Integer(borderPosition), border); } /** * Adds borders to the RtfBorderGroup * * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX) * @param borderStyle The style of border to add (from RtfBorder) * @param borderWidth The border width to use * @param borderColor The border color to use */ public void addBorder(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) { if((bordersToAdd & Rectangle.LEFT) == Rectangle.LEFT) { setBorder(RtfBorder.LEFT_BORDER, borderStyle, borderWidth, borderColor); } if((bordersToAdd & Rectangle.TOP) == Rectangle.TOP) { setBorder(RtfBorder.TOP_BORDER, borderStyle, borderWidth, borderColor); } if((bordersToAdd & Rectangle.RIGHT) == Rectangle.RIGHT) { setBorder(RtfBorder.RIGHT_BORDER, borderStyle, borderWidth, borderColor); } if((bordersToAdd & Rectangle.BOTTOM) == Rectangle.BOTTOM) { setBorder(RtfBorder.BOTTOM_BORDER, borderStyle, borderWidth, borderColor); } if((bordersToAdd & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) { setBorder(RtfBorder.VERTICAL_BORDER, borderStyle, borderWidth, borderColor); setBorder(RtfBorder.HORIZONTAL_BORDER, borderStyle, borderWidth, borderColor); } } /** * Removes borders from the list of borders * * @param bordersToRemove The borders to remove (from Rectangle) */ public void removeBorder(int bordersToRemove) { if((bordersToRemove & Rectangle.LEFT) == Rectangle.LEFT) { this.borders.remove(new Integer(RtfBorder.LEFT_BORDER)); } if((bordersToRemove & Rectangle.TOP) == Rectangle.TOP) { this.borders.remove(new Integer(RtfBorder.TOP_BORDER)); } if((bordersToRemove & Rectangle.RIGHT) == Rectangle.RIGHT) { this.borders.remove(new Integer(RtfBorder.RIGHT_BORDER)); } if((bordersToRemove & Rectangle.BOTTOM) == Rectangle.BOTTOM) { this.borders.remove(new Integer(RtfBorder.BOTTOM_BORDER)); } if((bordersToRemove & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) { this.borders.remove(new Integer(RtfBorder.VERTICAL_BORDER)); this.borders.remove(new Integer(RtfBorder.HORIZONTAL_BORDER)); } } /** * Writes the borders of this RtfBorderGroup */ public void writeContent(final OutputStream result) throws IOException { Iterator it = this.borders.values().iterator(); while(it.hasNext()) { ((RtfBorder) it.next()).writeContent(result); } } /** * Gets the RtfBorders of this RtfBorderGroup * * @return The RtfBorders of this RtfBorderGroup */ protected Hashtable getBorders() { return this.borders; } } src/rtf/com/lowagie/text/rtf/table/RtfCell.java100644 0 0 60677 11106243445 17100 0ustar 0 0 /* * $Id: RtfCell.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.table; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.BadElementException; import com.lowagie.text.Cell; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Image; import com.lowagie.text.List; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfExtendedElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfColor; import com.lowagie.text.rtf.style.RtfParagraphStyle; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfCell wraps a Cell, but can also be added directly to a Table. * The RtfCell is an extension of Cell, that supports a multitude of different * borderstyles. * * @version $Id: RtfCell.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen Stundzig * @author Benoit Wiart * @author Thomas Bickel (tmb99@inode.at) * @see com.lowagie.text.rtf.table.RtfBorder */ public class RtfCell extends Cell implements RtfExtendedElement { /** * This cell is not merged */ private static final int MERGE_NONE = 0; /** * This cell is the parent cell of a vertical merge operation */ private static final int MERGE_VERT_PARENT = 1; /** * This cell is a child cell of a vertical merge operation */ private static final int MERGE_VERT_CHILD = 2; /** * The parent RtfRow of this RtfCell */ private RtfRow parentRow = null; /** * The content of this RtfCell */ private ArrayList content = null; /** * The right margin of this RtfCell */ private int cellRight = 0; /** * The width of this RtfCell */ private int cellWidth = 0; /** * The borders of this RtfCell */ private RtfBorderGroup borders = null; /** * The background color of this RtfCell */ private RtfColor backgroundColor = null; /** * The padding of this RtfCell */ private int cellPadding = 0; /** * The merge type of this RtfCell */ private int mergeType = MERGE_NONE; /** * The RtfDocument this RtfCell belongs to */ private RtfDocument document = null; /** * Whether this RtfCell is in a header */ private boolean inHeader = false; /** * Whether this RtfCell is a placeholder for a removed table cell. */ private boolean deleted = false; /** * Whether to use generic padding or individual * padding values (cellPaddingLeft, cellPaddingTop, cellPaddingBottom, cellPaddingRight) */ private boolean usePadding = false; /* * Cell padding left */ private float cellPaddingLeft = 0; /* * Cell padding top */ private float cellPaddingTop = 0; /* * Cell padding bottom */ private float cellPaddingBottom = 0; /* * Cell padding right */ private float cellPaddingRight = 0; /** * Constructs an empty RtfCell */ public RtfCell() { super(); this.borders = new RtfBorderGroup(); verticalAlignment = ALIGN_MIDDLE; } /** * Constructs a RtfCell based upon a String * * @param content The String to base the RtfCell on */ public RtfCell(String content) { super(content); this.borders = new RtfBorderGroup(); verticalAlignment = ALIGN_MIDDLE; } /** * Constructs a RtfCell based upon an Element * * @param element The Element to base the RtfCell on * @throws BadElementException If the Element is not valid */ public RtfCell(Element element) throws BadElementException { super(element); this.borders = new RtfBorderGroup(); verticalAlignment = ALIGN_MIDDLE; } /** * Constructs a deleted RtfCell. * * @param deleted Whether this RtfCell is actually deleted. */ protected RtfCell(boolean deleted) { super(); this.deleted = deleted; verticalAlignment = ALIGN_MIDDLE; } /** * Constructs a RtfCell based on a Cell. * * @param doc The RtfDocument this RtfCell belongs to * @param row The RtfRow this RtfCell lies in * @param cell The Cell to base this RtfCell on */ protected RtfCell(RtfDocument doc, RtfRow row, Cell cell) { this.document = doc; this.parentRow = row; importCell(cell); } /** * Constructs a RtfCell based on a Cell. * * @param doc The RtfDocument this RtfCell belongs to * @param row The RtfRow this RtfCell lies in * @param cell The PdfPCell to base this RtfCell on * @since 2.1.3 */ protected RtfCell(RtfDocument doc, RtfRow row, PdfPCell cell) { this.document = doc; this.parentRow = row; importCell(cell); } /** * Imports the Cell properties into the RtfCell * * @param cell The Cell to import */ private void importCell(Cell cell) { this.content = new ArrayList(); if(cell == null) { this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, this.parentRow.getParentTable().getBorders()); return; } this.colspan = cell.getColspan(); this.rowspan = cell.getRowspan(); if(cell.getRowspan() > 1) { this.mergeType = MERGE_VERT_PARENT; } if(cell instanceof RtfCell) { this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, ((RtfCell) cell).getBorders()); } else { this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, cell.getBorder(), cell.getBorderWidth(), cell.getBorderColor()); } this.verticalAlignment = cell.getVerticalAlignment(); if(cell.getBackgroundColor() == null) { this.backgroundColor = new RtfColor(this.document, 255, 255, 255); } else { this.backgroundColor = new RtfColor(this.document, cell.getBackgroundColor()); } this.cellPadding = (int) this.parentRow.getParentTable().getCellPadding(); Iterator cellIterator = cell.getElements(); Paragraph container = null; while(cellIterator.hasNext()) { try { Element element = (Element) cellIterator.next(); // should we wrap it in a paragraph if(!(element instanceof Paragraph) && !(element instanceof List)) { if(container != null) { container.add(element); } else { container = new Paragraph(); container.setAlignment(cell.getHorizontalAlignment()); container.add(element); } } else { if(container != null) { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } container = null; } // if horizontal alignment is undefined overwrite // with that of enclosing cell if (element instanceof Paragraph && ((Paragraph) element).getAlignment() == Element.ALIGN_UNDEFINED) { ((Paragraph) element).setAlignment(cell.getHorizontalAlignment()); } RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(element); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } } catch(DocumentException de) { de.printStackTrace(); } } if(container != null) { try { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } catch(DocumentException de) { de.printStackTrace(); } } } /** * Imports the Cell properties into the RtfCell * * @param cell The PdfPCell to import * @since 2.1.3 */ private void importCell(PdfPCell cell) { this.content = new ArrayList(); if(cell == null) { this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, this.parentRow.getParentTable().getBorders()); return; } // padding this.cellPadding = (int) this.parentRow.getParentTable().getCellPadding(); this.cellPaddingBottom = cell.getPaddingBottom(); this.cellPaddingTop = cell.getPaddingTop(); this.cellPaddingRight = cell.getPaddingRight(); this.cellPaddingLeft = cell.getPaddingLeft(); // BORDERS this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, cell.getBorder(), cell.getBorderWidth(), cell.getBorderColor()); // border colors this.border = cell.getBorder(); this.borderColor = cell.getBorderColor(); this.borderColorBottom = cell.getBorderColorBottom(); this.borderColorTop = cell.getBorderColorTop(); this.borderColorLeft = cell.getBorderColorLeft(); this.borderColorRight = cell.getBorderColorRight(); // border widths this.borderWidth = cell.getBorderWidth(); this.borderWidthBottom = cell.getBorderWidthBottom(); this.borderWidthTop = cell.getBorderWidthTop(); this.borderWidthLeft = cell.getBorderWidthLeft(); this.borderWidthRight = cell.getBorderWidthRight(); this.colspan = cell.getColspan(); this.rowspan = 1; //cell.getRowspan(); // if(cell.getRowspan() > 1) { // this.mergeType = MERGE_VERT_PARENT; // } this.verticalAlignment = cell.getVerticalAlignment(); if(cell.getBackgroundColor() == null) { this.backgroundColor = new RtfColor(this.document, 255, 255, 255); } else { this.backgroundColor = new RtfColor(this.document, cell.getBackgroundColor()); } // does it have column composite info? java.util.List compositeElements = cell.getCompositeElements(); if(compositeElements != null) { Iterator cellIterator = compositeElements.iterator(); // does it have column info? Paragraph container = null; while(cellIterator.hasNext()) { try { Element element = (Element) cellIterator.next(); // should we wrap it in a paragraph if(!(element instanceof Paragraph) && !(element instanceof List)) { if(container != null) { container.add(element); } else { container = new Paragraph(); container.setAlignment(cell.getHorizontalAlignment()); container.add(element); } } else { if(container != null) { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } container = null; } // if horizontal alignment is undefined overwrite // with that of enclosing cell if (element instanceof Paragraph && ((Paragraph) element).getAlignment() == Element.ALIGN_UNDEFINED) { ((Paragraph) element).setAlignment(cell.getHorizontalAlignment()); } RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(element); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } } catch(DocumentException de) { de.printStackTrace(); } } if(container != null) { try { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container); for(int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } catch(DocumentException de) { de.printStackTrace(); } } } // does it have image info? Image img = cell.getImage(); if(img != null) { try { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(img); for (int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // does it have phrase info? Phrase phrase = cell.getPhrase(); if(phrase != null) { try { RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(phrase); for (int i = 0; i < rtfElements.length; i++) { rtfElements[i].setInTable(true); this.content.add(rtfElements[i]); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // does it have table info? PdfPTable table = cell.getTable(); if(table != null) { this.add(table); // try { // RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(table); // for (int i = 0; i < rtfElements.length; i++) { // rtfElements[i].setInTable(true); // this.content.add(rtfElements[i]); // } // } catch (DocumentException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } } /** * Write the cell definition part of this RtfCell */ public void writeDefinition(final OutputStream result) throws IOException { if(this.mergeType == MERGE_VERT_PARENT) { result.write(DocWriter.getISOBytes("\\clvmgf")); } else if(this.mergeType == MERGE_VERT_CHILD) { result.write(DocWriter.getISOBytes("\\clvmrg")); } switch (verticalAlignment) { case Element.ALIGN_BOTTOM: result.write(DocWriter.getISOBytes("\\clvertalb")); break; case Element.ALIGN_CENTER: case Element.ALIGN_MIDDLE: result.write(DocWriter.getISOBytes("\\clvertalc")); break; case Element.ALIGN_TOP: result.write(DocWriter.getISOBytes("\\clvertalt")); break; } this.borders.writeContent(result); if(this.backgroundColor != null) { result.write(DocWriter.getISOBytes("\\clcbpat")); result.write(intToByteArray(this.backgroundColor.getColorNumber())); } this.document.outputDebugLinebreak(result); result.write(DocWriter.getISOBytes("\\clftsWidth3")); this.document.outputDebugLinebreak(result); result.write(DocWriter.getISOBytes("\\clwWidth")); result.write(intToByteArray(this.cellWidth)); this.document.outputDebugLinebreak(result); if(this.cellPadding > 0) { result.write(DocWriter.getISOBytes("\\clpadl")); result.write(intToByteArray(this.cellPadding / 2)); result.write(DocWriter.getISOBytes("\\clpadt")); result.write(intToByteArray(this.cellPadding / 2)); result.write(DocWriter.getISOBytes("\\clpadr")); result.write(intToByteArray(this.cellPadding / 2)); result.write(DocWriter.getISOBytes("\\clpadb")); result.write(intToByteArray(this.cellPadding / 2)); result.write(DocWriter.getISOBytes("\\clpadfl3")); result.write(DocWriter.getISOBytes("\\clpadft3")); result.write(DocWriter.getISOBytes("\\clpadfr3")); result.write(DocWriter.getISOBytes("\\clpadfb3")); } result.write(DocWriter.getISOBytes("\\cellx")); result.write(intToByteArray(this.cellRight)); } /** * Write the content of this RtfCell */ public void writeContent(final OutputStream result) throws IOException { if(this.content.size() == 0) { result.write(RtfParagraph.PARAGRAPH_DEFAULTS); if(this.parentRow.getParentTable().getTableFitToPage()) { result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT); } result.write(RtfParagraph.IN_TABLE); } else { for(int i = 0; i < this.content.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement) this.content.get(i); if(rtfElement instanceof RtfParagraph) { ((RtfParagraph) rtfElement).setKeepTogetherWithNext(this.parentRow.getParentTable().getTableFitToPage()); } rtfElement.writeContent(result); if(rtfElement instanceof RtfParagraph && i < (this.content.size() - 1)) { result.write(RtfParagraph.PARAGRAPH); } } } result.write(DocWriter.getISOBytes("\\cell")); } /** * Sets the right margin of this cell. Used in merge operations * * @param cellRight The right margin to use */ protected void setCellRight(int cellRight) { this.cellRight = cellRight; } /** * Gets the right margin of this RtfCell * * @return The right margin of this RtfCell. */ protected int getCellRight() { return this.cellRight; } /** * Sets the cell width of this RtfCell. Used in merge operations. * * @param cellWidth The cell width to use */ protected void setCellWidth(int cellWidth) { this.cellWidth = cellWidth; } /** * Gets the cell width of this RtfCell * * @return The cell width of this RtfCell */ protected int getCellWidth() { return this.cellWidth; } /** * Gets the cell padding of this RtfCell * * @return The cell padding of this RtfCell */ protected int getCellpadding() { return this.cellPadding; } /** * Gets the borders of this RtfCell * * @return The borders of this RtfCell */ protected RtfBorderGroup getBorders() { return this.borders; } /** * Set the borders of this RtfCell * * @param borderGroup The RtfBorderGroup to use as borders */ public void setBorders(RtfBorderGroup borderGroup) { this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, borderGroup); } /** * Get the background color of this RtfCell * * @return The background color of this RtfCell */ protected RtfColor getRtfBackgroundColor() { return this.backgroundColor; } /** * Merge this cell into the parent cell. * * @param mergeParent The RtfCell to merge with */ protected void setCellMergeChild(RtfCell mergeParent) { this.mergeType = MERGE_VERT_CHILD; this.cellWidth = mergeParent.getCellWidth(); this.cellRight = mergeParent.getCellRight(); this.cellPadding = mergeParent.getCellpadding(); this.borders = mergeParent.getBorders(); this.verticalAlignment = mergeParent.getVerticalAlignment(); this.backgroundColor = mergeParent.getRtfBackgroundColor(); } /** * Sets the RtfDocument this RtfCell belongs to * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { this.document = doc; } /** * Unused * @param inTable */ public void setInTable(boolean inTable) { } /** * Sets whether this RtfCell is in a header * * @param inHeader True if this RtfCell is in a header, false otherwise */ public void setInHeader(boolean inHeader) { this.inHeader = inHeader; for(int i = 0; i < this.content.size(); i++) { ((RtfBasicElement) this.content.get(i)).setInHeader(inHeader); } } /** * Gets whether this RtfCell is in a header * * @return True if this RtfCell is in a header, false otherwise * @since 2.1.0 */ public boolean isInHeader() { return this.inHeader; } /** * Transforms an integer into its String representation and then returns the bytes * of that string. * * @param i The integer to convert * @return A byte array representing the integer */ private byte[] intToByteArray(int i) { return DocWriter.getISOBytes(Integer.toString(i)); } /** * Checks whether this RtfCell is a placeholder for * a table cell that has been removed due to col/row spanning. * * @return True if this RtfCell is deleted, false otherwise. */ public boolean isDeleted() { return this.deleted; } } src/rtf/com/lowagie/text/rtf/table/RtfRow.java100644 0 0 37530 11154165267 16770 0ustar 0 0 /* * $Id: RtfRow.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.table; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.Cell; import com.lowagie.text.DocWriter; import com.lowagie.text.Element; import com.lowagie.text.Row; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPRow; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfRow wraps one Row for a RtfTable. * INTERNAL USE ONLY * * @version $Id: RtfRow.java 3735 2009-02-26 01:44:03Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen Stundzig * @author Lorenz Maierhofer * @author Thomas Bickel (tmb99@inode.at) */ public class RtfRow extends RtfElement { /** * Constant for the RtfRow beginning */ private static final byte[] ROW_BEGIN = DocWriter.getISOBytes("\\trowd"); /** * Constant for the RtfRow width style */ private static final byte[] ROW_WIDTH_STYLE = DocWriter.getISOBytes("\\trftsWidth3"); /** * Constant for the RtfRow width */ private static final byte[] ROW_WIDTH = DocWriter.getISOBytes("\\trwWidth"); /** * Constant to specify that this RtfRow are not to be broken across pages */ private static final byte[] ROW_KEEP_TOGETHER = DocWriter.getISOBytes("\\trkeep"); /** * Constant to specify that this is a header RtfRow */ private static final byte[] ROW_HEADER_ROW = DocWriter.getISOBytes("\\trhdr"); /** * Constant for left alignment of this RtfRow */ private static final byte[] ROW_ALIGN_LEFT = DocWriter.getISOBytes("\\trql"); /** * Constant for right alignment of this RtfRow */ private static final byte[] ROW_ALIGN_RIGHT = DocWriter.getISOBytes("\\trqr"); /** * Constant for center alignment of this RtfRow */ private static final byte[] ROW_ALIGN_CENTER = DocWriter.getISOBytes("\\trqc"); /** * Constant for justified alignment of this RtfRow */ private static final byte[] ROW_ALIGN_JUSTIFIED = DocWriter.getISOBytes("\\trqj"); /** * Constant for the graph style of this RtfRow */ private static final byte[] ROW_GRAPH = DocWriter.getISOBytes("\\trgaph10"); /** * Constant for the cell left spacing */ private static final byte[] ROW_CELL_SPACING_LEFT = DocWriter.getISOBytes("\\trspdl"); /** * Constant for the cell top spacing */ private static final byte[] ROW_CELL_SPACING_TOP = DocWriter.getISOBytes("\\trspdt"); /** * Constant for the cell right spacing */ private static final byte[] ROW_CELL_SPACING_RIGHT = DocWriter.getISOBytes("\\trspdr"); /** * Constant for the cell bottom spacing */ private static final byte[] ROW_CELL_SPACING_BOTTOM = DocWriter.getISOBytes("\\trspdb"); /** * Constant for the cell left spacing style */ private static final byte[] ROW_CELL_SPACING_LEFT_STYLE = DocWriter.getISOBytes("\\trspdfl3"); /** * Constant for the cell top spacing style */ private static final byte[] ROW_CELL_SPACING_TOP_STYLE = DocWriter.getISOBytes("\\trspdft3"); /** * Constant for the cell right spacing style */ private static final byte[] ROW_CELL_SPACING_RIGHT_STYLE = DocWriter.getISOBytes("\\trspdfr3"); /** * Constant for the cell bottom spacing style */ private static final byte[] ROW_CELL_SPACING_BOTTOM_STYLE = DocWriter.getISOBytes("\\trspdfb3"); /** * Constant for the cell left padding */ private static final byte[] ROW_CELL_PADDING_LEFT = DocWriter.getISOBytes("\\trpaddl"); /** * Constant for the cell right padding */ private static final byte[] ROW_CELL_PADDING_RIGHT = DocWriter.getISOBytes("\\trpaddr"); /** * Constant for the cell left padding style */ private static final byte[] ROW_CELL_PADDING_LEFT_STYLE = DocWriter.getISOBytes("\\trpaddfl3"); /** * Constant for the cell right padding style */ private static final byte[] ROW_CELL_PADDING_RIGHT_STYLE = DocWriter.getISOBytes("\\trpaddfr3"); /** * Constant for the end of a row */ private static final byte[] ROW_END = DocWriter.getISOBytes("\\row"); /** * The RtfTable this RtfRow belongs to */ private RtfTable parentTable = null; /** * The cells of this RtfRow */ private ArrayList cells = null; /** * The width of this row */ private int width = 0; /** * The row number */ private int rowNumber = 0; /** * Constructs a RtfRow for a Row. * * @param doc The RtfDocument this RtfRow belongs to * @param rtfTable The RtfTable this RtfRow belongs to * @param row The Row this RtfRow is based on * @param rowNumber The number of this row */ protected RtfRow(RtfDocument doc, RtfTable rtfTable, Row row, int rowNumber) { super(doc); this.parentTable = rtfTable; this.rowNumber = rowNumber; importRow(row); } /** * Constructs a RtfRow for a Row. * * @param doc The RtfDocument this RtfRow belongs to * @param rtfTable The RtfTable this RtfRow belongs to * @param row The Row this RtfRow is based on * @param rowNumber The number of this row * @since 2.1.3 */ protected RtfRow(RtfDocument doc, RtfTable rtfTable, PdfPRow row, int rowNumber) { super(doc); this.parentTable = rtfTable; this.rowNumber = rowNumber; importRow(row); } /** * Imports a Row and copies all settings * * @param row The Row to import */ private void importRow(Row row) { this.cells = new ArrayList(); this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight(); this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100); int cellRight = 0; int cellWidth = 0; for(int i = 0; i < row.getColumns(); i++) { cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100); cellRight = cellRight + cellWidth; Cell cell = (Cell) row.getCell(i); RtfCell rtfCell = new RtfCell(this.document, this, cell); rtfCell.setCellRight(cellRight); rtfCell.setCellWidth(cellWidth); this.cells.add(rtfCell); } } /** * Imports a PdfPRow and copies all settings * * @param row The PdfPRow to import * @since 2.1.3 */ private void importRow(PdfPRow row) { this.cells = new ArrayList(); this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight(); this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100); int cellRight = 0; int cellWidth = 0; PdfPCell[] cells = row.getCells(); for(int i = 0; i < cells.length; i++) { cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100); cellRight = cellRight + cellWidth; PdfPCell cell = cells[i]; RtfCell rtfCell = new RtfCell(this.document, this, cell); rtfCell.setCellRight(cellRight); rtfCell.setCellWidth(cellWidth); this.cells.add(rtfCell); } } /** * Performs a second pass over all cells to handle cell row/column spanning. */ protected void handleCellSpanning() { RtfCell deletedCell = new RtfCell(true); for(int i = 0; i < this.cells.size(); i++) { RtfCell rtfCell = (RtfCell) this.cells.get(i); if(rtfCell.getColspan() > 1) { int cSpan = rtfCell.getColspan(); for(int j = i + 1; j < i + cSpan; j++) { if(j < this.cells.size()) { RtfCell rtfCellMerge = (RtfCell) this.cells.get(j); rtfCell.setCellRight(rtfCell.getCellRight() + rtfCellMerge.getCellWidth()); rtfCell.setCellWidth(rtfCell.getCellWidth() + rtfCellMerge.getCellWidth()); this.cells.set(j, deletedCell); } } } if(rtfCell.getRowspan() > 1) { ArrayList rows = this.parentTable.getRows(); for(int j = 1; j < rtfCell.getRowspan(); j++) { RtfRow mergeRow = (RtfRow) rows.get(this.rowNumber + j); if(this.rowNumber + j < rows.size()) { RtfCell rtfCellMerge = (RtfCell) mergeRow.getCells().get(i); rtfCellMerge.setCellMergeChild(rtfCell); } if(rtfCell.getColspan() > 1) { int cSpan = rtfCell.getColspan(); for(int k = i + 1; k < i + cSpan; k++) { if(k < mergeRow.getCells().size()) { mergeRow.getCells().set(k, deletedCell); } } } } } } } /** * Cleans the deleted RtfCells from the total RtfCells. */ protected void cleanRow() { int i = 0; while(i < this.cells.size()) { if(((RtfCell) this.cells.get(i)).isDeleted()) { this.cells.remove(i); } else { i++; } } } /** * Writes the row definition/settings. * * @param result The OutputStream to write the definitions to. */ private void writeRowDefinition(final OutputStream result) throws IOException { result.write(ROW_BEGIN); this.document.outputDebugLinebreak(result); result.write(ROW_WIDTH_STYLE); result.write(ROW_WIDTH); result.write(intToByteArray(this.width)); if(this.parentTable.getCellsFitToPage()) { result.write(ROW_KEEP_TOGETHER); } if(this.rowNumber <= this.parentTable.getHeaderRows()) { result.write(ROW_HEADER_ROW); } switch (this.parentTable.getAlignment()) { case Element.ALIGN_LEFT: result.write(ROW_ALIGN_LEFT); break; case Element.ALIGN_RIGHT: result.write(ROW_ALIGN_RIGHT); break; case Element.ALIGN_CENTER: result.write(ROW_ALIGN_CENTER); break; case Element.ALIGN_JUSTIFIED: case Element.ALIGN_JUSTIFIED_ALL: result.write(ROW_ALIGN_JUSTIFIED); break; } result.write(ROW_GRAPH); RtfBorderGroup borders =this.parentTable.getBorders(); if(borders != null) { borders.writeContent(result); } if(this.parentTable.getCellSpacing() > 0) { result.write(ROW_CELL_SPACING_LEFT); result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); result.write(ROW_CELL_SPACING_LEFT_STYLE); result.write(ROW_CELL_SPACING_TOP); result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); result.write(ROW_CELL_SPACING_TOP_STYLE); result.write(ROW_CELL_SPACING_RIGHT); result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); result.write(ROW_CELL_SPACING_RIGHT_STYLE); result.write(ROW_CELL_SPACING_BOTTOM); result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2))); result.write(ROW_CELL_SPACING_BOTTOM_STYLE); } result.write(ROW_CELL_PADDING_LEFT); result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); result.write(ROW_CELL_PADDING_RIGHT); result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2))); result.write(ROW_CELL_PADDING_LEFT_STYLE); result.write(ROW_CELL_PADDING_RIGHT_STYLE); this.document.outputDebugLinebreak(result); for(int i = 0; i < this.cells.size(); i++) { RtfCell rtfCell = (RtfCell) this.cells.get(i); rtfCell.writeDefinition(result); } } /** * Writes the content of this RtfRow */ public void writeContent(final OutputStream result) throws IOException { writeRowDefinition(result); for(int i = 0; i < this.cells.size(); i++) { RtfCell rtfCell = (RtfCell) this.cells.get(i); rtfCell.writeContent(result); } result.write(DELIMITER); if(this.document.getDocumentSettings().isOutputTableRowDefinitionAfter()) { writeRowDefinition(result); } result.write(ROW_END); this.document.outputDebugLinebreak(result); } /** * Gets the parent RtfTable of this RtfRow * * @return The parent RtfTable of this RtfRow */ protected RtfTable getParentTable() { return this.parentTable; } /** * Gets the cells of this RtfRow * * @return The cells of this RtfRow */ protected ArrayList getCells() { return this.cells; } } src/rtf/com/lowagie/text/rtf/table/RtfTable.java100644 0 0 26357 11036112746 17246 0ustar 0 0 /* * $Id: RtfTable.java 3533 2008-07-07 21:27:13Z Howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.table; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Element; import com.lowagie.text.Row; import com.lowagie.text.Table; import com.lowagie.text.pdf.PdfPRow; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfFont; import com.lowagie.text.rtf.text.RtfParagraph; /** * The RtfTable wraps a Table. * INTERNAL USE ONLY * * @version $Id: RtfTable.java 3533 2008-07-07 21:27:13Z Howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Steffen Stundzig * @author Benoit Wiart * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTable extends RtfElement { /** * The rows of this RtfTable */ private ArrayList rows = null; /** * The percentage of the page width that this RtfTable covers */ private float tableWidthPercent = 80; /** * An array with the proportional widths of the cells in each row */ private float[] proportionalWidths = null; /** * The cell padding */ private float cellPadding = 0; /** * The cell spacing */ private float cellSpacing = 0; /** * The border style of this RtfTable */ private RtfBorderGroup borders = null; /** * The alignment of this RtfTable */ private int alignment = Element.ALIGN_CENTER; /** * Whether the cells in this RtfTable must fit in a page */ private boolean cellsFitToPage = false; /** * Whether the whole RtfTable must fit in a page */ private boolean tableFitToPage = false; /** * The number of header rows in this RtfTable */ private int headerRows = 0; /** * The offset from the previous text */ private int offset = -1; /** * Constructs a RtfTable based on a Table for a RtfDocument. * * @param doc The RtfDocument this RtfTable belongs to * @param table The Table that this RtfTable wraps */ public RtfTable(RtfDocument doc, Table table) { super(doc); table.complete(); importTable(table); } /** * Constructs a RtfTable based on a PdfTable for a RtfDocument. * * @param doc The RtfDocument this RtfTable belongs to * @param table The PdfPTable that this RtfTable wraps * @since 2.1.3 */ public RtfTable(RtfDocument doc, PdfPTable table) { super(doc); importTable(table); } /** * Imports the rows and settings from the Table into this * RtfTable. * * @param table The source Table */ private void importTable(Table table) { this.rows = new ArrayList(); this.tableWidthPercent = table.getWidth(); this.proportionalWidths = table.getProportionalWidths(); this.cellPadding = (float) (table.getPadding() * TWIPS_FACTOR); this.cellSpacing = (float) (table.getSpacing() * TWIPS_FACTOR); this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor()); this.alignment = table.getAlignment(); int i = 0; Iterator rowIterator = table.iterator(); while(rowIterator.hasNext()) { this.rows.add(new RtfRow(this.document, this, (Row) rowIterator.next(), i)); i++; } for(i = 0; i < this.rows.size(); i++) { ((RtfRow) this.rows.get(i)).handleCellSpanning(); ((RtfRow) this.rows.get(i)).cleanRow(); } this.headerRows = table.getLastHeaderRow(); this.cellsFitToPage = table.isCellsFitPage(); this.tableFitToPage = table.isTableFitsPage(); if(!Float.isNaN(table.getOffset())) { this.offset = (int) (table.getOffset() * 2); } } /** * Imports the rows and settings from the Table into this * RtfTable. * * @param table The source PdfPTable * @since 2.1.3 */ private void importTable(PdfPTable table) { this.rows = new ArrayList(); this.tableWidthPercent = table.getWidthPercentage(); // this.tableWidthPercent = table.getWidth(); this.proportionalWidths = table.getAbsoluteWidths(); // this.proportionalWidths = table.getProportionalWidths(); this.cellPadding = (float) (table.spacingAfter() * TWIPS_FACTOR); // this.cellPadding = (float) (table.getPadding() * TWIPS_FACTOR); this.cellSpacing = (float) (table.spacingAfter() * TWIPS_FACTOR); // this.cellSpacing = (float) (table.getSpacing() * TWIPS_FACTOR); // this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor()); // this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor()); this.alignment = table.getHorizontalAlignment(); // this.alignment = table.getAlignment(); int i = 0; Iterator rowIterator = table.getRows().iterator(); // Iterator rowIterator = table.iterator(); while(rowIterator.hasNext()) { this.rows.add(new RtfRow(this.document, this, (PdfPRow) rowIterator.next(), i)); i++; } for(i = 0; i < this.rows.size(); i++) { ((RtfRow) this.rows.get(i)).handleCellSpanning(); ((RtfRow) this.rows.get(i)).cleanRow(); } this.headerRows = table.getHeaderRows(); // this.headerRows = table.getLastHeaderRow(); this.cellsFitToPage = table.getKeepTogether(); // this.cellsFitToPage = table.isCellsFitPage(); this.tableFitToPage = table.getKeepTogether(); // this.tableFitToPage = table.isTableFitsPage(); // if(!Float.isNaN(table.getOffset())) { // this.offset = (int) (table.getOffset() * 2); // } // if(!Float.isNaN(table.getOffset())) { // this.offset = (int) (table.getOffset() * 2); // } } /** * Writes the content of this RtfTable */ public void writeContent(final OutputStream result) throws IOException { if(!inHeader) { if(this.offset != -1) { result.write(RtfFont.FONT_SIZE); result.write(intToByteArray(this.offset)); } result.write(RtfParagraph.PARAGRAPH); } for(int i = 0; i < this.rows.size(); i++) { RtfElement re = (RtfElement)this.rows.get(i); //.result.write(re.write()); re.writeContent(result); } result.write(RtfParagraph.PARAGRAPH_DEFAULTS); } /** * Gets the alignment of this RtfTable * * @return The alignment of this RtfTable. */ protected int getAlignment() { return alignment; } /** * Gets the borders of this RtfTable * * @return The borders of this RtfTable. */ protected RtfBorderGroup getBorders() { return this.borders; } /** * Gets the cell padding of this RtfTable * * @return The cell padding of this RtfTable. */ protected float getCellPadding() { return cellPadding; } /** * Gets the cell spacing of this RtfTable * * @return The cell spacing of this RtfTable. */ protected float getCellSpacing() { return cellSpacing; } /** * Gets the proportional cell widths of this RtfTable * * @return The proportional widths of this RtfTable. */ protected float[] getProportionalWidths() { return (float[]) proportionalWidths.clone(); } /** * Gets the percentage of the page width this RtfTable covers * * @return The percentage of the page width. */ protected float getTableWidthPercent() { return tableWidthPercent; } /** * Gets the rows of this RtfTable * * @return The rows of this RtfTable */ protected ArrayList getRows() { return this.rows; } /** * Gets the cellsFitToPage setting of this RtfTable. * * @return The cellsFitToPage setting of this RtfTable. */ protected boolean getCellsFitToPage() { return this.cellsFitToPage; } /** * Gets the tableFitToPage setting of this RtfTable. * * @return The tableFitToPage setting of this RtfTable. */ protected boolean getTableFitToPage() { return this.tableFitToPage; } /** * Gets the number of header rows of this RtfTable * * @return The number of header rows */ protected int getHeaderRows() { return this.headerRows; } } src/rtf/com/lowagie/text/rtf/text/RtfAnnotation.java100644 0 0 11556 11106243445 20220 0ustar 0 0 /* * $Id: RtfAnnotation.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Annotation; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfAnnotation provides support for adding Annotations to the rtf document. * Only simple Annotations with Title / Content are supported. * * @version $Id: RtfAnnotation.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfAnnotation extends RtfElement { /** * Constant for the id of the annotation */ private static final byte[] ANNOTATION_ID = DocWriter.getISOBytes("\\*\\atnid"); /** * Constant for the author of the annotation */ private static final byte[] ANNOTATION_AUTHOR = DocWriter.getISOBytes("\\*\\atnauthor"); /** * Constant for the actual annotation */ private static final byte[] ANNOTATION = DocWriter.getISOBytes("\\*\\annotation"); /** * The title of this RtfAnnotation */ private String title = ""; /** * The content of this RtfAnnotation */ private String content = ""; /** * Constructs a RtfAnnotation based on an Annotation. * * @param doc The RtfDocument this RtfAnnotation belongs to * @param annotation The Annotation this RtfAnnotation is based off */ public RtfAnnotation(RtfDocument doc, Annotation annotation) { super(doc); title = annotation.title(); content = annotation.content(); } /** * Writes the content of the RtfAnnotation */ public void writeContent(final OutputStream result) throws IOException { result.write(OPEN_GROUP); result.write(ANNOTATION_ID); result.write(DELIMITER); result.write(intToByteArray(document.getRandomInt())); result.write(CLOSE_GROUP); result.write(OPEN_GROUP); result.write(ANNOTATION_AUTHOR); result.write(DELIMITER); result.write(DocWriter.getISOBytes(title)); result.write(CLOSE_GROUP); result.write(OPEN_GROUP); result.write(ANNOTATION); result.write(RtfParagraph.PARAGRAPH_DEFAULTS); result.write(DELIMITER); result.write(DocWriter.getISOBytes(content)); result.write(CLOSE_GROUP); } } src/rtf/com/lowagie/text/rtf/text/RtfChapter.java100644 0 0 10033 11106243445 17461 0ustar 0 0 /* * $Id: RtfChapter.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chapter; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfChapter wraps a Chapter element. * INTERNAL CLASS * * @version $Id: RtfChapter.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfChapter extends RtfSection { /** * Constructs a RtfChapter for a given Chapter * * @param doc The RtfDocument this RtfChapter belongs to * @param chapter The Chapter this RtfChapter is based on */ public RtfChapter(RtfDocument doc, Chapter chapter) { super(doc, chapter); } /** * Writes the RtfChapter and its contents */ public void writeContent(final OutputStream result) throws IOException { if(this.document.getLastElementWritten() != null && !(this.document.getLastElementWritten() instanceof RtfChapter)) { result.write(DocWriter.getISOBytes("\\page")); } result.write(DocWriter.getISOBytes("\\sectd")); document.getDocumentHeader().writeSectionDefinition(result); if(this.title != null) { this.title.writeContent(result); } for(int i = 0; i < items.size(); i++) { RtfBasicElement rbe = (RtfBasicElement)items.get(i); rbe.writeContent(result); } result.write(DocWriter.getISOBytes("\\sect")); } } src/rtf/com/lowagie/text/rtf/text/RtfChunk.java100644 0 0 15743 11106243445 17160 0ustar 0 0 /* * $Id: RtfChunk.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.awt.Color; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfColor; import com.lowagie.text.rtf.style.RtfFont; /** * The RtfChunk contains one piece of text. The smallest text element available * in iText. * * @version $Id: RtfChunk.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfChunk extends RtfElement { /** * Constant for the subscript flag */ private static final byte[] FONT_SUBSCRIPT = DocWriter.getISOBytes("\\sub"); /** * Constant for the superscript flag */ private static final byte[] FONT_SUPERSCRIPT = DocWriter.getISOBytes("\\super"); /** * Constant for the end of sub / superscript flag */ private static final byte[] FONT_END_SUPER_SUBSCRIPT = DocWriter.getISOBytes("\\nosupersub"); /** * Constant for background color. */ private static final byte[] BACKGROUND_COLOR = DocWriter.getISOBytes("\\chcbpat"); /** * The font of this RtfChunk */ private RtfFont font = null; /** * The actual content of this RtfChunk */ private String content = ""; /** * Whether to use soft line breaks instead of hard ones. */ private boolean softLineBreaks = false; /** * The super / subscript of this RtfChunk */ private float superSubScript = 0; /** * An optional background color. */ private RtfColor background = null; /** * Constructs a RtfChunk based on the content of a Chunk * * @param doc The RtfDocument that this Chunk belongs to * @param chunk The Chunk that this RtfChunk is based on */ public RtfChunk(RtfDocument doc, Chunk chunk) { super(doc); if(chunk == null) { return; } if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.SUBSUPSCRIPT) != null) { this.superSubScript = ((Float)chunk.getAttributes().get(Chunk.SUBSUPSCRIPT)).floatValue(); } if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.BACKGROUND) != null) { this.background = new RtfColor(this.document, (Color) ((Object[]) chunk.getAttributes().get(Chunk.BACKGROUND))[0]); } font = new RtfFont(doc, chunk.getFont()); content = chunk.getContent(); } /** * Writes the content of this RtfChunk. First the font information * is written, then the content, and then more font information */ public void writeContent(final OutputStream result) throws IOException { if(this.background != null) { result.write(OPEN_GROUP); } this.font.writeBegin(result); if(superSubScript < 0) { result.write(FONT_SUBSCRIPT); } else if(superSubScript > 0) { result.write(FONT_SUPERSCRIPT); } if(this.background != null) { result.write(BACKGROUND_COLOR); result.write(intToByteArray(this.background.getColorNumber())); } result.write(DELIMITER); document.filterSpecialChar(result, content, false, softLineBreaks || this.document.getDocumentSettings().isAlwaysGenerateSoftLinebreaks()); if(superSubScript != 0) { result.write(FONT_END_SUPER_SUBSCRIPT); } this.font.writeEnd(result); if(this.background != null) { result.write(CLOSE_GROUP); } } /** * Sets the RtfDocument this RtfChunk belongs to. * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { super.setRtfDocument(doc); this.font.setRtfDocument(this.document); } /** * Sets whether to use soft line breaks instead of default hard ones. * * @param softLineBreaks whether to use soft line breaks instead of default hard ones. */ public void setSoftLineBreaks(boolean softLineBreaks) { this.softLineBreaks = softLineBreaks; } /** * Gets whether to use soft line breaks instead of default hard ones. * * @return whether to use soft line breaks instead of default hard ones. */ public boolean getSoftLineBreaks() { return this.softLineBreaks; } } src/rtf/com/lowagie/text/rtf/text/RtfNewPage.java100644 0 0 6742 11106243445 17415 0ustar 0 0 /* * $Id: RtfNewPage.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; /** * The RtfNewPage creates a new page. INTERNAL CLASS * * @version $Id: RtfNewPage.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfNewPage extends RtfElement { /** * Constant for a new page */ public static final byte[] NEW_PAGE = DocWriter.getISOBytes("\\page"); /** * Constructs a RtfNewPage * * @param doc The RtfDocument this RtfNewPage belongs to */ public RtfNewPage(RtfDocument doc) { super(doc); } /** * Writes a new page */ public void writeContent(final OutputStream result) throws IOException { result.write(NEW_PAGE); result.write(RtfParagraph.PARAGRAPH_DEFAULTS); } } src/rtf/com/lowagie/text/rtf/text/RtfParagraph.java100644 0 0 20336 11154165267 20017 0ustar 0 0 /* * $Id: RtfParagraph.java 3670 2009-02-01 09:13:48Z blowagie $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Paragraph; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.graphic.RtfImage; import com.lowagie.text.rtf.style.RtfFont; import com.lowagie.text.rtf.style.RtfParagraphStyle; /** * The RtfParagraph is an extension of the RtfPhrase that adds alignment and * indentation properties. It wraps a Paragraph. * * @version $Id: RtfParagraph.java 3670 2009-02-01 09:13:48Z blowagie $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfParagraph extends RtfPhrase { /** * Constant for the end of a paragraph */ public static final byte[] PARAGRAPH = DocWriter.getISOBytes("\\par"); /** * An optional RtfParagraphStyle to use for styling. */ protected RtfParagraphStyle paragraphStyle = null; /** * Constructs a RtfParagraph belonging to a RtfDocument based on a Paragraph. * * @param doc The RtfDocument this RtfParagraph belongs to * @param paragraph The Paragraph that this RtfParagraph is based on */ public RtfParagraph(RtfDocument doc, Paragraph paragraph) { super(doc); RtfFont baseFont = null; if(paragraph.getFont() instanceof RtfParagraphStyle) { this.paragraphStyle = this.document.getDocumentHeader().getRtfParagraphStyle(((RtfParagraphStyle) paragraph.getFont()).getStyleName()); baseFont = this.paragraphStyle; } else { baseFont = new RtfFont(this.document, paragraph.getFont()); this.paragraphStyle = new RtfParagraphStyle(this.document, this.document.getDocumentHeader().getRtfParagraphStyle("Normal")); this.paragraphStyle.setAlignment(paragraph.getAlignment()); this.paragraphStyle.setFirstLineIndent((int) (paragraph.getFirstLineIndent() * RtfElement.TWIPS_FACTOR)); this.paragraphStyle.setIndentLeft((int) (paragraph.getIndentationLeft() * RtfElement.TWIPS_FACTOR)); this.paragraphStyle.setIndentRight((int) (paragraph.getIndentationRight() * RtfElement.TWIPS_FACTOR)); this.paragraphStyle.setSpacingBefore((int) (paragraph.getSpacingBefore() * RtfElement.TWIPS_FACTOR)); this.paragraphStyle.setSpacingAfter((int) (paragraph.getSpacingAfter() * RtfElement.TWIPS_FACTOR)); if(paragraph.hasLeading()) { this.paragraphStyle.setLineLeading((int) (paragraph.getLeading() * RtfElement.TWIPS_FACTOR)); } this.paragraphStyle.setKeepTogether(paragraph.getKeepTogether()); } for(int i = 0; i < paragraph.size(); i++) { Element chunk = (Element) paragraph.get(i); if(chunk instanceof Chunk) { ((Chunk) chunk).setFont(baseFont.difference(((Chunk) chunk).getFont())); } else if(chunk instanceof RtfImage) { ((RtfImage) chunks.get(i)).setAlignment(this.paragraphStyle.getAlignment()); } try { RtfBasicElement[] rtfElements = doc.getMapper().mapElement(chunk); for(int j = 0; j < rtfElements.length; j++) { chunks.add(rtfElements[j]); } } catch(DocumentException de) { } } } /** * Set whether this RtfParagraph must stay on the same page as the next one. * * @param keepTogetherWithNext Whether this RtfParagraph must keep together with the next. */ public void setKeepTogetherWithNext(boolean keepTogetherWithNext) { this.paragraphStyle.setKeepTogetherWithNext(keepTogetherWithNext); } /** * Writes the content of this RtfParagraph. First paragraph specific data is written * and then the RtfChunks of this RtfParagraph are added. */ public void writeContent(final OutputStream result) throws IOException { result.write(PARAGRAPH_DEFAULTS); result.write(PLAIN); if(inTable) { result.write(IN_TABLE); } if(this.paragraphStyle != null) { this.paragraphStyle.writeBegin(result); } result.write(DocWriter.getISOBytes("\\plain")); for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rbe = (RtfBasicElement)chunks.get(i); rbe.writeContent(result); } if(this.paragraphStyle != null) { this.paragraphStyle.writeEnd(result); } if(!inTable) { result.write(PARAGRAPH); } this.document.outputDebugLinebreak(result); } /** * Gets the left indentation of this RtfParagraph. * * @return The left indentation. */ public int getIndentLeft() { return this.paragraphStyle.getIndentLeft(); } /** * Sets the left indentation of this RtfParagraph. * * @param indentLeft The left indentation to use. */ public void setIndentLeft(int indentLeft) { this.paragraphStyle.setIndentLeft(indentLeft); } /** * Gets the right indentation of this RtfParagraph. * * @return The right indentation. */ public int getIndentRight() { return this.paragraphStyle.getIndentRight(); } /** * Sets the right indentation of this RtfParagraph. * * @param indentRight The right indentation to use. */ public void setIndentRight(int indentRight) { this.paragraphStyle.setIndentRight(indentRight); } } src/rtf/com/lowagie/text/rtf/text/RtfPhrase.java100644 0 0 16701 11106243445 17325 0ustar 0 0 /* * $Id: RtfPhrase.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.Chunk; import com.lowagie.text.DocWriter; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Phrase; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.style.RtfFont; /** * The RtfPhrase contains multiple RtfChunks * * @version $Id: RtfPhrase.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfPhrase extends RtfElement { /** * Constant for the resetting of the paragraph defaults */ public static final byte[] PARAGRAPH_DEFAULTS = DocWriter.getISOBytes("\\pard"); /** * Constant for resetting of font settings to their defaults */ public static final byte[] PLAIN = DocWriter.getISOBytes("\\plain"); /** * Constant for phrase in a table indication */ public static final byte[] IN_TABLE = DocWriter.getISOBytes("\\intbl"); /** * Constant for the line spacing. */ public static final byte[] LINE_SPACING = DocWriter.getISOBytes("\\sl"); /** * ArrayList containing the RtfChunks of this RtfPhrase */ protected ArrayList chunks = new ArrayList(); /** * The height of each line. */ private int lineLeading = 0; /** * A basically empty constructor that is used by the RtfParagraph. * * @param doc The RtfDocument this RtfPhrase belongs to. */ protected RtfPhrase(RtfDocument doc) { super(doc); } /** * Constructs a new RtfPhrase for the RtfDocument with the given Phrase * * @param doc The RtfDocument this RtfPhrase belongs to * @param phrase The Phrase this RtfPhrase is based on */ public RtfPhrase(RtfDocument doc, Phrase phrase) { super(doc); if(phrase == null) { return; } if(phrase.hasLeading()) { this.lineLeading = (int) (phrase.getLeading() * RtfElement.TWIPS_FACTOR); } else { this.lineLeading = 0; } RtfFont phraseFont = new RtfFont(null, phrase.getFont()); for(int i = 0; i < phrase.size(); i++) { Element chunk = (Element) phrase.get(i); if(chunk instanceof Chunk) { ((Chunk) chunk).setFont(phraseFont.difference(((Chunk) chunk).getFont())); } try { RtfBasicElement[] rtfElements = doc.getMapper().mapElement(chunk); for(int j = 0; j < rtfElements.length; j++) { chunks.add(rtfElements[j]); } } catch(DocumentException de) { } } } /** * Write the content of this RtfPhrase. First resets to the paragraph defaults * then if the RtfPhrase is in a RtfCell a marker for this is written and finally * the RtfChunks of this RtfPhrase are written. */ public void writeContent(final OutputStream result) throws IOException { result.write(PARAGRAPH_DEFAULTS); result.write(PLAIN); if(inTable) { result.write(IN_TABLE); } if(this.lineLeading > 0) { result.write(LINE_SPACING); result.write(intToByteArray(this.lineLeading)); } for(int i = 0; i < chunks.size(); i++) { RtfBasicElement rbe = (RtfBasicElement) chunks.get(i); rbe.writeContent(result); } } /** * Sets whether this RtfPhrase is in a table. Sets the correct inTable setting for all * child elements. * * @param inTable True if this RtfPhrase is in a table, false otherwise */ public void setInTable(boolean inTable) { super.setInTable(inTable); for(int i = 0; i < this.chunks.size(); i++) { ((RtfBasicElement) this.chunks.get(i)).setInTable(inTable); } } /** * Sets whether this RtfPhrase is in a header. Sets the correct inTable setting for all * child elements. * * @param inHeader True if this RtfPhrase is in a header, false otherwise */ public void setInHeader(boolean inHeader) { super.setInHeader(inHeader); for(int i = 0; i < this.chunks.size(); i++) { ((RtfBasicElement) this.chunks.get(i)).setInHeader(inHeader); } } /** * Sets the RtfDocument this RtfPhrase belongs to. Also sets the RtfDocument for all child * elements. * * @param doc The RtfDocument to use */ public void setRtfDocument(RtfDocument doc) { super.setRtfDocument(doc); for(int i = 0; i < this.chunks.size(); i++) { ((RtfBasicElement) this.chunks.get(i)).setRtfDocument(this.document); } } } src/rtf/com/lowagie/text/rtf/text/RtfSection.java100644 0 0 20157 11012562273 17506 0ustar 0 0 /* * $Id: RtfSection.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import com.lowagie.text.Chunk; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Section; import com.lowagie.text.rtf.RtfBasicElement; import com.lowagie.text.rtf.RtfElement; import com.lowagie.text.rtf.document.RtfDocument; import com.lowagie.text.rtf.field.RtfTOCEntry; /** * The RtfSection wraps a Section element. * INTERNAL CLASS * * @version $Id: RtfSection.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfSection extends RtfElement { /** * The title paragraph of this RtfSection */ protected RtfParagraph title = null; /** * The sub-items of this RtfSection */ protected ArrayList items = null; /** * Constructs a RtfSection for a given Section. If the autogenerateTOCEntries * property of the RtfDocument is set and the title is not empty then a TOC entry * is generated for the title. * * @param doc The RtfDocument this RtfSection belongs to * @param section The Section this RtfSection is based on */ public RtfSection(RtfDocument doc, Section section) { super(doc); items = new ArrayList(); try { if(section.getTitle() != null) { this.title = (RtfParagraph) doc.getMapper().mapElement(section.getTitle())[0]; } if(document.getAutogenerateTOCEntries()) { StringBuffer titleText = new StringBuffer(); Iterator it = section.getTitle().iterator(); while(it.hasNext()) { Element element = (Element) it.next(); if(element.type() == Element.CHUNK) { titleText.append(((Chunk) element).getContent()); } } if(titleText.toString().trim().length() > 0) { RtfTOCEntry tocEntry = new RtfTOCEntry(titleText.toString()); tocEntry.setRtfDocument(this.document); this.items.add(tocEntry); } } Iterator iterator = section.iterator(); while(iterator.hasNext()) { Element element = (Element) iterator.next(); RtfBasicElement[] rtfElements = doc.getMapper().mapElement(element); for(int i = 0; i < rtfElements.length; i++) { if(rtfElements[i] != null) { items.add(rtfElements[i]); } } } updateIndentation(section.getIndentationLeft(), section.getIndentationRight(), section.getIndentation()); } catch(DocumentException de) { de.printStackTrace(); } } /** * Write this RtfSection and its contents */ public void writeContent(final OutputStream result) throws IOException { result.write(RtfParagraph.PARAGRAPH); if(this.title != null) { this.title.writeContent(result); } for(int i = 0; i < items.size(); i++) { RtfBasicElement rbe = (RtfBasicElement) items.get(i); rbe.writeContent(result); } } /** * Sets whether this RtfSection is in a table. Sets the correct inTable setting for all * child elements. * * @param inTable True if this RtfSection is in a table, false otherwise */ public void setInTable(boolean inTable) { super.setInTable(inTable); for(int i = 0; i < this.items.size(); i++) { ((RtfBasicElement) this.items.get(i)).setInTable(inTable); } } /** * Sets whether this RtfSection is in a header. Sets the correct inTable setting for all * child elements. * * @param inHeader True if this RtfSection is in a header, false otherwise */ public void setInHeader(boolean inHeader) { super.setInHeader(inHeader); for(int i = 0; i < this.items.size(); i++) { ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader); } } /** * Updates the left, right and content indentation of all RtfParagraph and RtfSection * elements that this RtfSection contains. * * @param indentLeft The left indentation to add. * @param indentRight The right indentation to add. * @param indentContent The content indentation to add. */ private void updateIndentation(float indentLeft, float indentRight, float indentContent) { if(this.title != null) { this.title.setIndentLeft((int) (this.title.getIndentLeft() + indentLeft * RtfElement.TWIPS_FACTOR)); this.title.setIndentRight((int) (this.title.getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR)); } for(int i = 0; i < this.items.size(); i++) { RtfBasicElement rtfElement = (RtfBasicElement) this.items.get(i); if(rtfElement instanceof RtfSection) { ((RtfSection) rtfElement).updateIndentation(indentLeft + indentContent, indentRight, 0); } else if(rtfElement instanceof RtfParagraph) { ((RtfParagraph) rtfElement).setIndentLeft((int) (((RtfParagraph) rtfElement).getIndentLeft() + (indentLeft + indentContent) * RtfElement.TWIPS_FACTOR)); ((RtfParagraph) rtfElement).setIndentRight((int) (((RtfParagraph) rtfElement).getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR)); } } } } src/rtf/com/lowagie/text/rtf/text/RtfTab.java100644 0 0 12446 11106243445 16613 0ustar 0 0 /* * $Id: RtfTab.java 3580 2008-08-06 15:52:00Z howard_s $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are * Copyright (C) 2006 by Mark Hall. All Rights Reserved * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import com.lowagie.text.DocWriter; import com.lowagie.text.rtf.RtfAddableElement; /** * The RtfTab encapsulates a tab position and tab type in a paragraph. * To add tabs to a paragraph construct new RtfTab objects with the desired * tab position and alignment and then add them to the paragraph. In the actual * text the tabs are then defined as standard \t characters.

      * * RtfTab tab = new RtfTab(300, RtfTab.TAB_LEFT_ALIGN);
      * Paragraph para = new Paragraph();
      * para.add(tab);
      * para.add("This paragraph has a\ttab defined.");
      * * @version $Id: RtfTab.java 3580 2008-08-06 15:52:00Z howard_s $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTab extends RtfAddableElement { /** * A tab where the text is left aligned. */ public static final int TAB_LEFT_ALIGN = 0; /** * A tab where the text is center aligned. */ public static final int TAB_CENTER_ALIGN = 1; /** * A tab where the text is right aligned. */ public static final int TAB_RIGHT_ALIGN = 2; /** * A tab where the text is aligned on the decimal character. Which * character that is depends on the language settings of the viewer. */ public static final int TAB_DECIMAL_ALIGN = 3; /** * The tab position in twips. */ private int position = 0; /** * The tab alignment. */ private int type = TAB_LEFT_ALIGN; /** * Constructs a new RtfTab with the given position and type. The position * is in standard iText points. The type is one of the tab alignment * constants defined in the RtfTab. * * @param position The position of the tab in points. * @param type The tab type constant. */ public RtfTab(float position, int type) { this.position = (int) Math.round(position * TWIPS_FACTOR); switch(type) { case TAB_LEFT_ALIGN: this.type = TAB_LEFT_ALIGN; break; case TAB_CENTER_ALIGN: this.type = TAB_CENTER_ALIGN; break; case TAB_RIGHT_ALIGN: this.type = TAB_RIGHT_ALIGN; break; case TAB_DECIMAL_ALIGN: this.type = TAB_DECIMAL_ALIGN; break; default: this.type = TAB_LEFT_ALIGN; break; } } /** * Writes the tab settings. */ public void writeContent(final OutputStream result) throws IOException { switch(this.type) { case TAB_CENTER_ALIGN: result.write(DocWriter.getISOBytes("\\tqc")); break; case TAB_RIGHT_ALIGN: result.write(DocWriter.getISOBytes("\\tqr")); break; case TAB_DECIMAL_ALIGN: result.write(DocWriter.getISOBytes("\\tqdec")); break; } result.write(DocWriter.getISOBytes("\\tx")); result.write(intToByteArray(this.position)); } } src/rtf/com/lowagie/text/rtf/text/RtfTabGroup.java100644 0 0 10726 11012562273 17626 0ustar 0 0 /* * $Id: RtfTabGroup.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2001, 2002, 2003, 2004 by Mark Hall * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are * Copyright (C) 2006 by Mark Hall. All Rights Reserved * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.text.rtf.text; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import com.lowagie.text.rtf.RtfAddableElement; /** * The RtfTabGroup is a convenience class if the same tabs are to be added * to multiple paragraphs.

      * * RtfTabGroup tabs = new RtfTabGroup();
      * tabs.add(new RtfTab(70, RtfTab.TAB_LEFT_ALIGN));
      * tabs.add(new RtfTab(160, RtfTab.TAB_CENTER_ALIGN));
      * tabs.add(new RtfTab(250, RtfTab.TAB_DECIMAL_ALIGN));
      * tabs.add(new RtfTab(500, RtfTab.TAB_RIGHT_ALIGN));
      * Paragraph para = new Paragraph();
      * para.add(tabs);
      * para.add("\tLeft aligned\tCentre aligned\t12,45\tRight aligned");
      * * @version $Id: RtfTabGroup.java 3373 2008-05-12 16:21:24Z xlv $ * @author Mark Hall (Mark.Hall@mail.room3b.eu) * @author Thomas Bickel (tmb99@inode.at) */ public class RtfTabGroup extends RtfAddableElement { /** * The tabs to add. */ private ArrayList tabs = null; /** * Constructs an empty RtfTabGroup. */ public RtfTabGroup() { this.tabs = new ArrayList(); } /** * Constructs a RtfTabGroup with a set of tabs. * * @param tabs An ArrayList with the RtfTabs to group in this RtfTabGroup. */ public RtfTabGroup(ArrayList tabs) { this.tabs = new ArrayList(); for(int i = 0; i < tabs.size(); i++) { if(tabs.get(i) instanceof RtfTab) { this.tabs.add(tabs.get(i)); } } } /** * Adds a RtfTab to the list of grouped tabs. * * @param tab The RtfTab to add. */ public void add(RtfTab tab) { this.tabs.add(tab); } /** * Combines the tab output form all grouped tabs. */ public void writeContent(final OutputStream result) throws IOException { for(int i = 0; i < this.tabs.size(); i++) { RtfTab rt = (RtfTab) this.tabs.get(i); rt.writeContent(result); } } } src/rups/com/lowagie/rups/Rups.java100644 0 0 5146 11000663663 14766 0ustar 0 0 /* * $Id: Rups.java 3242 2008-04-13 23:00:20Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups; import java.awt.Dimension; import java.awt.Toolkit; import javax.swing.JFrame; import com.lowagie.rups.controller.RupsController; /** * iText RUPS is a tool that combines SUN's PDF Renderer (to view PDF * documents), iText's PdfReader (to inspect the internal structure of a * PDF file), and iText's PdfStamper to manipulate a PDF file. */ public class Rups { /** The version String; this String may only be changed by Bruno Lowagie. */ public static final String VERSION = "RUPS 0.0.1 (by lowagie.com)"; // main method /** * Main method of this PdfFrame class. * @param args no arguments needed */ public static void main(String[] args) { startApplication(); } // methods /** * Initializes the main components of the Rups application. */ public static void startApplication() { JFrame frame = new JFrame(); // size and location Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); frame.setSize((int)(screen.getWidth() * .90), (int)(screen.getHeight() * .90)); frame.setLocation((int)(screen.getWidth() * .05), (int)(screen.getHeight() * .05)); frame.setResizable(true); // title bar frame.setTitle("iText RUPS"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // the content RupsController controller = new RupsController(frame.getSize()); frame.setJMenuBar(controller.getMenuBar()); frame.getContentPane().add(controller.getMasterComponent(), java.awt.BorderLayout.CENTER); frame.setVisible(true); } // other member variables /** Serial Version UID. */ private static final long serialVersionUID = 4386633640535735848L; }src/rups/com/lowagie/rups/controller/PdfReaderController.java100644 0 0 20757 11154165267 22154 0ustar 0 0 /* * $Id: PdfReaderController.java 3692 2009-02-13 00:51:21Z mstorer $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.controller; import java.util.Observable; import java.util.Observer; import javax.swing.JTabbedPane; import javax.swing.event.TreeSelectionListener; import com.lowagie.rups.model.ObjectLoader; import com.lowagie.rups.model.PdfFile; import com.lowagie.rups.model.TreeNodeFactory; import com.lowagie.rups.view.PageNavigationListener; import com.lowagie.rups.view.RupsMenuBar; import com.lowagie.rups.view.itext.FormTree; import com.lowagie.rups.view.itext.OutlineTree; import com.lowagie.rups.view.itext.PagesTable; import com.lowagie.rups.view.itext.PdfObjectPanel; import com.lowagie.rups.view.itext.PdfTree; import com.lowagie.rups.view.itext.StreamTextArea; import com.lowagie.rups.view.itext.XRefTable; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; import com.lowagie.text.pdf.PRStream; import com.lowagie.text.pdf.PdfObject; /** * Controls the GUI components that get their content from iText's PdfReader. */ public class PdfReaderController extends Observable implements Observer { /** Treeview of the PDF file. */ protected PdfTree pdfTree; /** Tabbed Pane containing other components. */ protected JTabbedPane navigationTabs; /** JTable with all the pages and their labels. */ protected PagesTable pages; /** Treeview of the outlines. */ protected OutlineTree outlines; /** Treeview of the form. */ protected FormTree form; /** JTable corresponding with the CrossReference table. */ protected XRefTable xref; /** A panel that will show PdfObjects. */ protected PdfObjectPanel objectPanel; /** Tabbed Pane containing other components. */ protected JTabbedPane editorTabs; /** A panel that will show a stream. */ protected StreamTextArea streamArea; /** The factory producing tree nodes. */ protected TreeNodeFactory nodes; /** * Constructs the PdfReaderController. * This is an Observable object to which all iText related GUI components * are added as Observers. * @param treeSelectionListener when somebody selects a tree node, this listener listens to the event * @param pageNavigationListener when somebody changes a page, this listener changes accordingly */ public PdfReaderController(TreeSelectionListener treeSelectionListener, PageNavigationListener pageNavigationListener) { pdfTree = new PdfTree(); pdfTree.addTreeSelectionListener(treeSelectionListener); addObserver(pdfTree); pages = new PagesTable(this, pageNavigationListener); addObserver(pages); outlines = new OutlineTree(this); addObserver(outlines); form = new FormTree(this); addObserver(form); xref = new XRefTable(this); addObserver(xref); navigationTabs = new JTabbedPane(); navigationTabs.addTab("Pages", null, RupsController.getScrollPane(pages), "Pages"); navigationTabs.addTab("Outlines", null, RupsController.getScrollPane(outlines), "Outlines (Bookmarks)"); navigationTabs.addTab("Form", null, RupsController.getScrollPane(form), "Interactive Form"); navigationTabs.addTab("XFA", null, form.getXfaTree(), "Tree view of the XFA form"); navigationTabs.addTab("XRef", null, RupsController.getScrollPane(xref), "Cross-reference table"); objectPanel = new PdfObjectPanel(); addObserver(objectPanel); streamArea = new StreamTextArea(); addObserver(streamArea); editorTabs = new JTabbedPane(); editorTabs.addTab("Stream", null, streamArea, "Stream"); editorTabs.addTab("XFA", null, form.getXfaTextArea(), "XFA Form XML file"); } /** * Getter for the PDF Tree. * @return the PdfTree object */ public PdfTree getPdfTree() { return pdfTree; } /** * Getter for the tabs that allow you to navigate through * the PdfTree quickly (pages, form, outlines, xref table). * @return a JTabbedPane */ public JTabbedPane getNavigationTabs() { return navigationTabs; } /** * Getter for the panel that will show the contents * of a PDF Object (except for PdfStreams: only the * Stream Dictionary will be shown; the content stream * is shown in a StreamTextArea object). * @return the PdfObjectPanel */ public PdfObjectPanel getObjectPanel() { return objectPanel; } /** * Getter for the tabs with the editor windows * (to which the Console window will be added). */ public JTabbedPane getEditorTabs() { return editorTabs; } /** * Getter for the object that holds the TextArea * with the content stream of a PdfStream object. * @return a StreamTextArea */ public StreamTextArea getStreamArea() { return streamArea; } /** * Starts loading the PDF Objects in background. * @param file the wrapper object that holds the PdfReader as member variable */ public void startObjectLoader(PdfFile file) { setChanged(); notifyObservers(); setChanged(); new ObjectLoader(this, file.getPdfReader()); } /** * The GUI components that show the internals of a PDF file, * can only be shown if all objects are loaded into the * IndirectObjectFactory using the ObjectLoader. * As soon as this is done, the GUI components are notified. * @param obj in this case the Object should be an ObjectLoader * @see java.util.Observable#notifyObservers(java.lang.Object) */ @Override public void notifyObservers(Object obj) { if (obj instanceof ObjectLoader) { ObjectLoader loader = (ObjectLoader)obj; nodes = loader.getNodes(); PdfTrailerTreeNode root = pdfTree.getRoot(); root.setTrailer(loader.getReader().getTrailer()); root.setUserObject("PDF Object Tree"); nodes.expandNode(root); } super.notifyObservers(obj); } /** * Selects a node in the PdfTree. * @param node a node in the PdfTree */ public void selectNode(PdfObjectTreeNode node) { pdfTree.selectNode(node); } /** * Selects a node in the PdfTree. * @param objectNumber a number of a node in the PdfTree */ public void selectNode(int objectNumber) { selectNode(nodes.getNode(objectNumber)); } /** * Renders the syntax of a PdfObject in the objectPanel. * If the object is a PDF Stream, then the stream is shown * in the streamArea too. */ public void render(PdfObject object) { objectPanel.render(object); streamArea.render(object); if (object instanceof PRStream) { editorTabs.setSelectedComponent(streamArea); } else { editorTabs.setSelectedIndex(editorTabs.getComponentCount() - 1); } } /** * Selects the row in the pageTable that corresponds with * a certain page number. * @param pageNumber the page number that needs to be selected */ public void gotoPage(int pageNumber) { pageNumber--; if (pages == null || pages.getSelectedRow() == pageNumber) return; if (pageNumber < pages.getRowCount()) pages.setRowSelectionInterval(pageNumber, pageNumber); } /** * Forwards updates from the RupsController to the Observers of this class. * @param observable this should be the RupsController * @param obj the object that has to be forwarded to the observers of PdfReaderController * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (RupsMenuBar.CLOSE.equals(obj)) { setChanged(); notifyObservers(null); nodes = null; } if (obj instanceof PdfObjectTreeNode) { PdfObjectTreeNode node = (PdfObjectTreeNode)obj; nodes.expandNode(node); if (node.isRecursive()) { pdfTree.selectNode(node.getAncestor()); return; }/* if (node.isIndirect()) { xref.selectRowByReference(node.getNumber()); return; }*/ render(node.getPdfObject()); } } } src/rups/com/lowagie/rups/controller/PdfRendererController.java100644 0 0 10321 11000354132 22457 0ustar 0 0 /* * $Id: PdfRendererController.java 3146 2008-02-20 18:10:07Z blowagie $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.controller; import java.util.Observable; import java.util.Observer; import javax.swing.JSplitPane; import com.lowagie.rups.model.PageLoader; import com.lowagie.rups.model.PdfFile; import com.lowagie.rups.view.PageNavigationListener; import com.lowagie.rups.view.RupsMenuBar; import com.lowagie.rups.view.renderer.PagePanel; import com.lowagie.rups.view.renderer.ToolBar; /** * This is the part of Trapeze that uses SUN's PDF Renderer. */ public class PdfRendererController extends JSplitPane implements Observer { /** The page loader that provides access to the PDFPage objects. */ protected PageLoader pageLoader = null; /** The ToolBar. */ protected ToolBar toolbar; /** The PagePanel */ protected PagePanel pagePanel; /** A Serial Version UID. */ private static final long serialVersionUID = 3270054619281094248L; /** * Constructs the rendering controller. * @param listener a page navigation listener */ public PdfRendererController(PageNavigationListener listener) { setOrientation(JSplitPane.VERTICAL_SPLIT); setDividerLocation(33); setDividerSize(0); pagePanel = new PagePanel(); toolbar = new ToolBar(listener); add(toolbar, JSplitPane.TOP); add(pagePanel, JSplitPane.BOTTOM); } /** * Starts loading pages. * Shows page 1 of this file as soon as possible. * @param file the PdfFile that needs to be rendered */ public void startPageLoader(PdfFile file) { this.pageLoader = new PageLoader(file.getPDFFile()); gotoPage(1); } /** * Shows a specific page in the page panel. * @param pageNumber a number of a specific page. */ protected int showPage(int pageNumber) { if (pageLoader == null) { return -1; } pagePanel.showPage(pageLoader.loadPage(pageNumber)); pagePanel.requestFocus(); return pageNumber; } // page navigation /** * Gets the total number of pages in the document. * @return the total number of pages */ public int getTotalNumberOfPages() { if (pageLoader == null) return 0; return pageLoader.getNumberOfPages(); } /** * Getter for the current page number. * @return the page number of the page currently shown */ public int getCurrentPageNumber() { return pagePanel.getCurrentPageNumber(); } /** * Shows a specific page. * @param pageNumber the number of a specific page. */ public int gotoPage(int pageNumber) { if (pageNumber == getCurrentPageNumber()) { return pageNumber; } if (pageNumber < 0) { toolbar.setPageNumber(-1); return -1; } if (pageNumber == 0) { pageNumber = 1; } else if (pageNumber > getTotalNumberOfPages()) { pageNumber = getTotalNumberOfPages(); } pageNumber = showPage(pageNumber); toolbar.setPageNumber(pageNumber); return pageNumber; } // Observer interface /** * Forwards updates from the RupsController to the Observers of this class. * @param observable this should be the RupsController * @param obj the object that has to be forwarded to the observers of PdfReaderController * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (RupsMenuBar.CLOSE.equals(obj)) { pageLoader = null; pagePanel.showPage(null); toolbar.setPageNumber(-1); } } } src/rups/com/lowagie/rups/controller/RupsController.java100644 0 0 17045 11000663663 21236 0ustar 0 0 /* * $Id: RupsController.java 3244 2008-04-13 23:27:35Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.controller; import java.awt.Component; import java.awt.Dimension; import java.io.File; import java.io.IOException; import java.util.Observable; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import com.lowagie.rups.io.FileChooserAction; import com.lowagie.rups.io.FileCloseAction; import com.lowagie.rups.model.PdfFile; import com.lowagie.rups.view.Console; import com.lowagie.rups.view.PageNavigationListener; import com.lowagie.rups.view.RupsMenuBar; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; import com.lowagie.text.DocumentException; /** * This class controls all the GUI components that are shown in * the Trapeze application: the menu bar, the panels,... */ public class RupsController extends Observable implements TreeSelectionListener, PageNavigationListener { // member variables /* file */ /** The Pdf file that is currently open in the application. */ protected PdfFile pdfFile; /* main components */ /** The JMenuBar for the Trapeze application. */ protected RupsMenuBar menuBar; /** Contains all other components: the page panel, the outline tree, etc. */ protected JSplitPane masterComponent; /* Other controllers */ /** Object with the GUI components for SUN's PDF Renderer. */ protected PdfRendererController renderer; /** Object with the GUI components for iText. */ protected PdfReaderController reader; // constructor /** * Constructs the GUI components of the Trapeze application. */ public RupsController(Dimension dimension) { // creating components and controllers menuBar = new RupsMenuBar(this); addObserver(menuBar); Console console = Console.getInstance(); addObserver(console); renderer = new PdfRendererController(this); addObserver(renderer); reader = new PdfReaderController(this, this); addObserver(reader); // creating the master component masterComponent = new JSplitPane(); masterComponent.setOrientation(JSplitPane.VERTICAL_SPLIT); masterComponent.setDividerLocation((int)(dimension.getHeight() * .70)); masterComponent.setDividerSize(2); JSplitPane content = new JSplitPane(); masterComponent.add(content, JSplitPane.TOP); JSplitPane info = new JSplitPane(); masterComponent.add(info, JSplitPane.BOTTOM); content.setOrientation(JSplitPane.HORIZONTAL_SPLIT); content.setDividerLocation((int)(dimension.getWidth() * .75)); content.setDividerSize(1); JSplitPane viewers = new JSplitPane(); content.add(viewers, JSplitPane.LEFT); content.add(reader.getNavigationTabs(), JSplitPane.RIGHT); viewers.setOrientation(JSplitPane.HORIZONTAL_SPLIT); viewers.setDividerLocation((int)(dimension.getWidth() * .35)); viewers.setDividerSize(1); viewers.add(renderer, JSplitPane.RIGHT); viewers.add(RupsController.getScrollPane(reader.getPdfTree()), JSplitPane.LEFT); info.setDividerLocation((int) (dimension.getWidth() * .3)); info.setDividerSize(1); info.add(reader.getObjectPanel(), JSplitPane.LEFT); JTabbedPane editorPane = reader.getEditorTabs(); JScrollPane cons = RupsController.getScrollPane(console.getTextArea()); editorPane.addTab("Console", null, cons, "Console window (System.out/System.err)"); editorPane.setSelectedComponent(cons); info.add(editorPane, JSplitPane.RIGHT); } /** Getter for the menubar. */ public RupsMenuBar getMenuBar() { return menuBar; } /** Getter for the master component. */ public Component getMasterComponent() { return masterComponent; } // Observable /** * @see java.util.Observable#notifyObservers(java.lang.Object) */ @Override public void notifyObservers(Object obj) { if (obj instanceof FileChooserAction) { File file = ((FileChooserAction)obj).getFile(); try { pdfFile = new PdfFile(file); setChanged(); super.notifyObservers(RupsMenuBar.OPEN); renderer.startPageLoader(pdfFile); reader.startObjectLoader(pdfFile); } catch(IOException ioe) { JOptionPane.showMessageDialog(masterComponent, ioe.getMessage(), "Dialog", JOptionPane.ERROR_MESSAGE); } catch (DocumentException de) { JOptionPane.showMessageDialog(masterComponent, de.getMessage(), "Dialog", JOptionPane.ERROR_MESSAGE); } return; } if (obj instanceof FileCloseAction) { pdfFile = null; setChanged(); super.notifyObservers(RupsMenuBar.CLOSE); return; } } // tree selection /** * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent) */ public void valueChanged(TreeSelectionEvent evt) { Object selectednode = reader.getPdfTree().getLastSelectedPathComponent(); if (selectednode instanceof PdfTrailerTreeNode) { menuBar.update(this, RupsMenuBar.FILE_MENU); return; } if (selectednode instanceof PdfObjectTreeNode) { reader.update(this, selectednode); } } // page navigation /** * @see com.lowagie.rups.view.PageNavigationListener#getCurrentPageNumber() */ public int getCurrentPageNumber() { return renderer.getCurrentPageNumber(); } /** * @see com.lowagie.rups.view.PageNavigationListener#getTotalNumberOfPages() */ public int getTotalNumberOfPages() { return renderer.getTotalNumberOfPages(); } /** * @see com.lowagie.rups.view.PageNavigationListener#gotoFirstPage() */ public int gotoFirstPage() { return gotoPage(1); } /** * @see com.lowagie.rups.view.PageNavigationListener#gotoPreviousPage() */ public int gotoPreviousPage() { return gotoPage(getCurrentPageNumber() - 1); } /** * @see com.lowagie.rups.view.PageNavigationListener#gotoPage(int) */ public int gotoPage(int pageNumber) { pageNumber = renderer.gotoPage(pageNumber); reader.gotoPage(pageNumber); return pageNumber; } /** * @see com.lowagie.rups.view.PageNavigationListener#gotoNextPage() */ public int gotoNextPage() { return gotoPage(getCurrentPageNumber() + 1); } /** * @see com.lowagie.rups.view.PageNavigationListener#gotoLastPage() */ public int gotoLastPage() { return gotoPage(getTotalNumberOfPages()); } /** * Adds a component to a ScrollPane. * @param component the component that has to be scrollable * @return a JScrollPane * @since 2.1.0 */ public static JScrollPane getScrollPane(Component component) { JScrollPane scrollpane = new JScrollPane(); scrollpane.setViewportView(component); return scrollpane; } } src/rups/com/lowagie/rups/io/FileChooserAction.java100644 0 0 5477 11000354133 20000 0ustar 0 0 /* * $Id: FileChooserAction.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.io; import java.awt.event.ActionEvent; import java.io.File; import java.util.Observable; import javax.swing.AbstractAction; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; /** * Allows you to browse the file system and forwards the file * to the object that is waiting for you to choose a file. */ public class FileChooserAction extends AbstractAction { /** An object that is expecting the result of the file chooser action. */ protected Observable observable; /** A file filter to apply when browsing for a file. */ protected FileFilter filter; /** Indicates if you're browsing to create a new or an existing file. */ protected boolean newFile; /** The file that was chosen. */ protected File file; /** * Creates a new file chooser action. * @param observable the object waiting for you to select file * @param caption a description for the action * @param filter a filter to apply when browsing * @param newFile indicates if you should browse for a new or existing file */ public FileChooserAction(Observable observable, String caption, FileFilter filter, boolean newFile) { super(caption); this.observable = observable; this.filter = filter; this.newFile = newFile; } /** * Getter for the file. */ public File getFile() { return file; } /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent evt) { JFileChooser fc = new JFileChooser(); if (filter != null) { fc.setFileFilter(filter); } int okCancel; if (newFile) { okCancel = fc.showSaveDialog(null); } else { okCancel = fc.showOpenDialog(null); } if (okCancel == JFileChooser.APPROVE_OPTION) { file = fc.getSelectedFile(); observable.notifyObservers(this); } } /** A serial version UID. */ private static final long serialVersionUID = 2225830878098387118L; } src/rups/com/lowagie/rups/io/FileCloseAction.java100644 0 0 3225 11000354133 17430 0ustar 0 0 /* * $Id: FileCloseAction.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.io; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Observable; /** * Action that tells an observable to close a file and/or releases * resources relevant for the file that is being closed. */ public class FileCloseAction implements ActionListener { /** An object that allows you to close a file. */ protected Observable observable; /** * Creates the close action. * @param observable the object that expects you to close a file. */ public FileCloseAction(Observable observable) { this.observable = observable; } /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent evt) { observable.notifyObservers(this); } } src/rups/com/lowagie/rups/io/OutputStreamResource.java100644 0 0 2554 11000354133 20615 0ustar 0 0 /* * $Id: OutputStreamResource.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.io; import java.io.IOException; import java.io.OutputStream; /** * An object that implements this interface is a resource that * can be written to an OutputStream. */ public interface OutputStreamResource { /** * Writes a resource to an OutputStream. * @param os the OutputStream to which the XML is written. * @throws IOException usual exception when there's a problem writing to an OutputStream */ public void writeTo(OutputStream os) throws IOException; } src/rups/com/lowagie/rups/io/TextAreaOutputStream.java100644 0 0 4623 11000354133 20542 0ustar 0 0 /* * $Id: TextAreaOutputStream.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.io; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import javax.swing.JTextArea; /** * Everything writing to this OutputStream will be shown in a JTextArea. */ public class TextAreaOutputStream extends OutputStream { /** The text area to which we want to write. */ protected JTextArea text; /** Keeps track of the offset of the text in the text area. */ protected int offset; /** * Constructs a TextAreaOutputStream. * @param text the text area to which we want to write. * @throws IOException */ public TextAreaOutputStream(JTextArea text) throws IOException { this.text = text; clear(); } /** * Clear the text area. */ public void clear() { text.setText(null); offset = 0; } /** * @see java.io.OutputStream#write(int) */ @Override public void write(int i) throws IOException { byte[] b = { (byte)i }; write(b, 0, 1); } /** * @see java.io.OutputStream#write(byte[], int, int) */ @Override public void write(byte[] b, int off, int len) throws IOException { String snippet = new String(b, off, len); text.insert(snippet, offset); offset += len - off; } /** * @see java.io.OutputStream#write(byte[]) */ @Override public void write(byte[] b) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(b); byte[] snippet = new byte[1024]; int bytesread; while ((bytesread = bais.read(snippet)) > 0) { write(snippet, 0, bytesread); } } } src/rups/com/lowagie/rups/io/filters/PdfFilter.java100644 0 0 1452 11000663663 17767 0ustar 0 0 package com.lowagie.rups.io.filters; import java.io.File; import javax.swing.filechooser.FileFilter; /** * Filters PDF files in a JFileChooser. */ public class PdfFilter extends FileFilter { /** A public instance of the PdfFilter. */ public static final PdfFilter INSTANCE = new PdfFilter(); /** * * @see javax.swing.filechooser.FileFilter#accept(java.io.File) * @param f File * @return boolean */ public boolean accept(File f) { if (f.isDirectory()) return true; if (f.getName().toLowerCase().endsWith(".pdf")) return true; return false; } /** * * @see javax.swing.filechooser.FileFilter#getDescription() * @return String */ public String getDescription() { return "*.pdf PDF files"; } } src/rups/com/lowagie/rups/model/BackgroundTask.java100644 0 0 5716 11000354131 20025 0ustar 0 0 /* * $Id: BackgroundTask.java 3146 2008-02-20 18:10:07Z blowagie $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import javax.swing.SwingUtilities; /** * Allows you to perform long lasting tasks in background. * If we ever move to Java 6, we should use the SwingWorker class * (included in the JDK) instead of this custom Event Dispatching * code. */ public abstract class BackgroundTask { /** * Inner class that holds the reference to the thread. */ private static class ThreadWrapper { private Thread thread; ThreadWrapper(Thread t) { thread = t; } synchronized Thread get() { return thread; } synchronized void clear() { thread = null; } } /** A wrapper for the tread that executes a time-consuming task. */ private ThreadWrapper thread; /** * Starts a thread. * Executes the time-consuming task in the construct method; * finally calls the finish(). */ public BackgroundTask() { final Runnable doFinished = new Runnable() { public void run() { finished(); } }; Runnable doConstruct = new Runnable() { public void run() { try { doTask(); } finally { thread.clear(); } SwingUtilities.invokeLater(doFinished); } }; Thread t = new Thread(doConstruct); thread = new ThreadWrapper(t); } /** * Implement this class; the time-consuming task will go here. */ public abstract void doTask(); /** * Starts the thread. */ public void start() { Thread t = thread.get(); if (t != null) { t.start(); } } /** * Forces the thread to stop what it's doing. */ public void interrupt() { Thread t = thread.get(); if (t != null) { t.interrupt(); } thread.clear(); } /** * Called on the event dispatching thread once the * construct method has finished its task. */ public void finished() { } } src/rups/com/lowagie/rups/model/IndirectObjectFactory.java100644 0 0 12671 11000354131 21361 0ustar 0 0 /* * $Id: IndirectObjectFactory.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.util.ArrayList; import com.lowagie.text.pdf.IntHashtable; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNull; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; /** * A factory that can produce all the indirect objects in a PDF file. */ public class IndirectObjectFactory { /** The reader object. */ protected PdfReader reader; /** The current xref number. */ protected int current; /** The highest xref number. */ protected int n; /** A list of all the indirect objects in a PDF file. */ protected ArrayList objects = new ArrayList(); /** Mapping between the index in the objects list and the reference number in the xref table. */ protected IntHashtable idxToRef = new IntHashtable(); /** Mapping between the reference number in the xref table and the index in the objects list . */ protected IntHashtable refToIdx = new IntHashtable(); /** * Creates a list that will contain all the indirect objects * in a PDF document. * @param reader the reader that will read the PDF document */ public IndirectObjectFactory(PdfReader reader) { this.reader = reader; current = -1; n = reader.getXrefSize(); } /** * Gets the last object that has been registered. * This method only makes sense while loading the factory. * with loadNextObject(). * @return the number of the last object that was stored */ public int getCurrent() { return current; } /** * Gets the highest possible object number in the XRef table. * @return an object number */ public int getXRefMaximum() { return n; } /** * Stores the next object of the XRef table. * As soon as this method returns false, it makes no longer * sense calling it as all the objects have been stored. * @return false if there are no objects left to check. */ public boolean storeNextObject() { while (current < n) { current++; PdfObject object = reader.getPdfObjectRelease(current); if (object != null) { int idx = size(); idxToRef.put(idx, current); refToIdx.put(current, idx); store(object); return true; } } return false; } /** * If we store all the objects, we might run out of memory; * that's why we'll only store the objects that are necessary * to construct other objects (for instance the page table). * @param object an object we might want to store */ private void store(PdfObject object) { if (object.isDictionary()){ PdfDictionary dict = (PdfDictionary)object; if (PdfName.PAGE.equals(dict.get(PdfName.TYPE))) { objects.add(dict); return; } } objects.add(PdfNull.PDFNULL); } /** * Gets the total number of indirect objects in the PDF file. * This isn't necessarily the same number as returned by getXRefMaximum(). * The PDF specification allows gaps between object numbers. * @return the total number of indirect objects in the PDF. */ public int size() { return objects.size(); } /** * Gets the index of an object based on its number in the xref table. * @param ref a number in the xref table * @return the index in the list of indirect objects */ public int getIndexByRef(int ref) { return refToIdx.get(ref); } /** * Gets the reference number in the xref table based on the index in the * indirect object list. * @param i the index of an object in the indirect object list * @return the corresponding reference number in the xref table */ public int getRefByIndex(int i) { return idxToRef.get(i); } /** * Gets an object based on its index in the indirect object list. * @param i an index in the indirect object list * @return a PDF object */ public PdfObject getObjectByIndex(int i) { return getObjectByReference(getRefByIndex(i)); } /** * Gets an object based on its reference number in the xref table. * @param ref a number in the xref table * @return a PDF object */ public PdfObject getObjectByReference(int ref) { return objects.get(getIndexByRef(ref)); } /** * Loads an object based on its reference number in the xref table. * @param ref a reference number in the xref table. * @return a PDF object */ public PdfObject loadObjectByReference(int ref) { PdfObject object = getObjectByReference(ref); if (object instanceof PdfNull) { int idx = getIndexByRef(ref); object = reader.getPdfObject(ref); objects.set(idx, object); } return object; } } src/rups/com/lowagie/rups/model/ObjectLoader.java100644 0 0 5412 11000354131 17451 0ustar 0 0 /* * $Id: ObjectLoader.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.util.Observable; import com.lowagie.text.pdf.PdfReader; /** * Loads the necessary iText PDF objects in Background. */ public class ObjectLoader extends BackgroundTask { /** This is the object that will forward the updates to the observers. */ protected Observable observable; /** iText's PdfReader object. */ protected PdfReader reader; /** The factory that can provide PDF objects. */ protected IndirectObjectFactory objects; /** The factory that can provide tree nodes. */ protected TreeNodeFactory nodes; /** * Creates a new ObjectLoader. * @param observable the object that will forward the changes. * @param reader the PdfReader from which the objects will be read. */ public ObjectLoader(Observable observable, PdfReader reader) { this.observable = observable; this.reader = reader; start(); } /** * Getter for the PdfReader object. * @return a reader object */ public PdfReader getReader() { return reader; } /** * Getter for the object factory. * @return an indirect object factory */ public IndirectObjectFactory getObjects() { return objects; } /** * Getter for the tree node factory. * @return a tree node factory */ public TreeNodeFactory getNodes() { return nodes; } /** * @see com.lowagie.rups.model.BackgroundTask#doTask() */ @Override public void doTask() { ProgressDialog progress = new ProgressDialog(null, "Reading PDF file"); objects = new IndirectObjectFactory(reader); int n = objects.getXRefMaximum(); progress.setMessage("Reading the Cross-Reference table"); progress.setTotal(n); while (objects.storeNextObject()) { progress.setValue(objects.getCurrent()); } progress.setTotal(0); nodes = new TreeNodeFactory(objects); progress.setMessage("Updating GUI"); observable.notifyObservers(this); progress.dispose(); } }src/rups/com/lowagie/rups/model/PageLoader.java100644 0 0 5113 11000354131 17115 0ustar 0 0 /* * $Id: PageLoader.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import com.sun.pdfview.PDFFile; import com.sun.pdfview.PDFPage; /** * Loads all the PDFPage objects for SUN's PDF Renderer * in Background. */ public class PageLoader extends BackgroundTask { /** The PDFFile (SUN's PDF Renderer class) */ protected PDFFile file; /** The total number of pages. */ protected int numberOfPages; /** True for pages with page number equal to index + 1 that are being loaded. */ protected boolean[] busy; /** True for pages with page number equal to index + 1 that have already been loaded. */ protected boolean[] done; /** * Creates a new page loader. * @param file the PDFFile (SUN's PDF Renderer) */ public PageLoader(PDFFile file) { super(); this.file = file; numberOfPages = file.getNumPages(); busy = new boolean[numberOfPages]; done = new boolean[numberOfPages]; start(); } /** * Getter for the number of pages. * @return the number of pages in the PDF file. */ public int getNumberOfPages() { return numberOfPages; } /** * Loads a page. * @param pageNumber the number of the page that has to be loaded. * @return the PDFPage that has been loaded. */ public synchronized PDFPage loadPage(int pageNumber) { pageNumber--; if (busy[pageNumber]) return null; busy[pageNumber] = true; PDFPage page = file.getPage(pageNumber + 1, true); if (!done[pageNumber]) { System.out.println("Loading page " + (pageNumber + 1)); } done[pageNumber] = true; busy[pageNumber] = false; return page; } /** * @see com.lowagie.rups.model.BackgroundTask#doTask() */ @Override public void doTask() { for (int i = 0; i < numberOfPages; i++) { loadPage(i + 1); } } } src/rups/com/lowagie/rups/model/PdfFile.java100644 0 0 12355 11154165267 16475 0ustar 0 0 /* * $Id: PdfFile.java 3662 2009-01-26 20:54:49Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import com.lowagie.text.DocumentException; import com.lowagie.text.exceptions.BadPasswordException; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.RandomAccessFileOrArray; import com.sun.pdfview.PDFFile; /** * Wrapper for both iText's PdfReader (referring to a PDF file to read) * and SUN's PDFFile (referring to the same PDF file to render). */ public class PdfFile { // member variables /** The directory where the file can be found (if the PDF was passed as a file). */ protected File directory = null; /** The original filename. */ protected String filename = null; /** The PdfReader object. */ protected PdfReader reader = null; /** SUN's PDFFile object. */ protected PDFFile PDFFile = null; /** The file permissions */ protected Permissions permissions = null; // constructors /** * Constructs a PdfFile object. * @param file the File to read * @throws IOException * @throws DocumentException */ public PdfFile(File file) throws IOException, DocumentException { if (file == null) throw new IOException("No file selected."); RandomAccessFileOrArray pdf = new RandomAccessFileOrArray(file.getAbsolutePath()); directory = file.getParentFile(); filename = file.getName(); readFile(pdf); } /** * Constructs a PdfFile object. * @param file the byte[] to read * @throws IOException * @throws DocumentException */ public PdfFile(byte[] file) throws IOException, DocumentException { RandomAccessFileOrArray pdf = new RandomAccessFileOrArray(file); readFile(pdf); } /** * Does the actual reading of the file into PdfReader and PDFFile. * @param pdf a Random Access File or Array * @throws IOException * @throws DocumentException */ protected void readFile(RandomAccessFileOrArray pdf) throws IOException, DocumentException { // reading the file into PdfReader permissions = new Permissions(); try { reader = new PdfReader(pdf, null); permissions.setEncrypted(false); } catch(BadPasswordException bpe) { JPasswordField passwordField = new JPasswordField(32); JOptionPane.showConfirmDialog(null, passwordField, "Enter the User or Owner Password of this PDF file", JOptionPane.OK_CANCEL_OPTION); byte[] password = new String(passwordField.getPassword()).getBytes(); reader = new PdfReader(pdf, password); permissions.setEncrypted(true); permissions.setCryptoMode(reader.getCryptoMode()); permissions.setPermissions(reader.getPermissions()); if (reader.isOpenedWithFullPermissions()) { permissions.setOwnerPassword(password); permissions.setUserPassword(reader.computeUserPassword()); } else { throw new IOException("You need the owner password of this file to open it in iText Trapeze."); } } // if the file is encrypted, make a temporary copy if (permissions.isEncrypted()) { pdf = workAround(); } // reading the file into SUN's PDFFile pdf.reOpen(); try { PDFFile = new PDFFile(pdf.getNioByteBuffer()); } catch(IOException ioe) { PDFFile = new PDFFile(workAround().getNioByteBuffer()); } pdf.close(); } protected RandomAccessFileOrArray workAround() throws DocumentException, IOException { if (directory == null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfStamper stamper = new PdfStamper(reader, baos); stamper.close(); return new RandomAccessFileOrArray(baos.toByteArray()); } else { File temp = File.createTempFile(filename.substring(0, filename.lastIndexOf(".pdf")) + "~", ".pdf", directory); temp.deleteOnExit(); FileOutputStream fos = new FileOutputStream(temp); PdfStamper stamper = new PdfStamper(reader, fos); stamper.close(); return new RandomAccessFileOrArray(temp.getAbsolutePath()); } } /** * Getter for iText's PdfReader object. * @return a PdfReader object */ public PdfReader getPdfReader() { return reader; } /** * Getter for SUN's PDFFile object (for the renderer) * @return a PDFFile object */ public PDFFile getPDFFile() { return PDFFile; } }src/rups/com/lowagie/rups/model/Permissions.java100644 0 0 12470 11000354131 17451 0ustar 0 0 /* * $Id: Permissions.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import com.lowagie.text.pdf.PdfWriter; /** * This class can tell you more about the permissions that are allowed * on the PDF file. */ public class Permissions { /** Was the file encrypted? */ protected boolean encrypted = true; /** Which owner password was provided to open the file? */ protected byte[] ownerPassword = null; /** What is the user password? */ protected byte[] userPassword = null; /** What are the document permissions? */ protected int permissions = 0; /** How was the document encrypted? */ protected int cryptoMode = 0; /** * Tells you if the document was encrypted. * @return true is the document was encrypted */ public boolean isEncrypted() { return encrypted; } /** * Setter for the encrypted variable. * @param encrypted set this to true if the document was encrypted */ public void setEncrypted(boolean encrypted) { this.encrypted = encrypted; } /** * Returns the owner password of the PDF file (if any). * @return the owner password that was provided upon opening the document */ public byte[] getOwnerPassword() { return ownerPassword; } /** * Setter for the owner password. * @param ownerPassword the owner password */ public void setOwnerPassword(byte[] ownerPassword) { this.ownerPassword = ownerPassword; } /** * Returns the user password (if any). * @return the user password */ public byte[] getUserPassword() { return userPassword; } /** * Setter for the user password. * @param userPassword the user password of a PDF file */ public void setUserPassword(byte[] userPassword) { this.userPassword = userPassword; } /** * Returns the permissions in the form of an int (each bit is a specific permission) * @return the value for the permissions */ public int getPermissions() { return permissions; } /** * Setter for the permissions. * @param permissions the permissions in the form of an int */ public void setPermissions(int permissions) { this.permissions = permissions; } /** * Returns the crypto mode. * @return the crypto mode */ public int getCryptoMode() { return cryptoMode; } /** * Setter for the crypto mode * @param cryptoMode the crypto mode */ public void setCryptoMode(int cryptoMode) { this.cryptoMode = cryptoMode; } /** * Tells you if printing is allowed. * @return true if printing is allowed */ public boolean isAllowPrinting() { return !encrypted || (PdfWriter.ALLOW_PRINTING & permissions) == PdfWriter.ALLOW_PRINTING; } /** * Tells you if modifying the contents is allowed. * @return true if modifying contents is allowed */ public boolean isAllowModifyContents(boolean decrypted) { return !encrypted || (PdfWriter.ALLOW_MODIFY_CONTENTS & permissions) == PdfWriter.ALLOW_MODIFY_CONTENTS; } /** * Tells you if copying is allowed. * @return true if copying is allowed */ public boolean isAllowCopy(boolean decrypted) { return !encrypted || (PdfWriter.ALLOW_COPY & permissions) == PdfWriter.ALLOW_COPY; } /** * Tells you if modifying annotations is allowed * @return true if modifying annotations is allowed */ public boolean isAllowModifyAnnotations() { return !encrypted || (PdfWriter.ALLOW_MODIFY_ANNOTATIONS & permissions) == PdfWriter.ALLOW_MODIFY_ANNOTATIONS; } /** * Tells you if filling in forms is allowed. * @return true if filling in forms is allowed */ public boolean isAllowFillIn() { return !encrypted || (PdfWriter.ALLOW_FILL_IN & permissions) == PdfWriter.ALLOW_FILL_IN; } /** * Tells you if modifying the layout for screenreaders is allowed. * @return true if modifying the layout for screenreaders is allowed */ public boolean isAllowScreenReaders() { return !encrypted || (PdfWriter.ALLOW_SCREENREADERS & permissions) == PdfWriter.ALLOW_SCREENREADERS; } /** * Tells you if document assembly is allowed. * @return true if document assembly is allowed */ public boolean isAllowAssembly() { return !encrypted || (PdfWriter.ALLOW_ASSEMBLY & permissions) == PdfWriter.ALLOW_ASSEMBLY; } /** * Tells you if degraded printing is allowed. * @return true if degraded printing is allowed */ public boolean isAllowDegradedPrinting() { return !encrypted || (PdfWriter.ALLOW_DEGRADED_PRINTING & permissions) == PdfWriter.ALLOW_DEGRADED_PRINTING; } }src/rups/com/lowagie/rups/model/ProgressDialog.java100644 0 0 6755 11000354131 20053 0ustar 0 0 /* * $Id: ProgressDialog.java 3146 2008-02-20 18:10:07Z blowagie $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JProgressBar; import javax.swing.UIManager; /** * An informational dialog window showing the progress of a certain action. */ public class ProgressDialog extends JDialog { /** a serial version uid. */ private static final long serialVersionUID = -8286949678008659120L; /** label showing the message describing what's in progress. */ protected JLabel message; /** the progress bar */ protected JProgressBar progress; /** the icon used for this dialog box. */ public static final JLabel INFO = new JLabel(UIManager.getIcon("OptionPane.informationIcon")); /** * Creates a Progress frame displaying a certain message * and a progress bar in indeterminate mode. * @param parent the parent frame of this dialog (used to position the dialog) * @param msg the message that will be displayed. */ public ProgressDialog(JFrame parent, String msg) { super(); this.setTitle("Progress..."); setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); setSize(300, 100); this.setLocationRelativeTo(parent); setLayout(new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = 0; constraints.gridy = 0; constraints.gridheight = 2; getContentPane().add(INFO, constraints); constraints.gridheight = 1; constraints.gridx = 1; constraints.insets = new Insets(5, 5, 5, 5); message = new JLabel(msg); getContentPane().add(message, constraints); constraints.gridy = 1; progress = new JProgressBar(); progress.setIndeterminate(true); getContentPane().add(progress, constraints); setVisible(true); } /** * Changes the message describing what's in progress * @param msg the message describing what's in progress */ public void setMessage(String msg) { message.setText(msg); } /** * Changes the value of the progress bar. * @param value the current value */ public void setValue(int value) { progress.setValue(value); } /** * Sets the maximum value for the progress bar. * If 0 or less, sets the progress bar to indeterminate mode. * @param n the maximum value for the progress bar */ public void setTotal(int n) { if (n > 0) { progress.setMaximum(n); progress.setIndeterminate(false); progress.setStringPainted(true); } else { progress.setIndeterminate(true); progress.setStringPainted(false); } } } src/rups/com/lowagie/rups/model/TreeNodeFactory.java100644 0 0 11703 11154165267 20215 0ustar 0 0 /* * $Id: TreeNodeFactory.java 3735 2009-02-26 01:44:03Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfPagesTreeNode; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfIndirectReference; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNull; import com.lowagie.text.pdf.PdfObject; /** * A factory that creates TreeNode objects corresponding with PDF objects. */ public class TreeNodeFactory { /** The factory that can produce all indirect objects. */ protected IndirectObjectFactory objects; /** An list containing the nodes of every indirect object. */ protected ArrayList nodes = new ArrayList(); /** * Creates a factory that can produce TreeNode objects * corresponding with PDF objects. * @param objects a factory that can produce all the indirect objects of a PDF file. */ public TreeNodeFactory(IndirectObjectFactory objects) { this.objects = objects; for (int i = 0; i < objects.size(); i++) { int ref = objects.getRefByIndex(i); nodes.add(PdfObjectTreeNode.getInstance(PdfNull.PDFNULL, ref)); } } /** * Gets a TreeNode for an indirect objects. * @param ref the reference number of the indirect object. * @return the TreeNode representing the PDF object */ public PdfObjectTreeNode getNode(int ref) { int idx = objects.getIndexByRef(ref); PdfObjectTreeNode node = nodes.get(idx); if (node.getPdfObject().isNull()) { node = PdfObjectTreeNode.getInstance(objects.loadObjectByReference(ref), ref); nodes.set(idx, node); } return node; } /** * Creates the Child TreeNode objects for a PDF object TreeNode. * @param node the parent node */ public void expandNode(PdfObjectTreeNode node) { if (node.getChildCount() > 0) { return; } PdfObject object = node.getPdfObject(); PdfObjectTreeNode leaf; switch (object.type()) { case PdfObject.INDIRECT: PdfIndirectReference ref = (PdfIndirectReference)object; leaf = getNode(ref.getNumber()); addNodes(node, leaf); if (leaf instanceof PdfPagesTreeNode) expandNode(leaf); return; case PdfObject.ARRAY: PdfArray array = (PdfArray)object; for (Iterator it = array.listIterator(); it.hasNext(); ) { leaf = PdfObjectTreeNode.getInstance((PdfObject)it.next()); addNodes(node, leaf); expandNode(leaf); } return; case PdfObject.DICTIONARY: case PdfObject.STREAM: PdfDictionary dict = (PdfDictionary)object; for (Iterator it = dict.getKeys().iterator(); it.hasNext(); ) { leaf = PdfObjectTreeNode.getInstance(dict, (PdfName)it.next()); addNodes(node, leaf); expandNode(leaf); } return; } } /** * Finds a specific child of dictionary node. * @param node the node with a dictionary among its children * @param key the key of the item corresponding with the node we need */ public PdfObjectTreeNode getChildNode(PdfObjectTreeNode node, PdfName key) { Enumeration children = node.breadthFirstEnumeration(); PdfObjectTreeNode child; while (children.hasMoreElements()) { child = (PdfObjectTreeNode)children.nextElement(); if (child.isDictionaryNode(key)) { if (child.isIndirectReference()) { expandNode(child); child = (PdfObjectTreeNode)child.getFirstChild(); } expandNode(child); return child; } } return null; } /** * Tries adding a child node to a parent node without * throwing an exception. Normally, if the child node is already * added as one of the ancestors, an IllegalArgumentException is * thrown (to avoid an endless loop). Loops like this are allowed * in PDF, not in a JTree. * @param parent the parent node * @param child a child node */ private void addNodes(PdfObjectTreeNode parent, PdfObjectTreeNode child) { try { parent.add(child); } catch(IllegalArgumentException iae) { parent.setRecursive(true); } } } src/rups/com/lowagie/rups/model/XfaFile.java100644 0 0 5257 11000354131 16441 0ustar 0 0 /* * $Id: XfaFile.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.model; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import com.lowagie.rups.io.OutputStreamResource; /** Class that deals with the XFA file that can be inside a PDF file. */ public class XfaFile implements OutputStreamResource { /** The X4J Document object (XML). */ protected Document xfaDocument; /** * Constructs an XFA file from an OutputStreamResource. * This resource can be an XML file or a node in a RUPS application. * @param resource the XFA resource * @throws IOException * @throws DocumentException */ public XfaFile(OutputStreamResource resource) throws IOException, DocumentException { // Is there a way to avoid loading everything in memory? // Can we somehow get the XML from the PDF as an InputSource, Reader or InputStream? ByteArrayOutputStream baos = new ByteArrayOutputStream(); resource.writeTo(baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); SAXReader reader = new SAXReader(); xfaDocument = reader.read(bais); } /** * Getter for the XFA Document object. * @return a Document object (X4J) */ public Document getXfaDocument() { return xfaDocument; } /** * Writes a formatted XML file to the OutputStream. * @see com.lowagie.rups.io.OutputStreamResource#writeTo(java.io.OutputStream) */ public void writeTo(OutputStream os) throws IOException { if (xfaDocument == null) return; OutputFormat format = new OutputFormat(" ", true); XMLWriter writer = new XMLWriter(os, format); writer.write(xfaDocument); } } src/rups/com/lowagie/rups/view/Console.java100644 0 0 15753 11000663663 16436 0ustar 0 0 /* * $Id: Console.java 3242 2008-04-13 23:00:20Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view; import java.awt.Color; import java.io.IOException; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.io.PrintStream; import java.util.Observable; import java.util.Observer; import javax.swing.JTextPane; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.Document; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; /** * A Class that redirects everything written to System.out and System.err * to a JTextPane. */ public class Console implements Observer { /** Single Console instance. */ private static Console console = null; /** Custom PrintStream. */ PrintStream printStream; /** Custom OutputStream. */ PipedOutputStream poCustom; /** Custom InputStream. */ PipedInputStream piCustom; /** OutputStream for System.out. */ PipedOutputStream poOut; /** InputStream for System.out. */ PipedInputStream piOut; /** OutputStream for System.err. */ PipedOutputStream poErr; /** InputStream for System.err. */ PipedInputStream piErr; /** The StyleContext for the Console. */ ConsoleStyleContext styleContext = new ConsoleStyleContext(); /** The text area to which everything is written. */ JTextPane textArea = new JTextPane(new DefaultStyledDocument(styleContext)); /** * Creates a new Console object. * @throws IOException */ private Console() throws IOException { // Set up Custom piCustom = new PipedInputStream(); poCustom = new PipedOutputStream(); printStream = new PrintStream(poCustom); // Set up System.out piOut = new PipedInputStream(); poOut = new PipedOutputStream(piOut); System.setOut(new PrintStream(poOut, true)); // Set up System.err piErr = new PipedInputStream(); poErr = new PipedOutputStream(piErr); System.setErr(new PrintStream(poErr, true)); // Add a scrolling text area textArea.setEditable(false); // Create reader threads new ReadWriteThread(piCustom, ConsoleStyleContext.CUSTOM).start(); new ReadWriteThread(piOut, ConsoleStyleContext.SYSTEMOUT).start(); new ReadWriteThread(piErr, ConsoleStyleContext.SYSTEMERR).start(); } /** * Console is a Singleton class: you can only get one Console. */ public static synchronized Console getInstance() { if (console == null) { try { console = new Console(); } catch (IOException e) { console = null; } } return console; } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (RupsMenuBar.CLOSE.equals(obj)) { textArea.setText(""); } if (RupsMenuBar.OPEN.equals(obj)) { textArea.setText(""); } } /** * Allows you to print something to the custom PrintStream. * @param s the message you want to send to the Console */ public static void println(String s) { PrintStream ps = getInstance().getPrintStream(); if (ps == null) { System.out.println(s); } else { ps.println(s); ps.flush(); } } /** * Get the custom PrintStream of the console. */ public PrintStream getPrintStream() { return printStream; } /** * Get the JTextArea to which everything is written. */ public JTextPane getTextArea() { return textArea; } /** * The thread that will write everything to the text area. */ class ReadWriteThread extends Thread { /** The InputStream of this Thread */ PipedInputStream pi; /** The type (CUSTOM, SYSTEMOUT, SYSTEMERR) of this Thread */ String type; /** Create the ReaderThread. */ ReadWriteThread(PipedInputStream pi, String type) { super(); this.pi = pi; this.type = type; } /** * @see java.lang.Thread#run() */ public void run() { final byte[] buf = new byte[1024]; while (true) { try { final int len = pi.read(buf); if (len == -1) { break; } Document doc = textArea.getDocument(); AttributeSet attset = styleContext.getStyle(type); String snippet = new String(buf, 0, len); doc.insertString(doc.getLength(), snippet, attset); printStream.print(snippet); textArea.setCaretPosition(textArea.getDocument(). getLength()); } catch (BadLocationException ex) { } catch (IOException e) { } } } } /** * The style context defining the styles of each type of PrintStream. */ class ConsoleStyleContext extends StyleContext { /** A Serial Version UID. */ private static final long serialVersionUID = 7253870053566811171L; /** The name of the Style used for Custom messages */ public static final String CUSTOM = "Custom"; /** The name of the Style used for System.out */ public static final String SYSTEMOUT = "SystemOut"; /** The name of the Style used for System.err */ public static final String SYSTEMERR = "SystemErr"; /** Creates the style context for the Console. */ public ConsoleStyleContext() { super(); Style root = getStyle(DEFAULT_STYLE); Style s = addStyle(CUSTOM, root); StyleConstants.setForeground(s, Color.BLACK); s = addStyle(SYSTEMOUT, root); StyleConstants.setForeground(s, Color.GREEN); s = addStyle(SYSTEMERR, root); StyleConstants.setForeground(s, Color.RED); } } } src/rups/com/lowagie/rups/view/MessageAction.java100644 0 0 3340 11000354136 17513 0ustar 0 0 /* * $Id: MessageAction.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import com.lowagie.rups.Rups; import com.lowagie.text.Document; public class MessageAction implements ActionListener { public void actionPerformed(ActionEvent evt) { String message = "Unspecified message"; if (RupsMenuBar.ABOUT.equals(evt.getActionCommand())) { message = "RUPS is a tool by lowagie.com.\nIt uses iText, a Free Java-PDF Library\nand SUN's PDF Renderer.\nVisit http://www.lowagie.com/iText/ for more info."; } else if (RupsMenuBar.VERSIONS.equals(evt.getActionCommand())) { message = "RUPS version String: " + Rups.VERSION + "\niText version String: " + Document.getVersion() + "\nSUN's PDF Renderer version: version unknown"; } JOptionPane.showMessageDialog(null, message); } } src/rups/com/lowagie/rups/view/PageNavigationAction.java100644 0 0 6163 11000354136 21031 0ustar 0 0 /* * $Id: PageNavigationAction.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view; import java.awt.event.ActionEvent; import javax.swing.Icon; import com.lowagie.rups.view.icons.IconActionListener; import com.lowagie.rups.view.icons.IconFetcher; /** * Class that can be used for some basic navigation actions. * Each action also has a corresponding icon. */ public class PageNavigationAction implements IconActionListener { /** Type to go to the first page. */ public static final int FIRST_PAGE = 1; /** Type to go to the previous page. */ public static final int PREVIOUS_PAGE = 2; /** Type to go to the next page. */ public static final int NEXT_PAGE = 3; /** Type to go to the last page. */ public static final int LAST_PAGE = 4; /** The type of this action. */ protected int type; /** The object that is listening to the page navigation. */ protected PageNavigationListener listener; /** The icon corresponding with the action. */ protected Icon icon = null; /** * Creates a page navigation action. * @param listener the object listening to the page navigation * @param type the type of action * @param withIcon if false, no icon will be attached to the action */ public PageNavigationAction(PageNavigationListener listener, int type, boolean withIcon) { super(); this.listener = listener; this.type = type; if (withIcon) { switch(type) { case FIRST_PAGE: icon = IconFetcher.getIcon("navigation_first.png"); break; case PREVIOUS_PAGE: icon = IconFetcher.getIcon("navigation_previous.png"); break; case NEXT_PAGE: icon = IconFetcher.getIcon("navigation_next.png"); break; case LAST_PAGE: icon = IconFetcher.getIcon("navigation_last.png"); break; } } } /** * @see com.lowagie.rups.view.icons.IconActionListener#getIcon() */ public Icon getIcon() { return icon; } /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent evt) { switch(type) { case FIRST_PAGE: listener.gotoFirstPage(); return; case PREVIOUS_PAGE: listener.gotoPreviousPage(); return; case NEXT_PAGE: listener.gotoNextPage(); return; case LAST_PAGE: listener.gotoLastPage(); return; } } } src/rups/com/lowagie/rups/view/PageNavigationListener.java100644 0 0 4743 11000354136 21403 0ustar 0 0 /* * $Id: PageNavigationListener.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view; /** * Interface that has to be implemented by every class that listens * to page navigation features; keys that are pressed, buttons that * are pushed,... */ public interface PageNavigationListener { /** * Returns the total number of pages in a document. * @return the total number of pages in a document. */ public int getTotalNumberOfPages(); /** * Returns the current page number of a document. * @return the current page number. */ public int getCurrentPageNumber(); /** * Goes to the first page in a document. * @return the resulting page number. * Can be different from 1 if the document is null */ public int gotoFirstPage(); /** * Goes to the previous page in a document. * @return the resulting page number. * Can be different from (current page - 1) if the document is null * or the current page = 1. */ public int gotoPreviousPage(); /** * Goes to a specific page number in a document. * @param pageNumber * @return the resulting page number. * Can be different from pageNumber if pageNumber doesn't exist. */ public int gotoPage(int pageNumber); /** * Goes to the previous page in a document. * @return the resulting page number. * Can be different from (current page + 1) if the document is null * or the current page equals the total number of pages. */ public int gotoNextPage(); /** * Goes to the last page in a document. * @return the resulting page number. * Can be different from the total number of pages if the document is null */ public int gotoLastPage(); } src/rups/com/lowagie/rups/view/RupsMenuBar.java100644 0 0 10316 11000354136 17215 0ustar 0 0 /* * $Id: RupsMenuBar.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view; import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Observable; import java.util.Observer; import javax.swing.Box; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import com.lowagie.rups.io.FileChooserAction; import com.lowagie.rups.io.FileCloseAction; import com.lowagie.rups.io.filters.PdfFilter; public class RupsMenuBar extends JMenuBar implements Observer { /** Caption for the file menu. */ public static final String FILE_MENU = "File"; /** Caption for "Open file". */ public static final String OPEN = "Open"; /** Caption for "Close file". */ public static final String CLOSE = "Close"; /** Caption for the help menu. */ public static final String HELP_MENU = "Help"; /** Caption for "Help about". */ public static final String ABOUT = "About"; /** Caption for "Help versions". */ public static final String VERSIONS = "Versions"; /** The Observable object. */ protected Observable observable; /** The action needed to open a file. */ protected FileChooserAction fileChooserAction; /** The HashMap with all the actions. */ protected HashMap items; /** * Creates a JMenuBar. * @param observable the controller to which this menu bar is added */ public RupsMenuBar(Observable observable) { this.observable = observable; items = new HashMap(); fileChooserAction = new FileChooserAction(observable, "Open", PdfFilter.INSTANCE, false); MessageAction message = new MessageAction(); JMenu file = new JMenu(FILE_MENU); addItem(file, OPEN, fileChooserAction); addItem(file, CLOSE, new FileCloseAction(observable)); add(file); add(Box.createGlue()); JMenu help = new JMenu(HELP_MENU); addItem(help, ABOUT, message); addItem(help, VERSIONS, message); add(help); enableItems(false); } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (OPEN.equals(obj)) { enableItems(true); return; } if (CLOSE.equals(obj)) { enableItems(false); return; } if (FILE_MENU.equals(obj)) { fileChooserAction.actionPerformed(null); } } /** * Create an item with a certain caption and a certain action, * then add the item to a menu. * @param menu the menu to which the item has to be added * @param caption the caption of the item * @param action the action corresponding with the caption */ protected void addItem(JMenu menu, String caption, ActionListener action) { JMenuItem item = new JMenuItem(caption); item.addActionListener(action); menu.add(item); items.put(caption, item); } /** * Enables/Disables a series of menu items. * @param enabled true for enabling; false for disabling */ protected void enableItems(boolean enabled) { enableItem(CLOSE, enabled); } /** * Enables/disables a specific menu item * @param caption the caption of the item that needs to be enabled/disabled * @param enabled true for enabling; false for disabling */ protected void enableItem(String caption, boolean enabled) { items.get(caption).setEnabled(enabled); } /** A Serial Version UID. */ private static final long serialVersionUID = 6403040037592308742L; }src/rups/com/lowagie/rups/view/icons/IconActionListener.java100644 0 0 2234 11000354135 21640 0ustar 0 0 /* * $Id: IconActionListener.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.icons; import java.awt.event.ActionListener; import javax.swing.Icon; /** * Special ActionListener to be implemented by Buttons that need an Icon. */ public interface IconActionListener extends ActionListener { /** Returns an Icon. */ public Icon getIcon(); } src/rups/com/lowagie/rups/view/icons/IconButton.java100644 0 0 2532 11000354135 20171 0ustar 0 0 /* * $Id: IconButton.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.icons; import javax.swing.JButton; /** * JButton with an Icon that performs an Action if you push it. */ public class IconButton extends JButton { /** * Creates a button with an Icon that performs an * action when you push it. */ public IconButton(IconActionListener listener) { super(listener.getIcon()); addActionListener(listener); } /** A Serial Version UID. */ private static final long serialVersionUID = 3523016393512117003L; } src/rups/com/lowagie/rups/view/icons/IconFetcher.java100644 0 0 3301 11000354135 20271 0ustar 0 0 /* * $Id: IconFetcher.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.icons; import java.util.HashMap; import javax.swing.Icon; import javax.swing.ImageIcon; /** * Class that fetches the icons in com.lowagie.trapeze.icons. */ public class IconFetcher { /** Cache with icons. */ protected static HashMap cache = new HashMap(); /** * Gets an Icon with a specific name. * @param filename the filename of the Icon. * @return an Icon */ public static Icon getIcon(String filename) { if (filename == null) { return null; } Icon icon = cache.get(filename); if (icon == null) { try { icon = new ImageIcon(IconFetcher.class.getResource(filename)); cache.put(filename, icon); } catch(Exception e) { System.err.println("Can't find file: " + filename); return null; } } return icon; } } src/rups/com/lowagie/rups/view/icons/IconTreeCellRenderer.java100644 0 0 3435 11000354135 22107 0ustar 0 0 /* * $Id: IconTreeCellRenderer.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.icons; import java.awt.Component; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellRenderer; /** * Renders the tree cells with the correct icon. */ public class IconTreeCellRenderer extends DefaultTreeCellRenderer { /** a serial version UID. */ private static final long serialVersionUID = 6513462839504342074L; /** * @see javax.swing.tree.DefaultTreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean) */ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); if (value instanceof IconTreeNode) { IconTreeNode node = (IconTreeNode) value; setIcon(node.getIcon()); } return this; } }src/rups/com/lowagie/rups/view/icons/IconTreeNode.java100644 0 0 3471 11000354135 20426 0ustar 0 0 /* * $Id: IconTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.icons; import javax.swing.Icon; import javax.swing.tree.DefaultMutableTreeNode; /** * A tree node with a specific icon. */ public class IconTreeNode extends DefaultMutableTreeNode { /** The icon that has to be used for this TreeNode. */ protected Icon icon; /** * Constructs an IconTreeNode. * @param icon the filename of the icon to use for this node. */ public IconTreeNode(String icon) { super(); this.icon = IconFetcher.getIcon(icon); } /** * Constructs an IconTreeNode. * @param icon the filename of the icon to use for this node. * @param userobject the userobject for this node */ public IconTreeNode(String icon, Object userobject) { super(userobject); this.icon = IconFetcher.getIcon(icon); } /** Getter for the icon. */ public Icon getIcon() { return icon; } /** A Serial Version UID. */ private static final long serialVersionUID = -5900308991182960842L; }src/rups/com/lowagie/rups/view/icons/array.png100644 0 0 545 11000354135 17050 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8c?%LdL0C`l _RR򿠠vv ###EIwUqgy?b=]{OwKuGss游숈;;;obb_WWj q5P /{tŋfKH3FFFUTT/$$?;;fff@ia+tDմm/-IENDB`src/rups/com/lowagie/rups/view/icons/attribute.png100644 0 0 433 11000354135 17731 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT81 q_ɦ xe:%2\(etW'9[%bRF^K6ó~ꩯ|\5ӒfR89E/cb.HVb v(y; 6*P(GtFOw>B1#C6K#G#O4P$ꃄsfV36 h7eo %cGY')O4˹@tmA,YiyGy%"~Kt.%԰-*zQai~\7''S43ZƱ~Or[f4MW˲jX,m1ֱmraȄ5 `:fU ˅ 0L=&(*ȭC=^^Db0PodǕS׹Reo\>=?Ď3ٓWpE?3F0`IENDB`src/rups/com/lowagie/rups/view/icons/form.png100644 0 0 723 11000354135 16673 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<eIDATNam> IF4H:aa189HJ   uS( 2:}~!$@6W6/'ڀ%RedLdLRba{9i_,u;+Ḳ{9}LZw&cu43 UmLe0c|cTRl2/n|yJ4 hT%GJQ(EXz=..bLRR)s-1  ˳u$Qiے|͍ U4vJUB{o}2%" ɀ\[]]c4aTчvS(Ef"l[$!+qYXB:b&l  :LIENDB`src/rups/com/lowagie/rups/view/icons/name.png100644 0 0 1412 11000354135 16664 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˥kW?wLdL&1 6Ѩ(hR,M!R;TA.\tm\ >VtZ΢043$BH|=/_>8U}T!su4-WNV8 (wOo^uŕr#ɞF֮`!r pzyeHnVZԜგ[C*³2??\S +K;EСzrc%5*cb]3_槻i4|vQ @hԎdÅ"@IzSlՒ,Ѿ1AֆFޟXq AǏd'bβE.r`o+)ȶ6P)G!wGCqnfG SJy8ux8q8+g~jnBs14({^&xqXxXƘ0 `~Mqrd;;?ln]-G "8:Z &V#_M_G_8T-y/LZOr_wnYf .m[/-q_1rdߪr^LJ&KӼ~-<]0(Œ1n+iU ' 4`)7 r珁s?w ?{Y!IENDB`src/rups/com/lowagie/rups/view/icons/navigation_first.png100644 0 0 1012 11000354135 21306 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8S;HBQoWaT8.9DmBju(ѥZh @DWwB4.8p|1Pj:=h9s@_muW#rlqP!UT̢V"тE8PƁ-dsiDŽ"[?*PHxMr =Mȗ(Z\@-@bn3hSYmu>)( _@:Gקx ;2(U"ϩ'4{u>f0Yl1{{Z!m r0}A3bMIR*\O-Bܮʺ,(IENDB`src/rups/com/lowagie/rups/view/icons/navigation_last.png100644 0 0 1014 11000354135 21124 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8œkQ7; *,E/A^TI%XX,,?H6ɨA QL&q>X&_q81)%v]j1W٫G ;E)}z>wOu{G%lj٘=*l__v$>lIENDB`src/rups/com/lowagie/rups/view/icons/navigation_next.png100644 0 0 613 11000354135 21123 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8c?%4~nv xf%e@gמx}Ë Sl@ނGWK_%<\dD`Z~'UKX#꺝([m/ػ@J:t6%y]Dr4JDo]x濨d%$1ED*뿀IENDB`src/rups/com/lowagie/rups/view/icons/navigation_previous.png100644 0 0 605 11000354135 22022 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8c?%.d~؞: Hy=i'ـw=?k^7I3 jyK;_B7.xܶMk'΀Λ>?uNj/ZxSOgcõSg_ɘcUpE=kkV>6… -%c-?ouKz4y]d}[Ev'+! [nY`俰d'eA ̄ЊOIENDB`src/rups/com/lowagie/rups/view/icons/null.png100644 0 0 1431 11000354135 16717 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8eOQǿۮmmjCpzpkozĿވ1z0DցD"q~wgT^!,ƅrɠh6h٥UE\э;lTUkT}>bhcccz۰\b†\N1z_ߏp8 Z-T*i4 hfhpRPJeC`AV3TG @y!,o1fCT✌q1( WgG. ;;;<[@'>f[ mnmr9ztb̤HM&%nQUUdVg H%%h2 ƃ`1k.rLA:A*K!SS㲧4IENDB`src/rups/com/lowagie/rups/view/icons/number.png100644 0 0 1037 11000354135 17237 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˥S=kP/QA~ͯѹ//::uAF\U(hnEMKIv܄w=$9D+}&N$)UU1F090>SR%wZc[VWL&󟒛Wh4zZAQ830\ëVٰA3 U 7@JiB˲4-z'tNZs ݟNn!|>^Gk]45HmaB/ r950?J7DD"`~_p4A :)fv<ˉb&4|>l'a\Cx<M]סj+ V`Z3X֞,@o?^ 4PzϥvrionoCAh1IENDB`src/rups/com/lowagie/rups/view/icons/outline.png100644 0 0 1276 11000354135 17433 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<PIDAT8˥SMhA~MSbd- D!U\OL=TV$(H=xQ^<zAD, "ZPij JZB6zI;39x0{a6lHM-˂'fR(و^i&z6Sj"}nz(1\5pzPA0 {$ckp%?xh!Kxu O)t(Ģn|J|:L4B]H id4A lWJ$e_^I6:ο9r\EIENDB`src/rups/com/lowagie/rups/view/icons/page.png100644 0 0 446 11000354135 16646 0ustar 0 0 PNG  IHDR7gAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT(u[ E&}O(@_֖9a.і?v9\ bBWҴJ/\Y+DIO)n,T(pbeF8D`ñ_9υN8s]蔊d!4i/&~MMIENDB`src/rups/com/lowagie/rups/view/icons/pdf.png100644 0 0 1117 11000354135 16517 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8ˍKQeVJqҕ`QX>b%BB *t!ЕBiU| Qd&d+3D iνs9U0Oƨq es]>G99|>BIuE  ÀT $q( &]05wLӄiHӈb\d:X`6߸TUE</)X@;mknD"3}@3GH(,˕+!::? C=!QE8/0/a fyHBؒP/HvAmn)+/ 8ĿB"nƆ@Z[)j~Uh^N3QOR6]n^SݑI1Oc c4esKxCA fw5>VZS' 0000)(õϙ=w}þ%Bb+ 0Z&/;!fKؕ a5WiߧB-gϿ&.7+ ruN:~-!?,7EI1,4OQ/&ݿ??++s/?3vI4Ԭw5?++~(̓J [Vϕ~wq ?}yX[W_k r-y'KDž?soO%hy:cFIENDB`src/rups/com/lowagie/rups/view/icons/ref.png100644 0 0 1112 11000354135 16515 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˅يA%6<] dL.3C(((*n=n=.5fl{)qŹ:4unvV fAUU4+RNqj:JHZaL0d2q!t&RT*0LFz]5MmsV*FF!~ ˲0m~mcEr##]f3Yc{7(jMs|=KpH)]joČ|\ʦʖw|{< JH$"!R.1#_,;}ր-Q B+wB|>?|Mނ٦H&^ŢdY>\;$FmaZO/wdT*i mہe~}SˑH$X,iw@|@F9-X?) `0I<'Wp sZ:{)IENDB`src/rups/com/lowagie/rups/view/icons/ref_recursive.png100644 0 0 1120 11000354135 20603 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˅nA%|M[ |V,cbDZ+7V@fBq{݌~wuĒC]jjl^VZR\.T*PNh4`^c '! u&h4á pL&se:L(Q,˚s.rH&! u╰ l6.!VW[%X".v\񜙳R)ŲO} 0됋p8 yF|j<'?Ǝ?zӶsbj$i%u6bi1/rB!5贉'&(~UܴN Px^Ip8,WUt ch3串ܛIENDB`src/rups/com/lowagie/rups/view/icons/stream.png100644 0 0 1340 11000354135 17237 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<rIDAT8˥SKoQ;` Vkҝ6&.1Bf,QL* ڦT P (Ps.&ޜ;; ǵeШЩЫ@?x?NB{hp38ƝN@0,E7$3k0c<8MGPk!W(ȯ%( HFK͖xv*RVIr}~ɲE-@_X6f (hCG4׀\5;w7 hG:w`xJbn^I lj q5:qH ~`jR2Y&VhIsίE_%Zo^=SXWY߫_gtIENDB`src/rups/com/lowagie/rups/view/icons/string.png100644 0 0 1166 11000354135 17260 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˕ORqQl#W0/Ͱ&S\r (Lź[!Lkl>om\Ňr~g9s~^h7ESG~­VQ{N$l,`&o+4}Ps+^ ߟ֑>D%C>iCUZ;X,ysE/:FkMU=71l# ƥ1gR&j,eXes”Mlvm/lKBdCFoN%ވB)bp-%\Gs8n/7i]RY+d&'c tø1'G;3pP#fEН19U7/"d NOϏB?oݖc[nCt~w*`G=DzPxR%JBysU]3\_Q4^*#1Eɋ񴥩 ]L]FpcYpnݲZ?p IENDB`src/rups/com/lowagie/rups/view/icons/tag.png100644 0 0 605 11000354135 16502 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8c?%a`l :{{z,b0ͯ?x/~~ ${B+ܧ`!^+?HNVZED~p~S/!$'=\߁r(6e _c7@~\3Fwf-c\馗g>t 7#B?.I#I{O}t$4w\0PL"dpX][kң{+E_ 2-o)?9)I GyiԭIENDB`src/rups/com/lowagie/rups/view/icons/text.png100644 0 0 441 11000354135 16711 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8= Aq:dR2_ %eH2- \ORHn:ހM6Y?u fTiJAQ(jInœBK(Us0ڿgifH@jsebb wLs uDBve =${ P޸/G _BIENDB`src/rups/com/lowagie/rups/view/icons/xfa.png100644 0 0 1133 11000354135 16522 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8ˍ=OP)C0[!k_@ @ &~@[%C *UAVJ;dB ,@l_رo}nqHP=<>.]D\cn?/ 8FNq$ɷAIP0Hɦi²,0iDQdAJ|mTU&2t]$ILPT@IMIP[5AJ(Je%6O(~0[dāa(*yUtOлM̾_ ^I P%4UUoVNcc_E{v_B|NuXתA"*kfB"_0-K?6љc.oal7.`Z:g|)bbܬ*āG å2Da.a2A$tCʘ?IENDB`src/rups/com/lowagie/rups/view/itext/FormTree.java100644 0 0 16123 11000354136 17674 0ustar 0 0 /* * $Id: FormTree.java 3146 2008-02-20 18:10:07Z blowagie $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.io.IOException; import java.util.Enumeration; import java.util.Observable; import java.util.Observer; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeModel; import org.dom4j.DocumentException; import com.lowagie.rups.controller.PdfReaderController; import com.lowagie.rups.model.ObjectLoader; import com.lowagie.rups.model.TreeNodeFactory; import com.lowagie.rups.model.XfaFile; import com.lowagie.rups.view.icons.IconTreeCellRenderer; import com.lowagie.rups.view.itext.treenodes.FormTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; import com.lowagie.rups.view.itext.treenodes.XfaTreeNode; import com.lowagie.text.pdf.PdfName; /** * A JTree visualizing information about the Interactive Form of the * PDF file (if any). Normally shows a tree view of the field hierarchy * and individual XDP packets. */ public class FormTree extends JTree implements TreeSelectionListener, Observer { /** Nodes in the FormTree correspond with nodes in the main PdfTree. */ protected PdfReaderController controller; /** If the form is an XFA form, the XML file is stored in this object. */ protected XfaFile xfaFile; /** Treeview of the XFA file. */ protected XfaTree xfaTree; /** Textview of the XFA file. */ protected XfaTextArea xfaTextArea; /** * Creates a new FormTree. */ public FormTree(PdfReaderController controller) { super(); this.controller = controller; setCellRenderer(new IconTreeCellRenderer()); setModel(new DefaultTreeModel(new FormTreeNode())); addTreeSelectionListener(this); xfaTree = new XfaTree(); xfaTextArea = new XfaTextArea(); } /** * Loads the fields of a PDF document into the FormTree. * @param observable the observable object * @param obj the object */ public void update(Observable observable, Object obj) { if (obj == null) { setModel(new DefaultTreeModel(new FormTreeNode())); xfaFile = null; xfaTree.clear(); xfaTextArea.clear(); repaint(); return; } if (obj instanceof ObjectLoader) { ObjectLoader loader = (ObjectLoader)obj; TreeNodeFactory factory = loader.getNodes(); PdfTrailerTreeNode trailer = controller.getPdfTree().getRoot(); PdfObjectTreeNode catalog = factory.getChildNode(trailer, PdfName.ROOT); PdfObjectTreeNode form = factory.getChildNode(catalog, PdfName.ACROFORM); if (form == null) { return; } PdfObjectTreeNode fields = factory.getChildNode(form, PdfName.FIELDS); FormTreeNode root = new FormTreeNode(); if (fields != null) { FormTreeNode node = new FormTreeNode(fields); node.setUserObject("Fields"); loadFields(factory, node, fields); root.add(node); } PdfObjectTreeNode xfa = factory.getChildNode(form, PdfName.XFA); if (xfa != null) { XfaTreeNode node = new XfaTreeNode(xfa); node.setUserObject("XFA"); loadXfa(factory, node, xfa); root.add(node); try { xfaFile = new XfaFile(node); xfaTree.load(xfaFile); xfaTextArea.load(xfaFile); } catch (IOException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } } setModel(new DefaultTreeModel(root)); } } /** * Method that can be used recursively to load the fields hierarchy into the tree. * @param factory a factory that can produce new PDF object nodes * @param form_node the parent node in the form tree * @param object_node the object node that will be used to create a child node */ private void loadFields(TreeNodeFactory factory, FormTreeNode form_node, PdfObjectTreeNode object_node) { if (object_node == null) return; factory.expandNode(object_node); if (object_node.isIndirectReference()) { loadFields(factory, form_node, (PdfObjectTreeNode)object_node.getFirstChild()); } else if (object_node.isArray()) { Enumeration children = object_node.children(); while (children.hasMoreElements()) { loadFields(factory, form_node, (PdfObjectTreeNode)children.nextElement()); } } else if (object_node.isDictionary()) { FormTreeNode leaf = new FormTreeNode(object_node); form_node.add(leaf); PdfObjectTreeNode kids = factory.getChildNode(object_node, PdfName.KIDS); loadFields(factory, leaf, kids); } } /** * Method that will load the nodes that refer to XFA streams. * @param form_node the parent node in the form tree * @param object_node the object node that will be used to create a child node */ private void loadXfa(TreeNodeFactory factory, XfaTreeNode form_node, PdfObjectTreeNode object_node) { if (object_node == null) return; factory.expandNode(object_node); if (object_node.isIndirectReference()) { loadXfa(factory, form_node, (PdfObjectTreeNode)object_node.getFirstChild()); } else if (object_node.isArray()) { Enumeration children = object_node.children(); PdfObjectTreeNode key; PdfObjectTreeNode value; while (children.hasMoreElements()) { key = (PdfObjectTreeNode)children.nextElement(); value = (PdfObjectTreeNode)children.nextElement(); if (value.isIndirectReference()) { factory.expandNode(value); value = (PdfObjectTreeNode)value.getFirstChild(); } form_node.addPacket(key.getPdfObject().toString(), value); } } else if (object_node.isStream()) { form_node.addPacket("xdp", object_node); } } /** * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent) */ public void valueChanged(TreeSelectionEvent evt) { if (controller == null) return; FormTreeNode selectednode = (FormTreeNode)this.getLastSelectedPathComponent(); if (selectednode == null) return; PdfObjectTreeNode node = selectednode.getCorrespondingPdfObjectNode(); if (node != null) controller.selectNode(node); } public XfaTree getXfaTree() { return xfaTree; } public XfaTextArea getXfaTextArea() { return xfaTextArea; } /** A serial version UID. */ private static final long serialVersionUID = -3584003547303700407L; } src/rups/com/lowagie/rups/view/itext/OutlineTree.java100644 0 0 10041 11000354136 20401 0ustar 0 0 /* * $Id: OutlineTree.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.util.Observable; import java.util.Observer; import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeModel; import com.lowagie.rups.controller.PdfReaderController; import com.lowagie.rups.model.ObjectLoader; import com.lowagie.rups.model.TreeNodeFactory; import com.lowagie.rups.view.icons.IconTreeCellRenderer; import com.lowagie.rups.view.itext.treenodes.OutlineTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; import com.lowagie.text.pdf.PdfName; /** * A JTree visualizing information about the outlines (aka bookmarks) of * the PDF file (if any). */ public class OutlineTree extends JTree implements TreeSelectionListener, Observer { /** Nodes in the FormTree correspond with nodes in the main PdfTree. */ protected PdfReaderController controller; /** Creates a new outline tree. */ public OutlineTree(PdfReaderController controller) { super(); this.controller = controller; setCellRenderer(new IconTreeCellRenderer()); setModel(new DefaultTreeModel(new OutlineTreeNode())); addTreeSelectionListener(this); } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (obj == null) { setModel(new DefaultTreeModel(new OutlineTreeNode())); repaint(); return; } if (obj instanceof ObjectLoader) { ObjectLoader loader = (ObjectLoader)obj; TreeNodeFactory factory = loader.getNodes(); PdfTrailerTreeNode trailer = controller.getPdfTree().getRoot(); PdfObjectTreeNode catalog = factory.getChildNode(trailer, PdfName.ROOT); PdfObjectTreeNode outline = factory.getChildNode(catalog, PdfName.OUTLINES); if (outline == null) { return; } OutlineTreeNode root = new OutlineTreeNode(); loadOutline(factory, root, factory.getChildNode(outline, PdfName.FIRST)); setModel(new DefaultTreeModel(root)); } } /** * Method that can be used recursively to load the outline hierarchy into the tree. */ private void loadOutline(TreeNodeFactory factory, OutlineTreeNode parent, PdfObjectTreeNode child) { OutlineTreeNode childnode = new OutlineTreeNode(child); parent.add(childnode); PdfObjectTreeNode first = factory.getChildNode(child, PdfName.FIRST); if (first != null) { loadOutline(factory, childnode, first); } PdfObjectTreeNode next = factory.getChildNode(child, PdfName.NEXT); if (next != null) { loadOutline(factory, parent, next); } } /** * @see javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event.TreeSelectionEvent) */ public void valueChanged(TreeSelectionEvent evt) { if (controller == null) return; OutlineTreeNode selectednode = (OutlineTreeNode)this.getLastSelectedPathComponent(); PdfObjectTreeNode node = selectednode.getCorrespondingPdfObjectNode(); if (node != null) controller.selectNode(node); } /** A serial version uid. */ private static final long serialVersionUID = 5646572654823301007L; } src/rups/com/lowagie/rups/view/itext/PagesTable.java100644 0 0 12074 11000354136 20161 0ustar 0 0 /* * $Id: PagesTable.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.util.ArrayList; import java.util.Enumeration; import java.util.Observable; import java.util.Observer; import javax.swing.JTable; import javax.swing.event.ListSelectionEvent; import com.lowagie.rups.controller.PdfReaderController; import com.lowagie.rups.model.ObjectLoader; import com.lowagie.rups.model.TreeNodeFactory; import com.lowagie.rups.view.PageNavigationListener; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfPageTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfPagesTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; import com.lowagie.rups.view.models.JTableAutoModel; import com.lowagie.rups.view.models.JTableAutoModelInterface; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfPageLabels; /** * A JTable listing all the pages in a PDF file: the object number of each * page dictionary and the page numbers (with label information if present). */ public class PagesTable extends JTable implements JTableAutoModelInterface, Observer { /** A list with page nodes. */ protected ArrayList list = new ArrayList(); /** Nodes in the FormTree correspond with nodes in the main PdfTree. */ protected PdfReaderController controller; /***/ protected PageNavigationListener listener; /** * Constructs a PagesTable. * @param listener the page navigation listener. */ public PagesTable(PdfReaderController controller, PageNavigationListener listener) { this.controller = controller; this.listener = listener; } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (obj == null) { list = new ArrayList(); repaint(); return; } if (obj instanceof ObjectLoader) { ObjectLoader loader = (ObjectLoader)obj; String[] pagelabels = PdfPageLabels.getPageLabels(loader.getReader()); int i = 0; TreeNodeFactory factory = loader.getNodes(); PdfTrailerTreeNode trailer = controller.getPdfTree().getRoot(); PdfObjectTreeNode catalog = factory.getChildNode(trailer, PdfName.ROOT); PdfPagesTreeNode pages = (PdfPagesTreeNode)factory.getChildNode(catalog, PdfName.PAGES); if (pages == null) { return; } Enumeration p = pages.depthFirstEnumeration(); PdfObjectTreeNode child; StringBuffer buf; while (p.hasMoreElements()) { child = (PdfObjectTreeNode)p.nextElement(); if (child instanceof PdfPageTreeNode) { buf = new StringBuffer("Page "); buf.append(++i); if (pagelabels != null) { buf.append(" ( "); buf.append(pagelabels[i - 1]); buf.append(" )"); } child.setUserObject(buf.toString()); list.add((PdfPageTreeNode)child); } } } setModel(new JTableAutoModel(this)); } /** * @see javax.swing.JTable#getColumnCount() */ public int getColumnCount() { return 2; } /** * @see javax.swing.JTable#getRowCount() */ public int getRowCount() { return list.size(); } /** * @see javax.swing.JTable#getValueAt(int, int) */ public Object getValueAt(int rowIndex, int columnIndex) { if (getRowCount() == 0) return null; switch (columnIndex) { case 0: return "Object " + list.get(rowIndex).getNumber(); case 1: return list.get(rowIndex); } return null; } /** * @see javax.swing.JTable#getColumnName(int) */ public String getColumnName(int columnIndex) { switch (columnIndex) { case 0: return "Object"; case 1: return "Page"; default: return null; } } /** * @see javax.swing.JTable#valueChanged(javax.swing.event.ListSelectionEvent) */ @Override public void valueChanged(ListSelectionEvent evt) { if (evt != null) super.valueChanged(evt); if (controller == null) return; if (getRowCount() > 0) { controller.selectNode(list.get(getSelectedRow())); if (listener != null) listener.gotoPage(getSelectedRow() + 1); } } /** A serial version UID. */ private static final long serialVersionUID = -6523261089453886508L; }src/rups/com/lowagie/rups/view/itext/PdfObjectPanel.java100644 0 0 6657 11000354136 20764 0ustar 0 0 /* * $Id: PdfObjectPanel.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.awt.CardLayout; import java.util.Observable; import java.util.Observer; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import com.lowagie.rups.view.models.DictionaryTableModel; import com.lowagie.rups.view.models.PdfArrayTableModel; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfObject; public class PdfObjectPanel extends JPanel implements Observer { /** Name of a panel in the CardLayout. */ private static final String TEXT = "text"; /** Name of a panel in the CardLayout. */ private static final String TABLE = "table"; /** The layout that will show the info about the PDF object that is being analyzed. */ protected CardLayout layout = new CardLayout(); /** Table with dictionary entries. */ JTable table = new JTable(); /** The text pane with the info about a PDF object in the bottom panel. */ JTextArea text = new JTextArea(); /** Creates a PDF object panel. */ public PdfObjectPanel() { // layout setLayout(layout); // dictionary / array / stream JScrollPane dict_scrollpane = new JScrollPane(); dict_scrollpane.setViewportView(table); add(dict_scrollpane, TABLE); // number / string / ... JScrollPane text_scrollpane = new JScrollPane(); text_scrollpane.setViewportView(text); add(text_scrollpane, TEXT); } /** * Clear the object panel. */ public void clear() { text.setText(null); layout.show(this, TEXT); } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { clear(); } /** * Shows a PdfObject as text or in a table. * @param object the object that needs to be shown. */ public void render(PdfObject object) { if (object == null) { text.setText(null); layout.show(this, TEXT); this.repaint(); text.repaint(); return; } switch(object.type()) { case PdfObject.DICTIONARY: case PdfObject.STREAM: table.setModel(new DictionaryTableModel((PdfDictionary)object)); layout.show(this, TABLE); this.repaint(); break; case PdfObject.ARRAY: table.setModel(new PdfArrayTableModel((PdfArray)object)); layout.show(this, TABLE); this.repaint(); break; default: text.setText(object.toString()); layout.show(this, TEXT); break; } } /** a serial version id. */ private static final long serialVersionUID = 1302283071087762494L; } src/rups/com/lowagie/rups/view/itext/PdfTree.java100644 0 0 5321 11000663663 17470 0ustar 0 0 /* * $Id: PdfTree.java 3242 2008-04-13 23:00:20Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.util.Observable; import java.util.Observer; import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import com.lowagie.rups.view.icons.IconTreeCellRenderer; import com.lowagie.rups.view.itext.treenodes.PdfObjectTreeNode; import com.lowagie.rups.view.itext.treenodes.PdfTrailerTreeNode; /** * A JTree that shows the object hierarchy of a PDF document. */ public class PdfTree extends JTree implements Observer { /** The root of the PDF tree. */ protected PdfTrailerTreeNode root; /** * Constructs a PDF tree. */ public PdfTree() { super(); root = new PdfTrailerTreeNode(); setCellRenderer(new IconTreeCellRenderer()); update(null, null); } /** * Getter for the root node * @return the PDF Trailer node */ public PdfTrailerTreeNode getRoot() { return root; } /** * Updates the PdfTree when a file is closed or when a ObjectLoader * has finished loading objects. * @param observable the Observable class that started the update * @param obj the object that has all the updates * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (obj == null) { root = new PdfTrailerTreeNode(); } setModel(new DefaultTreeModel(root)); repaint(); } /** * Select a specific node in the tree. * Typically this method will be called from a different tree, * such as the pages, outlines or form tree. * @param node the node that has to be selected */ public void selectNode(PdfObjectTreeNode node) { TreePath path = new TreePath(node.getPath()); setSelectionPath(path); scrollPathToVisible(path); } /** a serial version UID */ private static final long serialVersionUID = 7545804447512085734L; }src/rups/com/lowagie/rups/view/itext/StreamTextArea.java100644 0 0 4663 11000354136 21030 0ustar 0 0 /* * $Id: StreamTextArea.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.io.IOException; import java.util.Observable; import java.util.Observer; import javax.swing.JScrollPane; import javax.swing.JTextArea; import com.lowagie.rups.io.TextAreaOutputStream; import com.lowagie.text.pdf.PRStream; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; public class StreamTextArea extends JScrollPane implements Observer { /** The text area with the content stream. */ protected JTextArea text; /** * Constructs a StreamTextArea. */ public StreamTextArea() { super(); text = new JTextArea(); setViewportView(text); } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { text.setText(null); } /** * Renders the content stream of a PdfObject or empties the text area. * @param object the object of which the content stream needs to be rendered */ public void render(PdfObject object) { if (object instanceof PRStream) { PRStream stream = (PRStream)object; try { TextAreaOutputStream taos = new TextAreaOutputStream(text); taos.write(PdfReader.getStreamBytes(stream)); //text.addMouseListener(new StreamEditorAction(stream)); } catch(IOException e) { text.setText("The stream could not be read: " + e.getMessage()); } } else { update(null, null); return; } text.repaint(); repaint(); } /** a serial version id. */ private static final long serialVersionUID = 1302283071087762494L; } src/rups/com/lowagie/rups/view/itext/XRefTable.java100644 0 0 11715 11000354136 17767 0ustar 0 0 /* * $Id: XRefTable.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import java.util.Observable; import java.util.Observer; import javax.swing.JTable; import javax.swing.event.ListSelectionEvent; import javax.swing.table.TableColumn; import com.lowagie.rups.controller.PdfReaderController; import com.lowagie.rups.model.IndirectObjectFactory; import com.lowagie.rups.model.ObjectLoader; import com.lowagie.rups.view.models.JTableAutoModel; import com.lowagie.rups.view.models.JTableAutoModelInterface; import com.lowagie.text.pdf.PdfNull; import com.lowagie.text.pdf.PdfObject; /** * A JTable that shows the indirect objects of a PDF xref table. */ public class XRefTable extends JTable implements JTableAutoModelInterface, Observer { /** The factory that can produce all the indirect objects. */ protected IndirectObjectFactory objects; /** The renderer that will render an object when selected in the table. */ protected PdfReaderController controller; /** Creates a JTable visualizing xref table. */ public XRefTable(PdfReaderController controller) { super(); this.controller = controller; } /** * @see java.util.Observer#update(java.util.Observable, java.lang.Object) */ public void update(Observable observable, Object obj) { if (obj == null) { objects = null; repaint(); return; } if (observable instanceof PdfReaderController && obj instanceof ObjectLoader) { ObjectLoader loader = (ObjectLoader)obj; objects = loader.getObjects(); setModel(new JTableAutoModel(this)); TableColumn col= getColumnModel().getColumn(0); col.setPreferredWidth(5); } } /** * @see javax.swing.JTable#getColumnCount() */ public int getColumnCount() { return 2; } /** * @see javax.swing.JTable#getRowCount() */ public int getRowCount() { if (objects == null) return 0; return objects.size(); } /** * @see javax.swing.JTable#getValueAt(int, int) */ public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return getObjectReferenceByRow(rowIndex); case 1: return getObjectDescriptionByRow(rowIndex); default: return null; } } /** * Gets the reference number of an indirect object * based on the row index. * @param rowIndex a row number * @return a reference number */ protected int getObjectReferenceByRow(int rowIndex) { return objects.getRefByIndex(rowIndex); } /** * Gets the object that is shown in a row. * @param rowIndex the row number containing the object * @return a PDF object */ protected String getObjectDescriptionByRow(int rowIndex) { PdfObject object = objects.getObjectByIndex(rowIndex); if (object instanceof PdfNull) return "Indirect object"; return object.toString(); } /** * @see javax.swing.JTable#getColumnName(int) */ public String getColumnName(int columnIndex) { switch (columnIndex) { case 0: return "Number"; case 1: return "Object"; default: return null; } } /** * Gets the object that is shown in a row. * @param rowIndex the row number containing the object * @return a PDF object */ protected PdfObject getObjectByRow(int rowIndex) { return objects.loadObjectByReference(getObjectReferenceByRow(rowIndex)); } /** * Selects a row containing information about an indirect object. * @param ref the reference number of the indirect object */ public void selectRowByReference(int ref) { int row = objects.getIndexByRef(ref); setRowSelectionInterval(row, row); scrollRectToVisible(getCellRect(row, 1, true)); valueChanged(null); } /** * @see javax.swing.JTable#valueChanged(javax.swing.event.ListSelectionEvent) */ @Override public void valueChanged(ListSelectionEvent evt) { if (evt != null) super.valueChanged(evt); if (controller != null && objects != null) { controller.render(getObjectByRow(this.getSelectedRow())); controller.selectNode(getObjectReferenceByRow(getSelectedRow())); } } /** A serial version UID. */ private static final long serialVersionUID = -382184619041375537L; }src/rups/com/lowagie/rups/view/itext/XfaTextArea.java100644 0 0 1566 11106243445 20321 0ustar 0 0 package com.lowagie.rups.view.itext; import java.io.IOException; import javax.swing.JScrollPane; import javax.swing.JTextArea; import com.lowagie.rups.io.OutputStreamResource; import com.lowagie.rups.io.TextAreaOutputStream; /** * TextArea that visualizes the XFA XML file. */ public class XfaTextArea extends JScrollPane { /** The text area with the content stream. */ protected JTextArea text; /** * Constructs a StreamTextArea. */ public XfaTextArea() { super(); text = new JTextArea(); setViewportView(text); } public void clear() { text.setText(""); } public void load(OutputStreamResource xml) throws IOException { TextAreaOutputStream stream = new TextAreaOutputStream(text); xml.writeTo(stream); } /** A Serial Version UID. */ private static final long serialVersionUID = -8275229961781669457L; } src/rups/com/lowagie/rups/view/itext/XfaTree.java100644 0 0 3344 11000354136 17470 0ustar 0 0 /* * $Id: XfaTree.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext; import javax.swing.JTree; import javax.swing.tree.DefaultTreeModel; import com.lowagie.rups.model.XfaFile; import com.lowagie.rups.view.icons.IconTreeCellRenderer; import com.lowagie.rups.view.icons.IconTreeNode; import com.lowagie.rups.view.itext.treenodes.XdpTreeNode; /** * Tree that visualizes the XFA information. */ public class XfaTree extends JTree { /** * Constructs an XfaTree. */ public XfaTree() { super(); } public void clear() { setCellRenderer(new IconTreeCellRenderer()); setModel(new DefaultTreeModel(new IconTreeNode("xfa.png"))); } public void load(XfaFile file) { setCellRenderer(new IconTreeCellRenderer()); setModel(new DefaultTreeModel(new XdpTreeNode(file.getXfaDocument()))); } /** A Serial Version UID. */ private static final long serialVersionUID = -5072971223015095193L; }src/rups/com/lowagie/rups/view/itext/treenodes/FormTreeNode.java100644 0 0 4321 11000354136 22447 0ustar 0 0 /* * $Id: FormTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.rups.view.icons.IconTreeNode; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; /** * A FormTreeNode is a standard node in a FormTree. */ public class FormTreeNode extends IconTreeNode { /** The corresponding tree node in the PdfTree. */ protected PdfObjectTreeNode object_node; /** * Creates the root node of the FormTree. */ public FormTreeNode() { super("form.png", "Form"); } /** * Creates a node corresponding with a node in the PdfTree. * @param node a corresponding node */ public FormTreeNode(PdfObjectTreeNode node) { super("form.png"); this.object_node = node; if (node.isDictionary()) { PdfDictionary dict = (PdfDictionary)node.getPdfObject(); PdfObject fieldname = dict.get(PdfName.T); if (fieldname != null) { this.setUserObject(fieldname); } else { this.setUserObject("unnamed field"); } } } /** * Gets the node in the PdfTree that corresponds with this * FormTreeNode. * @return a PdfObjectTreeNode in the PdfTree */ public PdfObjectTreeNode getCorrespondingPdfObjectNode() { return object_node; } /** A serial version UID. */ private static final long serialVersionUID = 7800080437550790989L; }src/rups/com/lowagie/rups/view/itext/treenodes/OutlineTreeNode.java100644 0 0 4001 11000354136 23156 0ustar 0 0 /* * $Id: OutlineTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.rups.view.icons.IconTreeNode; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; /** * A node in the OutlineTree. */ public class OutlineTreeNode extends IconTreeNode { /** The corresponding tree node in the PdfTree. */ protected PdfObjectTreeNode object_node; /** Creates the root node for the OutlineTree. */ public OutlineTreeNode() { super("outline.png", "Bookmarks"); } /** * Creates a node corresponding with a node in the PdfTree. * @param node a corresponding node */ public OutlineTreeNode(PdfObjectTreeNode node) { super("outline.png"); this.object_node = node; PdfDictionary dict = (PdfDictionary)node.getPdfObject(); this.setUserObject(dict.get(PdfName.TITLE)); } /** * Gets the node in the PdfTree that corresponds with this * OutlineTreeNode. * @return a PdfObjectTreeNode in the PdfTree */ public PdfObjectTreeNode getCorrespondingPdfObjectNode() { return object_node; } /** A serial version uid */ private static final long serialVersionUID = 5437651809665762952L; }src/rups/com/lowagie/rups/view/itext/treenodes/PdfObjectTreeNode.java100644 0 0 21224 11154165267 23444 0ustar 0 0 /* * $Id: PdfObjectTreeNode.java 3693 2009-02-13 17:37:31Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.rups.view.icons.IconFetcher; import com.lowagie.rups.view.icons.IconTreeNode; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfIndirectReference; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfString; /** * Every node in our tree corresponds with a PDF object. * This class is the superclass of all tree nodes used. */ public class PdfObjectTreeNode extends IconTreeNode { /** the PDF object corresponding with this node. */ protected PdfObject object; /** the key if the parent of this node is a dictionary. */ protected PdfName key = null; /** if the object is indirect, the number of the PDF object. */ protected int number = -1; /** indicates if the object is indirect and recursive. */ protected boolean recursive = false; /** * Creates a tree node for a PDF object. * @param object the PDF object represented by this tree node. */ protected PdfObjectTreeNode(PdfObject object) { super(null, getCaption(object)); this.object = object; switch(object.type()) { case PdfObject.INDIRECT: if (isRecursive()) icon = IconFetcher.getIcon("ref_recursive.png"); else icon = IconFetcher.getIcon("ref.png"); return; case PdfObject.ARRAY: icon = IconFetcher.getIcon("array.png"); return; case PdfObject.DICTIONARY: icon = IconFetcher.getIcon("dictionary.png"); return; case PdfObject.STREAM: icon = IconFetcher.getIcon("stream.png"); return; case PdfObject.BOOLEAN: icon = IconFetcher.getIcon("boolean.png"); return; case PdfObject.NAME: icon = IconFetcher.getIcon("name.png"); return; case PdfObject.NULL: icon = IconFetcher.getIcon("null.png"); return; case PdfObject.NUMBER: icon = IconFetcher.getIcon("number.png"); return; case PdfObject.STRING: icon = IconFetcher.getIcon("string.png"); return; } } /** * Creates a tree node for a PDF object. * @param icon the file with the icon * @param object the PDF object represented by this tree node. */ protected PdfObjectTreeNode(String icon, PdfObject object) { super(icon, getCaption(object)); this.object = object; } /** * Creates an instance of a tree node for a PDF object. * @param object the PDF object represented by this tree node. * @return a PdfObjectTreeNode */ public static PdfObjectTreeNode getInstance(PdfObject object) { if (object.isDictionary()) { if (PdfName.PAGE.equals(((PdfDictionary)object).get(PdfName.TYPE))) { return new PdfPageTreeNode((PdfDictionary)object); } else if (PdfName.PAGES.equals(((PdfDictionary)object).get(PdfName.TYPE))) { return new PdfPagesTreeNode((PdfDictionary)object); } } return new PdfObjectTreeNode(object); } /** * Creates an instance of a tree node for an indirect object. * @param object the PDF object represented by this tree node. * @param number the xref number of the indirect object * @return a PdfObjectTreeNode */ public static PdfObjectTreeNode getInstance(PdfObject object, int number) { PdfObjectTreeNode node = getInstance(object); node.number = number; return node; } /** * Creates an instance of a tree node for the object corresponding with a key in a dictionary. * @param dict the dictionary that is the parent of this tree node. * @param key the dictionary key corresponding with the PDF object in this tree node. * @return a PdfObjectTreeNode */ public static PdfObjectTreeNode getInstance(PdfDictionary dict, PdfName key) { PdfObjectTreeNode node = getInstance(dict.get(key)); node.setUserObject(getDictionaryEntryCaption(dict, key)); node.key = key; return node; } /** * Getter for the PDF Object. * @return the PDF object represented by this tree node. */ public PdfObject getPdfObject() { return object; } /** * Getter for the object number in case the object is indirect. * @return -1 for direct objects; the object number for indirect objects */ public int getNumber() { if (isIndirectReference()) { return ((PdfIndirectReference)object).getNumber(); } return number; } /** * Tells you if the node contains an indirect reference. * @return true if the object is an indirect reference */ public boolean isIndirectReference() { return object.type() == PdfObject.INDIRECT; } /** * Tells you if the object is indirect. * @return true for indirect objects; false for direct objects. */ public boolean isIndirect() { return isIndirectReference() || number > -1; } /** * Tells you if the node contains an array. * @return true if the object is a PdfArray */ public boolean isArray() { return object.isArray(); } /** * Checks if this node is a dictionary item with a specific key. * @param key the key of the node we're looking for */ public boolean isDictionaryNode(PdfName key) { if (key == null) return false; return key.equals(this.key); } /** * Tells you if the node contains a dictionary. * @return true if the object is a PdfDictionary */ public boolean isDictionary() { return object.isDictionary(); } /** * Tells you if the node contains a stream. * @return true if the object is a PRStream */ public boolean isStream() { return object.isStream(); } /** * Set this to true if the object is a reference to a node higher up in the tree. * @param recursive true if the object is indirect and recursive */ public void setRecursive(boolean recursive) { this.recursive = recursive; } /** * Tells you if the object is a reference to a node higher up in the tree. * @return true if the node is used recursively. */ public boolean isRecursive() { return recursive; } /** * Creates the caption for a PDF object. * @param object the object for which a caption has to be created. * @return a caption for a PDF object */ public static String getCaption(PdfObject object) { if (object == null) return "null"; switch (object.type()) { case PdfObject.INDIRECT: { String reffedCaption = getCaption( PdfReader.getPdfObject( object ) ); return object.toString() + " -> " + reffedCaption; } case PdfObject.ARRAY: return "Array"; case PdfObject.STREAM: return "Stream"; case PdfObject.STRING: return ((PdfString)object).toUnicodeString(); } return object.toString(); } /** * Creates the caption for an object that is a dictionary entry. * @param dict a dictionary * @param key a key in the dictionary * @return a caption for the object corresponding with the key in the dictionary. */ public static String getDictionaryEntryCaption(PdfDictionary dict, PdfName key) { StringBuffer buf = new StringBuffer(key.toString()); buf.append(": "); PdfObject valObj = dict.get(key); if (valObj.isIndirect()) { buf.append( getCaption( valObj ) ); } else { buf.append(dict.get(key).toString()); } return buf.toString(); } /** * Gets the tree path of an ancestor. * This only works with recursive references * @return the treepath to an ancestor */ public PdfObjectTreeNode getAncestor() { if (isRecursive()) { PdfObjectTreeNode node = this; while(true) { node = (PdfObjectTreeNode)node.getParent(); if (node.isIndirectReference() && node.getNumber() == getNumber()) { return node; } } } return null; } /** a serial version UID. */ private static final long serialVersionUID = -5617844659397445879L; } src/rups/com/lowagie/rups/view/itext/treenodes/PdfPageTreeNode.java100644 0 0 2566 11000354136 23063 0ustar 0 0 /* * $Id: PdfPageTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.text.pdf.PdfDictionary; /** * A tree node corresponding with a Page dictionary in a PDF file. */ public class PdfPageTreeNode extends PdfObjectTreeNode { /** * Creates a tree node for a Pages dictionary. * @param object a PdfDictionary of type pages. */ public PdfPageTreeNode(PdfDictionary object) { super("page.png", object); } /** A serial version uid */ private static final long serialVersionUID = 3747496604295843783L; } src/rups/com/lowagie/rups/view/itext/treenodes/PdfPagesTreeNode.java100644 0 0 2572 11000354136 23243 0ustar 0 0 /* * $Id: PdfPagesTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.text.pdf.PdfDictionary; /** * A tree node corresponding with a Pages dictionary in a PDF file. */ public class PdfPagesTreeNode extends PdfObjectTreeNode { /** * Creates a tree node for a Pages dictionary. * @param object a PdfDictionary of type pages. */ public PdfPagesTreeNode(PdfDictionary object) { super("pages.png", object); } /** a serial version uid */ private static final long serialVersionUID = 4527774449030791503L; } src/rups/com/lowagie/rups/view/itext/treenodes/PdfTrailerTreeNode.java100644 0 0 3055 11000354136 23603 0ustar 0 0 /* * $Id: PdfTrailerTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import com.lowagie.text.pdf.PdfDictionary; /** * A special treenode that will be used for the trailer dictionary * of a PDF file. */ public class PdfTrailerTreeNode extends PdfObjectTreeNode { /** * Constructs a simple text tree node. */ public PdfTrailerTreeNode() { super("pdf.png", null); setUserObject("Open a PDF file"); } /** * Sets the object for this node. * @param trailer the trailer dictionary of a PDF file. */ public void setTrailer(PdfDictionary trailer) { object = trailer; } /** A serial version id. */ private static final long serialVersionUID = -3607980103983635182L; } src/rups/com/lowagie/rups/view/itext/treenodes/XdpTreeNode.java100644 0 0 6700 11000663663 22312 0ustar 0 0 /* * $Id: XdpTreeNode.java 3242 2008-04-13 23:00:20Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Branch; import org.dom4j.Comment; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.Node; import org.dom4j.ProcessingInstruction; import org.dom4j.Text; import com.lowagie.rups.view.icons.IconFetcher; import com.lowagie.rups.view.icons.IconTreeNode; public class XdpTreeNode extends IconTreeNode { /** A serial version UID. */ private static final long serialVersionUID = -6431790925424045933L; /** * Constructs an XdpTreeNode * @param node the XML node */ public XdpTreeNode(Node node) { super(null, node); if (node instanceof Element) { Element element = (Element)node; addChildNodes(element.attributes()); } if (node instanceof Branch) { Branch branch = (Branch) node; addChildNodes(branch.content()); } if (node instanceof Attribute) { icon = IconFetcher.getIcon("attribute.png"); return; } if (node instanceof Text) { icon = IconFetcher.getIcon("text.png"); return; } if (node instanceof ProcessingInstruction) { icon = IconFetcher.getIcon("pi.png"); return; } if (node instanceof Document) { icon = IconFetcher.getIcon("xfa.png"); return; } icon = IconFetcher.getIcon("tag.png"); } private void addChildNodes(List list) { for (Iterator i = list.iterator(); i.hasNext(); ) { Node n = (Node)i.next(); if (n instanceof Namespace) continue; if (n instanceof Comment) continue; this.add(new XdpTreeNode(n)); } } public Node getNode() { return (Node)getUserObject(); } public String toString() { Node node = getNode(); if (node instanceof Element) { Element e = (Element)node; return e.getName(); } if (node instanceof Attribute) { Attribute a = (Attribute)node; StringBuffer buf = new StringBuffer(); buf.append(a.getName()); buf.append("=\""); buf.append(a.getValue()); buf.append('"'); return buf.toString(); } if (node instanceof Text) { Text t = (Text)node; return t.getText(); } if (node instanceof ProcessingInstruction) { ProcessingInstruction pi = (ProcessingInstruction)node; StringBuffer buf = new StringBuffer(""); return buf.toString(); } if (node instanceof Document) { return "XFA Document"; } return getNode().toString(); } }src/rups/com/lowagie/rups/view/itext/treenodes/XfaTreeNode.java100644 0 0 7534 11000354136 22273 0ustar 0 0 /* * $Id: XfaTreeNode.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.itext.treenodes; import java.io.IOException; import java.io.OutputStream; import java.util.Enumeration; import com.lowagie.rups.io.OutputStreamResource; import com.lowagie.text.pdf.PRStream; import com.lowagie.text.pdf.PdfReader; /** * This is the root tree node for the different parts of the XFA resource; it's a child * of the root in the FormTree. * This resource can be one XDP stream (in which case this root will only have one child) * or different streams with individual packets comprising the XML Data Package. */ public class XfaTreeNode extends FormTreeNode implements OutputStreamResource { /** Start sequence of an artificial boundary between XFA fragments added by RUPS */ public static final byte[] BOUNDARY_START = "".getBytes(); /** * Creates the root node of the XFA tree. * This will be a child of the FormTree root node. * @param xfa the XFA node in the PdfTree (a child of the AcroForm node in the PDF catalog) */ public XfaTreeNode(PdfObjectTreeNode xfa) { super(xfa); } /** * Writes (part of) the XFA resource to an OutputStream. * If key is null, the complete resource is written; * if key refers to an individual package, this package only is * written to the OutputStream. * @param os the OutputStream to which the XML is written. * @throws IOException usual exception when there's a problem writing to an OutputStream */ public void writeTo(OutputStream os) throws IOException { Enumeration children = this.children(); FormTreeNode node; PRStream stream; String key = null; String tmp = null; while (children.hasMoreElements()) { node = (FormTreeNode) children.nextElement(); if (key != null) { os.write(BOUNDARY_START); os.write(key.getBytes()); os.write(BOUNDARY_MIDDLE); tmp = (String)node.getUserObject(); os.write(tmp.getBytes()); os.write(BOUNDARY_END); } key = tmp; stream = (PRStream)node.getCorrespondingPdfObjectNode().getPdfObject(); os.write(PdfReader.getStreamBytes(stream)); } os.flush(); os.close(); } /** * Adds a child node to the XFA root. * The child node either corresponds with the complete XDP stream * (if the XFA root only has one child) or with individual packet. * @param key the name of the packet * @param value the corresponding stream node in the PdfTree */ public void addPacket(String key, PdfObjectTreeNode value) { FormTreeNode node = new FormTreeNode(value); node.setUserObject(key); this.add(node); } /** A serial version UID. */ private static final long serialVersionUID = 2463297568233643790L; }src/rups/com/lowagie/rups/view/models/DictionaryTableModel.java100644 0 0 5114 11000354133 22310 0ustar 0 0 /* * $Id: DictionaryTableModel.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.models; import java.util.ArrayList; import java.util.Iterator; import javax.swing.table.AbstractTableModel; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; /** * A TableModel in case we want to show a PDF dictionary in a JTable. */ public class DictionaryTableModel extends AbstractTableModel { /** A serial version UID. */ private static final long serialVersionUID = -8835275996639701776L; /** The PDF dictionary. */ protected PdfDictionary dictionary; /** An ArrayList with the dictionary keys. */ protected ArrayList keys = new ArrayList(); /** * Creates the TableModel. * @param dictionary the dictionary we want to show */ public DictionaryTableModel(PdfDictionary dictionary) { this.dictionary = dictionary; for (Iterator i = dictionary.getKeys().iterator(); i.hasNext(); ) this.keys.add((PdfName) i.next()); } /** * @see javax.swing.table.TableModel#getColumnCount() */ public int getColumnCount() { return 2; } /** * @see javax.swing.table.TableModel#getRowCount() */ public int getRowCount() { return dictionary.size(); } /** * @see javax.swing.table.TableModel#getValueAt(int, int) */ public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return keys.get(rowIndex); case 1: return dictionary.get(keys.get(rowIndex)); default: return null; } } /** * @see javax.swing.table.AbstractTableModel#getColumnName(int) */ public String getColumnName(int columnIndex) { switch (columnIndex) { case 0: return "Key"; case 1: return "Value"; default: return null; } } } src/rups/com/lowagie/rups/view/models/JTableAutoModel.java100644 0 0 4740 11000354133 21231 0ustar 0 0 /* * $Id: JTableAutoModel.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.models; import javax.swing.table.AbstractTableModel; /** * A reusable TableModel class for tables that implement the * JTableAutoModelInterface. */ public class JTableAutoModel extends AbstractTableModel { /** The serial version uid. */ private static final long serialVersionUID = -2229431581745521537L; /** The table that knows how to model itself. */ protected JTableAutoModelInterface table; /** * Constructs an auto model for a JTable. * @param table a JTable that knows information about its model. */ public JTableAutoModel(JTableAutoModelInterface table) { this.table = table; } /** * @see javax.swing.table.TableModel#getColumnCount() * @return int the number of columns */ public int getColumnCount() { return table.getColumnCount(); } /** * @see javax.swing.table.TableModel#getRowCount() * @return int the number of rows */ public int getRowCount() { return table.getRowCount(); } /** * @see javax.swing.table.AbstractTableModel#getColumnName(int) * @param columnIndex a column number. * @return the name of the column */ public String getColumnName(int columnIndex) { return table.getColumnName(columnIndex); } /** * @see javax.swing.table.TableModel#getValueAt(int, int) * @param rowIndex int a row number * @param columnIndex int a column number * @return Object an object corresponding with a cell in the table */ public Object getValueAt(int rowIndex, int columnIndex) { return table.getValueAt(rowIndex, columnIndex); } } src/rups/com/lowagie/rups/view/models/JTableAutoModelInterface.java100644 0 0 3640 11000354133 23050 0ustar 0 0 /* * $Id: JTableAutoModelInterface.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.models; /** * Tables that contain the information necessary for creating their model * should implement this interface, so that they can use the JTableAutoModel * class as TableModel. */ public interface JTableAutoModelInterface { /** * @see javax.swing.table.TableModel#getColumnCount() * @return int the number of columns */ public int getColumnCount(); /** * @see javax.swing.table.TableModel#getRowCount() * @return int the number of rows */ public int getRowCount(); /** * @see javax.swing.table.AbstractTableModel#getColumnName(int) * @param columnIndex a column number. * @return the name of the column */ public String getColumnName(int columnIndex); /** * @see javax.swing.table.TableModel#getValueAt(int, int) * @param rowIndex int a row number * @param columnIndex int a column number * @return Object an object corresponding with a cell in the table */ public Object getValueAt(int rowIndex, int columnIndex); } src/rups/com/lowagie/rups/view/models/PdfArrayTableModel.java100644 0 0 4164 11000354133 21717 0ustar 0 0 /* * $Id: PdfArrayTableModel.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.models; import javax.swing.table.AbstractTableModel; import com.lowagie.text.pdf.PdfArray; /** * A TableModel in case we want to show a PDF array in a JTable. */ public class PdfArrayTableModel extends AbstractTableModel { /** A serial version UID. */ private static final long serialVersionUID = 4665485782853993708L; /** The PDF array. */ protected PdfArray array; /** * Creates the TableModel. * @param array a PDF array */ public PdfArrayTableModel(PdfArray array) { this.array = array; } /** * @see javax.swing.table.TableModel#getColumnCount() */ public int getColumnCount() { return 1; } /** * @see javax.swing.table.TableModel#getRowCount() */ public int getRowCount() { return array.size(); } /** * @see javax.swing.table.TableModel#getValueAt(int, int) */ public Object getValueAt(int rowIndex, int columnIndex) { switch (columnIndex) { case 0: return array.getPdfObject(rowIndex); default: return null; } } /** * @see javax.swing.table.AbstractTableModel#getColumnName(int) */ public String getColumnName(int columnIndex) { switch (columnIndex) { case 0: return "Array"; default: return null; } } } src/rups/com/lowagie/rups/view/renderer/PageField.java100644 0 0 4126 11000354134 20420 0ustar 0 0 /* * $Id: PageField.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.renderer; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JTextField; import com.lowagie.rups.view.PageNavigationListener; /** * A field that can be used to fill in a number of a page that has * to be rendered. */ public class PageField extends JTextField implements ActionListener { /** An object that listens to page change events. */ protected PageNavigationListener listener; /** * Creates the page field. * @param listener the object that listens to page navigation changes. */ public PageField(PageNavigationListener listener) { super("", 5); this.listener = listener; setMaximumSize(new Dimension(45, 32)); addActionListener(this); } /** * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent evt) { int pageNumber; try { pageNumber = Integer.parseInt(getText()); } catch (NumberFormatException nfe) { pageNumber = -1; } listener.gotoPage(pageNumber); } /** A Serial Version UID. */ private static final long serialVersionUID = 8212776141917597892L; } src/rups/com/lowagie/rups/view/renderer/PagePanel.java100644 0 0 16265 11000354134 20463 0ustar 0 0 /* * $Id: PagePanel.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * Inspired by a demo shipped with SUN's PDF Renderer (released under the LGPL) * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.renderer; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Rectangle2D; import java.awt.image.ImageObserver; import javax.swing.JPanel; import com.sun.pdfview.PDFPage; /** * The panel that will show a rendered PDF page. */ public class PagePanel extends JPanel implements ImageObserver, MouseListener, MouseMotionListener { /** A Serial Version UID. */ private static final long serialVersionUID = -130815955294007634L; /** The current PDFPage that was rendered into currentImage */ protected PDFPage currentPage; /** The image of the rendered PDF page being displayed */ protected Image currentImage; /** The horizontal offset of the image from the left edge of the panel */ protected int offx; /** The vertical offset of the image from the top of the panel */ protected int offy; /** the size of the image */ Dimension prevSize; /** the current clip, in device space */ Rectangle2D clip; /** the clipping region used for the image */ Rectangle2D prevClip; /** the zooming marquee */ protected Rectangle zoomRect; /** the current transform from device space to page space */ AffineTransform deviceToPageSpaceTransformation; /** * Creates a new PagePanel */ public PagePanel() { super(); setFocusable(true); addMouseListener(this); addMouseMotionListener(this); } /** * Gets the current page number. * @return the number of the currently shown page. */ public int getCurrentPageNumber() { if (currentPage == null) return 0; return currentPage.getPageNumber(); } /** * Draw the image. */ public void paint(Graphics g) { Dimension sz= getSize(); g.setColor(Color.DARK_GRAY); g.fillRect(0, 0, getWidth(), getHeight()); if (currentImage == null) { // No image -- draw an empty box g.setColor(Color.black); g.drawString("No page selected", getWidth()/2-30, getHeight()/2); } else { // draw the image int imwid= currentImage.getWidth(null); int imhgt= currentImage.getHeight(null); // draw it centered within the panel offx = (sz.width-imwid)/2; offy = (sz.height-imhgt)/2; if ((imwid == sz.width && imhgt <= sz.height) || (imhgt == sz.height && imwid <= sz.width)) { g.drawImage(currentImage, offx, offy, this); } else { if (currentPage!=null) { showPage(currentPage); } } } // draw the zoomrect if there is one. if (zoomRect!=null) { g.setColor(Color.red); g.drawRect(zoomRect.x, zoomRect.y, zoomRect.width, zoomRect.height); } } /** * Stop the generation of any previous page, and draw the new one. * @param page the PDFPage to draw. */ public synchronized void showPage(PDFPage page) { // stop drawing the previous page if (currentPage != null && prevSize != null) { currentPage.stop(prevSize.width, prevSize.height, prevClip); } // set up the new page currentPage= page; if (page==null) { // no page currentImage= null; clip= null; deviceToPageSpaceTransformation = null; repaint(); } else { Dimension sz= getSize(); if (sz.width + sz.height == 0) { // no image to draw. return; } // calculate the clipping rectangle in page space from the // desired clip in screen space. Rectangle2D useClip = clip; if (clip != null && deviceToPageSpaceTransformation != null) { useClip = deviceToPageSpaceTransformation.createTransformedShape(clip).getBounds2D(); } Dimension pageSize = page.getUnstretchedSize(sz.width, sz.height, useClip); // get the new image currentImage= page.getImage(pageSize.width, pageSize.height, useClip, this); // calculate the transform from screen to page space deviceToPageSpaceTransformation = page.getInitialTransform(pageSize.width, pageSize.height, useClip); try { deviceToPageSpaceTransformation = deviceToPageSpaceTransformation.createInverse(); } catch (NoninvertibleTransformException nte) { System.out.println("Error inverting page transform!"); nte.printStackTrace(); } prevClip = useClip; prevSize = pageSize; repaint(); } } /** * Handles notification of the fact that some part of the image * changed. Repaints that portion. * @return true if more updates are desired. */ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { if ((infoflags & (SOMEBITS|ALLBITS))!=0) { repaint(x + offx, y + offy, width, height); } return true; } public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseDragged(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub } } src/rups/com/lowagie/rups/view/renderer/ToolBar.java100644 0 0 5145 11000354134 20144 0ustar 0 0 /* * $Id: ToolBar.java 3117 2008-01-31 05:53:22Z xlv $ * * Copyright 2007 Bruno Lowagie. * * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com.lowagie.rups.view.renderer; import javax.swing.Box; import javax.swing.JToolBar; import com.lowagie.rups.view.PageNavigationAction; import com.lowagie.rups.view.PageNavigationListener; import com.lowagie.rups.view.icons.IconButton; /** * The Tool Bar that will be used to navigate from page to page * and change the way a page is rendered. */ public class ToolBar extends JToolBar { /** the current page number text field */ protected PageField pageField; /** * Creates the tool bar. * @param listener an object that is listening to page navigation changes. */ public ToolBar(PageNavigationListener listener) { super(); pageField = new PageField(listener); setFloatable(false); add(Box.createHorizontalGlue()); addNavigationButton(listener, PageNavigationAction.FIRST_PAGE); addNavigationButton(listener, PageNavigationAction.PREVIOUS_PAGE); add(pageField); addNavigationButton(listener, PageNavigationAction.NEXT_PAGE); addNavigationButton(listener, PageNavigationAction.LAST_PAGE); } /** * Changes the page number in the page field. * @param pageNumber the number of the currently shown page */ public void setPageNumber(int pageNumber) { if (pageNumber > 0) { pageField.setText(String.valueOf(pageNumber)); } else { pageField.setText(""); } } /** * Convenience method to create navigation buttons. * @param listener a page navigation listener * @param type a type of page navigation */ protected void addNavigationButton(PageNavigationListener listener, int type) { add(new IconButton(new PageNavigationAction(listener, type, true))); } /** A Serial Version UID. */ private static final long serialVersionUID = -2062747250230455558L; }src/test.xml100644 0 0 30750 11213370070 10514 0ustar 0 0 TESTING iText (test.xml) src/toolbox/com/lowagie/toolbox/1t3xt.gif100644 0 0 6355 11000354006 16025 0ustar 0 0 GIF89axKCDEHHIFJPJQKRLM SMN TTOUVWZ['X](Y ^*Z"_#`%a&b(c)d5d6e7f0j8g1k:h2l;i4m5n>k6o7p8q:rCsDtFuGvHwJyKzL{M|N}O~PRXYZ[\]^X_`[b\dcdkelmnhopqkrlmtnovtpwuv}w~yz{|ƒ}Ä~ƂLJĉŐŊƋnjȍ͖̒Η͘,ϙϔ-˛њ̝қ΢8ϝФХѦҧӡԨԩժ֫W٭ڭֳִabjڸܺrs߽ņƇȎˏ͗ΘРҡתڴݶ!&Created with The GIMP by Bruno Lowagie! ,xK H*\ȰÇ#JHE S CtXL'Șn˗ + A7D ϟ JGeSSc(R{3HsX׳"髷 ի7_xzD+E'w8@EL^RXW4A}{LW&Lcg=G'94u7PzSg؜7P!o7D,zCçzk 蝇pW”{ W>c gY% 6Dt1=ܢlo}7c0`2SHzr8C&Ld8PT8` PXBǓ$s|H_ԀF)0HCjEU⋟F//#˓O(VTMǙR=ԣZvq>Z<"r+pBOHæt0 EIS=}YQpv p|d<{*\Jl LΗ4c PUxb mC ٦\q 8HPwAUi@0 S7blҁEe "6\^ s bɆNld~,d/&+ꃁ_(QSC匕e h[@E u*194%?cMU,9 s=KnNE_M%h| 6Gh=QrƢLjFg9=x_U ' D&8Pp,lB6P3e/U@r;; ~#V !|P̳V=ojUhO= I=/4FX"*={CO W! _P:v#~hN$"lDzS)44AtUb~<,Q3C5DzƒuL A 9aCz*HŦ! P!(-"(FPTG"J C&1aR; $(!Ә  N1Ha?Z()p""![%"O Vy2bd<CႂAQOdL"' <ꡍ&8aB* G@$B+1lsbqGq#y!<BNAԏ!Cz)TL% L`4!q%2APb" G0-{c8`h;s&*Jxn\@@Afr"Rbקx,!D )拱AS0F8?žCAN:$Y7pJ?( #AP )V ̧/ Ex ] G=415,v(@dÇ<3ԣ'AEz2>==ń` %hdHN# yEA.4O..8 jP`,CamF *L܂Eg<;|108* f'r;|#B >0 VwL |)-6;#L Us?P7S"4D^s ` HX,y n0B R$%0h"="& <_ă D0`r8 ;~z,l2G) OCqw"ĥ Q*!Y% TR@miʼnP@dL SeDhv=/AqORJ\y2PAp ar"ej[33fp6N[e&e~S@dÿ(QB =s"8JRhTs, @ ;| 'B=L$-@-;>'0` GA=<;:$6,ޝ 얿 `dv)' 97=ZgZ}vFpD)F#-(zypRl9R&(qYK3 C6qL1~q`hʓWт b>ԍj0fyQA j!J RP) <_vj2r87Ӡlvcuq@1"Q/'c092~VPqZ#B1: (%Pc j - ~p ='I#&a&Nrs07,LSAhCH"K(;src/toolbox/com/lowagie/toolbox/AbstractTool.java100644 0 0 27042 11006315533 17643 0ustar 0 0 /* * $Id: AbstractTool.java 3276 2008-04-19 00:32:58Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox; import java.awt.Desktop; import java.awt.event.*; import java.io.File; import java.util.ArrayList; import javax.swing.*; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.tools.Executable; /** * Every iText tool has to extend this abstract class. * * @author not attributable * @version $Id: AbstractTool.java 3276 2008-04-19 00:32:58Z xlv $ * @since 2.1.1 (imported from itexttoolbox project) */ public abstract class AbstractTool implements ActionListener { /** An array with the plugin_versions of the tool. */ public static ArrayList versionsarray = new ArrayList(); /** The internal frame of the tool. */ protected JInternalFrame internalFrame = null; /** The list of arguments needed by the tool. */ protected ArrayList arguments = new ArrayList(); /** Execute menu options */ protected int menuoptions = MENU_EXECUTE; /** a menu option */ public static final int MENU_EXECUTE = 1; /** a menu option */ public static final int MENU_EXECUTE_SHOW = 2; /** a menu option */ public static final int MENU_EXECUTE_PRINT = 4; /** a menu option */ public static final int MENU_EXECUTE_PRINT_SILENT = 8; /** * awtdesktop */ private Desktop awtdesktop = null; private JMenuBar menubar; /** * AbstractTool */ public AbstractTool() { if (Desktop.isDesktopSupported()) { awtdesktop = Desktop.getDesktop(); } } /** * Sets the arguments. * @param arguments The arguments to set. */ public void setArguments(ArrayList arguments) { this.arguments = arguments; } /** * Sets the arguments. * @param args the arguments as String-array. */ public void setMainArguments(String[] args) { int counter = 0; for (AbstractArgument argument: arguments) { if (args.length > counter) { argument.setValue(args[counter]); } else { break; } counter++; } } /** * Gets the arguments. * @return Returns the arguments. */ public ArrayList getArguments() { return arguments; } /** * Gets the value of a given argument. * * @param name the name of the argument * @return the value of an argument as an Object. * @throws InstantiationException */ public Object getValue(String name) throws InstantiationException { for (AbstractArgument argument: arguments) { if (name.equals(argument.getName())) { return argument.getArgument(); } } return null; } /** * Sets the internal frame. * @param internalFrame The internalFrame to set. */ public void setInternalFrame(JInternalFrame internalFrame) { this.internalFrame = internalFrame; } public void setMenubar(JMenuBar menubar) { this.menubar = menubar; } /** * Returns the internal frame. Creates one if it's null. * @return Returns the internalFrame. */ public JInternalFrame getInternalFrame() { if (internalFrame == null) { createFrame(); } return internalFrame; } /** * Gets the menubar. * @return a menubar for this tool */ public JMenuBar getMenubar() { menubar = new JMenuBar(); JMenu tool = new JMenu(ToolMenuItems.TOOL); tool.setMnemonic(KeyEvent.VK_F); JMenuItem usage = new JMenuItem(ToolMenuItems.USAGE); usage.setMnemonic(KeyEvent.VK_U); usage.addActionListener(this); tool.add(usage); JMenuItem args = new JMenuItem(ToolMenuItems.ARGUMENTS); args.setMnemonic(KeyEvent.VK_A); args.addActionListener(this); tool.add(args); if ((menuoptions & MENU_EXECUTE) > 0) { JMenuItem execute = new JMenuItem(ToolMenuItems.EXECUTE); execute.setMnemonic(KeyEvent.VK_E); execute.addActionListener(this); tool.add(execute); } if ((menuoptions & MENU_EXECUTE_SHOW) > 0) { JMenuItem execute = new JMenuItem(ToolMenuItems.EXECUTESHOW); execute.addActionListener(this); tool.add(execute); } if ((menuoptions & MENU_EXECUTE_PRINT) > 0) { JMenuItem execute = new JMenuItem(ToolMenuItems.EXECUTEPRINT); execute.addActionListener(this); tool.add(execute); } if ((menuoptions & MENU_EXECUTE_PRINT_SILENT) > 0) { JMenuItem execute = new JMenuItem(ToolMenuItems.EXECUTEPRINTSILENT); execute.addActionListener(this); tool.add(execute); } JMenuItem close = new JMenuItem(ToolMenuItems.CLOSE); close.setMnemonic(KeyEvent.VK_C); close.addActionListener(this); tool.add(close); menubar.add(tool); if (!arguments.isEmpty()) { JMenu params = new JMenu(ToolMenuItems.ARGUMENTS); tool.setMnemonic(KeyEvent.VK_T); JMenuItem item; for (AbstractArgument argument: arguments) { item = new JMenuItem(argument.getName()); item.setToolTipText(argument.getDescription()); item.addActionListener(argument); params.add(item); } menubar.add(params); } return menubar; } /** * Gets the usage of the tool. * @return a String describing how to use the tool. */ public String getUsage() { StringBuffer buf = new StringBuffer("java "); buf.append(getClass().getName()); for (AbstractArgument argument: arguments) { buf.append(' '); buf.append(argument.getName()); } buf.append('\n'); for (AbstractArgument argument: arguments) { buf.append(argument.getUsage()); } return buf.toString(); } /** * Gets the current arguments of the tool. * @return a String with the list of arguments and their values. */ private String getArgs() { StringBuffer buf = new StringBuffer("Current arguments:\n"); for (AbstractArgument argument: arguments) { buf.append(" "); buf.append(argument.getName()); if (argument.getValue() == null) { buf.append(" = null\n"); } else { buf.append(" = '"); buf.append(argument.toString()); buf.append("'\n"); } } return buf.toString(); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param evt ActionEvent */ public void actionPerformed(ActionEvent evt) { if (ToolMenuItems.CLOSE.equals(evt.getActionCommand())) { System.out.println("=== " + getInternalFrame().getTitle() + " CLOSED ==="); internalFrame.dispose(); } if (ToolMenuItems.USAGE.equals(evt.getActionCommand())) { JOptionPane.showMessageDialog(internalFrame, getUsage()); } if (ToolMenuItems.ARGUMENTS.equals(evt.getActionCommand())) { JOptionPane.showMessageDialog(internalFrame, getArgs()); } if (ToolMenuItems.EXECUTE.equals(evt.getActionCommand())) { this.execute(); } if (ToolMenuItems.EXECUTESHOW.equals(evt.getActionCommand())) { this.execute(); try { if (awtdesktop != null && awtdesktop.isSupported(Desktop.Action.OPEN)) { awtdesktop.open(getDestPathPDF()); } else { Executable.openDocument(getDestPathPDF()); } } catch (Exception e) { System.err.println(e.getMessage()); } } if (ToolMenuItems.EXECUTEPRINT.equals(evt.getActionCommand())) { this.execute(); try { if (awtdesktop != null && awtdesktop.isSupported(Desktop.Action.PRINT)) { awtdesktop.print(getDestPathPDF()); } else { Executable.printDocument(getDestPathPDF()); } } catch (Exception e) { System.err.println(e.getMessage()); } } if (ToolMenuItems.EXECUTEPRINTSILENT.equals(evt.getActionCommand())) { this.execute(); try { Executable.printDocumentSilent(getDestPathPDF()); } catch (Exception e) { System.err.println(e.getMessage()); } } } /** * Gets the PDF file that should be generated (or null if the output isn't a PDF file). * @return the PDF file that should be generated * @throws InstantiationException */ protected abstract File getDestPathPDF() throws InstantiationException; /** * Creates the internal frame. */ protected abstract void createFrame(); /** * Executes the tool (in most cases this generates a PDF file). */ public abstract void execute(); /** * Indicates that the value of an argument has changed. * @param arg the argument that has changed */ public abstract void valueHasChanged(AbstractArgument arg); /** * Add the version of the plugin to the plugin_versions array. * @param version the version to add. */ protected static void addVersion(String version) { version = version.substring(5, version.length() - 2); versionsarray.add(version); } } src/toolbox/com/lowagie/toolbox/ToolMenuItems.java100644 0 0 5534 11006315533 17770 0ustar 0 0 /* * $Id: ToolMenuItems.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This code was originally published under the MPL by Bruno Lowagie. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox; /** * Keeps all the possible menuitems. * @since 2.1.1 (imported from itexttoolbox project) */ public class ToolMenuItems { /** An item in the menubar. */ public static final String FILE = "File"; /** An item in the menubar. */ public static final String CLOSE = "Close"; /** An item in the menubar. */ public static final String TOOLS = "Tools"; public static final String FILELIST = "Filelist"; public static final String VIEW = "View"; public static final String RESET = "Reset"; /** An item in the menubar. */ public static final String HELP = "Help"; /** An item in the menubar. */ public static final String VERSION = "Version"; /** An item in the menubar. */ public static final String ABOUT = "About"; /** An item in the menubar. */ public static final String TOOL = "Tool"; /** An item in the menubar. */ public static final String USAGE = "Usage"; /** An item in the menubar. */ public static final String ARGUMENTS = "Arguments"; /** An item in the menubar. */ public static final String EXECUTE = "Execute"; /** An item in the menubar. */ public static final String EXECUTESHOW = "Execute+Open"; /** An item in the menubar. */ public static final String EXECUTEPRINT = "Execute+Printdialog"; /** An item in the menubar. */ public static final String EXECUTEPRINTSILENT = "Execute+Print"; } src/toolbox/com/lowagie/toolbox/Toolbox.java100644 0 0 41101 11006315533 16660 0ustar 0 0 /* * $Id: Toolbox.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.text.*; import com.lowagie.tools.Executable; /** * This is a utility that allows you to use a number of iText tools. * @since 2.1.1 (imported from itexttoolbox project) */ public class Toolbox extends JFrame implements ActionListener { /** A serial version ID */ private static final long serialVersionUID = -3766198389452935073L; /** The DesktopPane of the toolbox. */ private JDesktopPane desktop; /** The ConsolePane of the toolbox. */ private JScrollPane console; /** The list of tools in the toolbox. */ private Properties toolmap = new Properties(); /** x-coordinate of the location of a new internal frame. */ private int locationX = 0; /** y-coordinate of the location of a new internal frame. */ private int locationY = 0; /** * toolarray */ private ArrayList toolarray = new ArrayList(); private Vector menulist=new Vector(); private Vector menuitemlist=new Vector(); /** * Constructs the Toolbox object. */ public Toolbox() { super(); setSize(600, 500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(true); setTitle("iText Toolbox"); desktop = new JDesktopPane(); setJMenuBar(getMenubar()); setIconImage(new ImageIcon(com.lowagie.toolbox.Toolbox.class.getResource( "1t3xt.gif")).getImage()); Console c; try { c = new Console(); console = new JScrollPane(c.textArea); } catch (IOException e) { e.printStackTrace(); } JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, desktop, console); splitPane.setContinuousLayout(true); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(300); setContentPane(splitPane); centerFrame(this); setVisible(true); } /** * Starts the Toolbox utility. * * use as first argument the name of the plugin, * then the arguments of the plugin used. * * e.g. * * java -jar itext.jar Burst inputfile.pdf * * That way you can call plugins by name directly. * * @param args * no arguments needed */ public static void main(String[] args) { try { Class.forName("com.lowagie.text.Document"); } catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(null, "You need the iText.jar in your CLASSPATH!", e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.exit(1); } Toolbox toolbox = new Toolbox(); if (args.length > 0) { try { AbstractTool tool = toolbox.createFrame(args[0]); String[] nargs = new String[args.length - 1]; System.arraycopy(args, 1, nargs, 0, args.length - 1); tool.setMainArguments(nargs); tool.execute(); } catch (PropertyVetoException ex) { } catch (ClassNotFoundException ex) { } catch (IllegalAccessException ex) { } catch (InstantiationException ex) { } } } /** * Gets the menubar. * * @return a menubar */ private JMenuBar getMenubar() { Properties p = new Properties(); try { p.load(Toolbox.class.getClassLoader().getResourceAsStream( "com/lowagie/toolbox/tools.txt")); String usertoolstxt = System.getProperty("user.home") + System.getProperty("file.separator") + "tools.txt"; File uttf = new File(usertoolstxt); if (uttf.isFile() && uttf.exists()) { p.load(new FileInputStream(usertoolstxt)); } } catch (IOException e) { e.printStackTrace(); } toolmap = new Properties(); JMenuBar menubar = new JMenuBar(); JMenu file = new JMenu(ToolMenuItems.FILE); file.setMnemonic(KeyEvent.VK_T); JMenuItem close = new JMenuItem(ToolMenuItems.CLOSE); close.setMnemonic(KeyEvent.VK_C); close.addActionListener(this); file.add(close); JMenu view = new JMenu(ToolMenuItems.VIEW); JMenuItem reset = new JMenuItem(ToolMenuItems.RESET); reset.addActionListener(this); view.add(reset); // JMenuItem filelist = new JMenuItem(FILELIST); // filelist.addActionListener(this); // view.add(filelist); JMenu tools = new JMenu(ToolMenuItems.TOOLS); // Here one day should be the wizard to help you create a new beanshell script // JMenuItem create = new JMenuItem(CREATE); // create.addActionListener(this); // tools.add(create); buildPluginMenuItems(new TreeMap(p), tools); JMenu help = new JMenu(ToolMenuItems.HELP); JMenuItem about = new JMenuItem(ToolMenuItems.ABOUT); // about.setIcon(new ImageIcon(Toolbox.class.getResource( // "Help24.gif"))); about.setMnemonic(KeyEvent.VK_A); about.addActionListener(this); help.add(about); JMenuItem versions = new JMenuItem(ToolMenuItems.VERSION); // versions.setIcon(new ImageIcon(Toolbox.class.getResource( // "About24.gif"))); versions.addActionListener(this); help.add(versions); menubar.add(file); menubar.add(tools); menubar.add(view); menubar.add(Box.createGlue()); menubar.add(help); return menubar; } /** * BuildPluginMenuItems * * @param tmp Map * @param tools JMenu */ private void buildPluginMenuItems(Map tmp, JMenu tools) { String name, tool; JMenu current = null; JMenuItem item; for (Map.Entry entry: tmp.entrySet()) { name = (String) entry.getKey(); if (current == null || !name.startsWith(current.getText())) { String menu = name.substring(0, name.indexOf('.')); menulist.add(menu); current = new JMenu(menu); tools.add(current); } String menuitem = name.substring(current.getText().length() + 1); menuitemlist.add(menuitem); item = new JMenuItem(menuitem); item.addActionListener(this); tool = (String) entry.getValue(); try { if (Class.forName(tool) != null) { toolmap.put(item.getText(), tool); current.add(item); } } catch (ClassNotFoundException e) { System.err.println("Plugin " + name + " was not found in your CLASSPATH."); } } } /** * Creates an Internal Frame. * * @param name the name of the application * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException * @throws PropertyVetoException * @return AbstractTool */ public AbstractTool createFrame(String name) throws InstantiationException, IllegalAccessException, ClassNotFoundException, PropertyVetoException { AbstractTool ti = null; String classname = (String) toolmap.get(name); ti = (AbstractTool) Class.forName(classname).newInstance(); toolarray.add(ti); JInternalFrame f = ti.getInternalFrame(); f.setLocation(locationX, locationY); locationX += 25; if (locationX > this.getWidth() + 50) { locationX = 0; } locationY += 25; if (locationY > this.getHeight() + 50) { locationY = 0; } f.setVisible(true); desktop.add(f); f.setSelected(true); return ti; } /** * Centers a JFrame. * * @param f JFrame */ public static void centerFrame(Frame f) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = f.getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } f.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param evt ActionEvent */ public void actionPerformed(ActionEvent evt) { if (ToolMenuItems.CLOSE.equals(evt.getActionCommand())) { System.out.println("The Toolbox is closed."); System.exit(0); } else if (ToolMenuItems.ABOUT.equals(evt.getActionCommand())) { System.out .println("The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info."); try { Executable .launchBrowser("http://itexttoolbox.sourceforge.net/"); } catch (IOException ioe) { JOptionPane .showMessageDialog( this, "The iText Toolbox is part of iText, a Free Java-PDF Library.\nVisit http://itexttoolbox.sourceforge.net/ for more info."); } } else if (ToolMenuItems.RESET.equals(evt.getActionCommand())) { JInternalFrame[] framearray = desktop.getAllFrames(); int xx = 0, yy = 0; for (int i = 0; i < framearray.length; i++) { if (!framearray[i].isIcon()) { try { int frameDistance = framearray[i].getHeight() - framearray[i].getContentPane(). getHeight(); framearray[i].setMaximum(false); int fwidth = framearray[i].getWidth(); int fheight = framearray[i].getHeight(); framearray[i].reshape(xx, yy, fwidth, fheight); xx += frameDistance; yy += frameDistance; if (xx + fwidth > desktop.getWidth()) { xx = 0; } if (yy + fheight > desktop.getHeight()) { yy = 0; } } catch (PropertyVetoException e) { } } } } else if (ToolMenuItems.VERSION.equals(evt.getActionCommand())) { JFrame f = new Versions(); centerFrame(f); f.setVisible(true); } else { try { createFrame(evt.getActionCommand()); } catch (Exception e) { e.printStackTrace(); } } } /** * A Class that redirects output to System.out and System.err. */ public class Console { class ErrorContext extends StyleContext { private static final long serialVersionUID = 7766294638325167438L; public static final String STDERROR = "Error"; public static final String STDOUT = "StdOut"; public ErrorContext() { super(); Style root = getStyle(DEFAULT_STYLE); Style s = addStyle(STDERROR, root); StyleConstants.setForeground(s, Color.RED); s = addStyle(STDOUT, root); StyleConstants.setForeground(s, Color.BLACK); } } PipedInputStream piOut; PipedInputStream piErr; PipedOutputStream poOut; PipedOutputStream poErr; ErrorContext errorcontext = new ErrorContext(); JTextPane textArea = new JTextPane(new DefaultStyledDocument( errorcontext)); PrintStream oriout; PrintStream orierr; /** * Creates a new Console object. * @throws IOException */ public Console() throws IOException { // Set up System.out piOut = new PipedInputStream(); poOut = new PipedOutputStream(piOut); oriout = System.out; System.setOut(new PrintStream(poOut, true)); // Set up System.err piErr = new PipedInputStream(); poErr = new PipedOutputStream(piErr); orierr = System.err; System.setErr(new PrintStream(poErr, true)); // Add a scrolling text area textArea.setEditable(false); // Create reader threads new ReaderThread(piOut, ErrorContext.STDOUT).start(); new ReaderThread(piErr, ErrorContext.STDERROR).start(); } class ReaderThread extends Thread { PipedInputStream pi; String type; ReaderThread(PipedInputStream pi, String type) { this.pi = pi; this.type = type; } /** * @see java.lang.Thread#run() */ public void run() { final byte[] buf = new byte[1024]; while (true) { try { final int len = pi.read(buf); if (len == -1) { break; } javax.swing.text.Document doc = textArea.getDocument(); AttributeSet attset = errorcontext.getStyle(type); String snippet = new String(buf, 0, len); doc.insertString(doc.getLength(), snippet, attset); oriout.print(snippet); textArea.setCaretPosition(textArea.getDocument(). getLength()); } catch (BadLocationException ex) { } catch (IOException e) { } } } } } public Vector getMenulist() { return menulist; } } src/toolbox/com/lowagie/toolbox/Versions.java100644 0 0 17112 11012562263 17050 0ustar 0 0 /* * $Id: Versions.java 3372 2008-05-12 03:16:52Z xlv $ * Copyright (c) 2005-2007 Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie, * Paulo Soares, and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ /* * This class was originally written by Carsten Hammer. * Changes were made by Bruno Lowagie, Paulo Soares and Xavier Le Vourch. * These people were contacted before changing the license from MPL/LGPL to MIT. * Current copyright holders are Bruno Lowagie and Carsten Hammer. */ package com.lowagie.toolbox; import java.awt.BorderLayout; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Properties; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableModel; import com.lowagie.text.Document; import javax.swing.ImageIcon; import javax.swing.RowSorter; import javax.swing.table.TableRowSorter; /** * JFrame that shows the plugin_versions of all the plugins. * @since 2.1.1 (imported from itexttoolbox project) */ public class Versions extends JFrame { /** The serial version UID of this class. */ private static final long serialVersionUID = 2925242862240301106L; /** A label with info about the library, JVM,... */ JLabel library_versions = new JLabel(); /** The table with all the plug-ins (name, version and date). */ JTable plugin_versions = new JTable(); /** A scrollpane for the plugin_versions table. */ JScrollPane scroll_versions = new JScrollPane(); /** Constructs a Versions object. */ public Versions() { super("Plugins and their version"); try { initialize(); } catch (Exception ex) { ex.printStackTrace(); } } /** * Initialization of the jFrame. * * @throws Exception */ private void initialize() throws Exception { this.getContentPane().setLayout(new BorderLayout()); scroll_versions.setViewportView(plugin_versions); library_versions.setIcon(new ImageIcon(Versions.class.getResource( "1t3xt.gif"))); this.getContentPane().add(library_versions, BorderLayout.NORTH); this.getContentPane().add(scroll_versions, BorderLayout.CENTER); Properties properties = System.getProperties(); Runtime runtime = Runtime.getRuntime(); StringBuffer sb = new StringBuffer(); sb.append(""); sb.append("

      iTexttoolbox version: " + Versions.class.getPackage().getImplementationVersion() + "

      "); sb.append("

      iText version: " + Document.getVersion() + "

      "); sb.append("

      java.version: " + properties.getProperty("java.version") + "

      "); sb.append("

      java.vendor: " + properties.getProperty("java.vendor") + "

      "); sb.append("

      java.home: " + properties.getProperty("java.home") + "

      "); sb.append("

      java.freeMemory: " + runtime.freeMemory() + " bytes" + "

      "); sb.append("

      java.totalMemory: " + runtime.totalMemory() + " bytes" + "

      "); sb.append("

      user.home: " + properties.getProperty("user.home") + "

      "); sb.append("

      os.name: " + properties.getProperty("os.name") + "

      "); sb.append("

      os.arch: " + properties.getProperty("os.arch") + "

      "); sb.append("

      os.version: " + properties.getProperty("os.version") + "

      "); sb.append(""); library_versions.setText(sb.toString()); TableModel model = getVersionTableModel(AbstractTool.versionsarray); RowSorter sorter = new TableRowSorter (model); plugin_versions.setRowSorter(sorter); plugin_versions.setModel(model); pack(); } /** * Returns the TableModel implementation that will be used to show the plugin_versions. * * @param versionsarray ArrayList * @return TableModel */ public TableModel getVersionTableModel(final ArrayList versionsarray) { return new AbstractTableModel() { private static final long serialVersionUID = 5105003782164682777L; public int getColumnCount() { return 4; } public int getRowCount() { return versionsarray.size(); } public Object getValueAt(int rowIndex, int columnIndex) { String dummy; switch (columnIndex) { case 0: dummy = versionsarray.get(rowIndex); return dummy.split(".java")[0]; case 1: dummy = versionsarray.get(rowIndex); return dummy.split(" ")[1]; case 2: DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dummy = versionsarray.get(rowIndex); try { return df.parse(dummy.split(" ")[2] + " " + dummy.split(" ")[3]); } catch (ParseException ex) { return null; } case 3: dummy = versionsarray.get(rowIndex); return dummy.split(" ")[4]; } return versionsarray; } public String getColumnName(int column) { switch (column) { case 0: return "Name"; case 1: return "Version"; case 2: return "Changed"; case 3: return "ChangeBy"; default: return ""; } } public Class getColumnClass(int column) { switch (column) { case 0: return String.class; case 1: return String.class; case 2: return java.util.Date.class; case 3: return String.class; default: return null; } } }; } /** * Main method (test purposes only) * * @param args String[] */ public static void main(String[] args) { Versions version = new Versions(); version.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); version.setVisible(true); } } src/toolbox/com/lowagie/toolbox/arguments/AbstractArgument.java100644 0 0 7752 11006342354 22504 0ustar 0 0 package com.lowagie.toolbox.arguments; import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import com.lowagie.toolbox.AbstractTool; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * @since 2.1.1 (imported from itexttoolbox project) */ public abstract class AbstractArgument implements ActionListener, PropertyChangeListener{ public AbstractArgument() { } public AbstractArgument(AbstractTool tool, String name, String description, Object value) { this.tool = tool; this.name = name; this.description = description; this.value=value; } protected PropertyChangeSupport pcs = new PropertyChangeSupport(this); /** value of the argument. */ protected Object value = null; /** short name for the argument. */ protected String name; /** reference to the internal frame */ protected AbstractTool tool; /** describes the argument. */ protected String description; protected synchronized void firePropertyChange(PropertyChangeEvent evt) { pcs.firePropertyChange(evt); } public synchronized void removePropertyChangeListener( PropertyChangeListener l) { pcs.removePropertyChangeListener(l); } public synchronized void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); } /** * @return Returns the value. */ public Object getValue() { return value; } public void setValue(Object value, String propertyname) { Object oldvalue = this.value; this.value = value; tool.valueHasChanged(this); this.firePropertyChange(new PropertyChangeEvent(this, propertyname, oldvalue, this.value)); } /** * @param description * The description to set. */ public void setDescription(String description) { this.description = description; } /** * @return Returns the description. */ public String getDescription() { return description; } /** * @param name * The name to set. */ public void setName(String name) { this.name = name; } /** * Give you a String that can be used in a usage description. * * @return a String */ public String getUsage() { StringBuffer buf = new StringBuffer(" "); buf.append(name); buf.append(" - "); buf.append(description); buf.append('\n'); return buf.toString(); } public AbstractTool getTool() { return tool; } public void setTool(AbstractTool tool) { this.tool = tool; } /** * Gets the argument as an object. * * @return an object * @throws InstantiationException */ public Object getArgument() throws InstantiationException { if (value == null) { return null; } return value; } /** * @return Returns the name. */ public String getName() { return name; } /** * @param value * The value to set. */ public void setValue(Object value) { Object oldvalue = this.value; this.value = value; tool.valueHasChanged(this); this.firePropertyChange(new PropertyChangeEvent(this, name, oldvalue, this.value)); } public void propertyChange(PropertyChangeEvent evt) { System.out.println("AbstractArgument PropertyChange"); } public abstract void actionPerformed(ActionEvent e); /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return getValue().toString(); } } src/toolbox/com/lowagie/toolbox/arguments/BitsetArgument.java100644 0 0 10311 11006315533 22173 0ustar 0 0 /* * $Id: BitsetArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import javax.swing.JCheckBox; import javax.swing.JOptionPane; import com.lowagie.toolbox.AbstractTool; /** * Argument that results in a set of "1" and "0" values. * @since 2.1.1 (imported from itexttoolbox project) */ public class BitsetArgument extends AbstractArgument { /** These are the different options that can be true or false. */ private JCheckBox[] options; /** * Constructs an BitsetArgument. * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument * @param options the different options that can be true or false */ public BitsetArgument(AbstractTool tool, String name, String description, String[] options) { super(tool, name, description, null); this.options = new JCheckBox[options.length]; for (int i = 0; i < options.length; i++) { this.options[i] = new JCheckBox(options[i]); } } /** * * @see com.lowagie.toolbox.arguments.StringArgument#getUsage() * @return String */ public String getUsage() { StringBuffer buf = new StringBuffer(super.getUsage()); buf.append(" possible options:\n"); for (int i = 0; i < options.length; i++) { buf.append(" - "); buf.append(options[i].getText()); buf.append('\n'); } return buf.toString(); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param evt ActionEvent */ public void actionPerformed(ActionEvent evt) { Object[] message = new Object[1 + options.length]; message[0] = "Check the options you need:"; System.arraycopy(options, 0, message, 1, options.length); int result = JOptionPane.showOptionDialog( tool.getInternalFrame(), message, description, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null ); if (result == 0) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < options.length; i++) { if (options[i].isSelected()) { buf.append('1'); } else { buf.append('0'); } } setValue(buf.toString()); } } } src/toolbox/com/lowagie/toolbox/arguments/ColorArgument.java100644 0 0 5736 11006315533 22016 0ustar 0 0 /* * $Id: ColorArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.Color; import java.awt.event.ActionEvent; import javax.swing.JColorChooser; import com.lowagie.toolbox.AbstractTool; /** * @since 2.1.1 (imported from itexttoolbox project) */ public class ColorArgument extends AbstractArgument { public ColorArgument() { super(); } public ColorArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); } public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return Color.decode(value.toString()); } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } public void actionPerformed(ActionEvent e) { Color initialColor = new Color(0xFF, 0xFF, 0xFF); if (value != null) { initialColor = Color.decode(value.toString()); } Color newColor = JColorChooser.showDialog(tool.getInternalFrame(), "Choose Color", initialColor); setValue("0x" + Integer.toHexString( (newColor.getRed() << 16) | (newColor.getGreen() << 8) | (newColor.getBlue() << 0)).toUpperCase()); } } src/toolbox/com/lowagie/toolbox/arguments/FileArgument.java100644 0 0 12462 11006315533 21631 0ustar 0 0 /* * $Id: FileArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import java.io.File; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.filters.DirFilter; import com.lowagie.toolbox.swing.PdfInformationPanel; /** * FileArgument class if the argument is a java.io.File. * @since 2.1.1 (imported from itexttoolbox project) */ public class FileArgument extends AbstractArgument { /** a filter to put on the FileChooser. */ protected FileFilter filter; /** indicates if the argument has to point to a new or an existing file. */ protected boolean newFile; /** the label */ PdfInformationPanel label = null; public FileArgument() { super(); } /** * Constructs a FileArgument. * * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument * @param newFile makes the difference between an Open or Save dialog * @param filter FileFilter */ public FileArgument(AbstractTool tool, String name, String description, boolean newFile, FileFilter filter) { super(tool, name, description, null); this.newFile = newFile; this.filter = filter; } /** * Constructs a FileArgument. * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument * @param newFile makes the difference between an Open or Save dialog */ public FileArgument(AbstractTool tool, String name, String description, boolean newFile) { this(tool, name, description, newFile, null); } /** * Gets the argument as an object. * @return an object * @throws InstantiationException */ public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return new File(value.toString()); } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (filter != null) { fc.setFileFilter(filter); if (filter instanceof DirFilter) { fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } } if (label != null) { fc.setAccessory(label); fc.addPropertyChangeListener( JFileChooser.SELECTED_FILE_CHANGED_PROPERTY, label); } if (newFile) { fc.showSaveDialog(tool.getInternalFrame()); } else { fc.showOpenDialog(tool.getInternalFrame()); } try { setValue(fc.getSelectedFile()); } catch (NullPointerException npe) { } } /** * @return Returns the filter. */ public FileFilter getFilter() { return filter; } /** * @param filter The filter to set. */ public void setFilter(FileFilter filter) { this.filter = filter; } /** * @return Returns the label. */ public PdfInformationPanel getLabel() { return label; } /** * @param label The label to set. */ public void setLabel(PdfInformationPanel label) { this.label = label; } } src/toolbox/com/lowagie/toolbox/arguments/FileArrayArgument.java100644 0 0 10000 11006342354 22613 0ustar 0 0 /* * $Id: FileArrayArgument.java 3297 2008-05-01 12:19:24Z blowagie $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.io.File; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.swing.FileList; /** * @since 2.1.1 (imported from itexttoolbox project) */ public class FileArrayArgument extends AbstractArgument { public FileArrayArgument() { super(); try { jbInit(); } catch (Exception ex) { ex.printStackTrace(); } } public FileArrayArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); try { jbInit(); } catch (Exception ex) { ex.printStackTrace(); } } public void actionPerformed(ActionEvent e) { fileList1.setLocation(10, 10); fileList1.setVisible(true); this.getTool().getInternalFrame().getDesktopPane().add(fileList1); try { fileList1.setSelected(true); } catch (PropertyVetoException ex1) { System.out.println(ex1.getMessage()); } // try { // setValue(fileList1.getFilevector().toArray()); // } catch (NullPointerException npe) { // } } public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return value; } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } public static void main(String[] args) { FileArrayArgument filearrayargument = new FileArrayArgument(); } private void jbInit() throws Exception { fileList1.addPropertyChangeListener(this); } FileList fileList1 = new FileList(); public void propertyChange(PropertyChangeEvent evt) { String propertyname = evt.getPropertyName(); if (propertyname.equals("filevector")) { File[] filear = (File[]) evt.getNewValue(); if (filear != null) { this.setValue(filear); } } } /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return fileList1.getStringreprasentation(); } } src/toolbox/com/lowagie/toolbox/arguments/FloatArgument.java100644 0 0 4704 11006342354 22000 0ustar 0 0 /* * $Id: FloatArgument.java 3297 2008-05-01 12:19:24Z blowagie $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.swing.CustomDialog; /** * @since 2.1.1 (imported from itexttoolbox project) */ public class FloatArgument extends AbstractArgument { public FloatArgument() { super(); } public FloatArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); } /** * Invoked when an action occurs. * * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { CustomDialog cd=new CustomDialog("Enter a value for " + name + ":",CustomDialog.instantiateFloatDocument()); setValue(cd.showInputDialog(this.getValue()==null?"0":this.getValue().toString())); } } src/toolbox/com/lowagie/toolbox/arguments/ImageArgument.java100644 0 0 7564 11006315533 21763 0ustar 0 0 /* * $Id: ImageArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import com.lowagie.text.Image; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.filters.ImageFilter; /** * StringArgument class if the argument is a com.lowagie.text.Image. * @since 2.1.1 (imported from itexttoolbox project) */ public class ImageArgument extends AbstractArgument { /** a filter to put on the FileChooser. */ private FileFilter filter; /** * Constructs a FileArgument. * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument * @param filter a custom filter */ public ImageArgument(AbstractTool tool, String name, String description, FileFilter filter) { super(tool, name, description, null); this.filter = filter; } /** * Constructs a FileArgument. * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument */ public ImageArgument(AbstractTool tool, String name, String description) { this(tool, name, description, new ImageFilter()); } /** * Gets the argument as an object. * @return an object * @throws InstantiationException */ public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return Image.getInstance(value.toString()); } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); if (filter != null) { fc.setFileFilter(filter); } fc.showOpenDialog(tool.getInternalFrame()); try { setValue(fc.getSelectedFile().getAbsolutePath()); } catch (NullPointerException npe) { } } } src/toolbox/com/lowagie/toolbox/arguments/IntegerArgument.java100644 0 0 5631 11006315533 22327 0ustar 0 0 /* * $Id: IntegerArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.swing.CustomDialog; /** * This is an argument of one of the tools in the toolbox. * @since 2.1.1 (imported from itexttoolbox project) */ public class IntegerArgument extends AbstractArgument { /** Constructs a IntegerArgument. */ public IntegerArgument() { } /** * Constructs a IntegerArgument. * * @param tool * the tool that needs this argument * @param name * the name of the argument * @param description * the description of the argument */ public IntegerArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { CustomDialog cd = new CustomDialog("Enter a value for " + name + ":", CustomDialog.instantiateIntegerDocument()); setValue(cd.showInputDialog(this.getValue()==null?"0":this.getValue().toString())); } } src/toolbox/com/lowagie/toolbox/arguments/OptionArgument.java100644 0 0 14767 11006315533 22234 0ustar 0 0 /* * $Id: OptionArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import java.util.TreeMap; import javax.swing.JComboBox; import javax.swing.JOptionPane; import com.lowagie.toolbox.AbstractTool; /** * Argument that can be one of several options. * @since 2.1.1 (imported from itexttoolbox project) */ public class OptionArgument extends AbstractArgument { /** * An Entry that can be chosen as option. */ public class Entry { /** Describes the option. */ private Object description; /** Holds the actual value of the option. */ private Object value; /** * Constructs an entry. * @param value the value of the entry (that will be identical to the description) */ public Entry(Object value) { this.value = value; this.description = value; } /** * Constructs an entry. * @param description the description of the entry * @param value the value of the entry */ public Entry(Object description, Object value) { this.description = description; this.value = value; } /** * String representation of the Entry. * @return a description of the entry */ public String toString() { return description.toString(); } /** * Gets the value of the String. * @return the toString of the value */ public String getValueToString() { return value.toString(); } /** * @return Returns the description. */ public Object getDescription() { return description; } /** * @param description The description to set. */ public void setDescription(Object description) { this.description = description; } /** * @return Returns the value. */ public Object getValue() { return value; } /** * @param value The value to set. */ public void setValue(Object value) { this.value = value; } } private TreeMap options = new TreeMap(); /** * Constructs an OptionArgument. * @param tool the tool that needs this argument * @param name the name of the argument * @param description the description of the argument */ public OptionArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); // this.setClassname(new Entry("").getClass().getName()); } /** * Adds an Option. * @param description the description of the option * @param value the value of the option */ public void addOption(Object description, Object value) { options.put(value.toString(), new Entry(description, value)); } /** * Gets the argument as an object. * @return an object * @throws InstantiationException */ public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return options.get(value).getValue(); } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } /** * * @see com.lowagie.toolbox.arguments.StringArgument#getUsage() * @return String */ public String getUsage() { StringBuffer buf = new StringBuffer(super.getUsage()); buf.append(" possible options:\n"); for (Entry entry: options.values()) { buf.append(" - "); buf.append(entry.getValueToString()); buf.append(": "); buf.append(entry.toString()); buf.append('\n'); } return buf.toString(); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param evt ActionEvent */ public void actionPerformed(ActionEvent evt) { Object[] message = new Object[2]; message[0] = "Choose one of the following options:"; JComboBox cb = new JComboBox(); for (Entry entry: options.values()) { cb.addItem(entry); } message[1] = cb; int result = JOptionPane.showOptionDialog( tool.getInternalFrame(), message, description, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null ); if (result == 0) { Entry entry = (Entry) cb.getSelectedItem(); setValue(entry.getValueToString()); } } } src/toolbox/com/lowagie/toolbox/arguments/PageSizeArgument.java100644 0 0 13023 11006342354 22454 0ustar 0 0 /* * $Id: PageSizeArgument.java 3297 2008-05-01 12:19:24Z blowagie $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import java.lang.reflect.Field; import java.util.Iterator; import java.util.TreeMap; import javax.swing.JComboBox; import javax.swing.JOptionPane; import com.lowagie.text.PageSize; import com.lowagie.toolbox.AbstractTool; /** * Argument that can be one of several options. * @since 2.1.1 (imported from itexttoolbox project) */ public class PageSizeArgument extends OptionArgument { private TreeMap options = new TreeMap(); /** * Constructs an OptionArgument. * * @param tool * the tool that needs this argument * @param name * the name of the argument * @param description * the description of the argument */ public PageSizeArgument(AbstractTool tool, String name, String description) { super(tool, name, description); Class ps = PageSize.class; Field[] sizes = ps.getDeclaredFields(); try { for (int i = 0; i < sizes.length; i++) { addOption(sizes[i].getName(), sizes[i].get(null)); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } /** * Adds an Option. * @param description the description of the option * @param value the value of the option */ public void addOption(Object description, Object value) { options.put(description, value); } /** * Gets the options. * @return Returns the options. */ public TreeMap getOptions() { return options; } /** * Gets the argument as an object. * @return an object * @throws InstantiationException */ public Object getArgument() throws InstantiationException { if (value == null) { return null; } try { return options.get(value); } catch (Exception e) { throw new InstantiationException(e.getMessage()); } } /** * * @see com.lowagie.toolbox.arguments.StringArgument#getUsage() * @return String */ public String getUsage() { StringBuffer buf = new StringBuffer(" "); buf.append(name); buf.append(" - "); buf.append(description); buf.append('\n'); buf.append(" possible options:\n"); String s; for (Iterator i = options.keySet().iterator(); i.hasNext(); ) { s = (String) i.next(); buf.append(" - "); buf.append(s); buf.append('\n'); } return buf.toString(); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param evt ActionEvent */ public void actionPerformed(ActionEvent evt) { Object[] message = new Object[2]; message[0] = "Choose one of the following pagesizes:"; JComboBox cb = new JComboBox(); for(Iterator i = options.keySet().iterator(); i.hasNext(); ) { cb.addItem(i.next()); } message[1] = cb; int result = JOptionPane.showOptionDialog( tool.getInternalFrame(), message, description, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null ); if (result == 0) { setValue(cb.getSelectedItem()); } } /** * Returns a string representation of the object. * * @return a string representation of the object. */ public String toString() { return super.getValue().toString(); } } src/toolbox/com/lowagie/toolbox/arguments/StringArgument.java100644 0 0 5676 11006315533 22211 0ustar 0 0 /* * $Id: StringArgument.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments; import java.awt.event.ActionEvent; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.swing.CustomDialog; /** * This is an argument of one of the tools in the toolbox. * @since 2.1.1 (imported from itexttoolbox project) */ public class StringArgument extends AbstractArgument { /** Constructs a StringArgument. */ public StringArgument() { } /** * Constructs a StringArgument. * * @param tool * the tool that needs this argument * @param name * the name of the argument * @param description * the description of the argument */ public StringArgument(AbstractTool tool, String name, String description) { super(tool, name, description, null); } /** * * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) * @param e ActionEvent */ public void actionPerformed(ActionEvent e) { CustomDialog cd = new CustomDialog("Enter a value for " + name + ":", CustomDialog. instantiateStringDocument()); setValue(cd.showInputDialog(this.getValue()==null?"":this.getValue().toString())); } } src/toolbox/com/lowagie/toolbox/arguments/filters/DirFilter.java100644 0 0 4372 11006315533 22564 0ustar 0 0 /* * $Id: DirFilter.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 by Johannes Schindelin * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Johannes Schindelin. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments.filters; import java.io.File; import javax.swing.filechooser.FileFilter; /** * Filters directories in a JFileChooser. * @since 2.1.1 (imported from itexttoolbox project) */ public class DirFilter extends FileFilter { /** * * @see javax.swing.filechooser.FileFilter#accept(java.io.File) * @param f File * @return boolean */ public boolean accept(File f) { if (f.isDirectory()) return true; return false; } /** * * @see javax.swing.filechooser.FileFilter#getDescription() * @return String */ public String getDescription() { return "directories"; } } src/toolbox/com/lowagie/toolbox/arguments/filters/ImageFilter.java100644 0 0 7202 11006315533 23063 0ustar 0 0 /* * $Id: ImageFilter.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments.filters; import java.io.File; import javax.swing.filechooser.FileFilter; /** * Filters images in a FileChooser. * @since 2.1.1 (imported from itexttoolbox project) */ public class ImageFilter extends FileFilter { /** Array with all kinds of image extensions. */ public static final String[] IMAGES = new String[8]; static { IMAGES[0] = ".jpg"; IMAGES[1] = ".jpeg"; IMAGES[2] = ".png"; IMAGES[3] = ".gif"; IMAGES[4] = ".bmp"; IMAGES[5] = ".wmf"; IMAGES[6] = ".tif"; IMAGES[7] = ".tiff"; } /** array that enables you to filter on image types. */ public boolean[] filter = new boolean[8]; /** * Constructs an ImageFilter allowing all images. */ public ImageFilter() { for (int i = 0; i < filter.length; i++) { filter[i] = true; } } /** * Constructs an ImageFilter allowing some images. * @param jpeg indicates if jpegs are allowed * @param png indicates if pngs are allowed * @param gif indicates if gifs are allowed * @param bmp indicates if bmps are allowed * @param wmf indicates if wmfs are allowed * @param tiff indicates if tiffs are allowed */ public ImageFilter(boolean jpeg, boolean png, boolean gif, boolean bmp, boolean wmf, boolean tiff) { if (jpeg) { filter[0] = true; filter[1] = true; } if (png) { filter[2] = true; } if (gif) { filter[3] = true; } if (bmp) { filter[4] = true; } if (wmf) { filter[5] = true; } if (tiff) { filter[6] = true; filter[7] = true; } } /** * * @see javax.swing.filechooser.FileFilter#accept(java.io.File) * @param f File * @return boolean */ public boolean accept(File f) { if (f.isDirectory()) return true; for (int i = 0; i < IMAGES.length; i++) { if (filter[i] && f.getName().toLowerCase().endsWith(IMAGES[i])) return true; } return false; } /** * * @see javax.swing.filechooser.FileFilter#getDescription() * @return String */ public String getDescription() { return "Image files"; } } src/toolbox/com/lowagie/toolbox/arguments/filters/PdfFilter.java100644 0 0 4476 11006315533 22564 0ustar 0 0 /* * $Id: PdfFilter.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments.filters; import java.io.File; import javax.swing.filechooser.FileFilter; /** * Filters PDF files in a JFileChooser. * @since 2.1.1 (imported from itexttoolbox project) */ public class PdfFilter extends FileFilter { /** * * @see javax.swing.filechooser.FileFilter#accept(java.io.File) * @param f File * @return boolean */ public boolean accept(File f) { if (f.isDirectory()) return true; if (f.getName().toLowerCase().endsWith(".pdf")) return true; return false; } /** * * @see javax.swing.filechooser.FileFilter#getDescription() * @return String */ public String getDescription() { return "*.pdf PDF files"; } } src/toolbox/com/lowagie/toolbox/arguments/filters/U3DFilter.java100644 0 0 4476 11006315533 22446 0ustar 0 0 /* * $Id: U3DFilter.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.arguments.filters; import java.io.File; import javax.swing.filechooser.FileFilter; /** * Filters U3D files in a JFileChooser. * @since 2.1.1 (imported from itexttoolbox project) */ public class U3DFilter extends FileFilter { /** * * @see javax.swing.filechooser.FileFilter#accept(java.io.File) * @param f File * @return boolean */ public boolean accept(File f) { if (f.isDirectory()) return true; if (f.getName().toLowerCase().endsWith(".u3d")) return true; return false; } /** * * @see javax.swing.filechooser.FileFilter#getDescription() * @return String */ public String getDescription() { return "*.u3d U3D files"; } } src/toolbox/com/lowagie/toolbox/plugins/Add3D.java100644 0 0 31222 11012562263 17576 0ustar 0 0 /* * $Id: Add3D.java 3373 2008-05-12 16:21:24Z xlv $ * * Adapted from an example in C# from Christian Neuhold * published on the itext mailing list by Paulo Soares at 16. April 2007. * Changes by Paulo Soares to display without the need to click. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * */ package com.lowagie.toolbox.plugins; import java.io.*; import javax.swing.*; import com.lowagie.text.*; import com.lowagie.text.pdf.*; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.*; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.arguments.filters.U3DFilter; import java.net.*; /** * This tool lets you add a embedded u3d 3d annotation to the first page of a document. Look for * sample files at http://u3d.svn.sourceforge.net/viewvc/u3d/trunk/Source/Samples/Data/ * @since 2.1.1 (imported from itexttoolbox project) */ public class Add3D extends AbstractTool { static { addVersion("$Id: Add3D.java 3373 2008-05-12 16:21:24Z xlv $"); } FileArgument destfile = null; public static final String PDF_NAME_3D = "3D"; public static final String PDF_NAME_3DD = "3DD"; public static final String PDF_NAME_3DV = "3DV"; public static final String PDF_NAME_3DVIEW = "3DView"; public static final String PDF_NAME_C2W = "C2W"; public static final String PDF_NAME_IN = "IN"; public static final String PDF_NAME_MS = "MS"; public static final String PDF_NAME_U3D = "U3D"; public static final String PDF_NAME_XN = "XN"; /** * This tool lets you add a embedded u3d 3d annotation to the first page of a document. */ public Add3D() { super(); menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; FileArgument inputfile = new FileArgument(this, "srcfile", "The file you want to add the u3d File", false, new PdfFilter()); arguments.add(inputfile); FileArgument u3dinputfile = new FileArgument(this, "srcu3dfile", "The u3d file you want to add", false, new U3DFilter()); arguments.add(u3dinputfile); StringArgument pagenumber = new StringArgument(this, "pagenumber", "The pagenumber where to add the u3d annotation"); pagenumber.setValue("1"); arguments.add(pagenumber); destfile = new FileArgument(this, "destfile", "The file that contains the u3d annotation after processing", true, new PdfFilter()); arguments.add(destfile); inputfile.addPropertyChangeListener(destfile); } /** * Creates the internal frame. * */ protected void createFrame() { internalFrame = new JInternalFrame("Add3D", true, true, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Add3D OPENED ==="); } /** * Executes the tool (in most cases this generates a PDF file). * */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException( "You need to choose a sourcefile"); } if (getValue("srcu3dfile") == null) { throw new InstantiationException( "You need to choose a u3d file"); } if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } int pagenumber = Integer.parseInt( (String) getValue("pagenumber")); // Create 3D annotation // Required definitions PdfIndirectReference streamRef; PdfIndirectObject objRef; PdfReader reader = new PdfReader(((File) getValue("srcfile")) .getAbsolutePath()); String u3dFileName = ((File) getValue("srcu3dfile")) .getAbsolutePath(); PdfStamper stamp = new PdfStamper(reader, new FileOutputStream( (File) getValue("destfile"))); PdfWriter wr = stamp.getWriter(); PdfContentByte cb = stamp.getUnderContent(pagenumber); Rectangle rectori = reader.getCropBox(pagenumber); Rectangle rect = new Rectangle(new Rectangle(100, rectori.getHeight() - 550, rectori.getWidth() - 100, rectori.getHeight() - 150)); PdfStream oni = new PdfStream(PdfEncodings.convertToBytes( "runtime.setCurrentTool(\"Rotate\");", null)); oni.flateCompress(); // Create stream to carry attachment PdfStream stream = new PdfStream(new FileInputStream(u3dFileName), wr); stream.put(new PdfName("OnInstantiate"), wr.addToBody(oni).getIndirectReference()); stream.put(PdfName.TYPE, new PdfName(PDF_NAME_3D)); // Mandatory keys stream.put(PdfName.SUBTYPE, new PdfName(PDF_NAME_U3D)); stream.flateCompress(); streamRef = wr.addToBody(stream).getIndirectReference(); // Write stream contents, get reference to stream object, write actual stream length stream.writeLength(); // Create 3D view dictionary // PDF documentation states that this can be left out, but without normally we will just get a blank 3D image because of wrong coordinate space transformations, etc. // Instead of providing camera-to-world transformation here, we could also reference view in U3D file itself (would be U3DPath key instead of C2W key, U3D value instead of M value for MS key), but i haven't tried up to now // We could also provide an activation dictionary (defining activation behavior), and field-of-view for P entry if needed PdfDictionary dict = new PdfDictionary(new PdfName(PDF_NAME_3DVIEW)); dict.put(new PdfName(PDF_NAME_XN), new PdfString("Default")); dict.put(new PdfName(PDF_NAME_IN), new PdfString("Unnamed")); dict.put(new PdfName(PDF_NAME_MS), PdfName.M); // States that we have to provide camera-to-world coordinate transformation dict.put(new PdfName(PDF_NAME_C2W), new PdfArray(new float[] {1, 0, 0, 0, 0, -1, 0, 1, 0, 3, -235, 28F})); // 3d transformation matrix (demo for teapot) dict.put(PdfName.CO, new PdfNumber(235)); // Camera distance along z-axis (demo for teapot) objRef = wr.addToBody(dict); // Write view dictionary, get reference // Create appearance PdfAppearance ap = cb.createAppearance(rect.getRight() - rect.getLeft(), rect.getTop() - rect.getBottom()); ap.setBoundingBox(rect); // Create annotation with reference to stream PdfAnnotation annot = new PdfAnnotation(wr, rect); annot.put(PdfName.CONTENTS, new PdfString("3D Model")); annot.put(PdfName.SUBTYPE, new PdfName(PDF_NAME_3D)); // Mandatory keys annot.put(PdfName.TYPE, PdfName.ANNOT); annot.put(new PdfName(PDF_NAME_3DD), streamRef); // Reference to stream object annot.put(new PdfName(PDF_NAME_3DV), objRef.getIndirectReference()); // Reference to view dictionary object annot.put(new PdfName("3DI"), PdfBoolean.PDFFALSE); PdfDictionary adi = new PdfDictionary(); adi.put(PdfName.A, new PdfName("PO")); adi.put(new PdfName("DIS"), PdfName.I); annot.put(new PdfName("3DA"), adi); annot.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, ap); // Assign appearance and page annot.setPage(); // Actually write annotation stamp.addAnnotation(annot, pagenumber); AddButton(100, 100, "Rotate", "im = this.getAnnots3D(0)[0].context3D;\rim.runtime.setCurrentTool(\"Rotate\");", "rotate.png", wr); AddButton(150, 100, "Pan", "im = this.getAnnots3D(0)[0].context3D;\rim.runtime.setCurrentTool(\"Pan\");", "translate.png", wr); AddButton(200, 100, "Zoom", "im = this.getAnnots3D(0)[0].context3D;\rim.runtime.setCurrentTool(\"Zoom\");", "zoom.png", wr); stamp.close(); } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e .getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } public static void AddButton(float x, float y, String fname, String js, String image, PdfWriter wr) { try { // URL url=Add3D.class.getResource( // image); // PdfFileSpecification fs=PdfFileSpecification.fileEmbedded(wr,image,image,null); // wr.addAnnotation(PdfAnnotation.createScreen(wr,new Rectangle(x, y, x + img.plainWidth(), // y + img.plainHeight()))); Image img = Image.getInstance(image); PushbuttonField bt = new PushbuttonField(wr, new Rectangle(x, y, x + img.getPlainWidth(), y + img.getPlainHeight()), fname); bt.setLayout(PushbuttonField.LAYOUT_ICON_ONLY); bt.setImage(img); PdfFormField ff = bt.getField(); PdfAction ac = PdfAction.javaScript(js, wr); ff.setAction(ac); wr.addAnnotation(ff); } catch (MalformedURLException ex) { } catch (IOException ex) { } catch (BadElementException ex) { } catch (DocumentException ex) { } } /** * Gets the PDF file that should be generated (or null if the output isn't a * PDF file). * * @return the PDF file that should be generated * @throws InstantiationException */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } /** * Indicates that the value of an argument has changed. * * @param arg * the argument that has changed */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the // command line return; } if (destfile.getValue() == null && arg.getName().equalsIgnoreCase("srcfile")) { String filename = arg.getValue().toString(); String filenameout = filename.substring(0, filename.indexOf(".", filename.length() - 4)) + "_out.pdf"; destfile.setValue(filenameout); } } /** * This methods helps you running this tool as a standalone application. * @param args the srcfile and destfile */ public static void main(String[] args) { Add3D add3d = new Add3D(); if (args.length != 4) { System.err.println(add3d.getUsage()); } add3d.setMainArguments(args); add3d.execute(); } } src/toolbox/com/lowagie/toolbox/plugins/Bookmarks2XML.java100644 0 0 12127 11006315533 21314 0ustar 0 0 /* * $Id: Bookmarks2XML.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Hans-Werner Hilse, Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Hans-Werner Hilse. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.util.HashMap; import java.util.List; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Allows you to add bookmarks to an existing PDF file * @since 2.1.1 (imported from itexttoolbox project) */ public class Bookmarks2XML extends AbstractTool { static { addVersion("$Id: Bookmarks2XML.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs an Bookmarks2XML object. */ public Bookmarks2XML() { arguments.add(new FileArgument(this, "pdffile", "the PDF from which you want to extract bookmarks", false, new PdfFilter())); arguments.add(new FileArgument(this, "xmlfile", "the resulting bookmarks file in XML", true)); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Bookmarks2XML", true, true, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Bookmarks2XML OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("xmlfile") == null) throw new InstantiationException("You need to choose an xml file"); if (getValue("pdffile") == null) throw new InstantiationException("You need to choose a source PDF file"); PdfReader reader = new PdfReader(((File)getValue("pdffile")).getAbsolutePath()); reader.consolidateNamedDestinations(); List> bookmarks = SimpleBookmark.getBookmark( reader ); // save them in XML format FileOutputStream bmWriter = new FileOutputStream( (File)getValue("xmlfile") ); SimpleBookmark.exportToXML(bookmarks, bmWriter, "UTF-8", false); bmWriter.close(); } catch(Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Allows you to generate an index file in HTML containing Bookmarks to an existing PDF file. * * @param args String[] */ public static void main(String[] args) { Bookmarks2XML tool = new Bookmarks2XML(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is no file to show."); } } src/toolbox/com/lowagie/toolbox/plugins/Burst.java100644 0 0 14675 11006315533 20032 0ustar 0 0 /* * $Id: Burst.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This toolbox plug-in is based on a small example published * with the following notices: * * This code is free software. It may only be copied or modified * if you include the following copyright notice: * * This class by Mark Thompson. Copyright (c) 2002 Mark Thompson. * * This code 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. * * It was adapted by Bruno Lowagie and published as a toolbox plug-in * under the MPL by Bruno Lowagie and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.swing.PdfInformationPanel; /** * This tool lets you split a PDF in several separate PDF files (1 per page). * @since 2.1.1 (imported from itexttoolbox project) */ public class Burst extends AbstractTool { static { addVersion("$Id: Burst.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Burst object. */ public Burst() { FileArgument f = new FileArgument(this, "srcfile", "The file you want to split", false, new PdfFilter()); f.setLabel(new PdfInformationPanel()); arguments.add(f); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Burst", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Burst OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); File directory = src.getParentFile(); String name = src.getName(); name = name.substring(0, name.lastIndexOf('.')); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); // we retrieve the total number of pages int n = reader.getNumberOfPages(); int digits = 1 + (n / 10); System.out.println("There are " + n + " pages in the original file."); Document document; int pagenumber; String filename; for (int i = 0; i < n; i++) { pagenumber = i + 1; filename = String.valueOf(pagenumber); while (filename.length() < digits) filename = "0" + filename; filename = "_" + filename + ".pdf"; // step 1: creation of a document-object document = new Document(reader.getPageSizeWithRotation(pagenumber)); // step 2: we create a writer that listens to the document PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(new File(directory, name + filename))); // step 3: we open the document document.open(); PdfContentByte cb = writer.getDirectContent(); PdfImportedPage page = writer.getImportedPage(reader, pagenumber); int rotation = reader.getPageRotation(pagenumber); if (rotation == 90 || rotation == 270) { cb.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(pagenumber).getHeight()); } else { cb.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } // step 5: we close the document document.close(); } } catch(Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Divide PDF file into pages. * * @param args String[] */ public static void main(String[] args) { Burst tool = new Burst(); if (args.length < 1) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is more than one destfile."); } } src/toolbox/com/lowagie/toolbox/plugins/CompressDecompressPageContent.java100644 0 0 12660 11006315533 24673 0ustar 0 0 /* * $Id: CompressDecompressPageContent.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.swing.PdfInformationPanel; /** * @since 2.1.1 (imported from itexttoolbox project) */ public class CompressDecompressPageContent extends AbstractTool { static { addVersion("$Id: CompressDecompressPageContent.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Burst object. */ public CompressDecompressPageContent() { FileArgument f = new FileArgument(this, "srcfile", "The file you want to compress/decompress", false, new PdfFilter()); f.setLabel(new PdfInformationPanel()); arguments.add(f); arguments.add(new FileArgument(this, "destfile", "The file to which the compressed/decompressed PDF has to be written", true, new PdfFilter())); OptionArgument oa = new OptionArgument(this, "compress", "compress"); oa.addOption("Compress page content", "true"); oa.addOption("Decompress page content", "false"); arguments.add(oa); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Compress/Decompress", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Compress/Decompress OPENED ==="); } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Compresses/decompresses the page content streams in a PDF file. * * @param args String[] */ public static void main(String[] args) { CompressDecompressPageContent tool = new CompressDecompressPageContent(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); boolean compress = "true".equals(getValue("compress")); PdfReader reader = new PdfReader(((File)getValue("srcfile")).getAbsolutePath()); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(getDestPathPDF())); synchronized(arguments) { Document.compress = compress; int total = reader.getNumberOfPages() + 1; for (int i = 1; i < total; i++) { reader.setPageContent(i, reader.getPageContent(i)); } stamper.close(); Document.compress = true; } } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } } src/toolbox/com/lowagie/toolbox/plugins/Concat.java100644 0 0 15461 11006315533 20134 0ustar 0 0 /* * $Id: Concat.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer, Paulo Soares * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie, * Paulo Soares and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Concatenates two PDF files * @since 2.1.1 (imported from itexttoolbox project) */ public class Concat extends AbstractTool { static { addVersion("$Id: Concat.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Concat object. */ public Concat() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile1", "The first PDF file", false, new PdfFilter())); arguments.add(new FileArgument(this, "srcfile2", "The second PDF file", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the concatenated PDF has to be written", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Concatenate 2 PDF files", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Concat OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { String[] files = new String[2]; if (getValue("srcfile1") == null) throw new InstantiationException("You need to choose a first sourcefile"); files[0] = ((File)getValue("srcfile1")).getAbsolutePath(); if (getValue("srcfile2") == null) throw new InstantiationException("You need to choose a second sourcefile"); files[1] = ((File)getValue("srcfile2")).getAbsolutePath(); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); File pdf_file = (File)getValue("destfile"); int pageOffset = 0; List> master = new ArrayList>(); Document document = null; PdfCopy writer = null; for (int i = 0; i < 2; i++) { // we create a reader for a certain document PdfReader reader = new PdfReader(files[i]); reader.consolidateNamedDestinations(); // we retrieve the total number of pages int n = reader.getNumberOfPages(); List> bookmarks = SimpleBookmark.getBookmark(reader); if (bookmarks != null) { if (pageOffset != 0) SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null); master.addAll(bookmarks); } pageOffset += n; System.out.println("There are " + n + " pages in " + files[i]); if (i == 0) { // step 1: creation of a document-object document = new Document(reader.getPageSizeWithRotation(1)); // step 2: we create a writer that listens to the document writer = new PdfCopy(document, new FileOutputStream(pdf_file)); // step 3: we open the document document.open(); } // step 4: we add content PdfImportedPage page; for (int p = 0; p < n; ) { ++p; page = writer.getImportedPage(reader, p); writer.addPage(page); System.out.println("Processed page " + p); } } if (!master.isEmpty()) writer.setOutlines(master); // step 5: we close the document document.close(); } catch(Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Concatenates two PDF files. * * @param args String[] */ public static void main(String[] args) { Concat tool = new Concat(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/ConcatN.java100644 0 0 16121 11006315533 20244 0ustar 0 0 /* * $Id: ConcatN.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer, Paulo Soares * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie, * Paulo Soares and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.FileArrayArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Concatenates two PDF files * @since 2.1.1 (imported from itexttoolbox project) */ public class ConcatN extends AbstractTool { static { addVersion("$Id: ConcatN.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Concat object. */ public ConcatN() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArrayArgument(this, "srcfiles", "The list of PDF files")); arguments.add(new FileArgument(this, "destfile", "The file to which the concatenated PDF has to be written", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Concatenate n PDF files", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Concat OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { File[] files; if (getValue("srcfiles") == null) { throw new InstantiationException( "You need to choose a list of sourcefiles"); } files = ((File[]) getValue("srcfiles")); if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File pdf_file = (File) getValue("destfile"); int pageOffset = 0; ArrayList> master = new ArrayList>(); Document document = null; PdfCopy writer = null; for (int i = 0; i < files.length; i++) { // we create a reader for a certain document PdfReader reader = new PdfReader(files[i].getAbsolutePath()); reader.consolidateNamedDestinations(); // we retrieve the total number of pages int n = reader.getNumberOfPages(); List> bookmarks = SimpleBookmark.getBookmark(reader); if (bookmarks != null) { if (pageOffset != 0) { SimpleBookmark.shiftPageNumbers(bookmarks, pageOffset, null); } master.addAll(bookmarks); } pageOffset += n; System.out.println("There are " + n + " pages in " + files[i]); if (i == 0) { // step 1: creation of a document-object document = new Document(reader.getPageSizeWithRotation(1)); // step 2: we create a writer that listens to the document writer = new PdfCopy(document, new FileOutputStream(pdf_file)); // step 3: we open the document document.open(); } // step 4: we add content PdfImportedPage page; for (int p = 0; p < n; ) { ++p; page = writer.getImportedPage(reader, p); writer.addPage(page); System.out.println("Processed page " + p); } } if (!master.isEmpty()) { writer.setOutlines(master); } // step 5: we close the document document.close(); } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Concatenates two PDF files. * * @param args String[] */ public static void main(String[] args) { ConcatN tool = new ConcatN(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Decrypt.java100644 0 0 11706 11006315533 20335 0ustar 0 0 /* * $Id: Decrypt.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Allows you to decrypt an existing PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class Decrypt extends AbstractTool { static { addVersion("$Id: Decrypt.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Decrypt object. */ public Decrypt() { arguments.add(new FileArgument(this, "srcfile", "The file you want to decrypt", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the decrypted PDF has to be written", true, new PdfFilter())); arguments.add(new StringArgument(this, "ownerpassword", "The ownerpassword you want to add to the PDF file")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Decrypt", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Decrypt OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); byte[] ownerpassword = null; if (getValue("ownerpassword") != null) { ownerpassword = ((String)getValue("ownerpassword")).getBytes(); } PdfReader reader = new PdfReader(((File)getValue("srcfile")).getAbsolutePath(), ownerpassword); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream((File)getValue("destfile"))); stamper.close(); } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Decrypts an existing PDF file. * * @param args String[] */ public static void main(String[] args) { Decrypt tool = new Decrypt(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Divide.java100644 0 0 13720 11006315533 20125 0ustar 0 0 /* * $Id: Divide.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This tool lets you generate a PDF that shows N pages on 1. * @since 2.1.1 (imported from itexttoolbox project) */ public class Divide extends AbstractTool { static { addVersion("$Id: Divide.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs an Divide object. */ public Divide() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile", "The file you want to divide", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The resulting PDF", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Divide", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Divide OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException( "You need to choose a sourcefile"); } File src = (File) getValue("srcfile"); if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File dest = (File) getValue("destfile"); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); // we retrieve the total number of pages and the page size int total = reader.getNumberOfPages(); System.out.println("There are " + total + " pages in the original file."); Rectangle pageSize = reader.getPageSize(1); Rectangle newSize = new Rectangle(pageSize.getWidth() / 2, pageSize .getHeight()); // step 1: creation of a document-object Document document = new Document(newSize, 0, 0, 0, 0); // step 2: we create a writer that listens to the document PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); // step 3: we open the document document.open(); // step 4: adding the content PdfContentByte cb = writer.getDirectContent(); PdfImportedPage page; float offsetX, offsetY; int p; for (int i = 0; i < total; i++) { p = i + 1; pageSize = reader.getPageSize(p); newSize = new Rectangle(pageSize.getWidth() / 2, pageSize.getHeight()); document.newPage(); offsetX = 0; offsetY = 0; page = writer.getImportedPage(reader, p); cb.addTemplate(page, 1, 0, 0, 1, offsetX, offsetY); document.newPage(); offsetX = -newSize.getWidth(); offsetY = 0; page = writer.getImportedPage(reader, p); cb.addTemplate(page, 1, 0, 0, 1, offsetX, offsetY); } // step 5: we close the document document.close(); } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the // command line return; } // represent the changes of the argument in the internal frame } /** * Generates a divided version of an NUp version of an existing PDF file. * * @param args String[] */ public static void main(String[] args) { Divide tool = new Divide(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/DvdCover.java100644 0 0 17224 11006315533 20440 0ustar 0 0 /* * $Id: DvdCover.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.awt.Color; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.ColorArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.ImageArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This is a simple tool that generates a cover for a DVD. * @since 2.1.1 (imported from itexttoolbox project) */ public class DvdCover extends AbstractTool { static { addVersion("$Id: DvdCover.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a DvdCover object. */ public DvdCover() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW | MENU_EXECUTE_PRINT; arguments.add(new FileArgument(this, "destfile", "The file to which the PDF has to be written", true, new PdfFilter())); arguments.add(new StringArgument(this, "title", "The title of the DVD")); arguments.add(new ColorArgument(this, "backgroundcolor", "The backgroundcolor of the DVD Cover (for instance 0xFFFFFF)")); arguments.add(new ImageArgument(this, "front", "The front image of the DVD Cover")); arguments.add(new ImageArgument(this, "back", "The back image of the DVD Cover")); arguments.add(new ImageArgument(this, "side", "The side image of the DVD Cover")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Make your own DVD Cover", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== DvdCover OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { // step 1: creation of a document-object Rectangle pageSize = new Rectangle(780, 525); if (getValue("backgroundcolor") != null) pageSize.setBackgroundColor((Color)getValue("backgroundcolor")); Document document = new Document(pageSize); // step 2: // we create a writer that listens to the document // and directs a PDF-stream to a file if (getValue("destfile") == null) throw new DocumentException("You must provide a destination file!"); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream((File)getValue("destfile"))); // step 3: we open the document document.open(); // step 4: PdfContentByte cb = writer.getDirectContent(); if (getValue("title") != null) { cb.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, false), 24); cb.beginText(); if (getValue("front") == null) { cb.showTextAligned(Element.ALIGN_CENTER, (String)getValue("title"), 595f, 262f, 0f); } if (getValue("side") == null) { cb.showTextAligned(Element.ALIGN_CENTER, (String)getValue("title"), 385f, 262f, 270f); } cb.endText(); } cb.moveTo(370, 0); cb.lineTo(370, 525); cb.moveTo(410, 525); cb.lineTo(410, 0); cb.stroke(); if (getValue("front") != null) { Image front = (Image)getValue("front"); front.scaleToFit(370, 525); front.setAbsolutePosition(410f + (370f - front.getScaledWidth()) / 2f, (525f - front.getScaledHeight()) / 2f); document.add(front); } if (getValue("back") != null) { Image back = (Image)getValue("back"); back.scaleToFit(370, 525); back.setAbsolutePosition((370f - back.getScaledWidth()) / 2f, (525f - back.getScaledHeight()) / 2f); document.add(back); } if (getValue("side") != null) { Image side = (Image)getValue("side"); side.scaleToFit(40, 525); side.setAbsolutePosition(370 + (40f - side.getScaledWidth()) / 2f, (525f - side.getScaledHeight()) / 2f); document.add(side); } // step 5: we close the document document.close(); } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Generates a DVD Cover in PDF. * @param args an array containing [0] a filename [1] a title [2] a backgroundcolor [3] a front image [4] a back image [5] a side image */ public static void main(String[] args) { DvdCover tool = new DvdCover(); if (args.length == 0) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Encrypt.java100644 0 0 15075 11006315533 20352 0ustar 0 0 /* * $Id: Encrypt.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.pdf.PdfEncryptor; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.BitsetArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Allows you to encrypt an existing PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class Encrypt extends AbstractTool { static { addVersion("$Id: Encrypt.java 3271 2008-04-18 20:39:42Z xlv $"); } private final static int PERMISSIONS[] = { PdfWriter.ALLOW_PRINTING, PdfWriter.ALLOW_MODIFY_CONTENTS, PdfWriter.ALLOW_COPY, PdfWriter.ALLOW_MODIFY_ANNOTATIONS, PdfWriter.ALLOW_FILL_IN, PdfWriter.ALLOW_SCREENREADERS, PdfWriter.ALLOW_ASSEMBLY, PdfWriter.ALLOW_DEGRADED_PRINTING}; private final static String PERMISSION_OPTIONS[] = { "AllowPrinting", "AllowModifyContents", "AllowCopy", "AllowModifyAnnotations", "AllowFillIn (128 bit only)", "AllowScreenReaders (128 bit only)", "AllowAssembly (128 bit only)", "AllowDegradedPrinting (128 bit only)" }; /** * Constructs an Encrypt object. */ public Encrypt() { arguments.add(new FileArgument(this, "srcfile", "The file you want to encrypt", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the encrypted PDF has to be written", true, new PdfFilter())); arguments.add(new StringArgument(this, "ownerpassword", "The ownerpassword you want to add to the PDF file")); arguments.add(new StringArgument(this, "userpassword", "The userpassword you want to add to the PDF file")); arguments.add(new BitsetArgument(this, "permissions", "Permissions on the file", PERMISSION_OPTIONS)); OptionArgument oa = new OptionArgument(this, "strength", "Strength of the encryption"); oa.addOption("40 bit encryption", "40"); oa.addOption("128 bit encryption", "128"); arguments.add(oa); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Encrypt", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Encrypt OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); int permissions = 0; String p = (String)getValue("permissions"); if (p != null) { for (int k = 0; k < p.length(); ++k) { permissions |= (p.charAt(k) == '0' ? 0 : PERMISSIONS[k]); } } byte[] userpassword = null; if (getValue("userpassword") != null) { userpassword = ((String)getValue("userpassword")).getBytes(); } byte[] ownerpassword = null; if (getValue("ownerpassword") != null) { ownerpassword = ((String)getValue("ownerpassword")).getBytes(); } PdfReader reader = new PdfReader(((File)getValue("srcfile")).getAbsolutePath()); PdfEncryptor.encrypt( reader, new FileOutputStream((File)getValue("destfile")), userpassword, ownerpassword, permissions, "128".equals(getValue("strength")) ); } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Encrypts an existing PDF file. * * @param args String[] */ public static void main(String[] args) { Encrypt tool = new Encrypt(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/ExtractAttachments.java100644 0 0 16314 11154165264 22541 0ustar 0 0 /* * $Id: ExtractAttachments.java 3712 2009-02-20 20:11:31Z xlv $ * Copyright (c) 2005-2007 Paulo Soares, Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * Paulo Soares and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import javax.swing.JInternalFrame; import com.lowagie.text.pdf.PRStream; import com.lowagie.text.pdf.PdfArray; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfNameTree; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfString; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.swing.PdfInformationPanel; /** * This tool lets you extract the attachments of a PDF. * @since 2.1.1 (imported from itexttoolbox project) */ public class ExtractAttachments extends AbstractTool { static { addVersion("$Id: ExtractAttachments.java 3712 2009-02-20 20:11:31Z xlv $"); } /** * Constructs a ExtractAttachements object. */ public ExtractAttachments() { FileArgument f = new FileArgument(this, "srcfile", "The file you want to operate on", false, new PdfFilter()); f.setLabel(new PdfInformationPanel()); arguments.add(f); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("ExtractAttachments", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== ExtractAttachments OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException( "You need to choose a sourcefile"); File src = (File) getValue("srcfile"); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); final File parentFile = src.getParentFile(); final String outPath; if (parentFile != null) { outPath = parentFile.getAbsolutePath(); } else { outPath = ""; } PdfDictionary catalog = reader.getCatalog(); PdfDictionary names = catalog.getAsDict(PdfName.NAMES); if (names != null) { PdfDictionary embFiles = names.getAsDict(new PdfName("EmbeddedFiles")); if (embFiles != null) { HashMap embMap = PdfNameTree.readTree(embFiles); for (Iterator i = embMap.values().iterator(); i.hasNext();) { PdfDictionary filespec = (PdfDictionary) PdfReader .getPdfObject(i.next()); unpackFile(reader, filespec, outPath); } } } for (int k = 1; k <= reader.getNumberOfPages(); ++k) { PdfArray annots = reader.getPageN(k).getAsArray(PdfName.ANNOTS); if (annots == null) continue; for (Iterator i = annots.listIterator(); i.hasNext();) { PdfDictionary annot = (PdfDictionary) PdfReader .getPdfObject(i.next()); PdfName subType = annot.getAsName(PdfName.SUBTYPE); if (!PdfName.FILEATTACHMENT.equals(subType)) continue; PdfDictionary filespec = annot.getAsDict(PdfName.FS); unpackFile(reader, filespec, outPath); } } } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the // command line return; } // represent the changes of the argument in the internal frame } /** * Extract the attachments of a PDF. * * @param args String[] */ public static void main(String[] args) { ExtractAttachments tool = new ExtractAttachments(); if (args.length < 1) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is more than one destfile."); } /** * Unpacks a file attachment. * * @param reader * The object that reads the PDF document * @param filespec * The dictionary containing the file specifications * @param outPath * The path where the attachment has to be written * @throws IOException */ public static void unpackFile(PdfReader reader, PdfDictionary filespec, String outPath) throws IOException { if (filespec == null) return; PdfName type = filespec.getAsName(PdfName.TYPE); if (!PdfName.F.equals(type) && !PdfName.FILESPEC.equals(type)) return; PdfDictionary ef =filespec.getAsDict(PdfName.EF); if (ef == null) return; PdfString fn = filespec.getAsString(PdfName.F); System.out.println("Unpacking file '" + fn + "' to " + outPath); if (fn == null) return; File fLast = new File(fn.toUnicodeString()); File fullPath = new File(outPath, fLast.getName()); if (fullPath.exists()) return; PRStream prs = (PRStream) PdfReader.getPdfObject(ef.get(PdfName.F)); if (prs == null) return; byte b[] = PdfReader.getStreamBytes(prs); FileOutputStream fout = new FileOutputStream(fullPath); fout.write(b); fout.close(); } } src/toolbox/com/lowagie/toolbox/plugins/Handouts.java100644 0 0 17206 11006315533 20511 0ustar 0 0 /* * $Id: Handouts.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.PageSize; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Generates a PDF file that is usable as Handout. * @since 2.1.1 (imported from itexttoolbox project) */ public class Handouts extends AbstractTool { static { addVersion("$Id: Handouts.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Handouts object. */ public Handouts() { arguments.add(new FileArgument(this, "srcfile", "The file you want to convert", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the Handout has to be written", true, new PdfFilter())); OptionArgument oa = new OptionArgument(this, "pages", "The number of pages you want on one handout page"); oa.addOption("2 pages on 1", "2"); oa.addOption("3 pages on 1", "3"); oa.addOption("4 pages on 1", "4"); oa.addOption("5 pages on 1", "5"); oa.addOption("6 pages on 1", "6"); oa.addOption("7 pages on 1", "7"); oa.addOption("8 pages on 1", "8"); arguments.add(oa); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Handouts", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Handouts OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); File dest = (File)getValue("destfile"); int pages; try { pages = Integer.parseInt((String) getValue("pages")); } catch(Exception e) { pages = 4; } float x1 = 30f; float x2 = 280f; float x3 = 320f; float x4 = 565f; float[] y1 = new float[pages]; float[] y2 = new float[pages]; float height = (778f - (20f * (pages - 1))) / pages; y1[0] = 812f; y2[0] = 812f - height; for (int i = 1; i < pages; i++) { y1[i] = y2[i - 1] - 20f; y2[i] = y1[i] - height; } // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); // we retrieve the total number of pages int n = reader.getNumberOfPages(); System.out.println("There are " + n + " pages in the original file."); // step 1: creation of a document-object Document document = new Document(PageSize.A4); // step 2: we create a writer that listens to the document PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); // step 3: we open the document document.open(); PdfContentByte cb = writer.getDirectContent(); PdfImportedPage page; int rotation; int i = 0; int p = 0; // step 4: we add content while (i < n) { i++; Rectangle rect = reader.getPageSizeWithRotation(i); float factorx = (x2 - x1) / rect.getWidth(); float factory = (y1[p] - y2[p]) / rect.getHeight(); float factor = (factorx < factory ? factorx : factory); float dx = (factorx == factor ? 0f : ((x2 - x1) - rect.getWidth() * factor) / 2f); float dy = (factory == factor ? 0f : ((y1[p] - y2[p]) - rect.getHeight() * factor) / 2f); page = writer.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb.addTemplate(page, 0, -factor, factor, 0, x1 + dx, y2[p] + dy + rect.getHeight() * factor); } else { cb.addTemplate(page, factor, 0, 0, factor, x1 + dx, y2[p] + dy); } cb.setRGBColorStroke(0xC0, 0xC0, 0xC0); cb.rectangle(x3 - 5f, y2[p] - 5f, x4 - x3 + 10f, y1[p] - y2[p] + 10f); for (float l = y1[p] - 19; l > y2[p]; l -= 16) { cb.moveTo(x3, l); cb.lineTo(x4, l); } cb.rectangle(x1 + dx, y2[p] + dy, rect.getWidth() * factor, rect.getHeight() * factor); cb.stroke(); System.out.println("Processed page " + i); p++; if (p == pages) { p = 0; document.newPage(); } } // step 5: we close the document document.close(); } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Converts a PDF file to a PDF file usable as Handout. * * @param args String[] */ public static void main(String[] args) { Handouts tool = new Handouts(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/HtmlBookmarks.java100644 0 0 25011 11012562263 21473 0ustar 0 0 /* * $Id: HtmlBookmarks.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Bruno Lowagie. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.util.HashMap; import java.util.List; import java.util.StringTokenizer; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Anchor; import com.lowagie.text.Chapter; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.Header; import com.lowagie.text.Paragraph; import com.lowagie.text.Section; import com.lowagie.text.html.HtmlTags; import com.lowagie.text.html.HtmlWriter; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.tools.Executable; /** * Allows you to generate an index file in HTML containing Bookmarks to an existing PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class HtmlBookmarks extends AbstractTool { static { addVersion("$Id: HtmlBookmarks.java 3373 2008-05-12 16:21:24Z xlv $"); } /** * Constructs an HtmlBookmarks object. */ public HtmlBookmarks() { arguments.add(new FileArgument(this, "srcfile", "The file you want to inspect", false, new PdfFilter())); arguments.add(new StringArgument(this, "ownerpassword", "The owner password if the file is encrypt")); arguments.add(new StringArgument(this, "css", "The path to a CSS file")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Html Bookmarks", true, true, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Html Bookmarks OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); PdfReader reader; if (getValue("ownerpassword") == null) { reader = new PdfReader(src.getAbsolutePath()); } else { reader = new PdfReader(src.getAbsolutePath(), ((String)getValue("ownerpassword")).getBytes()); } File directory = src.getParentFile(); String name = src.getName(); name = name.substring(0, name.lastIndexOf('.')); File html = new File(directory, name + "_index.html"); Document document = new Document(); HtmlWriter.getInstance(document, new FileOutputStream(html)); Object css = getValue("css"); if (css != null) { document.add(new Header(HtmlTags.STYLESHEET, css.toString())); } Object title = reader.getInfo().get("Title"); if (title == null) document.addTitle("Index for " + src.getName()); else document.addKeywords("Index for '" + title + "'"); Object keywords = reader.getInfo().get("Keywords"); if (keywords != null) document.addKeywords((String)keywords); Object description = reader.getInfo().get("Subject"); if (keywords != null) document.addSubject((String)description); document.open(); Paragraph t; if (title == null) t = new Paragraph("Index for " + src.getName()); else t = new Paragraph("Index for '" + title + "'"); document.add(t); if (description != null) { Paragraph d = new Paragraph((String) description); document.add(d); } List> list = SimpleBookmark.getBookmark(reader); if (list == null) { document.add(new Paragraph("This document has no bookmarks.")); } else { for (HashMap c: list) { Chapter chapter = (Chapter)createBookmark(src.getName(), null, c); List> kids = (List>) c.get("Kids"); if (kids != null) { for (HashMap m: kids) { addBookmark(src.getName(), chapter, m); } } document.add(chapter); } } document.close(); Executable.launchBrowser(html.getAbsolutePath()); } catch(Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * Recursive method to write Bookmark titles to the System.out. * @param pdf the path to the PDF file * @param section the section to which the bookmarks should be added * @param bookmark a HashMap containing a Bookmark (and possible kids) */ private static void addBookmark(String pdf, Section section, HashMap bookmark) { Section s = createBookmark(pdf, section, bookmark); List> kids = (List>) bookmark.get("Kids"); if (kids == null) return; for (HashMap m: kids) { addBookmark(pdf, s, m); } } /** * Adds a line with the title and an anchor. * @param pdf the link to the PDF file * @param section the section that gets the line * @param bookmark the bookmark that has the data for the line * @return a subsection of section */ private static Section createBookmark(String pdf, Section section, HashMap bookmark) { Section s; Paragraph title = new Paragraph((String)bookmark.get("Title")); System.out.println((String)bookmark.get("Title")); String action = (String)bookmark.get("Action"); if ("GoTo".equals(action)) { if (bookmark.get("Page") != null) { String page = (String)bookmark.get("Page"); StringTokenizer tokens = new StringTokenizer(page); String token = tokens.nextToken(); Anchor anchor = new Anchor(" page" + token); anchor.setReference(pdf + "#page=" + token); title.add(anchor); } } else if ("URI".equals(action)) { String url = (String)bookmark.get("URI"); Anchor anchor = new Anchor(" Goto URL"); anchor.setReference(url); title.add(anchor); } else if ("GoToR".equals(action)) { String remote = (String)bookmark.get("File"); Anchor anchor = new Anchor(" goto " + remote); if (bookmark.get("Named") != null) { String named = (String)bookmark.get("Named"); remote = remote + "#nameddest=" + named; } else if (bookmark.get("Page") != null) { String page = (String)bookmark.get("Page"); StringTokenizer tokens = new StringTokenizer(page); String token = tokens.nextToken(); anchor.add(new Chunk(" page " + token)); remote = remote + "#page=" + token; } anchor.setReference(remote); title.add(anchor); } if (section == null) { s = new Chapter(title, 0); } else { s = section.addSection(title); } s.setNumberDepth(0); return s; } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Allows you to generate an index file in HTML containing Bookmarks to an existing PDF file. * * @param args String[] */ public static void main(String[] args) { HtmlBookmarks tool = new HtmlBookmarks(); if (args.length < 1) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is no file to show."); } } src/toolbox/com/lowagie/toolbox/plugins/ImageXRefViewer.java100644 0 0 21216 11006315533 21711 0ustar 0 0 /* * $Id: ImageXRefViewer.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Cursor; import java.awt.Toolkit; import java.io.File; import java.io.IOException; import javax.swing.BorderFactory; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.lowagie.text.pdf.PRStream; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStream; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.swing.EventDispatchingThread; /** * Allows you to inspect the Image XObjects inside a PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class ImageXRefViewer extends AbstractTool { class SpinnerListener implements ChangeListener { private ImageXRefViewer adaptee; SpinnerListener(ImageXRefViewer adaptee) { this.adaptee = adaptee; } /** * * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) * @param e ChangeEvent */ public void stateChanged(ChangeEvent e) { adaptee.propertyChange(e); } } static { addVersion("$Id: ImageXRefViewer.java 3271 2008-04-18 20:39:42Z xlv $"); } /** The total number of pictures inside the PDF. */ int total_number_of_pictures = 0; /** The spinner that will allow you to select an image. */ JSpinner jSpinner = new JSpinner(); /** The panel that will show the images. */ JPanel image_panel = new JPanel(); /** The layout with the images. */ CardLayout layout = new CardLayout(); /** * Creates a ViewImageXObjects object. */ public ImageXRefViewer() { arguments.add(new FileArgument(this, "srcfile", "The file you want to inspect", false, new PdfFilter())); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is no file to show."); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("View Image XObjects", true, false, true); internalFrame.setSize(500, 300); internalFrame.setJMenuBar(getMenubar()); internalFrame.getContentPane().setLayout(new BorderLayout()); JPanel master_panel = new JPanel(); master_panel.setLayout(new BorderLayout()); internalFrame.getContentPane().add(master_panel, java.awt.BorderLayout.CENTER); // images image_panel.setLayout(layout); jSpinner.addChangeListener(new SpinnerListener(this)); image_panel.setBorder(BorderFactory.createEtchedBorder()); JScrollPane scrollPane = new JScrollPane(); scrollPane.setViewportView(image_panel); master_panel.add(scrollPane, java.awt.BorderLayout.CENTER); // spinner JPanel spinner_panel = new JPanel(); spinner_panel.setLayout(new BorderLayout()); spinner_panel.add(jSpinner, java.awt.BorderLayout.CENTER); JLabel image_label = new JLabel(); image_label.setHorizontalAlignment(SwingConstants.CENTER); image_label.setText("images"); spinner_panel.add(image_label, java.awt.BorderLayout.NORTH); master_panel.add(spinner_panel, java.awt.BorderLayout.NORTH); System.out.println("=== Image XObject Viewer OPENED ==="); } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { // do nothing } /** * Reflects the change event in the JSpinner object. * * @param evt ChangeEvent */ public void propertyChange(ChangeEvent evt) { int picture = Integer.parseInt(jSpinner.getValue().toString()); if (picture < 0) { picture = 0; jSpinner.setValue("0"); } if (picture >= total_number_of_pictures) { picture = total_number_of_pictures - 1; jSpinner.setValue(String.valueOf(picture)); } layout.show(image_panel, String.valueOf(picture)); image_panel.repaint(); } /** * Shows the images that are in the PDF as Image XObjects. * * @param args String[] */ public static void main(String[] args) { ImageXRefViewer tool = new ImageXRefViewer(); if (args.length < 1) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { total_number_of_pictures = 0; try { if (getValue("srcfile") == null) throw new InstantiationException( "You need to choose a sourcefile"); EventDispatchingThread task = new EventDispatchingThread() { public Object construct() { try { PdfReader reader = new PdfReader( ((File) getValue("srcfile")).getAbsolutePath()); for (int i = 0; i < reader.getXrefSize(); i++) { PdfObject pdfobj = reader.getPdfObject(i); if (pdfobj != null) { if (pdfobj.isStream()) { PdfStream pdfdict = (PdfStream) pdfobj; PdfObject pdfsubtype = pdfdict .get(PdfName.SUBTYPE); if (pdfsubtype == null) { continue; } if (!pdfsubtype.toString().equals( PdfName.IMAGE.toString())) { continue; } System.out.println("total_number_of_pictures: " + total_number_of_pictures); System.out.println("height:" + pdfdict.get(PdfName.HEIGHT)); System.out.println("width:" + pdfdict.get(PdfName.WIDTH)); System.out.println("bitspercomponent:" + pdfdict.get(PdfName.BITSPERCOMPONENT)); byte[] barr = PdfReader .getStreamBytesRaw((PRStream) pdfdict); java.awt.Image im = Toolkit .getDefaultToolkit().createImage(barr); javax.swing.ImageIcon ii = new javax.swing.ImageIcon(im); JLabel label = new JLabel(); label.setIcon(ii); image_panel.add(label, String.valueOf(total_number_of_pictures++)); } } } } catch (InstantiationException ex) { } catch (IOException ex) { } internalFrame.setCursor(Cursor.getDefaultCursor()); return null; } }; internalFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); task.start(); } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e .getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } } src/toolbox/com/lowagie/toolbox/plugins/InspectPDF.java100644 0 0 13643 11213370067 20667 0ustar 0 0 /* * $Id: InspectPDF.java 3826 2009-03-31 17:46:18Z blowagie $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.pdf.PdfEncryptor; import com.lowagie.text.pdf.PdfReader; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Allows you to inspect an existing PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class InspectPDF extends AbstractTool { static { addVersion("$Id: InspectPDF.java 3826 2009-03-31 17:46:18Z blowagie $"); } /** * Constructs an InpectPDF object. */ public InspectPDF() { arguments.add(new FileArgument(this, "srcfile", "The file you want to inspect", false, new PdfFilter())); arguments.add(new StringArgument(this, "ownerpassword", "The owner password if the file is encrypt")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Pdf Information", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Pdf Information OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); PdfReader reader; if (getValue("ownerpassword") == null) { reader = new PdfReader(((File)getValue("srcfile")).getAbsolutePath()); } else { reader = new PdfReader(((File)getValue("srcfile")).getAbsolutePath(), ((String)getValue("ownerpassword")).getBytes()); } // Some general document information and page size System.out.println("=== Document Information ==="); System.out.println("PDF Version: " + reader.getPdfVersion()); System.out.println("Number of pages: " + reader.getNumberOfPages()); System.out.println("Number of PDF objects: " + reader.getXrefSize()); System.out.println("File length: " + reader.getFileLength()); System.out.println("Encrypted? " + reader.isEncrypted()); if (reader.isEncrypted()) { System.out.println("Permissions: " + PdfEncryptor.getPermissionsVerbose(reader.getPermissions())); System.out.println("128 bit? " + reader.is128Key()); } System.out.println("Rebuilt? " + reader.isRebuilt()); // Some metadata System.out.println("=== Metadata ==="); HashMap info = reader.getInfo(); String key; String value; for (Map.Entry entry: info.entrySet()) { key = entry.getKey(); value = entry.getValue(); System.out.println(key + ": " + value); } if (reader.getMetadata() == null) { System.out.println("There is no XML Metadata in the file"); } else { System.out.println("XML Metadata: " + new String(reader.getMetadata())); } } catch(Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Inspects an existing PDF file. * * @param args String[] */ public static void main(String[] args) { InspectPDF tool = new InspectPDF(); if (args.length < 1) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { throw new InstantiationException("There is no file to show."); } } src/toolbox/com/lowagie/toolbox/plugins/KnitTiff.java100644 0 0 14511 11006315533 20436 0ustar 0 0 /* * $Id: KnitTiff.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.RandomAccessFileOrArray; import com.lowagie.text.pdf.codec.TiffImage; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.ImageFilter; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Knits two TIFF files, one with the even pages and another with the odd pages, together. * @since 2.1.1 (imported from itexttoolbox project) */ public class KnitTiff extends AbstractTool { static { addVersion("$Id: KnitTiff.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a KnitTiff object. */ public KnitTiff() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "odd", "The tiff file with the odd pages", false, new ImageFilter(false, false, false, false, false, true))); arguments.add(new FileArgument(this, "even", "The tiff file with the even pages", false, new ImageFilter(false, false, false, false, false, true))); arguments.add(new FileArgument(this, "destfile", "The file to which the converted TIFF has to be written", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("KnitTiff", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== KnitTiff OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("odd") == null) throw new InstantiationException("You need to choose a sourcefile for the odd pages"); File odd_file = (File)getValue("odd"); if (getValue("even") == null) throw new InstantiationException("You need to choose a sourcefile for the even pages"); File even_file = (File)getValue("even"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); File pdf_file = (File)getValue("destfile"); RandomAccessFileOrArray odd = new RandomAccessFileOrArray(odd_file.getAbsolutePath()); RandomAccessFileOrArray even = new RandomAccessFileOrArray(even_file.getAbsolutePath()); Image img = TiffImage.getTiffImage(odd, 1); Document document = new Document(new Rectangle(img.getScaledWidth(), img.getScaledHeight())); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf_file)); document.open(); PdfContentByte cb = writer.getDirectContent(); int count = Math.max(TiffImage.getNumberOfPages(odd), TiffImage .getNumberOfPages(even)); for (int c = 0; c < count; ++c) { try { Image imgOdd = TiffImage.getTiffImage(odd, c + 1); Image imgEven = TiffImage.getTiffImage(even, count - c); document.setPageSize(new Rectangle(imgOdd.getScaledWidth(), imgOdd.getScaledHeight())); document.newPage(); imgOdd.setAbsolutePosition(0, 0); cb.addImage(imgOdd); document.setPageSize(new Rectangle(imgEven.getScaledWidth(), imgEven.getScaledHeight())); document.newPage(); imgEven.setAbsolutePosition(0, 0); cb.addImage(imgEven); } catch (Exception e) { System.out.println("Exception page " + (c + 1) + " " + e.getMessage()); } } odd.close(); even.close(); document.close(); } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Converts a tiff file to PDF. * * @param args String[] */ public static void main(String[] args) { KnitTiff tool = new KnitTiff(); if (args.length < 3) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/NUp.java100644 0 0 16030 11036112743 17421 0ustar 0 0 /* * $Id: NUp.java 3427 2008-05-24 18:32:31Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This tool lets you generate a PDF that shows N pages on 1. * @since 2.1.1 (imported from itexttoolbox project) */ public class NUp extends AbstractTool { static { addVersion("$Id: NUp.java 3427 2008-05-24 18:32:31Z xlv $"); } /** * Constructs an NUp object. */ public NUp() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile", "The file you want to N-up", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The resulting PDF", true, new PdfFilter())); OptionArgument oa = new OptionArgument(this, "pow2", "The number of pages you want to copy to 1 page"); oa.addOption("2", "1"); oa.addOption("4", "2"); oa.addOption("8", "3"); oa.addOption("16", "4"); oa.addOption("32", "5"); oa.addOption("64", "6"); arguments.add(oa); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("N-up", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== N-up OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); File dest = (File)getValue("destfile"); int pow2; try { pow2 = Integer.parseInt((String) getValue("pow2")); } catch(Exception e) { pow2 = 1; } // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); // we retrieve the total number of pages and the page size int total = reader.getNumberOfPages(); System.out.println("There are " + total + " pages in the original file."); Rectangle pageSize = reader.getPageSize(1); Rectangle newSize = (pow2 % 2) == 0 ? new Rectangle(pageSize.getWidth(), pageSize.getHeight()) : new Rectangle(pageSize.getHeight(), pageSize.getWidth()); Rectangle unitSize = new Rectangle(pageSize.getWidth(), pageSize.getHeight()); Rectangle currentSize; for (int i = 0; i < pow2; i++) { unitSize = new Rectangle(unitSize.getHeight() / 2, unitSize.getWidth()); } int n = (int)Math.pow(2, pow2); int r = (int)Math.pow(2, pow2 / 2); int c = n / r; // step 1: creation of a document-object Document document = new Document(newSize, 0, 0, 0, 0); // step 2: we create a writer that listens to the document PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest)); // step 3: we open the document document.open(); // step 4: adding the content PdfContentByte cb = writer.getDirectContent(); PdfImportedPage page; float offsetX, offsetY, factor; int p; for (int i = 0; i < total; i++) { if (i % n == 0) { document.newPage(); } p = i + 1; offsetX = unitSize.getWidth() * ((i % n) % c); offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c) + 1)); currentSize = reader.getPageSize(p); factor = Math.min(unitSize.getWidth() / currentSize.getWidth(), unitSize.getHeight() / currentSize.getHeight()); offsetX += (unitSize.getWidth() - (currentSize.getWidth() * factor)) / 2f; offsetY += (unitSize.getHeight() - (currentSize.getHeight() * factor)) / 2f; page = writer.getImportedPage(reader, p); cb.addTemplate(page, factor, 0, 0, factor, offsetX, offsetY); } // step 5: we close the document document.close(); } catch(Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Generates an NUp version of an existing PDF file. * * @param args String[] */ public static void main(String[] args) { NUp tool = new NUp(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Normalize.java100644 0 0 30731 11154165264 20672 0ustar 0 0 /* * $Id: Normalize.java 3736 2009-02-26 08:52:21Z xlv $ * * Copyright 2005 by Carsten Hammer. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package com.lowagie.toolbox.plugins; import java.io.*; import java.util.*; import javax.swing.*; import com.lowagie.text.*; import com.lowagie.text.pdf.*; import com.lowagie.toolbox.*; import com.lowagie.toolbox.arguments.*; import com.lowagie.toolbox.arguments.filters.*; /** * @since 2.1.1 (imported from itexttoolbox project) */ public class Normalize extends AbstractTool { static { addVersion("$Id: Normalize.java 3736 2009-02-26 08:52:21Z xlv $"); } FileArgument destfile = null; /** * Constructs a Burst object. */ public Normalize() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; FileArgument inputfile = new FileArgument(this, "srcfile", "The file you want to normalize", false, new PdfFilter()); arguments.add(inputfile); destfile = new FileArgument(this, "destfile", "The resulting PDF", true, new PdfFilter()); arguments.add(destfile); inputfile.addPropertyChangeListener(destfile); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Normalize", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Normalize OPENED ==="); } int pagecount; float width; float height; PdfDictionary lastpage = null; float tolerancex = 60; float tolerancey = 60; int pagecountinsertedpages; int pagecountrotatedpages; protected void iteratePages(PdfDictionary page, PdfReader pdfreader, ArrayList pageInh, int count_in_leaf, PdfWriter writer) throws IOException { float curwidth; float curheight; PdfArray kidsPR = page.getAsArray(PdfName.KIDS); if (kidsPR == null) { PdfArray arr = page.getAsArray(PdfName.MEDIABOX); curwidth = Float.parseFloat(arr.getPdfObject(2).toString()); curheight = Float.parseFloat(arr.getPdfObject(3).toString()); PdfNumber rotation = page.getAsNumber(PdfName.ROTATE); if (rotation == null) { System.out.println("optional rotation missing"); rotation = new PdfNumber(0); } Ausrichtung ausr = new Ausrichtung(rotation.floatValue(), new Rectangle(curwidth, curheight)); switch (ausr.type) { case Ausrichtung.A4Landscape: case Ausrichtung.A3Portrait: ausr.rotate(); page.put(PdfName.ROTATE, new PdfNumber(ausr.getRotation())); System.out.println("rotate page:" + (pagecount + 1) + " targetformat: " + ausr); this.pagecountrotatedpages++; break; } curwidth = ausr.getM5(); curheight = ausr.getM6(); if ( ( (pagecount + 1) % 2) == 0) { if ( (Math.abs(curwidth - width) > tolerancex) || (Math.abs(curheight - height) > tolerancey)) { Seitehinzufuegen(page, count_in_leaf, writer, arr); this.pagecountinsertedpages++; } } /** * Bei ungeraden Seiten die Seitenabmessungen speichern */ if ( ( (pagecount + 1) % 2) == 1) { width = curwidth; height = curheight; lastpage = page; } pageInh.add(pagecount, page); pagecount++; } else { page.put(PdfName.TYPE, PdfName.PAGES); for (int k = 0; k < kidsPR.size(); ++k) { PdfDictionary kid = kidsPR.getAsDict(k); iteratePages(kid, pdfreader, pageInh, k, writer); } } } private void Seitehinzufuegen(PdfDictionary page, int count_in_leaf, PdfWriter writer, PdfArray array) throws IOException { System.out.print("change!"); PdfDictionary parent = page.getAsDict(PdfName.PARENT); PdfArray kids = parent.getAsArray(PdfName.KIDS); PdfIndirectReference ref = writer.getPdfIndirectReference(); kids.add(count_in_leaf, ref); PdfDictionary newPage = new PdfDictionary(PdfName.PAGE); newPage.merge(lastpage); newPage.remove(PdfName.CONTENTS); newPage.remove(PdfName.ANNOTS); newPage.put(PdfName.RESOURCES, new PdfDictionary()); writer.addToBody(newPage, ref); PdfNumber count = null; while (parent != null) { count = parent.getAsNumber(PdfName.COUNT); parent.put(PdfName.COUNT, new PdfNumber(count.intValue() + 1)); parent = parent.getAsDict(PdfName.PARENT); } System.out.println("page:" + (pagecount + 1) + " nr in leaf:" + count_in_leaf + " arl x:" + array.getPdfObject(0) + " y:" + array.getPdfObject(1) + " width:" + array.getPdfObject(2) + " height:" + array.getPdfObject(3)); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException("You need to choose a sourcefile"); } File src = (File) getValue("srcfile"); if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File dest = (File) getValue("destfile"); pagecountinsertedpages = 0; pagecountrotatedpages = 0; pagecount = 0; PdfReader reader = new PdfReader(src.getAbsolutePath()); PdfStamper stp = new PdfStamper(reader, new FileOutputStream(dest)); PdfWriter writer = stp.getWriter(); ArrayList pageInh = new ArrayList(); PdfDictionary catalog = reader.getCatalog(); PdfDictionary rootPages = catalog.getAsDict(PdfName.PAGES); iteratePages(rootPages, reader, pageInh, 0, writer); if ( ( (pagecount) % 2) == 1) { appendemptypageatend(reader, writer); this.pagecountinsertedpages++; } stp.close(); System.out.println("In " + dest.getAbsolutePath() + " pages= " + pagecount + " inserted pages=" + this.getPagecountinsertedpages() + " rotated pages=" + this.getPagecountrotatedpages()); } catch (Exception e) { e.printStackTrace(System.out); } } private void appendemptypageatend(PdfReader reader, PdfWriter writer) throws IOException { System.out.println("last page odd. add page!"); PdfDictionary page = reader.getPageN(reader.getNumberOfPages()); PdfDictionary parent = page.getAsDict(PdfName.PARENT); PdfArray kids = parent.getAsArray(PdfName.KIDS); PdfIndirectReference ref = writer.getPdfIndirectReference(); kids.add(ref); PdfDictionary newPage = new PdfDictionary(PdfName.PAGE); newPage.merge(lastpage); newPage.remove(PdfName.CONTENTS); newPage.remove(PdfName.ANNOTS); newPage.put(PdfName.RESOURCES, new PdfDictionary()); writer.addToBody(newPage, ref); PdfNumber count = null; while (parent != null) { count = parent.getAsNumber(PdfName.COUNT); parent.put(PdfName.COUNT, new PdfNumber(count.intValue() + 1)); parent = parent.getAsDict(PdfName.PARENT); } } public int getPagecountinsertedpages() { return pagecountinsertedpages; } public int getPagecountrotatedpages() { return pagecountrotatedpages; } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame if (destfile.getValue() == null && arg.getName().equalsIgnoreCase("srcfile")) { String filename = arg.getValue().toString(); String filenameout = filename.substring(0, filename.indexOf(".", filename.length() - 4)) + "_out.pdf"; destfile.setValue(filenameout); } } /** * Normalize PDF file. * * @param args String[] */ public static void main(String[] args) { Normalize tool = new Normalize(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } public class Ausrichtung { static final float tolerance = 60; static final int UNKNOWN = 0; static final int A4Portrait = 1; static final int A4Landscape = 2; static final int A3Portrait = 3; static final int A3Landscape = 4; float rotation; Rectangle rect; float m5; float m6; int type; public Ausrichtung() { this(0, new Rectangle(1, 1)); } public Ausrichtung(float rotation, Rectangle unrotatedoriginalrect) { this.rotation = rotation; if ( (rotation == 90) || (rotation == 270)) { rect = unrotatedoriginalrect.rotate(); } else { rect = unrotatedoriginalrect; } m5 = rect.getWidth(); m6 = rect.getHeight(); klassifiziere(); } private void klassifiziere() { if (Math.abs(rect.getWidth() - 595) < tolerance && Math.abs(rect.getHeight() - 842) < tolerance) { this.type = A4Portrait; } else if (Math.abs(rect.getWidth() - 842) < tolerance && Math.abs(rect.getHeight() - 595) < tolerance) { this.type = A4Landscape; } else if (Math.abs(rect.getWidth() - 1190) < tolerance && Math.abs(rect.getHeight() - 842) < tolerance) { this.type = A3Landscape; } else if (Math.abs(rect.getWidth() - 842) < tolerance && Math.abs(rect.getHeight() - 1190) < tolerance) { this.type = A3Portrait; } else { type = UNKNOWN; } } public float getM5() { return m5; } public float getM6() { return m6; } public String toString() { String back; switch (type) { case UNKNOWN: back = rect.getWidth() + "*" + rect.getHeight(); break; case A3Landscape: back = "A3 Landscape"; break; case A3Portrait: back = "A3 Portrait"; break; case A4Landscape: back = "A4 Landscape"; break; case A4Portrait: back = "A4 Portrait"; break; default: back = ""; } return back; } public void rotate() { rect = rect.rotate(); m5 = rect.getWidth(); m6 = rect.getHeight(); rotation += 90; rotation = rotation % 360; klassifiziere(); } public float getRotation() { return rotation; } } } src/toolbox/com/lowagie/toolbox/plugins/PhotoAlbum.java100644 0 0 22204 11036112743 20771 0ustar 0 0 /* * $Id: PhotoAlbum.java 3451 2008-05-26 02:56:13Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. The introduction of the DirFilter by Johannes * Schindelin had an impact on this class. Darryl Miles suggested a bugfix * that was implemented by Bruno Lowagie. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import java.util.TreeSet; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.Image; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfPageLabels; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.DirFilter; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.text.pdf.PdfGState; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.BaseFont; /** * Converts the image files in a directory to a PDF file that acts as a photo album. * @since 2.1.1 (imported from itexttoolbox project) */ public class PhotoAlbum extends AbstractTool { static { addVersion("$Id: PhotoAlbum.java 3451 2008-05-26 02:56:13Z xlv $"); } /** * Constructs a PhotoAlbum object. */ public PhotoAlbum() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcdir", "The directory containing the image files", false, new DirFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the converted TIFF has to be written", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("PhotoAlbum", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== PhotoAlbum OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcdir") == null) { throw new InstantiationException( "You need to choose a source directory"); } File directory = (File) getValue("srcdir"); if (directory.isFile()) { directory = directory.getParentFile(); } if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File pdf_file = (File) getValue("destfile"); Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf_file)); writer.setViewerPreferences(PdfWriter.PageModeUseThumbs); PdfPageLabels pageLabels = new PdfPageLabels(); int dpiX, dpiY; float imgWidthPica, imgHeightPica; TreeSet images = new TreeSet(); File[] files = directory.listFiles(); if (files == null) { throw new NullPointerException("listFiles() returns null"); } for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { images.add(files[i]); } } String label; for (File image: images) { System.out.println("Testing image: " + image.getName()); try { Image img = Image.getInstance(image.getAbsolutePath()); String caption = ""; dpiX = img.getDpiX(); if (dpiX == 0) { dpiX = 72; } dpiY = img.getDpiY(); if (dpiY == 0) { dpiY = 72; } imgWidthPica = (72 * img.getPlainWidth()) / dpiX; imgHeightPica = (72 * img.getPlainHeight()) / dpiY; img.scaleAbsolute(imgWidthPica, imgHeightPica); document.setPageSize(new Rectangle(imgWidthPica, imgHeightPica)); if (document.isOpen()) { document.newPage(); } else { document.open(); } img.setAbsolutePosition(0, 0); document.add(img); BaseFont bf = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false); PdfGState gs1 = new PdfGState(); gs1.setBlendMode(PdfGState.BM_OVERLAY); PdfContentByte cb = writer.getDirectContent(); cb.saveState(); cb.setGState(gs1); cb.beginText(); cb.setFontAndSize(bf, 40); cb.setTextMatrix(50, 50); cb.showText(caption); cb.endText(); cb.restoreState(); label = image.getName(); if (label.lastIndexOf('.') > 0) { label = label.substring(0, label.lastIndexOf('.')); } pageLabels.addPageLabel(writer.getPageNumber(), PdfPageLabels.EMPTY, label); System.out.println("Added image: " + image.getName()); } catch (Exception e) { System.err.println(e.getMessage()); } } if (document.isOpen()) { writer.setPageLabels(pageLabels); document.close(); } else { System.err.println("No images were found in directory " + directory.getAbsolutePath()); } } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Converts a tiff file to PDF. * * @param args String[] */ public static void main(String[] args) { PhotoAlbum tool = new PhotoAlbum(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/RemoveLaunchApplication.java100644 0 0 14607 11006315533 23502 0ustar 0 0 /* * $Id: RemoveLaunchApplication.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.pdf.PRIndirectReference; import com.lowagie.text.pdf.PdfDictionary; import com.lowagie.text.pdf.PdfName; import com.lowagie.text.pdf.PdfObject; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.PdfString; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This tool copies an existing PDF and removes potentially dangerous code that launches an application. * @since 2.1.1 (imported from itexttoolbox project) */ public class RemoveLaunchApplication extends AbstractTool { static { addVersion( "$Id: RemoveLaunchApplication.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a ReversePages object. */ public RemoveLaunchApplication() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile", "The file from which you want to remove Launch Application actions", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the cleaned up version of the original PDF has to be written", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Remove Launch Applications", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Remove Launch Applications OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException("You need to choose a sourcefile"); } File src = (File) getValue("srcfile"); if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File dest = (File) getValue("destfile"); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); PdfObject o; PdfDictionary d; PdfDictionary l; PdfName n; for (int i = 1; i < reader.getXrefSize(); i++) { o = reader.getPdfObject(i); if (o instanceof PdfDictionary) { d = (PdfDictionary)o; o = d.get(PdfName.A); if (o == null) continue; if (o instanceof PdfDictionary) { l = (PdfDictionary)o; } else { PRIndirectReference r =(PRIndirectReference)o; l = (PdfDictionary)reader.getPdfObject(r.getNumber()); } n = (PdfName)l.get(PdfName.S); if (PdfName.LAUNCH.equals(n)) { if (l.get(PdfName.F) != null) { System.out.println("Removed: " + l.get(PdfName.F)); l.remove(PdfName.F); } if (l.get(PdfName.WIN) != null) { System.out.println("Removed: " + l.get(PdfName.WIN)); l.remove(PdfName.WIN); } l.put(PdfName.S, PdfName.JAVASCRIPT); l.put(PdfName.JS, new PdfString("app.alert('Launch Application Action removed by iText');\r")); } } } PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); stamper.close(); } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Copy an existing PDF and replace the Launch Application Action with JavaScript alerts. * * @param args String[] */ public static void main(String[] args) { RemoveLaunchApplication tool = new RemoveLaunchApplication(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/ReversePages.java100644 0 0 14203 11006315533 21311 0ustar 0 0 /* * $Id: ReversePages.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.*; import java.util.ArrayList; import javax.swing.*; import com.lowagie.text.*; import com.lowagie.text.pdf.*; import com.lowagie.toolbox.*; import com.lowagie.toolbox.arguments.*; import com.lowagie.toolbox.arguments.filters.*; /** * This tool lets you take pages from an existing PDF and copy them in reverse order into a new PDF. * @since 2.1.1 (imported from itexttoolbox project) */ public class ReversePages extends AbstractTool { static { addVersion( "$Id: ReversePages.java 3271 2008-04-18 20:39:42Z xlv $"); } FileArgument destfile = null; /** * Constructs a ReversePages object. */ public ReversePages() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; FileArgument inputfile = null; inputfile = new FileArgument(this, "srcfile", "The file you want to reorder", false, new PdfFilter()); arguments.add(inputfile); destfile = new FileArgument(this, "destfile", "The file to which the reordered version of the original PDF has to be written", true, new PdfFilter()); arguments.add(destfile); inputfile.addPropertyChangeListener(destfile); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("ReversePages", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== ReversePages OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException("You need to choose a sourcefile"); } File src = (File) getValue("srcfile"); if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } File dest = (File) getValue("destfile"); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); System.out.println("The original file had " + reader.getNumberOfPages() + " pages."); int pages = reader.getNumberOfPages(); ArrayList li = new ArrayList(); for (int i = pages; i > 0; i--) { li.add(Integer.valueOf(i)); } reader.selectPages(li); System.err.println("The new file has " + pages + " pages."); Document document = new Document(reader.getPageSizeWithRotation(1)); PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest.getAbsolutePath())); document.open(); PdfImportedPage page; for (int i = 0; i < pages; ) { ++i; System.out.println("Processed page " + i); page = copy.getImportedPage(reader, i); copy.addPage(page); } PRAcroForm form = reader.getAcroForm(); if (form != null) { copy.copyAcroForm(reader); } document.close(); } catch (Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } if (destfile.getValue() == null && arg.getName().equalsIgnoreCase("srcfile")) { String filename = arg.getValue().toString(); String filenameout = filename.substring(0, filename.indexOf(".", filename.length() - 4)) + "_out.pdf"; destfile.setValue(filenameout); } } /** * Take pages from an existing PDF and copy them in reverse order into a new PDF. * * @param args String[] */ public static void main(String[] args) { ReversePages tool = new ReversePages(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/SelectedPages.java100644 0 0 13447 11006315533 21437 0ustar 0 0 /* * $Id: SelectedPages.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.pdf.PRAcroForm; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This tool lets you select pages from an existing PDF and copy them into a new PDF. * @since 2.1.1 (imported from itexttoolbox project) */ public class SelectedPages extends AbstractTool { static { addVersion("$Id: SelectedPages.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a SelectedPages object. */ public SelectedPages() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile", "The file you want to split", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "The file to which the first part of the original PDF has to be written", true, new PdfFilter())); arguments.add(new StringArgument(this, "selection", "A selection of pages (see Help for more info)")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("SelectedPages", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== SelectedPages OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file for the first part of the PDF"); File dest = (File)getValue("destfile"); String selection = (String)getValue("selection"); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); System.out.println("The original file had " + reader.getNumberOfPages() + " pages."); reader.selectPages(selection); int pages = reader.getNumberOfPages(); System.err.println("The new file has " + pages + " pages."); Document document = new Document(reader.getPageSizeWithRotation(1)); PdfCopy copy = new PdfCopy(document, new FileOutputStream(dest.getAbsolutePath())); document.open(); PdfImportedPage page; for (int i = 0; i < pages; ) { ++i; System.out.println("Processed page " + i); page = copy.getImportedPage(reader, i); copy.addPage(page); } PRAcroForm form = reader.getAcroForm(); if (form != null) copy.copyAcroForm(reader); document.close(); } catch(Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Generates a PDF file with selected pages from an existing PDF. * * @param args String[] */ public static void main(String[] args) { SelectedPages tool = new SelectedPages(); if (args.length < 4) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Split.java100644 0 0 16465 11006315533 20025 0ustar 0 0 /* * $Id: Split.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.IntegerArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; import com.lowagie.toolbox.swing.PdfInformationPanel; /** * This tool lets you split a PDF in two separate PDF files. * @since 2.1.1 (imported from itexttoolbox project) */ public class Split extends AbstractTool { static { addVersion("$Id: Split.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs an Split object. */ public Split() { FileArgument f = new FileArgument(this, "srcfile", "The file you want to split", false, new PdfFilter()); f.setLabel(new PdfInformationPanel()); arguments.add(f); arguments.add(new FileArgument(this, "destfile1", "The file to which the first part of the original PDF has to be written", true, new PdfFilter())); arguments.add(new FileArgument(this, "destfile2", "The file to which the second part of the original PDF has to be written", true, new PdfFilter())); arguments.add(new IntegerArgument(this, "pagenumber", "The pagenumber where you want to split")); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Split", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Split OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File src = (File)getValue("srcfile"); if (getValue("destfile1") == null) throw new InstantiationException("You need to choose a destination file for the first part of the PDF"); File file1 = (File)getValue("destfile1"); if (getValue("destfile2") == null) throw new InstantiationException("You need to choose a destination file for the second part of the PDF"); File file2 = (File)getValue("destfile2"); int pagenumber = Integer.parseInt((String)getValue("pagenumber")); // we create a reader for a certain document PdfReader reader = new PdfReader(src.getAbsolutePath()); // we retrieve the total number of pages int n = reader.getNumberOfPages(); System.out.println("There are " + n + " pages in the original file."); if (pagenumber < 2 || pagenumber > n) { throw new DocumentException("You can't split this document at page " + pagenumber + "; there is no such page."); } // step 1: creation of a document-object Document document1 = new Document(reader.getPageSizeWithRotation(1)); Document document2 = new Document(reader.getPageSizeWithRotation(pagenumber)); // step 2: we create a writer that listens to the document PdfWriter writer1 = PdfWriter.getInstance(document1, new FileOutputStream(file1)); PdfWriter writer2 = PdfWriter.getInstance(document2, new FileOutputStream(file2)); // step 3: we open the document document1.open(); PdfContentByte cb1 = writer1.getDirectContent(); document2.open(); PdfContentByte cb2 = writer2.getDirectContent(); PdfImportedPage page; int rotation; int i = 0; // step 4: we add content while (i < pagenumber - 1) { i++; document1.setPageSize(reader.getPageSizeWithRotation(i)); document1.newPage(); page = writer1.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb1.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(i).getHeight()); } else { cb1.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } } while (i < n) { i++; document2.setPageSize(reader.getPageSizeWithRotation(i)); document2.newPage(); page = writer2.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { cb2.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(i).getHeight()); } else { cb2.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } } // step 5: we close the document document1.close(); document2.close(); } catch(Exception e) { e.printStackTrace(); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Split a PDF in two separate PDF files. * * @param args String[] */ public static void main(String[] args) { Split tool = new Split(); if (args.length < 4) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile1"); } } src/toolbox/com/lowagie/toolbox/plugins/Tiff2Pdf.java100644 0 0 17602 11006315533 20330 0ustar 0 0 /* * $Id: Tiff2Pdf.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.Image; import com.lowagie.text.PageSize; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.RandomAccessFileOrArray; import com.lowagie.text.pdf.codec.TiffImage; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.filters.ImageFilter; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Converts a Tiff file to a PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class Tiff2Pdf extends AbstractTool { static { addVersion("$Id: Tiff2Pdf.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Tiff2Pdf object. */ public Tiff2Pdf() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW; arguments.add(new FileArgument(this, "srcfile", "The file you want to convert", false, new ImageFilter(false, false, false, false, false, true))); arguments.add(new FileArgument(this, "destfile", "The file to which the converted TIFF has to be written", true, new PdfFilter())); OptionArgument oa = new OptionArgument(this, "pagesize", "Pagesize"); oa.addOption("A4", "A4"); oa.addOption("Letter", "LETTER"); oa.addOption("Original format", "ORIGINAL"); arguments.add(oa); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Tiff2Pdf", true, false, true); internalFrame.setSize(550, 250); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Tiff2Pdf OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("srcfile") == null) throw new InstantiationException("You need to choose a sourcefile"); File tiff_file = (File)getValue("srcfile"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination file"); File pdf_file = (File)getValue("destfile"); RandomAccessFileOrArray ra = new RandomAccessFileOrArray(tiff_file.getAbsolutePath()); int comps = TiffImage.getNumberOfPages(ra); boolean adjustSize = false; Document document = new Document(PageSize.A4); float width = PageSize.A4.getWidth() - 40; float height = PageSize.A4.getHeight() - 120; if ("ORIGINAL".equals(getValue("pagesize"))) { Image img = TiffImage.getTiffImage(ra, 1); if (img.getDpiX() > 0 && img.getDpiY() > 0) { img.scalePercent(7200f / img.getDpiX(), 7200f / img.getDpiY()); } document.setPageSize(new Rectangle(img.getScaledWidth(), img.getScaledHeight())); adjustSize = true; } else if ("LETTER".equals(getValue("pagesize"))) { document.setPageSize(PageSize.LETTER); width = PageSize.LETTER.getWidth() - 40; height = PageSize.LETTER.getHeight() - 120; } PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdf_file)); document.open(); PdfContentByte cb = writer.getDirectContent(); for (int c = 0; c < comps; ++c) { Image img = TiffImage.getTiffImage(ra, c + 1); if (img != null) { if (img.getDpiX() > 0 && img.getDpiY() > 0) { img.scalePercent(7200f / img.getDpiX(), 7200f / img.getDpiY()); } if (adjustSize) { document.setPageSize(new Rectangle(img.getScaledWidth(), img.getScaledHeight())); document.newPage(); img.setAbsolutePosition(0, 0); } else { if (img.getScaledWidth() > width || img.getScaledHeight() > height) { if (img.getDpiX() > 0 && img.getDpiY() > 0) { float adjx = width / img.getScaledWidth(); float adjy = height / img.getScaledHeight(); float adj = Math.min(adjx, adjy); img.scalePercent(7200f / img.getDpiX() * adj, 7200f / img.getDpiY() * adj); } else img.scaleToFit(width, height); } img.setAbsolutePosition(20, 20); document.newPage(); document.add(new Paragraph(tiff_file + " - page " + (c + 1))); } cb.addImage(img); System.out.println("Finished page " + (c + 1)); } } ra.close(); document.close(); } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Converts a tiff file to PDF. * * @param args String[] */ public static void main(String[] args) { Tiff2Pdf tool = new Tiff2Pdf(); if (args.length < 2) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Txt2Pdf.java100644 0 0 13421 11006315533 20212 0ustar 0 0 /* * $Id: Txt2Pdf.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Document; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.Paragraph; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.OptionArgument; import com.lowagie.toolbox.arguments.PageSizeArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Converts a monospaced txt file to a PDF file. * @since 2.1.1 (imported from itexttoolbox project) */ public class Txt2Pdf extends AbstractTool { static { addVersion("$Id: Txt2Pdf.java 3271 2008-04-18 20:39:42Z xlv $"); } /** * Constructs a Txt2Pdf object. */ public Txt2Pdf() { menuoptions = MENU_EXECUTE | MENU_EXECUTE_SHOW | MENU_EXECUTE_PRINT_SILENT; arguments.add(new FileArgument(this, "srcfile", "The file you want to convert", false)); arguments.add(new FileArgument(this, "destfile", "The file to which the converted text has to be written", true, new PdfFilter())); PageSizeArgument oa1 = new PageSizeArgument(this, "pagesize", "Pagesize"); arguments.add(oa1); OptionArgument oa2 = new OptionArgument(this, "orientation", "Orientation of the page"); oa2.addOption("Portrait", "PORTRAIT"); oa2.addOption("Landscape", "LANDSCAPE"); arguments.add(oa2); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("Txt2Pdf", true, true, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Txt2Pdf OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { String line = null; Document document; Font f; Rectangle pagesize = (Rectangle)getValue("pagesize"); if ("LANDSCAPE".equals(getValue("orientation"))) { f = FontFactory.getFont(FontFactory.COURIER, 10); document = new Document(pagesize.rotate(), 36, 9, 36, 36); } else { f = FontFactory.getFont(FontFactory.COURIER, 11); document = new Document(pagesize, 72, 36, 36, 36); } BufferedReader in = new BufferedReader(new FileReader((File)getValue("srcfile"))); PdfWriter.getInstance(document, new FileOutputStream((File)getValue("destfile"))); document.open(); while ((line = in.readLine()) != null) { document.add(new Paragraph(12, line, f)); } document.close(); } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Converts a monospaced txt file to a PDF file. * * @param args String[] */ public static void main(String[] args) { Txt2Pdf tool = new Txt2Pdf(); if (args.length < 3) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/Watermarker.java100644 0 0 22463 11006315533 21211 0ustar 0 0 /* * $Id: Watermarker.java 3271 2008-04-18 20:39:42Z xlv $ * Copyright (c) 2005-2007 Bruno Lowagie, Carsten Hammer * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Bruno Lowagie * and Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileOutputStream; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.Rectangle; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfGState; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.FloatArgument; import com.lowagie.toolbox.arguments.IntegerArgument; import com.lowagie.toolbox.arguments.StringArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * This tool lets you add a text watermark to all pages of a document. * @since 2.1.1 (imported from itexttoolbox project) */ public class Watermarker extends AbstractTool { static { addVersion("$Id: Watermarker.java 3271 2008-04-18 20:39:42Z xlv $"); } FileArgument destfile = null; /** * This tool lets you add a text watermark to all pages of a document. */ public Watermarker() { super(); FileArgument inputfile = new FileArgument(this, "srcfile", "The file you want to watermark", false, new PdfFilter()); arguments.add(inputfile); arguments.add(new StringArgument(this, "watermark", "The text that can be used as watermark")); arguments.add(new IntegerArgument(this, "fontsize", "The fontsize of the watermark text")); arguments.add(new FloatArgument(this, "opacity", "The opacity of the watermark text")); destfile = new FileArgument(this, "destfile", "The file to which the watermarked PDF has to be written", true, new PdfFilter()); arguments.add(destfile); inputfile.addPropertyChangeListener(destfile); } /** * Creates the internal frame. */ protected void createFrame() { internalFrame = new JInternalFrame("Watermark", true, false, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== Watermark OPENED ==="); } /** * Executes the tool (in most cases this generates a PDF file). */ public void execute() { try { if (getValue("srcfile") == null) { throw new InstantiationException( "You need to choose a sourcefile"); } if (getValue("destfile") == null) { throw new InstantiationException( "You need to choose a destination file"); } if (getValue("watermark") == null) { throw new InstantiationException( "You need to add a text for the watermark"); } int fontsize = Integer.parseInt((String) getValue("fontsize")); float opacity = Float.parseFloat((String) getValue("opacity")); BaseFont bf = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false); PdfReader reader = new PdfReader(((File) getValue("srcfile")) .getAbsolutePath()); int pagecount = reader.getNumberOfPages(); PdfGState gs1 = new PdfGState(); gs1.setFillOpacity(opacity); String text = (String) getValue("watermark"); PdfStamper stamp = new PdfStamper(reader, new FileOutputStream( (File) getValue("destfile"))); float txtwidth = bf.getWidthPoint(text, fontsize); for (int i = 1; i <= pagecount; i++) { PdfContentByte seitex = stamp.getOverContent(i); Rectangle recc = reader.getCropBox(i); float winkel = (float) Math.atan(recc.getHeight() / recc.getWidth()); float m1 = (float) Math.cos(winkel); float m2 = (float) - Math.sin(winkel); float m3 = (float) Math.sin(winkel); float m4 = (float) Math.cos(winkel); float xoff = (float) ( -Math.cos(winkel) * txtwidth / 2 - Math .sin(winkel) * fontsize / 2); float yoff = (float) (Math.sin(winkel) * txtwidth / 2 - Math .cos(winkel) * fontsize / 2); seitex.saveState(); seitex.setGState(gs1); seitex.beginText(); seitex.setFontAndSize(bf, fontsize); seitex.setTextMatrix(m1, m2, m3, m4, xoff + recc.getWidth() / 2, yoff + recc.getHeight() / 2); seitex.showText(text); seitex.endText(); seitex.restoreState(); } stamp.close(); } catch (Exception e) { JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e .getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * Gets the PDF file that should be generated (or null if the output isn't a PDF file). * * @return the PDF file that should be generated * @throws InstantiationException */ protected File getDestPathPDF() throws InstantiationException { return (File) getValue("destfile"); } /** * Indicates that the value of an argument has changed. * * @param arg * the argument that has changed */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the // command line return; } if (destfile.getValue() == null && arg.getName().equalsIgnoreCase("srcfile")) { String filename = arg.getValue().toString(); String filenameout = filename.substring(0, filename.indexOf(".", filename.length() - 4)) + "_out.pdf"; destfile.setValue(filenameout); } } /** * This methods helps you running this tool as a standalone application. * *

      Call it like this from command line: * java com.lowagie.tools.plugins.Watermarker input.pdf Draft 230 0.2 output.pdf * *

      "input.pdf" is the input file name to be processed *

      "Draft" is the text written as transparent "watermark" on top of each page *

      "230" is the font size *

      "0.2" is the opacity (1.0 completely opaque, 0.0 completely transparent) *

      "output.pdf" is the output file name * *

      Call it from within other Java code: * *

      Watermarker.main(new String[]{"input.pdf","Draft","230","0.2","output.pdf"}); * * @param args the srcfile, watermark text and destfile */ public static void main(String[] args) { Watermarker watermarker = new Watermarker(); if (args.length != 5) { System.err.println(watermarker.getUsage()); } watermarker.setMainArguments(args); watermarker.execute(); } } src/toolbox/com/lowagie/toolbox/plugins/XML2Bookmarks.java100644 0 0 14735 11012562263 21324 0ustar 0 0 /* * $Id: XML2Bookmarks.java 3373 2008-05-12 16:21:24Z xlv $ * * Copyright 2005 by Hans-Werner Hilse. * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or 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 Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */ package com.lowagie.toolbox.plugins; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.HashMap; import java.util.List; import javax.swing.JInternalFrame; import javax.swing.JOptionPane; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.SimpleBookmark; import com.lowagie.toolbox.AbstractTool; import com.lowagie.toolbox.arguments.AbstractArgument; import com.lowagie.toolbox.arguments.FileArgument; import com.lowagie.toolbox.arguments.filters.PdfFilter; /** * Allows you to add bookmarks to an existing PDF file * @since 2.1.1 (imported from itexttoolbox project) */ public class XML2Bookmarks extends AbstractTool { static { addVersion("$Id: XML2Bookmarks.java 3373 2008-05-12 16:21:24Z xlv $"); } /** * Constructs an XML2Bookmarks object. */ public XML2Bookmarks() { arguments.add(new FileArgument(this, "xmlfile", "the bookmarks in XML", false)); arguments.add(new FileArgument(this, "pdffile", "the PDF to which you want to add bookmarks", false, new PdfFilter())); arguments.add(new FileArgument(this, "destfile", "the resulting PDF", true, new PdfFilter())); } /** * @see com.lowagie.toolbox.AbstractTool#createFrame() */ protected void createFrame() { internalFrame = new JInternalFrame("XML + PDF = PDF", true, true, true); internalFrame.setSize(300, 80); internalFrame.setJMenuBar(getMenubar()); System.out.println("=== XML2Bookmarks OPENED ==="); } /** * @see com.lowagie.toolbox.AbstractTool#execute() */ public void execute() { try { if (getValue("xmlfile") == null) throw new InstantiationException("You need to choose an xml file"); if (getValue("pdffile") == null) throw new InstantiationException("You need to choose a source PDF file"); if (getValue("destfile") == null) throw new InstantiationException("You need to choose a destination PDF file"); FileInputStream bmReader = new FileInputStream( (File) getValue("xmlfile") ); List> bookmarks = SimpleBookmark.importFromXML( bmReader ); bmReader.close(); PdfReader reader = new PdfReader(((File)getValue("pdffile")).getAbsolutePath()); reader.consolidateNamedDestinations(); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream((File)getValue("destfile"))); stamper.setOutlines(bookmarks); stamper.setViewerPreferences(reader.getSimpleViewerPreferences() | PdfWriter.PageModeUseOutlines); stamper.close(); } catch(Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(internalFrame, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE); System.err.println(e.getMessage()); } } /** * * @see com.lowagie.toolbox.AbstractTool#valueHasChanged(com.lowagie.toolbox.arguments.AbstractArgument) * @param arg StringArgument */ public void valueHasChanged(AbstractArgument arg) { if (internalFrame == null) { // if the internal frame is null, the tool was called from the command line return; } // represent the changes of the argument in the internal frame } /** * Allows you to generate an index file in HTML containing Bookmarks to an existing PDF file. * * @param args String[] */ public static void main(String[] args) { XML2Bookmarks tool = new XML2Bookmarks(); if (args.length < 3) { System.err.println(tool.getUsage()); } tool.setMainArguments(args); tool.execute(); } /** * * @see com.lowagie.toolbox.AbstractTool#getDestPathPDF() * @throws InstantiationException * @return File */ protected File getDestPathPDF() throws InstantiationException { return (File)getValue("destfile"); } } src/toolbox/com/lowagie/toolbox/plugins/rotate.png100644 0 0 1140 11000354004 20021 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˵ORq;Es~Vh7D i)%FW;y ֋lENɜ&UgWZAd:{>sΑd`˚囒}06HWz*``ܶ+z>"Y HE# ]|zE^`%bŢvq<ߎ!l;;qOud_W!D0_"-IJx - tn$%!?[ؕҲגm8UޜBHÝu{N*Aƍck쿞&rPPz>2I)3A.uFk4KܖA.qsjw߈`LwЃK$H wh5G0zg'hcA` 1?1mR"@Qɩ`h70ɒpGZupvUO$M c'qCGH L+@Tk?FEkҼ갺|IENDB`src/toolbox/com/lowagie/toolbox/plugins/translate.png100644 0 0 1122 11000354004 20520 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8ݓoORaƟoqM #EDrHQ"uv<}?d1&K3 oI x.0x& /LBeKX;]k ’s|GgqDj~#oъWa-z|2sD>Է?2XhG%ᆪ9_aT Q3Lk}<8íCAh 6%F  05@z#OsЭ\Έچ"ݚ/ h7UFep4=s 6,UDD˓lL&11P㚮eXO肼`pكlYsu͍cN`J{C$k A* n:=zZ'_ݘ._qYx@hμp[+ZDKaHrT_=?!ʄnnY>}M~-7IENDB`src/toolbox/com/lowagie/toolbox/plugins/zoom.png100644 0 0 1264 11000354004 17516 0ustar 0 0 PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<FIDAT8ˍKHA̪-KC= CmfuP)DB"K$A etJZyum0}f~3#sL|!!|g-V9Q鎺c`TC8*5bF'R!DЋ kb^sP!Locgע≣.=^u֘[ 65޶FG ! P %wN5\q=(t@ȀѶ(t2)է"L?B2uXcYV$&a]ct< *Q1}E )hYҁ갎6` DXr<:=UR̞O98*}V&b==hցqف+;˜JT<A!C:̼}nAH~0bM36 +/痗sIĢ̾Ek J {v!=_MyKb]öa{6W03 filevector = new Vector(); public FileList() { super("FileList", true, true, true); try { jbInit(); } catch (Exception ex) { ex.printStackTrace(); } } private void jbInit() throws Exception { this.getContentPane().setLayout(borderLayout1); jTable1.addKeyListener(new FileList_jTable1_keyAdapter(this)); jLabel1.setText("pages"); jLabel2.setText("-"); model.addTableModelListener(new FileList_ftm_tableModelAdapter(this)); this.getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER); jPanel1.setLayout(borderLayout2); jPanel2.setLayout(borderLayout3); jPanel1.add(jPanel2, java.awt.BorderLayout.CENTER); jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER); jPanel1.add(jPanel3, java.awt.BorderLayout.NORTH); jPanel3.add(jLabel2); jPanel3.add(jLabel1); jScrollPane1.setViewportView(jTable1); jTable1.setRowSorter(sorter); // this.setSize(200,100); this.pack(); } JPanel jPanel1 = new JPanel(); BorderLayout borderLayout1 = new BorderLayout(); JPanel jPanel2 = new JPanel(); BorderLayout borderLayout2 = new BorderLayout(); JScrollPane jScrollPane1 = new JScrollPane(); FileTableModel model = new FileTableModel(); JTable jTable1 = new JTable(model); RowSorter sorter=new TableRowSorter (model); BorderLayout borderLayout3 = new BorderLayout(); DropTarget dt = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null); JPanel jPanel3 = new JPanel(); JLabel jLabel1 = new JLabel(); JLabel jLabel2 = new JLabel(); public void dragEnter(DropTargetDragEvent dtde) { } public void dragOver(DropTargetDragEvent dtde) { } public void dropActionChanged(DropTargetDragEvent dtde) { System.out.println("actionchanged"); } public void drop(DropTargetDropEvent dtde) { if ( (dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) == 0) { dtde.rejectDrop(); return; } dtde.acceptDrop(DnDConstants.ACTION_COPY); Vector oldvec=this.filevector; Transferable transferable = dtde.getTransferable(); try { java.util.List filelist = (java.util.List) transferable.getTransferData( DataFlavor.javaFileListFlavor); for (File f: filelist) { filevector.add(new RowContainer(f)); model.fireTableDataChanged(); System.out.println(f.toString()); } } catch (IOException ex) { ex.printStackTrace(); } catch (UnsupportedFlavorException ex) { ex.printStackTrace(); } dtde.dropComplete(true); File[] filar=new File[filevector.size()]; for(int i=0;i getColumnClass(int col) { switch (col) { case 0: return String.class; case 1: return Integer.class; case 2: return String.class; } return null; } public void removeRow(int row) { filevector.remove(row); } } public void jTable1_keyPressed(KeyEvent e) { if (e.getKeyCode() == 127) { int[] selected = jTable1.getSelectedRows(); for (int i = selected.length - 1; i >= 0; i--) { model.removeRow(selected[i]); model.fireTableDataChanged(); } } } public void ftm_tableChanged(TableModelEvent e) { int sum = 0; for (RowContainer c: filevector) { sum += c.getPages(); } this.jLabel2.setText(Integer.toString(sum)); } public Vector getFilevector() { return filevector; } public String getStringreprasentation(){ StringBuffer sb=new StringBuffer(); Vector vec=getFilevector(); for(RowContainer c: vec){ sb.append(c.getFile().getAbsolutePath()).append('\n'); } return sb.toString(); } } class FileList_ftm_tableModelAdapter implements TableModelListener { private FileList adaptee; FileList_ftm_tableModelAdapter(FileList adaptee) { this.adaptee = adaptee; } public void tableChanged(TableModelEvent e) { adaptee.ftm_tableChanged(e); } } class FileList_jTable1_keyAdapter extends KeyAdapter { private FileList adaptee; FileList_jTable1_keyAdapter(FileList adaptee) { this.adaptee = adaptee; } public void keyPressed(KeyEvent e) { adaptee.jTable1_keyPressed(e); } } class RowContainer { private File file; private int pages; public File getFile() { return file; } public int getPages() { return pages; } public void setFile(File file) { this.file = file; } public void setPages(int pages) { this.pages = pages; } /** * RowContainer */ RowContainer(File file) { this.file = file; PdfReader reader = null; try { reader = new PdfReader(file. getAbsolutePath()); } catch (IOException ex) { } this.pages = reader.getNumberOfPages(); } } src/toolbox/com/lowagie/toolbox/swing/PdfInformationPanel.java100644 0 0 12752 11012562263 22273 0ustar 0 0 /* * $Id: PdfInformationPanel.java 3372 2008-05-12 03:16:52Z xlv $ * Copyright (c) 2005-2007 Carsten Hammer, Bruno Lowagie * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * This class was originally published under the MPL by Carsten Hammer. * It was a part of iText, a Java-PDF library. You can now use it under * the MIT License; for backward compatibility you can also use it under * the MPL version 1.1: http://www.mozilla.org/MPL/ * A copy of the MPL license is bundled with the source code FYI. */ package com.lowagie.toolbox.swing; import java.awt.BorderLayout; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.util.HashMap; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingConstants; import com.lowagie.text.pdf.PdfDate; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.RandomAccessFileOrArray; /** * Label for the FileChooser * @since 2.1.1 (imported from itexttoolbox project) */ public class PdfInformationPanel extends JPanel implements PropertyChangeListener { /** A serial version id */ private static final long serialVersionUID = -4171577284617028707L; /** The file name of the PDF we're going to label. */ String filename = ""; /** the label containing the metadata */ JLabel label = new JLabel(); /** the scrollpane to scroll through the label */ JScrollPane scrollpane = new JScrollPane(); /** the panel to witch the scrollpane will be added. */ JPanel panel = new JPanel(); /** Construct the information label (actually it's a JPanel). */ public PdfInformationPanel() { try { this.setLayout(new BorderLayout()); label.setHorizontalAlignment(SwingConstants.CENTER); panel.setLayout(new BorderLayout()); this.add(panel, BorderLayout.CENTER); scrollpane.setPreferredSize(new Dimension(200, 200)); panel.add(scrollpane, BorderLayout.CENTER); scrollpane.setViewportView(label); } catch (Exception ex) { ex.printStackTrace(); } } /** * Reads a PDF file for retrieving its metadata. * * @param file File */ public void createTextFromPDF(File file) { if (file.exists()) { int page = 1; PdfReader reader = null; try { reader = new PdfReader(new RandomAccessFileOrArray(file.getAbsolutePath()), null); HashMap pdfinfo = reader.getInfo(); StringBuffer sb = new StringBuffer(); sb.append("=== Document Information ===

      "); sb.append(reader.getCropBox(page).getHeight() + "*" + reader.getCropBox(page).getWidth() + "

      "); sb.append("PDF Version: " + reader.getPdfVersion() + "

      "); sb.append("Number of pages: " + reader.getNumberOfPages() + "

      "); sb.append("Number of PDF objects: " + reader.getXrefSize() + "

      "); sb.append("File length: " + reader.getFileLength() + "

      "); sb.append("Encrypted= " + reader.isEncrypted() + "

      "); if (pdfinfo.get("Title") != null) { sb.append("Title= " + pdfinfo.get("Title") + "

      "); } if (pdfinfo.get("Author") != null) { sb.append("Author= " + pdfinfo.get("Author") + "

      "); } if (pdfinfo.get("Subject") != null) { sb.append("Subject= " + pdfinfo.get("Subject") + "

      "); } if (pdfinfo.get("Producer") != null) { sb.append("Producer= " + pdfinfo.get("Producer") + "

      "); } if (pdfinfo.get("ModDate") != null) { sb.append("ModDate= " + PdfDate.decode(pdfinfo.get("ModDate")) .getTime() + "

      "); } if (pdfinfo.get("CreationDate") != null) { sb.append("CreationDate= " + PdfDate.decode( pdfinfo.get("CreationDate")) .getTime() + "

      "); } sb.append(""); label.setText(sb.toString()); } catch (IOException ex) { label.setText(""); } } } /** * * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) * @param evt PropertyChangeEvent */ public void propertyChange(PropertyChangeEvent evt) { filename = evt.getPropertyName(); if (filename.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { File file = (File) evt.getNewValue(); if (file != null) { this.createTextFromPDF(file); this.repaint(); } } } } src/toolbox/com/lowagie/toolbox/tools.txt100644 0 0 3336 11006315533 16260 0ustar 0 0 # This is a list of tools that are available for the iText toolbox # $Id: tools.txt 3277 2008-04-19 00:47:48Z xlv $ # Made by Bruno Lowagie: Bookmarks.Bookmarks2XML: com.lowagie.toolbox.plugins.Bookmarks2XML Manipulate.Burst: com.lowagie.toolbox.plugins.Burst Manipulate.Watermarker: com.lowagie.toolbox.plugins.Watermarker Manipulate.CompressDecompress: com.lowagie.toolbox.plugins.CompressDecompressPageContent Manipulate.Concat: com.lowagie.toolbox.plugins.Concat Encryption.Decrypt: com.lowagie.toolbox.plugins.Decrypt Manipulate.Divide: com.lowagie.toolbox.plugins.Divide Various.DvdCover: com.lowagie.toolbox.plugins.DvdCover Encryption.Encrypt: com.lowagie.toolbox.plugins.Encrypt Various.ExtractAttachments: com.lowagie.toolbox.plugins.ExtractAttachments Various.Handouts: com.lowagie.toolbox.plugins.Handouts Bookmarks.HtmlBookmarks: com.lowagie.toolbox.plugins.HtmlBookmarks Properties.ImageXRefViewer: com.lowagie.toolbox.plugins.ImageXRefViewer Properties.InspectPDF: com.lowagie.toolbox.plugins.InspectPDF Convert2Pdf.KnitTiff: com.lowagie.toolbox.plugins.KnitTiff Manipulate.N-up: com.lowagie.toolbox.plugins.NUp Convert2Pdf.PhotoAlbum: com.lowagie.toolbox.plugins.PhotoAlbum Various.RemoveLaunchApplication: com.lowagie.toolbox.plugins.RemoveLaunchApplication Manipulate.ReversePages: com.lowagie.toolbox.plugins.ReversePages Manipulate.SelectedPages: com.lowagie.toolbox.plugins.SelectedPages Manipulate.Split: com.lowagie.toolbox.plugins.Split Convert2Pdf.Tiff2Pdf: com.lowagie.toolbox.plugins.Tiff2Pdf Convert2Pdf.Txt2Pdf: com.lowagie.toolbox.plugins.Txt2Pdf Bookmarks.XML2Bookmarks: com.lowagie.toolbox.plugins.XML2Bookmarks Manipulate.Normalize: com.lowagie.toolbox.plugins.Normalize Manipulate.Add3D: com.lowagie.toolbox.plugins.Add3D