All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.objects.acroforms.formData.ComponentData Maven / Gradle / Ivy

The newest version!
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/java-pdf-library-support/
 *
 * (C) Copyright 1997-2013, 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


 *
 * ---------------
 * ComponentData.java
 * ---------------
 */
package org.jpedal.objects.acroforms.formData;

import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.jpedal.PdfDecoder;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.Javascript;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.creation.FormFactory;
import org.jpedal.objects.acroforms.utils.FormUtils;
import org.jpedal.objects.layers.PdfLayerList;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.repositories.Vector_String;

/** holds all data not specific to Swing/SWT/ULC */
public abstract class ComponentData implements GUIData {

	// ########################### development flags ##########################

	// ################### static values ################

	/**
	 * flag to make forms draw as images, not swing components
	 */
	protected boolean rasterizeForms = false;

	@Override
	public void setRasterizeForms(boolean inlineForms) {
		this.rasterizeForms = inlineForms;
	}

	/** used by ULC only */
	protected int offset = 0;

	public static final int TEXT_TYPE = 0;
	public static final int BUTTON_TYPE = 1;
	public static final int LIST_TYPE = 2;
	public static final int UNKNOWN_TYPE = -1;

	// ##################### variables #####################

	/** for if we add a popup to the panel, could be used for adding other objects */
	protected boolean forceRedraw = false;

	protected Map hideObjectsMap = new HashMap();

	// allow user to move relative draw position
	protected int userX, userY, widestPageNR, widestPageR;

	/** the current display view, Display.SINGLE, Display.CONTINOUS etc */
	protected int displayView;

	PdfObjectReader currentPdfFile = null;

	int formFactoryType = FormFactory.SWING;

	/**
	 * holds forms data array of formObjects data from PDF as Map for fast lookup 
* convertformIDtoRef = component index to PDF reference
* nameToRef = field name to PDF Reference
* rawFormData = PDF Reference to FormObject
* duplicateNames = field name to PDF References seperated by commas
* caseInsensitiveNameToFieldName = gives the case sensitive fieldname back from case insensitive names use toLowerCase() before using get().
* nameToCompIndex = stores the name and component index as Integer in allFields array.
* refToCompIndex = stores the Pdf Reference and component index as Integer in allFields array.
**/ protected Map rawFormData = new HashMap(), convertFormIDtoRef = new HashMap(), nameToRef = new HashMap(), duplicateNames = new HashMap(), caseInsensitiveNameToFieldName = new HashMap(), nameToCompIndex, refToCompIndex; /** fully qualified field name to PDF reference */ private Map fullyQualToRef = new HashMap(); /** list of all fieldnames so we can find half referenced name such as "1.2." for fields 1.2.1 and 1.2.2 */ private List namesMap = new ArrayList(); /** * the lastValue set for a specified name,
* fieldname to LastValue selected */ protected Map LastValueByName = new HashMap(); /** keeps a record of the last value being changed in the flag and sync methods */ protected Map LastValueChanged = new HashMap(); /** used to map new XFA component references to there form object */ private Map xfaRefToForm; protected Map componentsToIgnore = new HashMap(); protected int insetW; protected int insetH; protected PdfPageData pageData; protected Javascript javascript; /** * local copy needed in rendering */ protected int pageHeight, indent; protected int[] cropOtherY; /** * track page scaling */ protected float displayScaling; protected int rotation; /** * used to only redraw as needed */ protected float lastScaling = -1, oldRotation = 0, oldIndent = 0; /** * used for page tracking */ protected int startPage, endPage, currentPage; /** * the last name added to the nameToCompIndex map */ protected String lastNameAdded = ""; /** stores map of names to indexs of components in allfields */ protected Map duplicates = new HashMap(); protected Map lastValidValue = new HashMap(); protected Map lastUnformattedValue = new HashMap(); protected Map typeValues; /** * next free slot */ protected int nextFreeField = 0; /** * holds the location and size for each field,
* [][0] = x1; [][1] = y1; [][2] = x2; [][3] = y2; */ protected float[][] popupBounds = new float[0][4]; /** * used to draw pages offset if not in SINGLE_PAGE mode */ protected int[] xReached, yReached; /** * table to store if page components already built */ protected int[] trackPagesRendered; /** stores the forms in there original order, accessable by page */ protected List[] formsUnordered; /** * array to hold page for each component so we can scan quickly on page change */ private int formCount; protected PdfLayerList layers; protected PdfDecoder pdfDecoder; /** last value set by user in GUI or null if none */ @Override public Object getLastValidValue(String fieldRef) { if (!fieldRef.contains(" 0 R") && !fieldRef.contains(" 0 X")) { fieldRef = (String) this.nameToRef.get(fieldRef); } return this.lastValidValue.get(fieldRef); } @Override public void setLayerData(PdfLayerList layers) { this.layers = layers; } /** * @param pageNumber * @return list of form names for page */ @Override public List getComponentNameList(int pageNumber) { if (this.trackPagesRendered == null) return null; if ((pageNumber != -1) && (this.trackPagesRendered[pageNumber] == -1)) return null; // now we can interrupt decode page this is more // appropriate // throw new PdfException("[PDF] Page "+pageNumber+" not decoded"); int currentComp; if (pageNumber == -1) currentComp = 0; else currentComp = this.trackPagesRendered[pageNumber]; ArrayList nameList = new ArrayList(); // go through all fields on page and add to list FormObject formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(currentComp)); while ((pageNumber == -1) || (formObject != null && formObject.getPageNumber() == pageNumber)) { String currentName = null; if (formObject != null) { currentName = formObject.getNameUsed(); if (currentName.length() == 0) currentName = null; } if (currentName != null) { if (formObject.testedForDuplicates()) { // stop multiple matches formObject.testedForDuplicates(true); // track duplicates String previous = this.duplicates.get(currentName); if (previous != null) this.duplicates.put(currentName, previous + ',' + currentComp); else this.duplicates.put(currentName, String.valueOf(currentComp)); } nameList.add(currentName); // add to list } currentComp++; if (currentComp == this.nextFreeField + 1) break; formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(currentComp)); } return nameList; } /** * last value set by user in GUI or null if none if fieldRef is not a reference we find a reference from a names table (which can be doubled up * and therefore wrong) */ @Override public Object getLastUnformattedValue(String fieldRef) { if (!fieldRef.contains(" 0 R") && !fieldRef.contains(" 0 X")) { fieldRef = (String) this.nameToRef.get(fieldRef); } return this.lastUnformattedValue.get(fieldRef); } /** reset params for the specified form names, or if null reset all forms params */ @Override public void reset(String[] aFields) { // System.out.println("ComponentData.reset() lastUnformattedMap cleared"); /** You can include non-terminal fields in the array. */ if (aFields != null) { for (String aField : aFields) { String ref = (String) this.nameToRef.get(aFields[0]); this.lastValidValue.remove(ref); this.lastUnformattedValue.remove(ref); } } else { this.lastValidValue.clear(); this.lastUnformattedValue.clear(); } } /** * allow user to lookup page with name of Form. * * @param formName * @return page number or -1 if no page found */ @Override public int getPageForFormObject(String formName) { // Object checkObj; FormObject formObj = null; if (formName.contains("R")) { // checkObj = refToCompIndex.get(formName); formObj = ((FormObject) this.rawFormData.get(formName)); } else { // checkObj = nameToCompIndex.get(formName); String ref = (String) this.nameToRef.get(formName); if (ref != null) formObj = ((FormObject) this.rawFormData.get(ref)); } if (formObj == null) return -1; else return formObj.getPageNumber(); } /** * returns the Type of pdf form, of the named field look at FormFactory.LIST etc to find out which type */ @Override public Integer getTypeValueByName(String fieldName) { /* * this would return the type of the form, or we could use getfieldtype int index; if(fieldName.indexOf("0 R")!=-1){ index = * ((Integer)refToCompIndex.get(fieldName)).intValue(); }else { index = ((Integer)nameToCompIndex.get(fieldName)).intValue(); } return * allFieldsType[index]; */ Object key = this.typeValues.get(fieldName); if (key == null) return FormFactory.UNKNOWN; else return this.typeValues.get(fieldName); } /** * @param page */ private void setStartForPage(int page) { // flag start this.trackPagesRendered[page] = this.nextFreeField; } @Override public void setUnsortedListForPage(int page, List unsortedComps) { this.formsUnordered[page] = unsortedComps; } /** * get value using objectName or field pdf ref. Pdf ref is more acurate */ @Override public Object getValue(Object objectName) { if (objectName == null) return ""; Object checkObj; if (((String) objectName).contains("R")) { checkObj = this.refToCompIndex.get(objectName); } else { checkObj = this.nameToCompIndex.get(objectName); } return getFormValue(checkObj); } protected Object checkGUIObjectResolved(int formNum) { if (1 == 1) throw new RuntimeException("base method checkGUIObjectResolved(formNum) should not be called"); return null; } public void displayComponent(int currentComp, FormObject formObject, Object comp, int startPage, int page) { if (1 == 1) throw new RuntimeException("base method displayComponent( ) should not be called"); } public void setCompVisible(Object comp, boolean visible) { if (1 == 1) throw new RuntimeException("base method setCompVisible(formNum) should not be called"); } /** * put components onto screen display * * @param startPage * @param endPage */ @Override public void displayComponents(int startPage, int endPage) { if (this.rasterizeForms) return; this.startPage = startPage; this.endPage = endPage; for (int page = startPage; page < endPage; page++) { int currentComp = getStartComponentCountForPage(page); // just put on page, allowing for no values (last one always empty as array 1 too big) // allow for empty form if (this.nextFreeField + 1 <= currentComp) return; // display components if (currentComp != -1 && currentComp != -999 && startPage > 0 && endPage > 0) { FormObject formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(currentComp)); while (formObject != null && formObject.getPageNumber() >= startPage && formObject.getPageNumber() < endPage) { Object comp = checkGUIObjectResolved(currentComp); if (comp != null) { /** * sync kid values if needed */ syncKidValues(currentComp); displayComponent(currentComp, formObject, comp, startPage, page); } currentComp++; if (currentComp == this.nextFreeField + 1) break; formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(currentComp)); } } } } @Override public void hideComp(String compName, boolean visible) { Object[] checkObj; int[] indexs = null; if (compName == null) { indexs = new int[this.nextFreeField + 1]; for (int i = 0; i < indexs.length; i++) { indexs[i] = i; } } Object compIndex = getIndexFromName(compName); checkObj = getComponentsByName(compName, compIndex, true); if (checkObj != null) { for (int j = 0; j < checkObj.length; j++) { if (indexs != null) { FormObject formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(indexs[j])); Rectangle rect = formObject.getBoundingRectangle(); // we need the index for the object so we can check the bounding boxes float rx = rect.x; float ry = rect.y; float rwidth = rect.width; float rheight = rect.height; Rectangle rootRect = new Rectangle((int) rx, (int) ry, (int) rwidth, (int) rheight); // find components hidden within this components bounds List indexsToHide = this.hideObjectsMap.get(rootRect); if (indexsToHide == null) { // if no list figure out the list indexsToHide = new ArrayList(); for (int i = 0; i < this.nextFreeField + 1; i++) { FormObject formObject2 = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(i)); if (formObject2 != null && rootRect.contains(formObject2.getBoundingRectangle())) { indexsToHide.add(i); } } this.hideObjectsMap.put(rootRect, indexsToHide); } // if we dont have a list we dont need to hide any other fields if (indexsToHide != null) { // we should have a list now for (Object anIndexsToHide : indexsToHide) { int index = (Integer) anIndexsToHide; // hide or show the components depending on if we are showing or hiding the root component FormObject formObject3 = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(index)); Object comp = null; if (formObject3 != null) { comp = formObject3.getGUIComponent(); if (comp != null) { setCompVisible(comp, !visible); } } } } } setCompVisible(checkObj[j], visible); } } } public Integer convertRefToID(Object ref) { Integer checkObj; if (ref.toString().contains("R")) { checkObj = (Integer) this.refToCompIndex.get(ref); } else { checkObj = (Integer) this.nameToCompIndex.get(ref); } return checkObj; } /** * get actual widget using objectName as ref or null if none * * @param objectName */ @Override public Object getWidget(Object objectName) { if (objectName == null) return null; else { Integer index = convertRefToID(objectName); if (index == null) return null; else { return checkGUIObjectResolved(index); } } } public void syncKidValues(int currentComp) { if (1 == 1) throw new RuntimeException("base method syncFormsByName(name) should not be called"); } public Object getFormValue(Object checkObj) { if (1 == 1) throw new RuntimeException("base method getFormValue(checkObj) should not be called"); return null; } /** * get next free field slot * */ @Override public int getNextFreeField() { return this.nextFreeField; } /** * max number of form slots */ public int getMaxFieldSize() { return this.formCount; } /** * @param page * @return start component ID or -1 if not set or -999 if trackPagesRendered not initialized */ @Override public int getStartComponentCountForPage(int page) { if (this.trackPagesRendered == null) return -999; else if (this.trackPagesRendered.length > page && page > -1) return this.trackPagesRendered[page]; else return -1; } /** * setup values needed for drawing page * * @param pageData * @param page */ @Override public void initParametersForPage(PdfPageData pageData, int page, PdfDecoder decoder) { // ensure setup if (this.cropOtherY == null || this.cropOtherY.length <= page) this.resetComponents(0, page + 1, false); int mediaHeight = pageData.getMediaBoxHeight(page); int cropTop = (pageData.getCropBoxHeight(page) + pageData.getCropBoxY(page)); // take into account crop if (mediaHeight != cropTop) this.cropOtherY[page] = (mediaHeight - cropTop); else this.cropOtherY[page] = 0; this.pageHeight = mediaHeight; this.currentPage = page; // track page displayed if (!formsRasterizedForDisplay()) { // set for page setStartForPage(page); } this.pdfDecoder = decoder; } /** * used to flush/resize data structures on new document/page * * @param formCount * @param pageCount * @param keepValues * return true if successful, false if formCount is less than current count. */ @Override public boolean resetComponents(int formCount, int pageCount, boolean keepValues) { if (keepValues && this.formCount > formCount) return false; this.formCount = formCount; if (!keepValues) { this.nextFreeField = 0; this.refToCompIndex = new HashMap(formCount + 1); this.nameToCompIndex = new HashMap(formCount + 1); this.typeValues = new HashMap(formCount + 1); // start up boundingBoxs this.popupBounds = new float[0][4]; // flag all fields as unread this.trackPagesRendered = new int[pageCount + 1]; for (int i = 0; i < pageCount + 1; i++) this.trackPagesRendered[i] = -1; this.formsUnordered = new List[pageCount + 1]; // reset offsets this.cropOtherY = new int[pageCount + 1]; // reset the multi page shifting values so we dont get forms half way across the page on a single page view. this.xReached = this.yReached = null; } return true; } /** * pass in current values used for all components * * @param scaling * @param rotation * @param indent */ @Override public void setPageValues(float scaling, int rotation, int indent, int userX, int userY, int displayView, int widestPageNR, int widestPageR) { this.rotation = rotation; this.displayScaling = scaling; this.indent = indent; this.userX = userX; this.userY = userY; this.displayView = displayView; this.widestPageNR = widestPageNR; this.widestPageR = widestPageR; } /** * used to pass in offsets and PdfPageData object so we can access in rendering * * @param pageData * @param insetW * @param insetH */ @Override public void setPageData(PdfPageData pageData, int insetW, int insetH) { // track inset on page this.insetW = insetW; this.insetH = insetH; this.pageData = pageData; } /** * offsets for forms in multi-page mode */ @Override public void setPageDisplacements(int[] xReached, int[] yReached) { this.xReached = xReached; this.yReached = yReached; // force redraw this.forceRedraw = true; } /** * force redraw (ie for refreshing layers) */ @Override public void setForceRedraw(boolean forceRedraw) { this.forceRedraw = forceRedraw; } /** * provide access to Javascript object * * @param javascript */ @Override public void setJavascript(Javascript javascript) { this.javascript = javascript; } @Override public void resetDuplicates() { this.duplicates.clear(); } protected boolean isFormNotPrinted(int currentComp) { // get correct key to lookup form data String ref = this.convertIDtoRef(currentComp); // System.out.println(currentComp+" "+comp.getLocation()+" "+comp); FormObject form = (FormObject) getRawForm(ref)[0]; if (form != null) { return this.componentsToIgnore != null && (this.componentsToIgnore.containsKey(form.getParameterConstant(PdfDictionary.Subtype)) || this.componentsToIgnore .containsKey(form.getParameterConstant(PdfDictionary.Type))); } else return false; } @Override public void storeXFARefToForm(Map xfaRefToFormObject) { this.xfaRefToForm = xfaRefToFormObject; } /** * store form data and allow lookup by PDF ref or name (name may not be unique) * * @param formObject */ @Override public void storeRawData(FormObject formObject) { String fieldName = formObject.getTextStreamValue(PdfDictionary.T); // add names to an array to track the kids if (fieldName != null) { this.namesMap.add(fieldName); // add case insensitive fieldname map to actual name, to fix some JS errors in files. this.caseInsensitiveNameToFieldName.put(fieldName.toLowerCase(), fieldName); } String ref = formObject.getObjectRefAsString(); this.nameToRef.put(fieldName, ref); this.rawFormData.put(ref, formObject); String parent = formObject.getParentRef(); // if no name, or parent has one recursively scan tree for one in Parent boolean isMultiple = false; String fullyQualName = null; while (parent != null && !parent.equals(ref)) { FormObject parentObj; { // parent.indexOf(" R")!=-1 parentObj = new FormObject(parent, false); this.pdfDecoder.getIO().readObject(parentObj); } // parentObj is null in mixedForms.pdf String newName = null; if (parentObj != null) newName = parentObj.getTextStreamValue(PdfDictionary.T); if (newName == null) break; else if (fieldName != null) { // we pass in kids data so stop name.name if (!fieldName.contains(newName)) { fullyQualName = newName + '.' + fieldName.substring(fieldName.lastIndexOf('.') + 1); isMultiple = true; } } parent = parentObj.getParentRef(); } // set the field name to be the Fully Qualified Name if (isMultiple) this.fullyQualToRef.put(fullyQualName, ref); /** * track duplicates */ String duplicate = (String) this.duplicateNames.get(fieldName); if (duplicate == null) { // first case this.duplicateNames.put(fieldName, ref); } else { // is a duplicate duplicate = duplicate + ',' + ref; // comma separated list this.duplicateNames.put(fieldName, duplicate); } } @Override public void flushFormData() { this.nameToRef.clear(); this.fullyQualToRef.clear(); this.rawFormData.clear(); this.LastValueByName.clear(); this.duplicateNames.clear(); this.convertFormIDtoRef.clear(); this.namesMap.clear(); this.lastNameAdded = ""; // clear the rectangle map for use in hiding objects behind this.hideObjectsMap.clear(); this.oldIndent = -this.oldIndent; } /** * convert ID used for GUI components to PDF ref for underlying object used so we can access form object knowing ID of component * * @param objectID */ @Override public String convertIDtoRef(int objectID) { return (String) this.convertFormIDtoRef.get(objectID); } @Override public int getFieldType(Object swingComp) { int subtype = ((FormObject) swingComp).getParameterConstant(PdfDictionary.Subtype); switch (subtype) { case PdfDictionary.Tx: return TEXT_TYPE; case PdfDictionary.Ch: return LIST_TYPE; default: // button or sig or annot return BUTTON_TYPE; } } /** * used to debug form names in test code * * @param objectName */ @Override public String getnameToRef(String objectName) { return (String) this.nameToRef.get(objectName); } @Override public int getIndexFromName(String name) { return (Integer) this.nameToCompIndex.get(FormUtils.removeStateToCheck(name, false)); } /** * calls getRawForm(objectName,true);
* check getRawForm(String,boolean) for description */ @Override public Object[] getRawForm(String objectName) { return getRawForm(objectName, true); } /** * returns an Object[] of FormObjects by the specified name.
* each item within the array can be NULL
* if a reference is sent in an array with one formobject will be set back.
* caseSensitive is default search use false for specific cases. */ @Override public Object[] getRawForm(String objectName, boolean caseSensative) { if (!caseSensative) { String name = (String) this.caseInsensitiveNameToFieldName.get(objectName.toLowerCase()); if (name != null) objectName = name; } // if name see if duplicates String matches = (String) this.duplicateNames.get(objectName); if (matches == null || (matches.indexOf(',') == -1)) {// single form // convert to PDFRef if name first objectName = getPossRef(objectName); if (!this.rawFormData.containsKey(objectName)) { // we may have a parent name and we want to return all the children String[] names = getChildNames(objectName); if (names != null && names.length > 0) { Object[] values = new Object[names.length]; for (int i = 0; i < names.length; i++) { objectName = getPossRef(names[i]); values[i] = this.rawFormData.get(objectName); } return values; } } // with 1 field I will just return new Object[]{our 1 object} (as below commented out) // currently we return either formobject or array[] of formobjects. return new Object[] { this.rawFormData.get(objectName) }; } else {// duplicates StringTokenizer comps = new StringTokenizer(matches, ","); int count = comps.countTokens(); Object[] values = new Object[count]; for (int ii = 0; ii < count; ii++) { values[ii] = this.rawFormData.get(comps.nextToken()); } return values; } } private String getPossRef(String objectName) { String possRef = (String) this.nameToRef.get(objectName); if (possRef != null) objectName = possRef; possRef = this.fullyQualToRef.get(objectName); if (possRef != null) objectName = possRef; return objectName; } /** returns the rawformdata map, the key is the pdfRef for whichever object you want */ @Override public Map getRawFormData() { return this.rawFormData; } /** * this takes in a name with a . at the end and returns the kids of that object */ @Override public String[] getChildNames(String name) { if (name == null) return null; // find all fullyqualifiednames and check them. // check if the name is within the list we currently have if (!this.namesMap.isEmpty() && this.namesMap.toString().contains(name)) { Vector_String childNames = new Vector_String(); // scan over the list and find the child names for (Object aNamesMap : this.namesMap) { String val = (String) aNamesMap; if (val.contains(name)) { // add them to our arrayList childNames.addElement(val); } } // return the Vector of childnames as a String[] // NOTE: remember to trim first otherwise you get a massive array childNames.trim(); return childNames.get(); } else { // if there is no name within our list return null return null; } } /** * store and complete setup of component * * @param formObject * @param formNum * @param formType * @param rawField * @param currentPdfFile */ @Override public void completeField(final FormObject formObject, int formNum, Integer formType, Object rawField, PdfObjectReader currentPdfFile) { // use as flag to show we don not increment on lazy init boolean isNotLazyReinitCall = true; if (formType < 0) { formType = -formType; isNotLazyReinitCall = false; } this.currentPdfFile = currentPdfFile; if (rawField == null && this.formFactoryType != FormFactory.SWING) { return; } // only in ULC builds // /** * // if(org.jpedal.examples.canoo.server.ULCViewer.formOption == SpecialOptions.SWING_WIDGETS_ON_CLIENT){ //special ULC case * if(formNum==-1) formNum = nextFreeField; } / **/ String fieldName = formObject.getTextStreamValue(PdfDictionary.T); this.refToCompIndex.put(formObject.getObjectRefAsString(), formNum); this.convertFormIDtoRef.put(formNum, formObject.getObjectRefAsString()); // set the type if (formType.equals(org.jpedal.objects.acroforms.creation.FormFactory.UNKNOWN)) this.typeValues.put(fieldName, org.jpedal.objects.acroforms.creation.FormFactory.ANNOTATION); else this.typeValues.put(fieldName, formType); // append state to name so we can retrieve later if needed String name = fieldName; if (name != null && isNotLazyReinitCall) {// we have some empty values as well as null String stateToCheck = formObject.getNormalOnState(); if (stateToCheck != null && stateToCheck.length() > 0) name = name + "-(" + stateToCheck + ')'; // add fieldname to map for action events String curCompName = FormUtils.removeStateToCheck(name, false); if (curCompName != null && !this.lastNameAdded.equals(curCompName)) { this.nameToCompIndex.put(curCompName, formNum); this.lastNameAdded = curCompName; } formObject.setNameUsed(curCompName); } if (isNotLazyReinitCall) { this.nextFreeField++; } if (rawField != null) { formObject.setGUIComponent(rawField); setGUIComp(formObject, formNum, rawField); } } public void setGUIComp(FormObject formObject, int formNum, Object rawField) { throw new RuntimeException("Should never be called"); } @Override public Object[] getComponentsByName(String objectName) { if (objectName == null) return null; Object checkObj = this.nameToCompIndex.get(objectName); if (checkObj == null) return null; if (checkObj instanceof Integer) { return getComponentsByName(objectName, checkObj, false); } else { LogWriter.writeLog("{stream} ERROR DefaultAcroRenderer.getComponentByName() Object NOT Integer and NOT null"); return null; } } /** * return components which match object name * */ public Object[] getComponentsByName(String objectName, Object checkObj, boolean collateIndexs) { int[] indexs = null; // avoid double counting duplicates Map valuesCounted = new HashMap(); // allow for duplicates String duplicateComponents = this.duplicates.get(objectName); int index = (Integer) checkObj; valuesCounted.put(String.valueOf(index), "x"); boolean moreToProcess = true; int firstIndex = index; String name; while (moreToProcess) { FormObject formObject = (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(index + 1)); if (index + 1 < this.nextFreeField + 1 && formObject != null) { name = formObject.getNameUsed(); if (name == null) { // we now pass Annots through so need to allow for no name moreToProcess = false; } else if (FormUtils.removeStateToCheck(name, false).equals(objectName)) { valuesCounted.put(String.valueOf((index + 1)), "x"); index += 1; } else { moreToProcess = false; } } else moreToProcess = false; } int size = (index + 1) - firstIndex; Object[] compsToRet = new Object[size]; if (collateIndexs) { // add all current indexs from values counted map only as there are no duplicates indexs = new int[size]; } for (int i = 0; i < size; i++, firstIndex++) { compsToRet[i] = checkGUIObjectResolved(firstIndex); if (collateIndexs) { indexs[i] = firstIndex; } if (firstIndex == index) break; } // recreate list and add in any duplicates if (duplicateComponents != null && duplicateComponents.indexOf(',') != -1) { StringTokenizer additionalComponents = new StringTokenizer(duplicateComponents, ","); int count = additionalComponents.countTokens(); // avoid double-counting int alreadyCounted = 0; String[] keys = new String[count]; for (int ii = 0; ii < count; ii++) { keys[ii] = additionalComponents.nextToken(); if (valuesCounted.containsKey(keys[ii])) { alreadyCounted++; keys[ii] = null; } } count = count - alreadyCounted; Object[] origComponentList = compsToRet; compsToRet = new Object[size + count]; // add in original components System.arraycopy(origComponentList, 0, compsToRet, 0, size); if (collateIndexs) { // collate original sized array with new size needed int[] tmpind = indexs; indexs = new int[compsToRet.length]; // add in original components System.arraycopy(tmpind, 0, indexs, 0, size); } // and duplicates int ii; for (int i = 0; i < count; i++) { if (keys[i] == null) // ignore if removed above continue; ii = Integer.parseInt(keys[i]); if (collateIndexs) { // add index ii for all other fields aswell indexs[i + size] = ii; } compsToRet[i + size] = checkGUIObjectResolved(ii); } } return compsToRet; } /** moves the bounds rectangle to be within the inside rectangle */ protected static Rectangle checkPopupBoundsOnPage(Rectangle bounds, Rectangle inside) { if (bounds.x < inside.x) { // if too far left move min X bounds.x = inside.x; } if (bounds.y < inside.y) { // if too far down move to min Y bounds.y = inside.y; } if (bounds.x + bounds.width > inside.x + inside.width) { // if too far right move to rightmost point bounds.x = (inside.x + inside.width - bounds.width); } if (bounds.y + bounds.height > inside.y + inside.height) { // if too far up move to uppermost point bounds.y = (inside.y + inside.height - bounds.height); } return bounds; } /** * if ref is not a reference we find a reference from a names table (which can be doubled up and therefore wrong) */ @Override public void setUnformattedValue(String ref, Object value) { if (!ref.contains(" 0 R") && !ref.contains(" 0 X")) { ref = (String) this.nameToRef.get(ref); } this.lastUnformattedValue.put(ref, value); } /** * if ref is not a reference we find a reference from a names table (which can be doubled up and therefore wrong) */ @Override public void setLastValidValue(String ref, Object value) { if (!ref.contains(" 0 R") && !ref.contains(" 0 X")) { ref = (String) this.nameToRef.get(ref); } this.lastValidValue.put(ref, value); } public Object setValue(String ref, Object value, boolean isValid, boolean isFormatted, Object oldValue) { // track so we can reset if needed if (isValid) { setLastValidValue(ref, value); } // save raw version before we overwrite if (isFormatted) { setUnformattedValue(ref, oldValue); } Object checkObj; if (ref.contains("R")) { checkObj = this.refToCompIndex.get(ref); } else { checkObj = this.nameToCompIndex.get(ref); } // Fix null exception in /PDFdata/baseline_screens/forms/406302.pdf if (checkObj == null) return null; // Now set the formObject value so we keep track of the current field value within our FormObject String pdfRef = convertIDtoRef(((Integer) checkObj).intValue()); FormObject form = ((FormObject) this.rawFormData.get(pdfRef)); // System.out.println("ComponentData.setValue("+ref+" formvalue="+value+")"); form.setValue((String) value); return checkObj; } @Override public void resetAfterPrinting() { this.forceRedraw = true; } /** * flag forms as needing redraw */ public void invalidateForms() { this.lastScaling = -this.lastScaling; } @Override public String getFieldNameFromRef(String ref) { return ((FormObject) this.rawFormData.get(ref)).getTextStreamValue(PdfDictionary.T); } public static int calculateFontSize(int height, int width, boolean area, String text) { int lineLen = text.length(); double v1 = height * 0.85; if (lineLen == 0) return (int) v1; double v2 = width / lineLen; if (v1 > v2 * 2) { return (int) v2; } else { return (int) v1; } } @Override public boolean formsRasterizedForDisplay() { return this.rasterizeForms; } @Override public FormObject getFormObject(int i) { return (FormObject) this.rawFormData.get(this.convertFormIDtoRef.get(i)); } @Override public void setOffset(int offset) { this.offset = offset; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy