diff --git a/src/scratchpad/examples/src/org/apache/poi/hwpf/Word2Forrest.java b/src/scratchpad/examples/src/org/apache/poi/hwpf/Word2Forrest.java index 0b9f443f8..a0787febc 100644 --- a/src/scratchpad/examples/src/org/apache/poi/hwpf/Word2Forrest.java +++ b/src/scratchpad/examples/src/org/apache/poi/hwpf/Word2Forrest.java @@ -69,8 +69,7 @@ public class Word2Forrest { int cruns = p.numCharacterRuns (); CharacterRun run = p.getCharacterRun (0); - int ftcAscii = run.getFontNameIndex (); - String fontName = doc.getFontTable().getMainFont(ftcAscii); + String fontName = run.getFontName(); if (fontName.startsWith ("Courier")) { if (!inCode) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index 0548dd449..f34847306 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -156,7 +156,7 @@ public class HWPFDocument _pbt.adjustForDelete(0, 0, cpMin); } - _st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin); + _st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin, getTextTable().getTextPieces()); _ss = new StyleSheet(_tableStream, _fib.getFcStshf()); _ft = new FontTable(_tableStream, _fib.getFcSttbfffn(), _fib.getLcbSttbfffn()); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ListTables.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ListTables.java index b621adaa6..8cd4f8783 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/ListTables.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ListTables.java @@ -1,56 +1,20 @@ /* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2003 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 - * . - */ + Copyright 2002-2004 Apache Software Foundation + + Licensed 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; @@ -66,6 +30,9 @@ import java.util.NoSuchElementException; import java.io.ByteArrayOutputStream; import java.io.IOException; +/** + * @author Ryan Ackley + */ public class ListTables { private static final int LIST_DATA_SIZE = 28; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java index ba0fee98f..89028b182 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/SectionTable.java @@ -19,6 +19,7 @@ package org.apache.poi.hwpf.model; import java.util.ArrayList; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.List; import org.apache.poi.util.LittleEndian; import org.apache.poi.hwpf.model.io.*; @@ -31,16 +32,19 @@ public class SectionTable private static final int SED_SIZE = 12; private ArrayList _sections = new ArrayList(); + private List _text; public SectionTable() { } + public SectionTable(byte[] documentStream, byte[] tableStream, int offset, - int size, int fcMin) + int size, int fcMin, + List tpt) { PlexOfCps sedPlex = new PlexOfCps(tableStream, offset, size, SED_SIZE); - + _text = tpt; int length = sedPlex.length(); for (int x = 0; x < length; x++) @@ -53,7 +57,7 @@ public class SectionTable // check for the optimization if (fileOffset == 0xffffffff) { - _sections.add(new SEPX(sed, node.getStart(), node.getEnd(), new byte[0])); + _sections.add(new SEPX(sed, CPtoFC(node.getStart()), CPtoFC(node.getEnd()), new byte[0])); } else { @@ -62,7 +66,7 @@ public class SectionTable byte[] buf = new byte[sepxSize]; fileOffset += LittleEndian.SHORT_SIZE; System.arraycopy(documentStream, fileOffset, buf, 0, buf.length); - _sections.add(new SEPX(sed, node.getStart(), node.getEnd(), buf)); + _sections.add(new SEPX(sed, CPtoFC(node.getStart()), CPtoFC(node.getEnd()), buf)); } } } @@ -81,6 +85,50 @@ public class SectionTable } } + private int CPtoFC(int cp) + { + int size = _text.size(); + int x = 0; + int end = 0; + int fc = 0; + for (; x < size; x++) + { + TextPiece piece = (TextPiece)_text.get(x); + int currentStart = end; + end += ((piece.getEnd()- piece.getStart())/(piece.usesUnicode() ? 2 : 1)); + if (cp <= end) + { + fc += ((cp - currentStart) * (piece.usesUnicode() ? 2 : 1)); + break; + } + else + { + fc += (piece.getEnd() - piece.getStart()); + } + } + return fc; + } + + private int FCtoCP(int fc) + { + int size = _text.size(); + int cp = 0; + for (int x = 0; x < size; x++) + { + TextPiece piece = (TextPiece)_text.get(x); + + if (fc <= piece.getEnd()) + { + cp += ((fc - piece.getStart())/ (piece.usesUnicode() ? 2 : 1)); + break; + } + else + { + cp += ((piece.getEnd() - piece.getStart())/ (piece.usesUnicode() ? 2 : 1)); + } + } + return cp; + } public ArrayList getSections() { @@ -115,7 +163,7 @@ public class SectionTable sed.setFc(offset); // add the section descriptor bytes to the PlexOfCps. - GenericPropertyNode property = new GenericPropertyNode(sepx.getStart(), sepx.getEnd(), sed.toByteArray()); + GenericPropertyNode property = new GenericPropertyNode(FCtoCP(sepx.getStart()), FCtoCP(sepx.getEnd()), sed.toByteArray()); plex.addProperty(property); offset = docStream.getOffset(); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java index 0028e26e5..345ebda20 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java @@ -1,56 +1,20 @@ /* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2003 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 - * . - */ + Copyright 2002-2004 Apache Software Foundation + + Licensed 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.usermodel; @@ -59,6 +23,9 @@ import org.apache.poi.hwpf.model.StyleDescription; import org.apache.poi.hwpf.sprm.SprmBuffer; +/** + * @author Ryan Ackley + */ public class CharacterProperties extends CHPAbstractType implements Cloneable { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java index c1eafe0b8..b403e6de2 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java @@ -428,9 +428,9 @@ public class CharacterRun _chpx.addSprm(SPRM_HIGHLIGHT, color); } - public int getFontNameIndex() + public String getFontName() { - return _props.getFtcAscii(); + return _doc.getFontTable().getMainFont(_props.getFtcAscii()); } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java index 29360ec94..ad7259cc5 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java @@ -252,7 +252,7 @@ public class Range TextPiece piece = (TextPiece)_text.get(x); int start = _start > piece.getStart() ? _start - piece.getStart() : 0; int end = _end <= piece.getEnd() ? _end - piece.getStart() : piece.getEnd() - piece.getStart(); - sb.append(piece.getStringBuffer().substring(start, end)); + sb.append(piece.substring(start, end)); } return sb.toString(); } @@ -312,9 +312,9 @@ public class Range int insertIndex = _start - tp.getStart(); sb.insert(insertIndex, text); int adjustedLength = _doc.getTextTable().adjustForInsert(_textStart, text.length()); - _doc.getCharacterTable().adjustForInsert(_textStart, adjustedLength); - _doc.getParagraphTable().adjustForInsert(_textStart, adjustedLength); - _doc.getSectionTable().adjustForInsert(_textStart, adjustedLength); + _doc.getCharacterTable().adjustForInsert(_charStart, adjustedLength); + _doc.getParagraphTable().adjustForInsert(_parStart, adjustedLength); + _doc.getSectionTable().adjustForInsert(_sectionStart, adjustedLength); adjustForInsert(text.length()); return getCharacterRun(0); @@ -329,11 +329,17 @@ public class Range public CharacterRun insertAfter(String text) { initAll(); + int listIndex = _textEnd - 1; TextPiece tp = (TextPiece)_text.get(listIndex); StringBuffer sb = (StringBuffer)tp.getStringBuffer(); int insertIndex = _end - tp.getStart(); + + if (tp.getStringBuffer().charAt(_end - 1) == '\r') + { + insertIndex--; + } sb.insert(insertIndex, text); int adjustedLength = _doc.getTextTable().adjustForInsert(listIndex, text.length()); _doc.getCharacterTable().adjustForInsert(_charEnd - 1, adjustedLength); @@ -567,6 +573,31 @@ public class Range return (ListEntry)insertBefore(props, styleIndex); } + /** + * Inserts a list into the beginning of this range. + * + * @param props The properties of the list entry. All list entries are + * paragraphs. + * @param listID The id of the list that contains the properties. + * @param level The indentation level of the list. + * @param styleIndex The base style's index in the stylesheet. + * @return The empty ListEntry that is now part of the document. + */ + public ListEntry insertAfter(ParagraphProperties props, int listID, int level, int styleIndex) + { + ListTables lt = _doc.getListTables(); + if (lt.getLevel(listID, level) == null) + { + throw new NoSuchElementException("The specified list and level do not exist"); + } + int ilfo = lt.getOverrideIndexFromListID(listID); + props.setIlfo(ilfo); + props.setIlvl((byte)level); + + return (ListEntry)insertAfter(props, styleIndex); + } + + /** * Gets the character run at index. The index is relative to this range. * diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/HWPFDocFixture.java b/src/scratchpad/testcases/org/apache/poi/hwpf/HWPFDocFixture.java index bc78a15ac..b92da6660 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/HWPFDocFixture.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/HWPFDocFixture.java @@ -30,7 +30,7 @@ public class HWPFDocFixture filename = "c:"; } - filename = filename + "/test99.doc"; + filename = filename + "/blankplus.doc"; POIFSFileSystem filesystem = new POIFSFileSystem(new FileInputStream( diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestListTables.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestListTables.java index c201ff014..38c9994bf 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestListTables.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestListTables.java @@ -22,19 +22,25 @@ public class TestListTables FileInformationBlock fib = _hWPFDocFixture._fib; byte[] tableStream = _hWPFDocFixture._tableStream; - ListTables listTables = new ListTables(tableStream, fib.getFcPlcfLst(), fib.getFcPlfLfo()); + int listOffset = fib.getFcPlcfLst(); + int lfoOffset = fib.getFcPlfLfo(); + if (listOffset != 0 && fib.getLcbPlcfLst() != 0) + { + ListTables listTables = new ListTables (tableStream, fib.getFcPlcfLst (), + fib.getFcPlfLfo ()); + HWPFFileSystem fileSys = new HWPFFileSystem (); - HWPFFileSystem fileSys = new HWPFFileSystem(); + HWPFOutputStream tableOut = fileSys.getStream ("1Table"); - HWPFOutputStream tableOut = fileSys.getStream("1Table"); + listTables.writeListDataTo (tableOut); + int offset = tableOut.getOffset (); + listTables.writeListOverridesTo (tableOut); - listTables.writeListDataTo(tableOut); - int offset = tableOut.getOffset(); - listTables.writeListOverridesTo(tableOut); + ListTables newTables = new ListTables (tableOut.toByteArray (), 0, offset); - ListTables newTables = new ListTables(tableOut.toByteArray(), 0, offset); + assertEquals(listTables, newTables); - assertEquals(listTables, newTables); + } } } diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java index 72707d02d..38f479dd5 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSectionTable.java @@ -80,10 +80,13 @@ public class TestSectionTable byte[] tableStream = _hWPFDocFixture._tableStream; int fcMin = fib.getFcMin(); + ComplexFileTable cft = new ComplexFileTable(mainStream, tableStream, fib.getFcClx(), fcMin); + TextPieceTable tpt = cft.getTextPieceTable(); + SectionTable sectionTable = new SectionTable(mainStream, tableStream, fib.getFcPlcfsed(), fib.getLcbPlcfsed(), - fcMin); + fcMin, tpt.getTextPieces()); HWPFFileSystem fileSys = new HWPFFileSystem(); sectionTable.writeTo(fileSys, 0); @@ -93,13 +96,26 @@ public class TestSectionTable byte[] newTableStream = tableOut.toByteArray(); byte[] newMainStream = mainOut.toByteArray(); - SectionTable newSectionTable = new SectionTable(newMainStream, newTableStream, 0, newTableStream.length, 0); + SectionTable newSectionTable = new SectionTable(newMainStream, newTableStream, 0, newTableStream.length, 0, tpt.getTextPieces()); ArrayList oldSections = sectionTable.getSections(); ArrayList newSections = newSectionTable.getSections(); assertEquals(oldSections.size(), newSections.size()); + //test for proper char offset conversions + PlexOfCps oldSedPlex = new PlexOfCps(tableStream, fib.getFcPlcfsed(), + fib.getLcbPlcfsed(), 12); + PlexOfCps newSedPlex = new PlexOfCps(newTableStream, 0, + newTableStream.length, 12); + assertEquals(oldSedPlex.length(), newSedPlex.length()); + + for (int x = 0; x < oldSedPlex.length(); x++) + { + assertEquals(oldSedPlex.getProperty(x).getStart(), newSedPlex.getProperty(x).getStart()); + assertEquals(oldSedPlex.getProperty(x).getEnd(), newSedPlex.getProperty(x).getEnd()); + } + int size = oldSections.size(); for (int x = 0; x < size; x++) {