Package org.jpedal.objects.acroforms.rendering

Source Code of org.jpedal.objects.acroforms.rendering.DefaultAcroRenderer

/**
* ===========================================
* 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


*
* ---------------
* DefaultAcroRenderer.java
* ---------------
*/
package org.jpedal.objects.acroforms.rendering;

import com.idrsolutions.pdf.acroforms.xfa.XFAFormStream;

import org.jpedal.objects.acroforms.utils.ConvertToString;
//<start-adobe><start-thin>
import org.jpedal.examples.simpleviewer.gui.SwingGUI;
//<end-thin><end-adobe>


import org.jpedal.objects.acroforms.overridingImplementations.CustomImageIcon;
import org.jpedal.PdfDecoder;
import org.jpedal.exception.PdfException;
import org.jpedal.external.Options;
import org.jpedal.gui.UIViewerInt;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.*;
import org.jpedal.objects.acroforms.actions.ActionHandler;
import org.jpedal.objects.acroforms.actions.DefaultActionHandler;
import org.jpedal.objects.acroforms.creation.FormFactory;
import org.jpedal.objects.acroforms.creation.SwingFormFactory;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.FormStream;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.acroforms.formData.ComponentData;
import org.jpedal.objects.acroforms.formData.GUIData;
import org.jpedal.objects.acroforms.formData.SwingData;
import org.jpedal.objects.acroforms.utils.FormUtils;

import org.jpedal.objects.raw.*;
import org.jpedal.parser.PdfStreamDecoder;
import org.jpedal.utils.StringUtils;

import javax.swing.*;
import java.util.*;

/**
* Provides top level to forms handling, assisted by separate classes to
* decode widgets (FormDecoder - default implements Swing set)
* create Form widgets (implementation of FormFactory),
* store and render widgets (GUIData),
* handle Javascript and Actions (Javascript and ActionHandler)
* and support for Signature object
*/
public class DefaultAcroRenderer implements AcroRenderer {

    public static final boolean testActions=false;/**/

  private static final boolean showFormsDecoded=false;

  /** holds all the FORMS raw data from the PDF in order read from PDF **/
  //private List FacroFormDataList;

  /** holds all the ANNOTS raw data from the PDF in order read from PDF **/
    //private List[] AacroFormDataList;

    private Map currentItems = new HashMap();

    FormObject[] Fforms, Aforms;

    PdfObject AcroRes=null;

    PdfArrayIterator fieldList=null;
    PdfArrayIterator[] annotList=null;


  /**
   * flags used to debug code
   */
  final private static boolean showMethods = false;
  final private static boolean identifyType = false;
  final private static boolean debug = false;

    /**
     * flag to show we ignore forms
     */
    private boolean ignoreForms=false;

    /**
   * creates all GUI components from raw data in PDF and stores in GUIData instance
   */
  private FormFactory formFactory;

  /**holder for all data (implementations to support Swing and ULC)*/
  private GUIData compData=new SwingData();
 
  private Map proxyObjects = new HashMap();

  /**holds sig object so we can easily retrieve*/
  private Set sigObject=null;

  /**
   * flags for types of form
   */
  //public static final int ANNOTATION = 1;
  //public static final int FORM = 2;
  //public static final int XFAFORM = 3;

    private Map cachedObjs=new HashMap();

  /**
   * holds copy of object to access the mediaBox and cropBox values
   */
  private PdfPageData pageData;

  /**
   * number of 'A' annot and 'F' form fields in total for this document
   */
  //private int FformCount;

  /**
   * number of entries in acroFormDataList, each entry can have a button group of more that one button
   * 'A' annot and 'F' form - A is per page, F is total hence 3 variables
   */
  private int[] AfieldCount = null;

    private int ATotalCount,FfieldCount = 0;

  /**
   * number of pages in current PDF document
   */
  protected int pageCount = 0;

  /**
   * handle on object reader for decoding objects
   */
  private PdfObjectReader currentPdfFile;

  /**
   * parses and decodes PDF data into generic data for converting to widgets
   */
  private FormStream fDecoder;

  /**
   * handles events like URLS, EMAILS
   */
  private ActionHandler formsActionHandler;

  /**
   * allow user to trap own events - not currently used
   */
  //private LinkHandler linkHandler;

  /**
   * handles Javascript events
   */
  private Javascript javascript;


  /**
   * local copy of inset on Height for use in displaying page
   */
  private int insetH;
    //private Map formKids;

    private PdfObject acroObj;

    /*flag to show if XFA or FDF*/
    private boolean hasXFA=false;

  //private boolean JSInitialised_K;

    private PdfDecoder decode_pdf;

  private boolean updatingForms = false;

  private List additionalAfterCallC = new ArrayList();

    /**
   * setup new instance but does not do anything else
   */
  public DefaultAcroRenderer() {}

  /**
   * reset handler (must be called Before page opened)
   * - null Object resets to default
   */
  public void resetHandler(Object userActionHandler,PdfDecoder decode_pdf, int type) {

        this.decode_pdf=decode_pdf;

    if(type==Options.FormsActionHandler){

      if (userActionHandler != null)
        formsActionHandler = (ActionHandler) userActionHandler;
      else
        formsActionHandler = new DefaultActionHandler();

      formsActionHandler.init(decode_pdf, javascript,this);

      if (formFactory != null){
        formFactory.reset(this, formsActionHandler);
        compData.resetDuplicates();
      }
    }
  }

  /**
   * make all components invisible on all pages by removing from Display
   */
  public void removeDisplayComponentsFromScreen() {

    if (showMethods)
      System.out.println("removeDisplayComponentsFromScreen ");

    if(compData!=null)
    compData.removeAllComponentsFromScreen();

  }

  /**
   * initialise holders and variables and get a handle on data object
   * <p/>
   * Complicated as Annotations stored on a PAGE basis whereas FORMS stored on
   * a file basis
   */
  public void resetFormData(int insetW, int insetH, PdfPageData pageData, PdfObjectReader currentPdfFile, PdfObject acroObj) {

        this.insetH=insetH;
    this.currentPdfFile = currentPdfFile;
    this.pageData = pageData;

        this.acroObj=acroObj;

        //explicitly flush
    sigObject=null;

    //track inset on page
    compData.setPageData(pageData,insetW,insetH);

//        System.out.println("obj="+obj);
//        System.out.println("acroObj="+acroObj);
//
//        if(acroObj!=null){
//        System.out.println(acroObj.getMixedArray(PdfDictionary.Fields));
//        System.out.println(acroObj.getMixedArray(PdfDictionary.Fields).getTokenCount());
//        }
//        if((obj==null)!=(acroObj==null))
//        throw new RuntimeException("xx");

    if (acroObj == null) {

      FfieldCount = 0;

            fieldList=null;
    } else{

            //handle XFA
            PdfObject XFAasStream;
            PdfArrayIterator XFAasArray = null;

            XFAasStream=acroObj.getDictionary(PdfDictionary.XFA);
            if(XFAasStream==null){
                XFAasArray=acroObj.getMixedArray(PdfDictionary.XFA);

                //empty array
                if(XFAasArray!=null && XFAasArray.getTokenCount()==0)
                    XFAasArray=null;
            }

            hasXFA= XFAasStream!=null || XFAasArray!=null;

            /**
       * choose correct decoder for form data
       */
            if (hasXFA)
        fDecoder = new XFAFormStream(acroObj, currentPdfFile);
      else
        fDecoder = new FormStream();

           /**
            * now read the fields
           **/
           fieldList = acroObj.getMixedArray(PdfDictionary.Fields);
           if(fieldList!=null){
             FfieldCount = fieldList.getTokenCount();

               AcroRes=acroObj.getDictionary(PdfDictionary.DR);

               if(AcroRes!=null)
                currentPdfFile.checkResolved(AcroRes);

           }else{
             FfieldCount=0;
               AcroRes=null;
           }

           //allow for indirect
           while(FfieldCount==1){

                String key=fieldList.getNextValueAsString(false);

                FormObject kidObject = new FormObject(key,formsActionHandler);
                currentPdfFile.readObject(kidObject);

                byte[][] childList =getKid(kidObject);

                if(childList==null)
                    break;

                fieldList=new PdfArrayIterator(childList);
                FfieldCount = fieldList.getTokenCount();
            }
    }

    resetContainers(true);

  }

  /**
   * initialise holders and variables and get a handle on data object
   * <p/>
   * Complicated as Annotations stored on a PAGE basis whereas FORMS stored on
   * a file basis
   */
  public void resetAnnotData(int insetW, int insetH, PdfPageData pageData, int page,
                               PdfObjectReader currentPdfFile, byte[][] currentAnnotList) {

        this.insetH=insetH;
        this.currentPdfFile = currentPdfFile;
        this.pageData = pageData;

        boolean resetToEmpty = true;

        //track inset on page
        compData.setPageData(pageData,insetW,insetH);

        if (currentAnnotList==null) {

            AfieldCount = null;
            ATotalCount=0;
            if(annotList!=null)
            annotList[page]=null;

            annotList=null;

        }else{

            int pageCount=pageData.getPageCount()+1;
            if(pageCount<=page)
                pageCount=page+1;
            if(annotList==null){
                annotList=new PdfArrayIterator[pageCount];
                AfieldCount=new int[pageCount];
            }else if(page>=annotList.length){

                PdfArrayIterator[] tempList=annotList;
                int[] tempCount=AfieldCount;
                AfieldCount=new int[pageCount];
                annotList=new PdfArrayIterator[pageCount];

                for(int ii=0;ii<tempList.length;ii++){
                    AfieldCount[ii]=tempCount[ii];
                    annotList[ii]=tempList[ii];
                }
            }else if(AfieldCount==null)
              AfieldCount=new int[pageCount];

            annotList[page]=new PdfArrayIterator(currentAnnotList);

            int size =annotList[page].getTokenCount();

            AfieldCount[page] = size;
            ATotalCount=ATotalCount+size;
            resetToEmpty = false;

            /**
             * choose correct decoder for form data
             */
            if(fDecoder==null){
                if (hasXFA)
                    fDecoder = new XFAFormStream(acroObj, currentPdfFile);
                else
                    fDecoder = new FormStream();
            }
        }

        resetContainers(resetToEmpty);

    }

  /**
   * flush or resize data containers
   */
  protected void resetContainers(boolean resetToEmpty) {
//System.out.println(this+" DefaultAcroRenderer.resetContainers()");
    if (debug)
      System.out.println("DefaultAcroRenderer.resetContainers()");

        /**form or reset Annots*/
    if (resetToEmpty) {

      //flush list
      currentItems.clear();

            compData.resetComponents(ATotalCount+FfieldCount, pageCount, false);
            proxyObjects.clear();
    }else{
        compData.resetComponents(ATotalCount+FfieldCount,pageCount,true);
      proxyObjects.clear();
    }
   
    if (formFactory == null) {
      formFactory = new SwingFormFactory(this, formsActionHandler);//,currentPdfFile);
//      System.out.println(this+" DefaultAcroRenderer.resetContainers() SWING FACTORY SET HERERER");
      //compData=new SwingData();
      //formFactory.setDataObjects(compData);
    } else {
      //to keep customers formfactory usable
      formFactory.reset(this, formsActionHandler);
      compData.resetDuplicates();
      //formFactory.setDataObjects(compData);
    }

        formsActionHandler.setActionFactory(formFactory.getActionFactory());

    }

  /**
   * build forms display using standard swing components
   */
  public void createDisplayComponentsForPage(int page, PdfStreamDecoder current) {

    boolean debugNew=false;

    Map formsCreated=new HashMap();

    //check if we want to flatten forms
    String s = System.getProperty("org.jpedal.flattenForm");
    if(s!=null && s.toLowerCase().equals("true")){
      compData.setRasterizeForms(true);
    }

    if (showMethods)
      System.out.println("createDisplayComponentsForPage " + page);


    /**see if already done*/
    int id=compData.getStartComponentCountForPage(page);
    if (id == -1 || id == -999) {


      /**ensure space for all values*/
      compData.initParametersForPage(pageData,page,decode_pdf);

      //sync values
      if(formsActionHandler!=null){
        formsActionHandler.init(decode_pdf, javascript,this);
        formsActionHandler.setPageAccess(pageData.getMediaBoxHeight(page), insetH);
      }

      if(fDecoder != null)
        currentItems.clear();

      /**
       * think this needs to be revised, and different approach maybe storing, and reuse if respecified in file,
       * need to look at other files to work out solution.
       * files :-
       * lettreenvoi.pdf page 2+ no next page field
       * costena.pdf checkboxes not changable
       *
       * maybe if its just reset on multipage files
       */

      //list of forms done
      Map formsProcessed=new HashMap();

      int Acount=0;
      if(AfieldCount!=null && AfieldCount.length>page)
        Acount=AfieldCount[page];

      Fforms = new FormObject[FfieldCount];
      FormObject[] xfaFormList = null;
      Aforms = new FormObject[Acount];
      FormObject formObject;
      String objRef;
      int i, count;

      //scan list for all relevant values and add to array if valid
      //0 = xfa, 1 = forms, 2 = annots
      int decodeToForm = 2;
      for(int forms=0;forms<decodeToForm;forms++){

        i=0;

        if(forms==0){
          count=0;
          if(fieldList!=null){
            fieldList.resetToStart();
            count=fieldList.getTokenCount()-1;
          }

        }else{
          if(annotList!=null && annotList.length>page && annotList[page]!=null){
            annotList[page].resetToStart();

                        //create lookup and array for values to set order correctly in HTML
                        if(formFactory.getType()==FormFactory.HTML){
                            Map annotOrder=new HashMap();

                            int count2=annotList[page].getTokenCount();
                            String val;
                            for(int ii=0;ii<count2;ii++){
                                val=annotList[page].getNextValueAsString(true);
                                annotOrder.put(val,String.valueOf(ii+1));
                            }

                            formFactory.setAnnotOrder(annotOrder);
                        }


                        annotList[page].resetToStart();
                    }
          count=Acount-1;
        }

        for (int fieldNum =count; fieldNum >-1; fieldNum--) {

          objRef=null;

          if(forms==0){
            if(fieldList!=null)
              objRef=fieldList.getNextValueAsString(true);
          }else{
            if(annotList.length>page && annotList[page]!=null)
              objRef=annotList[page].getNextValueAsString(true);

          }

          if(objRef==null || (objRef!=null && (formsProcessed.get(objRef)!=null || objRef.length()==0)))
            continue;

          formObject= (FormObject) cachedObjs.get(objRef);
          if(formObject==null){

            formObject = new FormObject(objRef,formsActionHandler,pageData.getRotation(page-1));
            //formObject.setPDFRef((String)objRef);

            if(objRef.charAt(objRef.length()-1)=='R'){
              currentPdfFile.readObject(formObject);
            }else{

              //changed by Mark as cover <<>> as well as 1 0 R
              formObject.setStatus(PdfObject.UNDECODED_REF);
              formObject.setUnresolvedData(StringUtils.toBytes(objRef),id);
              currentPdfFile.checkResolved(formObject);
            }

            cachedObjs.put(objRef,formObject);
          }

          byte[][] kids=formObject.getKeyArray(PdfDictionary.Kids);
          if(kids!=null) //not 'proper' kids so process here
            i = flattenKids(page, debugNew, formsProcessed, formObject, i, forms);
          else
            i = processFormObject(page, debugNew, formsProcessed, formObject, objRef, i, forms);
        }
      }

      /**
       * process XFA FORMS and add in values
       */
      if (hasXFA && fDecoder.hasXFADataSet()) {
        currentItems.clear();

        //needs reversing
        ///Users/markee/Downloads/write_test16_pdfform.pdf
        int size=Fforms.length;
        FormObject[] tmp=new FormObject[size];
        for(int ii=0;ii<size;ii++)
          tmp[ii]=Fforms[size-ii-1];

        xfaFormList = ((XFAFormStream) fDecoder).createAppearanceString(tmp);

        compData.storeXFARefToForm(((XFAFormStream)fDecoder).getRefToFormArray());

      }

      List unsortedForms= new ArrayList();
      compData.setUnsortedListForPage(page,unsortedForms);

      //XFA, FDF FORMS then ANNOTS
      int readToForm = 3;
      for(int forms=0;forms<readToForm;forms++){

        count=0;

        if(forms==0){
          if(xfaFormList!=null)
            count=xfaFormList.length;
        }else if(forms==1){
          //store current order of forms for printing
                    for (FormObject Fform : Fforms) {
                        if (Fform != null)
                            unsortedForms.add(Fform.getObjectRefAsString());
                    }

          //sort forms into size order for display
          Fforms = FormUtils.sortGroupLargestFirst(Fforms);
          count=Fforms.length;
        }else{
          //store current order of forms for printing
                    for (FormObject Aform : Aforms) {
                        if (Aform != null)
                            unsortedForms.add(Aform.getObjectRefAsString());
                    }

          //sort forms into size order for display
          Aforms = FormUtils.sortGroupLargestFirst(Aforms);
          count=Aforms.length;
        }

        for (int k = 0; k <count; k++) {

          if(forms==0)
            formObject = xfaFormList[k];
          else if(forms==1)
            formObject = Fforms[k];
          else
            formObject =Aforms[k];

          if (formObject != null && (formsCreated.get(formObject.getObjectRefAsString())==null) && page==formObject.getPageNumber()){// && !formObject.getObjectRefAsString().equals("216 0 R")){
            //String OEPROPval=formObject.getTextStreamValue(PdfDictionary.EOPROPtype);
            //NOTE: if this custom form needs redrawing more change ReadOnlyTextIcon.MAXSCALEFACTOR to 1;
            if(formsRasterizedForDisplay() && current!=null){// || OEPROPval!=null){
   
                            //rasterize any flattened PDF forms here
                            try {
                                current.drawFlattenedForm(formObject);
                            }catch( PdfException e ){
                                e.printStackTrace();
                            }
                           
            }else {
              createField(formObject, compData.getNextFreeField()); //now we turn the data into a Swing component
              //set the raw data here so that the field names are the fully qualified names
              compData.storeRawData(formObject); //store data so user can access

              formsCreated.put(formObject.getObjectRefAsString(), "x");
            }
          }
        }
      }

      if(!formsRasterizedForDisplay()){

        //html add radio button ordering at end to make overlapping forms show correct
        if(formFactory.getType()==FormFactory.HTML){
          formFactory.indexAllKids();
        }
       
        //finish off (some may have been picked up on other pages)
        compData.completeFields(page,this);

       
      }
    }

  }

    private int flattenKids(int page, boolean debugNew, Map formsProcessed, FormObject formObject, int i, int forms) {

        byte[][] kidList=formObject.getKeyArray(PdfDictionary.Kids);
        int kidCount=kidList.length;

        //resize to fit
        if(forms==0){
          int oldCount=Fforms.length;
          FormObject[] temp=Fforms;
          Fforms=new FormObject[oldCount+kidCount-1];
          System.arraycopy(temp, 0, Fforms, 0, oldCount);
        }else{
          int oldCount=Aforms.length;
          FormObject[] temp=Aforms;
          Aforms=new FormObject[oldCount+kidCount-1];
          System.arraycopy(temp, 0, Aforms, 0, oldCount);
        }

        for (byte[] aKidList : kidList) { //iterate through all parts

            String key = new String(aKidList);

            //now we have inherited values, read
            FormObject childObj = new FormObject(key, null);

            //inherit values
            if (formObject != null)
                childObj.copyInheritedValuesFromParent(formObject);

            currentPdfFile.readObject(childObj);
            //childObj.setPDFRef(key);


            childObj.setHandler(formsActionHandler);
            childObj.setRef(key);

            //flag its a kid so we can align value sif needed
            childObj.setKid(true);

            if (childObj.getKeyArray(PdfDictionary.Kids) == null) {

                //test and then test with it commented out
                //check space not filled
                Object rectTocheck = childObj.toString(childObj.getFloatArray(PdfDictionary.Rect), true);
                if (rectTocheck != null && !addItem(rectTocheck)) {

                } else {
                    new FormStream().createAppearanceString(childObj, currentPdfFile);
                }


                i = processFormObject(page, debugNew, formsProcessed, childObj, key, i, forms);
            } else {


                //test and then test with it commented out
                //check space not filled
//                Object rectTocheck=childObj.toString(childObj.getFloatArray(PdfDictionary.Rect),true);
//                if (rectTocheck!=null && !addItem(rectTocheck)) {
//
//                }else{
//                    new FormStream().createAppearanceString(childObj,currentPdfFile,1);
//                }

                i = flattenKids(page, debugNew, formsProcessed, childObj, i, forms);
            }
        }
        return i;
    }

    /**
    private int findObjectType(FormObject formObject) {

        int subtype=PdfDictionary.Unknown;

        byte[][] kidList = getKid(formObject);
        boolean hasKids=kidList!=null && kidList.length>0, found=false;

        //while(hasKids && subtype== PdfDictionary.Unknown){
            //System.out.println(hasKids+" "+formObject.getObjectRefAsString());
            if (hasKids) {
                int kidCount=kidList.length;

                FormObject[] kids=new FormObject[kidCount];

                for(int ii=0;ii<kidCount;ii++){ //iterate through all parts

                    kids[ii]=new FormObject(new String(kidList[ii]),null);
                    currentPdfFile.readObject(kids[ii]);

                    subtype=kids[ii].getParameterConstant(PdfDictionary.Subtype);
                    if(subtype!=PdfDictionary.Unknown){ //exit on first match as should be all the same
                        ii=kidCount;
                        found=true;
                    }
                }

                //none found so scan recursively
                /**if(!found){

                    for(int ii=0;ii<kidCount;ii++){ //iterate through all parts

                        subtype=findObjectType(kids[ii]);
                        if(subtype!=PdfDictionary.Unknown){ //exit on first match as should be all the same
                            ii=kidCount;
                            found=true;
                        }
                    }
                }/**/
    /**
            }
        //}
        return subtype;
    }/**/

    private int processFormObject(int page, boolean debugNew, Map formsProcessed, FormObject formObject, Object objRef, int i, int forms) {
        boolean isOnPage=false;
        if(forms==0){ //check page
            PdfObject pageObj=formObject.getDictionary(PdfDictionary.P);

            byte[] pageRef=null;

            if(pageObj!=null)
                pageRef=pageObj.getUnresolvedData();

            if(pageRef==null || pageObj==null){

                String parent=formObject.getStringKey(PdfDictionary.Parent);

                if(parent!=null){
                    PdfObject parentObj = getParent(parent);

                    pageObj=parentObj.getDictionary(PdfDictionary.P);
                    if(pageObj!=null)
                        pageRef=pageObj.getUnresolvedData();
                }
            }

            if(pageRef==null){

                byte[][] kidList = getKid(formObject);

                boolean hasKids=kidList!=null && kidList.length>0;

                if (hasKids) {

                    int kidCount=kidList.length;

                    FormObject kidObject;
                    for(int jj=0;jj<kidCount;jj++){
                        String key=new String(kidList[jj]);

                        kidObject= (FormObject) cachedObjs.get(key);

                        if(kidObject==null){
                            kidObject = new FormObject(key,formsActionHandler);
                            //kidObject.setPageNumber(page);
                            //kidObject.setPDFRef((String)key);
                            currentPdfFile.readObject(kidObject);

                            cachedObjs.put(key, kidObject);

                        }

                        pageObj=kidObject.getDictionary(PdfDictionary.P);

                        if(pageObj!=null)
                            pageRef=pageObj.getUnresolvedData();

                        if(pageRef!=null)
                            jj=kidCount;
                    }
                }
            }

            int objPage=-1;
            if(pageRef!=null)
                objPage=currentPdfFile.convertObjectToPageNumber(new String(pageRef));

            isOnPage=objPage==page;

        }

        if(forms==1 || isOnPage){


            //if(objRef!=null && objRef.equals("48 0 R"))
              //              System.out.println("c "+forms+" "+isOnPage);

          //code to read the page number from the P (page) object of the form, but it is wrong.
//          PdfObject pageObj = formObject.getDictionary(PdfDictionary.P);
//          if(pageObj!=null){
//            String pageObjRef = pageObj.getObjectRefAsString();
//            int formPage = decode_pdf.getPageFromObjectRef(pageObjRef);
//            if(formPage==-1)
//              formObject.setPageNumber(page);
//            else
//              formObject.setPageNumber(formPage);
//          }else
            formObject.setPageNumber(page);

            //lose from cache
            cachedObjs.remove(objRef);

            String parent=formObject.getStringKey(PdfDictionary.Parent);

            //clone parent to allow inheritance of values or create new
            if(parent!=null){
                FormObject parentObj = getParent(parent);

                //inherited values
                if(parentObj!=null){
                  //all values are copied from the parent inside this call
                    formObject.setParent(parent,parentObj,true);
                }

                //remove kids from Form
                //formObject.setKeyArray(PdfDictionary.Kids,null);
            }

            //work around for jcentricity.pdf
            /**
             PdfObject A=formObject.getDictionary(PdfDictionary.A);
             if(A!=null){
             PdfArrayIterator rawD=A.getMixedArray(PdfDictionary.Dest);

             if(rawD!=null && rawD.getTokenCount()==1){
             String D=rawD.getNextValueAsString(true);

             if(D!=null && !D.endsWith(" R"))
             D=currentPdfFile.convertNameToRef(D);

             if(D!=null){

             Map map=currentPdfFile.readObject(new PdfObject(1),D,null);

             if(map!=null){
             Object aData=currentField.get("A");
             if(aData!=null && aData instanceof Map)
             ((Map)aData).put("D",map.get("D"));
             }
             }
             }
             }/**/

            fDecoder.createAppearanceString(formObject, currentPdfFile);

            if (formObject!= null){

                if(parent!=null)
                    formObject.setParent(parent);//parent object was added earlier

                if(forms==0)
                    Fforms[i++] = formObject;
                else
                    Aforms[i++] = formObject;

                //also flag
                if(objRef!=null)
                    formsProcessed.put(objRef, "x");
//moved to after createField so the fully qualified names are stored.
//keep this in case we have to return to old functioning.
//                compData.storeRawData(formObject); //store data so user can access
            }
        }
        return i;
    }

    private FormObject getParent(String parent) {

        Map objects=compData.getRawFormData();

        FormObject parentObj;
        parentObj=(FormObject)objects.get(parent);

        if(parentObj==null && parent!=null){ //not yet read so read and cache
            parentObj = new FormObject(parent,formsActionHandler);
            currentPdfFile.readObject(parentObj);

            //remove kids in Parent
            parentObj.setKeyArray(PdfDictionary.Kids,new byte[][]{{0}});

            objects.put(parent, parentObj);

        }
        return parentObj;
    }

  private byte[][] getKid(FormObject formObject) {

        int subtype=formObject.getParameterConstant(PdfDictionary.Subtype);
        if(subtype==PdfDictionary.Tx || subtype==PdfDictionary.Btn)
                    return null;

        byte[][] kidList=formObject.getKeyArray(PdfDictionary.Kids);

    if(kidList!=null){
      String parentRef=formObject.getStringKey(PdfDictionary.Parent);

      PdfObject parentObj=(PdfObject) ((Object[]) compData.getRawForm(parentRef))[0];

      if(parentObj!=null && parentObj.getKeyArray(PdfDictionary.Kids)!=null)
        kidList=null;
    }

    return kidList;
  }

  /**
   * get properties in form as object with getMethods.
   *
   * This will take either the Name or the PDFref
   *
   * (ie Box or 12 0 R)
   *
   * This returns an object[]

   * In the case of a PDF with radio buttons Box (12 0 R), Box (13 0 R), Box (14 0 R)
   * getFormDataAsObject(Box) would return an Object[] which is actually Object[3]
   * getFormDataAsObject(12 0 R) would return an Object[] which has a single value
   * any of these values can be NULL
   *
   */
  public Object[] getFormDataAsObject(String objectName) {

    return compData.getRawForm(objectName);
  }

  /**
   * scan object or parents for page number

  private int getPageForComponent(int page, Map currentField) {

    int formPage = -1;
    Object rawPageNumber = currentPdfFile.resolveToMapOrString("PageNumber", currentField.get("PageNumber"));


    if (rawPageNumber != null)
      formPage = Integer.parseInt((String) rawPageNumber);

    if(formPage==-1 && currentField.containsKey("Kids")){

      Object kidData = currentPdfFile.resolveToMapOrString("Kids",currentField.get("Kids"));

      if(kidData instanceof Map){

        Map kidMap = (Map)kidData;

        Iterator iter = kidMap.keySet().iterator();
        int val=0,kidPage=-1;
        while(iter.hasNext()){
          String key = (String) iter.next();

          Object data = currentPdfFile.resolveToMapOrString(key,kidMap.get(key));
          if(data instanceof Map){
            Object kidPageNum = currentPdfFile.resolveToMapOrString("PageNumber",((Map)data).get("PageNumber"));
            if (kidPageNum != null)
              kidPage = Integer.parseInt((String) kidPageNum);
          }else {
          }

          if(kidPage==page)
            formPage = kidPage;
          val++;
        }
      }
    }
    return formPage;
  }

  /**
   * display widgets onscreen for range (inclusive)
   */
  public void displayComponentsOnscreen(int startPage, int endPage) {

            //<start-adobe>
        //just incase not removed
        if (this.decode_pdf.getDisplayView() != org.jpedal.Display.PAGEFLOW)
            this.removeDisplayComponentsFromScreen();
            //<end-adobe>

        if (showMethods)
      System.out.println(this + " displayComponentsOnscreen " + startPage + ' ' + endPage);

    //make sure this page is inclusive in loop
    endPage++;

    compData.displayComponents(startPage, endPage);
   
  }


    /**
   * create a widget to handle FDF button
   */
  private void createField(final FormObject formObject, int formNum) {
   
    if (showMethods)
      System.out.println("createField " + formNum);// + ' ' + formObject);

    Integer widgetType; //no value set

    Object retComponent;

        int subtype=formObject.getParameterConstant(PdfDictionary.Subtype);//FT

        //<start-noform>

    //if sig object set global sig object so we can access later
    if(subtype == PdfDictionary.Sig){
      if(sigObject==null) //ensure initialised
        sigObject=new HashSet();

      sigObject.add(formObject);

    }
   
    //check if a popup is associated
    if(formObject.getDictionary(PdfDictionary.Popup)!=null){
      formObject.setActionFlag(FormObject.POPUP);
    }

    //flags used to alter interactivity of all fields
    boolean readOnly, required, noexport;

    boolean[] flags = formObject.getFieldFlags();//Ff
    if (flags != null) {
            //noinspection UnusedAssignment
            readOnly = flags[FormObject.READONLY_ID];
            //noinspection UnusedAssignment
            required = flags[FormObject.REQUIRED_ID];
            //noinspection UnusedAssignment
            noexport = flags[FormObject.NOEXPORT_ID];

      /*
                 boolean comb=flags[FormObject.COMB_ID];
                 boolean comminOnSelChange=flags[FormObject.COMMITONSELCHANGE_ID];
                 boolean donotScrole=flags[FormObject.DONOTSCROLL_ID];
                 boolean doNotSpellCheck=flags[FormObject.DONOTSPELLCHECK_ID];
                 boolean fileSelect=flags[FormObject.FILESELECT_ID];
                 boolean isCombo=flags[FormObject.COMBO_ID];
                 boolean isEditable=flags[FormObject.EDIT_ID];
                boolean isMultiline=flags[FormObject.MULTILINE_ID];
                boolean isPushButton=flags[FormObject.PUSHBUTTON_ID];
                boolean isRadio=flags[FormObject.RADIO_ID];
                boolean hasNoToggleToOff=flags[FormObject.NOTOGGLETOOFF_ID];
                boolean hasPassword=flags[FormObject.PASSWORD_ID];
                boolean multiSelect=flags[FormObject.MULTISELECT_ID];
                boolean radioinUnison=flags[FormObject.RADIOINUNISON_ID];
                boolean richtext=flags[FormObject.RICHTEXT_ID];
                boolean sort=flags[FormObject.SORT_ID];
       */
    }

    if (debug) {
      if (flags != null) {
        System.out.println("FLAGS - pushbutton=" + flags[16] + " radio=" + flags[15] + " notoggletooff=" +
            flags[14] + "\n multiline=" + flags[12] + " password=" + flags[13] +
            "\n combo=" + flags[17] + " editable=" + flags[18] + " readOnly=" + readOnly +
            "\n BUTTON=" + (subtype == PdfDictionary.Btn) + " TEXT=" + (subtype ==PdfDictionary.Tx) +
                        " CHOICE=" + (subtype == PdfDictionary.Ch) + " SIGNATURE=" + (subtype == PdfDictionary.Sig) +
            "\n characteristic=" + ConvertToString.convertArrayToString(formObject.getCharacteristics()));
      } else {
        System.out.println("FLAGS - all false");
      }
    }

    if (debug && flags != null && (required || flags[19] || noexport || flags[20] || flags[21] || flags[23] || flags[25] || flags[25]))
      System.out.println("renderer UNTESTED FLAGS - readOnly=" + readOnly + " required=" + required + " sort=" + flags[19] + " noexport=" + noexport +
          " fileSelect=" + flags[20] + " multiSelect=" + flags[21] + " donotScrole=" + flags[23] + " radioinUnison=" + flags[25] +
          " richtext=" + flags[25]);

    /** setup field */
    if (subtype == PdfDictionary.Btn) {//----------------------------------- BUTTON  ----------------------------------------
      if(identifyType)
        System.out.println("button");
      //flags used for button types
      //20100212 (ms) Unused ones commented out
      boolean isPushButton = false, isRadio = false;// hasNoToggleToOff = false, radioinUnison = false;
      if (flags != null) {
        isPushButton = flags[FormObject.PUSHBUTTON_ID];
        isRadio = flags[FormObject.RADIO_ID];
        //hasNoToggleToOff = flags[FormObject.NOTOGGLETOOFF_ID];
        //radioinUnison = flags[FormObject.RADIOINUNISON_ID];
      }

      if (isPushButton) {

        widgetType=FormFactory.PUSHBUTTON;
        retComponent = formFactory.pushBut(formObject);

      }else if(isRadio){
        widgetType=FormFactory.RADIOBUTTON;
        retComponent = formFactory.radioBut(formObject);
      }else {
        widgetType=FormFactory.CHECKBOXBUTTON;
        retComponent = formFactory.checkBoxBut(formObject);
      }

    } else {
      if (subtype ==PdfDictionary.Tx) { //-----------------------------------------------  TEXT --------------------------------------
        if(identifyType)
          System.out.println("text");
        //flags used for text types
        // 20100212 (ms) commented out ones not used
        boolean isMultiline = false, hasPassword = false;// doNotScroll = false, richtext = false, fileSelect = false, doNotSpellCheck = false;
        if (flags != null) {
          isMultiline = flags[FormObject.MULTILINE_ID];
          hasPassword = flags[FormObject.PASSWORD_ID];
          //doNotScroll = flags[FormObject.DONOTSCROLL_ID];
          //richtext = flags[FormObject.RICHTEXT_ID];
          //fileSelect = flags[FormObject.FILESELECT_ID];
          //doNotSpellCheck = flags[FormObject.DONOTSPELLCHECK_ID];
        }

        if (isMultiline) {

          if (hasPassword) {

            widgetType=FormFactory.MULTILINEPASSWORD;
            retComponent = formFactory.multiLinePassword(formObject);

          } else {

            widgetType=FormFactory.MULTILINETEXT;
            retComponent = formFactory.multiLineText(formObject);

          }
        } else {//singleLine

          if (hasPassword) {

            widgetType=FormFactory.SINGLELINEPASSWORD;
            retComponent = formFactory.singleLinePassword(formObject);

          } else {

            widgetType=FormFactory.SINGLELINETEXT;
            retComponent = formFactory.singleLineText(formObject);


                    }
        }
      }else if (subtype==PdfDictionary.Ch) {//----------------------------------------- CHOICE ----------------------------------------------
        if(identifyType)
          System.out.println("choice");
        //flags used for choice types
        //20100212 (ms) Unused ones commented out
        boolean isCombo = false;// multiSelect = false, sort = false, isEditable = false, doNotSpellCheck = false, comminOnSelChange = false;
        if (flags != null) {
          isCombo = flags[FormObject.COMBO_ID];
          //multiSelect = flags[FormObject.MULTISELECT_ID];
          //sort = flags[FormObject.SORT_ID];
          //isEditable = flags[FormObject.EDIT_ID];
          //doNotSpellCheck = flags[FormObject.DONOTSPELLCHECK_ID];
          //comminOnSelChange = flags[FormObject.COMMITONSELCHANGE_ID];
        }

        if (isCombo) {// || (type==XFAFORM && ((XFAFormObject)formObject).choiceShown!=XFAFormObject.CHOICE_ALWAYS)){

          widgetType=FormFactory.COMBOBOX;
          retComponent = formFactory.comboBox(formObject);

        } else {//it is a list

          widgetType=FormFactory.LIST;
          retComponent = formFactory.listField(formObject);
        }
      } else if (subtype == PdfDictionary.Sig) {
        if(identifyType)
          System.out.println("signature");

        widgetType=FormFactory.SIGNATURE;
        retComponent = formFactory.signature(formObject);

      } else{//assume annotation if (formType == ANNOTATION) {
        if(identifyType)
          System.out.println("annotation "+formObject.getObjectRefAsString()+ ' ' +formFactory);
      //<end-noform>

        widgetType=FormFactory.ANNOTATION;
        retComponent = formFactory.annotationButton(formObject);
     //<start-noform>

//            } else {
//        if(identifyType)
//          System.out.println("else @@@@@@");
//
//        if (debug) {
//          if (flags != null) {
//            System.out.println("UNIMPLEMENTED field=FLAGS - pushbutton=" + flags[16] + " radio=" + flags[15] +
//                " multiline=" + flags[12] + " password=" + flags[13] + " combo=" + flags[17] +
//                " BUTTON=" + button + " TEXT=" + text + " CHOICE=" + choice);
//          } else
//            System.out.println("UNIMPLEMENTED field=BUTTON=" + button + " TEXT=" + text + " CHOICE=" + choice + " FLAGS=all false");
//        }
      }
    }

        //<end-noform>
   
    formObject.setFormType(widgetType);

        //set Component specific values such as Tooltip and mouse listener
    compData.completeField(formObject, formNum, widgetType, retComponent, currentPdfFile);
    }



    /**
   * return the component associated with this objectName (returns null if no match). Names are case-sensitive.
   * Please also see method getComponentNameList(int pageNumber),
   * if objectName is null then all components will be returned
   */
  public Object[] getComponentsByName(String objectName) {

    /**make sure all forms decoded*/
    for (int p = 1; p < this.pageCount + 1; p++) //add init method and move scaling/rotation to it
            createDisplayComponentsForPage(p,null);

        if (showMethods)
      System.out.println("getComponentNameList " + objectName);

    return compData.getComponentsByName(objectName);

  }

  /**
   * return a List containing the names of  forms on a specific page which has been decoded.
   * <p/>
   * <p/>
   *
   * @throws PdfException An exception is thrown if page not yet decoded
   */
    public List getComponentNameList() throws PdfException {

        if (showMethods)
            System.out.println("getComponentNameList");

        if (ATotalCount==0 && FfieldCount==0)// || compData.trackPagesRendered == null)
            return null;

        //must be switched off!
        boolean rasterizeForms=compData.formsRasterizedForDisplay();
        compData.setRasterizeForms(false);

        /**make sure all forms decoded*/
        for (int p = 1; p < this.pageCount + 1; p++)
            createDisplayComponentsForPage(p,null);

        //restore
        compData.setRasterizeForms(rasterizeForms);

        return getComponentNameList(-1);

    }

  /**
   * return a List containing the names of  forms on a specific page which has been decoded.
   *
   * @throws PdfException An exception is thrown if page not yet decoded
   */
  public List getComponentNameList(int pageNumber) throws PdfException {

    if (showMethods)
      System.out.println("getComponentNameList " + pageNumber);

    if(FfieldCount==0 && ATotalCount==0)
      return null;
    else
      return compData.getComponentNameList(pageNumber);


  }

  /**
   * setup object which creates all GUI objects
   */
  public void setFormFactory(FormFactory newFormFactory) {
    //if (showMethods)
//      System.out.println(this+" setFormFactory " + newFormFactory);

    formFactory = newFormFactory;

            formsActionHandler.setActionFactory(formFactory.getActionFactory());

            /**
             * allow user to create custom structure to hold data
             */
            compData=formFactory.getCustomCompData();

        //pass in Javascript
    compData.setJavascript(javascript);

    //formFactory.setDataObjects(compData);

    }


  /**
   * does nothing or FORM except set type, resets annots and last values
   */
  public void openFile(int pageCount) {

    if (showMethods)
      System.out.println("openFile " + pageCount);

    this.pageCount = pageCount;

        //flush data
    compData.reset(null);
    proxyObjects.clear();

    compData.flushFormData();

        cachedObjs.clear();
  }

  /**return form data in a Map
  public Map getSignatureObject(String ref) {

    Map certObj=this.currentPdfFile.readObject(new PdfObject(ref), ref, null);

    Object sigRef=certObj.get("V");

    if(sigRef == null)
      return null;

    Map fields=new HashMap();
    fields.put("Name", "x");
    fields.put("Reason", "x");
    fields.put("Location", "x");
    fields.put("M", "x");
    fields.put("Cert", "x");

    //allow for ref or direct
    if(sigRef instanceof String){
      certObj=currentPdfFile.readObject(new PdfObject((String)sigRef), (String)sigRef, fields);
    }else
      certObj=(Map)sigRef;

    //make string into strings
    Iterator strings=fields.keySet().iterator();
    while(strings.hasNext()){
      Object fieldName=strings.next();
      byte[] value=(byte[]) certObj.get(fieldName);
      if(value!=null && !fieldName.equals("Cert"))
        certObj.put(fieldName, PdfReader.getTextString(value));

    }

    return certObj;
  }/**/

  /**
   * get GUIData object with all widgets
   */
  public GUIData getCompData() {
    return compData;
  }

  /**return Signature as iterator with one or more objects or null*/
  public Iterator getSignatureObjects() {
    if(sigObject==null)
      return null;
    else
      return sigObject.iterator();
  }

  public ActionHandler getActionHandler() {
    return formsActionHandler;
  }

    public FormFactory getFormFactory() {
        return formFactory;
    }

    public Map getRawFormData(){
        return compData.getRawFormData();
    }

    public void setIgnoreForms(boolean ignoreForms) {
        this.ignoreForms=ignoreForms;
    }

    public boolean ignoreForms() {
        return ignoreForms;
    }

    public void dispose() {

    pageData=null;

    AfieldCount = null;

    fDecoder=null;

    formsActionHandler=null;

    //linkHandler=null;

    javascript=null;


      Fforms=null;

      Aforms=null;

      fieldList=null;
      annotList=null;

      formFactory=null;

    compData=null;
    proxyObjects.clear();

    sigObject=null;

      cachedObjs=null;

      pageData=null;

    currentPdfFile=null;

    fDecoder=null;

    //linkHandler=null;

      acroObj=null;

  }
 
  public Javascript getJavaScriptObject() {
    return javascript;
  }
 
  /**
   * get Iterator with list of all Annots on page or
   * return null if no Annots  - no longer needs
     * call to decodePage beforehand as checks itself
   */
    public PdfArrayIterator getAnnotsOnPage(final int page) {


        //idiot test (if I can make this mistake lets trap it)
        if(page<1 || page>decode_pdf.getPageCount())
            throw new RuntimeException("Page "+page+" out of range (1 - "+decode_pdf.getPageCount()+ ')');

        //check annots decoded - will just return if done
        if (SwingUtilities.isEventDispatchThread()){

            createDisplayComponentsForPage(page,null);

        }else {
            final Runnable doPaintComponent = new Runnable() {
                public void run() {
                    decode_pdf.waitForDecodingToFinish();
                    createDisplayComponentsForPage(page,null);
                }
            };
            SwingUtilities.invokeLater(doPaintComponent);
        }

    if(annotList!=null && annotList.length>page && annotList[page]!=null){
            annotList[page].resetToStart();
            return annotList[page];
    }else{
      return null;
    }
  }
 
  /**
   * checks if the string <b>toAdd</b> is already in the list,
   * if not adds it and returns true,
   * returns false if the item should not be added
   */
  private boolean addItem(Object toAdd){
    if(toAdd==null)
      return false;
    //toAdd = Strip.removeArrayDeleminators(toAdd.toString());

    if(!currentItems.containsKey(toAdd)){
      currentItems.put(toAdd,"x");
      return true;
    }else {
      return false;
    }
  }
 
    /**JS check all forms to see if any have been updated and if so update them */
    public void updateChangedForms() {
      // Get the raw form objects from the component data
      Map forms = compData.getRawFormData();

      //if some forms exist iterate over them
      if(forms.size()>1){
        Iterator formsIter = forms.keySet().iterator();
        FormObject form;
        while(formsIter.hasNext()){
          form = (FormObject) forms.get(formsIter.next());
          if (form != null){
           
            //check to see if the text color has changed
            if(form.hasColorChanged()){
              //update to the new color
              compData.setTextColor(form.getObjectRefAsString(), form.getTextColor());
              compData.invalidate(form.getTextStreamValue(PdfDictionary.T));
             
              // reset color changed, so we dant do it again unless needed
              form.resetColorChanged();
            }

            // if the form has changed reload the values into the display object
            if(form.hasValueChanged()){
            //dont set unformatted value here
            String objRef = form.getObjectRefAsString();
            compData.setUnformattedValue(objRef, compData.getValue(objRef));
            //dont set the last valid value as were not sure if it is valid
           
            //change the values within the componentData
            compData.setValue(form.getObjectRefAsString(), form.getValue(), false, false);

               
                      compData.invalidate(form.getTextStreamValue(PdfDictionary.T));

                        // reset values changed so we dant do it again unless needed
              form.resetFormChanged();
            }

          //check to see if the display has chnaged
            if(form.hasDisplayChanged()){

              boolean[] characteristic = form.getCharacteristics();
              //check if the form should be hidden, or shown now
                  if (characteristic[0] || characteristic[1] || characteristic[5]) {
                      compData.setCompVisible(form.getObjectRefAsString(),false);
                  }else {
                    compData.setCompVisible(form.getObjectRefAsString(),true);
                  }
            }
          }
        }
      }
    }

    /**JS returns an array of names, for which this parent object is extended into. */
    public String[] getChildNames(String name){
      return compData.getChildNames(name);
    }
   
  /**JS return the first field by the given name, name should never be NULL */
  public Object getField(String name){
    if(name==null)
      return null;
   
      return compData.getRawForm(name);
  }

  /**JS resets all the fields within this form. */
  public void resetForm(){ resetForm(null);}
 
  /**JS resets the fields within this form.
   * @param aFields - defines which fields to reset, or all fields if null.
   */
  public void resetForm(String[] aFields){
    formsActionHandler.getActionFactory().reset(aFields);
  }
 
  //<start-adobe><start-thin>
  public int getPageNum(){
   
        SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));
        if(swingGUI!=null)
            return swingGUI.getCurrentPage();
        else
            return 1;
  }
  //<end-thin><end-adobe>
 
  public void setPageNum(int page){
    //change the page to the page defined, using Unknown as this is from javascript so we dont care.
   
    //page is indexes so add 1 for actual page
    page++;
   
    //<start-adobe><start-thin>
    formsActionHandler.changeTo(null, page, null, null,true);
    //<end-thin><end-adobe>
  }

  public void setZoomType(String newType){
   
    //<start-adobe><start-thin>
    if(newType.equals("FitPage"))
      formsActionHandler.changeTo(null, -1, null, -3,true);
    else if(newType.equals("FitWidth"))
      formsActionHandler.changeTo(null, -1, null, -1,true);
    else if(newType.equals("FitHeight"))
      formsActionHandler.changeTo(null, -1, null, -2,true);
//    else if(newType.equals("FitVisibleWidth"))//check p263 of "javascript for acrobat API reference.pdf"
//      ;
//    else if(newType.equals("Preferred"))
//      ;
//    else if(newType.equals("ReflowWidth"))
//      ;
//    else if(newType.equals("NoVary"))
//      ;
    else {
     
    }
   
    //<end-thin><end-adobe>
  }
 
  //<start-adobe><start-thin>
  /*JS used to see if the forms need to be saved or not */
  public boolean getDirty(){
        SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));
        if(swingGUI!=null)
            return swingGUI.getFormsDirtyFlag();
        else
            return false;
  }
 
  /*JS sets the flag that defines if the forms should be saved or not*/
  public void setDirty(boolean dirty){
    SwingGUI swingGUI=((SwingGUI)decode_pdf.getExternalHandler(Options.SwingContainer));
        if(swingGUI!=null)
        swingGUI.setFormsDirtyFlag(dirty);
  }

  //<end-thin><end-adobe>
 
    public boolean hasFormsOnPage(int page) {

        boolean hasAnnots=(annotList!=null && annotList.length>page && annotList[page]!=null);
        boolean hasForm=(hasXFA && fDecoder.hasXFADataSet())||fieldList!=null;
        return hasAnnots || hasForm;
    }

    public PdfObject getFormResources() {
        return AcroRes;
    }

  public boolean formsRasterizedForDisplay() {
    return compData.formsRasterizedForDisplay();
  }
}
TOP

Related Classes of org.jpedal.objects.acroforms.rendering.DefaultAcroRenderer

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.