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

org.jpedal.objects.PdfPageData Maven / Gradle / Ivy

/*
 * ===========================================
 * 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@
 *
 * ---------------
 * PdfPageData.java
 * ---------------
 */
package org.jpedal.objects;

import java.io.Serializable;

import org.jpedal.objects.html.HtmlPageData;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.repositories.Vector_Int;
import org.jpedal.utils.repositories.Vector_Object;

/**
 * store data relating to page sizes set in PDF (MediaBox, CropBox, rotation)
 */
public class PdfPageData implements Serializable {

    //private boolean valuesSet=false;

    private int lastPage = -1;

    private int pagesRead = -1;

    private int pageCount = 1; //number of pages

    private int maxPageCount = -1;

//    private float[] defaultMediaBox=null;

    /**
     * any rotation on page (defined in degress)
     */
    private int rotation;

    /**
     * max media string for page
     */
    private final Vector_Object mediaBoxes = new Vector_Object(500);
    private final Vector_Object cropBoxes = new Vector_Object(500);

    private HtmlPageData htmlData;

    private Vector_Int rotations;

    /**
     * current x and y read from page info
     */
    private float cropBoxX = -99999, cropBoxY = -1,
            cropBoxW = -1, cropBoxH = -1;

    /**
     * current x and y read from page info
     */
    private float mediaBoxX = -1, mediaBoxY, mediaBoxW, mediaBoxH;

    /**
     * whether the document has varying page sizes and rotation
     */
    private boolean hasMultipleSizes, hasMultipleSizesSet;

    /**
     * string representation of crop box
     */
    private float scalingValue = 1f;

    private float[] mediaBox, cropBox;

    /**
     * where co-ords start so we can code for PDF and XFA
     */
    private PageOrigins pageOrigin = PageOrigins.BOTTOM_LEFT;

    public PdfPageData() {
    }

    /**
     * make sure a value set for crop and media box (used internally to trap 'odd' settings and insure setup correctly)
     *
     * @param pageNumber Page to be displayed
     */
    public void checkSizeSet(final int pageNumber) {

        if (pageNumber > pageCount) {
            pageCount = pageNumber;
        }

        //use default
//        if(mediaBox ==null)
//            mediaBox = defaultMediaBox;
//              System.out.println("CropBox "+pageNumber+" > "+cropBox);
        //value we keep
        if (cropBox != null &&
                (cropBox[0] != mediaBox[0] || cropBox[1] != mediaBox[1] || cropBox[2] != mediaBox[2] || cropBox[3] != mediaBox[3])) {

            mediaBoxes.setElementAt(mediaBox, pageNumber);

            if (cropBox[0] >= mediaBox[0] && cropBox[1] >= mediaBox[1] && (cropBox[2] - cropBox[0]) <= (mediaBox[2] - mediaBox[0]) && (cropBox[3] - cropBox[1]) <= (mediaBox[3] - mediaBox[1])) {
                cropBoxes.setElementAt(cropBox, pageNumber);
            }

        } else if (mediaBox != null)// &&
//                (defaultMediaBox[0]!=mediaBox[0] || defaultMediaBox[1]!=mediaBox[1] || defaultMediaBox[2]!=mediaBox[2] || defaultMediaBox[3]!=mediaBox[3])) //if matches default don't save
        {
            mediaBoxes.setElementAt(mediaBox, pageNumber);
        }

        //track which pages actually read
        if (pagesRead < pageNumber) {
            pagesRead = pageNumber;
        }


        lastPage = -1;
        mediaBox = null;
        cropBox = null;
    }


    /**
     * @param pageNumber Page to be displayed
     * @return height of mediaBox
     */
    public final int getMediaBoxHeight(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) mediaBoxH;
    }

    /**
     * @param pageNumber Page to be displayed
     * @return mediaBox y value
     */
    public final int getMediaBoxY(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) mediaBoxY;
    }

    /**
     * @param pageNumber Page to be displayed
     * @return mediaBox x value
     */
    public final int getMediaBoxX(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) mediaBoxX;
    }

    /**
     * set string with raw values and assign values to crop and media size
     *
     * @param mediaBox row values of PDF page data
     */
    public void setMediaBox(final float[] mediaBox) {

        this.mediaBox = mediaBox;
        cropBox = null;

//         if(defaultMediaBox==null)
//            defaultMediaBox=mediaBox;

    }

    /**
     * set crop with values and align with media box
     *
     * @param cropBox crop values of PDF page data
     */
    public void setCropBox(final float[] cropBox) {

        if (cropBox != null) {
            this.cropBox = cropBox;
        } else {
            this.cropBox = mediaBox;
        }

        //If mediaBox is set and crop box leaves this area
        //we should limit the cropBox by the mediaBox
        final boolean testAlteredCrop = true;
        if (testAlteredCrop && (mediaBox != null && !(mediaBox.length < 4))) {
            if (this.cropBox[0] < mediaBox[0]) {
                this.cropBox[0] = mediaBox[0];
            }

            if (this.cropBox[1] < mediaBox[1]) {
                this.cropBox[1] = mediaBox[1];
            }

            if (this.cropBox[2] > mediaBox[2]) {
                this.cropBox[2] = mediaBox[2];
            }

            if (this.cropBox[3] > mediaBox[3]) {
                this.cropBox[3] = mediaBox[3];
            }
        }
    }

    public void setPageRotation(final int value, final int pageNumber) {

        int raw_rotation = value;

        //convert negative
        if (raw_rotation < 0) {
            raw_rotation = 360 + raw_rotation;
        }

        //only create if we need and set value
        if (raw_rotation != 0 || rotations != null) {
            if (rotations == null) {
                if (pageNumber < 2000) {
                    rotations = new Vector_Int(2000);
                } else {
                    rotations = new Vector_Int(pageNumber * 2);
                }
            }

            rotations.setElementAt(raw_rotation, pageNumber);

        }
    }

    /**
     * @param pageNumber Page to be displayed
     * @return width of media box
     */
    public final int getMediaBoxWidth(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) mediaBoxW;
    }

    /**
     * @param currentPage the new current page
     * @return mediaBox string found in PDF file
     */
    public String getMediaValue(final int currentPage) {

        final StringBuilder returnValue = new StringBuilder();

        float[] mediaBox = null;

        if (mediaBoxes != null) {
            mediaBox = (float[]) mediaBoxes.elementAt(currentPage);
        }

        if (mediaBox != null) {

            for (int j = 0; j < 4; j++) {
                returnValue.append(mediaBox[j]);
                returnValue.append(' ');
            }
        }

        return returnValue.toString();
    }

    /**
     * @param currentPage the new current page
     * @return cropBox string found in PDF file
     */
    public String getCropValue(final int currentPage) {

        float[] cropBox = null;

        //use default
        if (cropBoxes != null) {
            cropBox = (float[]) cropBoxes.elementAt(currentPage);
        }

        if (cropBox == null) {
            cropBox = (float[]) mediaBoxes.elementAt(currentPage);
        }

//		if(cropBox==null)
//        	cropBox=defaultMediaBox;

        final StringBuilder returnValue = new StringBuilder();

        for (int j = 0; j < 4; j++) {
            returnValue.append(cropBox[j]);
            returnValue.append(' ');
        }

        return returnValue.toString();
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled x value for cropBox
     */
    public int getScaledCropBoxX(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(cropBoxX * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled cropBox width
     */
    public int getScaledCropBoxWidth(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(cropBoxW * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled y value for cropox
     */
    public int getScaledCropBoxY(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(cropBoxY * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled cropBox height
     */
    public int getScaledCropBoxHeight(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(cropBoxH * scalingValue);
    }


    /**
     * @param pageNumber the page to be displayed
     * @return x value for cropBox
     */
    public int getCropBoxX(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) cropBoxX;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return x value for cropBox
     */
    public float getCropBoxX2D(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return cropBoxX;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return cropBox width
     */
    public int getCropBoxWidth(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            //tell user and log
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) cropBoxW;
    }

    /**
     * return cropBox width
     *
     * @param pageNumber the page to be displayed
     */
    public float getCropBoxWidth2D(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return cropBoxW;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return y value for cropox
     */
    public int getCropBoxY(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) cropBoxY;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return y value for cropox
     */
    public float getCropBoxY2D(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return cropBoxY;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return cropBox height
     */
    public int getCropBoxHeight(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return (int) cropBoxH;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return cropBox height
     */
    public float getCropBoxHeight2D(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return cropBoxH;
    }

    /**
     * see if current figures generated for this page and setup if not
     */
    private synchronized void setSizeForPage(final int pageNumber) throws Exception {

        if (pageNumber == lastPage) {
            return;
        }

        if (pageNumber > pageCount) {
            pageCount = pageNumber;
        }

		 /*calculate values if first call for this page*/
        if (pageNumber > pagesRead) {

            //set values if no value
            mediaBoxX = 0;
            mediaBoxY = 0;
            mediaBoxW = 0;
            mediaBoxH = 0;

            //set values if no value
            cropBoxX = 0;
            cropBoxY = 0;
            cropBoxW = 0;
            cropBoxH = 0;

            lastPage = pageNumber;

        } else if (pageNumber > 0 && lastPage != pageNumber && (maxPageCount == -1 || pageNumber <= maxPageCount)) {

            lastPage = pageNumber;

//			 boolean usingDefault=false;

            final float[] cropBox = (float[]) cropBoxes.elementAt(pageNumber);
            final float[] mediaBox = (float[]) mediaBoxes.elementAt(pageNumber);
//			 if(mediaBox==null && defaultMediaBox!=null){
//				 mediaBox=defaultMediaBox;
//				 usingDefault=true;
//			 }

            //set rotation
            if (rotations != null) {
                rotation = rotations.elementAt(pageNumber);
            }

            while (rotation >= 360) {
                rotation -= 360;
            }

            //set values if no value
            mediaBoxX = 0;
            mediaBoxY = 0;
            mediaBoxW = 800;
            mediaBoxH = 800;

            if (mediaBox != null) {
                mediaBoxX = mediaBox[0];
                mediaBoxY = mediaBox[1];
                mediaBoxW = mediaBox[2] - mediaBoxX;
                mediaBoxH = mediaBox[3] - mediaBoxY;

                if (mediaBoxY > 0 && mediaBoxH == -mediaBoxY) {
                    mediaBoxH = -mediaBoxH;
                    mediaBoxY = 0;
                }
            }

            if (cropBox != null) {

                cropBoxX = cropBox[0];
                cropBoxY = cropBox[1];
                cropBoxW = cropBox[2];
                cropBoxH = cropBox[3];

                if (cropBoxX > cropBoxW) {
                    final float temp = cropBoxX;
                    cropBoxX = cropBoxW;
                    cropBoxW = temp;
                }
                if (cropBoxY > cropBoxH) {
                    final float temp = cropBoxY;
                    cropBoxY = cropBoxH;
                    cropBoxH = temp;
                }

                cropBoxW -= cropBoxX;
                cropBoxH -= cropBoxY;

                if (cropBoxY > 0 && cropBoxH == -cropBoxY) {
                    cropBoxH = -cropBoxH;
                    cropBoxY = 0;
                }

            } else {
                cropBoxX = mediaBoxX;
                cropBoxY = mediaBoxY;
                cropBoxW = mediaBoxW;
                cropBoxH = mediaBoxH;
            }
//			 }

            //fix for odd file with negative height
            if (cropBoxH < 0) {
                cropBoxY += cropBoxH;
                cropBoxH = -cropBoxH;
            }
            if (cropBoxW < 0) {
                cropBoxX += cropBoxW;
                cropBoxW = -cropBoxW;
            }

//			if(usingDefault && !valuesSet){
//
//				 defaultrotation=rotation;
//				 defaultcropBoxX=cropBoxX;
//				 defaultmediaBoxX=mediaBoxX;
//				 defaultcropBoxY=cropBoxY;
//				 defaultmediaBoxY=mediaBoxY;
//				 defaultcropBoxW=cropBoxW;
//				 defaultmediaBoxW=mediaBoxW;
//				 defaultcropBoxH=cropBoxH;
//				 defaultmediaBoxH=mediaBoxH;
//
//				 valuesSet=true;
//			}
        } else if (pageNumber <= 0 || (maxPageCount != -1 && pageNumber > maxPageCount)) {
            throw new Exception("Attempted to find page outside of page range 1 - " + maxPageCount + "  Page number requested:" + pageNumber);
        }
    }

    /**
     * Get the scaling value currently being used
     *
     * @return scalingValue
     */
    public float getScalingValue() {
        return scalingValue;
    }


    /**
     * Scaling value to apply to all values
     *
     * @param scalingValue The new scaling value
     */
    public void setScalingValue(final float scalingValue) {
        this.scalingValue = scalingValue;
    }

    private static int roundFloat(final float origValue) {
        int roundedValue = (int) origValue;

        final boolean useCustomRounding = true;
        if (useCustomRounding) {
            final float frac = origValue - roundedValue;
            if (frac > 0.3) {
                roundedValue += 1;
            }
        }
        return roundedValue;

    }

    /**
     * get page count
     *
     * @return number of pages
     */
    public final int getPageCount() {
        return pageCount;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return rotation value (for outside class)
     */
    public final int getRotation(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return rotation;
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled height of mediaBox
     */
    public final int getScaledMediaBoxHeight(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(mediaBoxH * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled width of media box
     */
    public final int getScaledMediaBoxWidth(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(mediaBoxW * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled mediaBox x value
     */
    public final int getScaledMediaBoxX(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(mediaBoxX * scalingValue);
    }

    /**
     * @param pageNumber the page to be displayed
     * @return Scaled mediaBox y value
     */
    public final int getScaledMediaBoxY(final int pageNumber) {

        //check values correctly set
        try {
            setSizeForPage(pageNumber);
        } catch (final Exception e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
        }

        return roundFloat(mediaBoxY * scalingValue);
    }

    public int getScaledTotalDoubleWidth() {
        int total = 0;
        if (getPageCount() == 2) {
            total = getScaledCropBoxWidth(1);
            if (total < getScaledCropBoxWidth(2)) {
                total = getScaledCropBoxWidth(2);
            }
        } else {
            for (int i = 1; i <= getPageCount(); i++) {
                if (i == 1) {
                    total += getScaledCropBoxWidth(i);
                } else {
                    if ((i & 1) == 0) { //left page
                        int page = getScaledCropBoxWidth(i);
                        if (i < getPageCount() && page < getScaledCropBoxWidth(i + 1)) {
                            page = getScaledCropBoxWidth(i + 1);
                        }
                        total += page;

                    }
                }
            }
        }
        return total;
    }

    public int getScaledTotalDoubleHeight() {
        int total = 0;
        if (getPageCount() == 2) {
            total = getScaledCropBoxHeight(1);
            if (total < getScaledCropBoxHeight(2)) {
                total = getScaledCropBoxHeight(2);
            }
        } else {
            for (int i = 1; i <= getPageCount(); i++) {
                if (i == 1) {
                    total += getScaledCropBoxHeight(i);
                } else {
                    if ((i & 1) == 0) { //left page
                        int page = getScaledCropBoxHeight(i);
                        if (i < getPageCount() && page < getScaledCropBoxHeight(i + 1)) {
                            page = getScaledCropBoxHeight(i + 1);
                        }
                        total += page;

                    }
                }
            }
        }
        return total;
    }

    public int getScaledTotalSingleHeight() {
        int total = 0;
        for (int i = 1; i <= getPageCount(); i++) {
            total += getScaledCropBoxHeight(i);
        }
        return total;
    }


    public int getScaledTotalSingleWidth() {
        int total = 0;
        for (int i = 1; i <= getPageCount(); i++) {
            total += getScaledCropBoxWidth(i);
        }
        return total;
    }

    public boolean hasMultipleSizes() {
        //return if already calculated
        if (hasMultipleSizesSet) {
            return hasMultipleSizes;
        }

        //scan all pages and if we find one different, disable page turn
        final int pageCount = this.pageCount;
        final int pageW = getCropBoxWidth(1);
        final int pageH = getCropBoxHeight(1);
        final int pageR = getRotation(1);

        if (pageCount > 1) {
            for (int jj = 2; jj < pageCount + 1; jj++) {

                if (pageW != getCropBoxWidth(jj) || pageH != getCropBoxHeight(jj) ||
                        pageR != getRotation(jj)) {
                    jj = pageCount;
                    hasMultipleSizes = true;
                }
            }
        }
        hasMultipleSizesSet = true;
        return hasMultipleSizes;
    }

    /**
     * set page co-ord system to different location
     *
     * @param newPageOrigin New location of page co-ord
     */
    public void setOrigin(final PageOrigins newPageOrigin) {
        this.pageOrigin = newPageOrigin;
    }

    /**
     * allow page to start at different locations (bottom left is default)
     *
     * @return Start location of the page
     */
    public PageOrigins getOrigin() {
        //marks test code
        //pageOrigin= PageOrigins.TOP_LEFT;

        return pageOrigin;
    }

    public void setPageCount(final int count) {
        maxPageCount = count;
    }

    public HtmlPageData getHTMLData() {

        if (htmlData == null) {
            htmlData = new HtmlPageData();
        }

        return htmlData;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy