]> source.dussan.org Git - poi.git/commitdiff
improved handling of StyleTextPropAtom bit masks, added more read-write roundtrip...
authorYegor Kozlov <yegor@apache.org>
Tue, 2 Sep 2008 09:59:53 +0000 (09:59 +0000)
committerYegor Kozlov <yegor@apache.org>
Tue, 2 Sep 2008 09:59:53 +0000 (09:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@691180 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hslf/model/textproperties/CharFlagsTextProp.java
src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestStyleTextPropAtom.java

index a78c2c27e531d813aab91fe00a1b075f68221f31..f038781534b92c7ddad72861ef0b71294aeec6cb 100644 (file)
@@ -35,19 +35,19 @@ public class CharFlagsTextProp extends BitMaskTextProp {
     public static String NAME = "char_flags";
        public CharFlagsTextProp() {
                super(2,0xffff, NAME, new String[] {
-                               "bold",          // 0x0001
-                               "italic",        // 0x0002
-                               "underline",     // 0x0004
-                               "char_unknown_1",// 0x0008
-                               "shadow",        // 0x0010
-                               "char_unknown_2",// 0x0020
-                               "char_unknown_3",// 0x0040
-                               "char_unknown_4",// 0x0080
-                               "strikethrough", // 0x0100
-                               "relief",        // 0x0200
-                               "reset_numbering",    // 0x0400
-                               "enable_numbering_1", // 0x0800
-                               "enable_numbering_2", // 0x1000
+                               "bold",                 // 0x0001  A bit that specifies whether the characters are bold.
+                               "italic",               // 0x0002  A bit that specifies whether the characters are italicized.
+                               "underline",            // 0x0004  A bit that specifies whether the characters are underlined.
+                               "char_unknown_1",       // 0x0008  Undefined and MUST be ignored.
+                               "shadow",               // 0x0010  A bit that specifies whether the characters have a shadow effect.
+                               "fehint",               // 0x0020  A bit that specifies whether characters originated from double-byte input.
+                               "char_unknown_2",       // 0x0040  Undefined and MUST be ignored.
+                               "kumi",                 // 0x0080  A bit that specifies whether Kumimoji are used for vertical text.
+                               "strikethrough",        // 0x0100  Undefined and MUST be ignored.
+                               "emboss",               // 0x0200  A bit that specifies whether the characters are embossed.
+                "char_unknown_3",       // 0x0400  Undefined and MUST be ignored.
+                "char_unknown_4",       // 0x0800  Undefined and MUST be ignored.
+                "char_unknown_5",       // 0x1000  Undefined and MUST be ignored.
                        }
                );
        }
index bcf4b997c428d63edae4a4c010e8b0d816eca231..f876c7d389413cc05954ec20b8aece96d6d8be18 100644 (file)
@@ -34,6 +34,7 @@ public class TextPropCollection {
        private int charactersCovered;
        private short reservedField;
        private LinkedList textPropList;
+    private int maskSpecial = 0;
 
        /** Fetch the number of characters this styling applies to */
        public int getCharactersCovered() { return charactersCovered; }
@@ -94,21 +95,28 @@ public class TextPropCollection {
                // If we do, decode that, save it, and shuffle on
                for(int i=0; i<potentialProperties.length; i++) {
                        // Check there's still data left to read
-                       if(dataOffset+bytesPassed >= data.length) {
-                               // Out of data, can't be any more properties to go
-                               return bytesPassed;
-                       }
-                       
+
                        // Check if this property is found in the mask
                        if((containsField & potentialProperties[i].getMask()) != 0) {
+                if(dataOffset+bytesPassed >= data.length) {
+                    // Out of data, can't be any more properties to go
+                    // remember the mask and return
+                    maskSpecial |= potentialProperties[i].getMask();
+                    return bytesPassed;
+                }
+
                                // Bingo, data contains this property
                                TextProp prop = (TextProp)potentialProperties[i].clone();
                                int val = 0;
                                if(prop.getSize() == 2) {
                                        val = LittleEndian.getShort(data,dataOffset+bytesPassed);
-                               } else {
+                               } else if(prop.getSize() == 4){
                                        val = LittleEndian.getInt(data,dataOffset+bytesPassed);
-                               }
+                               } else if (prop.getSize() == 0){
+                    //remember "special" bits.
+                    maskSpecial |= potentialProperties[i].getMask();
+                    continue;
+                }
                                prop.setValue(val);
                                bytesPassed += prop.getSize();
                                textPropList.add(prop);
@@ -161,15 +169,18 @@ public class TextPropCollection {
                }
 
                // Then the mask field
-               int mask = 0;
+               int mask = maskSpecial;
                for(int i=0; i<textPropList.size(); i++) {
                        TextProp textProp = (TextProp)textPropList.get(i);
             //sometimes header indicates that the bitmask is present but its value is 0
-            if (textProp instanceof BitMaskTextProp)
-                mask |= (textProp.getWriteMask() == 0 ? 1 : textProp.getWriteMask());
-            else
+
+            if (textProp instanceof BitMaskTextProp) {
+                if(mask == 0) mask |=  textProp.getWriteMask();
+            }
+            else {
                 mask |= textProp.getWriteMask();
-               }
+            }
+        }
                StyleTextPropAtom.writeLittleEndian(mask,o);
 
                // Then the contents of all the properties
@@ -178,7 +189,7 @@ public class TextPropCollection {
                        int val = textProp.getValue();
                        if(textProp.getSize() == 2) {
                                StyleTextPropAtom.writeLittleEndian((short)val,o);
-                       } else {
+                       } else if(textProp.getSize() == 4){
                                StyleTextPropAtom.writeLittleEndian(val,o);
                        }
                }
index 7b2304074f02dab8a323dc98ff8f6289876432ec..1207c68b3b72f4245a16e0c1869dcbd90aa35814 100644 (file)
@@ -124,47 +124,54 @@ public class StyleTextPropAtom extends RecordAtom
 
        /** All the different kinds of paragraph properties we might handle */
        public static TextProp[] paragraphTextPropTypes = new TextProp[] {
-                               new ParagraphFlagsTextProp(),
+                new TextProp(0, 0x1, "hasBullet"),
+                new TextProp(0, 0x2, "hasBulletFont"),
+                new TextProp(0, 0x4, "hasBulletColor"),
+                new TextProp(0, 0x8, "hasBulletSize"),
+                new ParagraphFlagsTextProp(),
                 new TextProp(2, 0x80, "bullet.char"),
                                new TextProp(2, 0x10, "bullet.font"),
                 new TextProp(2, 0x40, "bullet.size"),
                                new TextProp(4, 0x20, "bullet.color"),
                 new AlignmentTextProp(),
                 new TextProp(2, 0x100, "text.offset"),
-                               new TextProp(2, 0x200, "para_unknown_2"),
                 new TextProp(2, 0x400, "bullet.offset"),
-                               new TextProp(2, 0x1000, "linespacing"),
-                               new TextProp(2, 0x2000, "spacebefore"),
-                               new TextProp(2, 0x4000, "spaceafter"),
-                               new TextProp(2, 0x8000, "para_unknown_4"),
-                               new TextProp(2, 0x10000, "para_unknown_5"),
-                               new TextProp(2, 0xA0000, "para_unknown_6"),
-                               new TextProp(2, 0x200000, "para_unknown_7")
+                new TextProp(2, 0x1000, "linespacing"),
+                new TextProp(2, 0x2000, "spacebefore"),
+                new TextProp(2, 0x4000, "spaceafter"),
+                new TextProp(2, 0x8000, "defaultTabSize"),
+                               new TextProp(2, 0x100000, "tabStops"),
+                               new TextProp(2, 0x10000, "fontAlign"),
+                               new TextProp(2, 0xA0000, "wrapFlags"),
+                               new TextProp(2, 0x200000, "textDirection")
        };
        /** All the different kinds of character properties we might handle */
        public static TextProp[] characterTextPropTypes = new TextProp[] {
-                               new CharFlagsTextProp(),
+                new TextProp(0, 0x1, "bold"),
+                new TextProp(0, 0x2, "italic"),
+                new TextProp(0, 0x4, "underline"),
+                new TextProp(0, 0x8, "unused1"),
+                new TextProp(0, 0x10, "shadow"),
+                new TextProp(0, 0x20, "fehint"),
+                new TextProp(0, 0x40, "unused2"),
+                new TextProp(0, 0x80, "kumi"),
+                new TextProp(0, 0x100, "unused3"),
+                new TextProp(0, 0x200, "emboss"),
+                new CharFlagsTextProp(),
                                new TextProp(2, 0x10000, "font.index"),
-                new TextProp(2, 0x200000, "asian_or_complex"),
-                new TextProp(2, 0x400000, "char_unknown_2"),
-                new TextProp(2, 0x800000, "symbol"),
+                new TextProp(0, 0x100000, "pp10ext"),
+                new TextProp(2, 0x200000, "asian.font.index"),
+                new TextProp(2, 0x400000, "ansi.font.index"),
+                new TextProp(2, 0x800000, "symbol.font.index"),
                                new TextProp(2, 0x20000, "font.size"),
                                new TextProp(4, 0x40000, "font.color"),
-                               new TextProp(2, 0x80000, "superscript"),
-                               new TextProp(2, 0x100000, "char_unknown_1"),
-                               new TextProp(2, 0x1000000, "char_unknown_3"),
-                               new TextProp(2, 0x2000000, "char_unknown_4"),
-                               new TextProp(2, 0x4000000, "char_unknown_5"),
-                               new TextProp(2, 0x8000000, "char_unknown_6"),
-                               new TextProp(2, 0x10000000, "char_unknown_7"),
-                               new TextProp(2, 0x20000000, "char_unknown_8"),
-                               new TextProp(2, 0x40000000, "char_unknown_9"),
-                               new TextProp(2, 0x80000000, "char_unknown_10"),
-       };
+                new TextProp(2, 0x80000, "superscript"),
+
+    };
 
        /* *************** record code follows ********************** */
 
-       /** 
+       /**
         * For the Text Style Properties (StyleTextProp) Atom
         */
        public StyleTextPropAtom(byte[] source, int start, int len) {
@@ -192,7 +199,7 @@ public class StyleTextPropAtom extends RecordAtom
        }
 
 
-       /** 
+       /**
         * A new set of text style properties for some text without any.
         */
        public StyleTextPropAtom(int parentTextSize) {
@@ -209,11 +216,11 @@ public class StyleTextPropAtom extends RecordAtom
                paragraphStyles = new LinkedList();
                charStyles = new LinkedList();
 
-               TextPropCollection defaultParagraphTextProps = 
+               TextPropCollection defaultParagraphTextProps =
                        new TextPropCollection(parentTextSize, (short)0);
                paragraphStyles.add(defaultParagraphTextProps);
 
-               TextPropCollection defaultCharacterTextProps = 
+               TextPropCollection defaultCharacterTextProps =
                        new TextPropCollection(parentTextSize);
                charStyles.add(defaultCharacterTextProps);
 
@@ -269,8 +276,7 @@ public class StyleTextPropAtom extends RecordAtom
                        textHandled += textLen;
                        pos += 4;
 
-                       // Fetch the 2 byte value that is safe to ignore as 0
-                       short paraIgn = LittleEndian.getShort(rawContents,pos);
+                       short indent = LittleEndian.getShort(rawContents,pos);
                        pos += 2;
 
                        // Grab the 4 byte value that tells us what properties follow
@@ -278,7 +284,7 @@ public class StyleTextPropAtom extends RecordAtom
                        pos += 4;
 
                        // Now make sense of those properties
-                       TextPropCollection thisCollection = new TextPropCollection(textLen, paraIgn);
+                       TextPropCollection thisCollection = new TextPropCollection(textLen, indent);
                        int plSize = thisCollection.buildTextPropList(
                                        paraFlags, paragraphTextPropTypes, rawContents, pos);
                        pos += plSize;
index 7b1f614ee7e707be56a8ca972f9dc226b86f7c8d..17f9010eb2d4861b95e0cc1d9c341c9edc02a862 100644 (file)
@@ -31,6 +31,7 @@ import org.apache.poi.util.HexDump;
 import junit.framework.TestCase;
 import java.io.ByteArrayOutputStream;
 import java.util.LinkedList;
+import java.util.Arrays;
 
 /**
  * Tests that StyleTextPropAtom works properly
@@ -38,9 +39,9 @@ import java.util.LinkedList;
  * @author Nick Burch (nick at torchbox dot com)
  */
 public class TestStyleTextPropAtom extends TestCase {
-       /** From a real file: a paragraph with 4 different styles */
-       private byte[] data_a = new byte[] { 
-         0, 0, 0xA1-256, 0x0F, 0x2A, 0, 0, 0,
+    /** From a real file: a paragraph with 4 different styles */
+    private byte[] data_a = new byte[] {
+      0, 0, 0xA1-256, 0x0F, 0x2A, 0, 0, 0,
       0x36, 00, 00, 00, // paragraph is 54 long 
       00, 00,           // (paragraph reserved field)
       00, 00, 00, 00,   // it doesn't have any styles
@@ -52,84 +53,84 @@ public class TestStyleTextPropAtom extends TestCase {
       0x10, 00, 00, 00, // third char run is 16 long
       00, 00, 0x04, 00, // font.color only
       0xFF-256, 0x33, 00, 0xFE-256 // red
-       };
-       private int data_a_text_len = 0x36-1;
-
-       /** 
-        * From a real file: 4 paragraphs with text in 4 different styles:
-        * left aligned+bold (30)
-        * centre aligned+italic+blue (28)
-        * right aligned+red (25)
-        * left aligned+underlined+larger font size (96)
-        * left aligned+underlined+larger font size+red (1)
-        */
-       private byte[] data_b = new byte[] { 
-               0, 0, 0xA1-256, 0x0F, 0x80-256, 0, 0, 0, 
-               0x1E, 00, 00, 00,     // paragraph is 30 long 
-               00, 00,               // paragraph reserved field
-               00, 0x18, 00, 00,     // mask is 0x1800
-               00, 00,               // left aligned
-               0x50, 00,             // line spacing 80
-               0x1C, 00, 00, 00,     // paragprah is 28 long 
-               00, 00,               // paragraph reserved field
-               00, 0x10, 00, 00,     // mask is 0x1000
-               0x50, 00,             // line spacing 80
-               0x19, 00, 00, 00,     // paragraph is 25 long
-           00, 00,               // paragraph reserved field
-           00, 0x18, 00, 00,     // mask is 0x1800 
-           02, 00,               // right aligned
-           0x50, 00,             // line spacing 80
-           0x61, 00, 00, 00,     // paragraph is 97 long
-           00, 00,               // paragraph reserved field
-           00, 0x18, 00, 00,     // mask is 0x1800
-           00, 00,               // left aligned
-           0x50, 00,             // line spacing 80
-           
-           0x1E, 00, 00, 00,     // character run is 30 long
-           01, 00, 02, 00,       // mask is 0x020001
-           01, 00,               // char flags 0x0001 = bold
-           0x14, 00,             // font size 20
-           0x1C, 00, 00, 00,     // character run is 28 long
-           02, 00, 06, 00,       // mask is 0x060002
-           02, 00,               // char flags 0x0002 = italic
-           0x14, 00,             // font size 20
-           00, 00, 00, 05,       // colour blue
-           0x19, 00, 00, 00,     // character run is 25 long
-           00, 00, 06, 00,       // char flags 0x060000
-           0x14, 00,             // font size 20
-           0xFF-256, 0x33, 00, 0xFE-256, // colour red
-           0x60, 00, 00, 00,     // character run is 96 long
-           04, 00, 03, 00,       // mask is 0x030004
-           04, 00,               // char flags 0x0004 = underlined
-           01, 00,               // font index is 1
-           0x18, 00,             // font size 24
-           
-           01, 00, 00, 00,       // character run is 1 long
-           04, 00, 07, 00,       // mask is 0x070004
-           04, 00,               // char flags 0x0004 = underlined
-           01, 00,               // font index is 1 
-           0x18, 00,             // font size 24
-           0xFF-256, 0x33, 00, 0xFE-256 // colour red
-       };
-       private int data_b_text_len = 0xB3;
-       
-       /**
-        * From a real file. Has a mask with more bits
-        *  set than it actually has data for. Shouldn't do,
-        *  but some real files do :(
-        */
-       private byte[] data_c = new byte[] {
-               0, 0, -95, 15, 62, 0, 0, 0,
-               123, 0, 0, 0, 0, 0, 48, 8, 
-               10, 0, 1, 0, 0, 0, 0, 0, 
-               1, 0, 2, 0, 1, 0, 0, 0, 
-               0, 0, 48, 0, 10, 0, 1, 0, 
-               0, 0, 0, 0, 2, 0, 123, 0, 
-               0, 0, 0, 0, 3, 0, 1, 0, 
-               28, 0, 1, 0, 0, 0, 0, 0, 
-               3, 0, 1, 0, 24, 0
-       };
-       private int data_c_text_len = 123-1;
+    };
+    private int data_a_text_len = 0x36-1;
+
+    /**
+     * From a real file: 4 paragraphs with text in 4 different styles:
+     * left aligned+bold (30)
+     * centre aligned+italic+blue (28)
+     * right aligned+red (25)
+     * left aligned+underlined+larger font size (96)
+     * left aligned+underlined+larger font size+red (1)
+     */
+    private byte[] data_b = new byte[] {
+        0, 0, 0xA1-256, 0x0F, 0x80-256, 0, 0, 0,
+        0x1E, 00, 00, 00,     // paragraph is 30 long
+        00, 00,               // paragraph reserved field
+        00, 0x18, 00, 00,     // mask is 0x1800
+        00, 00,               // left aligned
+        0x50, 00,             // line spacing 80
+        0x1C, 00, 00, 00,     // paragprah is 28 long
+        00, 00,               // paragraph reserved field
+        00, 0x10, 00, 00,     // mask is 0x1000
+        0x50, 00,             // line spacing 80
+        0x19, 00, 00, 00,     // paragraph is 25 long
+        00, 00,               // paragraph reserved field
+        00, 0x18, 00, 00,     // mask is 0x1800
+        02, 00,               // right aligned
+        0x50, 00,             // line spacing 80
+        0x61, 00, 00, 00,     // paragraph is 97 long
+        00, 00,               // paragraph reserved field
+        00, 0x18, 00, 00,     // mask is 0x1800
+        00, 00,               // left aligned
+        0x50, 00,             // line spacing 80
+
+        0x1E, 00, 00, 00,     // character run is 30 long
+        01, 00, 02, 00,       // mask is 0x020001
+        01, 00,               // char flags 0x0001 = bold
+        0x14, 00,             // font size 20
+        0x1C, 00, 00, 00,     // character run is 28 long
+        02, 00, 06, 00,       // mask is 0x060002
+        02, 00,               // char flags 0x0002 = italic
+        0x14, 00,             // font size 20
+        00, 00, 00, 05,       // colour blue
+        0x19, 00, 00, 00,     // character run is 25 long
+        00, 00, 06, 00,       // char flags 0x060000
+        0x14, 00,             // font size 20
+        0xFF-256, 0x33, 00, 0xFE-256, // colour red
+        0x60, 00, 00, 00,     // character run is 96 long
+        04, 00, 03, 00,       // mask is 0x030004
+        04, 00,               // char flags 0x0004 = underlined
+        01, 00,               // font index is 1
+        0x18, 00,             // font size 24
+
+        01, 00, 00, 00,       // character run is 1 long
+        04, 00, 07, 00,       // mask is 0x070004
+        04, 00,               // char flags 0x0004 = underlined
+        01, 00,               // font index is 1
+        0x18, 00,             // font size 24
+        0xFF-256, 0x33, 00, 0xFE-256 // colour red
+    };
+    private int data_b_text_len = 0xB3;
+
+    /**
+     * From a real file. Has a mask with more bits
+     *  set than it actually has data for. Shouldn't do,
+     *  but some real files do :(
+     */
+    private byte[] data_c = new byte[] {
+        0, 0, -95, 15, 62, 0, 0, 0,
+        123, 0, 0, 0, 0, 0, 48, 8,
+        10, 0, 1, 0, 0, 0, 0, 0,
+        1, 0, 2, 0, 1, 0, 0, 0,
+        0, 0, 48, 0, 10, 0, 1, 0,
+        0, 0, 0, 0, 2, 0, 123, 0,
+        0, 0, 0, 0, 3, 0, 1, 0,
+        28, 0, 1, 0, 0, 0, 0, 0,
+        3, 0, 1, 0, 24, 0
+    };
+    private int data_c_text_len = 123-1;
 
     /**
      * From a real file supplied for Bug 40143 by tales@great.ufc.br
@@ -143,576 +144,563 @@ public class TestStyleTextPropAtom extends TestCase {
     private int data_d_text_len = 0xA0-1;
 
     public void testRecordType() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
-               assertEquals(4001l, stpa.getRecordType());
-               assertEquals(4001l, stpb.getRecordType());
-               assertEquals(4001l, stpc.getRecordType());
-       }
-
-
-       public void testCharacterStyleCounts() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-
-               // Set for the appropriate text sizes
-               stpa.setParentTextSize(data_a_text_len);
-               stpb.setParentTextSize(data_b_text_len);
-
-               // In case A, there is a single styling of the characters
-               assertEquals(3, stpa.getCharacterStyles().size());
-               // In case B, there are 5 different stylings
-               assertEquals(5, stpb.getCharacterStyles().size());
-       }
-
-       public void testParagraphStyleCounts() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-
-               // Set for the appropriate text sizes
-               stpa.setParentTextSize(data_a_text_len);
-               stpb.setParentTextSize(data_b_text_len);
-
-               // In case A, all has the same spacing and alignment
-               assertEquals(1, stpa.getParagraphStyles().size());
-               // In case B, all 4 sets have different alignments
-               assertEquals(4, stpb.getParagraphStyles().size());
-       }
-
-
-       public void testCharacterStyleLengths() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-
-               // Set for the appropriate text sizes
-               stpa.setParentTextSize(data_a_text_len);
-               stpb.setParentTextSize(data_b_text_len);
-
-               // 54 chars, 21 + 17 + 16
-               LinkedList a_ch_l = stpa.getCharacterStyles();
-               TextPropCollection a_ch_1 = (TextPropCollection)a_ch_l.get(0);
-               TextPropCollection a_ch_2 = (TextPropCollection)a_ch_l.get(1);
-               TextPropCollection a_ch_3 = (TextPropCollection)a_ch_l.get(2);
-               assertEquals(21, a_ch_1.getCharactersCovered());
-               assertEquals(17, a_ch_2.getCharactersCovered());
-               assertEquals(16, a_ch_3.getCharactersCovered());
-
-               // 179 chars, 30 + 28 + 25
-               LinkedList b_ch_l = stpb.getCharacterStyles();
-               TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
-               TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
-               TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
-               TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
-               assertEquals(30, b_ch_1.getCharactersCovered());
-               assertEquals(28, b_ch_2.getCharactersCovered());
-               assertEquals(25, b_ch_3.getCharactersCovered());
-               assertEquals(96, b_ch_4.getCharactersCovered());
-       }
-
-
-       public void testCharacterPropOrdering() throws Exception {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-
-               LinkedList b_ch_l = stpb.getCharacterStyles();
-               TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
-               TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
-               TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
-               TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
-               
-               // In first set, we get a CharFlagsTextProp and a font.size
-               assertEquals(2,b_ch_1.getTextPropList().size());
-               TextProp tp_1_1 = (TextProp)b_ch_1.getTextPropList().get(0);
-               TextProp tp_1_2 = (TextProp)b_ch_1.getTextPropList().get(1);
-               assertEquals(true, tp_1_1 instanceof CharFlagsTextProp);
-               assertEquals(true, tp_1_2 instanceof TextProp);
-               assertEquals("font.size", tp_1_2.getName());
-               assertEquals(20, tp_1_2.getValue());
-               
-               // In second set, we get a CharFlagsTextProp and a font.size and a font.color
-               assertEquals(3,b_ch_2.getTextPropList().size());
-               TextProp tp_2_1 = (TextProp)b_ch_2.getTextPropList().get(0);
-               TextProp tp_2_2 = (TextProp)b_ch_2.getTextPropList().get(1);
-               TextProp tp_2_3 = (TextProp)b_ch_2.getTextPropList().get(2);
-               assertEquals(true, tp_2_1 instanceof CharFlagsTextProp);
-               assertEquals(true, tp_2_2 instanceof TextProp);
-               assertEquals(true, tp_2_3 instanceof TextProp);
-               assertEquals("font.size", tp_2_2.getName());
-               assertEquals("font.color", tp_2_3.getName());
-               assertEquals(20, tp_2_2.getValue());
-               
-               // In third set, it's just a font.size and a font.color
-               assertEquals(2,b_ch_3.getTextPropList().size());
-               TextProp tp_3_1 = (TextProp)b_ch_3.getTextPropList().get(0);
-               TextProp tp_3_2 = (TextProp)b_ch_3.getTextPropList().get(1);
-               assertEquals(true, tp_3_1 instanceof TextProp);
-               assertEquals(true, tp_3_2 instanceof TextProp);
-               assertEquals("font.size", tp_3_1.getName());
-               assertEquals("font.color", tp_3_2.getName());
-               assertEquals(20, tp_3_1.getValue());
-               
-               // In fourth set, we get a CharFlagsTextProp and a font.index and a font.size
-               assertEquals(3,b_ch_4.getTextPropList().size());
-               TextProp tp_4_1 = (TextProp)b_ch_4.getTextPropList().get(0);
-               TextProp tp_4_2 = (TextProp)b_ch_4.getTextPropList().get(1);
-               TextProp tp_4_3 = (TextProp)b_ch_4.getTextPropList().get(2);
-               assertEquals(true, tp_4_1 instanceof CharFlagsTextProp);
-               assertEquals(true, tp_4_2 instanceof TextProp);
-               assertEquals(true, tp_4_3 instanceof TextProp);
-               assertEquals("font.index", tp_4_2.getName());
-               assertEquals("font.size", tp_4_3.getName());
-               assertEquals(24, tp_4_3.getValue());
-       }
-
-       public void testParagraphProps() throws Exception {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-               
-               LinkedList b_p_l = stpb.getParagraphStyles();
-               TextPropCollection b_p_1 = (TextPropCollection)b_p_l.get(0);
-               TextPropCollection b_p_2 = (TextPropCollection)b_p_l.get(1);
-               TextPropCollection b_p_3 = (TextPropCollection)b_p_l.get(2);
-               TextPropCollection b_p_4 = (TextPropCollection)b_p_l.get(3);
-               
-               // 1st is left aligned + normal line spacing
-               assertEquals(2,b_p_1.getTextPropList().size());
-               TextProp tp_1_1 = (TextProp)b_p_1.getTextPropList().get(0);
-               TextProp tp_1_2 = (TextProp)b_p_1.getTextPropList().get(1);
-               assertEquals(true, tp_1_1 instanceof TextProp);
-               assertEquals(true, tp_1_2 instanceof TextProp);
-               assertEquals("alignment", tp_1_1.getName());
-               assertEquals("linespacing", tp_1_2.getName());
-               assertEquals(0, tp_1_1.getValue());
-               assertEquals(80, tp_1_2.getValue());
-               
-               // 2nd is centre aligned (default) + normal line spacing
-               assertEquals(1,b_p_2.getTextPropList().size());
-               TextProp tp_2_1 = (TextProp)b_p_2.getTextPropList().get(0);
-               assertEquals(true, tp_2_1 instanceof TextProp);
-               assertEquals(true, tp_1_2 instanceof TextProp);
-               assertEquals("linespacing", tp_2_1.getName());
-               assertEquals(80, tp_2_1.getValue());
-               
-               // 3rd is right aligned + normal line spacing
-               assertEquals(2,b_p_3.getTextPropList().size());
-               TextProp tp_3_1 = (TextProp)b_p_3.getTextPropList().get(0);
-               TextProp tp_3_2 = (TextProp)b_p_3.getTextPropList().get(1);
-               assertEquals(true, tp_3_1 instanceof TextProp);
-               assertEquals(true, tp_3_2 instanceof TextProp);
-               assertEquals("alignment", tp_3_1.getName());
-               assertEquals("linespacing", tp_3_2.getName());
-               assertEquals(2, tp_3_1.getValue());
-               assertEquals(80, tp_3_2.getValue());
-               
-               // 4st is left aligned + normal line spacing (despite differing font)
-               assertEquals(2,b_p_4.getTextPropList().size());
-               TextProp tp_4_1 = (TextProp)b_p_4.getTextPropList().get(0);
-               TextProp tp_4_2 = (TextProp)b_p_4.getTextPropList().get(1);
-               assertEquals(true, tp_4_1 instanceof TextProp);
-               assertEquals(true, tp_4_2 instanceof TextProp);
-               assertEquals("alignment", tp_4_1.getName());
-               assertEquals("linespacing", tp_4_2.getName());
-               assertEquals(0, tp_4_1.getValue());
-               assertEquals(80, tp_4_2.getValue());
-       }
-
-       public void testCharacterProps() throws Exception {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-
-               LinkedList b_ch_l = stpb.getCharacterStyles();
-               TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
-               TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
-               TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
-               TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
-
-               // 1st is bold
-               CharFlagsTextProp cf_1_1 = (CharFlagsTextProp)b_ch_1.getTextPropList().get(0);
-               assertEquals(true,cf_1_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
-               assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
-               
-               // 2nd is italic
-               CharFlagsTextProp cf_2_1 = (CharFlagsTextProp)b_ch_2.getTextPropList().get(0);
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
-               assertEquals(true,cf_2_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
-               assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
-
-               // 3rd is normal, so lacks a CharFlagsTextProp
-               assertFalse(b_ch_3.getTextPropList().get(0) instanceof CharFlagsTextProp);
-               
-               // 4th is underlined
-               CharFlagsTextProp cf_4_1 = (CharFlagsTextProp)b_ch_4.getTextPropList().get(0);
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
-               assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
-               
-               // The value for this should be 4
-               assertEquals(0x0004, cf_4_1.getValue());
-               
-               // Now make the 4th bold, italic and not underlined
-               cf_4_1.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
-               cf_4_1.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
-               cf_4_1.setSubValue(false, CharFlagsTextProp.UNDERLINE_IDX);
-               
-               assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
-               assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
-               assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
-               
-               // The value should now be 3
-               assertEquals(0x0003, cf_4_1.getValue());
-       }
-       
-       public void testFindAddTextProp() {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-
-               LinkedList b_p_l = stpb.getParagraphStyles();
-               TextPropCollection b_p_1 = (TextPropCollection)b_p_l.get(0);
-               TextPropCollection b_p_2 = (TextPropCollection)b_p_l.get(1);
-               TextPropCollection b_p_3 = (TextPropCollection)b_p_l.get(2);
-               TextPropCollection b_p_4 = (TextPropCollection)b_p_l.get(3);
-               
-               LinkedList b_ch_l = stpb.getCharacterStyles();
-               TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
-               TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
-               TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
-               TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
-
-               // CharFlagsTextProp: 3 doesn't have, 4 does
-               assertNull(b_ch_3.findByName("char_flags"));
-               assertNotNull(b_ch_4.findByName("char_flags"));
-               
-               // Now add in on 3, should go to front
-               assertEquals(2, b_ch_3.getTextPropList().size());
-               TextProp new_cftp = b_ch_3.addWithName("char_flags");
-               assertEquals(3, b_ch_3.getTextPropList().size());
-               assertEquals(new_cftp, b_ch_3.getTextPropList().get(0));
-               
-               // alignment: 1 does have, 2 doesn't
-               assertNotNull(b_p_1.findByName("alignment"));
-               assertNull(b_p_2.findByName("alignment"));
-               
-               // Now add in on 2, should go to the front
-               assertEquals(1, b_p_2.getTextPropList().size());
-               TextProp new_al = b_p_2.addWithName("alignment");
-               assertEquals(2, b_p_2.getTextPropList().size());
-               assertEquals(new_al, b_p_2.getTextPropList().get(0));
-               
-               // This should go at the end
-               TextProp new_sa = b_p_2.addWithName("spaceafter");
-               assertEquals(3, b_p_2.getTextPropList().size());
-               assertEquals(new_sa, b_p_2.getTextPropList().get(2));
-               
-               // Check we get an error with a made up one
-               try {
-                       b_p_2.addWithName("madeUpOne");
-                       fail();
-               } catch(IllegalArgumentException e) {
-                       // Good, as expected
-               }
-       }
-       
-       /**
-        * Try to recreate an existing StyleTextPropAtom (a) from the empty
-        *  constructor, and setting the required properties
-        */
-       public void testCreateAFromScatch() throws Exception {
-               // Start with an empty one
-               StyleTextPropAtom stpa = new StyleTextPropAtom(54);
-               
-               // Don't need to touch the paragraph styles
-               // Add two more character styles
-               LinkedList cs = stpa.getCharacterStyles();
-               
-               // First char style is boring, and 21 long
-               TextPropCollection tpca = (TextPropCollection)cs.get(0);
-               tpca.updateTextSize(21);
-               
-               // Second char style is coloured, 00 00 00 05, and 17 long
-               TextPropCollection tpcb = stpa.addCharacterTextPropCollection(17);
-               TextProp tpb = tpcb.addWithName("font.color");
-               tpb.setValue(0x05000000);
-               
-               // Third char style is coloured, FF 33 00 FE, and 16 long
-               TextPropCollection tpcc = stpa.addCharacterTextPropCollection(16);
-               TextProp tpc = tpcc.addWithName("font.color");
-               tpc.setValue(0xFE0033FF);
-               
-               // Should now be the same as data_a
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpa.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_a.length, b.length);
-               for(int i=0; i<data_a.length; i++) {
-                       assertEquals(data_a[i],b[i]);
-               }
-       }
-
-       /**
-        * Try to recreate an existing StyleTextPropAtom (b) from the empty
-        *  constructor, and setting the required properties
-        */
-       public void testCreateBFromScatch() throws Exception {
-               // Start with an empty one
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_b_text_len);
-               
-               
-               // Need 4 paragraph styles
-               LinkedList ps = stpa.getParagraphStyles();
-               
-               // First is 30 long, left aligned, normal spacing
-               TextPropCollection tppa = (TextPropCollection)ps.get(0);
-               tppa.updateTextSize(30);
-               
-               TextProp tp = tppa.addWithName("alignment");
-               tp.setValue(0);
-               tp = tppa.addWithName("linespacing");
-               tp.setValue(80);
-
-               // Second is 28 long, centre aligned and normal spacing
-               TextPropCollection tppb = stpa.addParagraphTextPropCollection(28);
-               
-               tp = tppb.addWithName("linespacing");
-               tp.setValue(80);
-               
-               // Third is 25 long, right aligned and normal spacing
-               TextPropCollection tppc = stpa.addParagraphTextPropCollection(25);
-               
-               tp = tppc.addWithName("alignment");
-               tp.setValue(2);
-               tp = tppc.addWithName("linespacing");
-               tp.setValue(80);
-               
-               // Forth is left aligned + normal line spacing (despite differing font)
-               TextPropCollection tppd = stpa.addParagraphTextPropCollection(97);
-               
-               tp = tppd.addWithName("alignment");
-               tp.setValue(0);
-               tp = tppd.addWithName("linespacing");
-               tp.setValue(80);
-               
-               
-               // Now do 4 character styles
-               LinkedList cs = stpa.getCharacterStyles();
-               
-               // First is 30 long, bold and font size
-               TextPropCollection tpca = (TextPropCollection)cs.get(0);
-               tpca.updateTextSize(30);
-               
-               tp = tpca.addWithName("font.size");
-               tp.setValue(20);
-               CharFlagsTextProp cftp = (CharFlagsTextProp)
-                       tpca.addWithName("char_flags");
-               assertEquals(0, cftp.getValue());
-               cftp.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
-               assertEquals(1, cftp.getValue());
-               
-               // Second is 28 long, blue and italic
-               TextPropCollection tpcb = stpa.addCharacterTextPropCollection(28);
-               
-               tp = tpcb.addWithName("font.size");
-               tp.setValue(20);
-               tp = tpcb.addWithName("font.color");
-               tp.setValue(0x05000000);
-               cftp = (CharFlagsTextProp)tpcb.addWithName("char_flags");
-               cftp.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
-               assertEquals(2, cftp.getValue());
-               
-               // Third is 25 long and red
-               TextPropCollection tpcc = stpa.addCharacterTextPropCollection(25);
-               
-               tp = tpcc.addWithName("font.size");
-               tp.setValue(20);
-               tp = tpcc.addWithName("font.color");
-               tp.setValue(0xfe0033ff);
-               
-               // Fourth is 96 long, underlined and different+bigger font 
-               TextPropCollection tpcd = stpa.addCharacterTextPropCollection(96);
-               
-               tp = tpcd.addWithName("font.size");
-               tp.setValue(24);
-               tp = tpcd.addWithName("font.index");
-               tp.setValue(1);
-               cftp = (CharFlagsTextProp)tpcd.addWithName("char_flags");
-               cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
-               assertEquals(4, cftp.getValue());
-               
-               // Fifth is 1 long, underlined and different+bigger font + red
-               TextPropCollection tpce = stpa.addCharacterTextPropCollection(1);
-               
-               tp = tpce.addWithName("font.size");
-               tp.setValue(24);
-               tp = tpce.addWithName("font.index");
-               tp.setValue(1);
-               tp = tpce.addWithName("font.color");
-               tp.setValue(0xfe0033ff);
-               cftp = (CharFlagsTextProp)tpce.addWithName("char_flags");
-               cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
-               assertEquals(4, cftp.getValue());
-               
-               
-               // Check it's as expected
-               assertEquals(4, stpa.getParagraphStyles().size());
-               assertEquals(5, stpa.getCharacterStyles().size());
-               
-               // Compare in detail to b
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-               LinkedList psb = stpb.getParagraphStyles();
-               LinkedList csb = stpb.getCharacterStyles();
-               
-               assertEquals(psb.size(), ps.size());
-               assertEquals(csb.size(), cs.size());
-               
-               // Ensure Paragraph Character styles match
-               for(int z=0; z<2; z++) {
-                       LinkedList lla = cs; 
-                       LinkedList llb = csb;
-                       int upto = 5;
-                       if(z == 1) {
-                               lla = ps;
-                               llb = psb;
-                               upto = 4;
-                       }
-                       
-                       for(int i=0; i<upto; i++) {
-                               TextPropCollection ca = (TextPropCollection)lla.get(i);
-                               TextPropCollection cb = (TextPropCollection)llb.get(i);
-                               
-                               assertEquals(ca.getCharactersCovered(), cb.getCharactersCovered());
-                               assertEquals(ca.getTextPropList().size(), cb.getTextPropList().size());
-                               
-                               for(int j=0; j<ca.getTextPropList().size(); j++) {
-                                       TextProp tpa = (TextProp)ca.getTextPropList().get(j);
-                                       TextProp tpb = (TextProp)cb.getTextPropList().get(j);
-                                       //System.out.println("TP " + i + " " + j + " " + tpa.getName() + "\t" + tpa.getValue() );
-                                       assertEquals(tpa.getName(), tpb.getName());
-                                       assertEquals(tpa.getMask(), tpb.getMask());
-                                       assertEquals(tpa.getWriteMask(), tpb.getWriteMask());
-                                       assertEquals(tpa.getValue(), tpb.getValue());
-                               }
-                               
-                               ByteArrayOutputStream ba = new ByteArrayOutputStream();
-                               ByteArrayOutputStream bb = new ByteArrayOutputStream();
-                               
-                               ca.writeOut(ba);
-                               cb.writeOut(bb);
-                               byte[] cab = ba.toByteArray(); 
-                               byte[] cbb = bb.toByteArray();
-                               
-                               assertEquals(cbb.length, cab.length);
-                               for(int j=0; j<cab.length; j++) {
-                                       //System.out.println("On tp " + z + " " + i + " " + j + "\t" + cab[j] + "\t" + cbb[j]);
-                                       assertEquals(cbb[j], cab[j]);
-                               }
-                       }
-               }
-               
-
-               
-               // Check byte level with b
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpa.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_b.length, b.length);
-               for(int i=0; i<data_b.length; i++) {
-                       System.out.println(i + "\t" + b[i] + "\t" + data_b[i] + "\t" + Integer.toHexString(b[i]) );
-                       assertEquals(data_b[i],b[i]);
-               }
-       }
-
-       public void testWriteA() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpa.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_a.length, b.length);
-               for(int i=0; i<data_a.length; i++) {
-                       assertEquals(data_a[i],b[i]);
-               }
-       }
-
-       public void testLoadWriteA() throws Exception {
-               StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
-               stpa.setParentTextSize(data_a_text_len);
-
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpa.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_a.length, b.length);
-               for(int i=0; i<data_a.length; i++) {
-                       assertEquals(data_a[i],b[i]);
-               }
-       }
-
-
-       public void testWriteB() throws Exception {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpb.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_b.length, b.length);
-               for(int i=0; i<data_b.length; i++) {
-                       assertEquals(data_b[i],b[i]);
-               }
-       }
-
-       public void testLoadWriteB() throws Exception {
-               StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
-               stpb.setParentTextSize(data_b_text_len);
-
-               ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               stpb.writeOut(baos);
-               byte[] b = baos.toByteArray();
-
-               assertEquals(data_b.length, b.length);
-               for(int i=0; i<data_b.length; i++) {
-                       //System.out.println(i + "\t" + b[i] + "\t" + data_b[i] + "\t" + Integer.toHexString(b[i]) );
-                       assertEquals(data_b[i],b[i]);
-               }
-       }
-       
-       
-       public void testNotEnoughDataProp() throws Exception {
-               // We don't have enough data in the record to cover
-               //  all the properties the mask says we have
-               // Make sure we just do the best we can
-               StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
-               stpc.setParentTextSize(data_c_text_len);
-               
-               // If we get here, we didn't break
-       }
+        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
+        assertEquals(4001l, stpa.getRecordType());
+        assertEquals(4001l, stpb.getRecordType());
+        assertEquals(4001l, stpc.getRecordType());
+    }
+
+
+    public void testCharacterStyleCounts() throws Exception {
+        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+
+        // Set for the appropriate text sizes
+        stpa.setParentTextSize(data_a_text_len);
+        stpb.setParentTextSize(data_b_text_len);
+
+        // In case A, there is a single styling of the characters
+        assertEquals(3, stpa.getCharacterStyles().size());
+        // In case B, there are 5 different stylings
+        assertEquals(5, stpb.getCharacterStyles().size());
+    }
+
+    public void testParagraphStyleCounts() throws Exception {
+        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+
+        // Set for the appropriate text sizes
+        stpa.setParentTextSize(data_a_text_len);
+        stpb.setParentTextSize(data_b_text_len);
+
+        // In case A, all has the same spacing and alignment
+        assertEquals(1, stpa.getParagraphStyles().size());
+        // In case B, all 4 sets have different alignments
+        assertEquals(4, stpb.getParagraphStyles().size());
+    }
+
+
+    public void testCharacterStyleLengths() throws Exception {
+        StyleTextPropAtom stpa = new StyleTextPropAtom(data_a,0,data_a.length);
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+
+        // Set for the appropriate text sizes
+        stpa.setParentTextSize(data_a_text_len);
+        stpb.setParentTextSize(data_b_text_len);
+
+        // 54 chars, 21 + 17 + 16
+        LinkedList a_ch_l = stpa.getCharacterStyles();
+        TextPropCollection a_ch_1 = (TextPropCollection)a_ch_l.get(0);
+        TextPropCollection a_ch_2 = (TextPropCollection)a_ch_l.get(1);
+        TextPropCollection a_ch_3 = (TextPropCollection)a_ch_l.get(2);
+        assertEquals(21, a_ch_1.getCharactersCovered());
+        assertEquals(17, a_ch_2.getCharactersCovered());
+        assertEquals(16, a_ch_3.getCharactersCovered());
+
+        // 179 chars, 30 + 28 + 25
+        LinkedList b_ch_l = stpb.getCharacterStyles();
+        TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
+        TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
+        TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
+        TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
+        assertEquals(30, b_ch_1.getCharactersCovered());
+        assertEquals(28, b_ch_2.getCharactersCovered());
+        assertEquals(25, b_ch_3.getCharactersCovered());
+        assertEquals(96, b_ch_4.getCharactersCovered());
+    }
+
+
+    public void testCharacterPropOrdering() throws Exception {
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        stpb.setParentTextSize(data_b_text_len);
+
+        LinkedList b_ch_l = stpb.getCharacterStyles();
+        TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
+        TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
+        TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
+        TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
+
+        // In first set, we get a CharFlagsTextProp and a font.size
+        assertEquals(2,b_ch_1.getTextPropList().size());
+        TextProp tp_1_1 = (TextProp)b_ch_1.getTextPropList().get(0);
+        TextProp tp_1_2 = (TextProp)b_ch_1.getTextPropList().get(1);
+        assertEquals(true, tp_1_1 instanceof CharFlagsTextProp);
+        assertEquals(true, tp_1_2 instanceof TextProp);
+        assertEquals("font.size", tp_1_2.getName());
+        assertEquals(20, tp_1_2.getValue());
+
+        // In second set, we get a CharFlagsTextProp and a font.size and a font.color
+        assertEquals(3,b_ch_2.getTextPropList().size());
+        TextProp tp_2_1 = (TextProp)b_ch_2.getTextPropList().get(0);
+        TextProp tp_2_2 = (TextProp)b_ch_2.getTextPropList().get(1);
+        TextProp tp_2_3 = (TextProp)b_ch_2.getTextPropList().get(2);
+        assertEquals(true, tp_2_1 instanceof CharFlagsTextProp);
+        assertEquals(true, tp_2_2 instanceof TextProp);
+        assertEquals(true, tp_2_3 instanceof TextProp);
+        assertEquals("font.size", tp_2_2.getName());
+        assertEquals("font.color", tp_2_3.getName());
+        assertEquals(20, tp_2_2.getValue());
+
+        // In third set, it's just a font.size and a font.color
+        assertEquals(2,b_ch_3.getTextPropList().size());
+        TextProp tp_3_1 = (TextProp)b_ch_3.getTextPropList().get(0);
+        TextProp tp_3_2 = (TextProp)b_ch_3.getTextPropList().get(1);
+        assertEquals(true, tp_3_1 instanceof TextProp);
+        assertEquals(true, tp_3_2 instanceof TextProp);
+        assertEquals("font.size", tp_3_1.getName());
+        assertEquals("font.color", tp_3_2.getName());
+        assertEquals(20, tp_3_1.getValue());
+
+        // In fourth set, we get a CharFlagsTextProp and a font.index and a font.size
+        assertEquals(3,b_ch_4.getTextPropList().size());
+        TextProp tp_4_1 = (TextProp)b_ch_4.getTextPropList().get(0);
+        TextProp tp_4_2 = (TextProp)b_ch_4.getTextPropList().get(1);
+        TextProp tp_4_3 = (TextProp)b_ch_4.getTextPropList().get(2);
+        assertEquals(true, tp_4_1 instanceof CharFlagsTextProp);
+        assertEquals(true, tp_4_2 instanceof TextProp);
+        assertEquals(true, tp_4_3 instanceof TextProp);
+        assertEquals("font.index", tp_4_2.getName());
+        assertEquals("font.size", tp_4_3.getName());
+        assertEquals(24, tp_4_3.getValue());
+    }
+
+    public void testParagraphProps() throws Exception {
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        stpb.setParentTextSize(data_b_text_len);
+
+        LinkedList b_p_l = stpb.getParagraphStyles();
+        TextPropCollection b_p_1 = (TextPropCollection)b_p_l.get(0);
+        TextPropCollection b_p_2 = (TextPropCollection)b_p_l.get(1);
+        TextPropCollection b_p_3 = (TextPropCollection)b_p_l.get(2);
+        TextPropCollection b_p_4 = (TextPropCollection)b_p_l.get(3);
+
+        // 1st is left aligned + normal line spacing
+        assertEquals(2,b_p_1.getTextPropList().size());
+        TextProp tp_1_1 = (TextProp)b_p_1.getTextPropList().get(0);
+        TextProp tp_1_2 = (TextProp)b_p_1.getTextPropList().get(1);
+        assertEquals(true, tp_1_1 instanceof TextProp);
+        assertEquals(true, tp_1_2 instanceof TextProp);
+        assertEquals("alignment", tp_1_1.getName());
+        assertEquals("linespacing", tp_1_2.getName());
+        assertEquals(0, tp_1_1.getValue());
+        assertEquals(80, tp_1_2.getValue());
+
+        // 2nd is centre aligned (default) + normal line spacing
+        assertEquals(1,b_p_2.getTextPropList().size());
+        TextProp tp_2_1 = (TextProp)b_p_2.getTextPropList().get(0);
+        assertEquals(true, tp_2_1 instanceof TextProp);
+        assertEquals(true, tp_1_2 instanceof TextProp);
+        assertEquals("linespacing", tp_2_1.getName());
+        assertEquals(80, tp_2_1.getValue());
+
+        // 3rd is right aligned + normal line spacing
+        assertEquals(2,b_p_3.getTextPropList().size());
+        TextProp tp_3_1 = (TextProp)b_p_3.getTextPropList().get(0);
+        TextProp tp_3_2 = (TextProp)b_p_3.getTextPropList().get(1);
+        assertEquals(true, tp_3_1 instanceof TextProp);
+        assertEquals(true, tp_3_2 instanceof TextProp);
+        assertEquals("alignment", tp_3_1.getName());
+        assertEquals("linespacing", tp_3_2.getName());
+        assertEquals(2, tp_3_1.getValue());
+        assertEquals(80, tp_3_2.getValue());
+
+        // 4st is left aligned + normal line spacing (despite differing font)
+        assertEquals(2,b_p_4.getTextPropList().size());
+        TextProp tp_4_1 = (TextProp)b_p_4.getTextPropList().get(0);
+        TextProp tp_4_2 = (TextProp)b_p_4.getTextPropList().get(1);
+        assertEquals(true, tp_4_1 instanceof TextProp);
+        assertEquals(true, tp_4_2 instanceof TextProp);
+        assertEquals("alignment", tp_4_1.getName());
+        assertEquals("linespacing", tp_4_2.getName());
+        assertEquals(0, tp_4_1.getValue());
+        assertEquals(80, tp_4_2.getValue());
+    }
+
+    public void testCharacterProps() throws Exception {
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        stpb.setParentTextSize(data_b_text_len);
+
+        LinkedList b_ch_l = stpb.getCharacterStyles();
+        TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
+        TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
+        TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
+        TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
+
+        // 1st is bold
+        CharFlagsTextProp cf_1_1 = (CharFlagsTextProp)b_ch_1.getTextPropList().get(0);
+        assertEquals(true,cf_1_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
+        assertEquals(false,cf_1_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
+
+        // 2nd is italic
+        CharFlagsTextProp cf_2_1 = (CharFlagsTextProp)b_ch_2.getTextPropList().get(0);
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
+        assertEquals(true,cf_2_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
+        assertEquals(false,cf_2_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
+
+        // 3rd is normal, so lacks a CharFlagsTextProp
+        assertFalse(b_ch_3.getTextPropList().get(0) instanceof CharFlagsTextProp);
+
+        // 4th is underlined
+        CharFlagsTextProp cf_4_1 = (CharFlagsTextProp)b_ch_4.getTextPropList().get(0);
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
+        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
+
+        // The value for this should be 4
+        assertEquals(0x0004, cf_4_1.getValue());
+
+        // Now make the 4th bold, italic and not underlined
+        cf_4_1.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
+        cf_4_1.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
+        cf_4_1.setSubValue(false, CharFlagsTextProp.UNDERLINE_IDX);
+
+        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.BOLD_IDX));
+        assertEquals(true,cf_4_1.getSubValue(CharFlagsTextProp.ITALIC_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_1_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.ENABLE_NUMBERING_2_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RELIEF_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.RESET_NUMBERING_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.SHADOW_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.STRIKETHROUGH_IDX));
+        assertEquals(false,cf_4_1.getSubValue(CharFlagsTextProp.UNDERLINE_IDX));
+
+        // The value should now be 3
+        assertEquals(0x0003, cf_4_1.getValue());
+    }
+
+    public void testFindAddTextProp() {
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        stpb.setParentTextSize(data_b_text_len);
+
+        LinkedList b_p_l = stpb.getParagraphStyles();
+        TextPropCollection b_p_1 = (TextPropCollection)b_p_l.get(0);
+        TextPropCollection b_p_2 = (TextPropCollection)b_p_l.get(1);
+        TextPropCollection b_p_3 = (TextPropCollection)b_p_l.get(2);
+        TextPropCollection b_p_4 = (TextPropCollection)b_p_l.get(3);
+
+        LinkedList b_ch_l = stpb.getCharacterStyles();
+        TextPropCollection b_ch_1 = (TextPropCollection)b_ch_l.get(0);
+        TextPropCollection b_ch_2 = (TextPropCollection)b_ch_l.get(1);
+        TextPropCollection b_ch_3 = (TextPropCollection)b_ch_l.get(2);
+        TextPropCollection b_ch_4 = (TextPropCollection)b_ch_l.get(3);
+
+        // CharFlagsTextProp: 3 doesn't have, 4 does
+        assertNull(b_ch_3.findByName("char_flags"));
+        assertNotNull(b_ch_4.findByName("char_flags"));
+
+        // Now add in on 3, should go to front
+        assertEquals(2, b_ch_3.getTextPropList().size());
+        TextProp new_cftp = b_ch_3.addWithName("char_flags");
+        assertEquals(3, b_ch_3.getTextPropList().size());
+        assertEquals(new_cftp, b_ch_3.getTextPropList().get(0));
+
+        // alignment: 1 does have, 2 doesn't
+        assertNotNull(b_p_1.findByName("alignment"));
+        assertNull(b_p_2.findByName("alignment"));
+
+        // Now add in on 2, should go to the front
+        assertEquals(1, b_p_2.getTextPropList().size());
+        TextProp new_al = b_p_2.addWithName("alignment");
+        assertEquals(2, b_p_2.getTextPropList().size());
+        assertEquals(new_al, b_p_2.getTextPropList().get(0));
+
+        // This should go at the end
+        TextProp new_sa = b_p_2.addWithName("spaceafter");
+        assertEquals(3, b_p_2.getTextPropList().size());
+        assertEquals(new_sa, b_p_2.getTextPropList().get(2));
+
+        // Check we get an error with a made up one
+        try {
+            b_p_2.addWithName("madeUpOne");
+            fail();
+        } catch(IllegalArgumentException e) {
+            // Good, as expected
+        }
+    }
+
+    /**
+     * Try to recreate an existing StyleTextPropAtom (a) from the empty
+     *  constructor, and setting the required properties
+     */
+    public void testCreateAFromScatch() throws Exception {
+        // Start with an empty one
+        StyleTextPropAtom stpa = new StyleTextPropAtom(54);
+
+        // Don't need to touch the paragraph styles
+        // Add two more character styles
+        LinkedList cs = stpa.getCharacterStyles();
+
+        // First char style is boring, and 21 long
+        TextPropCollection tpca = (TextPropCollection)cs.get(0);
+        tpca.updateTextSize(21);
+
+        // Second char style is coloured, 00 00 00 05, and 17 long
+        TextPropCollection tpcb = stpa.addCharacterTextPropCollection(17);
+        TextProp tpb = tpcb.addWithName("font.color");
+        tpb.setValue(0x05000000);
+
+        // Third char style is coloured, FF 33 00 FE, and 16 long
+        TextPropCollection tpcc = stpa.addCharacterTextPropCollection(16);
+        TextProp tpc = tpcc.addWithName("font.color");
+        tpc.setValue(0xFE0033FF);
+
+        // Should now be the same as data_a
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        stpa.writeOut(baos);
+        byte[] b = baos.toByteArray();
+
+        assertEquals(data_a.length, b.length);
+        for(int i=0; i<data_a.length; i++) {
+            assertEquals(data_a[i],b[i]);
+        }
+    }
+
+    /**
+     * Try to recreate an existing StyleTextPropAtom (b) from the empty
+     *  constructor, and setting the required properties
+     */
+    public void testCreateBFromScatch() throws Exception {
+        // Start with an empty one
+        StyleTextPropAtom stpa = new StyleTextPropAtom(data_b_text_len);
+
+
+        // Need 4 paragraph styles
+        LinkedList ps = stpa.getParagraphStyles();
+
+        // First is 30 long, left aligned, normal spacing
+        TextPropCollection tppa = (TextPropCollection)ps.get(0);
+        tppa.updateTextSize(30);
+
+        TextProp tp = tppa.addWithName("alignment");
+        tp.setValue(0);
+        tp = tppa.addWithName("linespacing");
+        tp.setValue(80);
+
+        // Second is 28 long, centre aligned and normal spacing
+        TextPropCollection tppb = stpa.addParagraphTextPropCollection(28);
+
+        tp = tppb.addWithName("linespacing");
+        tp.setValue(80);
+
+        // Third is 25 long, right aligned and normal spacing
+        TextPropCollection tppc = stpa.addParagraphTextPropCollection(25);
+
+        tp = tppc.addWithName("alignment");
+        tp.setValue(2);
+        tp = tppc.addWithName("linespacing");
+        tp.setValue(80);
+
+        // Forth is left aligned + normal line spacing (despite differing font)
+        TextPropCollection tppd = stpa.addParagraphTextPropCollection(97);
+
+        tp = tppd.addWithName("alignment");
+        tp.setValue(0);
+        tp = tppd.addWithName("linespacing");
+        tp.setValue(80);
+
+
+        // Now do 4 character styles
+        LinkedList cs = stpa.getCharacterStyles();
+
+        // First is 30 long, bold and font size
+        TextPropCollection tpca = (TextPropCollection)cs.get(0);
+        tpca.updateTextSize(30);
+
+        tp = tpca.addWithName("font.size");
+        tp.setValue(20);
+        CharFlagsTextProp cftp = (CharFlagsTextProp)
+            tpca.addWithName("char_flags");
+        assertEquals(0, cftp.getValue());
+        cftp.setSubValue(true, CharFlagsTextProp.BOLD_IDX);
+        assertEquals(1, cftp.getValue());
+
+        // Second is 28 long, blue and italic
+        TextPropCollection tpcb = stpa.addCharacterTextPropCollection(28);
+
+        tp = tpcb.addWithName("font.size");
+        tp.setValue(20);
+        tp = tpcb.addWithName("font.color");
+        tp.setValue(0x05000000);
+        cftp = (CharFlagsTextProp)tpcb.addWithName("char_flags");
+        cftp.setSubValue(true, CharFlagsTextProp.ITALIC_IDX);
+        assertEquals(2, cftp.getValue());
+
+        // Third is 25 long and red
+        TextPropCollection tpcc = stpa.addCharacterTextPropCollection(25);
+
+        tp = tpcc.addWithName("font.size");
+        tp.setValue(20);
+        tp = tpcc.addWithName("font.color");
+        tp.setValue(0xfe0033ff);
+
+        // Fourth is 96 long, underlined and different+bigger font
+        TextPropCollection tpcd = stpa.addCharacterTextPropCollection(96);
+
+        tp = tpcd.addWithName("font.size");
+        tp.setValue(24);
+        tp = tpcd.addWithName("font.index");
+        tp.setValue(1);
+        cftp = (CharFlagsTextProp)tpcd.addWithName("char_flags");
+        cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
+        assertEquals(4, cftp.getValue());
+
+        // Fifth is 1 long, underlined and different+bigger font + red
+        TextPropCollection tpce = stpa.addCharacterTextPropCollection(1);
+
+        tp = tpce.addWithName("font.size");
+        tp.setValue(24);
+        tp = tpce.addWithName("font.index");
+        tp.setValue(1);
+        tp = tpce.addWithName("font.color");
+        tp.setValue(0xfe0033ff);
+        cftp = (CharFlagsTextProp)tpce.addWithName("char_flags");
+        cftp.setSubValue(true, CharFlagsTextProp.UNDERLINE_IDX);
+        assertEquals(4, cftp.getValue());
+
+
+        // Check it's as expected
+        assertEquals(4, stpa.getParagraphStyles().size());
+        assertEquals(5, stpa.getCharacterStyles().size());
+
+        // Compare in detail to b
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data_b,0,data_b.length);
+        stpb.setParentTextSize(data_b_text_len);
+        LinkedList psb = stpb.getParagraphStyles();
+        LinkedList csb = stpb.getCharacterStyles();
+
+        assertEquals(psb.size(), ps.size());
+        assertEquals(csb.size(), cs.size());
+
+        // Ensure Paragraph Character styles match
+        for(int z=0; z<2; z++) {
+            LinkedList lla = cs;
+            LinkedList llb = csb;
+            int upto = 5;
+            if(z == 1) {
+                lla = ps;
+                llb = psb;
+                upto = 4;
+            }
+
+            for(int i=0; i<upto; i++) {
+                TextPropCollection ca = (TextPropCollection)lla.get(i);
+                TextPropCollection cb = (TextPropCollection)llb.get(i);
+
+                assertEquals(ca.getCharactersCovered(), cb.getCharactersCovered());
+                assertEquals(ca.getTextPropList().size(), cb.getTextPropList().size());
+
+                for(int j=0; j<ca.getTextPropList().size(); j++) {
+                    TextProp tpa = (TextProp)ca.getTextPropList().get(j);
+                    TextProp tpb = (TextProp)cb.getTextPropList().get(j);
+                    //System.out.println("TP " + i + " " + j + " " + tpa.getName() + "\t" + tpa.getValue() );
+                    assertEquals(tpa.getName(), tpb.getName());
+                    assertEquals(tpa.getMask(), tpb.getMask());
+                    assertEquals(tpa.getWriteMask(), tpb.getWriteMask());
+                    assertEquals(tpa.getValue(), tpb.getValue());
+                }
+
+                ByteArrayOutputStream ba = new ByteArrayOutputStream();
+                ByteArrayOutputStream bb = new ByteArrayOutputStream();
+
+                ca.writeOut(ba);
+                cb.writeOut(bb);
+                byte[] cab = ba.toByteArray();
+                byte[] cbb = bb.toByteArray();
+
+                assertEquals(cbb.length, cab.length);
+                for(int j=0; j<cab.length; j++) {
+                    //System.out.println("On tp " + z + " " + i + " " + j + "\t" + cab[j] + "\t" + cbb[j]);
+                    assertEquals(cbb[j], cab[j]);
+                }
+            }
+        }
+
+
+
+        // Check byte level with b
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        stpa.writeOut(baos);
+        byte[] b = baos.toByteArray();
+
+        assertEquals(data_b.length, b.length);
+        for(int i=0; i<data_b.length; i++) {
+            //System.out.println(i + "\t" + b[i] + "\t" + data_b[i] + "\t" + Integer.toHexString(b[i]) );
+            assertEquals(data_b[i],b[i]);
+        }
+    }
+
+    public void testWriteA() throws Exception {
+        doReadWrite(data_a, -1);
+    }
+
+    public void testLoadWriteA() throws Exception {
+        doReadWrite(data_b, data_b_text_len);
+    }
+
+
+    public void testWriteB() throws Exception {
+        doReadWrite(data_b, -1);
+    }
+
+    public void testLoadWriteB() throws Exception {
+        doReadWrite(data_b, data_b_text_len);
+    }
+
+    public void testLoadWriteC() throws Exception {
+        doReadWrite(data_c, data_c_text_len);
+    }
+
+    public void testLoadWriteD() throws Exception {
+        doReadWrite(data_d, data_d_text_len);
+    }
+
+    protected void doReadWrite(byte[] data, int textlen) throws Exception {
+        StyleTextPropAtom stpb = new StyleTextPropAtom(data, 0,data.length);
+        if(textlen != -1) stpb.setParentTextSize(textlen);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        stpb.writeOut(out);
+        byte[] bytes = out.toByteArray();
+
+        assertEquals(data.length, bytes.length);
+        try {
+            assertTrue(Arrays.equals(data, bytes));
+        } catch (Throwable e){
+            //print hex dump if failed
+            assertEquals(HexDump.toHex(data), HexDump.toHex(bytes));
+        }
+    }
+
+    public void testNotEnoughDataProp() throws Exception {
+        // We don't have enough data in the record to cover
+        //  all the properties the mask says we have
+        // Make sure we just do the best we can
+        StyleTextPropAtom stpc = new StyleTextPropAtom(data_c,0,data_c.length);
+        stpc.setParentTextSize(data_c_text_len);
+
+        // If we get here, we didn't break
+    }
 
     /**
      * Check the test data for Bug 40143.
@@ -732,8 +720,8 @@ public class TestStyleTextPropAtom extends TestCase {
         assertEquals(1, chprops.findByName("char_flags").getValue());
         assertEquals(1, chprops.findByName("font.index").getValue());
         assertEquals(20, chprops.findByName("font.size").getValue());
-        assertEquals(0, chprops.findByName("asian_or_complex").getValue());
-        assertEquals(1, chprops.findByName("char_unknown_2").getValue());
+        assertEquals(0, chprops.findByName("asian.font.index").getValue());
+        assertEquals(1, chprops.findByName("ansi.font.index").getValue());
     }
 
     /**
@@ -747,16 +735,7 @@ public class TestStyleTextPropAtom extends TestCase {
                        0x00 , 0x00 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x63 , 0x00 ,
                        0x00 , 0x00 , 0x01 , 0x00 , 0x00 , 0x00 , 0x0F , 0x00
         };
-        StyleTextPropAtom stpa = new StyleTextPropAtom(data,0,data.length);
-        stpa.setParentTextSize(length);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        stpa.writeOut(baos);
-        byte[] b = baos.toByteArray();
-
-        assertEquals(data.length, b.length);
-        for(int i=0; i<data.length; i++) {
-            assertEquals(data[i],b[i]);
-        }
+        doReadWrite(data, length);
 
     }
 }