You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by "Roberto Mazzola (JIRA)" <ji...@apache.org> on 2011/03/21 15:56:11 UTC

[jira] [Issue Comment Edited] (PDFBOX-985) PDF Printing Orientation

    [ https://issues.apache.org/jira/browse/PDFBOX-985?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13009151#comment-13009151 ] 

Roberto Mazzola edited comment on PDFBOX-985 at 3/21/11 2:55 PM:
-----------------------------------------------------------------

I try to apply this patch on the PDPageable class and it is working for me...
Probably it is not the "best" way...

    public PageFormat getPageFormat(int i) throws IndexOutOfBoundsException {
        PageFormat format = job.defaultPage();

        PDPage page = pages.get(i); // can throw IOOBE
        
        Dimension media = page.findMediaBox().createDimension();
        Dimension crop = page.findCropBox().createDimension();

        // Center the ImageableArea if the crop is smaller than the media
        double diffWidth = 0.0;
        double diffHeight = 0.0;
        if (!media.equals(crop)) {
            diffWidth = (media.getWidth() - crop.getWidth()) / 2.0;
            diffHeight = (media.getHeight() - crop.getHeight()) / 2.0;
        }

        int vOrientation = PageFormat.PORTRAIT; 
        int vRotationOfThePage = page.findRotation();

        if (vRotationOfThePage == 90 || vRotationOfThePage == 270 )
           vOrientation = PageFormat.LANDSCAPE; 
        else
           if(vRotationOfThePage == 0 )
           {
              if(media.getWidth() == 792 && media.getHeight() == 612)
                 vOrientation = PageFormat.LANDSCAPE; 
           }
        format.setOrientation(vOrientation);
        Paper paper = format.getPaper();
        if (vOrientation == PageFormat.LANDSCAPE) {
           paper.setImageableArea(
                   diffHeight, diffWidth, crop.getHeight(), crop.getWidth());
           paper.setSize(media.getHeight(), media.getWidth());
        } else {
           paper.setImageableArea(
                   diffWidth, diffHeight, crop.getWidth(), crop.getHeight());
           paper.setSize(media.getWidth(), media.getHeight());
        }
        format.setPaper(paper);

        return format;
    }


Unfortunatelly check only the rotation is not valid. Because for example in my case rotation was 0, but retrieving the MediaBox you can 'guess' the orientation. When top/bottom is larger than right/left it means that the orientation is landscape. Otherwise it's portrait. (http://forums.adobe.com/thread/454009)
For a quick fix for me I apply a test with fixed value

media.getWidth() == 792 && media.getHeight() == 612

I hope this can be useful to fix this issue

Thanks

      was (Author: rmazzola):
    I try to apply this patch on the PDPageable class and it is working for me...
Probably it is not the "best" way...

    public PageFormat getPageFormat(int i) throws IndexOutOfBoundsException {
        PageFormat format = job.defaultPage();

        PDPage page = pages.get(i); // can throw IOOBE
        
        Dimension media = page.findMediaBox().createDimension();
        Dimension crop = page.findCropBox().createDimension();

        // Center the ImageableArea if the crop is smaller than the media
        double diffWidth = 0.0;
        double diffHeight = 0.0;
        if (!media.equals(crop)) {
            diffWidth = (media.getWidth() - crop.getWidth()) / 2.0;
            diffHeight = (media.getHeight() - crop.getHeight()) / 2.0;
        }

        int vOrientation = PageFormat.PORTRAIT; 
        int vRotationOfThePage = page.findRotation();
        System.out.println("vRotationOfThePage -->" + vRotationOfThePage);
        if (vRotationOfThePage == 90 || vRotationOfThePage == 270 )
           vOrientation = PageFormat.LANDSCAPE; 
        else
           if(vRotationOfThePage == 0 )
           {
              if(media.getWidth() == 792 && media.getHeight() == 612)
                 vOrientation = PageFormat.LANDSCAPE; 
           }
        format.setOrientation(vOrientation);
        Paper paper = format.getPaper();
        if (vOrientation == PageFormat.LANDSCAPE) {
           paper.setImageableArea(
                   diffHeight, diffWidth, crop.getHeight(), crop.getWidth());
           paper.setSize(media.getHeight(), media.getWidth());
        } else {
           paper.setImageableArea(
                   diffWidth, diffHeight, crop.getWidth(), crop.getHeight());
           paper.setSize(media.getWidth(), media.getHeight());
        }
        format.setPaper(paper);

        return format;
    }


Unfortunatelly check only the rotation is not valid. Because for example in my case rotation was 0, but retrieving the MediaBox you can 'guess' the orientation. When top/bottom is larger than right/left it means that the orientation is landscape. Otherwise it's portrait. (http://forums.adobe.com/thread/454009)
For a quick fix for me I apply a test with fixed value

media.getWidth() == 792 && media.getHeight() == 612

I hope this can be useful to fix this issue

Thanks
  
> PDF Printing Orientation
> ------------------------
>
>                 Key: PDFBOX-985
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-985
>             Project: PDFBox
>          Issue Type: Bug
>          Components: PDModel
>    Affects Versions: 1.5.0
>            Reporter: Roberto Mazzola
>              Labels: print
>
> I try to print a PDF using the following code
> {code}
> // aDevice is the printer device Name
> // aData is a byte array of my PDF (stored on a DB)
> ....
> 			vPrintService = this.getPrintService(aDevice);
> 			vPrinterJob = java.awt.print.PrinterJob.getPrinterJob();
> 			vPrinterJob.setPrintService(vPrintService);
> 			vPDDocument = this.getPDDocument(aData);
> 			vPDDocument.silentPrint(vPrinterJob);
> --
> {code}
> {code: Suppors methods}         
> public PrintService getPrintService(String aDevice) throws Exception
> {
> 	javax.print.PrintService[] vPrintServices = java.awt.print.PrinterJob.lookupPrintServices();
>     boolean printerFound = false;
>     for(int i = 0; i < vPrintServices.length; i++)
>     {
>     	if(vPrintServices[i].getName().trim().equals(aDevice.trim()))
>         	return vPrintServices[i];
>     }
> 	 return null;
> }
> public PDDocument getPDDocument(GenericBean aData) throws Exception
> {
>    byte[] vPageData  =  (byte[])aData.getValueAtKey("Byte");
>    return PDDocument.load( new ByteArrayInputStream(vPageData) );
> }
> {code}
> But if my PDF is LANDSCAPE and the printer instead as PORTRAIT as default, PORTRAIT wins and so the report is not well printed.
> Checking the code (based on 1.5.0 and also from lateast trunk) for class PDPageable... probably I found the issue.. and I believe that the implementation is not right (at least from my point of view).
> Get a look to the getPageFormat method.
> As first it get the page format from the job (PrinterJob)
>         PageFormat format = job.defaultPage();
> after it get the (optional) print  service from the job (Printer Job)
>      PrintService service = job.getPrintService(); // can be null
> If the printer service is not null and it have LANDSCAPE as orientation.. it force LANDSCAPE as orientation in the page format otherwise it force it as PORTRAIT
> But... in my mind, it should get the orientation from the PDF Page.. and not from the printer job / print service.
> I can print documents with different orientation on the same printer and also I can have in the same document pages with different orientation.
> Of couse I can make same mistake and read the code in the wrong way... (I found this project yesterday....)
> Maybe the "findRotation" method on the PDPage should be invoked and "checked".. or something else....
> It this a bug on PDFBox ?
> thanks
> Roberto

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira