PPDrawingpublic class PPDrawing extends RecordAtom These are actually wrappers onto Escher drawings. Make use of
the DDF classes to do useful things with them.
For now, creates a tree of the Escher records, and then creates any
PowerPoint (hslf) records found within the EscherTextboxRecord
(msofbtClientTextbox) records.
Also provides easy access to the EscherTextboxRecords, so that their
text may be extracted and used in Sheets |
Fields Summary |
---|
private byte[] | _header | private long | _type | private EscherRecord[] | childRecords | private EscherTextboxWrapper[] | textboxWrappers |
Constructors Summary |
---|
protected PPDrawing(byte[] source, int start, int len)Sets everything up, groks the escher etc
// Get the header
_header = new byte[8];
System.arraycopy(source,start,_header,0,8);
// Get the type
_type = LittleEndian.getUShort(_header,2);
// Get the contents for now
byte[] contents = new byte[len];
System.arraycopy(source,start,contents,0,len);
// Build up a tree of Escher records contained within
DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory();
Vector escherChildren = new Vector();
findEscherChildren(erf,contents,8,len-8,escherChildren);
childRecords = new EscherRecord[escherChildren.size()];
for(int i=0; i<childRecords.length; i++) {
childRecords[i] = (EscherRecord)escherChildren.get(i);
}
// Find and EscherTextboxRecord's, and wrap them up
Vector textboxes = new Vector();
findEscherTextboxRecord(childRecords, textboxes);
textboxWrappers = new EscherTextboxWrapper[textboxes.size()];
for(int i=0; i<textboxWrappers.length; i++) {
textboxWrappers[i] = (EscherTextboxWrapper)textboxes.get(i);
}
| public PPDrawing()Creates a new, empty, PPDrawing (typically for use with a new Slide
or Notes)
_header = new byte[8];
LittleEndian.putUShort(_header, 0, 15);
LittleEndian.putUShort(_header, 2, (int)RecordTypes.PPDrawing.typeID);
LittleEndian.putInt(_header, 4, 0);
textboxWrappers = new EscherTextboxWrapper[]{};
create();
|
Methods Summary |
---|
public void | addTextboxWrapper(org.apache.poi.hslf.record.EscherTextboxWrapper txtbox)Add a new EscherTextboxWrapper to this PPDrawing .
EscherTextboxWrapper[] tw = new EscherTextboxWrapper[textboxWrappers.length + 1];
System.arraycopy(textboxWrappers, 0, tw, 0, textboxWrappers.length);
tw[textboxWrappers.length] = txtbox;
textboxWrappers = tw;
| private void | create()Create the Escher records associated with a new PPDrawing
EscherContainerRecord dgContainer = new EscherContainerRecord();
dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER );
dgContainer.setOptions((short)15);
EscherDgRecord dg = new EscherDgRecord();
dg.setOptions((short)16);
dg.setNumShapes(1);
dgContainer.addChildRecord(dg);
EscherContainerRecord spgrContainer = new EscherContainerRecord();
spgrContainer.setOptions((short)15);
spgrContainer.setRecordId(EscherContainerRecord.SPGR_CONTAINER);
EscherContainerRecord spContainer = new EscherContainerRecord();
spContainer.setOptions((short)15);
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
EscherSpgrRecord spgr = new EscherSpgrRecord();
spgr.setOptions((short)1);
spContainer.addChildRecord(spgr);
EscherSpRecord sp = new EscherSpRecord();
sp.setOptions((short)((ShapeTypes.NotPrimitive << 4) + 2));
sp.setFlags(EscherSpRecord.FLAG_PATRIARCH | EscherSpRecord.FLAG_GROUP);
spContainer.addChildRecord(sp);
spgrContainer.addChildRecord(spContainer);
dgContainer.addChildRecord(spgrContainer);
spContainer = new EscherContainerRecord();
spContainer.setOptions((short)15);
spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
sp = new EscherSpRecord();
sp.setOptions((short)((ShapeTypes.Rectangle << 4) + 2));
sp.setFlags(EscherSpRecord.FLAG_BACKGROUND | EscherSpRecord.FLAG_HASSHAPETYPE);
spContainer.addChildRecord(sp);
EscherOptRecord opt = new EscherOptRecord();
opt.setRecordId(EscherOptRecord.RECORD_ID);
opt.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, 134217728));
opt.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLBACKCOLOR, 134217733));
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__RECTRIGHT, 10064750));
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__RECTBOTTOM, 7778750));
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 1179666));
opt.addEscherProperty(new EscherBoolProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524288));
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHAPE__BLACKANDWHITESETTINGS, 9));
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHAPE__BACKGROUNDSHAPE, 65537));
spContainer.addChildRecord(opt);
dgContainer.addChildRecord(spContainer);
childRecords = new EscherRecord[]{
dgContainer
};
| private void | findEscherChildren(org.apache.poi.ddf.DefaultEscherRecordFactory erf, byte[] source, int startPos, int lenToGo, java.util.Vector found)Tree walking way of finding Escher Child Records
// Find the record
EscherRecord r = erf.createRecord(source,startPos);
// Fill it in
r.fillFields( source, startPos, erf );
// Save it
found.add(r);
// Wind on
int size = r.getRecordSize();
if(size < 8) {
logger.log(POILogger.WARN, "Hit short DDF record at " + startPos + " - " + size);
}
startPos += size;
lenToGo -= size;
if(lenToGo >= 8) {
findEscherChildren(erf, source, startPos, lenToGo, found);
}
| private void | findEscherTextboxRecord(org.apache.poi.ddf.EscherRecord[] toSearch, java.util.Vector found)Look for EscherTextboxRecords
for(int i=0; i<toSearch.length; i++) {
if(toSearch[i] instanceof EscherTextboxRecord) {
EscherTextboxRecord tbr = (EscherTextboxRecord)toSearch[i];
EscherTextboxWrapper w = new EscherTextboxWrapper(tbr);
found.add(w);
for (int j = i; j >= 0; j--) {
if(toSearch[j] instanceof EscherSpRecord){
EscherSpRecord sp = (EscherSpRecord)toSearch[j];
w.setShapeId(sp.getShapeId());
break;
}
}
} else {
// If it has children, walk them
if(toSearch[i].isContainerRecord()) {
List childrenL = toSearch[i].getChildRecords();
EscherRecord[] children = new EscherRecord[childrenL.size()];
for(int j=0; j< children.length; j++) {
children[j] = (EscherRecord)childrenL.get(j);
}
findEscherTextboxRecord(children,found);
}
}
}
| public org.apache.poi.hslf.record.Record[] | getChildRecords()We're pretending to be an atom, so return null return null;
| public org.apache.poi.ddf.EscherRecord[] | getEscherRecords()Get access to the underlying Escher Records return childRecords;
| public long | getRecordType()We are type 1036 return _type;
| public org.apache.poi.hslf.record.EscherTextboxWrapper[] | getTextboxWrappers()Get access to the atoms inside Textboxes return textboxWrappers;
| public void | writeOut(java.io.OutputStream out)Write the contents of the record back, so it can be written
to disk
Walks the escher layer to get the contents
// Ensure the escher layer reflects the text changes
for(int i=0; i<textboxWrappers.length; i++) {
textboxWrappers[i].writeOut(null);
}
// Find the new size of the escher children;
int newSize = 0;
for(int i=0; i<childRecords.length; i++) {
newSize += childRecords[i].getRecordSize();
}
// Update the size (header bytes 5-8)
LittleEndian.putInt(_header,4,newSize);
// Write out our header
out.write(_header);
// Now grab the children's data
byte[] b = new byte[newSize];
int done = 0;
for(int i=0; i<childRecords.length; i++) {
int written = childRecords[i].serialize( done, b );
done += written;
}
// Finally, write out the children
out.write(b);
|
|