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

org.jpedal.render.RenderUtils Maven / Gradle / Ivy

There is a newer version: 7.15.25
Show newest version
/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2017 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
 @LICENSE@
 *
 * ---------------
 * 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.*;

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

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

    public static boolean isInverted(final float[][] CTM) {

        if (CTM[0][0] < 0 && CTM[1][1] < 1) {
            return false;
        } else if (CTM[0][0] < 0 && CTM[1][1] > 1) {
            return false;
        } else {
            return CTM[0][0] < 0 || CTM[1][1] < 0;
        }
    }

    public static BufferedImage invertImage(BufferedImage image) {

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

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

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

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

            final 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 (final Exception e) {
                failed = true;

                LogWriter.writeLog("Exception in handling image " + e);
            }
            if (failed) {
                try {
                    invert3 = new AffineTransformOp(image_at2, null);
                    image = invert3.filter(image, null);
                } catch (final Exception e) {
                    LogWriter.writeLog("Caught a Exception " + e);
                }
            }
        }

        return image;
    }


    static BufferedImage invertImageBeforeSave(BufferedImage image, final boolean horizontal) {

        //turn upside down
        final 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());
        }

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

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

            final 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, final int currentItem) {

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

            array = newArray;
        }


        return array;

    }

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

        if (g2 != null) {
            if (clip != null) {
                final Area aClip = (Area) clip.clone();

                //can cause problems in Canoo so limit effect if Canoo running
                if (dirtyRegion != null)// && (!isRunningOnRemoteClient || clip.intersects(dirtyRegion)))
                {
                    aClip.intersect(new Area(dirtyRegion.getBounds2D()));
                }

                g2.setClip(aClip);
            } else {
                g2.setClip(defaultClip);
            }
        }
    }


    //work out size glyph occupies
    static Rectangle getAreaForGlyph(final float[][] trm) {
        //workout area
        final int w = (int) Math.sqrt((trm[0][0] * trm[0][0]) + (trm[1][0] * trm[1][0]));
        final 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(final int[] area, final int x, final int y) {

        int lowX = area[0];
        int hiX = area[0] + area[2];
        int lowY = area[1];
        int hiY = area[1] + area[3];
        boolean containsPoint = false;

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

        if (lowY > hiY) {
            final 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(final ByteArrayInputStream bis) throws IOException, ClassNotFoundException { //turn back into object final 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 * @throws java.io.IOException */ public static void writeToStream(final ByteArrayOutputStream bos, final Object obj) throws IOException { final ObjectOutput os = new ObjectOutputStream(bos); os.writeObject(obj); os.close(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy