int page=-1;
if (showMethods)
System.out.println("DefaultActionHandler.gotoDest()");
PdfArrayIterator Dest = aData.getMixedArray(PdfDictionary.Dest);
if (Dest!=null) {
if (eventType == MOUSECLICKED) {
//allow for it being an indirect named object and convert if so
if(Dest.getTokenCount()==1){
// System.out.println("val="+ Dest.getNextValueAsString(false));
String ref=decode_pdf.getIO().convertNameToRef( Dest.getNextValueAsString(false));
if(ref!=null){
//can be indirect object stored between []
if(ref.charAt(0)=='['){
if(debugDest)
System.out.println("data for named obj "+ref);
byte[] raw=StringUtils.toBytes(ref);
//replace char so subroutine works -ignored but used as flag in routine
raw[0]= 0;
ArrayDecoder objDecoder=new ArrayDecoder(decode_pdf.getIO().getObjectReader(), 0, raw.length, PdfDictionary.VALUE_IS_MIXED_ARRAY,null, PdfDictionary.Names);
objDecoder.readArray(false, raw, aData, PdfDictionary.Dest);
Dest=aData.getMixedArray(PdfDictionary.Dest);
}else{
if(debugDest)
System.out.println("convert named obj "+ref);
aData=new OutlineObject(ref);
decode_pdf.getIO().readObject(aData);
Dest=aData.getMixedArray(PdfDictionary.Dest);
}
}
}
String filename = aData.getTextStreamValue(PdfDictionary.F);
if(filename==null){
PdfObject fDic = aData.getDictionary(PdfDictionary.F);
if(fDic!=null)
filename = fDic.getTextStreamValue(PdfDictionary.F);
}
//add path if none present
if(filename!=null && filename.indexOf('/')==-1 && filename.indexOf('\\')==-1)
filename=decode_pdf.getObjectStore().getCurrentFilepath()+filename;
//removed \\ checking from iff so slashIndex will work, and
//stop null pointer exceptions, \\ will also be quicker.
if(filename!=null){
//if we have any \\ then replace with / for Windows
int index = filename.indexOf("\\");
while(index!=-1){
//for some reason String.replaceAll didnt like "\\" so done custom
filename = filename.substring(0,index)+
'/' +filename.substring(index+("\\".length()),filename.length());
index = filename.indexOf("\\");
}
//if we dont start with a /,./ or ../ or #:/ then add ./
int slashIndex = filename.indexOf(":/");
if((slashIndex==-1 || slashIndex>1) && !filename.startsWith("/")){
File fileStart = new File(decode_pdf.getFileName());
filename = fileStart.getParent()+ '/' +filename;
}
//resolve any ../ by removing
//(ie /home/test/Downloads/hyperlinks2/Data/../Start.pdf to
// /home/test/Downloads/hyperlinks2/Start.pdf)
index=filename.indexOf("/../");
if(index!=-1){
int start=index-1;
while(start>0){
if((filename.charAt(start)=='/')|| start==0)
break;
start--;
}
if(start>0)
filename=filename.substring(0,start)+filename.substring(index+3,filename.length());
}
}
// new version - read Page Object to jump to
String pageRef = "";
if (Dest.getTokenCount() > 0){
//get pageRef as number of ref
int possiblePage=Dest.getNextValueAsInteger(false)+1;
pageRef = Dest.getNextValueAsString(true);
//convert to target page if ref or ignore
if(pageRef.endsWith(" R"))
page = decode_pdf.getPageFromObjectRef(pageRef);
else if(possiblePage>0){ //can also be a number (cant check range as not yet open)
page=possiblePage;
}
if(debugDest)
System.out.println("pageRef="+pageRef+" page="+page+ ' ' +aData.getObjectRefAsString());
//allow for named Dest
if(page==-1){
String newRef=decode_pdf.getIO().convertNameToRef(pageRef);
//System.out.println(newRef+" "+decode_pdf.getIO().convertNameToRef(pageRef+"XX"));
if(newRef!=null && newRef.endsWith(" R"))
page = decode_pdf.getPageFromObjectRef(newRef);
}
//commented out by mark as named dest should now be handled and -1 shows no page
//if(page==-1){
//we probably have a named destination
// page = 1;
//}
}
//added by Mark so we handle these types of links as well in code below with no Dest
//<</Type/Annot/Subtype/Link/Border[0 0 0]/Rect[56 715.1 137.1 728.9]/A<</Type/Action/S/GoToR/F(test1.pdf)>>
if(Dest.getTokenCount()==0 && aData.getNameAsConstant(PdfDictionary.S)==PdfDictionary.GoToR)
command=PdfDictionary.GoToR;
// boolean openInNewWindow = aData.getBoolean(PdfDictionary.NewWindow);
if(debugDest)
System.out.println("Command="+PdfDictionary.showAsConstant(command));
switch(command){
case PdfDictionary.Dest :
//read all the values
if (Dest.getTokenCount()>1) {
//get type of Dest
//System.out.println("Next value as String="+Dest.getNextValueAsString(false)); //debug code to show actual value (note false so does not roll on)
int type=Dest.getNextValueAsConstant(true);
if(debugDest)
System.out.println("Type="+PdfDictionary.showAsConstant(type));
Integer scale = null;
Rectangle position=null;
// - I have added all the keys for you and
//changed code below. If you run this on baseline,
//with new debug flag testActions on in DefaultAcroRender
// it will exit when it hits one
//not coded
//type of Dest (see page 552 in 1.6Spec (Table 8.2) for full list)
switch(type){
case PdfDictionary.XYZ: //get X,y values and convert to rectangle which we store for later
//get x and y, (null will return 0)
float x=Dest.getNextValueAsFloat();
float y=Dest.getNextValueAsFloat();
//third value is zoom which is not implemented yet
//create Rectangle to scroll to
position=new Rectangle((int)x,(int)y,10,10);
break;
case PdfDictionary.Fit: //type sent in so that we scale to Fit.
scale = -3;//0 for width in scaling box and -3 to show its an index
break;
case PdfDictionary.FitB:
/*[ page /FitB ] - (PDF 1.1) Display the page designated by page, with its contents
* magnified just enough to fit its bounding box 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 bounding box
* within the window in the other dimension.
*/
//scale to same as Fit so use Fit.
scale = -3;//0 for width in scaling box and -3 to show its an index
break;
case PdfDictionary.FitH:
/* [ page /FitH top ] - Display the page designated by page, with the vertical coordinate
* top positioned at the top edge of the window and the contents of the page magnified
* just enough to fit the entire width of the page within the window. A null value for
* top specifies that the current value of that parameter is to be retained unchanged.
*/
//scale to width
scale = -1;//2 for width in scaling box and -3 to show its an index
//and then scroll to location
float top=Dest.getNextValueAsFloat();
//create Rectangle to scroll to
position=new Rectangle(10,(int)top,10,10);
break;