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

org.jpedal.utils.PdfPageFormat 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


 *
 * ---------------
 * PdfPageFormat.java
 * ---------------
 */

package org.jpedal.utils;

/**
 * Factory methods for PdfPageFormats.  
 * 
 * 

Encapsulates all PageFormat creation for Acrobat-like results. Queries the printer * in order to find the most suitable PageFormat.

*/ import java.awt.print.PageFormat; import java.awt.print.Paper; import java.util.HashSet; import java.util.Locale; import java.util.Set; import javax.print.DocFlavor; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.Size2DSyntax; import javax.print.attribute.standard.Media; import javax.print.attribute.standard.MediaPrintableArea; import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.MediaSizeName; import org.jpedal.PdfDecoder; import org.jpedal.objects.PdfPageData; public class PdfPageFormat { private static Set availablePaper; public PdfPageFormat() { throw new AssertionError("PdfPageFormat cannot be instanced. Use factory methods."); } /** * The purpose of this method is to create a PageFormat object that covers the correct printable area of the given device. Use this * method to create paper in order to get Acrobat like results. * * The size of the PageFormat is based on the given MediaSize. See * http://download.oracle.com/javase/1.4.2/docs/api/javax/print/attribute/standard/MediaSize.html * * @param mediaSizeName The desired paper size (ie MediaSize.ISO.A4) * @param printingDevice The device to be printed to * @return A formatted PageFormat for use with printing PDFs. May return null if there is no available size information. */ public static final PageFormat createPdfPageFormat(MediaSizeName mediaSizeName, PrintService printingDevice) { boolean testFlag = false; if (printingDevice == null) { printingDevice = PrintServiceLookup.lookupDefaultPrintService(); } if (testFlag && printingDevice == null) System.out.println("Print Device is null"); PageFormat pdfPageFormat = new PageFormat(); MediaSize mediaSize = MediaSize.getMediaSizeForName(mediaSizeName); if (mediaSize == null) { mediaSize = MediaSize.getMediaSizeForName(PdfPageFormat.getDefaultMediaSizeName(printingDevice)); } if (testFlag && mediaSize == null) System.out.println("Media Size is null"); float xSize = mediaSize.getX(Size2DSyntax.INCH) * 72; float ySize = mediaSize.getY(Size2DSyntax.INCH) * 72; Paper pdfPaper = new Paper(); pdfPaper.setSize(xSize, ySize); MediaPrintableArea area = (MediaPrintableArea) printingDevice.getDefaultAttributeValue(MediaPrintableArea.class); if (testFlag && area == null) System.out.println("Area is null"); float[] imagable; // On my cheap tesco printer this return null, so accounted for that case. // if(area != null) { // imagable = area.getPrintableArea(Size2DSyntax.INCH); // } // else { PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); attributes.add(mediaSizeName); MediaPrintableArea areas[] = (MediaPrintableArea[]) printingDevice.getSupportedAttributeValues(MediaPrintableArea.class, null, attributes); if (testFlag && areas == null) System.out.println("Printable Area array is null"); int useArea = 0; if (areas[useArea] == null) for (int i = 0; i != areas.length && areas[useArea] == null; i++) useArea = i; imagable = areas[useArea].getPrintableArea(Size2DSyntax.INCH); // } for (int i = 0; i < 4; i++) { imagable[i] *= 72; } if (imagable[2] + imagable[0] > xSize) { imagable[2] = xSize - imagable[0]; } if (imagable[3] + imagable[1] > ySize) { imagable[3] = ySize - imagable[1]; } pdfPaper.setImageableArea(imagable[0], imagable[1], imagable[2], imagable[3]); pdfPageFormat.setPaper(pdfPaper); return pdfPageFormat; } /** * Find the default size for the given printer. If the printer hasnt got a default it will figure it out based on the locale. * * @param printingDevice * The PrintService to inspect * @return The default page size suitable for printing PDF files too. */ public static PageFormat getDefaultPage(PrintService printingDevice) { if (printingDevice == null) { printingDevice = PrintServiceLookup.lookupDefaultPrintService(); } return createPdfPageFormat(getDefaultMediaSizeName(printingDevice), printingDevice); } /** * Find an the default MediaSizeName from the PrintService. If there isnt a decent default one available get one based on locale. * * @param printingDevice * @return A valid, default MediaSizeName */ public static MediaSizeName getDefaultMediaSizeName(PrintService printingDevice) { MediaSizeName size = (MediaSizeName) printingDevice.getDefaultAttributeValue(MediaSizeName.class); if (size == null || MediaSize.getMediaSizeForName(size) == null) { Locale locale = Locale.getDefault(); if (locale.equals(Locale.UK)) { size = MediaSizeName.ISO_A4; } else if (locale.equals(Locale.US)) { size = MediaSizeName.NA_LETTER; } else { size = MediaSizeName.ISO_A4; } } return size; } /** * Used to create a set of available PageFormat based on what is available on the given device. * * @param printingDevice * The PrintService to examine */ public static void findPrinterPapers(PrintService printingDevice) { availablePaper = new HashSet(); if (printingDevice == null) { printingDevice = PrintServiceLookup.lookupDefaultPrintService(); } Media[] res = (Media[]) printingDevice.getSupportedAttributeValues(javax.print.attribute.standard.Media.class, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); for (Media m : res) { if (m instanceof javax.print.attribute.standard.MediaSizeName) { MediaSize size = MediaSize.getMediaSizeForName((MediaSizeName) m); if (size != null) { // The sun.print.CustomMediaSizeName returns null for some reason? availablePaper.add(createPdfPageFormat((MediaSizeName) m, printingDevice)); } } } } /** * Find the best fitting PageFormatPdfDecoder encapsulating the PdfPage * @return The nearest available PageFormat for this PrintService */ public static PageFormat getPageFormat(int p, PdfDecoder pdfDecoder) { PdfPageData pageData = pdfDecoder.getPdfPageData(); float cropW = pageData.getCropBoxWidth(p); float cropH = pageData.getCropBoxHeight(p); PageFormat result = PdfPageFormat.getAppropriatePageFormat(cropW, cropH); return result; } /** * Examine the Set of PageFormats to find the best fit. * * @param cropW * The desired paper width * @param cropH * The desired paper height */ private static PageFormat getAppropriatePageFormat(float cropW, float cropH) { if (availablePaper == null) { findPrinterPapers(null); } // Start off with null PageFormat result = null; for (PageFormat pf : availablePaper) { result = getClosestPageFormat(result, pf, cropW, cropH); } if (result == null) { // return the default PageFormat if null. Shouldnt really occur. result = PdfPageFormat.getDefaultPage(null); } return result; } /** * Compare two PageFormat objects to find which is a better fit. * * @param original * The current best fit PageFormat may be null. * @param newFormat * The PageFormat to compare against * @param cropW * The width of the PDF page * @param cropH * The height of the PDF page * @return The best fitting PageFormat either the original or a clone of the new best fitting one. */ private static PageFormat getClosestPageFormat(PageFormat original, PageFormat newFormat, float cropW, float cropH) { double newLongSide = newFormat.getHeight() > newFormat.getWidth() ? newFormat.getHeight() : newFormat.getWidth(); double newShortSide = newFormat.getHeight() < newFormat.getWidth() ? newFormat.getHeight() : newFormat.getWidth(); double cropLongSide = cropH > cropW ? cropH : cropW; double cropShortSide = cropH < cropW ? cropH : cropW; if (newShortSide >= cropShortSide && newLongSide >= cropLongSide) { if (original == null) { // No others so far so just have this one to start off with PageFormat result = (PageFormat) newFormat.clone(); return result; } double origLongSide = original.getHeight() > original.getWidth() ? original.getHeight() : original.getWidth(); double origShortSide = original.getHeight() < original.getWidth() ? original.getHeight() : original.getWidth(); if ((origLongSide + origShortSide) > (newShortSide + newLongSide)) { PageFormat result = (PageFormat) newFormat.clone(); return result; } } return original; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy