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

org.jpedal.parser.SwingPrinter 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


 *
 * ---------------
 * SwingPrinter.java
 * ---------------
 */
package org.jpedal.parser;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.util.HashMap;
import java.util.Map;

import javax.print.attribute.SetOfIntegerSyntax;

import org.jpedal.Overlays;
import org.jpedal.exception.PdfException;
import org.jpedal.external.ExternalHandlers;
import org.jpedal.io.ObjectStore;
import org.jpedal.io.PdfObjectReader;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.PrinterOptions;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.utils.Messages;

public class SwingPrinter {

	/** content we print onto display */
	private Overlays overlays;

	private int duplexGapOdd = 0, duplexGapEven = 0;

	/** the ObjectStore for this file for printing */
	ObjectStore objectPrintStoreRef = null;

	ExternalHandlers externalHandlers;

	private boolean centerOnScaling = false;

	/**
	 * flag used to show if printing worked
	 */
	public boolean operationSuccessful = true;

	/** page scaling mode to use for printing */
	public int pageScalingMode = PrinterOptions.PAGE_SCALING_REDUCE_TO_PRINTER_MARGINS;

	/**
	 * Any printer errors
	 */
	public String pageErrorMessages = "";

	// print only the visible area of the doc.
	public boolean printOnlyVisible = false;

	public int logicalPageOffset = 0;

	/**
	 * used by Canoo for printing
	 */
	public DynamicVectorRenderer printRender = null;

	/**
	 * last page printed
	 */
	public int lastPrintedPage = -1;

	/**
	 * current print page or -1 if finished
	 */
	public int currentPrintPage = 0;

	/**
	 * used is bespoke version of JPedal - do not use
	 */
	public boolean isCustomPrinting = false;

	PdfObjectReader currentPdfFile;

	/**
	 * holds pageformats
	 */
	public Map pageFormats = new HashMap(100);

	// list of pages in range for quick lookup
	public int[] listOfPages;

	public boolean allowDifferentPrintPageSizes = false;

	/**
	 * actual page range to print
	 */
	public int start = 0;
	public int end = -1;

	public boolean oddPagesOnly = false;
	public boolean evenPagesOnly = false;

	public SetOfIntegerSyntax range;

	public boolean pagesPrintedInReverse = false;
	public boolean stopPrinting = false;

	/** type of printing */
	public boolean isPrintAutoRotateAndCenter = false;

	/** flag to show we use PDF page size */
	public boolean usePDFPaperSize = false;

	/**
	 * printing object
	 */
	public PdfStreamDecoderForPrinting currentPrintDecoder = null;

	public boolean legacyPrintMode = true;
	private float scaling;
	private int insetW, insetH;

	public int getNumberOfPages(int pageCount) {

		// handle 1,2,5-7,12
		if (this.range != null) {
			int rangeCount = 0;
			for (int ii = 1; ii < pageCount + 1; ii++) {
				if (this.range.contains(ii) && (!this.oddPagesOnly || (ii & 1) == 1) && (!this.evenPagesOnly || (ii & 1) == 0)) rangeCount++;
			}
			return rangeCount;
		}

		int count = 1;

		if (this.end != -1) {
			count = this.end - this.start + 1;
			if (count < 0) // allow for reverse order
			count = 2 - count;
		}

		if (this.oddPagesOnly || this.evenPagesOnly) {
			return (count + 1) / 2;
		}
		else {
			return count;
		}
	}

	public PageFormat getPageFormat(int p, PdfPageData pageData, int pageCount) throws IndexOutOfBoundsException {

		Object returnValue;
		int actualPage;

		// remap if in list
		if (this.listOfPages != null && p < this.listOfPages.length) {
			p = this.listOfPages[p];
		}

		if (this.end == -1) actualPage = p + 1;
		else
			if (this.end > this.start) actualPage = this.start + p;
			else actualPage = this.start - p;

		returnValue = this.pageFormats.get(actualPage);

		if (returnValue == null) returnValue = this.pageFormats.get("standard");

		PageFormat pf = new PageFormat();

		this.pageFormats.put("Align-" + actualPage, "normal");

		if (this.usePDFPaperSize) {

			int crw = pageData.getCropBoxWidth(actualPage);
			int crh = pageData.getCropBoxHeight(actualPage);
			int rotation = pageData.getRotation(actualPage);

			if (this.allowDifferentPrintPageSizes) { // keep old mode for Rog
				// swap round if needed
				if (rotation == 90 || rotation == 270) {
					int tmp = crw;
					crw = crh;
					crh = tmp;
				}

				if (crw > crh) {
					int tmp = crw;
					crw = crh;
					crh = tmp;

					if (rotation == 90) this.pageFormats.put("Align-" + actualPage, "inverted");
				}
			}

			createCustomPaper(pf, crw, crh, pageCount, pageData);

		}
		else
			if (returnValue != null) pf = (PageFormat) returnValue;

		if (!this.isPrintAutoRotateAndCenter) {
			pf.setOrientation(PageFormat.PORTRAIT);
		}

		return pf;
	}

	private void createCustomPaper(PageFormat pf, int clipW, int clipH, int pageCount, PdfPageData pageData) {

		Paper customPaper = new Paper();

		// System.out.println("createCustomPaper "+pf+" "+clipW+" "+clipH);
		// Do not change this code, if you have check if it doesn't break
		// the barcode file (ABACUS) !
		// The barcode is to be printed horizontally on the page!

		if (pageCount == 1 || this.allowDifferentPrintPageSizes) {
			customPaper.setSize(clipW, clipH);
			customPaper.setImageableArea(0, 0, clipW, clipH);
		}
		else {

			// Due to the way printing (different sized pages in one go) works in Java we
			// work out the biggest for the printed selection and apply it to all printed pages.
			int paperClipW = 0;
			int paperClipH = 0;

			for (int t = this.start; t <= this.end; t++) {
				if (clipW <= (pageData.getMediaBoxWidth(t) + 1) && clipH <= (pageData.getMediaBoxHeight(t) + 1)) {
					paperClipW = pageData.getMediaBoxWidth(t) + 1;
					paperClipH = pageData.getMediaBoxHeight(t) + 1;
				}
			}

			customPaper.setSize(paperClipW, paperClipH);
			customPaper.setImageableArea(0, 0, clipW, clipH);

		}

		pf.setPaper(customPaper);
	}

	public void setPagePrintRange(SetOfIntegerSyntax range, int pageCount) throws PdfException {

		this.range = range;
		this.start = range.next(0); // find first

		int rangeCount = 0;

		// get number of items
		for (int ii = 0; ii < pageCount; ii++) {
			if (range.contains(ii)) rangeCount++;
		}

		// setup array
		this.listOfPages = new int[rangeCount + 1];

		// find last
		int i = this.start;
		this.end = this.start;
		if (range.contains(2147483647)) // allow for all returning largest int
		this.end = pageCount;
		else {
			while (range.next(i) != -1)
				i++;
			this.end = i;
		}

		// if actually backwards, reverse order
		if (this.start > this.end) {
			int tmp = this.start;
			this.start = this.end;
			this.end = tmp;
		}

		// populate table
		int j = 0;

		for (int ii = this.start; ii < this.end + 1; ii++) {
			if (range.contains(ii) && (!this.oddPagesOnly || (ii & 1) == 1) && (!this.evenPagesOnly || (ii & 1) == 0)) {
				this.listOfPages[j] = ii - this.start;
				j++;
			}
		}

		if ((this.start < 1) || (this.end < 1) || (this.start > pageCount) || (this.end > pageCount)) throw new PdfException(
				Messages.getMessage("PdfViewerPrint.InvalidPageRange") + ' ' + this.start + ' ' + this.end);
	}

	public void setPrintPageMode(int mode) {

		this.oddPagesOnly = (mode & PrinterOptions.ODD_PAGES_ONLY) == PrinterOptions.ODD_PAGES_ONLY;
		this.evenPagesOnly = (mode & PrinterOptions.EVEN_PAGES_ONLY) == PrinterOptions.EVEN_PAGES_ONLY;

		this.pagesPrintedInReverse = (mode & PrinterOptions.PRINT_PAGES_REVERSED) == PrinterOptions.PRINT_PAGES_REVERSED;
	}

	public void putPageFormat(Object key, PageFormat value) {
		this.pageFormats.put(key, value);
	}

	/**
	 * return page currently being printed or -1 if finished
	 */
	public int getCurrentPrintPage() {
		return this.currentPrintPage;
	}

	/**
	 * ask JPedal to stop printing a page
	 */
	final public void stopPrinting() {
		this.stopPrinting = true;
	}

	public void setPagePrintRange(int start, int end, int pageCount) throws PdfException {

		this.start = start;
		this.end = end;

		// all returns huge number not page end range
		if (end == 2147483647) end = pageCount;

		// if actually backwards, reverse order
		if (start > end) {
			int tmp = start;
			start = end;
			end = tmp;
		}
		if ((start < 1) || (end < 1) || (start > pageCount) || (end > pageCount)) throw new PdfException(
				Messages.getMessage("PdfViewerPrint.InvalidPageRange") + ' ' + start + ' ' + end);
	}

	public void useLogicalPrintOffset(int pagesPrinted) {
		this.logicalPageOffset = pagesPrinted;
	}

	public boolean isPageSuccessful() {
		return this.operationSuccessful;
	}

	/**
	 * Return String with all error messages from last printed (useful for debugging)
	 */
	public String getPageFailureMessage() {
		return this.pageErrorMessages;
	}

	/**
	 * set page scaling mode to use - default setting is PAGE_SCALING_REDUCE_TO_PRINTER_MARGINS All values start PAGE_SCALING
	 */
	public void setPrintPageScalingMode(int pageScalingMode) {
		this.pageScalingMode = pageScalingMode;
	}

	/**
	 * turn list into Array
	 * 
	 * @param values
	 */
	private static Map toMap(int[] values) {

		if (values == null || values.length == 0) return null;

		int count = values.length;
		Map newList = new HashMap(count);

		for (int value : values)
			newList.put(value, "x");

		return newList;
	}

	private Rectangle workoutClipping(int displayRotation, Rectangle vr, int print_x_size, int print_y_size) {

		Rectangle cRect;

		double x = vr.getX();
		double y = vr.getY();
		double w = vr.getWidth();
		double h = vr.getHeight();

		/**
		 * g2.clipRect((int)((vr.x-insetW)/this.scaling),(int) ((print_y_size) - ((vr.y+vr.height-insetH)/this.scaling)) ,(int)
		 * (vr.width/this.scaling)-1,(int) (vr.height/this.scaling));
		 */

		int newX = 0;
		int newY = 0;
		int newW = 0;
		int newH = 0;

		if (true) {
			switch (displayRotation) {
				case (0):
					newX = (int) ((vr.x - this.insetW) / this.scaling);
					newY = (int) ((print_y_size) - ((vr.y + vr.height - this.insetH) / this.scaling));
					newW = (int) (vr.width / this.scaling - 1);
					newH = (int) (vr.height / this.scaling);
					break;

				case (90):
					newX = (int) (((y - this.insetH) / this.scaling));
					newY = (int) (((x - this.insetW) / this.scaling));
					newW = (int) (h / this.scaling);
					newH = (int) (w / this.scaling);
					break;

				case (180):
					newY = (int) ((y / this.scaling) - (this.insetH / this.scaling));
					newX = (int) (print_x_size - ((x + w - this.insetW) / this.scaling));
					newW = (int) (w / this.scaling);
					newH = (int) (h / this.scaling);
					break;

				case (270):
					newX = (int) ((print_x_size - (y + h - this.insetH) / this.scaling));
					newY = (int) ((print_y_size - (x + w - this.insetW) / this.scaling));
					newW = (int) (h / this.scaling);
					newH = (int) (w / this.scaling);
					break;
			}
		}
		else {
			switch (displayRotation) {
				case (0):
					newX = (int) ((vr.x - this.insetW) / this.scaling);
					newY = (int) ((print_x_size) - ((vr.y + vr.height - this.insetH) / this.scaling));
					newW = (int) (vr.width / this.scaling - 1);
					newH = (int) (vr.height / this.scaling);
					break;

				case (90):
					newX = (int) (((y - this.insetH) / this.scaling));
					newY = (int) (((x - this.insetW) / this.scaling));
					newW = (int) (h / this.scaling);
					newH = (int) (w / this.scaling);
					break;

				case (180):
					newY = (int) ((y / this.scaling) - (this.insetH / this.scaling));
					newX = (int) (print_y_size - ((x + w - this.insetW) / this.scaling));
					newW = (int) (w / this.scaling);
					newH = (int) (h / this.scaling);
					break;

				case (270):
					newX = (int) ((print_y_size - (y + h - this.insetH) / this.scaling));
					newY = (int) ((print_x_size - (x + w - this.insetW) / this.scaling));
					newW = (int) (h / this.scaling);
					newH = (int) (w / this.scaling);
					break;
			}
		}

		cRect = new Rectangle(newX, newY, newW, newH);

		return cRect;
	}

	/**
	 * store objects to use on a print
	 * 
	 * @param page
	 * @param type
	 * @param colors
	 * @param obj
	 * @throws PdfException
	 */
	public void printAdditionalObjectsOverPage(int page, int[] type, Color[] colors, Object[] obj) throws PdfException {

		if (this.overlays == null) this.overlays = new Overlays();

		this.overlays.printAdditionalObjectsOverPage(page, type, colors, obj);
	}

	/**
	 * store objects to use on a print
	 * 
	 * @param type
	 * @param colors
	 * @param obj
	 * @throws PdfException
	 */
	public void printAdditionalObjectsOverAllPages(int[] type, Color[] colors, Object[] obj) throws PdfException {

		if (this.overlays == null) this.overlays = new Overlays();

		this.overlays.printAdditionalObjectsOverAllPages(type, colors, obj);
	}

	public void clear() {

		if (this.overlays != null) this.overlays.clear();

		if (this.objectPrintStoreRef != null) {
			this.objectPrintStoreRef.flush();
		}
	}

	public void setPrintIndent(int oddPages, int evenPages) {
		this.duplexGapOdd = oddPages;
		this.duplexGapEven = evenPages;
	}

	public void setCenterOnScaling(boolean center) {

		this.centerOnScaling = center;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy