* @param userZoom     Zoom factor to be applied to the rendered page
     * @return AffineTransform for translating from the rotated and zoomed PDF
     *         coordinate system to the Java Graphics coordinate system
     */
    public AffineTransform getPageTransform(final int boundary,
                                            float userRotation,
                                            float userZoom) {
        AffineTransform at = new AffineTransform();

        Rectangle2D.Double boundingBox = getBoundingBox(boundary, userRotation, userZoom);
        at.translate(0, boundingBox.getHeight());

        // setup canvas for PDF document orientation
        at.scale(1, -1);

        at.scale(userZoom, userZoom);

        float totalRotation = getTotalRotation(userRotation);
        PRectangle pageBoundary = getPageBoundary(boundary);

        if (totalRotation == 0) {
        } else if (totalRotation == 90) {
            at.translate(pageBoundary.height, 0);
        } else if (totalRotation == 180) {
            at.translate(pageBoundary.width, pageBoundary.height);
        } else if (totalRotation == 270) {
            at.translate(0, pageBoundary.width);
        } else {
            if (totalRotation > 0 && totalRotation < 90) {
                double xShift = pageBoundary.height * Math.cos(Math.toRadians(90 - totalRotation));
                at.translate(xShift, 0);
            } else if (totalRotation > 90 && totalRotation < 180) {
                double rad = Math.toRadians(180 - totalRotation);
                double cosRad = Math.cos(rad);
                double sinRad = Math.sin(rad);
                double xShift = pageBoundary.height * sinRad + pageBoundary.width * cosRad;
                double yShift = pageBoundary.height * cosRad;
                at.translate(xShift, yShift);
            } else if (totalRotation > 180 && totalRotation < 270) {
                double rad = Math.toRadians(totalRotation - 180);
                double cosRad = Math.cos(rad);
                double sinRad = Math.sin(rad);
                double xShift = pageBoundary.width * cosRad;
                double yShift = pageBoundary.width * sinRad + pageBoundary.height * cosRad;
                at.translate(xShift, yShift);
            } else if (totalRotation > 270 && totalRotation < 360) {
                double yShift = pageBoundary.width * Math.cos(Math.toRadians(totalRotation - 270));
                at.translate(0, yShift);
            }
        }

        // apply rotation on canvas, convert to Radians
        at.rotate(totalRotation * Math.PI / 180.0);

        // translate crop lower left corner back to where media box corner was
        float x = 0 - pageBoundary.x;
        float y = 0 - (pageBoundary.y - pageBoundary.height);
        at.translate(x, y);

        return at;
    }