Package org.jpedal.objects.outlines

Source Code of org.jpedal.objects.outlines.OutlineData

/**
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info:  http://www.jpedal.org
* (C) Copyright 1997-2008, IDRsolutions and Contributors.
*
*   This file is part of JPedal
*
    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


*
* ---------------
* OutlineData.java
* ---------------
*/
package org.jpedal.objects.outlines;

import org.jpedal.io.ArrayDecoder;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.PageLookup;
import org.jpedal.objects.raw.*;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.util.HashMap;
import java.util.Map;

/**
* encapsulate the Outline data
*/
public class OutlineData {

  private Document OutlineDataXML;

    private Map DestObjs=new HashMap();

  //private OutlineData(){}

  /**create list when object initialised*/
  public OutlineData(int pageCount){

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    try {
      OutlineDataXML=factory.newDocumentBuilder().newDocument();
    } catch (ParserConfigurationException e) {
      System.err.println("Exception "+e+" generating XML document");
    }

    //increment so arrays correct size
    pageCount++;

  }

  /**return the list*/
  public Document getList(){
    return OutlineDataXML;
  }

  /**
   * read the outline data
   */
  public int readOutlineFileMetadata(PdfObject OutlinesObj, PdfObjectReader currentPdfFile) {

    int count=OutlinesObj.getInt(PdfDictionary.Count);

    PdfObject FirstObj=OutlinesObj.getDictionary(PdfDictionary.First);
        currentPdfFile.checkResolved(FirstObj);
        if(FirstObj !=null){

      Element root=OutlineDataXML.createElement("root");

      OutlineDataXML.appendChild(root);

      int level=0;
      readOutlineLevel(root,currentPdfFile, FirstObj, level, false);

    }

    /**
    //build lookup table
    int pageCount=this.refTop.length;
    String lastLink=null,currentBottom;
    for(int i=1;i<pageCount;i++){

        //if page has link use bottom
        //otherwise last top
        String link=this.refTop[i];

        if(link!=null){
            lookup[i]=link;
        }else
            lookup[i]=lastLink;

        //System.out.println("Default for page "+i+" = "+lookup[i]+" "+refBottom[i]+" "+refTop[i]);
        //track last top link
        String top=this.refBottom[i];
        if(top!=null){
            lastLink=top;
        }

    }

    /***/
    return count;
  }

  /**
   * returns default bookmark to select for each page
   * - not part of API and not live
   *
  public Map getPointsForPage(){
      return this.pointLookupTable;
  }*/


  /**
   * read a level
   */
  private void readOutlineLevel(Element root,PdfObjectReader currentPdfFile, PdfObject outlineObj, int level, boolean isClosed) {

    String ID;
    //float coord=0;
    int page=-1;

    Element child=OutlineDataXML.createElement("title");

        PdfObject FirstObj=null, NextObj;

    PdfArrayIterator DestObj=null;

    while(true){

      if(FirstObj!=null)
        outlineObj=FirstObj;

      ID=outlineObj.getObjectRefAsString();

      //set to -1 as default
      //coord=-1;
      page=-1;

      /**
       * process and move onto next value
       */
      FirstObj=outlineObj.getDictionary(PdfDictionary.First);
            currentPdfFile.checkResolved(FirstObj);
            NextObj=outlineObj.getDictionary(PdfDictionary.Next);
            currentPdfFile.checkResolved(NextObj);

            int numberOfItems=outlineObj.getInt(PdfDictionary.Count);

            if(numberOfItems!=0)
            isClosed=numberOfItems<0;

            //get Dest from Dest or A object
      DestObj=outlineObj.getMixedArray(PdfDictionary.Dest);

            PdfObject Aobj=outlineObj;

            if(DestObj==null || DestObj.getTokenCount()==0){
        Aobj=outlineObj.getDictionary(PdfDictionary.A);

                //A can also have DEST as a D value (we convert it to DEST to simplify all our usage
                //so should not be set to null
        if(Aobj!=null){ //If there is an A object we will not encounter a Dest
            //DestObj=null; (will break files)
            DestObj=Aobj.getMixedArray(PdfDictionary.Dest);
        }
      }

      String ref=null;


      //get coord & page from data
            //if(type==PdfDictionary.GoToR){
         //   }else
        if (DestObj != null && DestObj.getTokenCount()>0){// && type==PdfDictionary.Goto) {

        int count=DestObj.getTokenCount();

                if(count>0){
          if(DestObj.isNextValueRef())
            ref=DestObj.getNextValueAsString(true);
          else{ //its nameString name (name) linking to obj so read that
                        String nameString =DestObj.getNextValueAsString(true);

                        //check if object and read if so (can also be an indirect name which we lookup
                        if(nameString!=null ){

                            ref=currentPdfFile.convertNameToRef(nameString);

                            //allow for direct value
                            if(ref!=null && ref.startsWith("[")){

                                byte[] raw=StringUtils.toBytes(ref);
                                ArrayDecoder objDecoder=new ArrayDecoder(currentPdfFile.getObjectReader(),0, raw.length, PdfDictionary.VALUE_IS_MIXED_ARRAY,null, PdfDictionary.Names);
                                objDecoder.readArray(false, raw, Aobj, PdfDictionary.Dest);
                                DestObj=Aobj.getMixedArray(PdfDictionary.Dest);
                            }else if(ref!=null){
                              Aobj=new OutlineObject(ref);
                                currentPdfFile.readObject(Aobj);
                                DestObj=Aobj.getMixedArray(PdfDictionary.Dest);
                            }

                            if(DestObj!=null){
                                count=DestObj.getTokenCount();

                                if(count>0 && DestObj.hasMoreTokens() && DestObj.isNextValueRef())
                                ref=DestObj.getNextValueAsString(true);
                            }
                        }
                    }
        }           
      }

      if(ref!=null)
        page=currentPdfFile.convertObjectToPageNumber(ref);

      //add title to tree
      byte[] titleData=outlineObj.getTextStreamValueAsByte(PdfDictionary.Title);
      if(titleData !=null){

        String title= StringUtils.getTextString(titleData, false);

        //add node
        child=OutlineDataXML.createElement("title");
        root.appendChild(child);
        child.setAttribute("title",title);

      }

            child.setAttribute("isClosed", String.valueOf(isClosed));

            //store Dest so we can access
            if(Aobj!=null)
                DestObjs.put(ID,Aobj);

            if(page!=-1)
                child.setAttribute("page", String.valueOf(page));

            child.setAttribute("level", String.valueOf(level));
            child.setAttribute("objectRef",ID);

      if(FirstObj!=null)
        readOutlineLevel(child,currentPdfFile, FirstObj, level+1, isClosed);

      if(NextObj==null)
        break;

      FirstObj=NextObj;

    }
  }

    /**
     * not recommended for general usage
     * @param ref
     * @return Aobj
     */
    public PdfObject getAobj(String ref) {
        return (PdfObject) DestObjs.get(ref);
    }
}
TOP

Related Classes of org.jpedal.objects.outlines.OutlineData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.