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

org.jpedal.render.RenderUtils 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


 *
 * ---------------
 * RenderUtils.java
 * ---------------
 */
package org.jpedal.render;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import org.jpedal.color.ColorSpaces;
import org.jpedal.io.JAIHelper;
import org.jpedal.utils.LogWriter;

/**
 * static helper methods for rendering
 */
public class RenderUtils {

	public static boolean isInverted(float[][] CTM) {
		return CTM[0][0] < 0 || CTM[1][1] < 0;
	}

	public static boolean isRotated(float[][] CTM) {
		return (CTM[0][0] == 0 && CTM[1][1] == 0) || (CTM[0][1] > 0 && CTM[1][0] < 0) || (CTM[0][1] < 0 && CTM[1][0] > 0);
	}

	static BufferedImage invertImage(float[][] CTM, BufferedImage image) {

		// if((CTM[0][0]==0 || CTM[1][1]==0) || (isRotated(CTM) && !isInverted(CTM))) {
		// return image;
		// }

		// turn upside down
		AffineTransform image_at2 = new AffineTransform();
		image_at2.scale(1, -1);
		image_at2.translate(0, -image.getHeight());

		AffineTransformOp invert3 = new AffineTransformOp(image_at2, ColorSpaces.hints);

		boolean imageProcessed = false;

		if (JAIHelper.isJAIused()) {

			imageProcessed = true;

			try {
				image = (javax.media.jai.JAI.create("affine", image, image_at2, new javax.media.jai.InterpolationNearest())).getAsBufferedImage();
			}
			catch (Exception e) {
				imageProcessed = false;
				// tell user and log
				if (LogWriter.isOutput()) LogWriter.writeLog("Exception: " + e.getMessage());
			}
			catch (Error err) {
				imageProcessed = false;

				// tell user and log
				if (LogWriter.isOutput()) LogWriter.writeLog("Error: " + err.getMessage());
			}

			if (!imageProcessed && LogWriter.isOutput()) LogWriter.writeLog("Unable to use JAI for image inversion");

		}

		if (!imageProcessed) {

			if (image.getType() == 12) { // avoid turning into ARGB

				BufferedImage source = image;
				image = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());

				invert3.filter(source, image);
			}
			else {

				boolean failed = false;
				// allow for odd behaviour on some files
				try {
					image = invert3.filter(image, null);
				}
				catch (Exception e) {
					failed = true;
				}
				if (failed) {
					try {
						invert3 = new AffineTransformOp(image_at2, null);
						image = invert3.filter(image, null);
					}
					catch (Exception e) {}
				}
			}
		}

		return image;
	}

	static BufferedImage invertImageBeforeSave(BufferedImage image, boolean horizontal) {

		// turn upside down
		AffineTransform image_at2 = new AffineTransform();
		if (horizontal) {
			image_at2.scale(-1, 1);
			image_at2.translate(-image.getWidth(), 0);
		}
		else {
			image_at2.scale(1, -1);
			image_at2.translate(0, -image.getHeight());
		}
		AffineTransformOp invert3 = new AffineTransformOp(image_at2, ColorSpaces.hints);

		boolean imageProcessed = false;

		if (JAIHelper.isJAIused()) {

			imageProcessed = true;

			try {
				image = (javax.media.jai.JAI.create("affine", image, image_at2, new javax.media.jai.InterpolationNearest())).getAsBufferedImage();
			}
			catch (Exception e) {
				imageProcessed = false;

				// tell user and log
				if (LogWriter.isOutput()) LogWriter.writeLog("Exception: " + e.getMessage());

			}
			catch (Error err) {
				imageProcessed = false;

				// tell user and log
				if (LogWriter.isOutput()) LogWriter.writeLog("Error: " + err.getMessage());
			}

			if (!imageProcessed && LogWriter.isOutput()) {
				LogWriter.writeLog("Unable to use JAI for image inversion");
			}

		}

		if (!imageProcessed) {

			if (image.getType() == 12) { // avoid turning into ARGB

				BufferedImage source = image;
				image = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());

				invert3.filter(source, image);
			}
			else image = invert3.filter(image, null);

		}
		return image;
	}

	/** resize array */
	static float[] checkSize(float[] array, int currentItem) {

		int size = array.length;
		if (size <= currentItem) {
			int newSize = size * 2;
			float[] newArray = new float[newSize];
			System.arraycopy(array, 0, newArray, 0, size);

			array = newArray;
		}

		return array;
	}

	/**
	 * update clip
	 * 
	 * @param defaultClip
	 */
	public static void renderClip(Area clip, Rectangle dirtyRegion, Shape defaultClip, Graphics2D g2) {

		if (clip != null) {
			g2.setClip(clip);

			// can cause problems in Canoo so limit effect if Canoo running
			if (dirtyRegion != null) // && (!isRunningOnRemoteClient || clip.intersects(dirtyRegion)))
			g2.clip(dirtyRegion);
		}
		else g2.setClip(defaultClip);
	}

	// work out size glyph occupies
	static Rectangle getAreaForGlyph(float[][] trm) {
		// workout area
		int w = (int) Math.sqrt((trm[0][0] * trm[0][0]) + (trm[1][0] * trm[1][0]));
		int h = (int) Math.sqrt((trm[1][1] * trm[1][1]) + (trm[0][1] * trm[0][1]));

		float xDiff = 0;
		float yDiff = 0;

		if (trm[0][0] < 0) xDiff = trm[0][0];
		else
			if (trm[1][0] < 0) xDiff = trm[1][0];

		if (trm[1][1] < 0) yDiff = trm[1][1];
		else
			if (trm[0][1] < 0) yDiff = trm[0][1];

		return (new Rectangle((int) (trm[2][0] + xDiff), (int) (trm[2][1] + yDiff), w, h));
	}

	/**
	 * Rectangle contains code does not handle negative values Use this instead.
	 * 
	 * @param area
	 *            : Rectangle to look in
	 * @param x
	 *            : value on the x axis
	 * @param y
	 *            : value on the y axis
	 * @return true is point is within area
	 */
	public static boolean rectangleContains(Rectangle area, int x, int y, int i) {

		int lowX = area.x;
		int hiX = area.x + area.width;
		int lowY = area.y;
		int hiY = area.y + area.height;
		boolean containsPoint = false;

		// if negative value used swap the lowest and highest point
		if (lowX > hiX) {
			int temp = lowX;
			lowX = hiX;
			hiX = temp;
		}

		if (lowY > hiY) {
			int temp = lowY;
			lowY = hiY;
			hiY = temp;
		}

		if ((lowY < y && y < hiY) && (lowX < x && x < hiX)) containsPoint = true;

		return containsPoint;
	}

	/**
	 * generic method to return a serilized object from an InputStream
	 * 
	 * NOT PART OF API and subject to change (DO NOT USE)
	 * 
	 * @param bis
	 *            - ByteArrayInputStream containing serilized object
	 * @return - deserilized object
	 * @throws java.io.IOException
	 * @throws ClassNotFoundException
	 */
	public static Object restoreFromStream(ByteArrayInputStream bis) throws IOException, ClassNotFoundException {

		// turn back into object
		ObjectInput os = new ObjectInputStream(bis);

		return os.readObject();
	}

	/**
	 * generic method to serilized an object to an OutputStream
	 * 
	 * NOT PART OF API and subject to change (DO NOT USE)
	 * 
	 * @param bos
	 *            - ByteArrayOutputStream to serilize to
	 * @param obj
	 *            - object to serilize
	 * @param string2
	 * @throws java.io.IOException
	 */
	public static void writeToStream(ByteArrayOutputStream bos, Object obj, String string2) throws IOException {

		ObjectOutput os = new ObjectOutputStream(bos);

		os.writeObject(obj);
		os.close();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy