]> source.dussan.org Git - poi.git/commitdiff
properly update TextSpecInfoAtom when parent text is changed
authorYegor Kozlov <yegor@apache.org>
Wed, 14 May 2008 10:15:00 +0000 (10:15 +0000)
committerYegor Kozlov <yegor@apache.org>
Wed, 14 May 2008 10:15:00 +0000 (10:15 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@656213 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
src/scratchpad/src/org/apache/poi/hslf/record/TextSpecInfoAtom.java
src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java [new file with mode: 0755]

index 5dac650258bad171f3b50df9978940af4c6506e7..f2d265363bc49abe5d7f4f5b7afead87774e2e6b 100644 (file)
@@ -45,7 +45,6 @@ public class TextRun
        protected TextBytesAtom  _byteAtom;
        protected TextCharsAtom  _charAtom;
        protected StyleTextPropAtom _styleAtom;
-    protected TextSpecInfoAtom  _specAtom;
        protected boolean _isUnicode;
        protected RichTextRun[] _rtRuns;
        private SlideShow slideShow;
@@ -361,6 +360,18 @@ public class TextRun
                                _isUnicode = true;
                        }
                }
+        /**
+         * If TextSpecInfoAtom is present, we must update the text size in it,
+         * otherwise the ppt will be corrupted
+         */
+        if(_records != null) for (int i = 0; i < _records.length; i++) {
+            if(_records[i] instanceof TextSpecInfoAtom){
+                TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];
+                if((s.length() + 1) != specAtom.getCharactersCovered()){
+                    specAtom.reset(s.length() + 1);
+                }
+            }
+        }
        }
        
        /**
@@ -474,17 +485,6 @@ public class TextRun
                        _rtRuns[0] = new RichTextRun(this,0,s.length());
                }
 
-        /**
-         * If TextSpecInfoAtom is present, we must update the text size,
-         * otherwise the ppt will be corrupted
-         */
-        if(_records != null) for (int i = 0; i < _records.length; i++) {
-            if(_records[i] instanceof TextSpecInfoAtom){
-                TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];
-                specAtom.setTextSize(s.length());
-            }
-
-        }
        }
 
        /**
index a8915f0498e293b1423971b9045b4a09542e6076..85cdd1e156ae7ad8e1cfc4fc704d0c93f41e014e 100755 (executable)
@@ -20,6 +20,7 @@ import org.apache.poi.util.LittleEndian;
 \r
 import java.io.OutputStream;\r
 import java.io.IOException;\r
+import java.util.ArrayList;\r
 \r
 /**\r
  * The special info runs contained in this text.\r
@@ -82,4 +83,118 @@ public class TextSpecInfoAtom extends RecordAtom {
     public void setTextSize(int size){\r
         LittleEndian.putInt(_data, 0, size);\r
     }\r
+\r
+    /**\r
+     * Reset the content to one info run with the default values\r
+     * @param size  the site of parent text\r
+     */\r
+    public void reset(int size){\r
+        _data = new byte[10];\r
+        // 01 00 00 00\r
+        LittleEndian.putInt(_data, 0, size);\r
+        // 01 00 00 00\r
+        LittleEndian.putInt(_data, 4, 1); //mask\r
+        // 00 00\r
+        LittleEndian.putShort(_data, 8, (short)0); //langId\r
+\r
+        // Update the size (header bytes 5-8)\r
+        LittleEndian.putInt(_header, 4, _data.length);\r
+    }\r
+\r
+    /**\r
+     * Get the number of characters covered by this records\r
+     *\r
+     * @return the number of characters covered by this records\r
+     */\r
+    public int getCharactersCovered(){\r
+        int covered = 0;\r
+        TextSpecInfoRun[] runs = getTextSpecInfoRuns();\r
+        for (int i = 0; i < runs.length; i++) covered += runs[i].len;\r
+        return covered;\r
+    }\r
+\r
+    public TextSpecInfoRun[] getTextSpecInfoRuns(){\r
+        ArrayList lst = new ArrayList();\r
+        int pos = 0;\r
+        int[] bits = {1, 0, 2};\r
+        while(pos < _data.length) {\r
+            TextSpecInfoRun run = new TextSpecInfoRun();\r
+            run.len = LittleEndian.getInt(_data, pos); pos += 4;\r
+            run.mask = LittleEndian.getInt(_data, pos); pos += 4;\r
+            for (int i = 0; i < bits.length; i++) {\r
+                if((run.mask & 1 << bits[i]) != 0){\r
+                    switch (bits[i]){\r
+                        case 0:\r
+                            run.spellInfo = LittleEndian.getShort(_data, pos); pos += 2;\r
+                            break;\r
+                        case 1:\r
+                            run.langId = LittleEndian.getShort(_data, pos); pos += 2;\r
+                            break;\r
+                        case 2:\r
+                            run.altLangId = LittleEndian.getShort(_data, pos); pos += 2;\r
+                            break;\r
+                    }\r
+                }\r
+            }\r
+            lst.add(run);\r
+        }\r
+        return (TextSpecInfoRun[])lst.toArray(new TextSpecInfoRun[lst.size()]);\r
+\r
+    }\r
+\r
+    public static class TextSpecInfoRun {\r
+        //Length of special info run.\r
+        protected int len;\r
+\r
+        //Special info mask of this run;\r
+        protected int mask;\r
+\r
+        // info fields as indicated by the mask.\r
+        // -1 means the bit is not set\r
+        protected short spellInfo = -1;\r
+        protected short langId = -1;\r
+        protected short altLangId = -1;\r
+\r
+        /**\r
+         * Spelling status of this text. See Spell Info table below.\r
+         *\r
+         * <p>Spell Info Types:</p>\r
+         * <li>0    Unchecked\r
+         * <li>1    Previously incorrect, needs rechecking\r
+         * <li>2    Correct\r
+         * <li>3    Incorrect\r
+         *\r
+         * @return Spelling status of this text\r
+         */\r
+        public short getSpellInfo(){\r
+            return spellInfo;\r
+        }\r
+\r
+        /**\r
+         * Windows LANGID for this text.\r
+         *\r
+         * @return Windows LANGID for this text.\r
+         */\r
+        public short getLangId(){\r
+            return spellInfo;\r
+        }\r
+\r
+        /**\r
+         * Alternate Windows LANGID of this text;\r
+         * must be a valid non-East Asian LANGID if the text has an East Asian language,\r
+         * otherwise may be an East Asian LANGID or language neutral (zero).\r
+         *\r
+         * @return  Alternate Windows LANGID of this text\r
+         */\r
+        public short getAltLangId(){\r
+            return altLangId;\r
+        }\r
+\r
+        /**\r
+         * @return Length of special info run.\r
+         */\r
+        public int length(){\r
+            return len;\r
+        }\r
+    }\r
 }\r
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextSpecInfoAtom.java
new file mode 100755 (executable)
index 0000000..5079628
--- /dev/null
@@ -0,0 +1,95 @@
+\r
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+        \r
+\r
+\r
+package org.apache.poi.hslf.record;\r
+\r
+import org.apache.poi.hslf.HSLFSlideShow;\r
+import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;\r
+import org.apache.poi.hslf.model.textproperties.TextProp;\r
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;\r
+import org.apache.poi.hslf.record.StyleTextPropAtom.*;\r
+import org.apache.poi.hslf.usermodel.SlideShow;\r
+import org.apache.poi.util.HexDump;\r
+\r
+import junit.framework.TestCase;\r
+import java.io.ByteArrayOutputStream;\r
+import java.util.LinkedList;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * Tests TextSpecInfoAtom\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestTextSpecInfoAtom extends TestCase {\r
+\r
+    //from a real file\r
+       private byte[] data_1 = new byte[] {\r
+        0x00, 0x00, (byte)0xAA, 0x0F, 0x2C, 0x00, 0x00, 0x00,\r
+        0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\r
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00,\r
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01,\r
+        0x00, 0x00, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+       };\r
+\r
+\r
+    public void testRead() throws Exception {\r
+               TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length);\r
+        TextSpecInfoAtom.TextSpecInfoRun[] run = spec.getTextSpecInfoRuns();\r
+        assertEquals(5, run.length);\r
+\r
+        assertEquals(10, run[0].length());\r
+        assertEquals(1, run[1].length());\r
+        assertEquals(70, run[2].length());\r
+        assertEquals(9, run[3].length());\r
+        assertEquals(32, run[4].length());\r
+\r
+    }\r
+\r
+    public void testWrite() throws Exception {\r
+        TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length);\r
+        ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+        spec.writeOut(out);\r
+\r
+        byte[] result = out.toByteArray();\r
+        assertTrue(Arrays.equals(result, data_1));\r
+       }\r
+\r
+    public void testReset() throws Exception {\r
+        TextSpecInfoAtom spec = new TextSpecInfoAtom(data_1, 0, data_1.length);\r
+        spec.reset(32);  //length of the parent text\r
+\r
+        TextSpecInfoAtom.TextSpecInfoRun[] run = spec.getTextSpecInfoRuns();\r
+        assertEquals(1, run.length);\r
+\r
+        assertEquals(32, run[0].length());\r
+\r
+        //serialize and read again\r
+        ByteArrayOutputStream out = new ByteArrayOutputStream();\r
+        spec.writeOut(out);\r
+\r
+        byte[] result = out.toByteArray();\r
+        TextSpecInfoAtom spec2 = new TextSpecInfoAtom(result, 0, result.length);\r
+        TextSpecInfoAtom.TextSpecInfoRun[] run2 = spec2.getTextSpecInfoRuns();\r
+        assertEquals(1, run2.length);\r
+\r
+        assertEquals(32, run2[0].length());\r
+    }\r
+}\r