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,97 @@ +package org.apache.fop.render.extensions; + +import java.awt.Rectangle; +import java.awt.geom.Point2D; + +import junit.framework.TestCase; + +import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes; +import org.apache.fop.render.extensions.prepress.PageScaleAttributes; + +/** + * 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 Rectangle TEST_AREA = new Rectangle(0, 0, 800, 800); + + /** + * 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.getRectangle(null, TEST_AREA); + assertSame("Result shouldn't be the same as TEST_AREA object", res, TEST_AREA); + + res = PageBoundariesAttributes.getRectangle("asdfasfdsf", null); + assertNull(res); + } + + public void testBoxOk2() throws Exception { + Rectangle res = PageBoundariesAttributes.getRectangle("-10pt", TEST_AREA); + assertEquals("Expected equal objects", res, TEST_AREA); + } + + public void testBoxOk3() throws Exception { + Rectangle res = PageBoundariesAttributes.getRectangle("-10pt -10pt", TEST_AREA); + assertEquals("Expected equal objects", res, TEST_AREA); + } + + public void testBoxOk4() throws Exception { + Rectangle res = PageBoundariesAttributes.getRectangle("0pt 0pt 100000pt", TEST_AREA); + assertEquals("Expected equal objects", res, TEST_AREA); + } + + public void testBoxOk5() throws Exception { + Rectangle res = PageBoundariesAttributes.getRectangle("-1pt -1pt 100000pt 100000pt", TEST_AREA); + assertEquals("Expected equal objects", res, TEST_AREA); + } + + public void testBoxIllArgExc() throws Exception { + try { + Rectangle res = PageBoundariesAttributes.getRectangle("0", TEST_AREA); + fail("Expected IllegalArgumentException. Box should have units"); + } catch (IllegalArgumentException iae) { + // Good! + } + } +} Property changes on: test/java/org/apache/fop/render/extensions/PrepressTest.java ___________________________________________________________________ Added: svn:keywords + Revision Id Added: svn:eol-style + native Index: test/java/org/apache/fop/StandardTestSuite.java =================================================================== --- test/java/org/apache/fop/StandardTestSuite.java (revision 798097) +++ 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; } 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,106 @@ +/* + * 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$ */ + +package org.apache.fop.render.extensions.prepress; + +import java.awt.Rectangle; +import java.text.MessageFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.xmlgraphics.util.QName; + +import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.fo.properties.FixedLength; + + +/** + * This class contains definition of page boundaries FOP's extension attributes for XSL-FO. + * That is: bleedBox, trimBox and cropBox. + * Also this class provides method to parse the possible values of these attributes + * and to generate original size of bounded area + */ +public final class PageBoundariesAttributes { + + /** + * The extension attribute for the PDF BleedBox area + */ + public static final QName EXT_BLEED_BOX + = new QName(ExtensionElementMapping.URI, null, "bleed-box"); + + /** + * The extension attribute for the PDF TrimBox area + */ + public static final QName EXT_TRIM_BOX + = new QName(ExtensionElementMapping.URI, null, "trim-box"); + + /** + * 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)$"); + + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+"); + + /** + * Utility classes should not have a public or default constructor + */ + private PageBoundariesAttributes() { + } + + + + /** + * Calculates the original size of extension box attributes + * @param coord string that contains coordinates of box area, + * format: left [right [ width [height]]]] + * @param bounds the outer area containing given box. The box should be in this area completely + * @return the rectangle from the given coordinates, check that it is in the given bounds + */ + public static Rectangle getRectangle(String coord, Rectangle bounds) { + assert bounds != null; + final String err = "Extension box variable has incorrect size values: {0}"; + + // if this box is undefined then we will return the outer box coordinates + if (coord == null) { + return bounds; + } + + String[] tmp = WHITESPACE_PATTERN.split(coord); + if (tmp.length > 4) { + throw new IllegalArgumentException("Too many arguments"); + } + int[] coordinates = {bounds.x, bounds.y, bounds.width, bounds.height}; + for (int i = 0; i < tmp.length; i++) { + Matcher m = SIZE_UNIT_PATTERN.matcher(tmp[i]); + if (m.find()) { + coordinates[i] = FixedLength.getInstance(Double.parseDouble(m.group(1)), m.group(2)) + .getLength().getValue(); + } else { + throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{coord})); + } + } + return bounds.intersection(new Rectangle(coordinates[0], coordinates[1], coordinates[2], + coordinates[3])); + } +} Property changes on: src/java/org/apache/fop/render/extensions/prepress/PageBoundariesAttributes.java ___________________________________________________________________ Added: svn:keywords + Revision Id Added: svn:eol-style + native 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$ */ + +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; + } +} Property changes on: src/java/org/apache/fop/render/extensions/prepress/PageScaleAttributes.java ___________________________________________________________________ Added: svn:keywords + Revision Id Added: svn:eol-style + native Index: src/java/org/apache/fop/render/java2d/Java2DRenderer.java =================================================================== --- src/java/org/apache/fop/render/java2d/Java2DRenderer.java (revision 798097) +++ src/java/org/apache/fop/render/java2d/Java2DRenderer.java (working copy) @@ -24,6 +24,7 @@ import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; @@ -75,6 +76,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.PageBoundariesAttributes; +import org.apache.fop.render.extensions.prepress.PageScaleAttributes; import org.apache.fop.render.pdf.CTMHelper; import org.apache.fop.util.CharUtilities; import org.apache.fop.util.ColorUtil; @@ -290,7 +293,7 @@ this.currentPageViewport = pageViewport; try { - Rectangle2D bounds = pageViewport.getViewArea(); + Rectangle bounds = pageViewport.getViewArea(); this.pageWidth = (int) Math.round(bounds.getWidth() / 1000f); this.pageHeight = (int) Math.round(bounds.getHeight() / 1000f); @@ -299,11 +302,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 +344,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 @@ -353,7 +371,17 @@ state = null; } - return currentPageImage; + // crop the bitmap image using cropBox extension page attribute + String crop = (String) currentPageViewport.getForeignAttributes().get( + PageBoundariesAttributes.EXT_CROP_BOX); + Rectangle cropArea = PageBoundariesAttributes.getRectangle(crop, + currentPageViewport.getViewArea()); + + return currentPageImage.getSubimage( + (int) (cropArea.x / 1000 * scaleX), + (int) (bitmapHeight - (cropArea.y + cropArea.height) / 1000 * scaleY), + (int) (cropArea.getWidth() / 1000f * scaleX), + (int) (cropArea.getHeight() / 1000f * scaleY)); } finally { this.currentPageViewport = null; } Index: src/java/org/apache/fop/render/pdf/PDFEventProducer.java =================================================================== --- src/java/org/apache/fop/render/pdf/PDFEventProducer.java (revision 798097) +++ src/java/org/apache/fop/render/pdf/PDFEventProducer.java (working copy) @@ -30,9 +30,14 @@ public interface PDFEventProducer extends EventProducer { /** Provider class for the event producer. */ - class Provider { + final class Provider { /** + * Utility classes should not have a public or default constructor. + */ + private Provider() { } + + /** * Returns an event producer. * @param broadcaster the event broadcaster to use * @return the event producer Index: src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java =================================================================== --- src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (revision 798097) +++ src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java (working copy) @@ -20,7 +20,10 @@ package org.apache.fop.render.pdf; import java.awt.Dimension; +import java.awt.Rectangle; import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.Map; @@ -37,6 +40,8 @@ import org.apache.fop.pdf.PDFReference; import org.apache.fop.pdf.PDFResourceContext; import org.apache.fop.pdf.PDFResources; +import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes; +import org.apache.fop.render.extensions.prepress.PageScaleAttributes; import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler; import org.apache.fop.render.intermediate.IFContext; import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator; @@ -166,11 +171,49 @@ throws IFException { this.pdfResources = this.pdfDoc.getResources(); + String crop = (String) getContext().getForeignAttribute( + PageBoundariesAttributes.EXT_CROP_BOX); + String bleed = (String) getContext().getForeignAttribute( + PageBoundariesAttributes.EXT_BLEED_BOX); + String trim = (String) getContext().getForeignAttribute( + PageBoundariesAttributes.EXT_TRIM_BOX); + // make sure that CropBox in the MediaBox + Rectangle cropBox = PageBoundariesAttributes.getRectangle(crop, + new Rectangle(0, 0, size.width, size.height)); + // make sure that BleedBox in the CropBox + Rectangle bleedBox = PageBoundariesAttributes.getRectangle(bleed, cropBox); + // make sure that TrimBox in the BleedBox + Rectangle trimBox = PageBoundariesAttributes.getRectangle(trim, bleedBox); + + // 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); + index, + new Rectangle2D.Double(0, 0, + (scaleX * size.getWidth()) / 1000, + (scaleY * size.getHeight()) / 1000), + new Rectangle2D.Double((scaleX * cropBox.getX()) / 1000, + (scaleY * cropBox.getY()) / 1000, + (scaleX * cropBox.getWidth()) / 1000, + (scaleY * cropBox.getHeight()) / 1000), + new Rectangle2D.Double((scaleX * bleedBox.getX()) / 1000, + (scaleY * bleedBox.getY()) / 1000, + (scaleX * bleedBox.getWidth()) / 1000, + (scaleY * bleedBox.getHeight()) / 1000), + new Rectangle2D.Double((scaleX * trimBox.getX()) / 1000, + (scaleY * trimBox.getY()) / 1000, + (scaleX * trimBox.getWidth()) / 1000, + (scaleY * trimBox.getHeight()) / 1000)); //pageReferences.put(new Integer(index)/*page.getKey()*/, currentPage.referencePDF()); //pvReferences.put(page.getKey(), page); @@ -182,7 +225,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: src/java/org/apache/fop/layoutmgr/Page.java =================================================================== --- src/java/org/apache/fop/layoutmgr/Page.java (revision 798097) +++ src/java/org/apache/fop/layoutmgr/Page.java (working copy) @@ -19,7 +19,7 @@ package org.apache.fop.layoutmgr; -import java.awt.geom.Rectangle2D; +import java.awt.Rectangle; import org.apache.fop.area.PageViewport; import org.apache.fop.fo.pagination.SimplePageMaster; @@ -54,7 +54,7 @@ * @param pageNumberStr the page number (as a String) * @param blank true if this is a blank page */ - public Page(Rectangle2D viewArea, int pageNumber, String pageNumberStr, boolean blank) { + public Page(Rectangle viewArea, int pageNumber, String pageNumberStr, boolean blank) { this.spm = null; this.pageViewport = new PageViewport(viewArea, pageNumber, pageNumberStr, null, blank); } Index: src/java/org/apache/fop/area/AreaTreeParser.java =================================================================== --- src/java/org/apache/fop/area/AreaTreeParser.java (revision 798097) +++ src/java/org/apache/fop/area/AreaTreeParser.java (working copy) @@ -20,6 +20,7 @@ package org.apache.fop.area; import java.awt.Color; +import java.awt.Rectangle; import java.awt.geom.Rectangle2D; import java.io.FileNotFoundException; import java.io.IOException; @@ -38,9 +39,10 @@ import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; - import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; @@ -48,9 +50,6 @@ import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.apache.xmlgraphics.image.loader.ImageException; import org.apache.xmlgraphics.image.loader.ImageInfo; import org.apache.xmlgraphics.image.loader.ImageManager; @@ -403,7 +402,7 @@ if (currentPageViewport != null) { throw new IllegalStateException("currentPageViewport must be null"); } - Rectangle2D viewArea = XMLUtil.getAttributeAsRectangle2D(attributes, "bounds"); + Rectangle viewArea = XMLUtil.getAttributeAsRectangle(attributes, "bounds"); int pageNumber = XMLUtil.getAttributeAsInt(attributes, "nr", -1); String key = attributes.getValue("key"); String pageNumberString = attributes.getValue("formatted-nr"); Index: src/java/org/apache/fop/area/PageViewport.java =================================================================== --- src/java/org/apache/fop/area/PageViewport.java (revision 798097) +++ src/java/org/apache/fop/area/PageViewport.java (working copy) @@ -20,7 +20,6 @@ package org.apache.fop.area; import java.awt.Rectangle; -import java.awt.geom.Rectangle2D; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -48,7 +47,7 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneable { private Page page; - private Rectangle2D viewArea; + private Rectangle viewArea; private String simplePageMasterName; /** @@ -100,6 +99,7 @@ public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, boolean blank) { this.simplePageMasterName = spm.getMasterName(); setExtensionAttachments(spm.getExtensionAttachments()); + setForeignAttributes(spm.getForeignAttributes()); this.blank = blank; int pageWidth = spm.getPageWidth().getValue(); int pageHeight = spm.getPageHeight().getValue(); @@ -118,11 +118,14 @@ if (original.extensionAttachments != null) { setExtensionAttachments(original.extensionAttachments); } + if (original.foreignAttributes != null) { + setForeignAttributes(original.foreignAttributes); + } this.pageIndex = original.pageIndex; this.pageNumber = original.pageNumber; this.pageNumberString = original.pageNumberString; this.page = (Page)original.page.clone(); - this.viewArea = (Rectangle2D)original.viewArea.clone(); + this.viewArea = new Rectangle(original.viewArea); this.simplePageMasterName = original.simplePageMasterName; this.blank = original.blank; } @@ -135,7 +138,7 @@ * @param simplePageMasterName name of the original simple-page-master that generated this page * @param blank true if this is a blank page */ - public PageViewport(Rectangle2D viewArea, int pageNumber, String pageStr, + public PageViewport(Rectangle viewArea, int pageNumber, String pageStr, String simplePageMasterName, boolean blank) { this.viewArea = viewArea; this.pageNumber = pageNumber; @@ -161,7 +164,7 @@ * Get the view area rectangle of this viewport. * @return the rectangle for this viewport */ - public Rectangle2D getViewArea() { + public Rectangle getViewArea() { return viewArea; } Index: src/java/org/apache/fop/pdf/PDFFactory.java =================================================================== --- src/java/org/apache/fop/pdf/PDFFactory.java (revision 798097) +++ src/java/org/apache/fop/pdf/PDFFactory.java (working copy) @@ -174,22 +174,19 @@ * PDFDocument later using addObject(). * * @param resources resources object to use - * @param pageWidth width of the page in points - * @param pageHeight height of the page in points * @param pageIndex index of the page (zero-based) + * @param mediaBox the MediaBox area + * @param cropBox the CropBox area + * @param bleedBox the BleedBox area + * @param trimBox the TrimBox area * * @return the created /Page object */ - public PDFPage makePage(PDFResources resources, - int pageWidth, int pageHeight, int pageIndex) { + public PDFPage makePage(PDFResources resources, int pageIndex, + Rectangle2D mediaBox, Rectangle2D cropBox, + Rectangle2D bleedBox, Rectangle2D trimBox) { + PDFPage page = new PDFPage(resources, pageIndex, mediaBox, cropBox, bleedBox, trimBox); - /* - * create a PDFPage with the next object number, the given - * resources, contents and dimensions - */ - PDFPage page = new PDFPage(resources, - pageWidth, pageHeight, pageIndex); - getDocument().assignObjectNumber(page); getDocument().getPages().addPage(page); return page; @@ -203,10 +200,28 @@ * @param resources resources object to use * @param pageWidth width of the page in points * @param pageHeight height of the page in points + * @param pageIndex index of the page (zero-based) * * @return the created /Page object */ public PDFPage makePage(PDFResources resources, + int pageWidth, int pageHeight, int pageIndex) { + Rectangle2D mediaBox = new Rectangle2D.Double(0, 0, pageWidth, pageHeight); + return makePage(resources, pageIndex, mediaBox, mediaBox, mediaBox, mediaBox); + } + + /** + * Make a /Page object. The page is assigned an object number immediately + * so references can already be made. The page must be added to the + * PDFDocument later using addObject(). + * + * @param resources resources object to use + * @param pageWidth width of the page in points + * @param pageHeight height of the page in points + * + * @return the created /Page object + */ + public PDFPage makePage(PDFResources resources, int pageWidth, int pageHeight) { return makePage(resources, pageWidth, pageHeight, -1); } Index: src/java/org/apache/fop/pdf/PDFPage.java =================================================================== --- src/java/org/apache/fop/pdf/PDFPage.java (revision 798097) +++ src/java/org/apache/fop/pdf/PDFPage.java (working copy) @@ -38,42 +38,42 @@ * Create a /Page object * * @param resources the /Resources object - * @param contents the content stream - * @param pageWidth the page's width in points - * @param pageHeight the page's height in points * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined) + * @param mediaBox the MediaBox + * @param cropBox the CropBox. If null, mediaBox is used. + * @param bleedBox the BleedBox. If null, cropBox is used. + * @param trimBox the TrimBox. If null, bleedBox is used. */ - public PDFPage(PDFResources resources, PDFStream contents, - int pageWidth, int pageHeight, int pageIndex) { + public PDFPage(PDFResources resources, int pageIndex, + Rectangle2D mediaBox, Rectangle2D cropBox, + Rectangle2D bleedBox, Rectangle2D trimBox) { + /* generic creation of object */ + super(resources); - /* generic creation of object */ - super(resources); - - put("Type", new PDFName("Page")); - /* set fields using parameters */ - setContents(contents); - setSimplePageSize(pageWidth, pageHeight); - this.pageIndex = pageIndex; + put("Type", new PDFName("Page")); + /* set fields using parameters */ + setSimplePageSize(mediaBox, cropBox, bleedBox, trimBox); + this.pageIndex = pageIndex; } - /** - * Create a /Page object - * - * @param resources the /Resources object - * @param pageWidth the page's width in points - * @param pageHeight the page's height in points - * @param pageIndex the page's zero-based index (or -1 if the page number is auto-determined) - */ - public PDFPage(PDFResources resources, - int pageWidth, int pageHeight, int pageIndex) { - this(resources, null, pageWidth, pageHeight, pageIndex); - } + private void setSimplePageSize(Rectangle2D mediaBox, Rectangle2D cropBox, + Rectangle2D bleedBox, Rectangle2D trimBox) { + setMediaBox(mediaBox); - private void setSimplePageSize(int width, int height) { - Rectangle2D box = new Rectangle2D.Double(0, 0, width, height); - setMediaBox(box); - setBleedBox(box); //Recommended by PDF/X - setTrimBox(box); //Needed for PDF/X + if (cropBox == null) { + cropBox = mediaBox; + } + setCropBox(cropBox); + + if (bleedBox == null) { + bleedBox = cropBox; + } + setBleedBox(bleedBox); //Recommended by PDF/X + + if (trimBox == null) { + trimBox = bleedBox; + } + setTrimBox(trimBox); //Needed for PDF/X } private PDFArray toPDFArray(Rectangle2D box) { @@ -90,11 +90,11 @@ } /** - * Sets the "TrimBox" entry - * @param box the trim rectangle + * Sets the "CropBox" entry + * @param box the bleed rectangle */ - public void setTrimBox(Rectangle2D box) { - put("TrimBox", toPDFArray(box)); + public void setCropBox(Rectangle2D box) { + put("CropBox", toPDFArray(box)); } /** @@ -106,6 +106,14 @@ } /** + * Sets the "TrimBox" entry + * @param box the trim rectangle + */ + public void setTrimBox(Rectangle2D box) { + put("TrimBox", toPDFArray(box)); + } + + /** * set this page contents * * @param contents the contents of the page Index: src/documentation/content/xdocs/trunk/extensions.xml =================================================================== --- src/documentation/content/xdocs/trunk/extensions.xml (revision 798097) +++ src/documentation/content/xdocs/trunk/extensions.xml (working copy) @@ -227,7 +227,33 @@
- +
+ fox:scale="sx [sy]"
attribute is used in fo:simple-page-master
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.
+
+ The box attributes which specify the CropBox, TrimBox and BleedBox parameters of PDF page.
+ These box attributes of fo:simple-page-master
element can consist out of up to 4 numeric values
+ (top, left, width, height) and should have units as suffix to each of the numbers.
+
+ Examples:
+ fox:trim-box="10pt 10pt 100pt 100pt"
would create TrimBox starting in (10pt, 10pt) point with width=100pt and height=100pt.
+ fox:crop-box="5px 5px"
would create CropBox starting in (5px, 5px) point with width and height equal of original page minus 5px.
+