Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* DestHandler.java
* ---------------
*/
package org.jpedal.objects.acroforms.actions;
import org.jpedal.io.PdfFileReader;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.io.types.Array;
import org.jpedal.io.types.StreamReaderUtils;
import org.jpedal.objects.raw.OutlineObject;
import org.jpedal.objects.raw.PdfArrayIterator;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.utils.StringUtils;
/**
*
*/
public class DestHandler {
public static PdfArrayIterator getDestFromObject(PdfObject formObj, final PdfObjectReader currentPdfFile) {
PdfArrayIterator Dest = formObj.getMixedArray(PdfDictionary.Dest);
if (Dest == null || Dest.getTokenCount() == 0) {
//aData can either be in top level of Form (as in Annots) and in A or AA
//or second level (as in A/ /D - this allows for both
//which this routine handles
PdfObject Aobj = formObj.getDictionary(PdfDictionary.A);
if (Aobj == null) {
Aobj = formObj.getDictionary(PdfDictionary.AA);
}
if (Aobj != null) {
formObj = Aobj;
}
//allow for D as indirect
final PdfObject Dobj = formObj.getDictionary(PdfDictionary.D);
if (Dobj != null) {
formObj = Dobj;
}
Dest = formObj.getMixedArray(PdfDictionary.D);
}
final String DestString = formObj.getTextStreamValue(PdfDictionary.D);
//its nameString name (name) linking to obj so read that
if (DestString != null) {
Dest = decodeDest(DestString, currentPdfFile, Dest);
} else if (Dest != null && Dest.getTokenCount() > 0 && !Dest.isNextValueRef()) { //its nameString name (name) linking to obj so read that
Dest = decodeDest(Dest.getNextValueAsString(false), currentPdfFile, Dest);
}
return Dest;
}
/**
* Gets the page number from an A entry and Dest or D entry
*
* @param dest Dest or D entry
* @param currentPdfFile
* @return page number
*/
public static int getPageNumberFromLink(final PdfArrayIterator dest, final PdfObjectReader currentPdfFile) {
int page = -1;
if (dest.hasMoreTokens()) {
final String pageRef = dest.getNextValueAsString(false);
//convert to target page if ref or ignore
page = currentPdfFile.convertObjectToPageNumber(pageRef);
if (page == -1 && dest.getTokenCount() > 2 && !pageRef.contains(" R") && !pageRef.isEmpty()) {
//get pageRef as number of ref
if (dest.hasMoreTokens()) {
final int possiblePage = dest.getNextValueAsInteger(false) + 1;
if (possiblePage > 0) { //can also be a number (cant check range as not yet open)
page = possiblePage;
}
}
}
//allow for number
if (page == -1 && dest.isNextValueNumber()) {
final int possiblePage = dest.getNextValueAsInteger(false) + 1;
if (possiblePage > 0) { //can also be a number (cant check range as not yet open)
page = possiblePage;
}
}
}
return page;
}
private static PdfArrayIterator convertRef(final String ref, final PdfObjectReader currentPdfFile) {
PdfArrayIterator dest = null;
final PdfObject aData = new OutlineObject(ref);
//can be indirect object stored between []
if (ref.charAt(0) == '[') {
dest = converDestStringToMixedArray(ref, currentPdfFile, aData);
} else {
dest = decodeDest(ref, currentPdfFile, dest);
}
return dest;
}
private static PdfArrayIterator converDestStringToMixedArray(final String ref, final PdfObjectReader currentPdfFile, final PdfObject aData) {
final byte[] raw = StringUtils.toBytes(ref);
final Array objDecoder = new Array(currentPdfFile.getObjectReader(), 0, PdfDictionary.VALUE_IS_MIXED_ARRAY, raw);
objDecoder.readArray(aData, PdfDictionary.Dest);
return aData.getMixedArray(PdfDictionary.Dest);
}
private static PdfArrayIterator decodeDest(String nameString, final PdfObjectReader currentPdfFile, PdfArrayIterator DestObj) {
if (nameString.startsWith("/")) {
nameString = nameString.substring(1);
}
byte[] rawRef = nameString.getBytes();
if (!StreamReaderUtils.isRef(rawRef, 0)) {
nameString = currentPdfFile.convertNameToRef(nameString);
}
if (nameString != null) {
rawRef = nameString.getBytes();
if (StreamReaderUtils.isRef(rawRef, 0)) { //indirect so needs resolving if []
final int[] values = StreamReaderUtils.readRefFromStream(rawRef, 0);
final int ref2 = values[0];
final int generation = values[1];
final OutlineObject obj = new OutlineObject(new String(rawRef));
final PdfFileReader objectReader = currentPdfFile.getObjectReader();
//read the Dictionary data
rawRef = objectReader.readObjectAsByteArray(obj, objectReader.isCompressed(ref2, generation), ref2, generation);
int startArray = 0;
while (rawRef[startArray] != '[' && rawRef[startArray] != '<') {
startArray++;
}
if (rawRef[startArray] == '[') {
final int length = rawRef.length;
final int newLength = length - startArray;
final byte[] strippedData = new byte[length];
System.arraycopy(rawRef, startArray, strippedData, 0, newLength);
nameString = new String(strippedData);
} else {
final OutlineObject Aobj = new OutlineObject(nameString);
currentPdfFile.readObject(Aobj);
DestObj = Aobj.getMixedArray(PdfDictionary.D);
final String DestString = Aobj.getTextStreamValue(PdfDictionary.D);
if (DestString != null) {
nameString = DestString;
}
}
}
}
//allow for direct value
if (nameString != null && nameString.startsWith("[")) {
DestObj = converDestStringToMixedArray(nameString, currentPdfFile, new OutlineObject(nameString));
}
return DestObj;
}
public static PdfArrayIterator resolveIfIndirect(final PdfObject formObj, PdfArrayIterator dest, final PdfObjectReader currentPdfFile) {
final byte[] rawName = formObj.getTextStreamValueAsByte(PdfDictionary.D);
if (rawName != null) {
final String name = new String(rawName);
final String ref = currentPdfFile.convertNameToRef(name);
if (ref != null) {
dest = convertRef(ref, currentPdfFile);
} else {
dest = decodeDest(name, currentPdfFile, dest);
}
} else if (dest.getTokenCount() == 1) { //indirect value to remap (Name or ref)
final String ref = currentPdfFile.convertNameToRef(dest.getNextValueAsString(false));
if (ref != null) {
dest = convertRef(ref, currentPdfFile);
} else {
dest = decodeDest(dest.getNextValueAsString(false), currentPdfFile, dest);
}
}
return dest;
}
private static Float getFloatOrNull(final PdfArrayIterator dest) {
if (dest.getNextValueAsString(false).equals("null")) {
dest.getNextValueAsString(true); // Roll on
return null;
} else {
return dest.getNextValueAsFloat();
}
}
public static Object[] getZoomFromDest(final PdfArrayIterator dest) {
while (dest.hasMoreTokens()) {
final Object[] action;
final int key = dest.getNextValueAsKey();
switch (key) {
case PdfDictionary.XYZ:
action = new Object[5];
action[0] = key;
action[1] = "XYZ";
action[2] = getFloatOrNull(dest);
action[3] = getFloatOrNull(dest);
action[4] = getFloatOrNull(dest);
return action;
case PdfDictionary.Fit:
action = new Object[2];
action[0] = key;
action[1] = "Fit";
return action;
case PdfDictionary.FitH:
action = new Object[3];
action[0] = key;
action[1] = "FitH";
action[2] = getFloatOrNull(dest);
return action;
case PdfDictionary.FitV:
action = new Object[3];
action[0] = key;
action[1] = "FitV";
action[2] = getFloatOrNull(dest);
return action;
case PdfDictionary.FitR:
action = new Object[6];
action[0] = key;
action[1] = "FitR";
// Specification does not mention null values for FitR (behavior unspecified)
action[2] = getFloatOrNull(dest);
action[3] = getFloatOrNull(dest);
action[4] = getFloatOrNull(dest);
action[5] = getFloatOrNull(dest);
return action;
case PdfDictionary.FitB:
action = new Object[2];
action[0] = key;
action[1] = "FitB";
return action;
case PdfDictionary.FitBH:
action = new Object[3];
action[0] = key;
action[1] = "FitBH";
action[2] = getFloatOrNull(dest);
return action;
case PdfDictionary.FitBV:
action = new Object[3];
action[0] = key;
action[1] = "FitBV";
action[2] = getFloatOrNull(dest);
return action;
}
}
return null;
}
public static String convertZoomArrayToString(final Object[] zoomArray) {
final StringBuilder zoom = new StringBuilder();
zoom.append(zoomArray[1]);
for (int i = 2; i < zoomArray.length; i++) {
zoom.append(' ').append(zoomArray[i]);
}
return zoom.toString();
}
}