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

org.jpedal.examples.handlers.ExampleAnnotationHandler 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


 *
 * ---------------
 * ExampleAnnotationHandler.java
 * ---------------
 */
package org.jpedal.examples.handlers;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.Map;

import javax.swing.JFileChooser;

import org.jpedal.PdfDecoder;
import org.jpedal.examples.viewer.Values;
import org.jpedal.examples.viewer.gui.SwingGUI;
import org.jpedal.external.AnnotationHandler;
import org.jpedal.io.ObjectStore;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.raw.FormObject;
import org.jpedal.objects.raw.PdfArrayIterator;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.render.ImageObject;

public class ExampleAnnotationHandler implements AnnotationHandler {

	/**
	 * example code to adapt
	 * 
	 * @param decode_pdf
	 * @param objs
	 * @param p
	 */
	@Override
	public void handleAnnotations(PdfDecoder decode_pdf, Map objs, int p) {

		// new list we can parse
		PdfArrayIterator annotListForPage = decode_pdf.getFormRenderer().getAnnotsOnPage(p);

		if (annotListForPage != null && annotListForPage.getTokenCount() > 0) { // can have empty lists

			/**
			 * new code to set Annot to have custom image
			 * 
			 * scan and overwrite images of certain types
			 */
			int i = 0;
			int count = annotListForPage.getTokenCount();
			int[] type = new int[count];
			Color[] colors = new Color[count];
			Object[] obj = new Object[count];

			while (annotListForPage.hasMoreTokens()) {

				// Due to the way some pdf's are created it is necessery to take the offset of a page into account when addding custom objects
				// Variables mX and mY represent that offset and need to be taken in to account when placing any additional object on a page.

				int mX = decode_pdf.getPdfPageData().getMediaBoxX(p);
				int mY = decode_pdf.getPdfPageData().getMediaBoxY(p);

				// get ID of annot which has already been decoded and get actual object
				String annotKey = annotListForPage.getNextValueAsString(true);

				Object[] rawObj = decode_pdf.getFormRenderer().getCompData().getRawForm(annotKey);

				for (Object aRawObj : rawObj) {
					if (aRawObj != null) {
						FormObject annotObj = (FormObject) aRawObj;

						// get the FS value
						// PdfObject FS=annotObj.getDictionary(PdfDictionary.FS);

						// and the text
						// if(FS!=null){
						// System.out.println("----"+annotObj.getObjectRefAsString());
						// System.out.println("Contents="+annotObj.getTextStreamValue(PdfDictionary.Contents));
						// System.out.println("F="+FS.getTextStreamValue(PdfDictionary.F));
						// System.out.println("D="+FS.getTextStreamValue(PdfDictionary.D));
						// }

						int subtype = annotObj.getParameterConstant(PdfDictionary.Subtype);

						// if(subtype==PdfDictionary.Link){
						// System.out.println("----"+annotObj.getObjectRefAsString());
						// PdfObject Aobj=annotObj.getDictionary(PdfDictionary.A);
						// System.out.println("A="+Aobj+" "+subtype);
						// PdfObject winObj=Aobj.getDictionary(PdfDictionary.Win);
						// System.out.println("Win="+winObj+" "+winObj.getTextStreamValue(PdfDictionary.D)+" "+winObj.getTextStreamValue(PdfDictionary.P));
						//
						// }
						// subtypes set in PdfDictionary - please use Constant as values may change
						// if not present ask me and I will add
						if (subtype == PdfDictionary.Link) { // might also be PdfDictionary.Link

							// @annot -save so we can lookup (kept as HashMap siply to reduce changes and in case
							// we want something else as value. Could be Set or Vector
							objs.put(annotObj, "x");

							Color col = Color.BLUE;

							// get origin of Form Object
							Rectangle location = annotObj.getBoundingRectangle();

							// SOME EXAMPLES to show other possible uses

							// example stroked shape
							// type[i]= org.jpedal.render.DynamicVectorRenderer.STROKEDSHAPE;
							// colors[i]=Color.RED;
							// obj[i]=new Rectangle(location.x,location.y,20,20); //ALSO sets location. Any shape can be used

							// example simple filled shape
							// type[i]= org.jpedal.render.DynamicVectorRenderer.FILLEDSHAPE;
							// colors[i]=Color.GREEN;
							// obj[i]=new Rectangle(location.x,location.y,20,20); //ALSO sets location. Any shape can be used

							// example text object
							// type[i]= org.jpedal.render.DynamicVectorRenderer.STRING;
							// org.jpedal.render.TextObject textObject=new org.jpedal.render.TextObject(); //composite object so we can pass in
							// parameters
							// textObject.x=location.x+mX;
							// textObject.y=location.y+mY;
							// textObject.text=""+(i+1);
							// textObject.font=new Font("Serif",Font.PLAIN,12);
							// colors[i]=col;
							// obj[i]=textObject; //ALSO sets location

							// example image object
							/**/
							type[i] = DynamicVectorRenderer.IMAGE;
							ImageObject imgObject = new ImageObject(); // composite object so we can pass in parameters
							imgObject.x = location.x + mX;
							imgObject.y = location.y + mY;
							imgObject.image = createUniqueImage(16, String.valueOf((i + 1)), col);
							obj[i] = imgObject; // ALSO sets location

							// example custom - TOTAL FLEXIBILTY as you implement you own custom object
							// type[i]=org.jpedal.render.DynamicVectorRenderer.CUSTOM;
							//
							// JPedalCustomDrawObject exampleObj=new ExampleCustomDrawObject();
							// exampleObj.setMedX(location.x+mX);
							// exampleObj.setMedY(location.x+mY);
							// obj[i]=exampleObj;

							i++;
						}
					}
				}
			}
			// pass into JPEDAL after page decoded - will be removed automatically on new page/open file
			// BUT PRINTING retains values until manually removed

			/**/

			// this code will remove ALL items already drawn on page
			// try{
			// decode_pdf.flushAdditionalObjectsOnPage(commonValues.getCurrentPage());
			// }catch(PdfException e){
			// e.printStackTrace();
			// //ShowGUIMessage.showGUIMessage( "", new JLabel(e.getMessage()),"Exception adding object to display");
			// }

		}
	}

	@Override
	public void checkLinks(Map objs, boolean mouseClicked, PdfObjectReader pdfObjectReader, int x, int y, SwingGUI currentGUI, Values commonValues) {

		// new code to check for match
		Iterator objKeys = objs.keySet().iterator();
		FormObject annotObj = null;
		while (objKeys.hasNext()) {
			annotObj = (FormObject) objKeys.next();
			if (annotObj.getBoundingRectangle().contains(x, y)) {
				break;
			}

			// reset to null so when exits no match
			annotObj = null;
		}

		/** action for moved over of clicked */
		if (annotObj != null) {

			/**
			 * get EF object containing file data
			 */
			// annotObj is now actual object (on lazy initialisation so EF has not been read).....

			System.out.println("clicked on=" + mouseClicked + " obj=" + annotObj + ' ' + annotObj.getObjectRefAsString() + ' '
					+ annotObj.getBoundingRectangle());

			// @annot - in my example, ignore if not clicked
			if (!mouseClicked) return;

			// FS obj contains an EF obj which contains an F obj with the data in
			// F can be various - we are only interested in it as a Dictionary with a stream
			PdfObject EFobj = null, FSobj = annotObj.getDictionary(PdfDictionary.FS);
			if (FSobj != null) EFobj = FSobj.getDictionary(PdfDictionary.EF);

			/**
			 * create the file chooser to select the file name
			 **/
			JFileChooser chooser = new JFileChooser(commonValues.getInputDir());
			chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			int state = chooser.showSaveDialog(currentGUI.getFrame());

			/**
			 * save file and take the hit
			 */
			if (state == 0) {
				File fileTarget = chooser.getSelectedFile();

				// here is where we take the hit (Only needed if on lazy init - ie Unread Dictionary like EF)....
				if (EFobj != null) pdfObjectReader.checkResolved(EFobj);

				// contains the actual file data
				PdfObject Fobj = EFobj.getDictionary(PdfDictionary.F);

				// see if cached or decoded (cached if LARGE)
				// IMPORTANT NOTE!!! - if the object is in a compressed stream (a 'blob' of
				// objects which we need to read in one go, it will not be cached
				String nameOnDisk = Fobj.getCachedStreamFile(pdfObjectReader.getObjectReader());

				// if you get null, make sure you have enabled caching and
				// file is bigger than cache
				System.out.println("file=" + nameOnDisk);

				if (nameOnDisk != null) { // just copy
					ObjectStore.copy(nameOnDisk, fileTarget.toString());
				}
				else { // save out
					byte[] fileData = Fobj.getDecodedStream();

					if (fileData != null) { // write out if in memory
						FileOutputStream fos;
						try {
							fos = new FileOutputStream(fileTarget);
							fos.write(fileData);
							fos.close();
						}
						catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	private static BufferedImage createUniqueImage(int size, String text, Color col) {
		// create a unique graphic
		BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = (Graphics2D) img.getGraphics();
		g2.setColor(col);
		g2.fill(new Rectangle(0, 0, size, size));
		g2.setColor(Color.BLACK);
		g2.draw(new Rectangle(0, 0, size - 1, size - 1));
		g2.setColor(Color.white);
		g2.drawString(text, 2, 12);

		return img;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy