001: /*
002: * $Id: PDFDestination.java,v 1.2 2007/12/20 18:17:41 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package com.sun.pdfview;
023:
024: import java.io.IOException;
025:
026: /**
027: * Represents a destination in a PDF file. Destinations take 3 forms:
028: * <ul>
029: * <li> An explicit destination, which contains a reference to a page
030: * as well as some stuff about how to fit it into the window.
031: * <li> A named destination, which uses the PDF file's Dests entry
032: * in the document catalog to map a name to an explicit destination
033: * <li> A string destintation, which uses the PDF file's Dests entry.
034: * in the name directory to map a string to an explicit destination.
035: * </ul>
036: *
037: * All three of these cases are handled by the getDestination() method.
038: */
039: public class PDFDestination {
040: /** The known types of destination */
041: public static final int XYZ = 0;
042: public static final int FIT = 1;
043: public static final int FITH = 2;
044: public static final int FITV = 3;
045: public static final int FITR = 4;
046: public static final int FITB = 5;
047: public static final int FITBH = 6;
048: public static final int FITBV = 7;
049:
050: /** the type of this destination (from the list above) */
051: private int type;
052:
053: /** the page we refer to */
054: private PDFObject pageObj;
055:
056: /** the left coordinate of the fit area, if applicable */
057: private float left;
058: /** the right coordinate of the fit area, if applicable */
059: private float right;
060:
061: /** the top coordinate of the fit area, if applicable */
062: private float top;
063: /** the bottom coordinate of the fit area, if applicable */
064: private float bottom;
065:
066: /** the zoom, if applicable */
067: private float zoom;
068:
069: /**
070: * Creates a new instance of PDFDestination
071: *
072: * @param pageObj the page object this destination refers to
073: * @param type the type of page this object refers to
074: */
075: protected PDFDestination(PDFObject pageObj, int type) {
076: this .pageObj = pageObj;
077: this .type = type;
078: }
079:
080: /**
081: * Get a destination from either an array (explicit destination), a
082: * name (named destination) or a string (name tree destination).
083: *
084: * @param obj the PDFObject representing this destination
085: * @param root the root of the PDF object tree
086: */
087: public static PDFDestination getDestination(PDFObject obj,
088: PDFObject root) throws IOException {
089: // resolve string and name issues
090: if (obj.getType() == PDFObject.NAME) {
091: obj = getDestFromName(obj, root);
092: } else if (obj.getType() == PDFObject.STRING) {
093: obj = getDestFromString(obj, root);
094: }
095:
096: // make sure we have the right kind of object
097: if (obj == null || obj.getType() != PDFObject.ARRAY) {
098: throw new PDFParseException(
099: "Can't create destination from: " + obj);
100: }
101:
102: // the array is in the form [page type args ... ]
103: PDFObject[] destArray = obj.getArray();
104:
105: // create the destination based on the type
106: PDFDestination dest = null;
107: String type = destArray[1].getStringValue();
108: if (type.equals("XYZ")) {
109: dest = new PDFDestination(destArray[0], XYZ);
110: } else if (type.equals("Fit")) {
111: dest = new PDFDestination(destArray[0], FIT);
112: } else if (type.equals("FitH")) {
113: dest = new PDFDestination(destArray[0], FITH);
114: } else if (type.equals("FitV")) {
115: dest = new PDFDestination(destArray[0], FITV);
116: } else if (type.equals("FitR")) {
117: dest = new PDFDestination(destArray[0], FITR);
118: } else if (type.equals("FitB")) {
119: dest = new PDFDestination(destArray[0], FITB);
120: } else if (type.equals("FitBH")) {
121: dest = new PDFDestination(destArray[0], FITBH);
122: } else if (type.equals("FitBV")) {
123: dest = new PDFDestination(destArray[0], FITBV);
124: } else {
125: throw new PDFParseException("Unknown destination type: "
126: + type);
127: }
128:
129: // now fill in the arguments based on the type
130: switch (dest.getType()) {
131: case XYZ:
132: dest.setLeft(destArray[2].getFloatValue());
133: dest.setTop(destArray[3].getFloatValue());
134: dest.setZoom(destArray[4].getFloatValue());
135: break;
136: case FITH:
137: dest.setTop(destArray[2].getFloatValue());
138: break;
139: case FITV:
140: dest.setLeft(destArray[2].getFloatValue());
141: break;
142: case FITR:
143: dest.setLeft(destArray[2].getFloatValue());
144: dest.setBottom(destArray[3].getFloatValue());
145: dest.setRight(destArray[4].getFloatValue());
146: dest.setTop(destArray[5].getFloatValue());
147: break;
148: case FITBH:
149: dest.setTop(destArray[2].getFloatValue());
150: break;
151: case FITBV:
152: dest.setLeft(destArray[2].getFloatValue());
153: break;
154: }
155:
156: return dest;
157: }
158:
159: /**
160: * Get the type of this destination
161: */
162: public int getType() {
163: return type;
164: }
165:
166: /**
167: * Get the PDF Page object associated with this destination
168: */
169: public PDFObject getPage() {
170: return pageObj;
171: }
172:
173: /**
174: * Get the left coordinate value
175: */
176: public float getLeft() {
177: return left;
178: }
179:
180: /**
181: * Set the left coordinate value
182: */
183: public void setLeft(float left) {
184: this .left = left;
185: }
186:
187: /**
188: * Get the right coordinate value
189: */
190: public float getRight() {
191: return right;
192: }
193:
194: /**
195: * Set the right coordinate value
196: */
197: public void setRight(float right) {
198: this .right = right;
199: }
200:
201: /**
202: * Get the top coordinate value
203: */
204: public float getTop() {
205: return top;
206: }
207:
208: /**
209: * Set the top coordinate value
210: */
211: public void setTop(float top) {
212: this .top = top;
213: }
214:
215: /**
216: * Get the bottom coordinate value
217: */
218: public float getBottom() {
219: return bottom;
220: }
221:
222: /**
223: * Set the bottom coordinate value
224: */
225: public void setBottom(float bottom) {
226: this .bottom = bottom;
227: }
228:
229: /**
230: * Get the zoom value
231: */
232: public float getZoom() {
233: return zoom;
234: }
235:
236: /**
237: * Set the zoom value
238: */
239: public void setZoom(float zoom) {
240: this .zoom = zoom;
241: }
242:
243: /**
244: * Get a destination, given a name. This means the destination is in
245: * the root node's dests dictionary.
246: */
247: private static PDFObject getDestFromName(PDFObject name,
248: PDFObject root) throws IOException {
249: // find the dests object in the root node
250: PDFObject dests = root.getDictRef("Dests");
251: if (dests != null) {
252: // find this name in the dests dictionary
253: return dests.getDictRef(name.getStringValue());
254: }
255:
256: // not found
257: return null;
258: }
259:
260: /**
261: * Get a destination, given a string. This means the destination is in
262: * the root node's names dictionary.
263: */
264: private static PDFObject getDestFromString(PDFObject str,
265: PDFObject root) throws IOException {
266: // find the names object in the root node
267: PDFObject names = root.getDictRef("Names");
268: if (names != null) {
269: // find the dests entry in the names dictionary
270: PDFObject dests = names.getDictRef("Dests");
271: if (dests != null) {
272: // create a name tree object
273: NameTree tree = new NameTree(dests);
274:
275: // find the value we're looking for
276: PDFObject obj = tree.find(str.getStringValue());
277:
278: // if we get back a dictionary, look for the /D value
279: if (obj != null
280: && obj.getType() == PDFObject.DICTIONARY) {
281: obj = obj.getDictRef("D");
282: }
283:
284: // found it
285: return obj;
286: }
287: }
288:
289: // not found
290: return null;
291: }
292:
293: }
|