class PDFPageable extends Book
{
    private final PDDocument document;
    private final int numberOfPages;
    private final boolean showPageBorder;
    private final float dpi;
    private final Orientation orientation;
    private boolean subsamplingAllowed = false;
    private RenderingHints renderingHints = null;

    /**
     * Creates a new PDFPageable.
     *
     * @param document the document to print
     */
    public PDFPageable(PDDocument document)
    {
        this(document, Orientation.AUTO, false, 0);
    }
    
    /**
     * Creates a new PDFPageable with the given page orientation.
     *
     * @param document the document to print
     * @param orientation page orientation policy
     */
    public PDFPageable(PDDocument document, Orientation orientation)
    {
        this(document, orientation, false, 0);
    }
    
    /**
     * Creates a new PDFPageable with the given page orientation and with optional page borders
     * shown. The image will be rasterized at the given DPI before being sent to the printer.
     *
     * @param document the document to print
     * @param orientation page orientation policy
     * @param showPageBorder true if page borders are to be printed
     */
    public PDFPageable(PDDocument document, Orientation orientation, boolean showPageBorder)
    {
        this(document, orientation, showPageBorder, 0);
    }

    /**
     * Creates a new PDFPageable with the given page orientation and with optional page borders
     * shown. The image will be rasterized at the given DPI before being sent to the printer.
     *
     * @param document the document to print
     * @param orientation page orientation policy
     * @param showPageBorder true if page borders are to be printed
     * @param dpi if non-zero then the image will be rasterized at the given DPI
     */
    public PDFPageable(PDDocument document, Orientation orientation, boolean showPageBorder,
                       float dpi)
    {
        this.document = document;
        this.orientation = orientation;
        this.showPageBorder = showPageBorder;
        this.dpi = dpi;
        numberOfPages = document.getNumberOfPages();
    }

    /**
     * Get the rendering hints.
     *
     * @return the rendering hints or null if none are set.
     */
    public RenderingHints getRenderingHints()
    {
        return renderingHints;
    }

    /**
     * Set the rendering hints. Use this to influence rendering quality and speed. If you don't set them yourself or
     * pass null, PDFBox will decide <b><u>at runtime</u></b> depending on the destination.
     *
     * @param renderingHints rendering hints to be used to influence rendering quality and speed
     */
    public void setRenderingHints(RenderingHints renderingHints)
    {
        this.renderingHints = renderingHints;
    }

    /**
     * Value indicating if the renderer is allowed to subsample images before drawing, according to
     * image dimensions and requested scale.
     *
     * Subsampling may be faster and less memory-intensive in some cases, but it may also lead to
     * loss of quality, especially in images with high spatial frequency.
     *
     * @return true if subsampling of images is allowed, false otherwise.
     */
    public boolean isSubsamplingAllowed()
    {
        return subsamplingAllowed;
    }

    /**
     * Sets a value instructing the renderer whether it is allowed to subsample images before
     * drawing. The subsampling frequency is determined according to image size and requested scale.
     *
     * Subsampling may be faster and less memory-intensive in some cases, but it may also lead to
     * loss of quality, especially in images with high spatial frequency.
     *
     * @param subsamplingAllowed The new value indicating if subsampling is allowed.
     */
    public void setSubsamplingAllowed(boolean subsamplingAllowed)
    {
        this.subsamplingAllowed = subsamplingAllowed;
    }

    @Override
    public int getNumberOfPages()
    {
        return numberOfPages;
    }

    /**
     * {@inheritDoc}
     * 
     * Returns the actual physical size of the pages in the PDF file. May not fit the local printer.
     */
    @Override
    public PageFormat getPageFormat(int pageIndex)
    {<FILL_FUNCTION_BODY>}
    
    @Override
    public Printable getPrintable(int i)
    {
        if (i >= numberOfPages)
        {
            throw new IndexOutOfBoundsException(i + " >= " + numberOfPages);
        }
        PDFPrintable printable = new PDFPrintable(document, Scaling.ACTUAL_SIZE, showPageBorder, dpi);
        printable.setSubsamplingAllowed(subsamplingAllowed);
        printable.setRenderingHints(renderingHints);
        return printable;
    }
}

        PDPage page = document.getPage(pageIndex);
        PDRectangle mediaBox = PDFPrintable.getRotatedMediaBox(page);
        PDRectangle cropBox = PDFPrintable.getRotatedCropBox(page);
        
        // Java does not seem to understand landscape paper sizes, i.e. where width > height, it
        // always crops the imageable area as if the page were in portrait. I suspect that this is
        // a JDK bug but it might be by design, see PDFBOX-2922.
        //
        // As a workaround, we normalise all Page(s) to be portrait, then flag them as landscape in
        // the PageFormat.
        Paper paper;
        boolean isLandscape;
        if (mediaBox.getWidth() > mediaBox.getHeight())
        {
            // rotate
            paper = new Paper();
            paper.setSize(mediaBox.getHeight(), mediaBox.getWidth());
            paper.setImageableArea(cropBox.getLowerLeftY(), cropBox.getLowerLeftX(),
                    cropBox.getHeight(), cropBox.getWidth());
            isLandscape = true;
        }
        else
        {
            paper = new Paper();
            paper.setSize(mediaBox.getWidth(), mediaBox.getHeight());
            paper.setImageableArea(cropBox.getLowerLeftX(), cropBox.getLowerLeftY(),
                    cropBox.getWidth(), cropBox.getHeight());
            isLandscape = false;
        }

        PageFormat format = new PageFormat();
        format.setPaper(paper);
        
        // auto portrait/landscape
        switch (orientation)
        {
            case AUTO:
                format.setOrientation(isLandscape ? PageFormat.LANDSCAPE : PageFormat.PORTRAIT);
                break;
            case LANDSCAPE:
                format.setOrientation(PageFormat.LANDSCAPE);
                break;
            case PORTRAIT:
                format.setOrientation(PageFormat.PORTRAIT);
                break;
            default:
                break;
        }
        
        return format;
    
<methods>public void <init>() ,public void append(java.awt.print.Printable, java.awt.print.PageFormat) ,public void append(java.awt.print.Printable, java.awt.print.PageFormat, int) ,public int getNumberOfPages() ,public java.awt.print.PageFormat getPageFormat(int) throws java.lang.IndexOutOfBoundsException,public java.awt.print.Printable getPrintable(int) throws java.lang.IndexOutOfBoundsException,public void setPage(int, java.awt.print.Printable, java.awt.print.PageFormat) throws java.lang.IndexOutOfBoundsException<variables>private Vector<java.awt.print.Book.BookPage> mPages