From 6a52dfb4c893ee070ed381c408e0254f7b235063 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Tue, 26 Jul 2016 14:42:01 +0000 Subject: [PATCH] FOP-2637: PTX records are incorrectly chained git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1754137 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/afp/AFPBorderPainter.java | 5 ++ .../fop/afp/modca/AbstractPageObject.java | 2 +- .../fop/afp/modca/PresentationTextObject.java | 13 ++- .../org/apache/fop/render/afp/AFPPainter.java | 14 ++- .../fop/render/afp/AFPPainterTestCase.java | 85 +++++++++++++++++++ 5 files changed, 116 insertions(+), 3 deletions(-) diff --git a/fop-core/src/main/java/org/apache/fop/afp/AFPBorderPainter.java b/fop-core/src/main/java/org/apache/fop/afp/AFPBorderPainter.java index f80a269a2..a10c5ae9a 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/AFPBorderPainter.java +++ b/fop-core/src/main/java/org/apache/fop/afp/AFPBorderPainter.java @@ -42,6 +42,11 @@ public class AFPBorderPainter extends AbstractAFPPainter { /** {@inheritDoc} */ public void paint(PaintingInfo paintInfo) { + Integer bytesAvailable = dataStream.getCurrentPage().getPresentationTextObject().getBytesAvailable(); + if (bytesAvailable != null && bytesAvailable < 1024) { + dataStream.getCurrentPage().endPresentationObject(); + } + BorderPaintingInfo borderPaintInfo = (BorderPaintingInfo)paintInfo; float w = borderPaintInfo.getX2() - borderPaintInfo.getX1(); float h = borderPaintInfo.getY2() - borderPaintInfo.getY1(); diff --git a/fop-core/src/main/java/org/apache/fop/afp/modca/AbstractPageObject.java b/fop-core/src/main/java/org/apache/fop/afp/modca/AbstractPageObject.java index 575697790..80d5da8e6 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/modca/AbstractPageObject.java +++ b/fop-core/src/main/java/org/apache/fop/afp/modca/AbstractPageObject.java @@ -186,7 +186,7 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen /** * Ends the presentation text object */ - protected void endPresentationObject() { + public void endPresentationObject() { if (currentPresentationTextObject != null) { currentPresentationTextObject.endControlSequence(); currentPresentationTextObject = null; diff --git a/fop-core/src/main/java/org/apache/fop/afp/modca/PresentationTextObject.java b/fop-core/src/main/java/org/apache/fop/afp/modca/PresentationTextObject.java index f4d4d93ed..d1b0c9318 100644 --- a/fop-core/src/main/java/org/apache/fop/afp/modca/PresentationTextObject.java +++ b/fop-core/src/main/java/org/apache/fop/afp/modca/PresentationTextObject.java @@ -60,7 +60,7 @@ public class PresentationTextObject extends AbstractNamedAFPObject { */ private List/**/ presentationTextDataList; - private PtocaBuilder builder = new DefaultBuilder(); + private DefaultBuilder builder = new DefaultBuilder(); /** * Construct a new PresentationTextObject for the specified name argument, @@ -105,6 +105,13 @@ public class PresentationTextObject extends AbstractNamedAFPObject { } private class DefaultBuilder extends PtocaBuilder { + public Integer getBytesAvailable() { + if (currentPresentationTextData == null) { + return null; + } + return currentPresentationTextData.getBytesAvailable(); + } + protected OutputStream getOutputStreamForControlSequence(int length) { if (length > currentPresentationTextData.getBytesAvailable()) { endPresentationTextData(); @@ -201,4 +208,8 @@ public class PresentationTextObject extends AbstractNamedAFPObject { } return super.toString(); } + + public Integer getBytesAvailable() { + return builder.getBytesAvailable(); + } } diff --git a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java index 7304d2e52..3fae2e0a0 100644 --- a/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java +++ b/fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java @@ -33,6 +33,7 @@ import java.awt.geom.Rectangle2D; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.CharacterCodingException; import java.security.MessageDigest; import java.util.Map; @@ -102,6 +103,7 @@ public class AFPPainter extends AbstractIFPainter { private final AFPUnitConverter unitConv; private final AFPEventProducer eventProducer; + private Integer bytesAvailable; /** * Default constructor. @@ -928,7 +930,16 @@ public class AFPPainter extends AbstractIFPainter { } AbstractPageObject page = getDataStream().getCurrentPage(); - PresentationTextObject pto = page.getPresentationTextObject(); + + try { + int size = charSet.encodeChars(text).getLength(); + if (bytesAvailable != null && bytesAvailable < size) { + page.endPresentationObject(); + } + } catch (CharacterCodingException e) { + throw new IFException(e.getMessage(), e); + } + final PresentationTextObject pto = page.getPresentationTextObject(); try { pto.createControlSequences(new PtocaProducer() { @@ -1053,6 +1064,7 @@ public class AFPPainter extends AbstractIFPainter { } } flushText(builder, sb, charSet); + bytesAvailable = pto.getBytesAvailable(); } private void flushText(PtocaBuilder builder, StringBuffer sb, diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java index fd6209bf1..2c3cb5332 100644 --- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java @@ -20,13 +20,26 @@ package org.apache.fop.render.afp; import java.awt.Color; +import java.awt.Dimension; import java.awt.Rectangle; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import javax.xml.transform.stream.StreamResult; + +import org.junit.Assert; import org.junit.Test; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -41,11 +54,18 @@ import org.apache.xmlgraphics.image.loader.impl.ImageBuffered; import org.apache.fop.afp.AFPEventProducer; import org.apache.fop.afp.AFPPaintingState; import org.apache.fop.afp.AFPResourceManager; +import org.apache.fop.afp.fonts.CharacterSet; +import org.apache.fop.afp.fonts.CharactersetEncoder; +import org.apache.fop.afp.fonts.RasterFont; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.Constants; +import org.apache.fop.fonts.Font; +import org.apache.fop.fonts.FontInfo; import org.apache.fop.render.ImageHandlerRegistry; import org.apache.fop.render.intermediate.IFContext; +import org.apache.fop.render.intermediate.IFException; import org.apache.fop.traits.BorderProps; public class AFPPainterTestCase { @@ -128,4 +148,69 @@ public class AFPPainterTestCase { } } + @Test + public void testPresentationText() throws URISyntaxException, IFException, IOException { + List strings = new ArrayList(); + strings.add("test"); + Assert.assertEquals(writeText(strings), "BEGIN DOCUMENT DOC00001\n" + + "BEGIN PAGE PGN00001\n" + + "BEGIN ACTIVE_ENVIRONMENT_GROUP AEG00001\n" + + "DESCRIPTOR PAGE\n" + + "MIGRATION PRESENTATION_TEXT\n" + + "END ACTIVE_ENVIRONMENT_GROUP AEG00001\n" + + "BEGIN PRESENTATION_TEXT PT000001\n" + + "DATA PRESENTATION_TEXT\n" + + "END PRESENTATION_TEXT PT000001\n" + + "END PAGE PGN00001\n" + + "END DOCUMENT DOC00001\n"); + + for (int i = 0; i < 5000; i++) { + strings.add("test"); + } + Assert.assertEquals(writeText(strings), "BEGIN DOCUMENT DOC00001\n" + + "BEGIN PAGE PGN00001\n" + + "BEGIN ACTIVE_ENVIRONMENT_GROUP AEG00001\n" + + "DESCRIPTOR PAGE\n" + + "MIGRATION PRESENTATION_TEXT\n" + + "END ACTIVE_ENVIRONMENT_GROUP AEG00001\n" + + "BEGIN PRESENTATION_TEXT PT000001\n" + + "DATA PRESENTATION_TEXT\n" + + "END PRESENTATION_TEXT PT000001\n" + + "BEGIN PRESENTATION_TEXT PT000002\n" + + "DATA PRESENTATION_TEXT\n" + + "END PRESENTATION_TEXT PT000002\n" + + "END PAGE PGN00001\n" + + "END DOCUMENT DOC00001\n"); + } + + private String writeText(List text) throws URISyntaxException, IOException, IFException { + FOUserAgent agent = FopFactory.newInstance(new URI(".")).newFOUserAgent(); + IFContext context = new IFContext(agent); + AFPDocumentHandler doc = new AFPDocumentHandler(context); + AFPPainter afpPainter = new AFPPainter(doc); + FontInfo fi = new FontInfo(); + fi.addFontProperties("", Font.DEFAULT_FONT); + RasterFont rf = new RasterFont("", true); + CharacterSet cs = mock(CharacterSet.class); + CharactersetEncoder.EncodedChars encoder = mock(CharactersetEncoder.EncodedChars.class); + when(cs.encodeChars(anyString())).thenReturn(encoder); + when(encoder.getLength()).thenReturn(text.get(0).length()); + rf.addCharacterSet(12000, cs); + fi.addMetrics("", rf); + doc.setFontInfo(fi); + afpPainter.setFont("any", "normal", 400, "", 12000, Color.BLACK); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + doc.setResult(new StreamResult(outputStream)); + doc.startDocument(); + doc.startPage(0, "", "", new Dimension()); + for (String s : text) { + afpPainter.drawText(0, 0, 0, 0, null, s); + } + doc.endDocument(); + + InputStream bis = new ByteArrayInputStream(outputStream.toByteArray()); + StringBuilder sb = new StringBuilder(); + new AFPParser(false).read(bis, sb); + return sb.toString(); + } } -- 2.39.5