Author: mehdi
Date: Fri May 11 13:14:17 2012
New Revision: 1337142

URL: http://svn.apache.org/viewvc?rev=1337142&view=rev
Log:
Changed the way AFP PTOCA TransparentData control sequences are written so that 
they end on character byte boundaries

Added:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java   
(with props)
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java   
(with props)
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
   (with props)
    xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/
    
xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
   (with props)
Modified:
    
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludeObject.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java?rev=1337142&r1=1337141&r2=1337142&view=diff
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
 (original)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
 Fri May 11 13:14:17 2012
@@ -105,9 +105,9 @@ public abstract class CharactersetEncode
         @Override
         EncodedChars getEncodedChars(byte[] byteArray, int length) {
             if (byteArray[0] == 0x0E && byteArray[length - 1] == 0x0F) {
-                return new EncodedChars(byteArray, 1, length - 2);
+                return new EncodedChars(byteArray, 1, length - 2, true);
             }
-            return new EncodedChars(byteArray);
+            return new EncodedChars(byteArray, true);
         }
     }
 
@@ -123,7 +123,7 @@ public abstract class CharactersetEncode
 
         @Override
         EncodedChars getEncodedChars(byte[] byteArray, int length) {
-            return new EncodedChars(byteArray);
+            return new EncodedChars(byteArray, false);
         }
     }
 
@@ -145,36 +145,25 @@ public abstract class CharactersetEncode
     /**
      * A container for encoded character bytes
      */
-    public static final class EncodedChars {
+    public static class EncodedChars {
 
         private final byte[] bytes;
-
         private final int offset;
-
         private final int length;
+        private final boolean isDBCS;
 
-        private EncodedChars(byte[] bytes, int offset, int length) {
-            if (offset < 0) {
-                throw new IllegalArgumentException();
-            }
-
-            if (length < 0) {
-                throw new IllegalArgumentException();
-            }
-
-            if (offset + length > bytes.length) {
+        private EncodedChars(byte[] bytes, int offset, int length, boolean 
isDBCS) {
+            if (offset < 0 || length < 0 || offset + length > bytes.length) {
                 throw new IllegalArgumentException();
             }
-
             this.bytes = bytes;
-
             this.offset = offset;
-
             this.length = length;
+            this.isDBCS = isDBCS;
         }
 
-        private EncodedChars(byte[] bytes) {
-           this(bytes, 0, bytes.length);
+        private EncodedChars(byte[] bytes, boolean isDBCS) {
+            this(bytes, 0, bytes.length, isDBCS);
         }
 
         /**
@@ -186,18 +175,9 @@ public abstract class CharactersetEncode
          * @throws IOException if an I/O error occurs
          */
         public void writeTo(OutputStream out, int offset, int length) throws 
IOException {
-            if (offset < 0) {
+            if (offset < 0 || length < 0 || offset + length > bytes.length) {
                 throw new IllegalArgumentException();
             }
-
-            if (length < 0) {
-                throw new IllegalArgumentException();
-            }
-
-            if (offset + length > this.length) {
-                throw new IllegalArgumentException();
-            }
-
             out.write(bytes, this.offset + offset, length);
         }
 
@@ -211,6 +191,15 @@ public abstract class CharactersetEncode
         }
 
         /**
+         * Indicates whether or not the EncodedChars object wraps double byte 
characters.
+         *
+         * @return true if the wrapped characters are double byte (DBCSs)
+         */
+        public boolean isDBCS() {
+            return isDBCS;
+        }
+
+        /**
          * The bytes
          *
          * @return the bytes

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java?rev=1337142&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java 
(added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java 
Fri May 11 13:14:17 2012
@@ -0,0 +1,82 @@
+/*
+ * 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.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Represents the 4 bytes that specify the axis-area rotation reference 
coordinate system
+ */
+public enum AxisOrientation {
+
+    RIGHT_HANDED_0(Rotation.ROTATION_0, Rotation.ROTATION_90),
+    RIGHT_HANDED_90(Rotation.ROTATION_90, Rotation.ROTATION_180),
+    RIGHT_HANDED_180(Rotation.ROTATION_180, Rotation.ROTATION_270),
+    RIGHT_HANDED_270(Rotation.ROTATION_270, Rotation.ROTATION_0);
+
+    /**
+     * The object area's X-axis rotation from the X axis of the reference 
coordinate system
+     */
+    private final Rotation xoaOrent;
+    /**
+     * The object area's Y-axis rotation from the Y axis of the reference 
coordinate system
+     */
+    private final Rotation yoaOrent;
+
+    public void writeTo(byte[] out, int offset) {
+        xoaOrent.writeTo(out, offset);
+        yoaOrent.writeTo(out, offset + 2);
+    }
+
+    private AxisOrientation(Rotation xoaOrent, Rotation yoaOrent) {
+        this.xoaOrent = xoaOrent;
+        this.yoaOrent = yoaOrent;
+    }
+
+    /**
+     * Writes the axis orientation area bytes to the output stream.
+     *
+     * @param stream the output stream to write to
+     * @throws IOException if an I/O error occurs
+     */
+    public void writeTo(OutputStream stream) throws IOException {
+        byte[] data = new byte[4];
+        writeTo(data, 0);
+        stream.write(data);
+    }
+
+    /**
+     * Gets the right-handed axis orientation object for a given orientation 
in degrees.
+     *
+     * @param orientation the orientation in degrees
+     * @return the {@link AxisOrientation} object
+     */
+    public static AxisOrientation getRightHandedAxisOrientationFor(int 
orientation) {
+        switch (orientation) {
+            case 0: return RIGHT_HANDED_0;
+            case 90: return RIGHT_HANDED_90;
+            case 180: return RIGHT_HANDED_180;
+            case 270: return RIGHT_HANDED_270;
+            default: throw new IllegalArgumentException(
+            "The orientation must be one of the values 0, 90, 180, 270");
+        }
+    }
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/AxisOrientation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludeObject.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludeObject.java?rev=1337142&r1=1337141&r2=1337142&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludeObject.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/IncludeObject.java 
Fri May 11 13:14:17 2012
@@ -67,7 +67,7 @@ public class IncludeObject extends Abstr
     private int yoaOset = 0;
 
     /** the orientation of the referenced object */
-    private ObjectAreaRotation oaOrent = ObjectAreaRotation.RIGHT_HANDED_0;
+    private AxisOrientation oaOrent = AxisOrientation.RIGHT_HANDED_0;
 
     /** the X-axis origin defined in the object */
     private int xocaOset = -1;
@@ -93,7 +93,7 @@ public class IncludeObject extends Abstr
      *            The orientation (0,90, 180, 270)
      */
     public void setObjectAreaOrientation(int orientation) {
-        this.oaOrent = ObjectAreaRotation.objectAreaRotationFor(orientation);
+        this.oaOrent = 
AxisOrientation.getRightHandedAxisOrientationFor(orientation);
     }
 
     /**
@@ -234,69 +234,4 @@ public class IncludeObject extends Abstr
         addTriplet(new MeasurementUnitsTriplet(xRes, xRes));
     }
 
-    /**
-     * Represents the 4 bytes that specify the area rotation reference 
coordinate system
-     *
-     */
-    private enum ObjectAreaRotation {
-
-        RIGHT_HANDED_0(Rotation.ROTATION_0, Rotation.ROTATION_90),
-        RIGHT_HANDED_90(Rotation.ROTATION_90, Rotation.ROTATION_180),
-        RIGHT_HANDED_180(Rotation.ROTATION_180, Rotation.ROTATION_270),
-        RIGHT_HANDED_270(Rotation.ROTATION_270, Rotation.ROTATION_0);
-
-        /**
-         * The object area's X-axis rotation from the X axis of the reference 
coordinate system
-         */
-        private final Rotation xoaOrent;
-        /**
-         * The object area's Y-axis rotation from the Y axis of the reference 
coordinate system
-         */
-        private final Rotation yoaOrent;
-
-        public void writeTo(byte[] out, int offset) {
-            xoaOrent.writeTo(out, offset);
-            yoaOrent.writeTo(out, offset + 2);
-        }
-
-        ObjectAreaRotation(Rotation xoaOrent, Rotation yoaOrent) {
-            this.xoaOrent = xoaOrent;
-            this.yoaOrent = yoaOrent;
-        }
-
-        private static ObjectAreaRotation objectAreaRotationFor(int 
orientation) {
-            switch (orientation) {
-                case 0: return RIGHT_HANDED_0;
-                case 90: return RIGHT_HANDED_90;
-                case 180: return RIGHT_HANDED_180;
-                case 270: return RIGHT_HANDED_270;
-                default: throw new IllegalArgumentException(
-                "The orientation must be one of the values 0, 90, 180, 270");
-            }
-        }
-    }
-
-    /**
-     * Represents a rotation value
-     *
-     */
-    private enum Rotation {
-
-        ROTATION_0(0),
-        ROTATION_90(0x2D),
-        ROTATION_180(0x5A),
-        ROTATION_270(0x87);
-
-        private final byte firstByte;
-
-        public void writeTo(byte[] out, int offset) {
-            out[offset] = firstByte;
-            out[offset + 1] = (byte)0;
-        }
-
-        Rotation(int firstByte) {
-            this.firstByte = (byte) firstByte;
-        }
-    }
-
 }

Added: xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java?rev=1337142&view=auto
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java 
(added)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java Fri 
May 11 13:14:17 2012
@@ -0,0 +1,46 @@
+/*
+ * 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.afp.modca;
+
+/**
+ * Represents a rotation value
+ *
+ */
+public enum Rotation {
+    ROTATION_0(0),
+    ROTATION_90(0x2D),
+    ROTATION_180(0x5A),
+    ROTATION_270(0x87);
+
+    private final byte firstByte;
+
+    public void writeTo(byte[] out, int offset) {
+        out[offset] = firstByte;
+        out[offset + 1] = (byte)0;
+    }
+
+    private Rotation(int firstByte) {
+        this.firstByte = (byte) firstByte;
+    }
+
+    public byte getByte() {
+        return firstByte;
+    }
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/modca/Rotation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java?rev=1337142&r1=1337141&r2=1337142&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java 
Fri May 11 13:14:17 2012
@@ -31,6 +31,8 @@ import org.apache.xmlgraphics.java2d.col
 import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
 
 import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.modca.AxisOrientation;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
 
 /**
  * Generator class for PTOCA data structures.
@@ -87,8 +89,10 @@ public abstract class PtocaBuilder imple
         baout.writeTo(out);
     }
 
-    private void writeByte(int data) {
-        baout.write(data);
+    private void writeBytes(int... data) {
+        for (int d : data) {
+            baout.write(d);
+        }
     }
 
     private void writeShort(int data) {
@@ -123,7 +127,7 @@ public abstract class PtocaBuilder imple
         }
 
         newControlSequence();
-        writeByte(font);
+        writeBytes(font);
         commit(chained(SCFL));
     }
 
@@ -187,26 +191,11 @@ public abstract class PtocaBuilder imple
      * @throws IOException if an I/O error occurs
      */
     public void addTransparentData(EncodedChars encodedChars) throws 
IOException {
-
-        // data size greater than TRANSPARENT_MAX_SIZE, so slice
-        int numTransData = encodedChars.getLength() / 
TRANSPARENT_DATA_MAX_SIZE;
-        int currIndex = 0;
-        for (int transDataCnt = 0; transDataCnt < numTransData; 
transDataCnt++) {
-            addTransparentDataChunk(encodedChars, currIndex, 
TRANSPARENT_DATA_MAX_SIZE);
-            currIndex += TRANSPARENT_DATA_MAX_SIZE;
+        for (TransparentData trn : new 
TransparentDataControlSequence(encodedChars)) {
+            newControlSequence();
+            trn.writeTo(baout);
+            commit(chained(TRN));
         }
-        int left = encodedChars.getLength() - currIndex;
-        addTransparentDataChunk(encodedChars, currIndex, left);
-
-    }
-
-
-
-    private void addTransparentDataChunk(EncodedChars encodedChars, int 
offset, int length)
-            throws IOException {
-        newControlSequence();
-        encodedChars.writeTo(baout, offset, length);
-        commit(chained(TRN));
     }
 
     /**
@@ -222,7 +211,7 @@ public abstract class PtocaBuilder imple
         newControlSequence();
         writeShort(length); // Rule length
         writeShort(width); // Rule width
-        writeByte(0); // Rule width fraction is always null. enough?
+        writeBytes(0); // Rule width fraction is always null. enough?
         commit(chained(DBR));
     }
 
@@ -239,7 +228,7 @@ public abstract class PtocaBuilder imple
         newControlSequence();
         writeShort(length); // Rule length
         writeShort(width); // Rule width
-        writeByte(0); // Rule width fraction is always null. enough?
+        writeBytes(0); // Rule width fraction is always null. enough?
         commit(chained(DIR));
     }
 
@@ -260,32 +249,7 @@ public abstract class PtocaBuilder imple
             return;
         }
         newControlSequence();
-        switch (orientation) {
-        case 90:
-            writeByte(0x2D);
-            writeByte(0x00);
-            writeByte(0x5A);
-            writeByte(0x00);
-            break;
-        case 180:
-            writeByte(0x5A);
-            writeByte(0x00);
-            writeByte(0x87);
-            writeByte(0x00);
-            break;
-        case 270:
-            writeByte(0x87);
-            writeByte(0x00);
-            writeByte(0x00);
-            writeByte(0x00);
-            break;
-        default:
-            writeByte(0x00);
-            writeByte(0x00);
-            writeByte(0x2D);
-            writeByte(0x00);
-            break;
-        }
+        
AxisOrientation.getRightHandedAxisOrientationFor(orientation).writeTo(baout);
         commit(chained(STO));
         this.currentOrientation = orientation;
         currentX = -1;
@@ -317,55 +281,30 @@ public abstract class PtocaBuilder imple
 
         newControlSequence();
         if (col.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x04); // Color space - 0x04 = CMYK
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(8); // Number of bits in component 1
-            writeByte(8); // Number of bits in component 2
-            writeByte(8); // Number of bits in component 3
-            writeByte(8); // Number of bits in component 4
+            // Color space - 0x04 = CMYK, all else are reserved and must be 
zero
+            writeBytes(0x00, 0x04, 0x00, 0x00, 0x00, 0x00);
+            writeBytes(8, 8, 8, 8); // Number of bits in component 1, 2, 3 & 4 
respectively
             float[] comps = col.getColorComponents(null);
             assert comps.length == 4;
             for (int i = 0; i < 4; i++) {
                 int component = Math.round(comps[i] * 255);
-                writeByte(component);
+                writeBytes(component);
             }
         } else if (cs instanceof CIELabColorSpace) {
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x08); // Color space - 0x08 = CIELAB
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(8); // Number of bits in component 1
-            writeByte(8); // Number of bits in component 2
-            writeByte(8); // Number of bits in component 3
-            writeByte(0); // Number of bits in component 4
+            // Color space - 0x08 = CIELAB, all else are reserved and must be 
zero
+            writeBytes(0x00, 0x08, 0x00, 0x00, 0x00, 0x00);
+            writeBytes(8, 8, 8, 0); // Number of bits in component 1,2,3 & 4
             //Sadly, 16 bit components don't seem to work
             float[] colorComponents = col.getColorComponents(null);
             int l = Math.round(colorComponents[0] * 255f);
             int a = Math.round(colorComponents[1] * 255f) - 128;
             int b = Math.round(colorComponents[2] * 255f) - 128;
-            writeByte(l); // L*
-            writeByte(a); // a*
-            writeByte(b); // b*
+            writeBytes(l, a, b); // l*, a* and b*
         } else {
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x01); // Color space - 0x01 = RGB
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(0x00); // Reserved; must be zero
-            writeByte(8); // Number of bits in component 1
-            writeByte(8); // Number of bits in component 2
-            writeByte(8); // Number of bits in component 3
-            writeByte(0); // Number of bits in component 4
-            writeByte(col.getRed()); // Red intensity
-            writeByte(col.getGreen()); // Green intensity
-            writeByte(col.getBlue()); // Blue intensity
+            // Color space - 0x01 = RGB, all else are reserved and must be zero
+            writeBytes(0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
+            writeBytes(8, 8, 8, 0); // Number of bits in component 1, 2, 3 & 4 
respectively
+            writeBytes(col.getRed(), col.getGreen(), col.getBlue()); // RGB 
intensity
         }
         commit(chained(SEC));
         this.currentColor = col;
@@ -407,7 +346,7 @@ public abstract class PtocaBuilder imple
         assert incr >= Short.MIN_VALUE && incr <= Short.MAX_VALUE;
         newControlSequence();
         writeShort(Math.abs(incr)); //Increment
-        writeByte(incr >= 0 ? 0 : 1); // Direction
+        writeBytes(incr >= 0 ? 0 : 1); // Direction
         commit(chained(SIA));
 
         this.currentInterCharacterAdjustment = incr;

Modified: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java?rev=1337142&r1=1337141&r2=1337142&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java 
(original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java 
Fri May 11 13:14:17 2012
@@ -64,6 +64,6 @@ public interface PtocaConstants {
     byte NOP = (byte)0xF8;
 
     /** Maximum size of transparent data chunks */
-    int TRANSPARENT_DATA_MAX_SIZE = 253;
+    int TRANSPARENT_DATA_MAX_SIZE = 253; // max length = 255 (minus the 
ControlSequence length)
 
 }

Added: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java?rev=1337142&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
 (added)
+++ 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
 Fri May 11 13:14:17 2012
@@ -0,0 +1,89 @@
+/*
+ * 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.afp.ptoca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
+
+import static 
org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE;
+
+/**
+ * This object represents a series of PTOCA TransparentData (TRN) control 
sequences. This implements
+ * {@link Iterable} to enable iteration through the TRNs.
+ */
+final class TransparentDataControlSequence implements 
Iterable<TransparentData> {
+
+    private static final int MAX_SBCS_TRN_SIZE = TRANSPARENT_DATA_MAX_SIZE;
+    // The maximum size of a TRN must be an EVEN number so that we're 
splitting TRNs on character
+    // boundaries rather than in the middle of a double-byte character
+    private static final int MAX_DBCS_TRN_SIZE = MAX_SBCS_TRN_SIZE - 1;
+
+    static final class TransparentData {
+        private final int offset;
+        private final int length;
+        private final EncodedChars encodedChars;
+
+        private TransparentData(int offset, int length, EncodedChars encChars) 
{
+            this.offset = offset;
+            this.length = length;
+            this.encodedChars = encChars;
+        }
+
+        void writeTo(OutputStream outStream) throws IOException {
+            encodedChars.writeTo(outStream, offset, length);
+        }
+    }
+
+    private final List<TransparentData> trns;
+
+    /**
+     * Converts an encoded String wrapped in an {@link EncodedChars} into a 
series of
+     * {@link TransparentData} control sequences.
+     *
+     * @param encChars the encoded characters to convert to TRNs
+     */
+    public TransparentDataControlSequence(EncodedChars encChars) {
+        int maxTrnLength = encChars.isDBCS() ? MAX_DBCS_TRN_SIZE : 
MAX_SBCS_TRN_SIZE;
+        int numTransData = encChars.getLength() / maxTrnLength;
+        int currIndex = 0;
+        List<TransparentData> trns = new ArrayList<TransparentData>();
+        for (int transDataCnt = 0; transDataCnt < numTransData; 
transDataCnt++) {
+            trns.add(new TransparentData(currIndex, maxTrnLength, encChars));
+            currIndex += maxTrnLength;
+        }
+        int left = encChars.getLength() - currIndex;
+        trns.add(new TransparentData(currIndex, left, encChars));
+        this.trns = Collections.unmodifiableList(trns);
+    }
+
+    /**
+     * The {@link Iterator} for retrieving the series of TRN control sequences.
+     */
+    public Iterator<TransparentData> iterator() {
+        return trns.iterator();
+    }
+}

Propchange: 
xmlgraphics/fop/trunk/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
URL: 
http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java?rev=1337142&view=auto
==============================================================================
--- 
xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
 (added)
+++ 
xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
 Fri May 11 13:14:17 2012
@@ -0,0 +1,73 @@
+/*
+ * 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.afp.ptoca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.junit.Test;
+
+import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
+
+import static 
org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class TransparentDataControlSequenceTestCase {
+
+    private EncodedChars encodedChars;
+    private final OutputStream outStream = mock(OutputStream.class);
+
+    @Test
+    public void testSingleByteCharacterSet() throws IOException {
+        testTRNs(false);
+    }
+
+    @Test
+    public void testDoubleByteCharacterSets() throws IOException {
+        testTRNs(true);
+    }
+
+    public void testTRNs(boolean isDBCS) throws IOException {
+        for (int length = 100; length < 10000; length += 1000) {
+            createTRNControlSequence(isDBCS, length);
+            int maxTRNSize = TRANSPARENT_DATA_MAX_SIZE - (isDBCS ? 1 : 0);
+            int numberOfTRNs = length / maxTRNSize;
+            for (int i = 0; i < numberOfTRNs; i++) {
+                verify(encodedChars, times(1)).writeTo(outStream, i * 
maxTRNSize, maxTRNSize);
+            }
+            int lastOffset = numberOfTRNs * maxTRNSize;
+            verify(encodedChars, times(1)).writeTo(outStream, numberOfTRNs * 
maxTRNSize,
+                    length - lastOffset);
+        }
+    }
+
+    private void createTRNControlSequence(boolean isDBCS, int length) throws 
IOException {
+        encodedChars = mock(EncodedChars.class);
+        when(encodedChars.isDBCS()).thenReturn(isDBCS);
+        when(encodedChars.getLength()).thenReturn(length);
+        for (TransparentData trn : new 
TransparentDataControlSequence(encodedChars)) {
+            trn.writeTo(outStream);
+        }
+    }
+}

Propchange: 
xmlgraphics/fop/trunk/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to