]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
FOP-2637: PTX records are incorrectly chained
authorSimon Steiner <ssteiner@apache.org>
Tue, 26 Jul 2016 14:42:01 +0000 (14:42 +0000)
committerSimon Steiner <ssteiner@apache.org>
Tue, 26 Jul 2016 14:42:01 +0000 (14:42 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1754137 13f79535-47bb-0310-9956-ffa450edef68

fop-core/src/main/java/org/apache/fop/afp/AFPBorderPainter.java
fop-core/src/main/java/org/apache/fop/afp/modca/AbstractPageObject.java
fop-core/src/main/java/org/apache/fop/afp/modca/PresentationTextObject.java
fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java
fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java

index f80a269a253c9a70da5934790c84c8d9960de362..a10c5ae9aa40662db1aeb5f0ef69fad52ce935a8 100644 (file)
@@ -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();
index 575697790aa19ed5e605216287870a99662ed0c7..80d5da8e60d3197637b3dbf3648ca4d0b803f00d 100644 (file)
@@ -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;
index f4d4d93edb137a67232f3dae3c14ed1191edf4f9..d1b0c9318d77b94a3d50c5d7947a52ff86497ab4 100644 (file)
@@ -60,7 +60,7 @@ public class PresentationTextObject extends AbstractNamedAFPObject {
      */
     private List/*<PresentationTextData>*/ 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();
+    }
 }
index 7304d2e52b99c622fcafc7733132f1a73f89bc7f..3fae2e0a048221e62b5cab88f216142841ad82c4 100644 (file)
@@ -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<AFPDocumentHandler> {
     private final AFPUnitConverter unitConv;
 
     private final AFPEventProducer eventProducer;
+    private Integer bytesAvailable;
 
     /**
      * Default constructor.
@@ -928,7 +930,16 @@ public class AFPPainter extends AbstractIFPainter<AFPDocumentHandler> {
         }
 
         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<AFPDocumentHandler> {
                         }
                     }
                     flushText(builder, sb, charSet);
+                    bytesAvailable = pto.getBytesAvailable();
                 }
 
                 private void flushText(PtocaBuilder builder, StringBuffer sb,
index fd6209bf12dd2a297538674327dfdb9c38a16097..2c3cb5332112a4accba999047553d3aea7999f30 100644 (file)
 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<String> strings = new ArrayList<String>();
+        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<String> 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();
+    }
 }