diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/HDFType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/HDFType.java deleted file mode 100644 index aabf02451..000000000 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/HDFType.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hwpf.model; - -import org.apache.poi.util.Internal; - -/** - * - * @author andy - */ -@Internal -@Deprecated -public interface HDFType { - -} - diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java index 2312f92d1..f357181a7 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleDescription.java @@ -34,266 +34,237 @@ import org.apache.poi.util.StringUtil; * @author Ryan Ackley */ @Internal -public final class StyleDescription implements HDFType -{ +public final class StyleDescription { - private static final POILogger logger = POILogFactory.getLogger( StyleDescription.class ); + private static final POILogger logger = POILogFactory.getLogger(StyleDescription.class); //arbitrarily selected; may need to increase private static final int MAX_RECORD_LENGTH = 100_000; - private final static int PARAGRAPH_STYLE = 1; - private final static int CHARACTER_STYLE = 2; - // private final static int TABLE_STYLE = 3; - // private final static int NUMBERING_STYLE = 4; + private final static int PARAGRAPH_STYLE = 1; + private final static int CHARACTER_STYLE = 2; + // private final static int TABLE_STYLE = 3; + // private final static int NUMBERING_STYLE = 4; - private int _baseLength; - private StdfBase _stdfBase; - private StdfPost2000 _stdfPost2000; + private int _baseLength; + private StdfBase _stdfBase; + private StdfPost2000 _stdfPost2000; - UPX[] _upxs; - String _name; - @Deprecated - ParagraphProperties _pap; - @Deprecated - CharacterProperties _chp; + UPX[] _upxs; + String _name; + @Deprecated + ParagraphProperties _pap; + @Deprecated + CharacterProperties _chp; - public StyleDescription() - { + public StyleDescription() { // _pap = new ParagraphProperties(); // _chp = new CharacterProperties(); - } - public StyleDescription(byte[] std, int baseLength, int offset, boolean word9) - { - _baseLength = baseLength; - int nameStart = offset + baseLength; + } + + public StyleDescription(byte[] std, int baseLength, int offset, boolean word9) { + _baseLength = baseLength; + int nameStart = offset + baseLength; boolean readStdfPost2000 = false; - if ( baseLength == 0x0012 ) - { + if (baseLength == 0x0012) { readStdfPost2000 = true; - } - else if ( baseLength == 0x000A ) - { + } else if (baseLength == 0x000A) { readStdfPost2000 = false; - } - else - { - logger.log( POILogger.WARN, + } else { + logger.log(POILogger.WARN, "Style definition has non-standard size of ", - Integer.valueOf( baseLength ) ); + Integer.valueOf(baseLength)); } - _stdfBase = new StdfBase(std, offset); - offset += StdfBase.getSize(); + _stdfBase = new StdfBase(std, offset); + offset += StdfBase.getSize(); - if ( readStdfPost2000 ) - { - _stdfPost2000 = new StdfPost2000( std, offset ); + if (readStdfPost2000) { + _stdfPost2000 = new StdfPost2000(std, offset); // offset += StdfPost2000.getSize(); } - //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 = LittleEndian.getShort(std, nameStart); - multiplier = 2; - nameStart += LittleEndian.SHORT_SIZE; - } - else - { - nameLength = std[nameStart]; - } - - _name = StringUtil.getFromUnicodeLE(std, nameStart, (nameLength*multiplier)/2); - - //length then null terminator. - - // the spec only refers to two possible upxs but it mentions - // that more may be added in the future - int varOffset = ((nameLength + 1) * multiplier) + nameStart; - int countOfUPX = _stdfBase.getCupx(); - _upxs = new UPX[countOfUPX]; - for(int x = 0; x < countOfUPX; x++) - { - int upxSize = LittleEndian.getShort(std, varOffset); - varOffset += LittleEndian.SHORT_SIZE; - - byte[] upx = IOUtils.safelyAllocate(upxSize, Short.MAX_VALUE); - System.arraycopy(std, varOffset, upx, 0, upxSize); - _upxs[x] = new UPX(upx); - varOffset += upxSize; - - - // the upx will always start on a word boundary. - if((upxSize & 1) == 1) - { - ++varOffset; - } - - } - - - } - public int getBaseStyle() - { - return _stdfBase.getIstdBase(); - } - public byte[] getCHPX() - { - switch (_stdfBase.getStk()) - { - case PARAGRAPH_STYLE: - if (_upxs.length > 1) - { - return _upxs[1].getUPX(); + //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 = LittleEndian.getShort(std, nameStart); + multiplier = 2; + nameStart += LittleEndian.SHORT_SIZE; + } else { + nameLength = std[nameStart]; } - return null; - case CHARACTER_STYLE: - return _upxs[0].getUPX(); - default: - return null; + + _name = StringUtil.getFromUnicodeLE(std, nameStart, (nameLength * multiplier) / 2); + + //length then null terminator. + + // the spec only refers to two possible upxs but it mentions + // that more may be added in the future + int varOffset = ((nameLength + 1) * multiplier) + nameStart; + int countOfUPX = _stdfBase.getCupx(); + _upxs = new UPX[countOfUPX]; + for (int x = 0; x < countOfUPX; x++) { + int upxSize = LittleEndian.getShort(std, varOffset); + varOffset += LittleEndian.SHORT_SIZE; + + byte[] upx = IOUtils.safelyAllocate(upxSize, Short.MAX_VALUE); + System.arraycopy(std, varOffset, upx, 0, upxSize); + _upxs[x] = new UPX(upx); + varOffset += upxSize; + + + // the upx will always start on a word boundary. + if ((upxSize & 1) == 1) { + ++varOffset; + } + + } + + } - } - public byte[] getPAPX() - { - switch (_stdfBase.getStk()) - { - case PARAGRAPH_STYLE: - return _upxs[0].getUPX(); - default: - return null; - } - } - @Deprecated - public ParagraphProperties getPAP() - { - return _pap; - } - @Deprecated - public CharacterProperties getCHP() - { - return _chp; - } - @Deprecated - void setPAP(ParagraphProperties pap) - { - _pap = pap; - } - @Deprecated - void setCHP(CharacterProperties chp) - { - _chp = chp; - } - - public String getName() - { - return _name; - } - - public byte[] toByteArray() - { - // size equals _baseLength bytes for known variables plus 2 bytes for name - // length plus name length * 2 plus 2 bytes for null plus upx's preceded by - // length - int size = _baseLength + 2 + ((_name.length() + 1) * 2); - - // determine the size needed for the upxs. They always fall on word - // boundaries. - size += _upxs[0].size() + 2; - for (int x = 1; x < _upxs.length; x++) - { - size += _upxs[x-1].size() % 2; - size += _upxs[x].size() + 2; + public int getBaseStyle() { + return _stdfBase.getIstdBase(); } + public byte[] getCHPX() { + switch (_stdfBase.getStk()) { + case PARAGRAPH_STYLE: + if (_upxs.length > 1) { + return _upxs[1].getUPX(); + } + return null; + case CHARACTER_STYLE: + return _upxs[0].getUPX(); + default: + return null; + } - byte[] buf = new byte[size]; - _stdfBase.serialize( buf, 0 ); - - int offset = _baseLength; - - char[] letters = _name.toCharArray(); - LittleEndian.putShort(buf, _baseLength, (short)letters.length); - offset += LittleEndian.SHORT_SIZE; - for (int x = 0; x < letters.length; x++) - { - LittleEndian.putShort(buf, offset, (short)letters[x]); - offset += LittleEndian.SHORT_SIZE; - } - // get past the null delimiter for the name. - offset += LittleEndian.SHORT_SIZE; - - for (int x = 0; x < _upxs.length; x++) - { - short upxSize = (short)_upxs[x].size(); - LittleEndian.putShort(buf, offset, upxSize); - offset += LittleEndian.SHORT_SIZE; - System.arraycopy(_upxs[x].getUPX(), 0, buf, offset, upxSize); - offset += upxSize + (upxSize % 2); } - return buf; - } + public byte[] getPAPX() { + switch (_stdfBase.getStk()) { + case PARAGRAPH_STYLE: + return _upxs[0].getUPX(); + default: + return null; + } + } + + @Deprecated + public ParagraphProperties getPAP() { + return _pap; + } + + @Deprecated + public CharacterProperties getCHP() { + return _chp; + } + + @Deprecated + void setPAP(ParagraphProperties pap) { + _pap = pap; + } + + @Deprecated + void setCHP(CharacterProperties chp) { + _chp = chp; + } + + public String getName() { + return _name; + } + + public byte[] toByteArray() { + // size equals _baseLength bytes for known variables plus 2 bytes for name + // length plus name length * 2 plus 2 bytes for null plus upx's preceded by + // length + int size = _baseLength + 2 + ((_name.length() + 1) * 2); + + // determine the size needed for the upxs. They always fall on word + // boundaries. + size += _upxs[0].size() + 2; + for (int x = 1; x < _upxs.length; x++) { + size += _upxs[x - 1].size() % 2; + size += _upxs[x].size() + 2; + } + + + byte[] buf = new byte[size]; + _stdfBase.serialize(buf, 0); + + int offset = _baseLength; + + char[] letters = _name.toCharArray(); + LittleEndian.putShort(buf, _baseLength, (short) letters.length); + offset += LittleEndian.SHORT_SIZE; + for (int x = 0; x < letters.length; x++) { + LittleEndian.putShort(buf, offset, (short) letters[x]); + offset += LittleEndian.SHORT_SIZE; + } + // get past the null delimiter for the name. + offset += LittleEndian.SHORT_SIZE; + + for (int x = 0; x < _upxs.length; x++) { + short upxSize = (short) _upxs[x].size(); + LittleEndian.putShort(buf, offset, upxSize); + offset += LittleEndian.SHORT_SIZE; + System.arraycopy(_upxs[x].getUPX(), 0, buf, offset, upxSize); + offset += upxSize + (upxSize % 2); + } + + return buf; + } @Override - public int hashCode() - { + public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ( ( _name == null ) ? 0 : _name.hashCode() ); + result = prime * result + ((_name == null) ? 0 : _name.hashCode()); result = prime * result - + ( ( _stdfBase == null ) ? 0 : _stdfBase.hashCode() ); - result = prime * result + Arrays.hashCode( _upxs ); + + ((_stdfBase == null) ? 0 : _stdfBase.hashCode()); + result = prime * result + Arrays.hashCode(_upxs); return result; } @Override - public boolean equals( Object obj ) - { - if ( this == obj ) + public boolean equals(Object obj) { + if (this == obj) return true; - if ( obj == null ) + if (obj == null) return false; - if ( getClass() != obj.getClass() ) + if (getClass() != obj.getClass()) return false; StyleDescription other = (StyleDescription) obj; - if ( _name == null ) - { - if ( other._name != null ) + if (_name == null) { + if (other._name != null) return false; - } - else if ( !_name.equals( other._name ) ) + } else if (!_name.equals(other._name)) return false; - if ( _stdfBase == null ) - { - if ( other._stdfBase != null ) + if (_stdfBase == null) { + if (other._stdfBase != null) return false; - } - else if ( !_stdfBase.equals( other._stdfBase ) ) + } else if (!_stdfBase.equals(other._stdfBase)) return false; - if ( !Arrays.equals( _upxs, other._upxs ) ) + if (!Arrays.equals(_upxs, other._upxs)) return false; return true; } @Override - public String toString() - { + public String toString() { StringBuilder result = new StringBuilder(); - result.append( "[STD]: '" ); - result.append( _name ); - result.append( "'" ); - result.append( ( "\nStdfBase:\t" + _stdfBase ).replaceAll( "\n", - "\n " ) ); - result.append( ( "\nStdfPost2000:\t" + _stdfPost2000 ).replaceAll( - "\n", "\n " ) ); - for ( UPX upx : _upxs ) - { - result.append( ( "\nUPX:\t" + upx ).replaceAll( "\n", "\n " ) ); + result.append("[STD]: '"); + result.append(_name); + result.append("'"); + result.append(("\nStdfBase:\t" + _stdfBase).replaceAll("\n", + "\n ")); + result.append(("\nStdfPost2000:\t" + _stdfPost2000).replaceAll( + "\n", "\n ")); + for (UPX upx : _upxs) { + result.append(("\nUPX:\t" + upx).replaceAll("\n", "\n ")); } return result.toString(); } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java index 8084f73e1..4f057fb3a 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/StyleSheet.java @@ -35,13 +35,13 @@ import org.apache.poi.util.LittleEndian; *
* Fields documentation is quotes from Microsoft Office Word 97-2007 Binary File * Format (.doc) Specification, page 36 of 210 - * + * * @author Ryan Ackley */ @Internal -public final class StyleSheet implements HDFType { +public final class StyleSheet { - public static final int NIL_STYLE = 4095; + public 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; @@ -52,8 +52,8 @@ public final class StyleSheet implements HDFType { @Deprecated private final static CharacterProperties NIL_CHP = new CharacterProperties(); - private final static byte[] NIL_CHPX = new byte[] {}; - private final static byte[] NIL_PAPX = new byte[] {0, 0}; + private final static byte[] NIL_CHPX = new byte[]{}; + private final static byte[] NIL_PAPX = new byte[]{0, 0}; /** * Size of the STSHI structure @@ -64,20 +64,19 @@ public final class StyleSheet implements HDFType { * General information about a stylesheet */ private Stshif _stshif; - - StyleDescription[] _styleDescriptions; - /** - * StyleSheet constructor. Loads a document's stylesheet information, - * - * @param tableStream A byte array containing a document's raw stylesheet - * info. Found by using FileInformationBlock.getFcStshf() and - * FileInformationBLock.getLcbStshf() - */ - public StyleSheet(byte[] tableStream, int offset) - { + StyleDescription[] _styleDescriptions; + + /** + * StyleSheet constructor. Loads a document's stylesheet information, + * + * @param tableStream A byte array containing a document's raw stylesheet + * info. Found by using FileInformationBlock.getFcStshf() and + * FileInformationBLock.getLcbStshf() + */ + public StyleSheet(byte[] tableStream, int offset) { int startOffset = offset; - _cbStshi = LittleEndian.getShort( tableStream, offset ); + _cbStshi = LittleEndian.getShort(tableStream, offset); offset += LittleEndian.SHORT_SIZE; /* @@ -87,47 +86,42 @@ public final class StyleSheet implements HDFType { * (cbSTD, STD) pairs in the file following the STSHI. Note: styles can * be empty, i.e. cbSTD==0. */ - - _stshif = new Stshif( tableStream, offset ); + + _stshif = new Stshif(tableStream, offset); offset += Stshif.getSize(); // shall we discard cbLSD and mpstilsd? - - offset = startOffset + LittleEndian.SHORT_SIZE + _cbStshi; - _styleDescriptions = new StyleDescription[_stshif.getCstd()]; - for(int x = 0; x < _stshif.getCstd(); x++) - { - int stdSize = LittleEndian.getShort(tableStream, offset); - //get past the size - offset += 2; - if(stdSize > 0) - { - //byte[] std = new byte[stdSize]; - StyleDescription aStyle = new StyleDescription(tableStream, - _stshif.getCbSTDBaseInFile(), offset, true); + offset = startOffset + LittleEndian.SHORT_SIZE + _cbStshi; + _styleDescriptions = new StyleDescription[_stshif.getCstd()]; + for (int x = 0; x < _stshif.getCstd(); x++) { + int stdSize = LittleEndian.getShort(tableStream, offset); + //get past the size + offset += 2; + if (stdSize > 0) { + //byte[] std = new byte[stdSize]; - _styleDescriptions[x] = aStyle; - } + StyleDescription aStyle = new StyleDescription(tableStream, + _stshif.getCbSTDBaseInFile(), offset, true); - offset += stdSize; + _styleDescriptions[x] = aStyle; + } - } - for(int x = 0; x < _styleDescriptions.length; x++) - { - if(_styleDescriptions[x] != null) - { - createPap(x); - createChp(x); - } - } - } + offset += stdSize; - public void writeTo(OutputStream out) - throws IOException - { + } + for (int x = 0; x < _styleDescriptions.length; x++) { + if (_styleDescriptions[x] != null) { + createPap(x); + createChp(x); + } + } + } - int offset = 0; + public void writeTo(OutputStream out) + throws IOException { + + int offset = 0; /* * we don't support 2003 Word extensions in STSHI (but may be we should @@ -136,270 +130,239 @@ public final class StyleSheet implements HDFType { */ this._cbStshi = 18; - // add two bytes so we can prepend the stylesheet w/ its size - byte[] buf = new byte[_cbStshi + 2]; + // add two bytes so we can prepend the stylesheet w/ its size + byte[] buf = new byte[_cbStshi + 2]; - LittleEndian.putUShort(buf, offset, (short)_cbStshi); - offset += LittleEndian.SHORT_SIZE; + LittleEndian.putUShort(buf, offset, (short) _cbStshi); + offset += LittleEndian.SHORT_SIZE; - _stshif.setCstd( _styleDescriptions.length ); - _stshif.serialize( buf, offset ); - // offset += Stshif.getSize(); + _stshif.setCstd(_styleDescriptions.length); + _stshif.serialize(buf, offset); + // offset += Stshif.getSize(); - out.write(buf); + out.write(buf); - byte[] sizeHolder = new byte[2]; - for (int x = 0; x < _styleDescriptions.length; x++) - { - if(_styleDescriptions[x] != null) - { - byte[] std = _styleDescriptions[x].toByteArray(); + byte[] sizeHolder = new byte[2]; + for (int x = 0; x < _styleDescriptions.length; x++) { + if (_styleDescriptions[x] != null) { + byte[] std = _styleDescriptions[x].toByteArray(); - // adjust the size so it is always on a word boundary - LittleEndian.putShort(sizeHolder, 0, (short)((std.length) + (std.length % 2))); - out.write(sizeHolder); - out.write(std); + // adjust the size so it is always on a word boundary + LittleEndian.putShort(sizeHolder, 0, (short) ((std.length) + (std.length % 2))); + out.write(sizeHolder); + out.write(std); - // Must always start on a word boundary. - if (std.length % 2 == 1) - { - out.write('\0'); - } - } - else - { - sizeHolder[0] = 0; - sizeHolder[1] = 0; - out.write(sizeHolder); - } - } - } - - @Override - public boolean equals(Object o) - { - if (!(o instanceof StyleSheet)) return false; - StyleSheet ss = (StyleSheet)o; - - if (!ss._stshif.equals( this._stshif ) - || ss._cbStshi != this._cbStshi - || ss._styleDescriptions.length != this._styleDescriptions.length - ) return false; - - for (int i=0; i<_styleDescriptions.length; i++) { - StyleDescription tsd = this._styleDescriptions[i]; - StyleDescription osd = ss._styleDescriptions[i]; - if (tsd == null && osd == null) continue; - if (tsd == null || osd == null || !osd.equals(tsd)) return false; + // Must always start on a word boundary. + if (std.length % 2 == 1) { + out.write('\0'); + } + } else { + sizeHolder[0] = 0; + sizeHolder[1] = 0; + out.write(sizeHolder); + } + } } - return true; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof StyleSheet)) return false; + StyleSheet ss = (StyleSheet) o; - @Override - public int hashCode() { - assert false : "hashCode not designed"; - return 42; // any arbitrary constant will do - } + if (!ss._stshif.equals(this._stshif) + || ss._cbStshi != this._cbStshi + || ss._styleDescriptions.length != this._styleDescriptions.length + ) return false; - /** - * Creates a PartagraphProperties object from a papx stored in the - * StyleDescription at the index istd in the StyleDescription array. The PAP - * is placed in the StyleDescription at istd after its been created. Not - * every StyleDescription will contain a papx. In these cases this function - * does nothing - * - * @param istd The index of the StyleDescription to create the - * ParagraphProperties from (and also place the finished PAP in) - */ - @Deprecated - private void createPap(int istd) - { - StyleDescription sd = _styleDescriptions[istd]; - ParagraphProperties pap = sd.getPAP(); - byte[] papx = sd.getPAPX(); - int baseIndex = sd.getBaseStyle(); - if(pap == null && papx != null) - { - ParagraphProperties parentPAP = new ParagraphProperties(); - if(baseIndex != NIL_STYLE) - { + for (int i = 0; i < _styleDescriptions.length; i++) { + StyleDescription tsd = this._styleDescriptions[i]; + StyleDescription osd = ss._styleDescriptions[i]; + if (tsd == null && osd == null) continue; + if (tsd == null || osd == null || !osd.equals(tsd)) return false; + } - parentPAP = _styleDescriptions[baseIndex].getPAP(); - if(parentPAP == null) { - if(baseIndex == istd) { - // Oh dear, style claims that it is its own parent - throw new IllegalStateException("Pap style " + istd + " claimed to have itself as its parent, which isn't allowed"); - } - // Create the parent style - createPap(baseIndex); - parentPAP = _styleDescriptions[baseIndex].getPAP(); - } + return true; + } - } + @Override + public int hashCode() { + assert false : "hashCode not designed"; + return 42; // any arbitrary constant will do + } - if (parentPAP == null) { - parentPAP = new ParagraphProperties(); - } + /** + * Creates a PartagraphProperties object from a papx stored in the + * StyleDescription at the index istd in the StyleDescription array. The PAP + * is placed in the StyleDescription at istd after its been created. Not + * every StyleDescription will contain a papx. In these cases this function + * does nothing + * + * @param istd The index of the StyleDescription to create the + * ParagraphProperties from (and also place the finished PAP in) + */ + @Deprecated + private void createPap(int istd) { + StyleDescription sd = _styleDescriptions[istd]; + ParagraphProperties pap = sd.getPAP(); + byte[] papx = sd.getPAPX(); + int baseIndex = sd.getBaseStyle(); + if (pap == null && papx != null) { + ParagraphProperties parentPAP = new ParagraphProperties(); + if (baseIndex != NIL_STYLE) { - pap = ParagraphSprmUncompressor.uncompressPAP(parentPAP, papx, 2); - sd.setPAP(pap); - } - } - /** - * Creates a CharacterProperties object from a chpx stored in the - * StyleDescription at the index istd in the StyleDescription array. The - * CharacterProperties object is placed in the StyleDescription at istd after - * its been created. Not every StyleDescription will contain a chpx. In these - * cases this function does nothing. - * - * @param istd The index of the StyleDescription to create the - * CharacterProperties object from. - */ - @Deprecated - private void createChp(int istd) - { - StyleDescription sd = _styleDescriptions[istd]; - CharacterProperties chp = sd.getCHP(); - byte[] chpx = sd.getCHPX(); - int baseIndex = sd.getBaseStyle(); - - if(baseIndex == istd) { - // Oh dear, this isn't allowed... - // The word file seems to be corrupted - // Switch to using the nil style so that - // there's a chance we can read it - baseIndex = NIL_STYLE; - } - - // Build and decompress the Chp if required - if(chp == null && chpx != null) - { - CharacterProperties parentCHP = new CharacterProperties(); - if(baseIndex != NIL_STYLE) - { - parentCHP = _styleDescriptions[baseIndex].getCHP(); - if(parentCHP == null) - { - createChp(baseIndex); - parentCHP = _styleDescriptions[baseIndex].getCHP(); - } - if(parentCHP == null) { - parentCHP = new CharacterProperties(); - } - } + parentPAP = _styleDescriptions[baseIndex].getPAP(); + if (parentPAP == null) { + if (baseIndex == istd) { + // Oh dear, style claims that it is its own parent + throw new IllegalStateException("Pap style " + istd + " claimed to have itself as its parent, which isn't allowed"); + } + // Create the parent style + createPap(baseIndex); + parentPAP = _styleDescriptions[baseIndex].getPAP(); + } - chp = CharacterSprmUncompressor.uncompressCHP(parentCHP, chpx, 0); - sd.setCHP(chp); - } - } + } - /** - * Gets the number of styles in the style sheet. - * @return The number of styles in the style sheet. - */ - public int numStyles() { - return _styleDescriptions.length; - } + if (parentPAP == null) { + parentPAP = new ParagraphProperties(); + } + + pap = ParagraphSprmUncompressor.uncompressPAP(parentPAP, papx, 2); + sd.setPAP(pap); + } + } + + /** + * Creates a CharacterProperties object from a chpx stored in the + * StyleDescription at the index istd in the StyleDescription array. The + * CharacterProperties object is placed in the StyleDescription at istd after + * its been created. Not every StyleDescription will contain a chpx. In these + * cases this function does nothing. + * + * @param istd The index of the StyleDescription to create the + * CharacterProperties object from. + */ + @Deprecated + private void createChp(int istd) { + StyleDescription sd = _styleDescriptions[istd]; + CharacterProperties chp = sd.getCHP(); + byte[] chpx = sd.getCHPX(); + int baseIndex = sd.getBaseStyle(); + + if (baseIndex == istd) { + // Oh dear, this isn't allowed... + // The word file seems to be corrupted + // Switch to using the nil style so that + // there's a chance we can read it + baseIndex = NIL_STYLE; + } + + // Build and decompress the Chp if required + if (chp == null && chpx != null) { + CharacterProperties parentCHP = new CharacterProperties(); + if (baseIndex != NIL_STYLE) { + parentCHP = _styleDescriptions[baseIndex].getCHP(); + if (parentCHP == null) { + createChp(baseIndex); + parentCHP = _styleDescriptions[baseIndex].getCHP(); + } + if (parentCHP == null) { + parentCHP = new CharacterProperties(); + } + } + + chp = CharacterSprmUncompressor.uncompressCHP(parentCHP, chpx, 0); + sd.setCHP(chp); + } + } + + /** + * Gets the number of styles in the style sheet. + * + * @return The number of styles in the style sheet. + */ + public int numStyles() { + return _styleDescriptions.length; + } /** * Gets the StyleDescription at index x. - * - * @param styleIndex - * the index of the desired StyleDescription. + * + * @param styleIndex the index of the desired StyleDescription. */ - public StyleDescription getStyleDescription( int styleIndex ) - { + public StyleDescription getStyleDescription(int styleIndex) { return _styleDescriptions[styleIndex]; } @Deprecated - public CharacterProperties getCharacterStyle( int styleIndex ) - { - if ( styleIndex == NIL_STYLE ) - { + public CharacterProperties getCharacterStyle(int styleIndex) { + if (styleIndex == NIL_STYLE) { return NIL_CHP; } - if ( styleIndex >= _styleDescriptions.length ) - { + if (styleIndex >= _styleDescriptions.length) { return NIL_CHP; } - return ( _styleDescriptions[styleIndex] != null ? _styleDescriptions[styleIndex] - .getCHP() : NIL_CHP ); + return (_styleDescriptions[styleIndex] != null ? _styleDescriptions[styleIndex] + .getCHP() : NIL_CHP); } @Deprecated - public ParagraphProperties getParagraphStyle( int styleIndex ) - { - if ( styleIndex == NIL_STYLE ) - { + public ParagraphProperties getParagraphStyle(int styleIndex) { + if (styleIndex == NIL_STYLE) { return NIL_PAP; } - if ( styleIndex >= _styleDescriptions.length ) - { + if (styleIndex >= _styleDescriptions.length) { return NIL_PAP; } - if ( _styleDescriptions[styleIndex] == null ) - { + if (_styleDescriptions[styleIndex] == null) { return NIL_PAP; } - if ( _styleDescriptions[styleIndex].getPAP() == null ) - { + if (_styleDescriptions[styleIndex].getPAP() == null) { return NIL_PAP; } return _styleDescriptions[styleIndex].getPAP(); } - public byte[] getCHPX( int styleIndex ) - { - if ( styleIndex == NIL_STYLE ) - { + public byte[] getCHPX(int styleIndex) { + if (styleIndex == NIL_STYLE) { return NIL_CHPX; } - if ( styleIndex >= _styleDescriptions.length ) - { + if (styleIndex >= _styleDescriptions.length) { return NIL_CHPX; } - if ( _styleDescriptions[styleIndex] == null ) - { + if (_styleDescriptions[styleIndex] == null) { return NIL_CHPX; } - if ( _styleDescriptions[styleIndex].getCHPX() == null ) - { + if (_styleDescriptions[styleIndex].getCHPX() == null) { return NIL_CHPX; } return _styleDescriptions[styleIndex].getCHPX(); } - public byte[] getPAPX( int styleIndex ) - { - if ( styleIndex == NIL_STYLE ) - { + public byte[] getPAPX(int styleIndex) { + if (styleIndex == NIL_STYLE) { return NIL_PAPX; } - if ( styleIndex >= _styleDescriptions.length ) - { + if (styleIndex >= _styleDescriptions.length) { return NIL_PAPX; } - if ( _styleDescriptions[styleIndex] == null ) - { + if (_styleDescriptions[styleIndex] == null) { return NIL_PAPX; } - if ( _styleDescriptions[styleIndex].getPAPX() == null ) - { + if (_styleDescriptions[styleIndex].getPAPX() == null) { return NIL_PAPX; }