Index: src/documentation/content/xdocs/trunk/extensions.xml
===================================================================
--- src/documentation/content/xdocs/trunk/extensions.xml	(revision 798988)
+++ src/documentation/content/xdocs/trunk/extensions.xml	(working copy)
@@ -227,7 +227,76 @@
           </p>
         </section>
       </section>
-      
+      <section id="scale">
+        <title>fox:scale</title>
+        <p>
+          <code>fox:scale="sx [sy]"</code> attribute is used in <code>fo:simple-page-master</code> element and specifies
+          the a scale operation by sx and sy. If sy is not provided, it is assumed to be equal to sx.
+          sx and sy should be between 0 and 1.
+        </p>
+        <note>
+          It is implemented for PDF and Java2D renderers.
+        </note>
+      </section>
+      <section id="bleed">
+        <title>fox:bleed</title>
+        <p>
+            Value: &lt;length&gt;{1,4}
+        </p>
+        <p>
+            Default: 0pt
+        </p>
+        <p>
+            If there is only one value, it applies to all sides. If there are two values, the top and bottom
+            bleed widths are set to the first value and the right and left bleed widths are set to the second.
+            If there are three values, the top is set to the first value, the left and right are set to the second,
+            and the bottom is set to the third. If there are four values, they apply to the top, right, bottom, and
+            left, respectively.
+            (Corresponds to <a href="http://www.w3.org/TR/xsl11/#padding">http://www.w3.org/TR/xsl11/#padding</a>.
+        </p>
+        <p>
+            This extension indirectly defines the BleedBox and is calculated by expanding the TrimBox by
+            the bleed widths. The lengths must be non-negative
+        </p>
+      </section>
+      <section id="cropOffset">
+        <title>fox:crop-offset</title>
+        <p>
+          Value: &lt;length&gt;{1,4}
+        </p>
+        <p>
+          Default: 0pt
+        </p>
+        <p>
+          Same behaviour as with fox:bleed.
+        </p>
+        <p>
+          This extension indirectly defines the MediaBox and is calculated by expanding
+          the TrimBox by the crop offsets. The lengths must be non-negative. 
+        </p>
+      </section>
+      <section id="cropBox">
+        <title>fox:crop-box</title>
+        <p>
+          Alternative names due to the closeness to fox:crop-offset: crop-box-selector, crop-box-source, page-clip-area
+        </p>
+        <p>
+          Value: (trim-box|bleed-box|media-box)
+        </p>
+        <p>
+          Default: media-box
+        </p>
+        <p>
+          The crop box controls how Acrobat displays the page (CropBox in PDF) or how the Java2DRenderer sizes
+          the output media. The PDF spec defines that the CropBox defaults to the MediaBox. This extension
+          follows that definition. To simplify usage and cover most use cases, the three supported enumeration
+          values "trim-box", "bleed-box" and "media-box" set the CropBox to one of those three other boxes. 
+        </p>
+        <p>
+          If requested in the future, we could offer to specify the CropBox in absolute coordinates rather
+          than just be referencing another box.
+        </p>
+      </section>
     </section>
   </body>
 </document>
Index: src/java/org/apache/fop/render/awt/AWTRenderer.java
===================================================================
--- src/java/org/apache/fop/render/awt/AWTRenderer.java	(revision 798988)
+++ src/java/org/apache/fop/render/awt/AWTRenderer.java	(working copy)
@@ -30,6 +30,7 @@
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
 import java.awt.print.PageFormat;
 import java.awt.print.Pageable;
 import java.awt.print.Paper;
@@ -46,6 +47,7 @@
 import org.apache.fop.render.awt.viewer.Renderable;
 import org.apache.fop.render.awt.viewer.StatusListener;
 import org.apache.fop.render.java2d.Java2DRenderer;
+import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
 
 /**
  * The AWTRender outputs the pages generated by the layout engine to a Swing
@@ -149,11 +151,23 @@
         Rectangle2D bounds = getPageViewport(pageNum).getViewArea();
         pageWidth = (int) Math.round(bounds.getWidth() / 1000f);
         pageHeight = (int) Math.round(bounds.getHeight() / 1000f);
-        double scale = scaleFactor
+        double scaleX = scaleFactor
                 * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
                 / userAgent.getTargetPixelUnitToMillimeter();
-        int bitmapWidth = (int) ((pageWidth * scale) + 0.5);
-        int bitmapHeight = (int) ((pageHeight * scale) + 0.5);
+        double scaleY = scaleFactor
+                * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+                / userAgent.getTargetPixelUnitToMillimeter();
+        if (getPageViewport(pageNum).getForeignAttributes() != null) {
+            String scale = (String) getPageViewport(pageNum).getForeignAttributes().get(
+                    PageScaleAttributes.EXT_PAGE_SCALE);
+            Point2D scales = PageScaleAttributes.getScaleAttributes(scale);
+            if (scales != null) {
+                scaleX *= scales.getX();
+                scaleY *= scales.getY();
+            }
+        }
+        int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5);
+        int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5);
         return new Dimension(bitmapWidth, bitmapHeight);
     }
 
Index: src/java/org/apache/fop/render/extensions/prepress/PageBoundariesAttributes.java
===================================================================
--- src/java/org/apache/fop/render/extensions/prepress/PageBoundariesAttributes.java	(revision 0)
+++ src/java/org/apache/fop/render/extensions/prepress/PageBoundariesAttributes.java	(revision 0)
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: PageBoundariesAttributes.java $ */
+
+package org.apache.fop.render.extensions.prepress;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+import org.apache.fop.fo.properties.FixedLength;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.text.MessageFormat;
+import java.awt.Rectangle;
+
+
+/**
+ * This class contains definition of page boundaries FOF's extension attributes for XSL-FO.
+ * That is: bleedBox, trimBox and cropBox.
+ * Also this class provides method to parse the possible values of these attibutes
+ * and to generate original size of bounded area
+ */
+public final class PageBoundariesAttributes {
+
+    /**
+     * The extension attribute for calculating the PDF BleedBox area - specifies the bleed width
+     */
+    public static final QName EXT_BLEED
+            = new QName(ExtensionElementMapping.URI, null, "bleed");
+
+    /**
+     * The extension attribute for the PDF CropBox area
+     */
+    public static final QName EXT_CROP_OFFSET
+            = new QName(ExtensionElementMapping.URI, null, "crop-offset");
+
+    /**
+     * The extension attribute for the PDF CropBox area
+     */
+    public static final QName EXT_CROP_BOX
+            = new QName(ExtensionElementMapping.URI, null, "crop-box");
+
+
+    private static final Pattern SIZE_UNIT_PATTERN
+            = Pattern.compile("^(-?\\d*\\.?\\d*)(px|in|cm|mm|pt|pc|mpt)$");
+
+
+    /**
+     * Utility classes should not have a public or default constructor
+     */
+    private PageBoundariesAttributes() {
+    }
+
+
+    /**
+     * The BleedBox is calculated by expanding the TrimBox by the bleed widths.
+     *
+     * @param trimBox the TrimBox rectangle
+     * @param bleed   the given bleed widths
+     * @return the calculated BleedBox rectangle
+     */
+    public static Rectangle getBleedBoxRectangle(Rectangle trimBox, String bleed) {
+        return getRectagleUsingOffset(trimBox, bleed);
+    }
+
+    /**
+     * The MediaBox is calculated by expanding the BleedBox by the crop offsets
+     *
+     * @param bleedBox    the BleedBox rectangle
+     * @param cropOffsets the given crop offsets
+     * @return the calculated MediaBox rectangle
+     */
+    public static Rectangle getMediaBoxRectangle(Rectangle bleedBox, String cropOffsets) {
+        return getRectagleUsingOffset(bleedBox, cropOffsets);
+    }
+
+    /**
+     * The crop box controls how Acrobat display the page or how the Java2DRenderer
+     * sizes the output media. The PDF spec defines that the CropBox defaults to the  MediaBox
+     * <p/>
+     * The possible values of crop-box: (trim-box|bleed-box|media-box)
+     * Default value: media-box
+     *
+     * @param trimBox  the TrimBox rectangle
+     * @param bleedBox the BleedBox rectangle
+     * @param mediaBox the MediaBox rectangle
+     * @param value    the crop-box value
+     * @return the calculated CropBox rectangle
+     */
+    public static Rectangle getCropBoxRectangle(final Rectangle trimBox, final Rectangle bleedBox,
+                                                final Rectangle mediaBox, final String value) {
+        final String err = "The crop-box has invalid value: {0}, "
+                + "possible values of crop-box: (trim-box|bleed-box|media-box)";
+
+        if ("trim-box".equals(value)) {
+            return trimBox;
+        } else if ("bleed-box".equals(value)) {
+            return bleedBox;
+        } else if ("media-box".equals(value) || value == null || "".equals(value)) {
+            return mediaBox;
+        } else {
+            throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{value}));
+        }
+    }
+
+    /**
+     * The crop box controls how Acrobat display the page or how the Java2DRenderer
+     * sizes the output media. The PDF spec defines that the CropBox defaults to the  MediaBox
+     * <p/>
+     * The possible values of crop-box: (trim-box|bleed-box|media-box)
+     * Default value: media-box
+     *
+     * @param trimBox    the TrimBox rectangle
+     * @param bleed      the given bleed widths
+     * @param cropOffset the given crop offsets
+     * @param value      the crop-box value
+     * @return the calculated CropBox rectangle
+     */
+    public static Rectangle getCropBoxRectangle(final Rectangle trimBox, final String bleed,
+                                                final String cropOffset, final String value) {
+        Rectangle bleedBox = getBleedBoxRectangle(trimBox, bleed);
+        Rectangle mediaBox = getMediaBoxRectangle(bleedBox, cropOffset);
+
+        return getCropBoxRectangle(trimBox, bleedBox, mediaBox, value);
+    }
+
+    private static Rectangle getRectagleUsingOffset(Rectangle originalRect, String offset) {
+        if (offset == null || "".equals(offset) || originalRect == null) {
+            return originalRect;
+        }
+
+        String[] bleeds = offset.split(" ");
+        int[] coords = new int[4]; // top, rigth, bottom, left
+        if (bleeds.length == 1) {
+            coords[0] = getLengthIntValue(bleeds[0]);
+            coords[1] = coords[0];
+            coords[2] = coords[0];
+            coords[3] = coords[0];
+        } else if (bleeds.length == 2) {
+            coords[0] = getLengthIntValue(bleeds[0]);
+            coords[2] = coords[0];
+            coords[1] = getLengthIntValue(bleeds[1]);
+            coords[3] = coords[1];
+        } else if (bleeds.length == 3) {
+            coords[0] = getLengthIntValue(bleeds[0]);
+            coords[1] = getLengthIntValue(bleeds[1]);
+            coords[3] = coords[1];
+            coords[2] = getLengthIntValue(bleeds[2]);
+        } else if (bleeds.length == 4) {
+            coords[0] = getLengthIntValue(bleeds[0]);
+            coords[1] = getLengthIntValue(bleeds[1]);
+            coords[2] = getLengthIntValue(bleeds[2]);
+            coords[3] = getLengthIntValue(bleeds[3]);
+        }
+        return new Rectangle((int) (originalRect.getX() - coords[3]),
+                (int) (originalRect.getY() - coords[0]),
+                (int) (originalRect.getWidth() + coords[3] + coords[1]),
+                (int) (originalRect.getHeight() + coords[0] + coords[2]));
+    }
+
+    private static int getLengthIntValue(final String length) {
+        final String err = "Incorrect length value: {0}";
+        Matcher m = SIZE_UNIT_PATTERN.matcher(length);
+
+        if (m.find()) {
+            return FixedLength.getInstance(Double.parseDouble(m.group(1)), m.group(2))
+                    .getLength().getValue();
+        } else {
+            throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{length}));
+        }
+    }
+}
Index: src/java/org/apache/fop/render/extensions/prepress/PageScaleAttributes.java
===================================================================
--- src/java/org/apache/fop/render/extensions/prepress/PageScaleAttributes.java	(revision 0)
+++ src/java/org/apache/fop/render/extensions/prepress/PageScaleAttributes.java	(revision 0)
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: PageScaleAttributes.java $ */
+
+package org.apache.fop.render.extensions.prepress;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.fop.fo.extensions.ExtensionElementMapping;
+
+import java.awt.geom.Point2D;
+import java.text.MessageFormat;
+
+
+/**
+ * This class contains definition of 'scale' FOF's extension attribute for XSL-FO, and provides
+ * utility method to parse the possible values of this attibute
+ */
+public final class PageScaleAttributes {
+
+    /**
+     * The extension 'scale' attribute for simple-page-master element
+     */
+    public static final QName EXT_PAGE_SCALE
+            = new QName(ExtensionElementMapping.URI, null, "scale");
+
+
+    /**
+     * Utility classes should not have a public or default constructor
+     */
+    private PageScaleAttributes() {
+    }
+
+    /**
+     * Compute scale parameters from given fox:scale attribute which has format: scaleX [scaleY]
+     * If scaleY is not defined, it equals scaleX
+     * @param scale scale attribute, input format: scaleX [scaleY]
+     * @return the pair of (sx, sy) values
+     */
+    public static Point2D.Double getScaleAttributes(String scale) {
+        final String err = "Extension 'scale' attribute has incorrect value(s): {0}";
+
+        if (scale == null) {
+            return null;
+        }
+
+        Point2D.Double result = null;
+
+        try {
+            String[] scales = scale.split(" ");
+            if (scales.length > 0) {
+                result = new Point2D.Double(Double.parseDouble(scales[0]),
+                        Double.parseDouble(scales[0]));
+            }
+            if (scales.length > 1) {
+                result.y = Double.parseDouble(scales[1]);
+            }
+            if (result.x <= 0 || result.x > 1 || result.y <= 0 || result.y > 1) {
+                throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{scale}));
+            }
+        } catch (NumberFormatException nfe) {
+            throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{scale}));
+        }
+
+        return result;
+    }
+}
Index: src/java/org/apache/fop/render/intermediate/IFRenderer.java
===================================================================
--- src/java/org/apache/fop/render/intermediate/IFRenderer.java	(revision 798988)
+++ src/java/org/apache/fop/render/intermediate/IFRenderer.java	(working copy)
@@ -549,7 +549,7 @@
         }
         try {
             pageIndices.put(page.getKey(), new Integer(page.getPageIndex()));
-            Rectangle2D viewArea = page.getViewArea();
+            Rectangle viewArea = page.getViewArea();
             Dimension dim = new Dimension(
                     (int)Math.ceil(viewArea.getWidth()),
                     (int)Math.ceil(viewArea.getHeight()));
Index: src/java/org/apache/fop/render/java2d/Java2DRenderer.java
===================================================================
--- src/java/org/apache/fop/render/java2d/Java2DRenderer.java	(revision 798988)
+++ src/java/org/apache/fop/render/java2d/Java2DRenderer.java	(working copy)
@@ -75,6 +75,8 @@
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
+import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes;
 import org.apache.fop.render.pdf.CTMHelper;
 import org.apache.fop.util.CharUtilities;
 import org.apache.fop.util.ColorUtil;
@@ -290,7 +292,18 @@
 
         this.currentPageViewport = pageViewport;
         try {
-            Rectangle2D bounds = pageViewport.getViewArea();
+            String bleed = (String) currentPageViewport.getForeignAttributes().get(
+                    PageBoundariesAttributes.EXT_BLEED);
+            String cropOffset = (String) currentPageViewport.getForeignAttributes().get(
+                    PageBoundariesAttributes.EXT_CROP_OFFSET);
+            String cropBoxValue = (String) currentPageViewport.getForeignAttributes().get(
+                    PageBoundariesAttributes.EXT_CROP_BOX);
+            Rectangle2D bounds = PageBoundariesAttributes.getCropBoxRectangle(
+                    pageViewport.getViewArea(),
+                    bleed,
+                    cropOffset,
+                    cropBoxValue
+            );
             this.pageWidth = (int) Math.round(bounds.getWidth() / 1000f);
             this.pageHeight = (int) Math.round(bounds.getHeight() / 1000f);
 
@@ -299,11 +312,26 @@
                             + " (pageWidth " + pageWidth + ", pageHeight "
                             + pageHeight + ")");
 
-            double scale = scaleFactor
+            // set scale factor
+            double scaleX = scaleFactor;
+            double scaleY = scaleFactor;
+            String scale = (String) currentPageViewport.getForeignAttributes().get(
+                    PageScaleAttributes.EXT_PAGE_SCALE);
+            Point2D scales = PageScaleAttributes.getScaleAttributes(scale);
+            if (scales != null) {
+                scaleX *= scales.getX();
+                scaleY *= scales.getY();
+            }
+
+
+            scaleX = scaleX
                 * (25.4f / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
                 / userAgent.getTargetPixelUnitToMillimeter();
-            int bitmapWidth = (int) ((pageWidth * scale) + 0.5);
-            int bitmapHeight = (int) ((pageHeight * scale) + 0.5);
+            scaleY = scaleY
+                * (25.4f / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+                / userAgent.getTargetPixelUnitToMillimeter();
+            int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5);
+            int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5);
 
 
             BufferedImage currentPageImage = getBufferedImage(bitmapWidth, bitmapHeight);
@@ -326,7 +354,7 @@
 
             // transform page based on scale factor supplied
             AffineTransform at = graphics.getTransform();
-            at.scale(scale, scale);
+            at.scale(scaleX, scaleY);
             graphics.setTransform(at);
 
             // draw page frame
Index: src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
===================================================================
--- src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java	(revision 798988)
+++ src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java	(working copy)
@@ -19,8 +19,10 @@
 
 package org.apache.fop.render.pdf;
 
+import java.awt.Rectangle;
 import java.awt.Dimension;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.io.IOException;
 import java.util.Map;
 
@@ -43,6 +45,8 @@
 import org.apache.fop.render.intermediate.IFDocumentNavigationHandler;
 import org.apache.fop.render.intermediate.IFException;
 import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes;
+import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
 
 /**
  * {@code IFDocumentHandler} implementation that produces PDF.
@@ -166,11 +170,53 @@
                 throws IFException {
         this.pdfResources = this.pdfDoc.getResources();
 
+        String bleedWidth = (String) getContext().getForeignAttribute(
+                PageBoundariesAttributes.EXT_BLEED);
+        String cropOffset = (String) getContext().getForeignAttribute(
+                PageBoundariesAttributes.EXT_CROP_OFFSET);
+        String cropBoxValue = (String) getContext().getForeignAttribute(
+                PageBoundariesAttributes.EXT_CROP_BOX);
+
+        Rectangle trimBox = new Rectangle(0, 0,
+                (int) size.getWidth(), (int) size.getHeight());
+        Rectangle bleedBox =
+                PageBoundariesAttributes.getBleedBoxRectangle(trimBox, bleedWidth);
+        Rectangle mediaBox =
+                PageBoundariesAttributes.getMediaBoxRectangle(bleedBox, cropOffset);
+
+        Rectangle cropBox = PageBoundariesAttributes.getCropBoxRectangle(
+                trimBox, bleedBox, mediaBox, cropBoxValue);
+
+        // set scale attributes
+        double scaleX = 1;
+        double scaleY = 1;
+        String scale = (String) getContext().getForeignAttribute(
+                PageScaleAttributes.EXT_PAGE_SCALE);
+        Point2D scales = PageScaleAttributes.getScaleAttributes(scale);
+        if (scales != null) {
+            scaleX = scales.getX();
+            scaleY = scales.getY();
+        }
+
         this.currentPage = this.pdfDoc.getFactory().makePage(
-            this.pdfResources,
-            (int)Math.round(size.getWidth() / 1000),
-            (int)Math.round(size.getHeight() / 1000),
-            index);
+                this.pdfResources,
+                index,
+                new Rectangle((int) (mediaBox.getX() * scaleX / 1000),
+                        (int) (mediaBox.getY() * scaleY / 1000),
+                        (int) (mediaBox.getWidth() * scaleX / 1000),
+                        (int) (mediaBox.getHeight() * scaleY / 1000)),
+                new Rectangle((int) (cropBox.getX() * scaleX / 1000),
+                        (int) (cropBox.getY() * scaleY / 1000),
+                        (int) (cropBox.getWidth() * scaleX / 1000),
+                        (int) (cropBox.getHeight() * scaleY / 1000)),
+                new Rectangle((int) (bleedBox.getX() * scaleX / 1000),
+                        (int) (bleedBox.getY() * scaleY / 1000),
+                        (int) (bleedBox.getWidth() * scaleX / 1000),
+                        (int) (bleedBox.getHeight() * scaleY / 1000)),
+                new Rectangle((int) (trimBox.getX() * scaleX / 1000),
+                        (int) (trimBox.getY() * scaleY / 1000),
+                        (int) (trimBox.getWidth() * scaleX / 1000),
+                        (int) (trimBox.getHeight() * scaleY / 1000)));
         //pageReferences.put(new Integer(index)/*page.getKey()*/, currentPage.referencePDF());
         //pvReferences.put(page.getKey(), page);
 
@@ -182,7 +228,8 @@
         this.generator = new PDFContentGenerator(this.pdfDoc, this.outputStream, this.currentPage);
         // Transform the PDF's default coordinate system (0,0 at lower left) to the PDFPainter's
         AffineTransform basicPageTransform = new AffineTransform(1, 0, 0, -1, 0,
-                size.height / 1000f);
+                (scaleY * size.height) / 1000f);
+        basicPageTransform.scale(scaleX, scaleY);
         generator.concatenate(basicPageTransform);
     }
 
Index: test/java/org/apache/fop/render/extensions/PrepressTest.java
===================================================================
--- test/java/org/apache/fop/render/extensions/PrepressTest.java	(revision 0)
+++ test/java/org/apache/fop/render/extensions/PrepressTest.java	(revision 0)
@@ -0,0 +1,105 @@
+package org.apache.fop.render.extensions;
+
+import junit.framework.TestCase;
+import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
+import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes;
+
+import java.awt.geom.Point2D;
+import java.awt.Rectangle;
+
+/**
+ * Base class for automated tests for
+ * {@link org.apache.fop.render.extensions.prepress.PageBoundariesAttributes}
+ * and
+ * {@link org.apache.fop.render.extensions.prepress.PageScaleAttributes}
+ */
+public class PrepressTest extends TestCase {
+
+    private static final int w = 800;
+    private static final int h = 600;
+    private static final Rectangle TEST_AREA = new Rectangle(0, 0, w, h);
+    private static final String bleed1 = "5pt";
+    private static final String cropOffset1 = "3pt";
+    private static final String cropBox = "media-box";
+
+
+    /**
+     * Main constructor
+     * @param name the name of the test case
+     */
+    public PrepressTest(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Tests for 'scale' extension attribute
+     */
+    public void testScaleOk() throws Exception {
+        Point2D res = PageScaleAttributes.getScaleAttributes("0.5");
+        assertEquals("Points should be equal", res.getX(), res.getY(), 0);
+    }
+
+    public void testScaleFailIllArgExc() throws Exception {
+        try {
+            Point2D res = PageScaleAttributes.getScaleAttributes("0.5mm 0.5cm");
+            fail("Expected IllegalArgumentException. Scale shouldn't contain units");
+        } catch (IllegalArgumentException iae) {
+            // Good!
+        }
+    }
+
+    public void testScaleNotEqual() throws Exception {
+        Point2D res = PageScaleAttributes.getScaleAttributes("0.5 0.6");
+        assertFalse("Points shouldn't be equal", res.getX() == res.getY());
+    }
+
+    public void testScaleNull() throws Exception {
+        Point2D res = PageScaleAttributes.getScaleAttributes(null);
+        assertNull("Result shouldn't be null", res);
+    }
+
+
+    /**
+     * Tests for page boundaries
+     */
+    public void testBoxOk1() throws Exception {
+        Rectangle res = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, null);
+        assertSame("Result should be the same as TEST_AREA object", res, TEST_AREA);
+
+        res = PageBoundariesAttributes.getBleedBoxRectangle(null, bleed1);
+        assertNull(res);
+    }
+
+    public void testBoxOk2() throws Exception {
+        Rectangle res1 = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, bleed1);
+        assertNotNull("Expected not null object", res1);
+        assertTrue("Values should be equal", res1.getX() == -5000);
+        assertTrue("Values should be equal", res1.getY() == -5000);
+        assertTrue("Values should be equal", res1.getWidth() == w + 10000);
+        assertTrue("Values should be equal", res1.getHeight() ==  h + 10000);
+
+        Rectangle res2 = PageBoundariesAttributes.getMediaBoxRectangle(res1, cropOffset1);
+        assertNotNull("Expected not null object", res2);
+        assertTrue("Values should be equal", res2.getX() == -8000);
+        assertTrue("Values should be equal", res2.getY() == -8000);
+        assertTrue("Values should be equal", res2.getWidth() == w + 16000);
+        assertTrue("Values should be equal", res2.getHeight() ==  h + 16000);
+
+        Rectangle res3 = PageBoundariesAttributes.getCropBoxRectangle(TEST_AREA, res1, res2, cropBox);
+        assertNotNull("Expected not null object", res3);
+        assertTrue("Values should be equal", res3.getX() == res2.getX());
+        assertTrue("Values should be equal", res3.getY() == res2.getY());
+        assertTrue("Values should be equal", res3.getWidth() == res2.getWidth());
+        assertTrue("Values should be equal", res3.getHeight() ==  res2.getHeight());
+    }
+
+    public void testBoxIllArgExc() throws Exception {
+        try {
+            Rectangle res = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, "0");
+            fail("Expected IllegalArgumentException. Box should have units");
+        } catch (IllegalArgumentException iae) {
+            // Good!
+        }
+    }
+}
Index: test/java/org/apache/fop/StandardTestSuite.java
===================================================================
--- test/java/org/apache/fop/StandardTestSuite.java	(revision 798988)
+++ test/java/org/apache/fop/StandardTestSuite.java	(working copy)
@@ -31,6 +31,7 @@
 import org.apache.fop.render.pdf.PDFEncodingTestCase;
 import org.apache.fop.render.pdf.PDFsRGBSettingsTestCase;
 import org.apache.fop.render.rtf.RichTextFormatTestSuite;
+import org.apache.fop.render.extensions.PrepressTest;
 
 /**
  * Test suite for basic functionality of FOP.
@@ -56,6 +57,7 @@
         suite.addTest(new TestSuite(ImageLoaderTestCase.class));
         suite.addTest(new TestSuite(ImagePreloaderTestCase.class));
         suite.addTest(new TestSuite(IFMimickingTestCase.class));
+        suite.addTest(new TestSuite(PrepressTest.class));
         //$JUnit-END$
         return suite;
     }
