FileDocCategorySizeDatePackage
PPDrawing.javaAPI DocApache Poi 3.0.19435Thu May 31 18:45:28 BST 2007org.apache.poi.hslf.record

PPDrawing

public 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
author
Nick Burch

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 voidaddTextboxWrapper(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 voidcreate()
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 voidfindEscherChildren(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 voidfindEscherTextboxRecord(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 longgetRecordType()
We are type 1036

 return _type; 
public org.apache.poi.hslf.record.EscherTextboxWrapper[]getTextboxWrappers()
Get access to the atoms inside Textboxes

 return textboxWrappers; 
public voidwriteOut(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);