diff options
author | Joao Goncalves <jgoncalves@smartcommunications.com> | 2024-12-30 12:41:32 -0600 |
---|---|---|
committer | Joao Goncalves <jgoncalves@smartcommunications.com> | 2024-12-30 12:41:32 -0600 |
commit | e4cd07daa55ade2f0b8274c04f068fde8ec25006 (patch) | |
tree | 1bec010c917365ac6cbee7be8c5cf79a7ded0b3c | |
parent | d0c8f243f4bc0f8eb3e964a780590d528034260c (diff) | |
download | xmlgraphics-fop-e4cd07daa55ade2f0b8274c04f068fde8ec25006.tar.gz xmlgraphics-fop-e4cd07daa55ade2f0b8274c04f068fde8ec25006.zip |
-rw-r--r-- | fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java | 13 | ||||
-rw-r--r-- | fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java | 104 |
2 files changed, 104 insertions, 13 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java index 5478f4490..c513e61ca 100644 --- a/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java @@ -87,6 +87,8 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> { private final LanguageAvailabilityChecker languageAvailabilityChecker; + private AffineTransform viewportContentArea; + private static class LanguageAvailabilityChecker { private final IFContext context; @@ -144,6 +146,7 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> { throws IFException { generator.saveGraphicsState(); generator.concatenate(toPoints(transform)); + this.viewportContentArea = transform; if (clipRect != null) { clipRect(clipRect); } @@ -192,10 +195,16 @@ public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> { if (structElem != null) { //structElem is null if the image is marked as an artifact PDFDictionary d = new PDFDictionary(); int x = rect.x / 1000; - int y = rect.y / 1000; + int y = (getDocumentHandler().getCurrentPageRef().getPageDimension().height - rect.y) / 1000; int w = rect.width / 1000; int h = rect.height / 1000; - d.put("BBox", new PDFArray(x, y, w, h)); + + if (viewportContentArea != null) { + x += (int) viewportContentArea.getTranslateX() / 1000; + y -= (int) viewportContentArea.getTranslateY() / 1000; + } + + d.put("BBox", new PDFArray(x, y - h, x + w, y)); d.put("O", new PDFName("Layout")); structElem.put("A", d); } diff --git a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java index c2d9a325b..c814029de 100644 --- a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java @@ -22,6 +22,7 @@ package org.apache.fop.render.pdf; import java.awt.Color; import java.awt.Dimension; import java.awt.Rectangle; +import java.awt.geom.AffineTransform; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -37,6 +38,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.endsWith; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.mock; @@ -77,6 +79,18 @@ import org.apache.fop.traits.BorderProps; public class PDFPainterTestCase { + private static final int PAGE_WIDTH = 100000; + + private static final int PAGE_HEIGHT = 100000; + + private static final int IMAGE_X = 10000; + + private static final int IMAGE_Y = 15000; + + private static final int IMAGE_WIDTH = 20000; + + private static final int IMAGE_HEIGHT = 20000; + private FOUserAgent foUserAgent; private PDFContentGenerator pdfContentGenerator; private PDFDocumentHandler pdfDocumentHandler; @@ -335,35 +349,103 @@ public class PDFPainterTestCase { } @Test - public void testPDFUAImage() throws IFException, IOException { + public void testPDFUAImage() throws IOException, IFException { + String output = defaultTestPDFUAImage(new Dimension(), new Rectangle(), new AffineTransform()); + assertTrue("The page dimensions and the image position is not set", + output.contains("/BBox [0 0 0 0]")); + } + + @Test + public void testPDFUAImageWithoutPageRegionMargins() throws IOException, IFException { + defaultTestPDFUAImageWithImagePosition(new AffineTransform()); + } + + @Test + public void testPDFUAImageWithPageWithRegionMargins() throws IOException, IFException { + defaultTestPDFUAImageWithImagePosition(new AffineTransform(0d, 0d, 0d, 0d, 5000d, 5000d)); + } + + @Test + public void testPDFUAImageNullPageRegionMargins() throws IOException, IFException { + defaultTestPDFUAImageWithImagePosition(null); + } + + private void defaultTestPDFUAImageWithImagePosition(AffineTransform transform) throws IOException, IFException { + String output = defaultTestPDFUAImage(new Dimension(PAGE_WIDTH, PAGE_HEIGHT), + new Rectangle(IMAGE_X, IMAGE_Y, IMAGE_WIDTH, IMAGE_HEIGHT), transform); + + int rectX = 0; + int rectY = 0; + if (transform != null) { + rectX = (int) transform.getTranslateX(); + rectY = (int) transform.getTranslateY(); + } + + output = output.substring(output.indexOf("[") + 1); + output = output.substring(0, output.indexOf("]")); + + String[] array = output.split(" "); + + // on the X axis, 0 is on the left + // on the Y axis, 0 is at the bottom + int position = (IMAGE_X + rectX) / 1000; + assertEquals("Left box boundary must be the X image position, adjusted to the region margins", + position, Integer.parseInt(array[0])); + + position = (PAGE_HEIGHT - IMAGE_Y - rectY - IMAGE_HEIGHT) / 1000; + assertEquals("Top box boundary must be the page height minus the image height and the " + + "Y image position, adjusted to the region margins", + position, Integer.parseInt(array[1])); + + position = (IMAGE_X + rectX + IMAGE_WIDTH) / 1000; + assertEquals("Right box boundary must be the left box boundary plus the image width," + + " adjusted to the region margins", + position, Integer.parseInt(array[2])); + + position = (PAGE_HEIGHT - IMAGE_Y - rectY) / 1000; + assertEquals("Bottom box boundary must be the image height minus the Y image position, " + + "adjusted to the region margins", + position, Integer.parseInt(array[3])); + } + + private String defaultTestPDFUAImage(Dimension dimension, Rectangle rectangle, AffineTransform transform) + throws IFException, IOException { FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); foUserAgent = fopFactory.newFOUserAgent(); foUserAgent.setAccessibility(true); + IFContext ifContext = new IFContext(foUserAgent); pdfDocumentHandler = new PDFDocumentHandler(ifContext); pdfDocumentHandler.getStructureTreeEventHandler(); pdfDocumentHandler.setResult(new StreamResult(new ByteArrayOutputStream())); pdfDocumentHandler.startDocument(); - pdfDocumentHandler.startPage(0, "", "", new Dimension()); + pdfDocumentHandler.startPage(0, "", "", dimension); + PDFDocument doc = pdfDocumentHandler.getPDFDocument(); doc.getProfile().setPDFUAMode(PDFUAMode.PDFUA_1); doc.getInfo().setTitle("a"); + PDFLogicalStructureHandler structureHandler = new PDFLogicalStructureHandler(doc); structureHandler.startPage(new PDFPage(new PDFResources(doc), 0, new Rectangle(), new Rectangle(), new Rectangle(), new Rectangle())); + PDFPainter pdfPainter = new PDFPainter(pdfDocumentHandler, structureHandler); + if (transform != null) { + pdfPainter.startViewport(transform, dimension, null); + } + ifContext.setLanguage(Locale.US); - drawImage(doc, pdfPainter, ifContext); - String output = drawImage(doc, pdfPainter, ifContext); - Assert.assertTrue(output, output.contains("/BBox [0 0 0 0]")); + + drawImage(doc, pdfPainter, ifContext, rectangle); + return drawImage(doc, pdfPainter, ifContext, rectangle); } - private String drawImage(PDFDocument doc, PDFPainter pdfPainter, IFContext ifContext) + private String drawImage(PDFDocument doc, PDFPainter pdfPainter, IFContext ifContext, Rectangle rectangle) throws IOException, IFException { PDFStructElem structElem = new PDFStructElem(doc.getRoot(), StandardStructureTypes.InlineLevelStructure.NOTE); structElem.setDocument(doc); ifContext.setStructureTreeElement(structElem); - pdfPainter.drawImage("test/resources/images/cmyk.jpg", new Rectangle()); + pdfPainter.drawImage("test/resources/images/cmyk.jpg", rectangle); ByteArrayOutputStream bos = new ByteArrayOutputStream(); structElem.output(bos); return bos.toString(); @@ -418,8 +500,8 @@ public class PDFPainterTestCase { String out = drawSVGFont("<svg xmlns=\"http://www.w3.org/2000/svg\">\n" + "<circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"3\" fill=\"red\" />\n" + "</svg>"); - Assert.assertTrue(out.contains("0.00012 0 0 0.00012 0 0 cm")); - Assert.assertTrue(out.contains("1 0 0 rg")); + assertTrue(out.contains("0.00012 0 0 0.00012 0 0 cm")); + assertTrue(out.contains("1 0 0 rg")); } @Test @@ -442,8 +524,8 @@ public class PDFPainterTestCase { + "<g transform=\"translate(0 0) translate(0 0) scale(50)\"/>" + "<circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"3\" fill=\"red\" />\n" + "</svg>"); - Assert.assertTrue(out.contains("0.00012 0 0 0.00012 0 0 cm")); - Assert.assertTrue(out.contains("1 0 0 rg")); + assertTrue(out.contains("0.00012 0 0 0.00012 0 0 cm")); + assertTrue(out.contains("1 0 0 rg")); } private String drawSVGFont(String svg) throws IFException, IOException { |