]> source.dussan.org Git - poi.git/commitdiff
Added Ryan Akland's new contributions... THANKS RYAN!!! - Schneider Aventinus is...
authorAndrew C. Oliver <acoliver@apache.org>
Sat, 23 Feb 2002 14:47:48 +0000 (14:47 +0000)
committerAndrew C. Oliver <acoliver@apache.org>
Sat, 23 Feb 2002 14:47:48 +0000 (14:47 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352116 13f79535-47bb-0310-9956-ffa450edef68

27 files changed:
src/scratchpad/src/org/apache/poi/hdf/extractor/CHP.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/FontTable.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/HeaderFooter.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/NewOleFile.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/PAP.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/PropertySet.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/SEP.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/StyleDescription.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/StyleSheet.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/TAP.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/TC.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/TableRow.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/TextPiece.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/Utils.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/DOP.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFO.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFOLVL.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/LST.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/LVL.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/data/ListTables.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/BTreeSet.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/ChpxNode.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/NumberFormatter.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/PapxNode.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/PropertyNode.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hdf/extractor/util/SepxNode.java [new file with mode: 0644]

diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/CHP.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/CHP.java
new file mode 100644 (file)
index 0000000..7dfed85
--- /dev/null
@@ -0,0 +1,216 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class CHP implements Cloneable
+{
+  boolean _bold;
+  boolean _italic;
+  boolean _fRMarkDel;
+  boolean _fOutline;
+  boolean _fSmallCaps;
+  boolean _fCaps;
+  boolean _fVanish;
+  boolean _fRMark;
+  boolean _fSpec;
+  boolean _fStrike;
+  boolean _fObj;
+  boolean _fShadow;
+  boolean _fLowerCase;
+  boolean _fData;
+  boolean _fOle2;
+  boolean _fEmboss;
+  boolean _fImprint;
+  boolean _fDStrike;
+
+  short _ftcAscii;
+  short _ftcFE;
+  short _ftcOther;
+  short _ftc;
+  int _hps;//font size in half points
+  int _dxaSpace;//space following each character in the run expressed in twip units
+  byte _iss;//superscript/subscript indices 0 means no super/subscripting 1 means text in run is superscripted 2 means text in run is subscripted
+  byte _kul;//underline code see spec
+  byte _ico;//color of text see spec
+  short _hpsPos;//super/subscript position in half points; positive means text is raised; negative means text is lowered
+  short _lidDefault;//language for non-Far East text
+  short _lidFE;//language for Far East text
+  byte _idctHint;
+  int _wCharScale;
+  short _chse;
+
+  int _specialFC;//varies depending on whether this is a special char
+  short _ibstRMark;//index to author IDs stored in hsttbfRMark. used when text in run was newly typed when revision marking was enabled
+  short _ibstRMarkDel;//index to author IDs stored in hsttbfRMark. used when text in run was newly typed when revision marking was enabled
+  int[] _dttmRMark = new int[2];//Date/time at which this run of text was
+  int[] _dttmRMarkDel = new int[2];//entered/modified by the author. (Only
+                                     //recorded when revision marking is on.)Date/time at which this run of text was deleted by the author. (Only recorded when revision marking is on.)
+  int _istd;
+  int _baseIstd = -1;
+  int _fcPic;
+  short _ftcSym;// see spec
+  short _xchSym;//see spec
+  byte _ysr;//hyphenation rules
+  byte _chYsr;//used for hyphenation see spec
+  int _hpsKern;//kerning distance for characters in run recorded in half points
+  int _fcObj;
+  byte _icoHighlight;//highlight color
+  boolean _fChsDiff;
+  boolean _highlighted;//when true characters are highlighted with color specified by chp.icoHighlight
+  boolean _fPropMark;//when true, properties have been changed with revision marking on
+  short _ibstPropRMark;//index to author IDs stored in hsttbfRMark. used when properties have been changed when revision marking was enabled
+  int _dttmPropRMark;//Date/time at which properties of this were changed for this run of text by the author
+  byte _sfxtText;//text animation see spec
+  boolean _fDispFldRMark;//see spec
+  short _ibstDispFldRMark;//Index to author IDs stored in hsttbfRMark. used when ListNum field numbering has been changed when revision marking was enabled
+  int _dttmDispFldRMark;//The date for the ListNum field number change
+  byte[] _xstDispFldRMark = new byte[32];//The string value of the ListNum field when revision mark tracking began
+  short _shd;//shading
+  short[] _brc = new short[2];//border
+  short _paddingStart = 0;
+  short _paddingEnd = 0;
+
+  public CHP()
+  {
+      _istd = 10;
+      _hps = 20;
+      _lidDefault = 0x0400;
+      _lidFE = 0x0400;
+
+  }
+  public void copy(CHP toCopy)
+  {
+      _bold = toCopy._bold;
+      _italic = toCopy._italic;
+       _fRMarkDel = toCopy._fRMarkDel;
+       _fOutline = toCopy._fOutline;
+       _fSmallCaps = toCopy._fSmallCaps;
+       _fCaps = toCopy._fCaps;
+       _fVanish = toCopy._fVanish;
+       _fRMark = toCopy._fRMark;
+       _fSpec = toCopy._fSpec;
+       _fStrike = toCopy._fStrike;
+       _fObj = toCopy._fObj;
+       _fShadow = toCopy._fShadow;
+       _fLowerCase = toCopy._fLowerCase;
+       _fData = toCopy._fData;
+       _fOle2 = toCopy._fOle2;
+       _fEmboss = toCopy._fEmboss;
+       _fImprint = toCopy._fImprint;
+       _fDStrike = toCopy._fDStrike;
+
+       _ftcAscii = toCopy._ftcAscii;
+       _ftcFE = toCopy._ftcFE;
+       _ftcOther = toCopy._ftcOther;
+       _ftc = toCopy._ftc;
+       _hps = toCopy._hps;
+       _dxaSpace = toCopy._dxaSpace;
+       _iss = toCopy._iss;
+       _kul = toCopy._kul;
+       _ico = toCopy._ico;
+       _hpsPos = toCopy._hpsPos;
+       _lidDefault = toCopy._lidDefault;
+       _lidFE = toCopy._lidFE;
+       _idctHint = toCopy._idctHint;
+       _wCharScale = toCopy._wCharScale;
+       _chse = toCopy._chse;
+
+       _specialFC = toCopy._specialFC;
+       _ibstRMark = toCopy._ibstRMark;
+       _ibstRMarkDel = toCopy._ibstRMarkDel;
+       _dttmRMark = toCopy._dttmRMark;
+       _dttmRMarkDel  = toCopy._dttmRMarkDel;
+
+       _istd = toCopy._istd;
+       _baseIstd = toCopy._baseIstd;
+       _fcPic = toCopy._fcPic;
+       _ftcSym = toCopy._ftcSym;
+       _xchSym = toCopy._xchSym;
+       _ysr = toCopy._ysr;
+       _chYsr = toCopy._chYsr;
+       _hpsKern = toCopy._hpsKern;
+       _fcObj = toCopy._fcObj;
+       _icoHighlight = toCopy._icoHighlight;
+       _fChsDiff = toCopy._fChsDiff;
+       _highlighted = toCopy._highlighted;
+       _fPropMark = toCopy._fPropMark;
+       _ibstPropRMark = toCopy._ibstPropRMark;
+       _dttmPropRMark = toCopy._dttmPropRMark;
+       _sfxtText = toCopy._sfxtText;
+       _fDispFldRMark = toCopy._fDispFldRMark;
+       _ibstDispFldRMark = toCopy._ibstDispFldRMark;
+       _dttmDispFldRMark = toCopy._dttmDispFldRMark;
+       _xstDispFldRMark = toCopy._xstDispFldRMark;
+       _shd = toCopy._shd;
+       _brc = toCopy._brc;
+
+  }
+
+  public Object clone() throws CloneNotSupportedException
+  {
+    CHP clone = (CHP)super.clone();
+    clone._brc = new short[2];
+    System.arraycopy(_brc, 0, clone._brc, 0, 2);
+    return clone;
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/FontTable.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/FontTable.java
new file mode 100644 (file)
index 0000000..c14b2c1
--- /dev/null
@@ -0,0 +1,100 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class FontTable
+{
+  String[] fontNames;
+
+  public FontTable(byte[] fontTable)
+  {
+    int size = Utils.convertBytesToShort(fontTable, 0);
+    fontNames = new String[size];
+
+    int currentIndex = 4;
+    for(int x = 0; x < size; x++)
+    {
+      byte ffnLength = fontTable[currentIndex];
+
+      int nameOffset = currentIndex + 40;
+      StringBuffer nameBuf = new StringBuffer();
+      char ch = Utils.getUnicodeCharacter(fontTable, nameOffset);
+      while(ch != '\0')
+      {
+        nameBuf.append(ch);
+        nameOffset += 2;
+        ch = Utils.getUnicodeCharacter(fontTable, nameOffset);
+      }
+      fontNames[x] = nameBuf.toString();
+      if(fontNames[x].startsWith("Times"))
+      {
+        fontNames[x] = "Times";
+      }
+
+      currentIndex += ffnLength + 1;
+    }
+
+  }
+  public String getFont(int index)
+  {
+    return fontNames[index];
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/HeaderFooter.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/HeaderFooter.java
new file mode 100644 (file)
index 0000000..10b3ebc
--- /dev/null
@@ -0,0 +1,102 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class HeaderFooter
+{
+  public static final int HEADER_EVEN = 1;
+  public static final int HEADER_ODD = 2;
+  public static final int FOOTER_EVEN = 3;
+  public static final int FOOTER_ODD = 4;
+  public static final int HEADER_FIRST = 5;
+  public static final int FOOTER_FIRST = 6;
+
+  private int _type;
+  private int _start;
+  private int _end;
+
+  public HeaderFooter(int type, int startFC, int endFC)
+  {
+    _type = type;
+    _start = startFC;
+    _end = endFC;
+  }
+  public int getStart()
+  {
+    return _start;
+  }
+  public int getEnd()
+  {
+    return _end;
+  }
+  public boolean isEmpty()
+  {
+    if(_start - _end == 0)
+    {
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/NewOleFile.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/NewOleFile.java
new file mode 100644 (file)
index 0000000..7b02963
--- /dev/null
@@ -0,0 +1,282 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class NewOleFile extends RandomAccessFile
+{
+    private byte[] LAOLA_ID_ARRAY = new byte[]{(byte)0xd0, (byte)0xcf, (byte)0x11,
+                                               (byte)0xe0, (byte)0xa1, (byte)0xb1,
+                                               (byte)0x1a, (byte)0xe1};
+    private int _num_bbd_blocks;
+    private int _root_startblock;
+    private int _sbd_startblock;
+    private long _size;
+    private int[] _bbd_list;
+    protected int[] _big_block_depot;
+    protected int[] _small_block_depot;
+    Hashtable _propertySetsHT = new Hashtable();
+    Vector _propertySetsV = new Vector();
+
+    public NewOleFile(String fileName, String mode) throws FileNotFoundException
+    {
+        super(fileName, mode);
+        try
+        {
+            init();
+        }
+        catch(Throwable e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    private void init() throws IOException
+    {
+
+        for(int x = 0; x < LAOLA_ID_ARRAY.length; x++)
+        {
+            if(LAOLA_ID_ARRAY[x] != readByte())
+            {
+                throw new IOException("Not an OLE file");
+            }
+        }
+        _size = length();
+        _num_bbd_blocks = readInt(0x2c);
+        _root_startblock = readInt(0x30);
+        _sbd_startblock = readInt(0x3c);
+        _bbd_list = new int[_num_bbd_blocks];
+        //populate bbd_list. If _num_bbd_blocks > 109 I have to do it
+        //differently
+        if(_num_bbd_blocks <= 109)
+        {
+            seek(0x4c);
+            for(int x = 0; x < _num_bbd_blocks; x++)
+            {
+                _bbd_list[x] = readIntLE();
+            }
+        }
+        else
+        {
+            populateBbdList();
+        }
+        //populate the big block depot
+        _big_block_depot = new int[_num_bbd_blocks * 128];
+        int counter = 0;
+        for(int x = 0; x < _num_bbd_blocks; x++)
+        {
+            byte[] bigBlock = new byte[512];
+            int offset = (_bbd_list[x] + 1) * 512;
+            seek(offset);
+            for(int y = 0; y < 128; y++)
+            {
+                _big_block_depot[counter++] = readIntLE();
+            }
+        }
+        _small_block_depot = createSmallBlockDepot();
+        int[] rootChain = readChain(_big_block_depot, _root_startblock);
+        initializePropertySets(rootChain);
+
+    }
+    public static void main(String args[])
+    {
+      try
+      {
+          NewOleFile file = new NewOleFile(args[0], "r");
+      }
+      catch(Exception e)
+      {
+      }
+    }
+    protected int[] readChain(int[] blockChain, int startBlock) throws IOException
+    {
+
+        int[] tempChain = new int[blockChain.length];
+        tempChain[0] = startBlock;
+        int x = 1;
+        for(;;x++)
+        {
+            int nextVal = blockChain[tempChain[x-1]];
+            if(nextVal != -2)
+            {
+                tempChain[x] = nextVal;
+            }
+            else
+            {
+                break;
+            }
+        }
+        int[] newChain = new int[x];
+        System.arraycopy(tempChain, 0, newChain, 0, x);
+
+        return newChain;
+    }
+    private void initializePropertySets(int[] rootChain) throws IOException
+    {
+        for(int x = 0; x < rootChain.length; x++)
+        {
+            int offset = (rootChain[x] + 1) * 512;
+            seek(offset);
+            for(int y = 0; y < 4; y++)
+            {
+                //read the block the makes up the property set
+                byte[] propArray = new byte[128];
+                read(propArray);
+
+                //parse the byte array for properties
+                int nameSize = Utils.convertBytesToShort(propArray[0x41], propArray[0x40])/2 - 1;
+                if(nameSize > 0)
+                {
+                    StringBuffer nameBuffer = new StringBuffer(nameSize);
+                    for(int z = 0; z < nameSize; z++)
+                    {
+                        nameBuffer.append((char)propArray[z*2]);
+                    }
+                    int type = propArray[0x42];
+                    int previous_pps = Utils.convertBytesToInt(propArray[0x47], propArray[0x46], propArray[0x45], propArray[0x44]);
+                    int next_pps = Utils.convertBytesToInt(propArray[0x4b], propArray[0x4a], propArray[0x49], propArray[0x48]);
+                    int pps_dir = Utils.convertBytesToInt(propArray[0x4f], propArray[0x4e], propArray[0x4d], propArray[0x4c]);
+                    int pps_sb = Utils.convertBytesToInt(propArray[0x77], propArray[0x76], propArray[0x75], propArray[0x74]);
+                    int pps_size = Utils.convertBytesToInt(propArray[0x7b], propArray[0x7a], propArray[0x79], propArray[0x78]);
+
+                    PropertySet propSet = new PropertySet(nameBuffer.toString(),
+                                                          type, previous_pps, next_pps,
+                                                          pps_dir, pps_sb, pps_size,
+                                                          (x*4) + y);
+                    _propertySetsHT.put(nameBuffer.toString(), propSet);
+                    _propertySetsV.add(propSet);
+                }
+            }
+        }
+
+    }
+    private int[] createSmallBlockDepot() throws IOException
+    {
+
+        int[] sbd_list = readChain(_big_block_depot, _sbd_startblock);
+        int[] small_block_depot = new int[sbd_list.length * 128];
+
+        for(int x = 0; x < sbd_list.length && sbd_list[x] != -2; x++)
+        {
+            int offset = ((sbd_list[x] + 1) * 512);
+            seek(offset);
+            for(int y = 0; y < 128; y++)
+            {
+                small_block_depot[y] = readIntLE();
+            }
+        }
+        return small_block_depot;
+    }
+
+    private void populateBbdList() throws IOException
+    {
+      seek(0x4c);
+      for(int x = 0; x < 109; x++)
+      {
+          _bbd_list[x] = readIntLE();
+      }
+      int pos = 109;
+      int remainder = _num_bbd_blocks - 109;
+      seek(0x48);
+      int numLists = readIntLE();
+      seek(0x44);
+      int firstList = readIntLE();
+
+      firstList = (firstList + 1) * 512;
+
+      for(int y = 0; y < numLists; y++)
+      {
+        int size = Math.min(127, remainder);
+        for(int z = 0; z < size; z++)
+        {
+          seek(firstList + (z * 4));
+          _bbd_list[pos++] = readIntLE();
+        }
+        if(size == 127)
+        {
+          seek(firstList + (127 * 4));
+          firstList = readIntLE();
+          firstList = (firstList + 1) * 512;
+          remainder -= 127;
+        }
+      }
+
+    }
+    private int readInt(long offset) throws IOException
+    {
+        seek(offset);
+        return readIntLE();
+    }
+    private int readIntLE() throws IOException
+    {
+        byte[] intBytes = new byte[4];
+        read(intBytes);
+        return Utils.convertBytesToInt(intBytes[3], intBytes[2], intBytes[1], intBytes[0]);
+    }
+
+
+
+
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/PAP.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/PAP.java
new file mode 100644 (file)
index 0000000..dbc392d
--- /dev/null
@@ -0,0 +1,169 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class PAP implements Cloneable
+{
+  int _istd;//index to style descriptor.
+  byte _jc;//justification code
+  byte _fKeep;//keep entire paragraph on one page if possible
+  byte _fKeepFollow;//keep paragraph on same page with next paragraph if possible
+  byte _fPageBreakBefore;//start this paragraph on new page
+  byte _positionByte;//multiple flags see spec;
+  byte _brcp;//rectangle border codes for Macword 3.0
+  byte _brcl;//border line styles for Macword 3.0
+  byte _ilvl;//when non-zero, list level for this paragraph
+  byte _fNoLnn;//no line numbering for this paragraph. (makes this an exception to the section property of line numbering)
+  int  _ilfo;//when non-zero, (1-based) index into the pllfo identifying the list to which the paragraph belongs
+  byte _fSideBySide;//when 1, paragraph is a side by side paragraph
+  byte _fNoAutoHyph;//when 0, text in paragraph may be auto hyphenated.
+  byte _fWindowControl;//when 1, Word will prevent widowed lines in this paragraph from being placed at the beginning of a page
+  int _dxaRight;//indent from right margin (signed).
+  int _dxaLeft;//indent from left margin (signed)
+  int _dxaLeft1;//first line indent; signed number relative to dxaLeft
+  int[] _lspd = new int[2];//line spacing descriptor see spec
+  int _dyaBefore;// vertical spacing before paragraph (unsigned)
+  int _dyaAfter;//vertical spacing after paragraph (unsigned)
+  byte[] _phe = new byte[12];//height of current paragraph
+  byte _fCrLf;//undocumented
+  byte _fUsePgsuSettings;//undocumented
+  byte _fAdjustRight;//undocumented
+  byte _fKinsoku;// when 1, apply kinsoku rules when performing line wrapping
+  byte _fWordWrap;//when 1, perform word wrap
+  byte _fOverflowPunct;//when 1, apply overflow punctuation rules when performing line wrapping
+  byte _fTopLinePunct;//when 1, perform top line punctuation processing
+  byte _fAutoSpaceDE;//when 1, auto space FE and alphabetic characters
+  byte _fAutoSpaceDN;// when 1, auto space FE and numeric characters
+  int _wAlignFont;//font alignment 0 Hanging 1 Centered 2 Roman 3 Variable 4 Auto
+  short _fontAlign;//multiVal see Spec.
+  byte _fInTable;//when 1, paragraph is contained in a table row
+  byte _fTtp;//when 1, paragraph consists only of the row mark special character and marks the end of a table row
+  byte _wr;//Wrap Code for absolute objects
+  byte _fLocked;//when 1, paragraph may not be edited
+  int _dxaAbs;//see spec
+  int _dyaAbs;//see spec
+  int _dxaWidth;//when not == 0, paragraph is constrained to be dxaWidth wide, independent of current margin or column settings
+  short[] _brcTop = new short[2];//spec for border above paragraph
+  short[] _brcLeft = new short[2];//specification for border to the left of
+  short[] _brcBottom = new short[2];//paragraphspecification for border below
+  short[] _brcRight = new short[2];//paragraphspecification for border to the
+  short[] _brcBetween = new short[2];//right of paragraphsee spec
+  short[] _brcBar = new short[2];//specification of border to place on
+  short _brcTop1;//outside of text when facing pages are to be displayed.spec
+  short _brcLeft1;//for border above paragraphspecification for border to the
+  short _brcBottom1;//left ofparagraphspecification for border below
+  short _brcRight1;//paragraphspecification for border to the
+  short _brcBetween1;//right of paragraphsee spec
+  short _brcBar1;//specification of border to place on outside of text when facing pages are to be displayed.
+  int _dxaFromText;//horizontal distance to be maintained between an absolutely positioned paragraph and any non-absolute positioned text
+  int _dyaFromText;//vertical distance to be maintained between an absolutely positioned paragraph and any non-absolute positioned text
+  int _dyaHeight;//see spec
+  int _shd;//shading
+  int _dcs;//drop cap specifier
+  byte[] _anld = new byte[84];//autonumber list descriptor (see ANLD definition)
+  short _fPropRMark;//when 1, properties have been changed with revision marking on
+  short _ibstPropRMark;//index to author IDs stored in hsttbfRMark. used when properties have been changed when revision marking was enabled
+  byte[] _dttmPropRMark = new byte[4];//Date/time at which properties of this were changed for this run of text by the author. (Only recorded when revision marking is on.)
+  byte[] _numrm = new byte[8];//paragraph numbering revision mark data (see NUMRM)
+  short _itbdMac;//number of tabs stops defined for paragraph. Must be >= 0 and <= 64.
+
+
+
+  public PAP()
+  {
+    _fWindowControl = 1;
+    //lspd[0] = 240;
+    _lspd[1] = 1;
+    _ilvl = 9;
+  }
+  public Object clone() throws CloneNotSupportedException
+  {
+      PAP clone =  (PAP)super.clone();
+
+      clone._brcBar = new short[2];
+      clone._brcBottom = new short[2];
+      clone._brcLeft = new short[2];
+      clone._brcBetween = new short[2];
+      clone._brcRight = new short[2];
+      clone._brcTop = new short[2];
+      clone._lspd = new int[2];
+      clone._phe = new byte[12];
+      clone._anld = new byte[84];
+      clone._dttmPropRMark = new byte[4];
+      clone._numrm = new byte[8];
+
+      System.arraycopy(_brcBar, 0, clone._brcBar, 0, 2);
+      System.arraycopy(_brcBottom, 0, clone._brcBottom, 0, 2);
+      System.arraycopy(_brcLeft, 0, clone._brcLeft, 0, 2);
+      System.arraycopy(_brcBetween, 0, clone._brcBetween, 0, 2);
+      System.arraycopy(_brcRight, 0, clone._brcRight, 0, 2);
+      System.arraycopy(_brcTop, 0, clone._brcTop, 0, 2);
+      System.arraycopy(_lspd, 0, clone._lspd, 0, 2);
+      System.arraycopy(_phe, 0, clone._phe, 0, 12);
+      System.arraycopy(_anld, 0, clone._anld, 0, 84);
+      System.arraycopy(_dttmPropRMark, 0, clone._dttmPropRMark, 0, 4);
+      System.arraycopy(_numrm, 0, clone._numrm, 0, 8);
+
+      return clone;
+  }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/PropertySet.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/PropertySet.java
new file mode 100644 (file)
index 0000000..f9391ae
--- /dev/null
@@ -0,0 +1,95 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class PropertySet
+{
+    private String _name;
+    private int _type;
+    private int _previous;
+    private int _next;
+    private int _dir;
+    private int _sb;
+    private int _size;
+    private int _num;
+
+    public PropertySet(String name, int type, int previous, int next, int dir,
+                       int sb, int size, int num)
+    {
+        _name = name;
+        _type = type;
+        _previous = previous;
+        _next = next;
+        _dir = dir;
+        _sb = sb;
+        _size = size;
+        _num = num;
+    }
+    public int getSize()
+    {
+        return _size;
+    }
+    public int getStartBlock()
+    {
+        return _sb;
+    }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/SEP.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/SEP.java
new file mode 100644 (file)
index 0000000..6c9eeea
--- /dev/null
@@ -0,0 +1,138 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class SEP
+{
+  int _index;
+  byte _bkc;
+  boolean _fTitlePage;
+  boolean _fAutoPgn;
+  byte _nfcPgn;
+  boolean _fUnlocked;
+  byte _cnsPgn;
+  boolean _fPgnRestart;
+  boolean _fEndNote;
+  byte _lnc;
+  byte _grpfIhdt;
+  short _nLnnMod;
+  int _dxaLnn;
+  short _dxaPgn;
+  short _dyaPgn;
+  boolean _fLBetween;
+  byte _vjc;
+  short _dmBinFirst;
+  short _dmBinOther;
+  short _dmPaperReq;
+  short[] _brcTop = new short[2];
+  short[] _brcLeft = new short[2];
+  short[] _brcBottom = new short[2];
+  short[] _brcRight = new short[2];
+  boolean _fPropMark;
+  int _dxtCharSpace;
+  int _dyaLinePitch;
+  short _clm;
+  byte _dmOrientPage;
+  byte _iHeadingPgn;
+  short _pgnStart;
+  short _lnnMin;
+  short _wTextFlow;
+  short _pgbProp;
+  int _xaPage;
+  int _yaPage;
+  int _dxaLeft;
+  int _dxaRight;
+  int _dyaTop;
+  int _dyaBottom;
+  int _dzaGutter;
+  int _dyaHdrTop;
+  int _dyaHdrBottom;
+  short _ccolM1;
+  boolean _fEvenlySpaced;
+  int _dxaColumns;
+  int[] _rgdxaColumnWidthSpacing;
+  byte _dmOrientFirst;
+  byte[] _olstAnn;
+
+
+
+  public SEP()
+  {
+      _bkc = 2;
+      _dyaPgn = 720;
+      _dxaPgn = 720;
+      _fEndNote = true;
+      _fEvenlySpaced = true;
+      _xaPage = 12240;
+      _yaPage = 15840;
+      _dyaHdrTop = 720;
+      _dyaHdrBottom = 720;
+      _dmOrientPage = 1;
+      _dxaColumns = 720;
+      _dyaTop = 1440;
+      _dxaLeft = 1800;
+      _dyaBottom = 1440;
+      _dxaRight = 1800;
+      _pgnStart = 1;
+
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/StyleDescription.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/StyleDescription.java
new file mode 100644 (file)
index 0000000..e721a1e
--- /dev/null
@@ -0,0 +1,170 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class StyleDescription
+{
+
+  private static int PARAGRAPH_STYLE = 1;
+  private static int CHARACTER_STYLE = 2;
+
+  int _baseStyleIndex;
+  int _styleTypeCode;
+  int _numUPX;
+  byte[] _papx;
+  byte[] _chpx;
+  PAP _pap;
+  CHP _chp;
+
+  public StyleDescription()
+  {
+      _pap = new PAP();
+      _chp = new CHP();
+  }
+  public StyleDescription(byte[] std, int baseLength, boolean word9)
+  {
+      int infoShort = Utils.convertBytesToShort(std, 2);
+      _styleTypeCode = (infoShort & 0xf);
+      _baseStyleIndex = (infoShort & 0xfff0) >> 4;
+
+      infoShort = Utils.convertBytesToShort(std, 4);
+      _numUPX = infoShort & 0xf;
+
+      //first byte(s) of variable length section of std is the length of the
+      //style name and aliases string
+      int nameLength = 0;
+      int multiplier = 1;
+      if(word9)
+      {
+          nameLength = Utils.convertBytesToShort(std, baseLength);
+          multiplier = 2;
+      }
+      else
+      {
+          nameLength = std[baseLength];
+      }
+      //2 bytes for length, length then null terminator.
+      int grupxStart = multiplier + ((nameLength + 1) * multiplier) + baseLength;
+
+      int offset = 0;
+      for(int x = 0; x < _numUPX; x++)
+      {
+          int upxSize = Utils.convertBytesToShort(std, grupxStart + offset);
+          if(_styleTypeCode == PARAGRAPH_STYLE)
+          {
+              if(x == 0)
+              {
+                  _papx = new byte[upxSize];
+                  System.arraycopy(std, grupxStart + offset + 2, _papx, 0, upxSize);
+              }
+              else if(x == 1)
+              {
+                  _chpx = new byte[upxSize];
+                  System.arraycopy(std, grupxStart + offset + 2, _chpx, 0, upxSize);
+              }
+          }
+          else if(_styleTypeCode == CHARACTER_STYLE && x == 0)
+          {
+              _chpx = new byte[upxSize];
+              System.arraycopy(std, grupxStart + offset + 2, _chpx, 0, upxSize);
+          }
+
+          if(upxSize % 2 == 1)
+          {
+              ++upxSize;
+          }
+          offset += 2 + upxSize;
+      }
+
+
+
+  }
+  public int getBaseStyle()
+  {
+      return _baseStyleIndex;
+  }
+  public byte[] getCHPX()
+  {
+      return _chpx;
+  }
+  public byte[] getPAPX()
+  {
+      return _papx;
+  }
+  public PAP getPAP()
+  {
+      return _pap;
+  }
+  public CHP getCHP()
+  {
+      return _chp;
+  }
+  public void setPAP(PAP pap)
+  {
+      _pap = pap;
+  }
+  public void setCHP(CHP chp)
+  {
+      _chp = chp;
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/StyleSheet.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/StyleSheet.java
new file mode 100644 (file)
index 0000000..853a81d
--- /dev/null
@@ -0,0 +1,1333 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+import java.util.*;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class StyleSheet
+{
+
+  private static final int NIL_STYLE = 4095;
+  private static final int PAP_TYPE = 1;
+  private static final int CHP_TYPE = 2;
+  private static final int SEP_TYPE = 4;
+  private static final int TAP_TYPE = 5;
+  //Vector _styleDescriptions;
+  StyleDescription _nilStyle = new StyleDescription();
+  StyleDescription[] _styleDescriptions;
+
+  public StyleSheet(byte[] styleSheet)
+  {
+      int stshiLength = Utils.convertBytesToShort(styleSheet, 0);
+      int stdCount = Utils.convertBytesToShort(styleSheet, 2);
+      int baseLength = Utils.convertBytesToShort(styleSheet, 4);
+      int[] rgftc = new int[3];
+
+      rgftc[0] = Utils.convertBytesToInt(styleSheet, 14);
+      rgftc[1] = Utils.convertBytesToInt(styleSheet, 18);
+      rgftc[2] = Utils.convertBytesToInt(styleSheet, 22);
+
+      int offset = 0;
+      _styleDescriptions = new StyleDescription[stdCount];
+      for(int x = 0; x < stdCount; x++)
+      {
+          int stdOffset = (2 + stshiLength) + offset;
+          int stdSize = Utils.convertBytesToShort(styleSheet, stdOffset);
+          if(stdSize > 0)
+          {
+              byte[] std = new byte[stdSize];
+
+              //get past the size
+              stdOffset += 2;
+              System.arraycopy(styleSheet, stdOffset, std, 0, stdSize);
+              StyleDescription aStyle = new StyleDescription(std, baseLength, true);
+
+              _styleDescriptions[x] = aStyle;
+          }
+
+
+          offset += stdSize + 2;
+
+      }
+      for(int x = 0; x < _styleDescriptions.length; x++)
+      {
+          if(_styleDescriptions[x] != null)
+          {
+              createPap(x);
+              createChp(x);
+          }
+      }
+  }
+  private void createPap(int istd)
+  {
+      StyleDescription sd = _styleDescriptions[istd];
+      PAP pap = sd.getPAP();
+      byte[] papx = sd.getPAPX();
+      int baseIndex = sd.getBaseStyle();
+      if(pap == null && papx != null)
+      {
+          PAP parentPAP = _nilStyle.getPAP();
+          if(baseIndex != NIL_STYLE)
+          {
+
+              parentPAP = _styleDescriptions[baseIndex].getPAP();
+              if(parentPAP == null)
+              {
+                  createPap(baseIndex);
+                  parentPAP = _styleDescriptions[baseIndex].getPAP();
+              }
+
+          }
+
+          pap = (PAP)uncompressProperty(papx, parentPAP, this);
+          sd.setPAP(pap);
+      }
+  }
+  private void createChp(int istd)
+  {
+      StyleDescription sd = _styleDescriptions[istd];
+      CHP chp = sd.getCHP();
+      byte[] chpx = sd.getCHPX();
+      int baseIndex = sd.getBaseStyle();
+      if(chp == null && chpx != null)
+      {
+          CHP parentCHP = _nilStyle.getCHP();
+          if(baseIndex != NIL_STYLE)
+          {
+
+              parentCHP = _styleDescriptions[baseIndex].getCHP();
+              if(parentCHP == null)
+              {
+                  createChp(baseIndex);
+                  parentCHP = _styleDescriptions[baseIndex].getCHP();
+              }
+
+          }
+
+          chp = (CHP)uncompressProperty(chpx, parentCHP, this);
+          sd.setCHP(chp);
+      }
+  }
+  public StyleDescription getStyleDescription(int x)
+  {
+      return _styleDescriptions[x];
+  }
+  static void doCHPOperation(CHP oldCHP, CHP newCHP, int operand, int param,
+                             byte[] varParam, byte[] grpprl, int offset,
+                             StyleSheet styleSheet)
+  {
+      switch(operand)
+      {
+          case 0:
+               newCHP._fRMarkDel = getFlag(param);
+               break;
+          case 0x1:
+               newCHP._fRMark = getFlag(param);
+               break;
+          case 0x2:
+               break;
+          case 0x3:
+               newCHP._fcPic = param;
+               newCHP._fSpec = true;
+               break;
+          case 0x4:
+               newCHP._ibstRMark = (short)param;
+               break;
+          case 0x5:
+               newCHP._dttmRMark[0] = Utils.convertBytesToShort(grpprl, (offset - 4));
+               newCHP._dttmRMark[1] = Utils.convertBytesToShort(grpprl, (offset - 2));
+               break;
+          case 0x6:
+               newCHP._fData = getFlag(param);
+               break;
+          case 0x7:
+               //don't care about this
+               break;
+          case 0x8:
+               short chsDiff = (short)((param & 0xff0000) >>> 8);
+               newCHP._fChsDiff = getFlag(chsDiff);
+               newCHP._chse = (short)(param & 0xffff);
+               break;
+          case 0x9:
+               newCHP._fSpec = true;
+               newCHP._ftcSym = (short)Utils.convertBytesToShort(varParam, 0);
+               newCHP._xchSym = (short)Utils.convertBytesToShort(varParam, 2);
+               break;
+          case 0xa:
+               newCHP._fOle2 = getFlag(param);
+               break;
+          case 0xb:
+               //?
+               break;
+          case 0xc:
+               newCHP._icoHighlight = (byte)param;
+               newCHP._highlighted = getFlag(param);
+               break;
+          case 0xd:
+               break;
+          case 0xe:
+               newCHP._fcObj = param;
+               break;
+          case 0xf:
+               break;
+          case 0x10:
+               //?
+               break;
+          case 0x11:
+               break;
+          case 0x12:
+               break;
+          case 0x13:
+               break;
+          case 0x14:
+               break;
+          case 0x15:
+               break;
+          case 0x16:
+               break;
+          case 0x17:
+               break;
+          case 0x18:
+               break;
+          case 0x19:
+               break;
+          case 0x1a:
+               break;
+          case 0x1b:
+               break;
+          case 0x1c:
+               break;
+          case 0x1d:
+               break;
+          case 0x1e:
+               break;
+          case 0x1f:
+               break;
+          case 0x20:
+               break;
+          case 0x21:
+               break;
+          case 0x22:
+               break;
+          case 0x23:
+               break;
+          case 0x24:
+               break;
+          case 0x25:
+               break;
+          case 0x26:
+               break;
+          case 0x27:
+               break;
+          case 0x28:
+               break;
+          case 0x29:
+               break;
+          case 0x2a:
+               break;
+          case 0x2b:
+               break;
+          case 0x2c:
+               break;
+          case 0x2d:
+               break;
+          case 0x2e:
+               break;
+          case 0x2f:
+               break;
+          case 0x30:
+               newCHP._istd = param;
+               break;
+          case 0x31:
+               //permutation vector for fast saves who cares!
+               break;
+          case 0x32:
+               newCHP._bold = false;
+               newCHP._italic = false;
+               newCHP._fOutline = false;
+               newCHP._fStrike = false;
+               newCHP._fShadow = false;
+               newCHP._fSmallCaps = false;
+               newCHP._fCaps = false;
+               newCHP._fVanish = false;
+               newCHP._kul = 0;
+               newCHP._ico = 0;
+               break;
+          case 0x33:
+               newCHP.copy(oldCHP);
+               return;
+          case 0x34:
+               break;
+          case 0x35:
+               newCHP._bold = getCHPFlag((byte)param, oldCHP._bold);
+               break;
+          case 0x36:
+               newCHP._italic = getCHPFlag((byte)param, oldCHP._italic);
+               break;
+          case 0x37:
+               newCHP._fStrike = getCHPFlag((byte)param, oldCHP._fStrike);
+               break;
+          case 0x38:
+               newCHP._fOutline = getCHPFlag((byte)param, oldCHP._fOutline);
+               break;
+          case 0x39:
+               newCHP._fShadow = getCHPFlag((byte)param, oldCHP._fShadow);
+               break;
+          case 0x3a:
+               newCHP._fSmallCaps = getCHPFlag((byte)param, oldCHP._fSmallCaps);
+               break;
+          case 0x3b:
+               newCHP._fCaps = getCHPFlag((byte)param, oldCHP._fCaps);
+               break;
+          case 0x3c:
+               newCHP._fVanish = getCHPFlag((byte)param, oldCHP._fVanish);
+               break;
+          case 0x3d:
+               newCHP._ftc = (short)param;
+               break;
+          case 0x3e:
+               newCHP._kul = (byte)param;
+               break;
+          case 0x3f:
+               int hps = param & 0xff;
+               if(hps != 0)
+               {
+                  newCHP._hps = hps;
+               }
+               byte cInc = (byte)(((byte)(param & 0xfe00) >>> 4) >> 1);
+               if(cInc != 0)
+               {
+                  newCHP._hps = Math.max(newCHP._hps + (cInc * 2), 2);
+               }
+               byte hpsPos = (byte)((param & 0xff0000) >>> 8);
+               if(hpsPos != 0x80)
+               {
+                  newCHP._hpsPos = hpsPos;
+               }
+               boolean fAdjust = (param & 0x0100) > 0;
+               if(fAdjust && hpsPos != 128 && hpsPos != 0 && oldCHP._hpsPos == 0)
+               {
+                  newCHP._hps = Math.max(newCHP._hps + (-2), 2);
+               }
+               if(fAdjust && hpsPos == 0 && oldCHP._hpsPos != 0)
+               {
+                  newCHP._hps = Math.max(newCHP._hps + 2, 2);
+               }
+               break;
+          case 0x40:
+               newCHP._dxaSpace = param;
+               break;
+          case 0x41:
+               newCHP._lidDefault = (short)param;
+               break;
+          case 0x42:
+               newCHP._ico = (byte)param;
+               break;
+          case 0x43:
+               newCHP._hps = param;
+               break;
+          case 0x44:
+               byte hpsLvl = (byte)param;
+               newCHP._hps = Math.max(newCHP._hps + (hpsLvl * 2), 2);
+               break;
+          case 0x45:
+               newCHP._hpsPos = (short)param;
+               break;
+          case 0x46:
+               if(param != 0)
+               {
+                  if(oldCHP._hpsPos == 0)
+                  {
+                      newCHP._hps = Math.max(newCHP._hps + (-2), 2);
+                  }
+               }
+               else
+               {
+                  if(oldCHP._hpsPos != 0)
+                  {
+                      newCHP._hps = Math.max(newCHP._hps + 2, 2);
+                  }
+               }
+               break;
+          case 0x47:
+               CHP genCHP = new CHP();
+               genCHP._ftc = 4;
+               genCHP = (CHP)uncompressProperty(varParam, genCHP, styleSheet);
+               CHP styleCHP = styleSheet.getStyleDescription(oldCHP._baseIstd).getCHP();
+               if(genCHP._bold == newCHP._bold)
+               {
+                  newCHP._bold = styleCHP._bold;
+               }
+               if(genCHP._italic == newCHP._italic)
+               {
+                  newCHP._italic = styleCHP._italic;
+               }
+               if(genCHP._fSmallCaps == newCHP._fSmallCaps)
+               {
+                  newCHP._fSmallCaps = styleCHP._fSmallCaps;
+               }
+               if(genCHP._fVanish == newCHP._fVanish)
+               {
+                  newCHP._fVanish = styleCHP._fVanish;
+               }
+               if(genCHP._fStrike == newCHP._fStrike)
+               {
+                  newCHP._fStrike = styleCHP._fStrike;
+               }
+               if(genCHP._fCaps == newCHP._fCaps)
+               {
+                  newCHP._fCaps = styleCHP._fCaps;
+               }
+               if(genCHP._ftcAscii == newCHP._ftcAscii)
+               {
+                  newCHP._ftcAscii = styleCHP._ftcAscii;
+               }
+               if(genCHP._ftcFE == newCHP._ftcFE)
+               {
+                  newCHP._ftcFE = styleCHP._ftcFE;
+               }
+               if(genCHP._ftcOther == newCHP._ftcOther)
+               {
+                  newCHP._ftcOther = styleCHP._ftcOther;
+               }
+               if(genCHP._hps == newCHP._hps)
+               {
+                  newCHP._hps = styleCHP._hps;
+               }
+               if(genCHP._hpsPos == newCHP._hpsPos)
+               {
+                  newCHP._hpsPos = styleCHP._hpsPos;
+               }
+               if(genCHP._kul == newCHP._kul)
+               {
+                  newCHP._kul = styleCHP._kul;
+               }
+               if(genCHP._dxaSpace == newCHP._dxaSpace)
+               {
+                  newCHP._dxaSpace = styleCHP._dxaSpace;
+               }
+               if(genCHP._ico == newCHP._ico)
+               {
+                  newCHP._ico = styleCHP._ico;
+               }
+               if(genCHP._lidDefault == newCHP._lidDefault)
+               {
+                  newCHP._lidDefault = styleCHP._lidDefault;
+               }
+               if(genCHP._lidFE == newCHP._lidFE)
+               {
+                  newCHP._lidFE = styleCHP._lidFE;
+               }
+               break;
+          case 0x48:
+               newCHP._iss = (byte)param;
+               break;
+          case 0x49:
+               newCHP._hps = Utils.convertBytesToShort(varParam, 0);
+               break;
+          case 0x4a:
+               int increment = Utils.convertBytesToShort(varParam, 0);
+               newCHP._hps = Math.max(newCHP._hps + increment, 8);
+               break;
+          case 0x4b:
+               newCHP._hpsKern = param;
+               break;
+          case 0x4c:
+               doCHPOperation(oldCHP, newCHP, 0x47, param, varParam, grpprl, offset, styleSheet);
+               break;
+          case 0x4d:
+               float percentage = (float)param/100.0f;
+               int add = (int)((float)percentage * (float)newCHP._hps);
+               newCHP._hps += add;
+               break;
+          case 0x4e:
+               newCHP._ysr = (byte)param;
+               break;
+          case 0x4f:
+               newCHP._ftcAscii = (short)param;
+               break;
+          case 0x50:
+               newCHP._ftcFE = (short)param;
+               break;
+          case 0x51:
+               newCHP._ftcOther = (short)param;
+               break;
+          case 0x52:
+               break;
+          case 0x53:
+               newCHP._fDStrike = getFlag(param);
+               break;
+          case 0x54:
+               newCHP._fImprint = getFlag(param);
+               break;
+          case 0x55:
+               newCHP._fSpec = getFlag(param);
+               break;
+          case 0x56:
+               newCHP._fObj = getFlag(param);
+               break;
+          case 0x57:
+               newCHP._fPropMark = getFlag(varParam[0]);
+               newCHP._ibstPropRMark = (short)Utils.convertBytesToShort(varParam, 1);
+               newCHP._dttmPropRMark = Utils.convertBytesToInt(varParam, 3);
+               break;
+          case 0x58:
+               newCHP._fEmboss = getFlag(param);
+               break;
+          case 0x59:
+               newCHP._sfxtText = (byte)param;
+               break;
+          case 0x5a:
+               break;
+          case 0x5b:
+               break;
+          case 0x5c:
+               break;
+          case 0x5d:
+               break;
+          case 0x5e:
+               break;
+          case 0x5f:
+               break;
+          case 0x60:
+               break;
+          case 0x61:
+               break;
+          case 0x62:
+               newCHP._fDispFldRMark = getFlag(varParam[0]);
+               newCHP._ibstDispFldRMark = (short)Utils.convertBytesToShort(varParam, 1);
+               newCHP._dttmDispFldRMark = Utils.convertBytesToInt(varParam, 3);
+               System.arraycopy(varParam, 7, newCHP._xstDispFldRMark, 0, 32);
+               break;
+          case 0x63:
+               newCHP._ibstRMarkDel = (short)param;
+               break;
+          case 0x64:
+               newCHP._dttmRMarkDel[0] = Utils.convertBytesToShort(grpprl, offset - 4);
+               newCHP._dttmRMarkDel[1] = Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x65:
+               newCHP._brc[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newCHP._brc[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x66:
+               newCHP._shd = (short)param;
+               break;
+          case 0x67:
+               break;
+          case 0x68:
+               break;
+          case 0x69:
+               break;
+          case 0x6a:
+               break;
+          case 0x6b:
+               break;
+          case 0x6c:
+               break;
+          case 0x6d:
+               newCHP._lidDefault = (short)param;
+               break;
+          case 0x6e:
+               newCHP._lidFE = (short)param;
+               break;
+          case 0x6f:
+               newCHP._idctHint = (byte)param;
+               break;
+      }
+  }
+
+  static Object uncompressProperty(byte[] grpprl, Object parent, StyleSheet styleSheet)
+  {
+    return uncompressProperty(grpprl, parent, styleSheet, true);
+  }
+
+
+  static Object uncompressProperty(byte[] grpprl, Object parent, StyleSheet styleSheet, boolean doIstd)
+  {
+      Object newProperty = null;
+      int offset = 0;
+      int propertyType = PAP_TYPE;
+
+
+      if(parent instanceof PAP)
+      {
+          try
+          {
+              newProperty = ((PAP)parent).clone();
+          }
+          catch(Exception e){}
+          if(doIstd)
+          {
+            ((PAP)newProperty)._istd = Utils.convertBytesToShort(grpprl, 0);
+
+            offset = 2;
+          }
+      }
+      else if(parent instanceof CHP)
+      {
+          try
+          {
+              newProperty = ((CHP)parent).clone();
+              ((CHP)newProperty)._baseIstd = ((CHP)parent)._istd;
+          }
+          catch(Exception e){}
+          propertyType = CHP_TYPE;
+      }
+      else if(parent instanceof SEP)
+      {
+          newProperty = parent;
+          propertyType = SEP_TYPE;
+      }
+      else if(parent instanceof TAP)
+      {
+          newProperty = parent;
+          propertyType = TAP_TYPE;
+          offset = 2;//because this is really just a papx
+      }
+      else
+      {
+          return null;
+      }
+
+      while(offset < grpprl.length)
+      {
+          short sprm = Utils.convertBytesToShort(grpprl, offset);
+          offset += 2;
+
+          byte spra = (byte)((sprm & 0xe000) >> 13);
+          int opSize = 0;
+          int param = 0;
+          byte[] varParam = null;
+
+          switch(spra)
+          {
+              case 0:
+              case 1:
+                   opSize = 1;
+                   param = grpprl[offset];
+                   break;
+              case 2:
+                   opSize = 2;
+                   param = Utils.convertBytesToShort(grpprl, offset);
+                   break;
+              case 3:
+                   opSize = 4;
+                   param = Utils.convertBytesToInt(grpprl, offset);
+                   break;
+              case 4:
+              case 5:
+                   opSize = 2;
+                   param = Utils.convertBytesToShort(grpprl, offset);
+                   break;
+              case 6://variable size
+
+                   //there is one sprm that is a very special case
+                   if(sprm != (short)0xd608)
+                   {
+                     opSize = Utils.convertUnsignedByteToInt(grpprl[offset]);
+                     offset++;
+                   }
+                   else
+                   {
+                     opSize = Utils.convertBytesToShort(grpprl, offset) - 1;
+                     offset += 2;
+                   }
+                   varParam = new byte[opSize];
+                   System.arraycopy(grpprl, offset, varParam, 0, opSize);
+
+                   break;
+              case 7:
+                   opSize = 3;
+                   param = Utils.convertBytesToInt((byte)0, grpprl[offset + 2], grpprl[offset + 1], grpprl[offset]);
+                   break;
+              default:
+                  throw new RuntimeException("unrecognized pap opcode");
+          }
+
+          offset += opSize;
+          short operand = (short)(sprm & 0x1ff);
+          byte type = (byte)((sprm & 0x1c00) >> 10);
+          switch(propertyType)
+          {
+              case PAP_TYPE:
+                   if(type == 1)//papx stores TAP sprms along with PAP sprms
+                   {
+                     doPAPOperation((PAP)newProperty, operand, param, varParam, grpprl,
+                                    offset, spra);
+                   }
+                   break;
+              case CHP_TYPE:
+
+                   doCHPOperation((CHP)parent, (CHP)newProperty, operand, param, varParam,
+                                  grpprl, offset, styleSheet);
+                   break;
+              case SEP_TYPE:
+
+                   doSEPOperation((SEP)newProperty, operand, param, varParam);
+                   break;
+              case TAP_TYPE:
+                   if(type == 5)
+                   {
+                     doTAPOperation((TAP)newProperty, operand, param, varParam);
+                   }
+                   break;
+          }
+
+
+      }
+      return newProperty;
+
+  }
+  static void doPAPOperation(PAP newPAP, int operand, int param,
+                             byte[] varParam, byte[] grpprl, int offset,
+                             int spra)
+  {
+      switch(operand)
+      {
+          case 0:
+               newPAP._istd = param;
+               break;
+          case 0x1:
+               //permuteIstd(newPAP, varParam);
+               break;
+          case 0x2:
+               if(newPAP._istd <=9 || newPAP._istd >=1)
+               {
+                  newPAP._istd += param;
+                  if(param > 0)
+                  {
+                      newPAP._istd = Math.max(newPAP._istd, 9);
+                  }
+                  else
+                  {
+                      newPAP._istd = Math.min(newPAP._istd, 1);
+                  }
+               }
+               break;
+          case 0x3:
+               newPAP._jc = (byte)param;
+               break;
+          case 0x4:
+               newPAP._fSideBySide = (byte)param;
+               break;
+          case 0x5:
+               newPAP._fKeep = (byte)param;
+               break;
+          case 0x6:
+               newPAP._fKeepFollow = (byte)param;
+               break;
+          case 0x7:
+               newPAP._fPageBreakBefore = (byte)param;
+               break;
+          case 0x8:
+               newPAP._brcl = (byte)param;
+               break;
+          case 0x9:
+               newPAP._brcp = (byte)param;
+               break;
+          case 0xa:
+               newPAP._ilvl = (byte)param;
+               break;
+          case 0xb:
+               newPAP._ilfo = param;
+               break;
+          case 0xc:
+               newPAP._fNoLnn = (byte)param;
+               break;
+          case 0xd:
+               /**@todo handle tabs*/
+               break;
+          case 0xe:
+               newPAP._dxaRight = param;
+               break;
+          case 0xf:
+               newPAP._dxaLeft = param;
+               break;
+          case 0x10:
+               newPAP._dxaLeft += param;
+               newPAP._dxaLeft = Math.max(0, newPAP._dxaLeft);
+               break;
+          case 0x11:
+               newPAP._dxaLeft1 = param;
+               break;
+          case 0x12:
+               newPAP._lspd[0] = Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._lspd[1] = Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x13:
+               newPAP._dyaBefore = param;
+               break;
+          case 0x14:
+               newPAP._dyaAfter = param;
+               break;
+          case 0x15:
+               /**@todo handle tabs*/
+               break;
+          case 0x16:
+               newPAP._fInTable = (byte)param;
+               break;
+          case 0x17:
+               newPAP._fTtp =(byte)param;
+               break;
+          case 0x18:
+               newPAP._dxaAbs = param;
+               break;
+          case 0x19:
+               newPAP._dyaAbs = param;
+               break;
+          case 0x1a:
+               newPAP._dxaWidth = param;
+               break;
+          case 0x1b:
+               /** @todo handle paragraph postioning*/
+               /*byte pcVert = (param & 0x0c) >> 2;
+               byte pcHorz = param & 0x03;
+               if(pcVert != 3)
+               {
+                  newPAP._pcVert = pcVert;
+               }
+               if(pcHorz != 3)
+               {
+                  newPAP._pcHorz = pcHorz;
+               }*/
+               break;
+          case 0x1c:
+               newPAP._brcTop1 = (short)param;
+               break;
+          case 0x1d:
+               newPAP._brcLeft1 = (short)param;
+               break;
+          case 0x1e:
+               newPAP._brcBottom1 = (short)param;
+               break;
+          case 0x1f:
+               newPAP._brcRight1 = (short)param;
+               break;
+          case 0x20:
+               newPAP._brcBetween1 = (short)param;
+               break;
+          case 0x21:
+               newPAP._brcBar1 = (byte)param;
+               break;
+          case 0x22:
+               newPAP._dxaFromText = param;
+               break;
+          case 0x23:
+               newPAP._wr = (byte)param;
+               break;
+          case 0x24:
+               newPAP._brcTop[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcTop[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x25:
+               newPAP._brcLeft[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcLeft[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x26:
+               newPAP._brcBottom[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcBottom[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x27:
+               newPAP._brcRight[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcRight[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x28:
+               newPAP._brcBetween[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcBetween[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x29:
+               newPAP._brcBar[0] = (short)Utils.convertBytesToShort(grpprl, offset - 4);
+               newPAP._brcBar[1] = (short)Utils.convertBytesToShort(grpprl, offset - 2);
+               break;
+          case 0x2a:
+               newPAP._fNoAutoHyph = (byte)param;
+               break;
+          case 0x2b:
+               newPAP._dyaHeight = param;
+               break;
+          case 0x2c:
+               newPAP._dcs = param;
+               break;
+          case 0x2d:
+               newPAP._shd = param;
+               break;
+          case 0x2e:
+               newPAP._dyaFromText = param;
+               break;
+          case 0x2f:
+               newPAP._dxaFromText = param;
+               break;
+          case 0x30:
+               newPAP._fLocked = (byte)param;
+               break;
+          case 0x31:
+               newPAP._fWindowControl = (byte)param;
+               break;
+          case 0x32:
+               //undocumented
+               break;
+          case 0x33:
+               newPAP._fKinsoku = (byte)param;
+               break;
+          case 0x34:
+               newPAP._fWordWrap = (byte)param;
+               break;
+          case 0x35:
+               newPAP._fOverflowPunct = (byte)param;
+               break;
+          case 0x36:
+               newPAP._fTopLinePunct = (byte)param;
+               break;
+          case 0x37:
+               newPAP._fAutoSpaceDE = (byte)param;
+               break;
+          case 0x38:
+               newPAP._fAutoSpaceDN = (byte)param;
+               break;
+          case 0x39:
+               newPAP._wAlignFont = param;
+               break;
+          case 0x3a:
+               newPAP._fontAlign = (short)param;
+               break;
+          case 0x3b:
+               //obsolete
+               break;
+          case 0x3e:
+               newPAP._anld = varParam;
+               break;
+          case 0x3f:
+               //don't really need this. spec is confusing regarding this
+               //sprm
+               break;
+          case 0x40:
+               //newPAP._lvl = param;
+               break;
+          case 0x41:
+               //?
+               break;
+          case 0x43:
+               //?
+              break;
+          case 0x44:
+               //?
+               break;
+          case 0x45:
+               if(spra == 6)
+               {
+                  newPAP._numrm = varParam;
+               }
+               else
+               {
+                  /**@todo handle large PAPX from data stream*/
+               }
+               break;
+
+          case 0x47:
+               newPAP._fUsePgsuSettings = (byte)param;
+               break;
+          case 0x48:
+               newPAP._fAdjustRight = (byte)param;
+               break;
+          default:
+               break;
+      }
+  }
+  static void doTAPOperation(TAP newTAP, int operand, int param, byte[] varParam)
+  {
+      switch(operand)
+      {
+          case 0:
+               newTAP._jc = (short)param;
+               break;
+          case 0x01:
+          {
+               int adjust = param - (newTAP._rgdxaCenter[0] + newTAP._dxaGapHalf);
+               for(int x = 0; x < newTAP._itcMac; x++)
+               {
+                  newTAP._rgdxaCenter[x] += adjust;
+               }
+               break;
+          }
+          case 0x02:
+               if(newTAP._rgdxaCenter != null)
+               {
+                 int adjust = newTAP._dxaGapHalf - param;
+                 newTAP._rgdxaCenter[0] += adjust;
+               }
+               newTAP._dxaGapHalf = param;
+               break;
+          case 0x03:
+               newTAP._fCantSplit = getFlag(param);
+               break;
+          case 0x04:
+               newTAP._fTableHeader = getFlag(param);
+               break;
+          case 0x05:
+
+               newTAP._brcTop[0] = Utils.convertBytesToShort(varParam, 0);
+               newTAP._brcTop[1] = Utils.convertBytesToShort(varParam, 2);
+
+               newTAP._brcLeft[0] = Utils.convertBytesToShort(varParam, 4);
+               newTAP._brcLeft[1] = Utils.convertBytesToShort(varParam, 6);
+
+               newTAP._brcBottom[0] = Utils.convertBytesToShort(varParam, 8);
+               newTAP._brcBottom[1] = Utils.convertBytesToShort(varParam, 10);
+
+               newTAP._brcRight[0] = Utils.convertBytesToShort(varParam, 12);
+               newTAP._brcRight[1] = Utils.convertBytesToShort(varParam, 14);
+
+               newTAP._brcHorizontal[0] = Utils.convertBytesToShort(varParam, 16);
+               newTAP._brcHorizontal[1] = Utils.convertBytesToShort(varParam, 18);
+
+               newTAP._brcVertical[0] = Utils.convertBytesToShort(varParam, 20);
+               newTAP._brcVertical[1] = Utils.convertBytesToShort(varParam, 22);
+               break;
+          case 0x06:
+               //obsolete, used in word 1.x
+               break;
+          case 0x07:
+               newTAP._dyaRowHeight = param;
+               break;
+          case 0x08:
+               //I use varParam[0] and newTAP._itcMac interchangably
+               newTAP._itcMac = varParam[0];
+               newTAP._rgdxaCenter = new short[varParam[0] + 1];
+               newTAP._rgtc = new TC[varParam[0]];
+
+               for(int x = 0; x < newTAP._itcMac; x++)
+               {
+                 newTAP._rgdxaCenter[x] = Utils.convertBytesToShort(varParam , 1 + (x * 2));
+                 newTAP._rgtc[x] = TC.convertBytesToTC(varParam, 1 + ((varParam[0] + 1) * 2) + (x * 20));
+               }
+               newTAP._rgdxaCenter[newTAP._itcMac] = Utils.convertBytesToShort(varParam , 1 + (newTAP._itcMac * 2));
+               break;
+          case 0x09:
+               /** @todo handle cell shading*/
+               break;
+          case 0x0a:
+               /** @todo handle word defined table styles*/
+               break;
+          case 0x20:
+               for(int x = varParam[0]; x < varParam[1]; x++)
+               {
+                 if((varParam[2] & 0x08) > 0)
+                 {
+                   newTAP._rgtc[x]._brcRight[0] = Utils.convertBytesToShort(varParam, 6);
+                   newTAP._rgtc[x]._brcRight[1] = Utils.convertBytesToShort(varParam, 8);
+                 }
+                 else if((varParam[2] & 0x04) > 0)
+                 {
+                   newTAP._rgtc[x]._brcBottom[0] = Utils.convertBytesToShort(varParam, 6);
+                   newTAP._rgtc[x]._brcBottom[1] = Utils.convertBytesToShort(varParam, 8);
+                 }
+                 else if((varParam[2] & 0x02) > 0)
+                 {
+                   newTAP._rgtc[x]._brcLeft[0] = Utils.convertBytesToShort(varParam, 6);
+                   newTAP._rgtc[x]._brcLeft[1] = Utils.convertBytesToShort(varParam, 8);
+                 }
+                 else if((varParam[2] & 0x01) > 0)
+                 {
+                   newTAP._rgtc[x]._brcTop[0] = Utils.convertBytesToShort(varParam, 6);
+                   newTAP._rgtc[x]._brcTop[1] = Utils.convertBytesToShort(varParam, 8);
+                 }
+               }
+               break;
+          case 0x21:
+               int index = (param & 0xff000000) >> 24;
+               int count = (param & 0x00ff0000) >> 16;
+               int width = (param & 0x0000ffff);
+
+               short[] rgdxaCenter = new short[newTAP._itcMac + count + 1];
+               TC[] rgtc = new TC[newTAP._itcMac + count];
+               if(index >= newTAP._itcMac)
+               {
+                 index = newTAP._itcMac;
+                 System.arraycopy(newTAP._rgdxaCenter, 0, rgdxaCenter, 0, newTAP._itcMac + 1);
+                 System.arraycopy(newTAP._rgtc, 0, rgtc, 0, newTAP._itcMac);
+               }
+               else
+               {
+                 //copy rgdxaCenter
+                 System.arraycopy(newTAP._rgdxaCenter, 0, rgdxaCenter, 0, index + 1);
+                 System.arraycopy(newTAP._rgdxaCenter, index + 1, rgdxaCenter, index + count, (newTAP._itcMac) - (index));
+                 //copy rgtc
+                 System.arraycopy(newTAP._rgtc, 0, rgtc, 0, index);
+                 System.arraycopy(newTAP._rgtc, index, rgtc, index + count, newTAP._itcMac - index);
+               }
+
+               for(int x = index; x < index + count; x++)
+               {
+                 rgtc[x] = new TC();
+                 rgdxaCenter[x] = (short)(rgdxaCenter[x-1] + width);
+               }
+               rgdxaCenter[index + count] = (short)(rgdxaCenter[(index + count)-1] + width);
+               break;
+          /**@todo handle table sprms from complex files*/
+          case 0x22:
+          case 0x23:
+          case 0x24:
+          case 0x25:
+          case 0x26:
+          case 0x27:
+          case 0x28:
+          case 0x29:
+          case 0x2a:
+          case 0x2b:
+          case 0x2c:
+               break;
+          default:
+               break;
+      }
+  }
+  static void doSEPOperation(SEP newSEP, int operand, int param, byte[] varParam)
+  {
+      switch(operand)
+      {
+          case 0:
+               newSEP._cnsPgn = (byte)param;
+               break;
+          case 0x1:
+               newSEP._iHeadingPgn = (byte)param;
+               break;
+          case 0x2:
+               newSEP._olstAnn = varParam;
+               break;
+          case 0x3:
+               //not quite sure
+               break;
+          case 0x4:
+               //not quite sure
+               break;
+          case 0x5:
+               newSEP._fEvenlySpaced = getFlag(param);
+               break;
+          case 0x6:
+               newSEP._fUnlocked = getFlag(param);
+               break;
+          case 0x7:
+               newSEP._dmBinFirst = (short)param;
+               break;
+          case 0x8:
+               newSEP._dmBinOther = (short)param;
+               break;
+          case 0x9:
+               newSEP._bkc = (byte)param;
+               break;
+          case 0xa:
+               newSEP._fTitlePage = getFlag(param);
+               break;
+          case 0xb:
+               newSEP._ccolM1 = (short)param;
+               break;
+          case 0xc:
+               newSEP._dxaColumns = param;
+               break;
+          case 0xd:
+               newSEP._fAutoPgn = getFlag(param);
+               break;
+          case 0xe:
+               newSEP._nfcPgn = (byte)param;
+               break;
+          case 0xf:
+               newSEP._dyaPgn = (short)param;
+               break;
+          case 0x10:
+               newSEP._dxaPgn = (short)param;
+               break;
+          case 0x11:
+               newSEP._fPgnRestart = getFlag(param);
+               break;
+          case 0x12:
+               newSEP._fEndNote = getFlag(param);
+               break;
+          case 0x13:
+               newSEP._lnc = (byte)param;
+               break;
+          case 0x14:
+               newSEP._grpfIhdt = (byte)param;
+               break;
+          case 0x15:
+               newSEP._nLnnMod = (short)param;
+               break;
+          case 0x16:
+               newSEP._dxaLnn = param;
+               break;
+          case 0x17:
+               newSEP._dyaHdrTop = param;
+               break;
+          case 0x18:
+               newSEP._dyaHdrBottom = param;
+               break;
+          case 0x19:
+               newSEP._fLBetween = getFlag(param);
+               break;
+          case 0x1a:
+               newSEP._vjc = (byte)param;
+               break;
+          case 0x1b:
+               newSEP._lnnMin = (short)param;
+               break;
+          case 0x1c:
+               newSEP._pgnStart = (short)param;
+               break;
+          case 0x1d:
+               newSEP._dmOrientPage = (byte)param;
+               break;
+          case 0x1e:
+               //nothing
+               break;
+          case 0x1f:
+               newSEP._xaPage = param;
+               break;
+          case 0x20:
+               newSEP._yaPage = param;
+               break;
+          case 0x21:
+               newSEP._dxaLeft = param;
+               break;
+          case 0x22:
+               newSEP._dxaRight = param;
+               break;
+          case 0x23:
+               newSEP._dyaTop = param;
+               break;
+          case 0x24:
+               newSEP._dyaBottom = param;
+               break;
+          case 0x25:
+               newSEP._dzaGutter = param;
+               break;
+          case 0x26:
+               newSEP._dmPaperReq = (short)param;
+               break;
+          case 0x27:
+               newSEP._fPropMark = getFlag(varParam[0]);
+               break;
+          case 0x28:
+               break;
+          case 0x29:
+               break;
+          case 0x2a:
+               break;
+          case 0x2b:
+               newSEP._brcTop[0] = (short)(param & 0xffff);
+               newSEP._brcTop[1] = (short)((param & 0xffff0000) >> 16);
+               break;
+          case 0x2c:
+               newSEP._brcLeft[0] = (short)(param & 0xffff);
+               newSEP._brcLeft[1] = (short)((param & 0xffff0000) >> 16);
+               break;
+          case 0x2d:
+               newSEP._brcBottom[0] = (short)(param & 0xffff);
+               newSEP._brcBottom[1] = (short)((param & 0xffff0000) >> 16);
+               break;
+          case 0x2e:
+               newSEP._brcRight[0] = (short)(param & 0xffff);
+               newSEP._brcRight[1] = (short)((param & 0xffff0000) >> 16);
+               break;
+          case 0x2f:
+               newSEP._pgbProp = (short)param;
+               break;
+          case 0x30:
+               newSEP._dxtCharSpace = param;
+               break;
+          case 0x31:
+               newSEP._dyaLinePitch = param;
+               break;
+          case 0x33:
+               newSEP._wTextFlow = (short)param;
+               break;
+          default:
+               break;
+      }
+
+  }
+  private static boolean getCHPFlag(byte x, boolean oldVal)
+  {
+      switch(x)
+      {
+          case 0:
+               return false;
+          case 1:
+               return true;
+          case (byte)0x80:
+               return oldVal;
+          case (byte)0x81:
+               return !oldVal;
+          default:
+               return false;
+      }
+  }
+  public static boolean getFlag(int x)
+  {
+      if(x != 0)
+      {
+          return true;
+      }
+      else
+      {
+          return false;
+      }
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/TAP.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/TAP.java
new file mode 100644 (file)
index 0000000..6aa9d43
--- /dev/null
@@ -0,0 +1,87 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class TAP
+{
+  short _jc;
+  int _dxaGapHalf;
+  int _dyaRowHeight;
+  boolean _fCantSplit;
+  boolean _fTableHeader;
+  boolean _fLastRow;
+  short _itcMac;
+  short[] _rgdxaCenter;
+  short[] _brcLeft = new short[2];
+  short[] _brcRight = new short[2];
+  short[] _brcTop = new short[2];
+  short[] _brcBottom = new short[2];
+  short[] _brcHorizontal = new short[2];
+  short[] _brcVertical = new short[2];
+
+  TC[] _rgtc;
+
+
+  public TAP()
+  {
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/TC.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/TC.java
new file mode 100644 (file)
index 0000000..14d85f9
--- /dev/null
@@ -0,0 +1,111 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class TC
+{
+
+  boolean _fFirstMerged;
+  boolean _fMerged;
+  boolean _fVertical;
+  boolean _fBackward;
+  boolean _fRotateFont;
+  boolean _fVertMerge;
+  boolean _fVertRestart;
+  short _vertAlign;
+  short[] _brcTop = new short[2];
+  short[] _brcLeft = new short[2];
+  short[] _brcBottom = new short[2];
+  short[] _brcRight = new short [2];
+
+  public TC()
+  {
+  }
+  static TC convertBytesToTC(byte[] array, int offset)
+  {
+    TC tc = new TC();
+    int rgf = Utils.convertBytesToShort(array, offset);
+    tc._fFirstMerged = (rgf & 0x0001) > 0;
+    tc._fMerged = (rgf & 0x0002) > 0;
+    tc._fVertical = (rgf & 0x0004) > 0;
+    tc._fBackward = (rgf & 0x0008) > 0;
+    tc._fRotateFont = (rgf & 0x0010) > 0;
+    tc._fVertMerge = (rgf & 0x0020) > 0;
+    tc._fVertRestart = (rgf & 0x0040) > 0;
+    tc._vertAlign = (short)((rgf & 0x0180) >> 7);
+
+    tc._brcTop[0] = Utils.convertBytesToShort(array, offset + 4);
+    tc._brcTop[1] = Utils.convertBytesToShort(array, offset + 6);
+
+    tc._brcLeft[0] = Utils.convertBytesToShort(array, offset + 8);
+    tc._brcLeft[1] = Utils.convertBytesToShort(array, offset + 10);
+
+    tc._brcBottom[0] = Utils.convertBytesToShort(array, offset + 12);
+    tc._brcBottom[1] = Utils.convertBytesToShort(array, offset + 14);
+
+    tc._brcRight[0] = Utils.convertBytesToShort(array, offset + 16);
+    tc._brcRight[1] = Utils.convertBytesToShort(array, offset + 18);
+
+    return tc;
+  }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/TableRow.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/TableRow.java
new file mode 100644 (file)
index 0000000..cdd969e
--- /dev/null
@@ -0,0 +1,84 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+import java.util.*;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class TableRow
+{
+  TAP _descriptor;
+  Vector _cells;
+
+  public TableRow(Vector cells, TAP descriptor)
+  {
+    _cells = cells;
+    _descriptor = descriptor;
+  }
+  public TAP getTAP()
+  {
+    return _descriptor;
+  }
+  public Vector getCells()
+  {
+    return _cells;
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/TextPiece.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/TextPiece.java
new file mode 100644 (file)
index 0000000..f52536a
--- /dev/null
@@ -0,0 +1,88 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hdf.extractor;
+
+import org.apache.poi.hdf.extractor.util.*;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class TextPiece extends PropertyNode implements Comparable
+{
+  private boolean _usesUnicode;
+  private int _length;
+
+  public TextPiece(int start, int length, boolean unicode)
+  {
+    super(start, start + length, null);
+      _usesUnicode = unicode;
+      _length = length;
+      //_fcStart = start;
+      //_fcEnd = start + length;
+
+  }
+   public boolean usesUnicode()
+  {
+      return _usesUnicode;
+  }
+
+   public int compareTo(Object obj) {
+       return 0;
+   }
+   
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/Utils.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/Utils.java
new file mode 100644 (file)
index 0000000..6c397c9
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class Utils
+{
+
+    public static short convertBytesToShort(byte firstByte, byte secondByte)
+    {
+        return (short)convertBytesToInt((byte)0, (byte)0, firstByte, secondByte);
+    }
+    public static int convertBytesToInt(byte firstByte, byte secondByte,
+                                  byte thirdByte, byte fourthByte)
+    {
+        int firstInt = 0xff & firstByte;
+        int secondInt = 0xff & secondByte;
+        int thirdInt = 0xff & thirdByte;
+        int fourthInt = 0xff & fourthByte;
+
+        return (firstInt << 24) | (secondInt << 16) | (thirdInt << 8) | fourthInt;
+    }
+    public static short convertBytesToShort(byte[] array, int offset)
+    {
+        return convertBytesToShort(array[offset + 1], array[offset]);
+    }
+    public static int convertBytesToInt(byte[] array, int offset)
+    {
+        return convertBytesToInt(array[offset + 3], array[offset + 2], array[offset + 1], array[offset]);
+    }
+    public static int convertUnsignedByteToInt(byte b)
+    {
+        return (0xff & b);
+    }
+    public static char getUnicodeCharacter(byte[] array, int offset)
+    {
+      return (char)convertBytesToShort(array, offset);
+    }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/WordDocument.java
new file mode 100644 (file)
index 0000000..3796fe0
--- /dev/null
@@ -0,0 +1,1755 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor;
+
+import org.apache.poi.hdf.extractor.util.*;
+import org.apache.poi.hdf.extractor.data.*;
+import java.util.*;
+import java.io.*;
+import javax.swing.*;
+//import javax.swing.text.StyleContext;
+import java.awt.*;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class WordDocument extends NewOleFile
+{
+  byte[] _header;
+
+  StyleSheet _styleSheet;
+  ListTables _listTables;
+  DOP _docProps = new DOP();
+  int _currentList = -1;
+  int _tableSize;
+  int _sectionCounter = 1;
+  FontTable _fonts;
+
+  BTreeSet _text = new BTreeSet();
+  BTreeSet _characterTable = new BTreeSet();
+  BTreeSet _paragraphTable = new BTreeSet();
+  BTreeSet _sectionTable = new BTreeSet();
+
+  //WordDocWriter _writer = this;
+  StringBuffer _headerBuffer = new StringBuffer();
+  StringBuffer _bodyBuffer = new StringBuffer();
+  StringBuffer _cellBuffer;
+
+  Vector _cells;
+  Vector _table;
+
+  byte[] _plcfHdd;
+  int _fcMin;
+  int _ccpText;
+  int _ccpFtn;
+
+
+  private static int HEADER_EVEN_INDEX = 0;
+  private static int HEADER_ODD_INDEX = 1;
+  private static int FOOTER_EVEN_INDEX = 2;
+  private static int FOOTER_ODD_INDEX = 3;
+  private static int HEADER_FIRST_INDEX = 4;
+  private static int FOOTER_FIRST_INDEX = 5;
+
+
+  public static void main(String args[])
+  {
+      /*try
+      {
+        WordDocument file = new WordDocument(args[0], "r");
+        Writer out = new BufferedWriter(new FileWriter(args[1]));
+        file.writeAllText(out);
+        out.flush();
+        out.close();
+      }
+      catch(Throwable t)
+      {
+        t.printStackTrace();
+      }*/
+      try
+      {
+          WordDocument file = new WordDocument(args[0], "r");
+          file.closeDoc();
+      }
+      catch(Exception e)
+      {
+          e.printStackTrace();
+      }
+      System.exit(0);
+  }
+  public void writeAllText(Writer out) throws IOException
+  {
+    int textStart = Utils.convertBytesToInt(_header, 0x18);
+    int textEnd = Utils.convertBytesToInt(_header, 0x1c);
+    Vector textPieces = findProperties(textStart, textEnd, _text.root);
+    int size = textPieces.size();
+
+    for(int x = 0; x < size; x++)
+    {
+      TextPiece nextPiece = (TextPiece)textPieces.get(x);
+      int start = nextPiece.getStart();
+      int end = nextPiece.getEnd();
+      boolean unicode = nextPiece.usesUnicode();
+      int add = 1;
+
+      if(unicode)
+      {
+        add = 2;
+      }
+      char ch;
+      for(int y = start; y < end; y += add)
+      {
+        if(unicode)
+        {
+          ch = (char)Utils.convertBytesToShort(_header, y);
+        }
+        else
+        {
+          ch = (char)_header[y];
+        }
+        out.write(ch);
+      }
+    }
+  }
+  public WordDocument(String fileName, String mode) throws IOException
+  {
+        super(fileName, mode);
+
+        readFIB();
+
+        Vector sections = findProperties(_fcMin, _fcMin + _ccpText, _sectionTable.root);
+
+        int size = sections.size();
+        for(int x = 0; x < size; x++)
+        {
+          SepxNode node = (SepxNode)sections.get(x);
+          int start = node.getStart();
+          int end = node.getEnd();
+          SEP sep = (SEP)StyleSheet.uncompressProperty(node.getSepx(), new SEP(), _styleSheet);
+          writeSection(Math.max(_fcMin, start), Math.min(_fcMin + _ccpText, end), sep, _text, _paragraphTable, _characterTable, _styleSheet);
+        }
+
+  }
+  private void readFIB() throws IOException
+  {
+      PropertySet headerProps = (PropertySet)_propertySetsHT.get("WordDocument");
+
+      if(headerProps.getSize() >= 4096)
+      {
+          _header = createBufferFromBBD(headerProps.getStartBlock());
+      }
+      int info = Utils.convertBytesToShort(_header, 0xa);
+
+      _fcMin = Utils.convertBytesToInt(_header, 0x18);
+      _ccpText = Utils.convertBytesToInt(_header, 0x4c);
+      _ccpFtn = Utils.convertBytesToInt(_header, 0x50);
+
+      int charPLC = Utils.convertBytesToInt(_header, 0xfa);
+      int charPlcSize = Utils.convertBytesToInt(_header, 0xfe);
+      int parPLC = Utils.convertBytesToInt(_header, 0x102);
+      int parPlcSize = Utils.convertBytesToInt(_header, 0x106);
+      boolean useTable1 = (info & 0x200) != 0;
+
+      processComplexFile(useTable1, charPLC, charPlcSize, parPLC, parPlcSize);
+  }
+
+  private boolean processComplexFile(boolean useTable1, int charTable,
+                                     int charPlcSize, int parTable, int parPlcSize) throws IOException
+  {
+      int complexOffset = Utils.convertBytesToInt(_header, 0x1a2);
+      //int complexSize = Utils.convertBytesToInt(_header, 0x1a6);
+
+      //if(complexSize <= 0)
+      //{
+      //    return false;
+      //}
+
+      PropertySet tableProps = null;
+      if(useTable1)
+      {
+          tableProps = (PropertySet)_propertySetsHT.get("1Table");
+      }
+      else
+      {
+          tableProps = (PropertySet)_propertySetsHT.get("0Table");
+      }
+      //get table properties
+      int size = tableProps.getSize();
+      int startBlock = tableProps.getStartBlock();
+
+      byte[] tableStream = null;
+      //big enough to use BBD?
+      if(size >= 4096)
+      {
+          tableStream = createBufferFromBBD(startBlock);
+      }
+      initDocProperties(tableStream);
+      initPclfHdd(tableStream);
+      findText(tableStream, complexOffset);
+      findFormatting(tableStream, charTable, charPlcSize, parTable, parPlcSize);
+
+      return true;
+
+  }
+  private void findText(byte[] tableStream, int complexOffset) throws IOException
+  {
+    //actual text
+    int pos = complexOffset;
+    while(tableStream[pos] == 1)
+    {
+        pos++;
+        int skip = Utils.convertBytesToShort(tableStream, pos);
+        pos += 2 + skip;
+    }
+    if(tableStream[pos] != 2)
+    {
+        throw new IOException("corrupted Word file");
+    }
+    else
+    {
+        int pieceTableSize = Utils.convertBytesToInt(tableStream, ++pos);
+        pos += 4;
+        int pieces = (pieceTableSize - 4) / 12;
+        for (int x = 0; x < pieces; x++)
+        {
+            int filePos = Utils.convertBytesToInt(tableStream, pos + ((pieces + 1) * 4) + (x * 8) + 2);
+            boolean unicode = false;
+            if ((filePos & 0x40000000) == 0)
+            {
+                unicode = true;
+            }
+            else
+            {
+                unicode = false;
+                filePos &= ~(0x40000000);//gives me FC in doc stream
+                filePos /= 2;
+            }
+            int totLength = Utils.convertBytesToInt(tableStream, pos + (x + 1) * 4) -
+                            Utils.convertBytesToInt(tableStream, pos + (x * 4));
+
+            TextPiece piece = new TextPiece(filePos, totLength, unicode);
+            _text.add(piece);
+
+        }
+
+    }
+  }
+  private void printText(CHP chp, byte[] grpprl, int filePos, int length)
+  {
+
+  }
+
+  private void findFormatting(byte[] tableStream, int charOffset,
+                              int charPlcSize, int parOffset, int parPlcSize) throws IOException
+  {
+      openDoc();
+      createStyleSheet(tableStream);
+      createListTables(tableStream);
+      createFontTable(tableStream);
+
+      //find character runs
+      //Get all the chpx info and store it
+
+      int arraySize = (charPlcSize - 4)/8;
+      //int[][] parFkpTable = new int[arraySize][2];
+      //first we must go through the bin table and find the fkps
+      for(int x = 0; x < arraySize; x++)
+      {
+
+          //get fc of the start of the paragraph
+          //parFkpTable[x][0] = Utils.convertBytesToInt(tableStream, parOffset + (x * 4));
+          //get pn containing the chpx for the paragraph
+          //parFkpTable[x][1] = Utils.convertBytesToInt(tableStream, parOffset + (4 * (arraySize + 1) + (4 * x)));
+          int PN = Utils.convertBytesToInt(tableStream, charOffset + (4 * (arraySize + 1) + (4 * x)));
+
+          byte[] fkp = new byte[512];
+          System.arraycopy(_header, (PN * 512), fkp, 0, 512);
+          //take each fkp and get the paps
+          int crun = Utils.convertUnsignedByteToInt(fkp[511]);
+          for(int y = 0; y < crun; y++)
+          {
+              //get the beginning fc of each paragraph text run
+              int fcStart = Utils.convertBytesToInt(fkp, y * 4);
+              int fcEnd = Utils.convertBytesToInt(fkp, (y+1) * 4);
+              //get the offset in fkp of the papx for this paragraph
+              int chpxOffset = 2 * Utils.convertUnsignedByteToInt(fkp[((crun + 1) * 4) + y]);
+
+              //optimization if offset == 0 use "Normal" style
+              if(chpxOffset == 0)
+
+              {
+                _characterTable.add(new ChpxNode(fcStart, fcEnd, new byte[0]));
+                continue;
+              }
+
+              int size = Utils.convertUnsignedByteToInt(fkp[chpxOffset]);
+
+              byte[] chpx = new byte[size];
+              System.arraycopy(fkp, ++chpxOffset, chpx, 0, size);
+              //_papTable.put(new Integer(fcStart), papx);
+              _characterTable.add(new ChpxNode(fcStart, fcEnd, chpx));
+          }
+
+      }
+
+      //find paragraphs
+      arraySize = (parPlcSize - 4)/8;
+      //first we must go through the bin table and find the fkps
+      for(int x = 0; x < arraySize; x++)
+      {
+          int PN = Utils.convertBytesToInt(tableStream, parOffset + (4 * (arraySize + 1) + (4 * x)));
+
+          byte[] fkp = new byte[512];
+          System.arraycopy(_header, (PN * 512), fkp, 0, 512);
+          //take each fkp and get the paps
+          int crun = Utils.convertUnsignedByteToInt(fkp[511]);
+          for(int y = 0; y < crun; y++)
+          {
+              //get the beginning fc of each paragraph text run
+              int fcStart = Utils.convertBytesToInt(fkp, y * 4);
+              int fcEnd = Utils.convertBytesToInt(fkp, (y+1) * 4);
+              //get the offset in fkp of the papx for this paragraph
+              int papxOffset = 2 * Utils.convertUnsignedByteToInt(fkp[((crun + 1) * 4) + (y * 13)]);
+              int size = 2 * Utils.convertUnsignedByteToInt(fkp[papxOffset]);
+              if(size == 0)
+              {
+                  size = 2 * Utils.convertUnsignedByteToInt(fkp[++papxOffset]);
+              }
+              else
+              {
+                  size--;
+              }
+
+              byte[] papx = new byte[size];
+              System.arraycopy(fkp, ++papxOffset, papx, 0, size);
+              _paragraphTable.add(new PapxNode(fcStart, fcEnd, papx));
+
+          }
+
+      }
+      //find sections
+      int fcMin = Utils.convertBytesToInt(_header, 0x18);
+      int plcfsedFC = Utils.convertBytesToInt(_header, 0xca);
+      int plcfsedSize = Utils.convertBytesToInt(_header, 0xce);
+      byte[] plcfsed = new byte[plcfsedSize];
+      System.arraycopy(tableStream, plcfsedFC, plcfsed, 0, plcfsedSize);
+
+      arraySize = (plcfsedSize - 4)/16;
+
+      //openDoc();
+
+      for(int x = 0; x < arraySize; x++)
+      {
+          int sectionStart = Utils.convertBytesToInt(plcfsed, x * 4) + fcMin;
+          int sectionEnd = Utils.convertBytesToInt(plcfsed, (x+1) * 4) + fcMin;
+          int sepxStart = Utils.convertBytesToInt(plcfsed, 4 * (arraySize + 1) + (x * 12) + 2);
+          int sepxSize = Utils.convertBytesToShort(_header, sepxStart);
+          byte[] sepx = new byte[sepxSize];
+          System.arraycopy(_header, sepxStart + 2, sepx, 0, sepxSize);
+          SepxNode node = new SepxNode(x + 1, sectionStart, sectionEnd, sepx);
+          _sectionTable.add(node);
+          //HeaderFooter[] hdrftr = findSectionHdrFtr(x);
+      }
+
+
+  }
+  public void openDoc()
+  {
+    _headerBuffer.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\r\n");
+    _headerBuffer.append("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\r\n");
+    _headerBuffer.append("<fo:layout-master-set>\r\n");
+    //_headerBuffer.append("<fo:simple-page-master master-name=\"my-page\">\r\n");
+
+  }
+  private HeaderFooter findSectionHdrFtr(int type, int index)
+  {
+    if(_plcfHdd.length < 50)
+    {
+      return new HeaderFooter(0,0,0);
+    }
+    int start = _fcMin + _ccpText + _ccpFtn;
+    int end = start;
+    int arrayIndex = 0;
+
+    switch(type)
+    {
+      case HeaderFooter.HEADER_EVEN:
+           arrayIndex = (HEADER_EVEN_INDEX + (index * 6));
+           break;
+      case HeaderFooter.FOOTER_EVEN:
+           arrayIndex = (FOOTER_EVEN_INDEX + (index * 6));
+           break;
+      case HeaderFooter.HEADER_ODD:
+           arrayIndex = (HEADER_ODD_INDEX + (index * 6));
+           break;
+      case HeaderFooter.FOOTER_ODD:
+           arrayIndex = (FOOTER_ODD_INDEX + (index * 6));
+           break;
+      case HeaderFooter.HEADER_FIRST:
+           arrayIndex = (HEADER_FIRST_INDEX + (index * 6));
+           break;
+      case HeaderFooter.FOOTER_FIRST:
+           arrayIndex = (FOOTER_FIRST_INDEX + (index * 6));
+           break;
+    }
+    start += Utils.convertBytesToInt(_plcfHdd, (arrayIndex * 4));
+    end += Utils.convertBytesToInt(_plcfHdd, (arrayIndex + 1) * 4);
+
+    HeaderFooter retValue = new HeaderFooter(type, start, end);
+
+    if((end - start) == 0 && index > 1)
+    {
+      retValue = findSectionHdrFtr(type, index - 1);
+    }
+    return retValue;
+  }
+  private void initDocProperties(byte[] tableStream)
+  {
+    int pos = Utils.convertBytesToInt(_header, 0x192);
+    int size = Utils.convertBytesToInt(_header, 0x196);
+    byte[] dop = new byte[size];
+
+    System.arraycopy(tableStream, pos, dop, 0, size);
+
+    _docProps._fFacingPages = (dop[0] & 0x1) > 0;
+    _docProps._fpc = (dop[0] & 0x60) >> 5;
+
+    short num = Utils.convertBytesToShort(dop, 2);
+    _docProps._rncFtn = (num & 0x3);
+    _docProps._nFtn = (short)(num & 0xfffc) >> 2;
+    num = Utils.convertBytesToShort(dop, 52);
+    _docProps._rncEdn = num & 0x3;
+    _docProps._nEdn = (short)(num & 0xfffc) >> 2;
+    num = Utils.convertBytesToShort(dop, 54);
+    _docProps._epc = num & 0x3;
+  }
+
+  public void writeSection(int start, int end, SEP sep, BTreeSet text,
+                           BTreeSet paragraphTable, BTreeSet characterTable,
+                           StyleSheet stylesheet)
+  {
+
+    HeaderFooter titleHeader = findSectionHdrFtr(HeaderFooter.HEADER_FIRST, _sectionCounter);
+    HeaderFooter titleFooter = findSectionHdrFtr(HeaderFooter.FOOTER_FIRST, _sectionCounter);
+    HeaderFooter oddHeader = findSectionHdrFtr(HeaderFooter.HEADER_ODD, _sectionCounter);
+    HeaderFooter evenHeader = findSectionHdrFtr(HeaderFooter.HEADER_EVEN, _sectionCounter);
+    HeaderFooter oddFooter = findSectionHdrFtr(HeaderFooter.FOOTER_ODD, _sectionCounter);
+    HeaderFooter evenFooter = findSectionHdrFtr(HeaderFooter.FOOTER_EVEN, _sectionCounter);
+
+    String titlePage = null;
+    String evenPage = null;
+    String oddPage = null;
+    String regPage = null;
+
+    String sequenceName = null;
+
+    /*if(sep._fTitlePage)
+    {
+      titlePage = createPageMaster(sep, "first", _sectionCounter, createRegion("before", "title-header"), createRegion("after", "title-footer"));
+
+      if(!titleHeader.isEmpty())
+      {
+        addStaticContent("title-header" + _sectionCounter, titleHeader);
+      }
+      if(!titleFooter.isEmpty())
+      {
+        addStaticContent("title-footer" + _sectionCounter, titleFooter);
+      }
+    }*/
+
+    if(_docProps._fFacingPages)
+    {
+      if(sep._fTitlePage)
+      {
+        String before = createRegion(true, titleHeader, sep, "title-header" + _sectionCounter);
+        String after = createRegion(false, titleFooter, sep, "title-footer" + _sectionCounter);
+        titlePage = createPageMaster(sep, "first", _sectionCounter, before, after);
+      }
+      String before = createRegion(true, evenHeader, sep, "even-header" + _sectionCounter);
+      String after = createRegion(false, evenFooter, sep, "even-footer" + _sectionCounter);
+      evenPage = createPageMaster(sep, "even", _sectionCounter, before, after);
+      before = createRegion(true, oddHeader, sep, "odd-header" + _sectionCounter);
+      after = createRegion(false, oddFooter, sep, "odd-footer" + _sectionCounter);
+      oddPage = createPageMaster(sep, "odd", _sectionCounter, before, after);
+      sequenceName = createEvenOddPageSequence(titlePage, evenPage, oddPage, _sectionCounter);
+
+      openPage(sequenceName, "reference");
+
+      if(sep._fTitlePage)
+      {
+
+
+        if(!titleHeader.isEmpty())
+        {
+          addStaticContent("title-header" + _sectionCounter, titleHeader);
+        }
+        if(!titleFooter.isEmpty())
+        {
+          addStaticContent("title-footer" + _sectionCounter, titleFooter);
+        }
+      }
+
+      //handle the headers and footers for odd and even pages
+      if(!oddHeader.isEmpty())
+      {
+        addStaticContent("odd-header" + _sectionCounter, oddHeader);
+      }
+      if(!oddFooter.isEmpty())
+      {
+        addStaticContent("odd-footer" + _sectionCounter, oddFooter);
+      }
+      if(!evenHeader.isEmpty())
+      {
+        addStaticContent("even-header" + _sectionCounter, evenHeader);
+      }
+      if(!evenFooter.isEmpty())
+      {
+        addStaticContent("even-footer" + _sectionCounter, evenFooter);
+      }
+      openFlow();
+      addBlockContent(start, end, text, paragraphTable, characterTable);
+      closeFlow();
+      closePage();
+    }
+    else
+    {
+      /*if(sep._fTitlePage)
+      {
+        String before = createRegion(true, titleHeader, sep);
+        String after = createRegion(false, titleFooter, sep);
+        titlePage = createPageMaster(sep, "first", _sectionCounter, before, after);
+      }*/
+      String before = createRegion(true, oddHeader, sep, null);
+      String after = createRegion(false, oddFooter, sep, null);
+      regPage = createPageMaster(sep, "page", _sectionCounter, before, after);
+
+      if(sep._fTitlePage)
+      {
+        before = createRegion(true, titleHeader, sep, "title-header" + _sectionCounter);
+        after = createRegion(false, titleFooter, sep, "title-footer" + _sectionCounter);
+        titlePage = createPageMaster(sep, "first", _sectionCounter, before, after);
+        sequenceName = createPageSequence(titlePage, regPage, _sectionCounter);
+        openPage(sequenceName, "reference");
+
+        if(!titleHeader.isEmpty())
+        {
+          addStaticContent("title-header" + _sectionCounter, titleHeader);
+        }
+        if(!titleFooter.isEmpty())
+        {
+          addStaticContent("title-footer" + _sectionCounter, titleFooter);
+        }
+      }
+      else
+      {
+        openPage(regPage, "name");
+      }
+      if(!oddHeader.isEmpty())
+      {
+        addStaticContent("xsl-region-before", oddHeader);
+      }
+      if(!oddFooter.isEmpty())
+      {
+        addStaticContent("xsl-region-after", oddFooter);
+      }
+      openFlow();
+      addBlockContent(start, end, text, paragraphTable, characterTable);
+      closeFlow();
+      closePage();
+    }
+    _sectionCounter++;
+  }
+
+  private int calculateHeaderHeight(int start, int end, int pageWidth)
+  {
+    Vector paragraphs = findProperties(start, end, _paragraphTable.root);
+    int size = paragraphs.size();
+    Vector lineHeights = new Vector();
+    //StyleContext context = StyleContext.getDefaultStyleContext();
+
+    for(int x = 0; x < size; x++)
+    {
+      PapxNode node = (PapxNode)paragraphs.get(x);
+      int parStart = Math.max(node.getStart(), start);
+      int parEnd = Math.min(node.getEnd(), end);
+
+      int lineWidth = 0;
+      int maxHeight = 0;
+
+      Vector textRuns = findProperties(parStart, parEnd, _characterTable.root);
+      int charSize = textRuns.size();
+
+      //StringBuffer lineBuffer = new StringBuffer();
+      for(int y = 0; y < charSize; y++)
+      {
+        ChpxNode charNode = (ChpxNode)textRuns.get(y);
+        int istd = Utils.convertBytesToShort(node.getPapx(), 0);
+        StyleDescription sd = _styleSheet.getStyleDescription(istd);
+        CHP chp = (CHP)StyleSheet.uncompressProperty(charNode.getChpx(), sd.getCHP(), _styleSheet);
+
+        //get Font info
+        //FontMetrics metrics = getFontMetrics(chp, context);
+
+        int height = 10;//metrics.getHeight();
+        maxHeight = Math.max(maxHeight, height);
+
+        int charStart = Math.max(parStart, charNode.getStart());
+        int charEnd = Math.min(parEnd, charNode.getEnd());
+
+        Vector text = findProperties(charStart, charEnd, _text.root);
+
+        int textSize = text.size();
+        StringBuffer buf = new StringBuffer();
+        for(int z = 0; z < textSize; z++)
+        {
+
+          TextPiece piece = (TextPiece)text.get(z);
+          int textStart = Math.max(piece.getStart(), charStart);
+          int textEnd = Math.min(piece.getEnd(), charEnd);
+
+          if(piece.usesUnicode())
+          {
+            addUnicodeText(textStart, textEnd, buf);
+          }
+          else
+          {
+            addText(textStart, textEnd, buf);
+          }
+        }
+
+        String tempString = buf.toString();
+        lineWidth += 10 * tempString.length();//metrics.stringWidth(tempString);
+        if(lineWidth > pageWidth)
+        {
+          lineHeights.add(new Integer(maxHeight));
+          maxHeight = 0;
+          lineWidth = 0;
+        }
+      }
+      lineHeights.add(new Integer(maxHeight));
+    }
+    int sum = 0;
+    size = lineHeights.size();
+    for(int x = 0; x < size; x++)
+    {
+      Integer height = (Integer)lineHeights.get(x);
+      sum += height.intValue();
+    }
+
+    return sum;
+  }
+/*  private FontMetrics getFontMetrics(CHP chp, StyleContext context)
+  {
+    String fontName = _fonts.getFont(chp._ftcAscii);
+    int style = 0;
+    if(chp._bold)
+    {
+      style |= Font.BOLD;
+    }
+    if(chp._italic)
+    {
+      style |= Font.ITALIC;
+    }
+
+    Font font = new Font(fontName, style, chp._hps/2);
+
+
+    return context.getFontMetrics(font);
+  }*/
+  private String createRegion(boolean before, HeaderFooter header, SEP sep, String name)
+  {
+    if(header.isEmpty())
+    {
+      return "";
+    }
+    String region = "region-name=\"" + name + "\"";
+    if(name == null)
+    {
+      region = "";
+    }
+    int height = calculateHeaderHeight(header.getStart(), header.getEnd(), sep._xaPage/20);
+    int marginTop = 0;
+    int marginBottom = 0;
+    int extent = 0;
+    String where = null;
+    String align = null;
+
+    if(before)
+    {
+      where = "before";
+      align = "before";
+      marginTop = sep._dyaHdrTop/20;
+      extent = height + marginTop;
+      sep._dyaTop = Math.max(extent*20, sep._dyaTop);
+    }
+    else
+    {
+      where = "after";
+      align = "after";
+      marginBottom = sep._dyaHdrBottom/20;
+      extent = height + marginBottom;
+      sep._dyaBottom = Math.max(extent*20, sep._dyaBottom);
+    }
+
+    int marginLeft = sep._dxaLeft/20;
+    int marginRight = sep._dxaRight/20;
+
+    return "<fo:region-" + where + " display-align=\"" + align + "\" extent=\"" +
+             extent + "pt\" padding-left=\"" + marginLeft + "pt\" padding-right=\"" +
+             marginRight + "pt\" padding-top=\"" + marginTop + "pt\" padding-bottom=\"" +
+             marginBottom + "pt\" " + region + "/>";
+
+  }
+  private String createRegion(String where, String name)
+  {
+    return "<fo:region-" + where + " overflow=\"scroll\" region-name=\"" + name + "\"/>";
+  }
+  private String createEvenOddPageSequence(String titlePage, String evenPage, String oddPage, int counter)
+  {
+    String name = "my-sequence" + counter;
+    _headerBuffer.append("<fo:page-sequence-master master-name=\"" + name + "\"> ");
+    _headerBuffer.append("<fo:repeatable-page-master-alternatives>");
+    if(titlePage != null)
+    {
+      _headerBuffer.append("<fo:conditional-page-master-reference " +
+                           "page-position=\"first\" master-reference=\"" +
+                            titlePage + "\"/>");
+    }
+    _headerBuffer.append("<fo:conditional-page-master-reference odd-or-even=\"odd\" ");
+    _headerBuffer.append("master-reference=\""+ oddPage + "\"/> ");
+    _headerBuffer.append("<fo:conditional-page-master-reference odd-or-even=\"even\" ");
+    _headerBuffer.append("master-reference=\"" + evenPage + "\"/> ");
+    _headerBuffer.append("</fo:repeatable-page-master-alternatives>");
+    _headerBuffer.append("</fo:page-sequence-master>");
+    return name;
+  }
+  private String createPageSequence(String titlePage, String regPage, int counter)
+  {
+    String name = null;
+    if(titlePage != null)
+    {
+      name = "my-sequence" + counter;
+      _headerBuffer.append("<fo:page-sequence-master master-name=\"" + name + "\"> ");
+      _headerBuffer.append("<fo:single-page-master-reference master-reference=\"" + titlePage + "\"/>");
+      _headerBuffer.append("<fo:repeatable-page-master-reference master-reference=\"" + regPage + "\"/>");
+      _headerBuffer.append("</fo:page-sequence-master>");
+    }
+    return name;
+  }
+  private void addBlockContent(int start, int end, BTreeSet text,
+                              BTreeSet paragraphTable, BTreeSet characterTable)
+  {
+
+    BTreeSet.BTreeNode root = paragraphTable.root;
+    Vector pars = findProperties(start, end, root);
+    //root = characterTable.root;
+    int size = pars.size();
+
+    for(int c = 0; c < size; c++)
+    {
+      PapxNode currentNode = (PapxNode)pars.get(c);
+      createParagraph(start, end, currentNode, characterTable, text);
+    }
+    //closePage();
+  }
+  private String getTextAlignment(byte jc)
+  {
+    switch(jc)
+    {
+      case 0:
+        return "start";
+      case 1:
+        return "center";
+      case 2:
+        return "end";
+      case 3:
+        return "justify";
+      default:
+        return "left";
+    }
+  }
+  private void createParagraph(int start, int end, PapxNode currentNode,
+                               BTreeSet characterTable, BTreeSet text)
+  {
+    StringBuffer blockBuffer = _bodyBuffer;
+    byte[] papx = currentNode.getPapx();
+    int istd = Utils.convertBytesToShort(papx, 0);
+    StyleDescription std = _styleSheet.getStyleDescription(istd);
+    PAP pap = (PAP)StyleSheet.uncompressProperty(papx, std.getPAP(), _styleSheet);
+
+    //handle table cells
+    if(pap._fInTable > 0)
+    {
+      if(pap._fTtp == 0)
+      {
+        if(_cellBuffer == null)
+        {
+          _cellBuffer = new StringBuffer();
+        }
+        blockBuffer = _cellBuffer;
+      }
+      else
+      {
+        if(_table == null)
+        {
+          _table = new Vector();
+        }
+        TAP tap = (TAP)StyleSheet.uncompressProperty(papx, new TAP(), _styleSheet);
+        TableRow nextRow = new TableRow(_cells, tap);
+        _table.add(nextRow);
+        _cells = null;
+        return;
+      }
+    }
+    else
+    {
+      //just prints out any table that is stored in _table
+      printTable();
+    }
+
+    if(pap._ilfo > 0)
+    {
+      LVL lvl = _listTables.getLevel(pap._ilfo, pap._ilvl);
+      addListParagraphContent(lvl, blockBuffer, pap, currentNode, start, end, std);
+    }
+    else
+    {
+      addParagraphContent(blockBuffer, pap, currentNode, start, end, std);
+    }
+
+  }
+
+  private void addListParagraphContent(LVL lvl, StringBuffer blockBuffer, PAP pap,
+                                       PapxNode currentNode, int start, int end,
+                                       StyleDescription std)
+  {
+    pap = (PAP)StyleSheet.uncompressProperty(lvl._papx, pap, _styleSheet, false);
+
+    addParagraphProperties(pap, blockBuffer);
+
+    Vector charRuns = findProperties(Math.max(currentNode.getStart(), start),
+                                     Math.min(currentNode.getEnd(), end),
+                                     _characterTable.root);
+    int len = charRuns.size();
+
+    CHP numChp = (CHP)StyleSheet.uncompressProperty(((ChpxNode)charRuns.get(len-1)).getChpx(), std.getCHP(), _styleSheet);
+
+    numChp = (CHP)StyleSheet.uncompressProperty(lvl._chpx, numChp, _styleSheet);
+
+    //StyleContext context = StyleContext.getDefaultStyleContext();
+    //FontMetrics metrics = getFontMetrics(numChp, context);
+    int indent = -1 * pap._dxaLeft1;
+    String bulletText = getBulletText(lvl, pap);
+
+    indent = indent - (bulletText.length() * 10) * 20;//(metrics.stringWidth(bulletText) * 20);
+
+    if(indent > 0)
+    {
+      numChp._paddingEnd = (short)indent;
+    }
+
+    addCharacterProperties(numChp, blockBuffer);
+    int listNum = 0;
+
+    //if(number != null)
+    //{
+    blockBuffer.append(bulletText);
+      //listNum = 1;
+    //}
+
+    //for(;listNum < lvl._xst.length; listNum++)
+    //{
+    //  addText(lvl._xst[listNum], blockBuffer);
+    //}
+
+
+    switch (lvl._ixchFollow)
+    {
+      case 0:
+        addText('\u0009', blockBuffer);
+        break;
+      case 1:
+        addText(' ', blockBuffer);
+        break;
+    }
+
+    closeLine(blockBuffer);
+    for(int x = 0; x < len; x++)
+    {
+      ChpxNode charNode = (ChpxNode)charRuns.get(x);
+      byte[] chpx = charNode.getChpx();
+      CHP chp = (CHP)StyleSheet.uncompressProperty(chpx, std.getCHP(), _styleSheet);
+
+
+      addCharacterProperties(chp, blockBuffer);
+
+      int charStart = Math.max(charNode.getStart(), currentNode.getStart());
+      int charEnd = Math.min(charNode.getEnd(), currentNode.getEnd());
+      Vector textRuns = findProperties(charStart, charEnd, _text.root);
+      int textRunLen = textRuns.size();
+      for(int y = 0; y < textRunLen; y++)
+      {
+        TextPiece piece = (TextPiece)textRuns.get(y);
+        charStart = Math.max(charStart, piece.getStart());
+        charEnd = Math.min(charEnd, piece.getEnd());
+
+        if(piece.usesUnicode())
+        {
+          addUnicodeText(charStart, charEnd, blockBuffer);
+        }
+        else
+        {
+          addText(charStart, charEnd, blockBuffer);
+        }
+        closeLine(blockBuffer);
+      }
+    }
+    closeBlock(blockBuffer);
+  }
+
+  private void addParagraphContent(StringBuffer blockBuffer, PAP pap,
+                                   PapxNode currentNode, int start, int end,
+                                   StyleDescription std)
+  {
+    addParagraphProperties(pap, blockBuffer);
+
+    Vector charRuns = findProperties(Math.max(currentNode.getStart(), start),
+                                     Math.min(currentNode.getEnd(), end),
+                                     _characterTable.root);
+    int len = charRuns.size();
+
+    for(int x = 0; x < len; x++)
+    {
+      ChpxNode charNode = (ChpxNode)charRuns.get(x);
+      byte[] chpx = charNode.getChpx();
+      CHP chp = (CHP)StyleSheet.uncompressProperty(chpx, std.getCHP(), _styleSheet);
+
+      addCharacterProperties(chp, blockBuffer);
+
+      int charStart = Math.max(charNode.getStart(), currentNode.getStart());
+      int charEnd = Math.min(charNode.getEnd(), currentNode.getEnd());
+      Vector textRuns = findProperties(charStart, charEnd, _text.root);
+      int textRunLen = textRuns.size();
+      for(int y = 0; y < textRunLen; y++)
+      {
+        TextPiece piece = (TextPiece)textRuns.get(y);
+        charStart = Math.max(charStart, piece.getStart());
+        charEnd = Math.min(charEnd, piece.getEnd());
+
+        if(piece.usesUnicode())
+        {
+          addUnicodeText(charStart, charEnd, blockBuffer);
+        }
+        else
+        {
+          addText(charStart, charEnd, blockBuffer);
+        }
+        closeLine(blockBuffer);
+      }
+    }
+    closeBlock(blockBuffer);
+  }
+  private void addText(int start, int end, StringBuffer buf)
+  {
+    for(int x = start; x < end; x++)
+    {
+      char ch = '?';
+
+
+      ch = (char)_header[x];
+
+      addText(ch, buf);
+    }
+  }
+  private void addText(char ch, StringBuffer buf)
+  {
+    int num = 0xffff & ch;
+    if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
+      (ch >= '0' && ch <= '9') || ch == '_' || ch == ' ' || ch == '-' || ch == '.' || ch == '$')
+    {
+      buf.append(ch);
+    }
+    else if(num == 0x07 && _cellBuffer != null)
+    {
+
+      if(_cells == null)
+      {
+        _cells = new Vector();
+      }
+      closeLine(_cellBuffer);
+      closeBlock(_cellBuffer);
+      _cells.add(_cellBuffer.toString());
+      _cellBuffer = null;
+
+    }
+
+    else
+    {
+      /** @todo handle special characters */
+      if(num < 0x20)
+      num=0x20;
+      buf.append("&#");
+      buf.append(num);
+      buf.append(';');
+    }
+  }
+  private void addUnicodeText(int start, int end, StringBuffer buf)
+  {
+    for(int x = start; x < end; x += 2)
+    {
+      char ch = Utils.getUnicodeCharacter(_header, x);
+      //if(ch < 0x0020)
+      //{
+      //  _bodyBuffer.append('?');
+      //}
+      //else
+      //{
+        addText(ch, buf);
+      //}
+    }
+  }
+  private void addParagraphProperties(PAP pap, StringBuffer buf)
+  {
+    buf.append("<fo:block ");
+    buf.append("text-align=\"" + getTextAlignment(pap._jc) + "\"\r\n");
+    buf.append("linefeed-treatment=\"preserve\" ");
+    buf.append("white-space-collapse=\"false\" ");
+
+    if(pap._fKeep > 0)
+    {
+      buf.append("keep-together.within-page=\"always\"\r\n");
+    }
+    if(pap._fKeepFollow > 0)
+    {
+      buf.append("keep-with-next.within-page=\"always\"\r\n");
+    }
+    if(pap._fPageBreakBefore > 0)
+    {
+      buf.append("break-before=\"page\"\r\n");
+    }
+    if(pap._fNoAutoHyph == 0)
+    {
+      buf.append("hyphenate=\"true\"\r\n");
+    }
+    else
+    {
+      buf.append("hyphenate=\"false\"\r\n");
+    }
+    if(pap._dxaLeft > 0)
+    {
+      buf.append("start-indent=\"" + ((float)pap._dxaLeft)/1440.0f + "in\"\r\n");
+    }
+    if(pap._dxaRight > 0)
+    {
+      buf.append("end-indent=\"" + ((float)pap._dxaRight)/1440.0f + "in\"\r\n");
+    }
+    if(pap._dxaLeft1 != 0)
+    {
+      buf.append("text-indent=\"" + ((float)pap._dxaLeft1)/1440.0f + "in\"\r\n");
+    }
+    if(pap._lspd[1] == 0)
+    {
+      //buf.append("line-height=\"" + ((float)pap._lspd[0])/1440.0f + "in\"\r\n");
+    }
+    addBorder(buf, pap._brcTop, "top");
+    addBorder(buf, pap._brcBottom, "bottom");
+    addBorder(buf, pap._brcLeft, "left");
+    addBorder(buf, pap._brcRight, "right");
+
+    buf.append(">");
+
+  }
+
+  private void addCharacterProperties(CHP chp, StringBuffer buf)
+  {
+    buf.append("<fo:inline ");
+    buf.append("font-family=\"" + _fonts.getFont(chp._ftcAscii) + "\" ");
+    buf.append("font-size=\"" + (chp._hps / 2) + "pt\" ");
+    buf.append("color=\"" + getColor(chp._ico) + "\" ");
+    //not supported by fop
+    //buf.append("letter-spacing=\"" + ((double)chp._dxaSpace)/1440.0f + "in\" ");
+
+    addBorder(buf, chp._brc, "top");
+    addBorder(buf, chp._brc, "bottom");
+    addBorder(buf, chp._brc, "left");
+    addBorder(buf, chp._brc, "right");
+
+    if(chp._italic)
+    {
+      buf.append("font-style=\"italic\" ");
+    }
+    if(chp._bold)
+    {
+      buf.append("font-weight=\"bold\" ");
+    }
+    if(chp._fSmallCaps)
+    {
+      buf.append("font-variant=\"small-caps\" ");
+    }
+    if(chp._fCaps)
+    {
+      buf.append("text-transform=\"uppercase\" ");
+    }
+    if(chp._fStrike || chp._fDStrike)
+    {
+      buf.append("text-decoration=\"line-through\" ");
+    }
+    if(chp._fShadow)
+    {
+      int size = chp._hps/24;
+      buf.append("text-shadow=\"" + size + "pt\"");
+    }
+    if(chp._fLowerCase)
+    {
+      buf.append("text-transform=\"lowercase\" ");
+    }
+    if(chp._kul > 0)
+    {
+      buf.append("text-decoration=\"underline\" ");
+    }
+    if(chp._highlighted)
+    {
+      buf.append("background-color=\"" + getColor(chp._icoHighlight) + "\" ");
+    }
+    if(chp._paddingStart != 0)
+    {
+      buf.append("padding-start=\"" + (float)chp._paddingStart/1440.0f + "in\" ");
+    }
+    if(chp._paddingEnd != 0)
+    {
+      buf.append("padding-end=\"" + (float)chp._paddingEnd/1440.0f + "in\" ");
+    }
+    buf.append(">");
+  }
+  private void addStaticContent(String flowName, HeaderFooter content)
+  {
+    _bodyBuffer.append("<fo:static-content flow-name=\"" + flowName + "\">");
+    //_bodyBuffer.append("<fo:float float=\"before\">");
+    addBlockContent(content.getStart(), content.getEnd(),_text, _paragraphTable, _characterTable);
+    //_bodyBuffer.append("</fo:float>");
+    _bodyBuffer.append("</fo:static-content>");
+
+  }
+  private String getBulletText(LVL lvl, PAP pap)
+  {
+    StringBuffer bulletBuffer = new StringBuffer();
+    for(int x = 0; x < lvl._xst.length; x++)
+    {
+      if(lvl._xst[x] < 9)
+      {
+        LVL numLevel = _listTables.getLevel(pap._ilfo, lvl._xst[x]);
+        int num = numLevel._iStartAt;
+        if(lvl == numLevel)
+        {
+          numLevel._iStartAt++;
+        }
+        else if(num > 1)
+        {
+          num--;
+        }
+        bulletBuffer.append(NumberFormatter.getNumber(num, lvl._nfc));
+
+      }
+      else
+      {
+        bulletBuffer.append(lvl._xst[x]);
+      }
+
+    }
+    return bulletBuffer.toString();
+  }
+  /**
+   * finds all chpx's that are between start and end
+   */
+  private Vector findProperties(int start, int end, BTreeSet.BTreeNode root)
+  {
+    Vector results = new Vector();
+    BTreeSet.Entry[] entries = root.entries;
+
+    for(int x = 0; x < entries.length; x++)
+    {
+      if(entries[x] != null)
+      {
+        BTreeSet.BTreeNode child = entries[x].child;
+        PropertyNode xNode = (PropertyNode)entries[x].element;
+        if(xNode != null)
+        {
+          int xStart = xNode.getStart();
+          int xEnd = xNode.getEnd();
+          if(xStart < end)
+          {
+            if(xStart >= start)
+            {
+              if(child != null)
+              {
+                Vector beforeItems = findProperties(start, end, child);
+                results.addAll(beforeItems);
+              }
+              results.add(xNode);
+            }
+            else if(start < xEnd)
+            {
+              results.add(xNode);
+              //break;
+            }
+          }
+          else
+          {
+            if(child != null)
+            {
+              Vector beforeItems = findProperties(start, end, child);
+              results.addAll(beforeItems);
+            }
+            break;
+          }
+        }
+        else if(child != null)
+        {
+          Vector afterItems = findProperties(start, end, child);
+          results.addAll(afterItems);
+        }
+      }
+      else
+      {
+        break;
+      }
+    }
+    return results;
+  }
+  private void openPage(String page, String type)
+  {
+    _bodyBuffer.append("<fo:page-sequence master-reference=\"" + page + "\">\r\n");
+  }
+  private void openFlow()
+  {
+    _bodyBuffer.append("<fo:flow flow-name=\"xsl-region-body\">\r\n");
+  }
+  private void closeFlow()
+  {
+    _bodyBuffer.append("</fo:flow>\r\n");
+  }
+  private void closePage()
+  {
+    _bodyBuffer.append("</fo:page-sequence>\r\n");
+  }
+  private void closeLine(StringBuffer buf)
+  {
+    buf.append("</fo:inline>");
+  }
+  private void closeBlock(StringBuffer buf)
+  {
+    buf.append("</fo:block>\r\n");
+  }
+  private Vector findPAPProperties(int start, int end, BTreeSet.BTreeNode root)
+  {
+    Vector results = new Vector();
+    BTreeSet.Entry[] entries = root.entries;
+
+    for(int x = 0; x < entries.length; x++)
+    {
+      if(entries[x] != null)
+      {
+        BTreeSet.BTreeNode child = entries[x].child;
+        PapxNode papxNode = (PapxNode)entries[x].element;
+        if(papxNode != null)
+        {
+          int papxStart = papxNode.getStart();
+          if(papxStart < end)
+          {
+            if(papxStart >= start)
+            {
+              if(child != null)
+              {
+                Vector beforeItems = findPAPProperties(start, end, child);
+                results.addAll(beforeItems);
+              }
+              results.add(papxNode);
+            }
+          }
+          else
+          {
+            if(child != null)
+            {
+              Vector beforeItems = findPAPProperties(start, end, child);
+              results.addAll(beforeItems);
+            }
+            break;
+          }
+        }
+        else if(child != null)
+        {
+          Vector afterItems = findPAPProperties(start, end, child);
+          results.addAll(afterItems);
+        }
+      }
+      else
+      {
+        break;
+      }
+    }
+    return results;
+  }
+
+  private String createPageMaster(SEP sep, String type, int section,
+                                  String regionBefore, String regionAfter)
+  {
+    float height = ((float)sep._yaPage)/1440.0f;
+    float width = ((float)sep._xaPage)/1440.0f;
+    float leftMargin = ((float)sep._dxaLeft)/1440.0f;
+    float rightMargin = ((float)sep._dxaRight)/1440.0f;
+    float topMargin = ((float)sep._dyaTop)/1440.0f;
+    float bottomMargin = ((float)sep._dyaBottom)/1440.0f;
+
+    //add these to the header
+    String thisPage = type + "-page" + section;
+
+    _headerBuffer.append("<fo:simple-page-master master-name=\"" +
+                        thisPage + "\"\r\n");
+    _headerBuffer.append("page-height=\"" + height + "in\"\r\n");
+    _headerBuffer.append("page-width=\"" + width + "in\"\r\n");
+    _headerBuffer.append(">\r\n");
+
+
+
+    _headerBuffer.append("<fo:region-body ");
+    //top right bottom left
+
+    _headerBuffer.append("margin=\"" + topMargin + "in " + rightMargin + "in " +
+                         bottomMargin + "in " + leftMargin + "in\"\r\n");
+
+    //String style = null;
+    //String color = null;
+    addBorder(_headerBuffer, sep._brcTop, "top");
+    addBorder(_headerBuffer, sep._brcBottom, "bottom");
+    addBorder(_headerBuffer, sep._brcLeft, "left");
+    addBorder(_headerBuffer, sep._brcRight, "right");
+
+    if(sep._ccolM1 > 0)
+    {
+      _headerBuffer.append("column-count=\"" + (sep._ccolM1 + 1) + "\" ");
+      if(sep._fEvenlySpaced)
+      {
+        _headerBuffer.append("column-gap=\"" + ((float)(sep._dxaColumns))/1440.0f + "in\"");
+      }
+      else
+      {
+        _headerBuffer.append("column-gap=\"0.25in\"");
+      }
+    }
+    _headerBuffer.append("/>\r\n");
+
+    if(regionBefore != null)
+    {
+      _headerBuffer.append(regionBefore);
+    }
+    if(regionAfter != null)
+    {
+      _headerBuffer.append(regionAfter);
+    }
+
+    _headerBuffer.append("</fo:simple-page-master>\r\n");
+    return thisPage;
+  }
+  private void addBorder(StringBuffer buf, short[] brc, String where)
+  {
+    if((brc[0] & 0xff00) != 0 && brc[0] != -1)
+    {
+      int type = (brc[0] & 0xff00) >> 8;
+      float width = ((float)(brc[0] & 0x00ff))/8.0f;
+      String style = getBorderStyle(brc[0]);
+      String color = getColor(brc[1] & 0x00ff);
+      String thickness = getBorderThickness(brc[0]);
+      buf.append("border-" + where + "-style=\"" + style + "\"\r\n");
+      buf.append("border-" + where + "-color=\"" + color + "\"\r\n");
+      buf.append("border-" + where + "-width=\"" + width + "pt\"\r\n");
+    }
+  }
+  public void closeDoc()
+  {
+    _headerBuffer.append("</fo:layout-master-set>");
+    _bodyBuffer.append("</fo:root>");
+    //_headerBuffer.append();
+
+    //test code
+    try
+    {
+      OutputStreamWriter test = new OutputStreamWriter(new FileOutputStream("/home/andy/test.xml"), "8859_1");
+      test.write(_headerBuffer.toString());
+      test.write(_bodyBuffer.toString());
+      test.flush();
+      test.close();
+    }
+    catch(Throwable t)
+    {
+      t.printStackTrace();
+    }
+  }
+  private String getBorderThickness(int style)
+  {
+    switch(style)
+    {
+      case 1:
+        return "medium";
+      case 2:
+        return "thick";
+      case 3:
+        return "medium";
+      case 5:
+        return "thin";
+      default:
+        return "medium";
+    }
+  }
+
+
+  private String getColor(int ico)
+  {
+    switch(ico)
+    {
+      case 1:
+        return "black";
+      case 2:
+        return "blue";
+      case 3:
+        return "cyan";
+      case 4:
+        return "green";
+      case 5:
+        return "magenta";
+      case 6:
+        return "red";
+      case 7:
+        return "yellow";
+      case 8:
+        return "white";
+      case 9:
+        return "darkblue";
+      case 10:
+        return "darkcyan";
+      case 11:
+        return "darkgreen";
+      case 12:
+        return "darkmagenta";
+      case 13:
+        return "darkred";
+      case 14:
+        return "darkyellow";
+      case 15:
+        return "darkgray";
+      case 16:
+        return "lightgray";
+      default:
+        return "black";
+    }
+  }
+
+  private String getBorderStyle(int type)
+  {
+
+    switch(type)
+    {
+      case 1:
+      case 2:
+        return "solid";
+      case 3:
+        return "double";
+      case 5:
+        return "solid";
+      case 6:
+        return "dotted";
+      case 7:
+      case 8:
+        return "dashed";
+      case 9:
+        return "dotted";
+      case 10:
+      case 11:
+      case 12:
+      case 13:
+      case 14:
+      case 15:
+      case 16:
+      case 17:
+      case 18:
+      case 19:
+        return "double";
+      case 20:
+        return "solid";
+      case 21:
+        return "double";
+      case 22:
+        return "dashed";
+      case 23:
+        return "dashed";
+      case 24:
+        return "ridge";
+      case 25:
+        return "grooved";
+      default:
+        return "solid";
+    }
+  }
+  private void createListTables(byte[] tableStream)
+  {
+
+
+    int lfoOffset = Utils.convertBytesToInt(_header, 0x2ea);
+    int lfoSize = Utils.convertBytesToInt(_header, 0x2ee);
+    byte[] plflfo = new byte[lfoSize];
+
+    System.arraycopy(tableStream, lfoOffset, plflfo, 0, lfoSize);
+
+    int lstOffset = Utils.convertBytesToInt(_header, 0x2e2);
+    int lstSize = Utils.convertBytesToInt(_header, 0x2e2);
+    if(lstOffset > 0 && lstSize > 0)
+    {
+      lstSize = lfoOffset - lstOffset;
+      byte[] plcflst = new byte[lstSize];
+      System.arraycopy(tableStream, lstOffset, plcflst, 0, lstSize);
+      _listTables = new ListTables(plcflst, plflfo);
+    }
+
+  }
+  private void createStyleSheet(byte[] tableStream)
+  {
+      int stshIndex = Utils.convertBytesToInt(_header, 0xa2);
+      int stshSize = Utils.convertBytesToInt(_header, 0xa6);
+      byte[] stsh = new byte[stshSize];
+      System.arraycopy(tableStream, stshIndex, stsh, 0, stshSize);
+
+      _styleSheet = new StyleSheet(stsh);
+
+  }
+  private void createFontTable(byte[] tableStream)
+  {
+    int fontTableIndex = Utils.convertBytesToInt(_header, 0x112);
+    int fontTableSize = Utils.convertBytesToInt(_header, 0x116);
+    byte[] fontTable = new byte[fontTableSize];
+    System.arraycopy(tableStream, fontTableIndex, fontTable, 0, fontTableSize);
+    _fonts = new FontTable(fontTable);
+  }
+
+  private byte[] createBufferFromBBD(int startBlock) throws IOException
+  {
+
+      int[] blockChain = readChain(_big_block_depot, startBlock);
+      byte[] streamBuffer = new byte[512 * blockChain.length];
+
+
+      for(int x = 0; x < blockChain.length; x++)
+      {
+          byte[] bigBlock = new byte[512];
+          seek((blockChain[x] + 1) * 512);
+          read(bigBlock);
+          System.arraycopy(bigBlock, 0, streamBuffer, x * 512, 512);
+      }
+      return streamBuffer;
+
+  }
+  private void overrideCellBorder(int row, int col, int height,
+                                  int width, TC tc, TAP tap)
+  {
+
+    if(row == 0)
+    {
+      if(tc._brcTop[0] == 0 || tc._brcTop[0] == -1)
+      {
+        tc._brcTop = tap._brcTop;
+      }
+      if(tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1)
+      {
+        tc._brcBottom = tap._brcHorizontal;
+      }
+    }
+    else if(row == (height - 1))
+    {
+      if(tc._brcTop[0] == 0 || tc._brcTop[0] == -1)
+      {
+        tc._brcTop = tap._brcHorizontal;
+      }
+      if(tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1)
+      {
+        tc._brcBottom = tap._brcBottom;
+      }
+    }
+    else
+    {
+      if(tc._brcTop[0] == 0 || tc._brcTop[0] == -1)
+      {
+        tc._brcTop = tap._brcHorizontal;
+      }
+      if(tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1)
+      {
+        tc._brcBottom = tap._brcHorizontal;
+      }
+    }
+    if(col == 0)
+    {
+      if(tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1)
+      {
+        tc._brcLeft = tap._brcLeft;
+      }
+      if(tc._brcRight[0] == 0 || tc._brcRight[0] == -1)
+      {
+        tc._brcRight = tap._brcVertical;
+      }
+    }
+    else if(col == (width - 1))
+    {
+      if(tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1)
+      {
+        tc._brcLeft = tap._brcVertical;
+      }
+      if(tc._brcRight[0] == 0 || tc._brcRight[0] == -1)
+      {
+        tc._brcRight = tap._brcRight;
+      }
+    }
+    else
+    {
+      if(tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1)
+      {
+        tc._brcLeft = tap._brcVertical;
+      }
+      if(tc._brcRight[0] == 0 || tc._brcRight[0] == -1)
+      {
+        tc._brcRight = tap._brcVertical;
+      }
+    }
+  }
+  private void printTable()
+  {
+    if(_table != null)
+    {
+      int size = _table.size();
+
+      //local buffers for the table
+      StringBuffer tableHeaderBuffer = new StringBuffer();
+      StringBuffer tableBodyBuffer = new StringBuffer();
+
+      for(int x = 0; x < size; x++)
+      {
+        StringBuffer rowBuffer = tableBodyBuffer;
+        TableRow row = (TableRow)_table.get(x);
+        TAP tap = row.getTAP();
+        Vector cells = row.getCells();
+
+        if(tap._fTableHeader)
+        {
+          rowBuffer = tableHeaderBuffer;
+        }
+        rowBuffer.append("<fo:table-row ");
+        if(tap._dyaRowHeight > 0)
+        {
+          rowBuffer.append("height=\"" + ((float)tap._dyaRowHeight)/1440.0f + "in\" ");
+        }
+        if(tap._fCantSplit)
+        {
+          rowBuffer.append("keep-together=\"always\" ");
+        }
+        rowBuffer.append(">");
+        //add cells
+        for(int y = 0; y < tap._itcMac; y++)
+        {
+          TC tc = tap._rgtc[y];
+          overrideCellBorder(x, y, size, tap._itcMac, tc, tap);
+          rowBuffer.append("<fo:table-cell ");
+          rowBuffer.append("width=\"" + ((float)(tap._rgdxaCenter[y+1] - tap._rgdxaCenter[y]))/1440.0f + "in\" ");
+          rowBuffer.append("padding-start=\"" + ((float)tap._dxaGapHalf)/1440.0f + "in\" ");
+          rowBuffer.append("padding-end=\"" + ((float)tap._dxaGapHalf)/1440.0f + "in\" ");
+          addBorder(rowBuffer, tc._brcTop, "top");
+          addBorder(rowBuffer, tc._brcLeft, "left");
+          addBorder(rowBuffer, tc._brcBottom, "bottom");
+          addBorder(rowBuffer, tc._brcRight, "right");
+          rowBuffer.append(">");
+          rowBuffer.append((String)cells.get(y));
+          rowBuffer.append("</fo:table-cell>");
+        }
+        rowBuffer.append("</fo:table-row>");
+      }
+      StringBuffer tableBuffer = new StringBuffer();
+      tableBuffer.append("<fo:table>");
+      if(tableHeaderBuffer.length() > 0)
+      {
+        tableBuffer.append("<fo:table-header>");
+        tableBuffer.append(tableHeaderBuffer.toString());
+        tableBuffer.append("</fo:table-header>");
+      }
+      tableBuffer.append("<fo:table-body>");
+      tableBuffer.append(tableBodyBuffer.toString());
+      tableBuffer.append("</fo:table-body>");
+      tableBuffer.append("</fo:table>");
+      _bodyBuffer.append(tableBuffer.toString());
+      _table = null;
+    }
+  }
+  private void initPclfHdd(byte[] tableStream)
+  {
+    int size = Utils.convertBytesToInt(_header, 0xf6);
+    int pos = Utils.convertBytesToInt(_header, 0xf2);
+
+    _plcfHdd = new byte[size];
+
+    System.arraycopy(tableStream, pos, _plcfHdd, 0, size);
+  }
+
+
+
+
+}
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/DOP.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/DOP.java
new file mode 100644 (file)
index 0000000..2f78c0a
--- /dev/null
@@ -0,0 +1,78 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class DOP
+{
+
+  public boolean _fFacingPages;
+  public int _fpc;
+  public int _epc;
+  public int _rncFtn;
+  public int _nFtn;
+  public int _rncEdn;
+  public int _nEdn;
+
+  public DOP()
+  {
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFO.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFO.java
new file mode 100644 (file)
index 0000000..397ef9a
--- /dev/null
@@ -0,0 +1,74 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class LFO
+{
+  int _lsid;
+  int _clfolvl;
+  LFOLVL[] _levels;
+
+  public LFO()
+  {
+
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFOLVL.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LFOLVL.java
new file mode 100644 (file)
index 0000000..d63fa1c
--- /dev/null
@@ -0,0 +1,75 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class LFOLVL
+{
+  int _iStartAt;
+  int _ilvl;
+  boolean _fStartAt;
+  boolean _fFormatting;
+  LVL _override;
+
+  public LFOLVL()
+  {
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LST.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LST.java
new file mode 100644 (file)
index 0000000..7bdd32a
--- /dev/null
@@ -0,0 +1,75 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class LST
+{
+  int _lsid;
+  int _tplc;
+  byte[] _rgistd = new byte[18];
+  boolean _fSimpleList;
+  LVL[] _levels;
+
+  public LST()
+  {
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LVL.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/LVL.java
new file mode 100644 (file)
index 0000000..05731e5
--- /dev/null
@@ -0,0 +1,102 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+
+public class LVL
+{
+  public int _iStartAt;
+  public byte _nfc;
+  byte _jc;
+  boolean _fLegal;
+  boolean _fNoRestart;
+  boolean _fPrev;
+  boolean _fPrevSpace;
+  boolean _fWord6;
+  public byte[] _rgbxchNums = new byte[9];
+  public byte _ixchFollow;
+  public byte[] _chpx;
+  public byte[] _papx;
+  public char[] _xst;
+  public short _istd;
+
+  //byte _cbGrpprlChpx;
+  //byte _cbGrpprlPapx;
+
+
+  public LVL()
+  {
+  }
+  public Object clone()
+  {
+    LVL obj = null;
+    try
+    {
+      obj = (LVL)super.clone();
+    }
+    catch(Exception e)
+    {
+      e.printStackTrace();
+    }
+    return obj;
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/data/ListTables.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/data/ListTables.java
new file mode 100644 (file)
index 0000000..a4481af
--- /dev/null
@@ -0,0 +1,221 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.data;
+
+import java.util.*;
+
+import org.apache.poi.hdf.extractor.*;
+
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class ListTables
+{
+
+  LFO[] _pllfo;
+  Hashtable _lists = new Hashtable();
+
+  public ListTables(byte[] plcflst, byte[] plflfo)
+  {
+    initLST(plcflst);
+    initLFO(plflfo);
+  }
+  public LVL getLevel(int list, int level)
+  {
+
+    LFO override = _pllfo[list - 1];
+
+    for(int x = 0; x < override._clfolvl; x++)
+    {
+      if(override._levels[x]._ilvl == level)
+      {
+        LFOLVL lfolvl = override._levels[x];
+        if(lfolvl._fFormatting)
+        {
+          LST lst = (LST)_lists.get(new Integer(override._lsid));
+          LVL lvl = lfolvl._override;
+          lvl._istd = Utils.convertBytesToShort(lst._rgistd, level * 2);
+          return lvl;
+        }
+        else if(lfolvl._fStartAt)
+        {
+          LST lst = (LST)_lists.get(new Integer(override._lsid));
+          LVL lvl = lst._levels[level];
+          LVL newLvl = (LVL)lvl.clone();
+          newLvl._istd = Utils.convertBytesToShort(lst._rgistd, level * 2);
+          newLvl._iStartAt = lfolvl._iStartAt;
+          return newLvl;
+        }
+      }
+    }
+
+    LST lst = (LST)_lists.get(new Integer(override._lsid));
+    LVL lvl = lst._levels[level];
+    lvl._istd = Utils.convertBytesToShort(lst._rgistd, level * 2);
+    return lvl;
+
+
+  }
+  private void initLST(byte[] plcflst)
+  {
+    short length = Utils.convertBytesToShort(plcflst, 0);
+    int nextLevelOffset = 0;
+    //LST[] lstArray = new LST[length];
+    for(int x = 0; x < length; x++)
+    {
+      LST lst = new LST();
+      lst._lsid = Utils.convertBytesToInt(plcflst, 2 + (x * 28));
+      lst._tplc = Utils.convertBytesToInt(plcflst, 2 + 4 + (x * 28));
+      System.arraycopy(plcflst, 2 + 8 + (x * 28), lst._rgistd, 0, 18);
+      byte code = plcflst[2 + 26 + (x * 28)];
+      lst._fSimpleList = StyleSheet.getFlag(code & 0x01);
+      //lstArray[x] = lst;
+      _lists.put(new Integer(lst._lsid), lst);
+
+      if(lst._fSimpleList)
+      {
+        lst._levels = new LVL[1];
+      }
+      else
+      {
+        lst._levels = new LVL[9];
+      }
+
+      for(int y = 0; y < lst._levels.length; y++)
+      {
+        int offset = 2 + (length * 28) + nextLevelOffset;
+        lst._levels[y] = new LVL();
+        nextLevelOffset += createLVL(plcflst, offset, lst._levels[y]);
+      }
+    }
+
+
+  }
+  private void initLFO(byte[] plflfo)
+  {
+    int lfoSize = Utils.convertBytesToInt(plflfo, 0);
+    _pllfo = new LFO[lfoSize];
+    for(int x = 0; x < lfoSize; x++)
+    {
+      LFO nextLFO = new LFO();
+      nextLFO._lsid = Utils.convertBytesToInt(plflfo, 4 + (x * 16));
+      nextLFO._clfolvl = plflfo[4 + 12 + (x * 16)];
+      nextLFO._levels = new LFOLVL[nextLFO._clfolvl];
+      _pllfo[x] = nextLFO;
+    }
+
+    int lfolvlOffset = (lfoSize * 16) + 4;
+    int lvlOffset = 0;
+    int lfolvlNum = 0;
+    for(int x = 0; x < lfoSize; x++)
+    {
+      for(int y = 0; y < _pllfo[x]._clfolvl; y++)
+      {
+        int offset = lfolvlOffset + (lfolvlNum * 8) + lvlOffset;
+        LFOLVL lfolvl = new LFOLVL();
+        lfolvl._iStartAt = Utils.convertBytesToInt(plflfo, offset);
+        lfolvl._ilvl = Utils.convertBytesToInt(plflfo, offset + 4);
+        lfolvl._fStartAt = StyleSheet.getFlag(lfolvl._ilvl & 0x10);
+        lfolvl._fFormatting = StyleSheet.getFlag(lfolvl._ilvl & 0x20);
+        lfolvl._ilvl = (lfolvl._ilvl & (byte)0x0f);
+        lfolvlNum++;
+
+        if(lfolvl._fFormatting)
+        {
+          offset = lfolvlOffset + (lfolvlNum * 12) + lvlOffset;
+          lfolvl._override = new LVL();
+          lvlOffset += createLVL(plflfo, offset, lfolvl._override);
+        }
+        _pllfo[x]._levels[y] = lfolvl;
+      }
+    }
+  }
+  private int createLVL(byte[] data, int offset, LVL lvl)
+  {
+
+    lvl._iStartAt = Utils.convertBytesToInt(data, offset);
+    lvl._nfc = data[offset + 4];
+    int code = Utils.convertBytesToInt(data, offset + 5);
+    lvl._jc = (byte)(code & 0x03);
+    lvl._fLegal = StyleSheet.getFlag(code & 0x04);
+    lvl._fNoRestart = StyleSheet.getFlag(code & 0x08);
+    lvl._fPrev = StyleSheet.getFlag(code & 0x10);
+    lvl._fPrevSpace = StyleSheet.getFlag(code & 0x20);
+    lvl._fWord6 = StyleSheet.getFlag(code & 0x40);
+    System.arraycopy(data, offset + 6, lvl._rgbxchNums, 0, 9);
+    lvl._ixchFollow = data[offset + 15];
+    int chpxSize = data[offset + 24];
+    int papxSize = data[offset + 25];
+    lvl._chpx = new byte[chpxSize];
+    lvl._papx = new byte[papxSize];
+    System.arraycopy(data, offset + 28, lvl._papx, 0, papxSize);
+    System.arraycopy(data, offset + 28 + papxSize, lvl._chpx, 0, chpxSize);
+    offset += 28 + papxSize + chpxSize;//modify offset
+    int xstSize = Utils.convertBytesToShort(data, offset);
+    lvl._xst = new char[xstSize];
+
+    offset += 2;
+    for(int x = 0; x < xstSize; x++)
+    {
+      lvl._xst[x] = (char)Utils.convertBytesToShort(data, offset + (x * 2));
+    }
+    return 28 + papxSize + chpxSize + 2 + (xstSize * 2);
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/BTreeSet.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/BTreeSet.java
new file mode 100644 (file)
index 0000000..13462ea
--- /dev/null
@@ -0,0 +1,730 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+import java.util.*;
+
+
+/*
+ * A B-Tree like implementation of the java.util.Set inteface.  This is a modifiable set
+ * and thus allows elements to be added and removed.  An instance of java.util.Comparator
+ * must be provided at construction else all Objects added to the set must implement
+ * java.util.Comparable and must be comparable to one another.  No duplicate elements
+ * will be allowed in any BTreeSet in accordance with the specifications of the Set interface.
+ * Any attempt to add a null element will result in an IllegalArgumentException being thrown.
+ * The java.util.Iterator returned by the iterator method guarantees the elements returned
+ * are in ascending order.  The Iterator.remove() method is supported.
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ *
+*/
+
+public class BTreeSet extends AbstractSet implements Set {
+
+    /*
+     * Instance Variables
+    */
+    public BTreeNode root;
+    private Comparator comparator = null;
+    private int order;
+    private int size = 0;
+
+    /*
+     *                             Constructors
+     * A no-arg constructor is supported in accordance with the specifications of the
+     * java.util.Collections interface.  If the order for the B-Tree is not specified
+     * at construction it defaults to 32.
+    */
+
+    public BTreeSet() {
+        this(6);           // Default order for a BTreeSet is 32
+    }
+
+    public BTreeSet(Collection c) {
+        this(6);           // Default order for a BTreeSet is 32
+        addAll(c);
+    }
+
+    public BTreeSet(int order) {
+        this(order, null);
+    }
+
+    public BTreeSet(int order, Comparator comparator) {
+        this.order = order;
+        this.comparator = comparator;
+        root = new BTreeNode(null);
+    }
+
+
+    /*
+     * Public Methods
+    */
+    public boolean add(Object x) throws IllegalArgumentException {
+        if (x == null) throw new IllegalArgumentException();
+        return root.insert(x, -1);
+    }
+
+    public boolean contains(Object x) {
+        return root.includes(x);
+    }
+
+    public boolean remove(Object x) {
+        if (x == null) return false;
+        return root.delete(x, -1);
+    }
+
+    public int size() {
+        return size;
+    }
+
+    public void clear() {
+        root = new BTreeNode(null);
+        size = 0;
+    }
+
+    public java.util.Iterator iterator() {
+        return new Iterator();
+    }
+
+
+    /*
+     * Private methods
+    */
+    private int compare(Object x, Object y) {
+        return (comparator == null ? ((Comparable)x).compareTo(y) : comparator.compare(x, y));
+    }
+
+
+
+    /*
+     * Inner Classes
+    */
+
+    /*
+     * Guarantees that the Objects are returned in ascending order.  Due to the volatile
+     * structure of a B-Tree (many splits, steals and merges can happen in a single call to remove)
+     * this Iterator does not attempt to track any concurrent changes that are happening to
+     * it's BTreeSet.  Therefore, after every call to BTreeSet.remove or BTreeSet.add a new
+     * Iterator should be constructed.  If no new Iterator is constructed than there is a
+     * chance of receiving a NullPointerException. The Iterator.delete method is supported.
+    */
+
+    private class Iterator implements java.util.Iterator {
+        private int index = 0;
+        private Stack parentIndex = new Stack(); // Contains all parentIndicies for currentNode
+        private Object lastReturned = null;
+        private Object next;
+        private BTreeNode currentNode;
+
+        Iterator() {
+            currentNode = firstNode();
+            next = nextElement();
+        }
+
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        public Object next() {
+            if (next == null) throw new NoSuchElementException();
+
+            lastReturned = next;
+            next = nextElement();
+            return lastReturned;
+        }
+
+        public void remove() {
+            if (lastReturned == null) throw new NoSuchElementException();
+
+            BTreeSet.this.remove(lastReturned);
+            lastReturned = null;
+        }
+
+        private BTreeNode firstNode() {
+            BTreeNode temp = BTreeSet.this.root;
+
+            while (temp.entries[0].child != null) {
+                temp = temp.entries[0].child;
+                parentIndex.push(new Integer(0));
+            }
+
+            return temp;
+        }
+
+        private Object nextElement() {
+            if (currentNode.isLeaf()) {
+                if (index < currentNode.nrElements) return currentNode.entries[index++].element;
+
+                else if (!parentIndex.empty()) { //All elements have been returned, return successor of lastReturned if it exists
+                    currentNode = currentNode.parent;
+                    index = ((Integer)parentIndex.pop()).intValue();
+
+                    while (index == currentNode.nrElements) {
+                        if (parentIndex.empty()) break;
+                        currentNode = currentNode.parent;
+                        index = ((Integer)parentIndex.pop()).intValue();
+                    }
+
+                    if (index == currentNode.nrElements) return null; //Reached root and he has no more children
+                    return currentNode.entries[index++].element;
+                }
+
+                else { //Your a leaf and the root
+                    if (index == currentNode.nrElements) return null;
+                    return currentNode.entries[index++].element;
+                }
+            }
+
+            else { //Your not a leaf so simply find and return the successor of lastReturned
+                currentNode = currentNode.entries[index].child;
+                parentIndex.push(new Integer(index));
+
+                while (currentNode.entries[0].child != null) {
+                    currentNode = currentNode.entries[0].child;
+                    parentIndex.push(new Integer(0));
+                }
+
+                index = 1;
+                return currentNode.entries[0].element;
+            }
+        }
+    }
+
+
+    public static class Entry {
+
+        public Object element;
+        public BTreeNode child;
+    }
+
+
+    public class BTreeNode {
+
+        public Entry[] entries;
+        public BTreeNode parent;
+        private int nrElements = 0;
+        private final int MIN = (BTreeSet.this.order - 1) / 2;
+
+        BTreeNode(BTreeNode parent) {
+            this.parent = parent;
+            entries = new Entry[BTreeSet.this.order];
+            entries[0] = new Entry();
+        }
+
+        boolean insert(Object x, int parentIndex) {
+            if (isFull()) { // If full, you must split and promote splitNode before inserting
+                Object splitNode = entries[nrElements / 2].element;
+                BTreeNode rightSibling = split();
+
+                if (isRoot()) { // Grow a level
+                    splitRoot(splitNode, this, rightSibling);
+                    // Determine where to insert
+                    if (BTreeSet.this.compare(x, BTreeSet.this.root.entries[0].element) < 0) insert(x, 0);
+                    else rightSibling.insert(x, 1);
+                }
+
+                else { // Promote splitNode
+                    parent.insertSplitNode(splitNode, this, rightSibling, parentIndex);
+                    if (BTreeSet.this.compare(x, parent.entries[parentIndex].element) < 0) return insert(x, parentIndex);
+                    else return rightSibling.insert(x, parentIndex + 1);
+                }
+            }
+
+            else if (isLeaf()) { // If leaf, simply insert the non-duplicate element
+                int insertAt = childToInsertAt(x, true);
+                if (insertAt == -1) return false; // Determine if the element already exists
+                else {
+                    insertNewElement(x, insertAt);
+                    BTreeSet.this.size++;
+                    return true;
+                }
+            }
+
+            else { // If not full and not leaf recursively find correct node to insert at
+                int insertAt = childToInsertAt(x, true);
+                return (insertAt == -1 ? false : entries[insertAt].child.insert(x, insertAt));
+            }
+            return false;
+        }
+
+        boolean includes(Object x) {
+            int index = childToInsertAt(x, true);
+            if (index == -1) return true;
+            if (entries[index] == null || entries[index].child == null) return false;
+            return entries[index].child.includes(x);
+        }
+
+        boolean delete(Object x, int parentIndex) {
+            int i = childToInsertAt(x, true);
+            int priorParentIndex = parentIndex;
+            BTreeNode temp = this;
+            if (i != -1) {
+                do {
+                    if (temp.entries[i] == null || temp.entries[i].child == null) return false;
+                    temp = temp.entries[i].child;
+                    priorParentIndex = parentIndex;
+                    parentIndex = i;
+                    i = temp.childToInsertAt(x, true);
+                } while (i != -1);
+            } // Now temp contains element to delete and temp's parentIndex is parentIndex
+
+            if (temp.isLeaf()) { // If leaf and have more than MIN elements, simply delete
+                if (temp.nrElements > MIN) {
+                    temp.deleteElement(x);
+                    BTreeSet.this.size--;
+                    return true;
+                }
+
+                else { // If leaf and have less than MIN elements, than prepare the BTreeSet for deletion
+                    temp.prepareForDeletion(parentIndex);
+                    temp.deleteElement(x);
+                    BTreeSet.this.size--;
+                    temp.fixAfterDeletion(priorParentIndex);
+                    return true;
+                }
+            }
+
+            else { // Only delete at leaf so first switch with successor than delete
+                temp.switchWithSuccessor(x);
+                parentIndex = temp.childToInsertAt(x, false) + 1;
+                return temp.entries[parentIndex].child.delete(x, parentIndex);
+            }
+        }
+
+
+        private boolean isFull() { return nrElements == (BTreeSet.this.order - 1); }
+
+        private boolean isLeaf() { return entries[0].child == null; }
+
+        private boolean isRoot() { return parent == null; }
+
+        /*
+         * Splits a BTreeNode into two BTreeNodes, removing the splitNode from the
+         * calling BTreeNode.
+        */
+        private BTreeNode split() {
+            BTreeNode rightSibling = new BTreeNode(parent);
+            int index = nrElements / 2;
+            entries[index++].element = null;
+
+            for (int i = 0, nr = nrElements; index <= nr; i++, index++) {
+                rightSibling.entries[i] = entries[index];
+                if (rightSibling.entries[i] != null && rightSibling.entries[i].child != null)
+                    rightSibling.entries[i].child.parent = rightSibling;
+                entries[index] = null;
+                nrElements--;
+                rightSibling.nrElements++;
+            }
+
+            rightSibling.nrElements--; // Need to correct for copying the last Entry which has a null element and a child
+            return rightSibling;
+        }
+
+        /*
+         * Creates a new BTreeSet.root which contains only the splitNode and pointers
+         * to it's left and right child.
+        */
+        private void splitRoot(Object splitNode, BTreeNode left, BTreeNode right) {
+            BTreeNode newRoot = new BTreeNode(null);
+            newRoot.entries[0].element = splitNode;
+            newRoot.entries[0].child = left;
+            newRoot.entries[1] = new Entry();
+            newRoot.entries[1].child = right;
+            newRoot.nrElements = 1;
+            left.parent = right.parent = newRoot;
+            BTreeSet.this.root = newRoot;
+        }
+
+        private void insertSplitNode(Object splitNode, BTreeNode left, BTreeNode right, int insertAt) {
+            for (int i = nrElements; i >= insertAt; i--) entries[i + 1] = entries[i];
+
+            entries[insertAt] = new Entry();
+            entries[insertAt].element = splitNode;
+            entries[insertAt].child = left;
+            entries[insertAt + 1].child = right;
+
+            nrElements++;
+        }
+
+        private void insertNewElement(Object x, int insertAt) {
+
+            for (int i = nrElements; i > insertAt; i--) entries[i] = entries[i - 1];
+
+            entries[insertAt] = new Entry();
+            entries[insertAt].element = x;
+
+            nrElements++;
+        }
+
+        /*
+         * Possibly a deceptive name for a pretty cool method.  Uses binary search
+         * to determine the postion in entries[] in which to traverse to find the correct
+         * BTreeNode in which to insert a new element.  If the element exists in the calling
+         * BTreeNode than -1 is returned.  When the parameter position is true and the element
+         * is present in the calling BTreeNode -1 is returned, if position is false and the
+         * element is contained in the calling BTreeNode than the position of the element
+         * in entries[] is returned.
+        */
+        private int childToInsertAt(Object x, boolean position) {
+            int index = nrElements / 2;
+
+            if (entries[index] == null || entries[index].element == null) return index;
+
+            int lo = 0, hi = nrElements - 1;
+            while (lo <= hi) {
+                if (BTreeSet.this.compare(x, entries[index].element) > 0) {
+                    lo = index + 1;
+                    index = (hi + lo) / 2;
+                }
+                else {
+                    hi = index - 1;
+                    index = (hi + lo) / 2;
+                }
+            }
+
+            hi++;
+            if (entries[hi] == null || entries[hi].element == null) return hi;
+            return (!position ? hi : BTreeSet.this.compare(x, entries[hi].element) == 0 ? -1 : hi);
+        }
+
+
+        private void deleteElement(Object x) {
+            int index = childToInsertAt(x, false);
+            for (; index < (nrElements - 1); index++) entries[index] = entries[index + 1];
+
+            if (nrElements == 1) entries[index] = new Entry(); // This is root and it is empty
+            else entries[index] = null;
+
+            nrElements--;
+        }
+
+        private void prepareForDeletion(int parentIndex) {
+            if (isRoot()) return; // Don't attempt to steal or merge if your the root
+
+            // If not root then try to steal left
+            else if (parentIndex != 0 && parent.entries[parentIndex - 1].child.nrElements > MIN) {
+                stealLeft(parentIndex);
+                return;
+            }
+
+            // If not root and can't steal left try to steal right
+            else if (parentIndex < entries.length && parent.entries[parentIndex + 1] != null && parent.entries[parentIndex + 1].child != null && parent.entries[parentIndex + 1].child.nrElements > MIN) {
+                    stealRight(parentIndex);
+                    return;
+            }
+
+            // If not root and can't steal left or right then try to merge left
+            else if (parentIndex != 0) {
+                mergeLeft(parentIndex);
+                return;
+            }
+
+            // If not root and can't steal left or right and can't merge left you must be able to merge right
+            else mergeRight(parentIndex);
+        }
+
+        private void fixAfterDeletion(int parentIndex) {
+            if (isRoot() || parent.isRoot()) return; // No fixing needed
+
+            if (parent.nrElements < MIN) { // If parent lost it's n/2 element repair it
+                BTreeNode temp = parent;
+                temp.prepareForDeletion(parentIndex);
+                if (temp.parent == null) return; // Root changed
+                if (!temp.parent.isRoot() && temp.parent.nrElements < MIN) { // If need be recurse
+                    BTreeNode x = temp.parent.parent;
+                    int i = 0;
+                    // Find parent's parentIndex
+                    for (; i < entries.length; i++) if (x.entries[i].child == temp.parent) break;
+                    temp.parent.fixAfterDeletion(i);
+                }
+            }
+        }
+
+        private void switchWithSuccessor(Object x) {
+            int index = childToInsertAt(x, false);
+            BTreeNode temp = entries[index + 1].child;
+            while (temp.entries[0] != null && temp.entries[0].child != null) temp = temp.entries[0].child;
+            Object successor = temp.entries[0].element;
+            temp.entries[0].element = entries[index].element;
+            entries[index].element = successor;
+        }
+
+        /*
+         * This method is called only when the BTreeNode has the minimum number of elements,
+         * has a leftSibling, and the leftSibling has more than the minimum number of elements.
+        */
+        private void stealLeft(int parentIndex) {
+            BTreeNode p = parent;
+            BTreeNode ls = parent.entries[parentIndex - 1].child;
+
+            if (isLeaf()) { // When stealing from leaf to leaf don't worry about children
+                int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
+                insertNewElement(p.entries[parentIndex - 1].element, add);
+                p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
+                ls.entries[ls.nrElements - 1] = null;
+                ls.nrElements--;
+            }
+
+            else { // Was called recursively to fix an undermanned parent
+                entries[0].element = p.entries[parentIndex - 1].element;
+                p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
+                entries[0].child = ls.entries[ls.nrElements].child;
+                entries[0].child.parent = this;
+                ls.entries[ls.nrElements] = null;
+                ls.entries[ls.nrElements - 1].element = null;
+                nrElements++;
+                ls.nrElements--;
+            }
+        }
+
+        /*
+         * This method is called only when stealLeft can't be called, the BTreeNode
+         * has the minimum number of elements, has a rightSibling, and the rightSibling
+         * has more than the minimum number of elements.
+        */
+        private void stealRight(int parentIndex) {
+            BTreeNode p = parent;
+            BTreeNode rs = p.entries[parentIndex + 1].child;
+
+            if (isLeaf()) { // When stealing from leaf to leaf don't worry about children
+                entries[nrElements] = new Entry();
+                entries[nrElements].element = p.entries[parentIndex].element;
+                p.entries[parentIndex].element = rs.entries[0].element;
+                for (int i = 0; i < rs.nrElements; i++) rs.entries[i] = rs.entries[i + 1];
+                rs.entries[rs.nrElements - 1] = null;
+                nrElements++;
+                rs.nrElements--;
+            }
+
+            else { // Was called recursively to fix an undermanned parent
+                for (int i = 0; i <= nrElements; i++) entries[i] = entries[i + 1];
+                entries[nrElements].element = p.entries[parentIndex].element;
+                p.entries[parentIndex].element = rs.entries[0].element;
+                entries[nrElements + 1] = new Entry();
+                entries[nrElements + 1].child = rs.entries[0].child;
+                entries[nrElements + 1].child.parent = this;
+                for (int i = 0; i <= rs.nrElements; i++) rs.entries[i] = rs.entries[i + 1];
+                rs.entries[rs.nrElements] = null;
+                nrElements++;
+                rs.nrElements--;
+            }
+        }
+
+        /*
+         * This method is called only when stealLeft and stealRight could not be called,
+         * the BTreeNode has the minimum number of elements, has a leftSibling, and the
+         * leftSibling has more than the minimum number of elements.  If after completion
+         * parent has fewer than the minimum number of elements than the parents entries[0]
+         * slot is left empty in anticipation of a recursive call to stealLeft, stealRight,
+         * mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
+         * expect the parent to be in such a condition.
+        */
+        private void mergeLeft(int parentIndex) {
+            BTreeNode p = parent;
+            BTreeNode ls = p.entries[parentIndex - 1].child;
+
+            if (isLeaf()) { // Don't worry about children
+                int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
+                insertNewElement(p.entries[parentIndex - 1].element, add); // Could have been a successor switch
+                p.entries[parentIndex - 1].element = null;
+
+                for (int i = nrElements - 1, nr = ls.nrElements; i >= 0; i--)
+                    entries[i + nr] = entries[i];
+
+                for (int i = ls.nrElements - 1; i >= 0; i--) {
+                    entries[i] = ls.entries[i];
+                    nrElements++;
+                }
+
+                if (p.nrElements == MIN && p != BTreeSet.this.root) {
+
+                    for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
+                        p.entries[x] = p.entries[y];
+                    p.entries[0] = new Entry();
+                    p.entries[0].child = ls; //So p doesn't think it's a leaf this will be deleted in the next recursive call
+                }
+
+                else {
+
+                    for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
+                        p.entries[x] = p.entries[y];
+                    p.entries[p.nrElements] = null;
+                }
+
+                p.nrElements--;
+
+                if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
+                    BTreeSet.this.root = this;
+                    parent = null;
+                }
+            }
+
+            else { // I'm not a leaf but fixing the tree structure
+                entries[0].element = p.entries[parentIndex - 1].element;
+                entries[0].child = ls.entries[ls.nrElements].child;
+                nrElements++;
+
+                for (int x = nrElements, nr = ls.nrElements; x >= 0; x--)
+                    entries[x + nr] = entries[x];
+
+                for (int x = ls.nrElements - 1; x >= 0; x--) {
+                    entries[x] = ls.entries[x];
+                    entries[x].child.parent = this;
+                    nrElements++;
+                }
+
+                if (p.nrElements == MIN && p != BTreeSet.this.root) { // Push everything to the right
+                    for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x++, y++){
+                        System.out.println(x + " " + y);
+                        p.entries[x] = p.entries[y];}
+                    p.entries[0] = new Entry();
+                }
+
+                else { // Either p.nrElements > MIN or p == BTreeSet.this.root so push everything to the left
+                    for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
+                        p.entries[x] = p.entries[y];
+                    p.entries[p.nrElements] = null;
+                }
+
+                p.nrElements--;
+
+                if (p.isRoot() && p.nrElements == 0) { // p == BTreeSet.this.root and it's empty
+                    BTreeSet.this.root = this;
+                    parent = null;
+                }
+            }
+        }
+
+        /*
+         * This method is called only when stealLeft, stealRight, and mergeLeft could not be called,
+         * the BTreeNode has the minimum number of elements, has a rightSibling, and the
+         * rightSibling has more than the minimum number of elements.  If after completion
+         * parent has fewer than the minimum number of elements than the parents entries[0]
+         * slot is left empty in anticipation of a recursive call to stealLeft, stealRight,
+         * mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
+         * expect the parent to be in such a condition.
+        */
+        private void mergeRight(int parentIndex) {
+            BTreeNode p = parent;
+            BTreeNode rs = p.entries[parentIndex + 1].child;
+
+            if (isLeaf()) { // Don't worry about children
+                entries[nrElements] = new Entry();
+                entries[nrElements].element = p.entries[parentIndex].element;
+                nrElements++;
+                for (int i = 0, nr = nrElements; i < rs.nrElements; i++, nr++) {
+                    entries[nr] = rs.entries[i];
+                    nrElements++;
+                }
+                p.entries[parentIndex].element = p.entries[parentIndex + 1].element;
+                if (p.nrElements == MIN && p != BTreeSet.this.root) {
+                    for (int x = parentIndex + 1, y = parentIndex; y >= 0; x--, y--)
+                        p.entries[x] = p.entries[y];
+                    p.entries[0] = new Entry();
+                    p.entries[0].child = rs; // So it doesn't think it's a leaf, this child will be deleted in the next recursive call
+                }
+
+                else {
+                    for (int x = parentIndex + 1, y = parentIndex + 2; y <= p.nrElements; x++, y++)
+                        p.entries[x] = p.entries[y];
+                    p.entries[p.nrElements] = null;
+                }
+
+                p.nrElements--;
+                if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
+                    BTreeSet.this.root = this;
+                    parent = null;
+                }
+           }
+
+           else { // It's not a leaf
+
+               entries[nrElements].element = p.entries[parentIndex].element;
+               nrElements++;
+
+               for (int x = nrElements + 1, y = 0; y <= rs.nrElements; x++, y++) {
+                   entries[x] = rs.entries[y];
+                   rs.entries[y].child.parent = this;
+                   nrElements++;
+               }
+               nrElements--;
+
+               p.entries[++parentIndex].child = this;
+
+               if (p.nrElements == MIN && p != BTreeSet.this.root) {
+                  for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
+                      p.entries[x] = p.entries[y];
+                  p.entries[0] = new Entry();
+               }
+
+               else {
+                   for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
+                       p.entries[x] = p.entries[y];
+                   p.entries[p.nrElements] = null;
+               }
+
+               p.nrElements--;
+
+               if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
+                   BTreeSet.this.root = this;
+                   parent = null;
+               }
+            }
+        }
+  }
+}
+
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/ChpxNode.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/ChpxNode.java
new file mode 100644 (file)
index 0000000..a666fb2
--- /dev/null
@@ -0,0 +1,78 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class ChpxNode extends PropertyNode
+{
+
+
+  public ChpxNode(int fcStart, int fcEnd, byte[] chpx)
+  {
+    super(fcStart, fcEnd, chpx);
+  }
+  public byte[] getChpx()
+  {
+    return super.getGrpprl();
+  }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/NumberFormatter.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/NumberFormatter.java
new file mode 100644 (file)
index 0000000..5627dee
--- /dev/null
@@ -0,0 +1,122 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class NumberFormatter
+{
+  private final static int ARABIC = 0;
+  private final static int UPPER_ROMAN = 1;
+  private final static int LOWER_ROMAN = 2;
+  private final static int UPPER_LETTER = 3;
+  private final static int LOWER_LETTER = 4;
+  private final static int ORDINAL = 5;
+
+  private static String[] _arabic = new String[] {"1", "2", "3", "4", "5", "6",
+                                                  "7", "8", "9", "10", "11", "12",
+                                                  "13", "14", "15", "16", "17", "18",
+                                                  "19", "20", "21", "22", "23",
+                                                  "24", "25", "26", "27", "28",
+                                                  "29", "30", "31", "32", "33",
+                                                  "34", "35", "36", "37", "38",
+                                                  "39", "40", "41", "42", "43",
+                                                  "44", "45", "46", "47", "48",
+                                                  "49", "50", "51", "52", "53"};
+  private static String[] _roman = new String[]{"i", "ii", "iii", "iv", "v", "vi",
+                                                "vii", "viii", "ix", "x", "xi", "xii",
+                                                "xiii","xiv", "xv", "xvi", "xvii",
+                                                "xviii", "xix", "xx", "xxi", "xxii",
+                                                "xxiii", "xxiv", "xxv", "xxvi",
+                                                "xxvii", "xxviii", "xxix", "xxx",
+                                                "xxxi", "xxxii", "xxxiii", "xxxiv",
+                                                "xxxv", "xxxvi", "xxxvii", "xxxvii",
+                                                "xxxviii", "xxxix", "xl", "xli", "xlii",
+                                                "xliii", "xliv", "xlv", "xlvi", "xlvii",
+                                                "xlviii", "xlix", "l"};
+  private static String[] _letter = new String[]{"a", "b", "c", "d", "e", "f", "g",
+                                                 "h", "i", "j", "k", "l", "m", "n",
+                                                 "o", "p", "q", "r", "s", "t", "u",
+                                                 "v", "x", "y", "z"};
+  public NumberFormatter()
+  {
+  }
+  public static String getNumber(int num, int style)
+  {
+    switch(style)
+    {
+      case ARABIC:
+        return _arabic[num - 1];
+      case UPPER_ROMAN:
+        return _roman[num-1].toUpperCase();
+      case LOWER_ROMAN:
+        return _roman[num-1];
+      case UPPER_LETTER:
+        return _letter[num-1].toUpperCase();
+      case LOWER_LETTER:
+        return _letter[num-1];
+      case ORDINAL:
+        return _arabic[num - 1];
+      default:
+        return _arabic[num - 1];
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/PapxNode.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/PapxNode.java
new file mode 100644 (file)
index 0000000..d2e5298
--- /dev/null
@@ -0,0 +1,77 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class PapxNode extends PropertyNode
+{
+
+
+  public PapxNode(int fcStart, int fcEnd, byte[] papx)
+  {
+    super(fcStart, fcEnd, papx);
+  }
+  public byte[] getPapx()
+  {
+    return super.getGrpprl();
+  }
+
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/PropertyNode.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/PropertyNode.java
new file mode 100644 (file)
index 0000000..6b5f66b
--- /dev/null
@@ -0,0 +1,104 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class PropertyNode implements Comparable
+{
+  private byte[] _grpprl;
+  private int _fcStart;
+  private int _fcEnd;
+
+  public PropertyNode(int fcStart, int fcEnd, byte[] grpprl)
+  {
+      _fcStart = fcStart;
+      _fcEnd = fcEnd;
+      _grpprl = grpprl;
+  }
+  public int getStart()
+  {
+      return _fcStart;
+  }
+  public int getEnd()
+  {
+    return _fcEnd;
+  }
+  protected byte[] getGrpprl()
+  {
+    return _grpprl;
+  }
+  public int compareTo(Object o)
+  {
+      int fcStart = ((PropertyNode)o).getStart();
+      if(_fcStart == fcStart)
+      {
+        return 0;
+      }
+      else if(_fcStart < fcStart)
+      {
+        return -1;
+      }
+      else
+      {
+        return 1;
+      }
+  }
+}
\ No newline at end of file
diff --git a/src/scratchpad/src/org/apache/poi/hdf/extractor/util/SepxNode.java b/src/scratchpad/src/org/apache/poi/hdf/extractor/util/SepxNode.java
new file mode 100644 (file)
index 0000000..f7d7a18
--- /dev/null
@@ -0,0 +1,82 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+
+package org.apache.poi.hdf.extractor.util;
+
+/**
+ * Comment me
+ *
+ * @author Ryan Ackley 
+ */
+
+public class SepxNode extends PropertyNode
+{
+
+  int _index;
+
+  public SepxNode(int index, int start, int end, byte[] sepx)
+  {
+    super(start, end, sepx);
+  }
+  public byte[] getSepx()
+  {
+    return getGrpprl();
+  }
+  
+  public int compareTo(Object obj) {
+      return 0;
+  }
+  
+}
\ No newline at end of file