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;
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;
/** 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;
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());
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
*/
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;
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';
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 )
}
}
+ 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 );
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;
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;
{
switch ( languageCode )
{
+ case 1024:
+ return EMPTY;
case 1033:
return "en-us";
case 1049:
default:
logger.log( POILogger.WARN, "Uknown or unmapped language code: ",
Integer.valueOf( languageCode ) );
- return "";
+ return EMPTY;
}
}
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;
+ "\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 );
}
boolean outputPapxProperties = false;
boolean outputBookmarks = false;
+ boolean outputEscher = false;
boolean outputFields = false;
boolean outputPictures = false;
+ boolean outputOfficeDrawings = false;
boolean writereadback = false;
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;
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 ==" );
}
}
+ 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();
}
}
+ 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<PAPX> papxs = new ArrayList<PAPX>();
-//
-// 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<PAPX> papxs = new ArrayList<PAPX>();
+ //
+ // 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() )
// {
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;
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();
- }
}
--- /dev/null
+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;
+ }
+}
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<FSPA> _shapes = new ArrayList<FSPA>();
- private final Map<Integer, Integer> _shapeIndexesByPropertyStart = new HashMap<Integer, Integer>();
- private final List<TextPiece> _text;
- public FSPATable(byte[] tableStream, int fcPlcspa, int lcbPlcspa, List<TextPiece> tpt)
+ private final Map<Integer, GenericPropertyNode> _byStart = new LinkedHashMap<Integer, GenericPropertyNode>();
+
+ 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<TextPiece> 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<FSPA> result = new ArrayList<FSPA>( _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<Integer, Integer> entry: _shapeIndexesByPropertyStart.entrySet()) {
+ for ( Map.Entry<Integer, GenericPropertyNode> 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();
}
}
_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);
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
private HWPFDocument _document;
private byte[] _dataStream;
private byte[] _mainStream;
+ @Deprecated
private FSPATable _fspa;
+ @Deprecated
private EscherRecordHolder _dgg;
/** @link dependency
* @param _document
* @param _dataStream
*/
+ @Deprecated
public PicturesTable(HWPFDocument _document, byte[] _dataStream, byte[] _mainStream, FSPATable fspa, EscherRecordHolder dgg)
{
this._document = _document;
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
import org.apache.poi.hwpf.usermodel.Shape;
+@Deprecated
public final class ShapesTable {
private List<Shape> _shapes;
private List<Shape> _shapesVisibili; //holds visible shapes
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.hwpf.model.types;\r
+\r
+\r
+import org.apache.poi.util.BitField;\r
+import org.apache.poi.util.Internal;\r
+import org.apache.poi.util.LittleEndian;\r
+\r
+/**\r
+ * File Shape Address (FSPA).\r
+ * <p>\r
+ * Class and fields descriptions are quoted from Microsoft Office Word 97-2007\r
+ * Binary File Format\r
+ * \r
+ * <p>\r
+ * NOTE: This source is automatically generated please do not modify this file.\r
+ * Either subclass or remove the record in src/types/definitions.\r
+ * <p>\r
+ * This class is internal. It content or properties may change without notice\r
+ * due to changes in our knowledge of internal Microsoft Word binary structures.\r
+ * \r
+ * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary\r
+ * File Format Specification [*.doc]\r
+ */\r
+@Internal\r
+public abstract class FSPAAbstractType\r
+{\r
+\r
+ protected int field_1_spid;\r
+ protected int field_2_xaLeft;\r
+ protected int field_3_yaTop;\r
+ protected int field_4_xaRight;\r
+ protected int field_5_yaBottom;\r
+ protected short field_6_flags;\r
+ /**/private static BitField fHdr = new BitField(0x0001);\r
+ /**/private static BitField bx = new BitField(0x0006);\r
+ /**/private static BitField by = new BitField(0x0018);\r
+ /**/private static BitField wr = new BitField(0x01E0);\r
+ /**/private static BitField wrk = new BitField(0x1E00);\r
+ /**/private static BitField fRcaSimple = new BitField(0x2000);\r
+ /**/private static BitField fBelowText = new BitField(0x4000);\r
+ /**/private static BitField fAnchorLock = new BitField(0x8000);\r
+ protected int field_7_cTxbx;\r
+\r
+ protected FSPAAbstractType()\r
+ {\r
+ }\r
+\r
+ protected void fillFields( byte[] data, int offset )\r
+ {\r
+ field_1_spid = LittleEndian.getInt(data, 0x0 + offset);\r
+ field_2_xaLeft = LittleEndian.getInt(data, 0x4 + offset);\r
+ field_3_yaTop = LittleEndian.getInt(data, 0x8 + offset);\r
+ field_4_xaRight = LittleEndian.getInt(data, 0xc + offset);\r
+ field_5_yaBottom = LittleEndian.getInt(data, 0x10 + offset);\r
+ field_6_flags = LittleEndian.getShort(data, 0x14 + offset);\r
+ field_7_cTxbx = LittleEndian.getInt(data, 0x16 + offset);\r
+ }\r
+\r
+ public void serialize( byte[] data, int offset )\r
+ {\r
+ LittleEndian.putInt(data, 0x0 + offset, field_1_spid);\r
+ LittleEndian.putInt(data, 0x4 + offset, field_2_xaLeft);\r
+ LittleEndian.putInt(data, 0x8 + offset, field_3_yaTop);\r
+ LittleEndian.putInt(data, 0xc + offset, field_4_xaRight);\r
+ LittleEndian.putInt(data, 0x10 + offset, field_5_yaBottom);\r
+ LittleEndian.putShort(data, 0x14 + offset, (short)field_6_flags);\r
+ LittleEndian.putInt(data, 0x16 + offset, field_7_cTxbx);\r
+ }\r
+\r
+ /**\r
+ * Size of record\r
+ */\r
+ public static int getSize()\r
+ {\r
+ return 0 + 4 + 4 + 4 + 4 + 4 + 2 + 4;\r
+ }\r
+\r
+ public String toString()\r
+ {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("[FSPA]\n");\r
+ builder.append(" .spid = ");\r
+ builder.append(" (").append(getSpid()).append(" )\n");\r
+ builder.append(" .xaLeft = ");\r
+ builder.append(" (").append(getXaLeft()).append(" )\n");\r
+ builder.append(" .yaTop = ");\r
+ builder.append(" (").append(getYaTop()).append(" )\n");\r
+ builder.append(" .xaRight = ");\r
+ builder.append(" (").append(getXaRight()).append(" )\n");\r
+ builder.append(" .yaBottom = ");\r
+ builder.append(" (").append(getYaBottom()).append(" )\n");\r
+ builder.append(" .flags = ");\r
+ builder.append(" (").append(getFlags()).append(" )\n");\r
+ builder.append(" .fHdr = ").append(isFHdr()).append('\n');\r
+ builder.append(" .bx = ").append(getBx()).append('\n');\r
+ builder.append(" .by = ").append(getBy()).append('\n');\r
+ builder.append(" .wr = ").append(getWr()).append('\n');\r
+ builder.append(" .wrk = ").append(getWrk()).append('\n');\r
+ builder.append(" .fRcaSimple = ").append(isFRcaSimple()).append('\n');\r
+ builder.append(" .fBelowText = ").append(isFBelowText()).append('\n');\r
+ builder.append(" .fAnchorLock = ").append(isFAnchorLock()).append('\n');\r
+ builder.append(" .cTxbx = ");\r
+ builder.append(" (").append(getCTxbx()).append(" )\n");\r
+\r
+ builder.append("[/FSPA]\n");\r
+ return builder.toString();\r
+ }\r
+\r
+ /**\r
+ * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape.\r
+ */\r
+ @Internal\r
+ public int getSpid()\r
+ {\r
+ return field_1_spid;\r
+ }\r
+\r
+ /**\r
+ * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape.\r
+ */\r
+ @Internal\r
+ public void setSpid( int field_1_spid )\r
+ {\r
+ this.field_1_spid = field_1_spid;\r
+ }\r
+\r
+ /**\r
+ * Left of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public int getXaLeft()\r
+ {\r
+ return field_2_xaLeft;\r
+ }\r
+\r
+ /**\r
+ * Left of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public void setXaLeft( int field_2_xaLeft )\r
+ {\r
+ this.field_2_xaLeft = field_2_xaLeft;\r
+ }\r
+\r
+ /**\r
+ * Top of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public int getYaTop()\r
+ {\r
+ return field_3_yaTop;\r
+ }\r
+\r
+ /**\r
+ * Top of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public void setYaTop( int field_3_yaTop )\r
+ {\r
+ this.field_3_yaTop = field_3_yaTop;\r
+ }\r
+\r
+ /**\r
+ * Right of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public int getXaRight()\r
+ {\r
+ return field_4_xaRight;\r
+ }\r
+\r
+ /**\r
+ * Right of rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public void setXaRight( int field_4_xaRight )\r
+ {\r
+ this.field_4_xaRight = field_4_xaRight;\r
+ }\r
+\r
+ /**\r
+ * Bottom of the rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public int getYaBottom()\r
+ {\r
+ return field_5_yaBottom;\r
+ }\r
+\r
+ /**\r
+ * Bottom of the rectangle enclosing shape relative to the origin of the shape.\r
+ */\r
+ @Internal\r
+ public void setYaBottom( int field_5_yaBottom )\r
+ {\r
+ this.field_5_yaBottom = field_5_yaBottom;\r
+ }\r
+\r
+ /**\r
+ * Get the flags field for the FSPA record.\r
+ */\r
+ @Internal\r
+ public short getFlags()\r
+ {\r
+ return field_6_flags;\r
+ }\r
+\r
+ /**\r
+ * Set the flags field for the FSPA record.\r
+ */\r
+ @Internal\r
+ public void setFlags( short field_6_flags )\r
+ {\r
+ this.field_6_flags = field_6_flags;\r
+ }\r
+\r
+ /**\r
+ * Count of textboxes in shape (undo doc only).\r
+ */\r
+ @Internal\r
+ public int getCTxbx()\r
+ {\r
+ return field_7_cTxbx;\r
+ }\r
+\r
+ /**\r
+ * Count of textboxes in shape (undo doc only).\r
+ */\r
+ @Internal\r
+ public void setCTxbx( int field_7_cTxbx )\r
+ {\r
+ this.field_7_cTxbx = field_7_cTxbx;\r
+ }\r
+\r
+ /**\r
+ * Sets the fHdr field value.\r
+ * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc)\r
+ */\r
+ @Internal\r
+ public void setFHdr( boolean value )\r
+ {\r
+ field_6_flags = (short)fHdr.setBoolean(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc)\r
+ * @return the fHdr field value.\r
+ */\r
+ @Internal\r
+ public boolean isFHdr()\r
+ {\r
+ return fHdr.isSet(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the bx field value.\r
+ * X position of shape relative to anchor CP\r
+ */\r
+ @Internal\r
+ public void setBx( byte value )\r
+ {\r
+ field_6_flags = (short)bx.setValue(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * X position of shape relative to anchor CP\r
+ * @return the bx field value.\r
+ */\r
+ @Internal\r
+ public byte getBx()\r
+ {\r
+ return ( byte )bx.getValue(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the by field value.\r
+ * Y position of shape relative to anchor CP\r
+ */\r
+ @Internal\r
+ public void setBy( byte value )\r
+ {\r
+ field_6_flags = (short)by.setValue(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * Y position of shape relative to anchor CP\r
+ * @return the by field value.\r
+ */\r
+ @Internal\r
+ public byte getBy()\r
+ {\r
+ return ( byte )by.getValue(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the wr field value.\r
+ * Text wrapping mode\r
+ */\r
+ @Internal\r
+ public void setWr( byte value )\r
+ {\r
+ field_6_flags = (short)wr.setValue(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * Text wrapping mode\r
+ * @return the wr field value.\r
+ */\r
+ @Internal\r
+ public byte getWr()\r
+ {\r
+ return ( byte )wr.getValue(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the wrk field value.\r
+ * Text wrapping mode type (valid only for wrapping modes 2 and 4\r
+ */\r
+ @Internal\r
+ public void setWrk( byte value )\r
+ {\r
+ field_6_flags = (short)wrk.setValue(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * Text wrapping mode type (valid only for wrapping modes 2 and 4\r
+ * @return the wrk field value.\r
+ */\r
+ @Internal\r
+ public byte getWrk()\r
+ {\r
+ return ( byte )wrk.getValue(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the fRcaSimple field value.\r
+ * When set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative.\r
+ */\r
+ @Internal\r
+ public void setFRcaSimple( boolean value )\r
+ {\r
+ field_6_flags = (short)fRcaSimple.setBoolean(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * When set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative.\r
+ * @return the fRcaSimple field value.\r
+ */\r
+ @Internal\r
+ public boolean isFRcaSimple()\r
+ {\r
+ return fRcaSimple.isSet(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the fBelowText field value.\r
+ * \r
+ */\r
+ @Internal\r
+ public void setFBelowText( boolean value )\r
+ {\r
+ field_6_flags = (short)fBelowText.setBoolean(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @return the fBelowText field value.\r
+ */\r
+ @Internal\r
+ public boolean isFBelowText()\r
+ {\r
+ return fBelowText.isSet(field_6_flags);\r
+ }\r
+\r
+ /**\r
+ * Sets the fAnchorLock field value.\r
+ * \r
+ */\r
+ @Internal\r
+ public void setFAnchorLock( boolean value )\r
+ {\r
+ field_6_flags = (short)fAnchorLock.setBoolean(field_6_flags, value);\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @return the fAnchorLock field value.\r
+ */\r
+ @Internal\r
+ public boolean isFAnchorLock()\r
+ {\r
+ return fAnchorLock.isSet(field_6_flags);\r
+ }\r
+\r
+} // END OF CLASS\r
--- /dev/null
+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();
+
+}
--- /dev/null
+package org.apache.poi.hwpf.usermodel;
+
+import java.util.Collection;
+
+public interface OfficeDrawings
+{
+ OfficeDrawing getOfficeDrawingAt( int characterPosition );
+
+ Collection<OfficeDrawing> getOfficeDrawings();
+}
--- /dev/null
+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<OfficeDrawing> getOfficeDrawings()
+ {
+ List<OfficeDrawing> result = new ArrayList<OfficeDrawing>();
+ for ( FSPA fspa : _fspaTable.getShapes() )
+ {
+ result.add( getOfficeDrawing( fspa ) );
+ }
+ return Collections.unmodifiableList( result );
+ }
+}
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;
/**
--- /dev/null
+<?xml version="1.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.
+ ====================================================================
+-->
+<record fromfile="true" name="FSPA" package="org.apache.poi.hwpf.model.types">
+ <suffix>AbstractType</suffix>
+ <extends>HDFType</extends>
+ <description>File Shape Address (FSPA). <p>Class and fields descriptions are quoted from
+ Microsoft Office Word 97-2007 Binary File Format
+ </description>
+ <author>Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format
+ Specification [*.doc]
+ </author>
+ <fields>
+ <field type="int" size="4" name="spid"
+ description="Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape"/>
+ <field type="int" size="4" name="xaLeft"
+ description="Left of rectangle enclosing shape relative to the origin of the shape"/>
+ <field type="int" size="4" name="yaTop"
+ description="Top of rectangle enclosing shape relative to the origin of the shape"/>
+ <field type="int" size="4" name="xaRight"
+ description="Right of rectangle enclosing shape relative to the origin of the shape"/>
+ <field type="int" size="4" name="yaBottom"
+ description="Bottom of the rectangle enclosing shape relative to the origin of the shape"/>
+ <field type="short" size="2" name="flags">
+ <bit number="0" mask="0x0001" name="fHdr"
+ description="1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc)"/>
+ <bit number="1" mask="0x0006" name="bx" description="X position of shape relative to anchor CP">
+ <const type="byte" value="0" name="PAGEMARGIN" description="relative to page margin"/>
+ <const type="byte" value="1" name="PAGETOP" description="relative to top of page"/>
+ <const type="byte" value="2" name="TEXT"
+ description="relative to text (column for horizontal text; paragraph for vertical text)"/>
+ <const type="byte" value="3" name="RESERVED" description="reserved for future use"/>
+ </bit>
+ <bit number="2" mask="0x0018" name="by" description="Y position of shape relative to anchor CP">
+ <const type="byte" value="0" name="PAGEMARGIN" description="relative to page margin"/>
+ <const type="byte" value="1" name="PAGETOP" description="relative to top of page"/>
+ <const type="byte" value="2" name="TEXT"
+ description="relative to text (paragraph for horizontal text; column for vertical text)"/>
+ </bit>
+ <bit number="3" mask="0x01E0" name="wr" description="Text wrapping mode">
+ <const type="byte" value="0" name="AROUNDABSOLUTENR"
+ description="like 2, but doesnât require absolute object"/>
+ <const type="byte" value="1" name="NOTEXTNEXTTO" description="no text next to shape"/>
+ <const type="byte" value="2" name="AROUNDABSOLUTE" description="wrap around absolute object"/>
+ <const type="byte" value="3" name="NOOBJECT" description="wrap as if no object present"/>
+ <const type="byte" value="4" name="TIGHTLY" description="wrap tightly around object"/>
+ <const type="byte" value="5" name="TIGHTLYWITHHOLES" description="wrap tightly, but allow holes"/>
+ </bit>
+ <bit number="4" mask="0x1E00" name="wrk"
+ description="Text wrapping mode type (valid only for wrapping modes 2 and 4"/>
+ <bit number="5" mask="0x2000" name="fRcaSimple"
+ description="When set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative."/>
+ <bit number="6" mask="0x4000" name="fBelowText"/>
+ <bit number="7" mask="0x8000" name="fAnchorLock"/>
+ </field>
+ <field type="int" size="4" name="cTxbx" description="Count of textboxes in shape (undo doc only)"/>
+ </fields>
+</record>