From: Sergey Vladimirov Date: Thu, 28 Jul 2011 13:46:57 +0000 (+0000) Subject: add initial code for office drawings (and pictures saved as such drawings) X-Git-Tag: REL_3_8_BETA4~56 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=91d49be238fdda1965937b5ddb4ed4111adad763;p=poi.git add initial code for office drawings (and pictures saved as such drawings) git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1151845 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index b426be0e68..b2d4660459 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -30,6 +30,7 @@ import org.apache.poi.hwpf.model.CPSplitCalculator; import org.apache.poi.hwpf.model.ComplexFileTable; import org.apache.poi.hwpf.model.DocumentProperties; import org.apache.poi.hwpf.model.EscherRecordHolder; +import org.apache.poi.hwpf.model.FSPADocumentPart; import org.apache.poi.hwpf.model.FSPATable; import org.apache.poi.hwpf.model.FieldsTables; import org.apache.poi.hwpf.model.FontTable; @@ -57,6 +58,8 @@ import org.apache.poi.hwpf.usermodel.FieldsImpl; import org.apache.poi.hwpf.usermodel.HWPFList; import org.apache.poi.hwpf.usermodel.Notes; import org.apache.poi.hwpf.usermodel.NotesImpl; +import org.apache.poi.hwpf.usermodel.OfficeDrawings; +import org.apache.poi.hwpf.usermodel.OfficeDrawingsImpl; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.DirectoryNode; @@ -99,18 +102,28 @@ public final class HWPFDocument extends HWPFDocumentCore /** Holds the revision mark authors for this document. */ protected RevisionMarkAuthorTable _rmat; - /** Holds pictures table */ - protected PicturesTable _pictures; + /** Holds FSBA (shape) information */ + private FSPATable _fspaHeaders; /** Holds FSBA (shape) information */ - protected FSPATable _fspa; + private FSPATable _fspaMain; /** Escher Drawing Group information */ - protected EscherRecordHolder _dgg; + protected EscherRecordHolder _escherRecordHolder; + + /** Holds pictures table */ + protected PicturesTable _pictures; /** Holds Office Art objects */ + @Deprecated protected ShapesTable _officeArts; + /** Holds Office Art objects */ + protected OfficeDrawingsImpl _officeDrawingsHeaders; + + /** Holds Office Art objects */ + protected OfficeDrawingsImpl _officeDrawingsMain; + /** Holds the bookmarks tables */ protected BookmarksTables _bookmarksTables; @@ -276,22 +289,30 @@ public final class HWPFDocument extends HWPFDocumentCore 0 ) ) ); } - // Read FSPA and Escher information - _fspa = new FSPATable(_tableStream, _fib.getFcPlcspaMom(), _fib.getLcbPlcspaMom(), getTextTable().getTextPieces()); + // Read FSPA and Escher information + // _fspa = new FSPATable(_tableStream, _fib.getFcPlcspaMom(), + // _fib.getLcbPlcspaMom(), getTextTable().getTextPieces()); + _fspaHeaders = new FSPATable( _tableStream, _fib, + FSPADocumentPart.HEADER ); + _fspaMain = new FSPATable( _tableStream, _fib, FSPADocumentPart.MAIN ); if (_fib.getFcDggInfo() != 0) { - _dgg = new EscherRecordHolder(_tableStream, _fib.getFcDggInfo(), _fib.getLcbDggInfo()); + _escherRecordHolder = new EscherRecordHolder(_tableStream, _fib.getFcDggInfo(), _fib.getLcbDggInfo()); } else { - _dgg = new EscherRecordHolder(); + _escherRecordHolder = new EscherRecordHolder(); } // read in the pictures stream - _pictures = new PicturesTable(this, _dataStream, _mainStream, _fspa, _dgg); + _pictures = new PicturesTable(this, _dataStream, _mainStream, _fspaMain, _escherRecordHolder); // And the art shapes stream _officeArts = new ShapesTable(_tableStream, _fib); + // And escher pictures + _officeDrawingsHeaders = new OfficeDrawingsImpl( _fspaHeaders, _escherRecordHolder ); + _officeDrawingsMain = new OfficeDrawingsImpl( _fspaMain , _escherRecordHolder); + _st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin, _tpt, _cpSplit); _ss = new StyleSheet(_tableStream, _fib.getFcStshf()); _ft = new FontTable(_tableStream, _fib.getFcSttbfffn(), _fib.getLcbSttbfffn()); @@ -498,13 +519,31 @@ public final class HWPFDocument extends HWPFDocumentCore return _pictures; } - /** - * @return ShapesTable object, that is able to extract office are shapes from this document - */ - public ShapesTable getShapesTable() { - return _officeArts; + public EscherRecordHolder getEscherRecordHolder() { + return _escherRecordHolder; } + /** + * @return ShapesTable object, that is able to extract office are shapes + * from this document + * @deprecated use {@link #getOfficeDrawingsMain()} instead + */ + @Deprecated + public ShapesTable getShapesTable() + { + return _officeArts; + } + + public OfficeDrawings getOfficeDrawingsHeaders() + { + return _officeDrawingsHeaders; + } + + public OfficeDrawings getOfficeDrawingsMain() + { + return _officeDrawingsMain; + } + /** * @return user-friendly interface to access document bookmarks */ diff --git a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java index 45e29a4a8a..b65e8cf713 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java @@ -38,6 +38,7 @@ import org.apache.poi.hwpf.usermodel.Bookmark; import org.apache.poi.hwpf.usermodel.CharacterRun; import org.apache.poi.hwpf.usermodel.Field; import org.apache.poi.hwpf.usermodel.Notes; +import org.apache.poi.hwpf.usermodel.OfficeDrawing; import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.Range; @@ -65,6 +66,8 @@ public abstract class AbstractWordConverter private static final byte SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE = 2; + private static final byte SPECCHAR_DRAWN_OBJECT = 8; + private static final char UNICODECHAR_NONBREAKING_HYPHEN = '\u2011'; private static final char UNICODECHAR_ZERO_WIDTH_SPACE = '\u200b'; @@ -381,6 +384,13 @@ public abstract class AbstractWordConverter processNoteAnchor( doc, characterRun, block ); continue; } + if ( text.charAt( 0 ) == SPECCHAR_DRAWN_OBJECT + && ( document instanceof HWPFDocument ) ) + { + HWPFDocument doc = (HWPFDocument) document; + processDrawnObject( doc, characterRun, block ); + continue; + } } if ( text.getBytes()[0] == FIELD_BEGIN_MARK ) @@ -565,6 +575,23 @@ public abstract class AbstractWordConverter } } + protected void processDrawnObject( HWPFDocument doc, + CharacterRun characterRun, Element block ) + { + // main? + OfficeDrawing officeDrawing = doc.getOfficeDrawingsMain() + .getOfficeDrawingAt( characterRun.getStartOffset() ); + if ( officeDrawing == null ) + { + logger.log( POILogger.WARN, "Characters #" + characterRun + + " references missing drawn object" ); + return; + } + + // TODO: do something :) + + } + protected abstract void processEndnoteAutonumbered( HWPFDocument doc, int noteIndex, Element block, Range endnoteTextRange ); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordUtils.java b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordUtils.java index 5e4dc65426..8ed299f4ed 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordUtils.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordUtils.java @@ -23,9 +23,6 @@ import java.io.InputStream; import java.util.Set; import java.util.TreeSet; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; - import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.HWPFDocumentCore; import org.apache.poi.hwpf.HWPFOldDocument; @@ -39,6 +36,8 @@ import org.apache.poi.hwpf.usermodel.TableCell; import org.apache.poi.hwpf.usermodel.TableRow; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.IOUtils; +import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -387,6 +386,8 @@ public class AbstractWordUtils { switch ( languageCode ) { + case 1024: + return EMPTY; case 1033: return "en-us"; case 1049: @@ -396,7 +397,7 @@ public class AbstractWordUtils default: logger.log( POILogger.WARN, "Uknown or unmapped language code: ", Integer.valueOf( languageCode ) ); - return ""; + return EMPTY; } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java b/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java index 1591797856..5aacf2edff 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java @@ -43,6 +43,7 @@ import org.apache.poi.hwpf.sprm.SprmOperation; import org.apache.poi.hwpf.usermodel.Bookmark; import org.apache.poi.hwpf.usermodel.Bookmarks; import org.apache.poi.hwpf.usermodel.Field; +import org.apache.poi.hwpf.usermodel.OfficeDrawing; import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.Range; @@ -97,7 +98,9 @@ public final class HWPFLister + "\t\t[--chpx] [--chpxProperties] [--chpxSprms]\n" + "\t\t[--papx] [--papxProperties]\n" + "\t\t[--paragraphs] [--paragraphsSprms] [--paragraphsText]\n" - + "\t\t[--bookmarks]\n" +"\t\t[--fields]\n" + "\t\t[--pictures]\n" + + "\t\t[--bookmarks]\n" + "\t\t[--escher]\n" + + "\t\t[--fields]\n" + "\t\t[--pictures]\n" + + "\t\t[--officeDrawings]\n" + "\t\t[--writereadback]\n" ); System.exit( 1 ); } @@ -117,8 +120,10 @@ public final class HWPFLister boolean outputPapxProperties = false; boolean outputBookmarks = false; + boolean outputEscher = false; boolean outputFields = false; boolean outputPictures = false; + boolean outputOfficeDrawings = false; boolean writereadback = false; @@ -150,8 +155,12 @@ public final class HWPFLister if ( "--bookmarks".equals( arg ) ) outputBookmarks = true; + if ( "--eschaer".equals( arg ) ) + outputEscher = true; if ( "--fields".equals( arg ) ) outputFields = true; + if ( "--officeDrawings".equals( arg ) ) + outputOfficeDrawings = true; if ( "--pictures".equals( arg ) ) outputPictures = true; @@ -200,12 +209,24 @@ public final class HWPFLister lister.dumpBookmarks(); } + if ( outputEscher ) + { + System.out.println( "== ESCHER PROPERTIES ==" ); + lister.dumpEscher(); + } + if ( outputFields ) { System.out.println( "== FIELDS ==" ); lister.dumpFields(); } + if ( outputOfficeDrawings ) + { + System.out.println( "== OFFICE DRAWINGS ==" ); + lister.dumpOfficeDrawings(); + } + if ( outputPictures ) { System.out.println( "== PICTURES ==" ); @@ -323,6 +344,17 @@ public final class HWPFLister } } + private void dumpEscher() + { + if ( _doc instanceof HWPFOldDocument ) + { + System.out.println( "Word 95 not supported so far" ); + return; + } + System.out.println( ( (HWPFDocument) _doc ).getEscherRecordHolder() ); + + } + public void dumpFIB() { FileInformationBlock fib = _doc.getFileInformationBlock(); @@ -350,71 +382,88 @@ public final class HWPFLister } } + private void dumpOfficeDrawings() + { + if ( !( _doc instanceof HWPFDocument ) ) + { + System.out.println( "Word 95 not supported so far" ); + return; + } + + HWPFDocument document = (HWPFDocument) _doc; + + System.out.println( "=== Document part: MAIN ===" ); + for ( OfficeDrawing officeDrawing : document.getOfficeDrawingsMain().getOfficeDrawings() ) + { + System.out.println( officeDrawing ); + } + } + public void dumpPapx( boolean withProperties ) throws Exception { -// if ( _doc instanceof HWPFDocument ) -// { -// System.out.println( "binary PAP pages " ); -// -// HWPFDocument doc = (HWPFDocument) _doc; -// -// java.lang.reflect.Field fMainStream = HWPFDocumentCore.class -// .getDeclaredField( "_mainStream" ); -// fMainStream.setAccessible( true ); -// byte[] mainStream = (byte[]) fMainStream.get( _doc ); -// -// PlexOfCps binTable = new PlexOfCps( doc.getTableStream(), doc -// .getFileInformationBlock().getFcPlcfbtePapx(), doc -// .getFileInformationBlock().getLcbPlcfbtePapx(), 4 ); -// -// List papxs = new ArrayList(); -// -// int length = binTable.length(); -// for ( int x = 0; x < length; x++ ) -// { -// GenericPropertyNode node = binTable.getProperty( x ); -// -// int pageNum = LittleEndian.getInt( node.getBytes() ); -// int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE -// * pageNum; -// -// PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage( -// mainStream, doc.getDataStream(), pageOffset, -// doc.getTextTable() ); -// -// System.out.println( "* PFKP: " + pfkp ); -// -// for ( PAPX papx : pfkp.getPAPXs() ) -// { -// System.out.println( "** " + papx ); -// papxs.add( papx ); -// if ( papx != null && true ) -// { -// SprmIterator sprmIt = new SprmIterator( -// papx.getGrpprl(), 2 ); -// while ( sprmIt.hasNext() ) -// { -// SprmOperation sprm = sprmIt.next(); -// System.out.println( "*** " + sprm.toString() ); -// } -// } -// -// } -// } -// -// Collections.sort( papxs ); -// System.out.println( "* Sorted by END" ); -// for ( PAPX papx : papxs ) -// { -// System.out.println( "** " + papx ); -// SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); -// while ( sprmIt.hasNext() ) -// { -// SprmOperation sprm = sprmIt.next(); -// System.out.println( "*** " + sprm.toString() ); -// } -// } -// } + // if ( _doc instanceof HWPFDocument ) + // { + // System.out.println( "binary PAP pages " ); + // + // HWPFDocument doc = (HWPFDocument) _doc; + // + // java.lang.reflect.Field fMainStream = HWPFDocumentCore.class + // .getDeclaredField( "_mainStream" ); + // fMainStream.setAccessible( true ); + // byte[] mainStream = (byte[]) fMainStream.get( _doc ); + // + // PlexOfCps binTable = new PlexOfCps( doc.getTableStream(), doc + // .getFileInformationBlock().getFcPlcfbtePapx(), doc + // .getFileInformationBlock().getLcbPlcfbtePapx(), 4 ); + // + // List papxs = new ArrayList(); + // + // int length = binTable.length(); + // for ( int x = 0; x < length; x++ ) + // { + // GenericPropertyNode node = binTable.getProperty( x ); + // + // int pageNum = LittleEndian.getInt( node.getBytes() ); + // int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE + // * pageNum; + // + // PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage( + // mainStream, doc.getDataStream(), pageOffset, + // doc.getTextTable() ); + // + // System.out.println( "* PFKP: " + pfkp ); + // + // for ( PAPX papx : pfkp.getPAPXs() ) + // { + // System.out.println( "** " + papx ); + // papxs.add( papx ); + // if ( papx != null && true ) + // { + // SprmIterator sprmIt = new SprmIterator( + // papx.getGrpprl(), 2 ); + // while ( sprmIt.hasNext() ) + // { + // SprmOperation sprm = sprmIt.next(); + // System.out.println( "*** " + sprm.toString() ); + // } + // } + // + // } + // } + // + // Collections.sort( papxs ); + // System.out.println( "* Sorted by END" ); + // for ( PAPX papx : papxs ) + // { + // System.out.println( "** " + papx ); + // SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 ); + // while ( sprmIt.hasNext() ) + // { + // SprmOperation sprm = sprmIt.next(); + // System.out.println( "*** " + sprm.toString() ); + // } + // } + // } // for ( PAPX papx : _doc.getParagraphTable().getParagraphs() ) // { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FIBFieldHandler.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FIBFieldHandler.java index 69232d9dd1..ec43bea1ea 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FIBFieldHandler.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FIBFieldHandler.java @@ -80,7 +80,8 @@ public final class FIBFieldHandler public static final int PLCDOAHDR = 39; // 474 == 0x01DA; 478 == 0x01DE public static final int PLCSPAMOM = 40; - public static final int PLCSPAHDR = 41; + // 482 == 0x01E2; 490 == 0x01E6 + public static final int PLCSPAHDR = 41; public static final int PLCFATNBKF = 42; // 498 == 0x01F2; 502 == 0x01F6 public static final int PLCFATNBKL = 43; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FSPA.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPA.java index 2f683589d1..d914f82e28 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FSPA.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPA.java @@ -17,166 +17,34 @@ package org.apache.poi.hwpf.model; -import org.apache.poi.util.BitField; -import org.apache.poi.util.BitFieldFactory; -import org.apache.poi.util.LittleEndian; +import org.apache.poi.hwpf.model.types.FSPAAbstractType; +import org.apache.poi.util.Internal; /** * File Shape Address structure - * + * * @author Squeeself */ -public final class FSPA +@Internal +public final class FSPA extends FSPAAbstractType { - public static final int FSPA_SIZE = 26; - private int spid; // Shape identifier. Used to get data position - private int xaLeft; // Enclosing rectangle - private int yaTop; // Enclosing rectangle - private int xaRight; // Enclosing rectangle - private int yaBottom; // Enclosing rectangle - private short options; - private static BitField fHdr = BitFieldFactory.getInstance(0x0001); // 1 in undo when in header - private static BitField bx = BitFieldFactory.getInstance(0x0006); // x pos relative to anchor CP: 0 - page margin, 1 - top of page, 2 - text, 3 - reserved - private static BitField by = BitFieldFactory.getInstance(0x0018); // y pos relative to anchor CP: ditto - private static BitField wr = BitFieldFactory.getInstance(0x01E0); // Text wrapping mode: 0 - like 2 w/o absolute, 1 - no text next to shape, 2 - wrap around absolute object, 3 - wrap as if no object, 4 - wrap tightly around object, 5 - wrap tightly, allow holes, 6-15 - reserved - private static BitField wrk = BitFieldFactory.getInstance(0x1E00); // Text wrapping mode type (for modes 2&4): 0 - wrap both sides, 1 - wrap only left, 2 - wrap only right, 3 - wrap largest side - private static BitField fRcaSimple = BitFieldFactory.getInstance(0x2000); // Overwrites bx if set, forcing rectangle to be page relative - private static BitField fBelowText = BitFieldFactory.getInstance(0x4000); // if true, shape is below text, otherwise above - private static BitField fAnchorLock = BitFieldFactory.getInstance(0x8000); // if true, anchor is locked - private int cTxbx; // Count of textboxes in shape (undo doc only) + @Deprecated + public static final int FSPA_SIZE = getSize(); // 26 public FSPA() { } - public FSPA(byte[] bytes, int offset) + public FSPA( byte[] bytes, int offset ) { - spid = LittleEndian.getInt(bytes, offset); - offset += LittleEndian.INT_SIZE; - xaLeft = LittleEndian.getInt(bytes, offset); - offset += LittleEndian.INT_SIZE; - yaTop = LittleEndian.getInt(bytes, offset); - offset += LittleEndian.INT_SIZE; - xaRight = LittleEndian.getInt(bytes, offset); - offset += LittleEndian.INT_SIZE; - yaBottom = LittleEndian.getInt(bytes, offset); - offset += LittleEndian.INT_SIZE; - options = LittleEndian.getShort(bytes, offset); - offset += LittleEndian.SHORT_SIZE; - cTxbx = LittleEndian.getInt(bytes, offset); - } - - public int getSpid() - { - return spid; - } - - public int getXaLeft() - { - return xaLeft; - } - - public int getYaTop() - { - return yaTop; - } - - public int getXaRight() - { - return xaRight; - } - - public int getYaBottom() - { - return yaBottom; - } - - public boolean isFHdr() - { - return fHdr.isSet(options); - } - - public short getBx() - { - return bx.getShortValue(options); - } - - public short getBy() - { - return by.getShortValue(options); - } - - public short getWr() - { - return wr.getShortValue(options); - } - - public short getWrk() - { - return wrk.getShortValue(options); - } - - public boolean isFRcaSimple() - { - return fRcaSimple.isSet(options); - } - - public boolean isFBelowText() - { - return fBelowText.isSet(options); - } - - public boolean isFAnchorLock() - { - return fAnchorLock.isSet(options); - } - - public int getCTxbx() - { - return cTxbx; + fillFields( bytes, offset ); } public byte[] toByteArray() { - int offset = 0; byte[] buf = new byte[FSPA_SIZE]; - - LittleEndian.putInt(buf, offset, spid); - offset += LittleEndian.INT_SIZE; - LittleEndian.putInt(buf, offset, xaLeft); - offset += LittleEndian.INT_SIZE; - LittleEndian.putInt(buf, offset, yaTop); - offset += LittleEndian.INT_SIZE; - LittleEndian.putInt(buf, offset, xaRight); - offset += LittleEndian.INT_SIZE; - LittleEndian.putInt(buf, offset, yaBottom); - offset += LittleEndian.INT_SIZE; - LittleEndian.putShort(buf, offset, options); - offset += LittleEndian.SHORT_SIZE; - LittleEndian.putInt(buf, offset, cTxbx); - offset += LittleEndian.INT_SIZE; - + serialize( buf, 0 ); return buf; } - public String toString() - { - StringBuffer buf = new StringBuffer(); - buf.append("spid: ").append(spid); - buf.append(", xaLeft: ").append(xaLeft); - buf.append(", yaTop: ").append(yaTop); - buf.append(", xaRight: ").append(xaRight); - buf.append(", yaBottom: ").append(yaBottom); - buf.append(", options: ").append(options); - buf.append(" (fHdr: ").append(isFHdr()); - buf.append(", bx: ").append(getBx()); - buf.append(", by: ").append(getBy()); - buf.append(", wr: ").append(getWr()); - buf.append(", wrk: ").append(getWrk()); - buf.append(", fRcaSimple: ").append(isFRcaSimple()); - buf.append(", fBelowText: ").append(isFBelowText()); - buf.append(", fAnchorLock: ").append(isFAnchorLock()); - buf.append("), cTxbx: ").append(cTxbx); - return buf.toString(); - } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FSPADocumentPart.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPADocumentPart.java new file mode 100644 index 0000000000..53ce9dbbbe --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPADocumentPart.java @@ -0,0 +1,19 @@ +package org.apache.poi.hwpf.model; + +public enum FSPADocumentPart { + HEADER( FIBFieldHandler.PLCSPAHDR ), + + MAIN( FIBFieldHandler.PLCSPAMOM ); + + private final int fibFieldsField; + + private FSPADocumentPart( final int fibHandlerField ) + { + this.fibFieldsField = fibHandlerField; + } + + public int getFibFieldsField() + { + return fibFieldsField; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FSPATable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPATable.java index 40a4fb9446..c192b3ef5c 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FSPATable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FSPATable.java @@ -18,68 +18,99 @@ package org.apache.poi.hwpf.model; import java.util.ArrayList; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.apache.poi.util.Internal; + /** * This class holds all the FSPA (File Shape Address) structures. - * + * * @author Squeeself */ +@Internal public final class FSPATable { - private final List _shapes = new ArrayList(); - private final Map _shapeIndexesByPropertyStart = new HashMap(); - private final List _text; - public FSPATable(byte[] tableStream, int fcPlcspa, int lcbPlcspa, List tpt) + private final Map _byStart = new LinkedHashMap(); + + public FSPATable( byte[] tableStream, FileInformationBlock fib, + FSPADocumentPart part ) + { + int offset = fib.getFSPAPlcfOffset( part ); + int length = fib.getFSPAPlcfLength( part ); + + PlexOfCps plex = new PlexOfCps( tableStream, offset, length, + FSPA.getSize() ); + for ( int i = 0; i < plex.length(); i++ ) + { + GenericPropertyNode property = plex.getProperty( i ); + _byStart.put( Integer.valueOf( property.getStart() ), property ); + } + } + + @Deprecated + public FSPATable( byte[] tableStream, int fcPlcspa, int lcbPlcspa, + List tpt ) { - _text = tpt; // Will be 0 if no drawing objects in document - if (fcPlcspa == 0) + if ( fcPlcspa == 0 ) return; - PlexOfCps plex = new PlexOfCps(tableStream, fcPlcspa, lcbPlcspa, FSPA.FSPA_SIZE); - for (int i=0; i < plex.length(); i++) + PlexOfCps plex = new PlexOfCps( tableStream, fcPlcspa, lcbPlcspa, + FSPA.FSPA_SIZE ); + for ( int i = 0; i < plex.length(); i++ ) { - GenericPropertyNode property = plex.getProperty(i); - FSPA fspa = new FSPA(property.getBytes(), 0); - - _shapes.add(fspa); - _shapeIndexesByPropertyStart.put(Integer.valueOf(property.getStart()), Integer.valueOf(i)); + GenericPropertyNode property = plex.getProperty( i ); + _byStart.put( Integer.valueOf( property.getStart() ), property ); } } - public FSPA getFspaFromCp(int cp) + public FSPA getFspaFromCp( int cp ) { - Integer idx = _shapeIndexesByPropertyStart.get(Integer.valueOf(cp)); - if (idx == null) { + GenericPropertyNode propertyNode = _byStart.get( Integer.valueOf( cp ) ); + if ( propertyNode == null ) + { return null; } - return _shapes.get(idx.intValue()); + return new FSPA( propertyNode.getBytes(), 0 ); } public FSPA[] getShapes() { - FSPA[] result = new FSPA[_shapes.size()]; - _shapes.toArray(result); - return result; + List result = new ArrayList( _byStart.size() ); + for ( GenericPropertyNode propertyNode : _byStart.values() ) + { + result.add( new FSPA( propertyNode.getBytes(), 0 ) ); + } + return result.toArray( new FSPA[result.size()] ); } public String toString() { StringBuffer buf = new StringBuffer(); - buf.append("[FPSA PLC size=").append(_shapes.size()).append("]\n"); + buf.append( "[FPSA PLC size=" ).append( _byStart.size() ) + .append( "]\n" ); - for (Map.Entry entry: _shapeIndexesByPropertyStart.entrySet()) { + for ( Map.Entry entry : _byStart + .entrySet() ) + { Integer i = entry.getKey(); - FSPA fspa = _shapes.get((entry.getValue()).intValue()); - buf.append(" [FC: ").append(i.toString()).append("] "); - buf.append(fspa.toString()); - buf.append("\n"); + buf.append( " " ).append( i.toString() ).append( " => \t" ); + + try + { + FSPA fspa = getFspaFromCp( i.intValue() ); + buf.append( fspa.toString() ); + } + catch ( Exception exc ) + { + buf.append( exc.getMessage() ); + } + buf.append( "\n" ); } - buf.append("[/FSPA PLC]"); + buf.append( "[/FSPA PLC]" ); return buf.toString(); } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java index f574d0939b..60a22ab1b7 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java @@ -849,11 +849,34 @@ public final class FileInformationBlock extends FIBAbstractType _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDTXBX, size ); } + + public int getFSPAPlcfOffset( FSPADocumentPart part ) + { + return _fieldHandler.getFieldOffset( part.getFibFieldsField() ); + } + + public int getFSPAPlcfLength( FSPADocumentPart part ) + { + return _fieldHandler.getFieldSize( part.getFibFieldsField() ); + } + + public void setFSPAPlcfOffset( FSPADocumentPart part, int offset ) + { + _fieldHandler.setFieldOffset( part.getFibFieldsField(), offset ); + } + + public void setFSPAPlcfLength( FSPADocumentPart part, int length ) + { + _fieldHandler.setFieldSize( part.getFibFieldsField(), length ); + } + + @Deprecated public int getFcPlcspaMom() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCSPAMOM); } + @Deprecated public int getLcbPlcspaMom() { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCSPAMOM); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/PicturesTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/PicturesTable.java index f904b6141b..cce3526e45 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/PicturesTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/PicturesTable.java @@ -17,19 +17,19 @@ package org.apache.poi.hwpf.model; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hwpf.HWPFDocument; -import org.apache.poi.hwpf.usermodel.CharacterRun; -import org.apache.poi.hwpf.usermodel.Picture; -import org.apache.poi.hwpf.usermodel.Range; - -import java.util.List; import java.util.ArrayList; +import java.util.List; + import org.apache.poi.ddf.DefaultEscherRecordFactory; import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBlipRecord; import org.apache.poi.ddf.EscherRecord; import org.apache.poi.ddf.EscherRecordFactory; +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.usermodel.CharacterRun; +import org.apache.poi.hwpf.usermodel.Picture; +import org.apache.poi.hwpf.usermodel.Range; +import org.apache.poi.util.LittleEndian; /** * Holds information about all pictures embedded in Word Document either via "Insert -> Picture -> From File" or via @@ -61,7 +61,9 @@ public final class PicturesTable private HWPFDocument _document; private byte[] _dataStream; private byte[] _mainStream; + @Deprecated private FSPATable _fspa; + @Deprecated private EscherRecordHolder _dgg; /** @link dependency @@ -73,6 +75,7 @@ public final class PicturesTable * @param _document * @param _dataStream */ + @Deprecated public PicturesTable(HWPFDocument _document, byte[] _dataStream, byte[] _mainStream, FSPATable fspa, EscherRecordHolder dgg) { this._document = _document; @@ -82,6 +85,14 @@ public final class PicturesTable this._dgg = dgg; } + public PicturesTable( HWPFDocument _document, byte[] _dataStream, + byte[] _mainStream ) + { + this._document = _document; + this._dataStream = _dataStream; + this._mainStream = _mainStream; + } + /** * determines whether specified CharacterRun contains reference to a picture * @param run diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java index 3d42b8866b..5428215133 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java @@ -22,6 +22,7 @@ import java.util.List; import org.apache.poi.hwpf.usermodel.Shape; +@Deprecated public final class ShapesTable { private List _shapes; private List _shapesVisibili; //holds visible shapes diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/types/FSPAAbstractType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/types/FSPAAbstractType.java new file mode 100644 index 0000000000..a3a916d0b2 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/types/FSPAAbstractType.java @@ -0,0 +1,411 @@ +/* ==================================================================== + 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.types; + + +import org.apache.poi.util.BitField; +import org.apache.poi.util.Internal; +import org.apache.poi.util.LittleEndian; + +/** + * File Shape Address (FSPA). + *

+ * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format + * + *

+ * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/definitions. + *

+ * This class is internal. It content or properties may change without notice + * due to changes in our knowledge of internal Microsoft Word binary structures. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format Specification [*.doc] + */ +@Internal +public abstract class FSPAAbstractType +{ + + protected int field_1_spid; + protected int field_2_xaLeft; + protected int field_3_yaTop; + protected int field_4_xaRight; + protected int field_5_yaBottom; + protected short field_6_flags; + /**/private static BitField fHdr = new BitField(0x0001); + /**/private static BitField bx = new BitField(0x0006); + /**/private static BitField by = new BitField(0x0018); + /**/private static BitField wr = new BitField(0x01E0); + /**/private static BitField wrk = new BitField(0x1E00); + /**/private static BitField fRcaSimple = new BitField(0x2000); + /**/private static BitField fBelowText = new BitField(0x4000); + /**/private static BitField fAnchorLock = new BitField(0x8000); + protected int field_7_cTxbx; + + protected FSPAAbstractType() + { + } + + protected void fillFields( byte[] data, int offset ) + { + field_1_spid = LittleEndian.getInt(data, 0x0 + offset); + field_2_xaLeft = LittleEndian.getInt(data, 0x4 + offset); + field_3_yaTop = LittleEndian.getInt(data, 0x8 + offset); + field_4_xaRight = LittleEndian.getInt(data, 0xc + offset); + field_5_yaBottom = LittleEndian.getInt(data, 0x10 + offset); + field_6_flags = LittleEndian.getShort(data, 0x14 + offset); + field_7_cTxbx = LittleEndian.getInt(data, 0x16 + offset); + } + + public void serialize( byte[] data, int offset ) + { + LittleEndian.putInt(data, 0x0 + offset, field_1_spid); + LittleEndian.putInt(data, 0x4 + offset, field_2_xaLeft); + LittleEndian.putInt(data, 0x8 + offset, field_3_yaTop); + LittleEndian.putInt(data, 0xc + offset, field_4_xaRight); + LittleEndian.putInt(data, 0x10 + offset, field_5_yaBottom); + LittleEndian.putShort(data, 0x14 + offset, (short)field_6_flags); + LittleEndian.putInt(data, 0x16 + offset, field_7_cTxbx); + } + + /** + * Size of record + */ + public static int getSize() + { + return 0 + 4 + 4 + 4 + 4 + 4 + 2 + 4; + } + + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append("[FSPA]\n"); + builder.append(" .spid = "); + builder.append(" (").append(getSpid()).append(" )\n"); + builder.append(" .xaLeft = "); + builder.append(" (").append(getXaLeft()).append(" )\n"); + builder.append(" .yaTop = "); + builder.append(" (").append(getYaTop()).append(" )\n"); + builder.append(" .xaRight = "); + builder.append(" (").append(getXaRight()).append(" )\n"); + builder.append(" .yaBottom = "); + builder.append(" (").append(getYaBottom()).append(" )\n"); + builder.append(" .flags = "); + builder.append(" (").append(getFlags()).append(" )\n"); + builder.append(" .fHdr = ").append(isFHdr()).append('\n'); + builder.append(" .bx = ").append(getBx()).append('\n'); + builder.append(" .by = ").append(getBy()).append('\n'); + builder.append(" .wr = ").append(getWr()).append('\n'); + builder.append(" .wrk = ").append(getWrk()).append('\n'); + builder.append(" .fRcaSimple = ").append(isFRcaSimple()).append('\n'); + builder.append(" .fBelowText = ").append(isFBelowText()).append('\n'); + builder.append(" .fAnchorLock = ").append(isFAnchorLock()).append('\n'); + builder.append(" .cTxbx = "); + builder.append(" (").append(getCTxbx()).append(" )\n"); + + builder.append("[/FSPA]\n"); + return builder.toString(); + } + + /** + * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape. + */ + @Internal + public int getSpid() + { + return field_1_spid; + } + + /** + * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape. + */ + @Internal + public void setSpid( int field_1_spid ) + { + this.field_1_spid = field_1_spid; + } + + /** + * Left of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public int getXaLeft() + { + return field_2_xaLeft; + } + + /** + * Left of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public void setXaLeft( int field_2_xaLeft ) + { + this.field_2_xaLeft = field_2_xaLeft; + } + + /** + * Top of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public int getYaTop() + { + return field_3_yaTop; + } + + /** + * Top of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public void setYaTop( int field_3_yaTop ) + { + this.field_3_yaTop = field_3_yaTop; + } + + /** + * Right of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public int getXaRight() + { + return field_4_xaRight; + } + + /** + * Right of rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public void setXaRight( int field_4_xaRight ) + { + this.field_4_xaRight = field_4_xaRight; + } + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public int getYaBottom() + { + return field_5_yaBottom; + } + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the shape. + */ + @Internal + public void setYaBottom( int field_5_yaBottom ) + { + this.field_5_yaBottom = field_5_yaBottom; + } + + /** + * Get the flags field for the FSPA record. + */ + @Internal + public short getFlags() + { + return field_6_flags; + } + + /** + * Set the flags field for the FSPA record. + */ + @Internal + public void setFlags( short field_6_flags ) + { + this.field_6_flags = field_6_flags; + } + + /** + * Count of textboxes in shape (undo doc only). + */ + @Internal + public int getCTxbx() + { + return field_7_cTxbx; + } + + /** + * Count of textboxes in shape (undo doc only). + */ + @Internal + public void setCTxbx( int field_7_cTxbx ) + { + this.field_7_cTxbx = field_7_cTxbx; + } + + /** + * Sets the fHdr field value. + * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc) + */ + @Internal + public void setFHdr( boolean value ) + { + field_6_flags = (short)fHdr.setBoolean(field_6_flags, value); + } + + /** + * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc) + * @return the fHdr field value. + */ + @Internal + public boolean isFHdr() + { + return fHdr.isSet(field_6_flags); + } + + /** + * Sets the bx field value. + * X position of shape relative to anchor CP + */ + @Internal + public void setBx( byte value ) + { + field_6_flags = (short)bx.setValue(field_6_flags, value); + } + + /** + * X position of shape relative to anchor CP + * @return the bx field value. + */ + @Internal + public byte getBx() + { + return ( byte )bx.getValue(field_6_flags); + } + + /** + * Sets the by field value. + * Y position of shape relative to anchor CP + */ + @Internal + public void setBy( byte value ) + { + field_6_flags = (short)by.setValue(field_6_flags, value); + } + + /** + * Y position of shape relative to anchor CP + * @return the by field value. + */ + @Internal + public byte getBy() + { + return ( byte )by.getValue(field_6_flags); + } + + /** + * Sets the wr field value. + * Text wrapping mode + */ + @Internal + public void setWr( byte value ) + { + field_6_flags = (short)wr.setValue(field_6_flags, value); + } + + /** + * Text wrapping mode + * @return the wr field value. + */ + @Internal + public byte getWr() + { + return ( byte )wr.getValue(field_6_flags); + } + + /** + * Sets the wrk field value. + * Text wrapping mode type (valid only for wrapping modes 2 and 4 + */ + @Internal + public void setWrk( byte value ) + { + field_6_flags = (short)wrk.setValue(field_6_flags, value); + } + + /** + * Text wrapping mode type (valid only for wrapping modes 2 and 4 + * @return the wrk field value. + */ + @Internal + public byte getWrk() + { + return ( byte )wrk.getValue(field_6_flags); + } + + /** + * Sets the fRcaSimple field value. + * When set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative. + */ + @Internal + public void setFRcaSimple( boolean value ) + { + field_6_flags = (short)fRcaSimple.setBoolean(field_6_flags, value); + } + + /** + * When set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative. + * @return the fRcaSimple field value. + */ + @Internal + public boolean isFRcaSimple() + { + return fRcaSimple.isSet(field_6_flags); + } + + /** + * Sets the fBelowText field value. + * + */ + @Internal + public void setFBelowText( boolean value ) + { + field_6_flags = (short)fBelowText.setBoolean(field_6_flags, value); + } + + /** + * + * @return the fBelowText field value. + */ + @Internal + public boolean isFBelowText() + { + return fBelowText.isSet(field_6_flags); + } + + /** + * Sets the fAnchorLock field value. + * + */ + @Internal + public void setFAnchorLock( boolean value ) + { + field_6_flags = (short)fAnchorLock.setBoolean(field_6_flags, value); + } + + /** + * + * @return the fAnchorLock field value. + */ + @Internal + public boolean isFAnchorLock() + { + return fAnchorLock.isSet(field_6_flags); + } + +} // END OF CLASS diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java new file mode 100644 index 0000000000..20e3cc5222 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java @@ -0,0 +1,31 @@ +package org.apache.poi.hwpf.usermodel; + +public interface OfficeDrawing +{ + /** + * Shape Identifier + */ + int getShapeId(); + + /** + * Left of rectangle enclosing shape relative to the origin of the shape + */ + int getRectangleLeft(); + + /** + * Top of rectangle enclosing shape relative to the origin of the shape + */ + int getRectangleTop(); + + /** + * Right of rectangle enclosing shape relative to the origin of the shape + */ + int getRectangleRight(); + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the + * shape + */ + int getRectangleBottom(); + +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawings.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawings.java new file mode 100644 index 0000000000..672d5e193e --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawings.java @@ -0,0 +1,10 @@ +package org.apache.poi.hwpf.usermodel; + +import java.util.Collection; + +public interface OfficeDrawings +{ + OfficeDrawing getOfficeDrawingAt( int characterPosition ); + + Collection getOfficeDrawings(); +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java new file mode 100644 index 0000000000..933821c147 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java @@ -0,0 +1,79 @@ +package org.apache.poi.hwpf.usermodel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.apache.poi.hwpf.model.EscherRecordHolder; +import org.apache.poi.hwpf.model.FSPA; +import org.apache.poi.hwpf.model.FSPATable; + +public class OfficeDrawingsImpl implements OfficeDrawings +{ + private final EscherRecordHolder _escherRecordHolder; + private final FSPATable _fspaTable; + + public OfficeDrawingsImpl( FSPATable fspaTable, + EscherRecordHolder escherRecordHolder ) + { + this._fspaTable = fspaTable; + this._escherRecordHolder = escherRecordHolder; + } + + private OfficeDrawing getOfficeDrawing( final FSPA fspa ) + { + return new OfficeDrawing() + { + public int getRectangleBottom() + { + return fspa.getYaBottom(); + } + + public int getRectangleLeft() + { + return fspa.getXaLeft(); + } + + public int getRectangleRight() + { + return fspa.getXaRight(); + } + + public int getRectangleTop() + { + return fspa.getYaTop(); + } + + public int getShapeId() + { + return fspa.getSpid(); + } + + @Override + public String toString() + { + return "OfficeDrawingImpl: " + fspa.toString(); + } + }; + } + + public OfficeDrawing getOfficeDrawingAt( int characterPosition ) + { + final FSPA fspa = _fspaTable.getFspaFromCp( characterPosition ); + if ( fspa == null ) + return null; + + return getOfficeDrawing( fspa ); + } + + public Collection getOfficeDrawings() + { + List result = new ArrayList(); + for ( FSPA fspa : _fspaTable.getShapes() ) + { + result.add( getOfficeDrawing( fspa ) ); + } + return Collections.unmodifiableList( result ); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java index aecc0d3461..3d3e136316 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java @@ -20,6 +20,10 @@ package org.apache.poi.hwpf.usermodel; import org.apache.poi.hwpf.model.GenericPropertyNode; import org.apache.poi.util.LittleEndian; +/** + * @deprecated Use {@link OfficeDrawing} instead + */ +@Deprecated public final class Shape { int _id, _left, _right, _top, _bottom; /** diff --git a/src/types/definitions/fspa_type.xml b/src/types/definitions/fspa_type.xml new file mode 100644 index 0000000000..42e464aa5a --- /dev/null +++ b/src/types/definitions/fspa_type.xml @@ -0,0 +1,74 @@ + + + + AbstractType + HDFType + File Shape Address (FSPA). <p>Class and fields descriptions are quoted from + Microsoft Office Word 97-2007 Binary File Format + + Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format + Specification [*.doc] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +