Browse Source

Bugzilla #47311:

Fixed typos.
Bugfix: when crop-offset wasn't specified, but bleed was, the media box was wrong.
Tried to fix encapsulation problem mentioned by Vincent.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@800401 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_0
Jeremias Maerki 15 years ago
parent
commit
837d5f3d51

src/java/org/apache/fop/render/extensions/prepress/PageBoundariesAttributes.java → src/java/org/apache/fop/render/extensions/prepress/PageBoundaries.java View File

@@ -19,8 +19,10 @@

package org.apache.fop.render.extensions.prepress;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.text.MessageFormat;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@@ -29,29 +31,27 @@ 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 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 attributes
* and to generate original size of bounded area.
* This class is used to calculate the effective boundaries of a page including special-purpose
* boxes used in prepress. These are specified using extension attributes:
* bleedBox, trimBox and cropBox. The semantics are further described on the website.
*/
public final class PageBoundariesAttributes {
public class PageBoundaries {

/**
* The extension attribute for calculating the PDF BleedBox area - specifies the bleed width
* 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
* 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
* The extension attribute for the PDF CropBox area.
*/
public static final QName EXT_CROP_BOX
= new QName(ExtensionElementMapping.URI, null, "crop-box");
@@ -60,10 +60,98 @@ public final class PageBoundariesAttributes {
private static final Pattern SIZE_UNIT_PATTERN
= Pattern.compile("^(-?\\d*\\.?\\d*)(px|in|cm|mm|pt|pc|mpt)$");

private Rectangle trimBox;
private Rectangle bleedBox;
private Rectangle mediaBox;
private Rectangle cropBox;

/**
* Creates a new instance.
* @param pageSize the page size (in mpt) defined by the simple-page-master.
* @param bleed the bleed value (raw value as given in the property value)
* @param cropOffset the crop-offset value (raw value as given in the property value)
* @param cropBoxSelector the crop-box, valid values: (trim-box|bleed-box|media-box)
*/
public PageBoundaries(Dimension pageSize, String bleed, String cropOffset,
String cropBoxSelector) {
calculate(pageSize, bleed, cropOffset, cropBoxSelector);
}

/**
* Creates a new instance.
* @param pageSize the page size (in mpt) defined by the simple-page-master.
* @param foreignAttributes the foreign attributes for the page
* (used to extract the extension attribute values)
*/
public PageBoundaries(Dimension pageSize, Map foreignAttributes) {
String bleed = (String)foreignAttributes.get(EXT_BLEED);
String cropOffset = (String)foreignAttributes.get(EXT_CROP_OFFSET);
String cropBoxSelector = (String)foreignAttributes.get(EXT_CROP_BOX);
calculate(pageSize, bleed, cropOffset, cropBoxSelector);
}

private void calculate(Dimension pageSize, String bleed, String cropOffset,
String cropBoxSelector) {
this.trimBox = new Rectangle(pageSize);
this.bleedBox = getBleedBoxRectangle(this.trimBox, bleed);
Rectangle cropMarksBox = getCropMarksAreaRectangle(trimBox, cropOffset);

//MediaBox includes all of the following three rectangles
this.mediaBox = new Rectangle();
this.mediaBox.add(this.trimBox);
this.mediaBox.add(this.bleedBox);
this.mediaBox.add(cropMarksBox);

if ("trim-box".equals(cropBoxSelector)) {
this.cropBox = this.trimBox;
} else if ("bleed-box".equals(cropBoxSelector)) {
this.cropBox = this.bleedBox;
} else if ("media-box".equals(cropBoxSelector)
|| cropBoxSelector == null
|| "".equals(cropBoxSelector)) {
this.cropBox = this.mediaBox;
} else {
final String err = "The crop-box has invalid value: {0}, "
+ "possible values of crop-box: (trim-box|bleed-box|media-box)";
throw new IllegalArgumentException(MessageFormat.format(err,
new Object[]{cropBoxSelector}));
}
}

/**
* Utility classes should not have a public or default constructor.
* Returns the trim box for the page. This is equal to the page size given in XSL-FO.
* After production the printed media is trimmed to this rectangle.
* @return the trim box
*/
private PageBoundariesAttributes() {
public Rectangle getTrimBox() {
return this.trimBox;
}

/**
* Returns the bleed box for the page.
* @return the bleed box
*/
public Rectangle getBleedBox() {
return this.bleedBox;
}

/**
* Returns the media box for the page.
* @return the media box
*/
public Rectangle getMediaBox() {
return this.mediaBox;
}

/**
* Returns the crop box for the page. The crop box is used by Adobe Acrobat to select which
* parts of the document shall be displayed and it also defines the rectangle to which a
* RIP will clip the document. For bitmap output, this defines the size of the size of
* the bitmap.
* @return the crop box
*/
public Rectangle getCropBox() {
return this.cropBox;
}

/**
@@ -84,67 +172,17 @@ public final class PageBoundariesAttributes {
* @param cropOffsets the given crop offsets
* @return the calculated MediaBox rectangle
*/
public static Rectangle getMediaBoxRectangle(Rectangle trimBox, String cropOffsets) {
public static Rectangle getCropMarksAreaRectangle(Rectangle trimBox, String cropOffsets) {
return getRectagleUsingOffset(trimBox, 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(trimBox, 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
int[] coords = new int[4]; // top, right, bottom, left
if (bleeds.length == 1) {
coords[0] = getLengthIntValue(bleeds[0]);
coords[1] = coords[0];
@@ -183,4 +221,5 @@ public final class PageBoundariesAttributes {
throw new IllegalArgumentException(MessageFormat.format(err, new Object[]{length}));
}
}

}

+ 4
- 6
src/java/org/apache/fop/render/extensions/prepress/PageScaleAttributes.java View File

@@ -26,15 +26,13 @@ import org.apache.xmlgraphics.util.QName;

import org.apache.fop.fo.extensions.ExtensionElementMapping;


/**
* 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
* This class provides utility methods to parse the 'fox:scale' extension attribute.
*/
public final class PageScaleAttributes {

/**
* The extension 'scale' attribute for simple-page-master element
* The extension 'scale' attribute for the simple-page-master element.
*/
public static final QName EXT_PAGE_SCALE
= new QName(ExtensionElementMapping.URI, null, "scale");
@@ -47,8 +45,8 @@ public final class PageScaleAttributes {
}

/**
* Compute scale parameters from given fox:scale attribute which has format: scaleX [scaleY]
* If scaleY is not defined, it equals scaleX
* Compute scale parameters from given fox:scale attribute which has the 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
*/

+ 6
- 16
src/java/org/apache/fop/render/java2d/Java2DRenderer.java View File

@@ -24,6 +24,7 @@ import java.awt.BasicStroke;
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,7 +76,7 @@ import org.apache.fop.fonts.Typeface;
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.PageBoundaries;
import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
import org.apache.fop.render.pdf.CTMHelper;
import org.apache.fop.util.CharUtilities;
@@ -292,20 +293,10 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem

this.currentPageViewport = pageViewport;
try {
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
);
Rectangle2D bleedBox = PageBoundariesAttributes.getBleedBoxRectangle(
pageViewport.getViewArea(), bleed);
PageBoundaries boundaries = new PageBoundaries(
pageViewport.getViewArea().getSize(), pageViewport.getForeignAttributes());
Rectangle bounds = boundaries.getCropBox();
Rectangle bleedBox = boundaries.getBleedBox();
this.pageWidth = (int) Math.round(bounds.getWidth() / 1000f);
this.pageHeight = (int) Math.round(bounds.getHeight() / 1000f);

@@ -325,7 +316,6 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
scaleY *= scales.getY();
}


scaleX = scaleX
* (25.4f / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
/ userAgent.getTargetPixelUnitToMillimeter();

+ 18
- 32
src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java View File

@@ -24,6 +24,7 @@ import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Rectangle2D.Double;
import java.io.IOException;
import java.util.Map;

@@ -40,7 +41,7 @@ import org.apache.fop.pdf.PDFPage;
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.PageBoundaries;
import org.apache.fop.render.extensions.prepress.PageScaleAttributes;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFContext;
@@ -171,22 +172,12 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
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);
PageBoundaries boundaries = new PageBoundaries(size, getContext().getForeignAttributes());

Rectangle trimBox = new Rectangle(0, 0,
(int) size.getWidth(), (int) size.getHeight());
Rectangle bleedBox
= PageBoundariesAttributes.getBleedBoxRectangle(trimBox, bleedWidth);
Rectangle mediaBox
= PageBoundariesAttributes.getMediaBoxRectangle(trimBox, cropOffset);

Rectangle cropBox = PageBoundariesAttributes.getCropBoxRectangle(
trimBox, bleedBox, mediaBox, cropBoxValue);
Rectangle trimBox = boundaries.getTrimBox();
Rectangle bleedBox = boundaries.getBleedBox();
Rectangle mediaBox = boundaries.getMediaBox();
Rectangle cropBox = boundaries.getCropBox();

// set scale attributes
double scaleX = 1;
@@ -202,22 +193,10 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
this.currentPage = this.pdfDoc.getFactory().makePage(
this.pdfResources,
index,
new Rectangle2D.Double(mediaBox.getX() * scaleX / 1000,
mediaBox.getY() * scaleY / 1000,
mediaBox.getWidth() * scaleX / 1000,
mediaBox.getHeight() * scaleY / 1000),
new Rectangle2D.Double(cropBox.getX() * scaleX / 1000,
cropBox.getY() * scaleY / 1000,
cropBox.getWidth() * scaleX / 1000,
cropBox.getHeight() * scaleY / 1000),
new Rectangle2D.Double(bleedBox.getX() * scaleX / 1000,
bleedBox.getY() * scaleY / 1000,
bleedBox.getWidth() * scaleX / 1000,
bleedBox.getHeight() * scaleY / 1000),
new Rectangle2D.Double(trimBox.getX() * scaleX / 1000,
trimBox.getY() * scaleY / 1000,
trimBox.getWidth() * scaleX / 1000,
trimBox.getHeight() * scaleY / 1000));
toPointAndScale(mediaBox, scaleX, scaleY),
toPointAndScale(cropBox, scaleX, scaleY),
toPointAndScale(bleedBox, scaleX, scaleY),
toPointAndScale(trimBox, scaleX, scaleY));

pdfUtil.generatePageLabel(index, name);

@@ -232,6 +211,13 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
generator.concatenate(basicPageTransform);
}

private Double toPointAndScale(Rectangle box, double scaleX, double scaleY) {
return new Rectangle2D.Double(box.getX() * scaleX / 1000,
box.getY() * scaleY / 1000,
box.getWidth() * scaleX / 1000,
box.getHeight() * scaleY / 1000);
}

/** {@inheritDoc} */
public IFPainter startPageContent() throws IFException {
return new PDFPainter(this);

+ 44
- 32
test/java/org/apache/fop/render/extensions/PrepressTest.java View File

@@ -24,7 +24,7 @@ import java.awt.geom.Point2D;

import junit.framework.TestCase;

import org.apache.fop.render.extensions.prepress.PageBoundariesAttributes;
import org.apache.fop.render.extensions.prepress.PageBoundaries;
import org.apache.fop.render.extensions.prepress.PageScaleAttributes;

/**
@@ -80,47 +80,59 @@ public class PrepressTest extends TestCase {
* Tests for page boundaries
*/
public void testBoxOk1() throws Exception {
Rectangle res = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, null);
Rectangle res = PageBoundaries.getBleedBoxRectangle(TEST_AREA, null);
assertSame("Result should be the same as TEST_AREA object", res, TEST_AREA);

res = PageBoundariesAttributes.getBleedBoxRectangle(null, BLEED1);
res = PageBoundaries.getBleedBoxRectangle(null, BLEED1);
assertNull(res);
}

public void testBoxOk2() throws Exception {
Rectangle res1 = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, BLEED1);
assertNotNull("Expected not null object", res1);
assertEquals(-5000, res1.getX(), 1);
assertEquals(-5000, res1.getY(), 1);
assertEquals(30000, res1.getWidth(), 1);
assertEquals(25000, res1.getHeight(), 1);

Rectangle res2 = PageBoundariesAttributes.getMediaBoxRectangle(TEST_AREA, CROP_OFFSET1);
assertNotNull("Expected not null object", res2);
assertEquals(-8000, res2.getX(), 1);
assertEquals(-8000, res2.getY(), 1);
assertEquals(36000, res2.getWidth(), 1);
assertEquals(31000, res2.getHeight(), 1);

Rectangle res3 = PageBoundariesAttributes.getCropBoxRectangle(
TEST_AREA, res1, res2, "media-box");
assertNotNull("Expected not null object", res3);
assertEquals(res3, res2);

res3 = PageBoundariesAttributes.getCropBoxRectangle(
TEST_AREA, res1, res2, "bleed-box");
assertNotNull("Expected not null object", res3);
assertEquals(res3, res1);

res3 = PageBoundariesAttributes.getCropBoxRectangle(
TEST_AREA, res1, res2, "trim-box");
assertNotNull("Expected not null object", res3);
assertEquals(res3, TEST_AREA);
PageBoundaries boundaries = new PageBoundaries(
TEST_AREA.getSize(), BLEED1, CROP_OFFSET1, null);
assertNotNull("Expected not null object", boundaries.getBleedBox());
assertEquals(-5000, boundaries.getBleedBox().getX(), 1);
assertEquals(-5000, boundaries.getBleedBox().getY(), 1);
assertEquals(30000, boundaries.getBleedBox().getWidth(), 1);
assertEquals(25000, boundaries.getBleedBox().getHeight(), 1);

assertNotNull("Expected not null object", boundaries.getMediaBox());
assertEquals(-8000, boundaries.getMediaBox().getX(), 1);
assertEquals(-8000, boundaries.getMediaBox().getY(), 1);
assertEquals(36000, boundaries.getMediaBox().getWidth(), 1);
assertEquals(31000, boundaries.getMediaBox().getHeight(), 1);

assertEquals(TEST_AREA, boundaries.getTrimBox());
assertEquals(boundaries.getMediaBox(), boundaries.getCropBox());

boundaries = new PageBoundaries(
TEST_AREA.getSize(), BLEED1, CROP_OFFSET1, "media-box");
assertEquals(boundaries.getMediaBox(), boundaries.getCropBox());

boundaries = new PageBoundaries(
TEST_AREA.getSize(), BLEED1, CROP_OFFSET1, "bleed-box");
assertEquals(boundaries.getBleedBox(), boundaries.getCropBox());

boundaries = new PageBoundaries(
TEST_AREA.getSize(), BLEED1, CROP_OFFSET1, "trim-box");
assertEquals(boundaries.getTrimBox(), boundaries.getCropBox());
assertEquals(TEST_AREA, boundaries.getCropBox());

boundaries = new PageBoundaries(
TEST_AREA.getSize(), BLEED1, null, null);
assertNotNull("Expected not null object", boundaries.getBleedBox());
assertEquals(-5000, boundaries.getBleedBox().getX(), 1);
assertEquals(-5000, boundaries.getBleedBox().getY(), 1);
assertEquals(30000, boundaries.getBleedBox().getWidth(), 1);
assertEquals(25000, boundaries.getBleedBox().getHeight(), 1);
assertEquals(boundaries.getBleedBox(), boundaries.getCropBox());
assertEquals(boundaries.getBleedBox(), boundaries.getMediaBox());
}

public void testBoxIllArgExc() throws Exception {
try {
Rectangle res = PageBoundariesAttributes.getBleedBoxRectangle(TEST_AREA, "0");
PageBoundaries boundaries = new PageBoundaries(
TEST_AREA.getSize(), "0", null, null);
fail("Expected IllegalArgumentException. Box should have units");
} catch (IllegalArgumentException iae) {
// Good!

Loading…
Cancel
Save