diff --git a/src/java/org/apache/poi/ddf/EscherBitmapBlip.java b/src/java/org/apache/poi/ddf/EscherBitmapBlip.java
new file mode 100644
index 000000000..6222aeceb
--- /dev/null
+++ b/src/java/org/apache/poi/ddf/EscherBitmapBlip.java
@@ -0,0 +1,139 @@
+package org.apache.poi.ddf;
+
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * @author Glen Stampoultzis
+ * @version $Id$
+ */
+public class EscherBitmapBlip
+ extends EscherBlipRecord
+{
+ public static final short RECORD_ID_JPEG = (short) 0xF018 + 5;
+ public static final short RECORD_ID_PNG = (short) 0xF018 + 6;
+ public static final short RECORD_ID_DIB = (short) 0xF018 + 7;
+
+ private static final int HEADER_SIZE = 8;
+
+ private byte[] field_1_UID;
+ private byte field_2_marker = (byte) 0xFF;
+
+
+ /**
+ * This method deserializes the record from a byte array.
+ *
+ * @param data The byte array containing the escher record information
+ * @param offset The starting offset into data
.
+ * @param recordFactory May be null since this is not a container record.
+ * @return The number of bytes read from the byte array.
+ */
+ public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory )
+ {
+ int bytesAfterHeader = readHeader( data, offset );
+ int pos = offset + HEADER_SIZE;
+
+ field_1_UID = new byte[16];
+ System.arraycopy( data, pos, field_1_UID, 0, 16 ); pos += 16;
+ field_2_marker = data[pos]; pos++;
+
+ field_pictureData = new byte[bytesAfterHeader - 17];
+ System.arraycopy( data, pos, field_pictureData, 0, field_pictureData.length );
+
+ return bytesAfterHeader + HEADER_SIZE;
+ }
+
+ /**
+ * Serializes the record to an existing byte array.
+ *
+ * @param offset the offset within the byte array
+ * @param data the data array to serialize to
+ * @param listener a listener for begin and end serialization events. This
+ * is useful because the serialization is
+ * hierarchical/recursive and sometimes you need to be able
+ * break into that.
+ * @return the number of bytes written.
+ */
+ public int serialize( int offset, byte[] data, EscherSerializationListener listener )
+ {
+ listener.beforeRecordSerialize(offset, getRecordId(), this);
+
+ LittleEndian.putShort( data, offset, getOptions() );
+ LittleEndian.putShort( data, offset + 2, getRecordId() );
+ LittleEndian.putInt( data, offset + 4, getRecordSize() - HEADER_SIZE );
+ int pos = offset + HEADER_SIZE;
+
+ System.arraycopy( field_1_UID, 0, data, pos, 16 );
+ data[pos + 16] = field_2_marker;
+ System.arraycopy( field_pictureData, 0, data, pos + 17, field_pictureData.length );
+
+ listener.afterRecordSerialize(offset + getRecordSize(), getRecordId(), getRecordSize(), this);
+ return HEADER_SIZE + 16 + 1 + field_pictureData.length;
+ }
+
+ /**
+ * Returns the number of bytes that are required to serialize this record.
+ *
+ * @return Number of bytes
+ */
+ public int getRecordSize()
+ {
+ return 8 + 16 + 1 + field_pictureData.length;
+ }
+
+ public byte[] getUID()
+ {
+ return field_1_UID;
+ }
+
+ public void setUID( byte[] field_1_UID )
+ {
+ this.field_1_UID = field_1_UID;
+ }
+
+ public byte getMarker()
+ {
+ return field_2_marker;
+ }
+
+ public void setMarker( byte field_2_marker )
+ {
+ this.field_2_marker = field_2_marker;
+ }
+
+ public byte[] getPicturedata()
+ {
+ return field_pictureData;
+ }
+
+ public void setPictureData(byte[] pictureData)
+ {
+ field_pictureData = pictureData;
+ }
+
+ public String toString()
+ {
+ String nl = System.getProperty( "line.separator" );
+
+ String extraData;
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ try
+ {
+ HexDump.dump( this.field_pictureData, 0, b, 0 );
+ extraData = b.toString();
+ }
+ catch ( Exception e )
+ {
+ extraData = e.toString();
+ }
+ return getClass().getName() + ":" + nl +
+ " RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
+ " Options: 0x" + HexDump.toHex( getOptions() ) + nl +
+ " UID: 0x" + HexDump.toHex( field_1_UID ) + nl +
+ " Marker: 0x" + HexDump.toHex( field_2_marker ) + nl +
+ " Extra Data:" + nl + extraData;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/model/DrawingManager.java b/src/java/org/apache/poi/hssf/model/DrawingManager.java
deleted file mode 100644
index fbf1f444c..000000000
--- a/src/java/org/apache/poi/hssf/model/DrawingManager.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/* ====================================================================
- Copyright 2004 Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.model;
-
-import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.ddf.EscherDgRecord;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Provides utilities to manage drawing groups.
- *
- * @author Glen Stampoultzis (glens at apache.org)
- */
-public class DrawingManager
-{
- EscherDggRecord dgg;
- Map dgMap = new HashMap(); // key = Short(drawingId), value=EscherDgRecord
-
- public DrawingManager( EscherDggRecord dgg )
- {
- this.dgg = dgg;
- }
-
- public EscherDgRecord createDgRecord()
- {
- EscherDgRecord dg = new EscherDgRecord();
- dg.setRecordId( EscherDgRecord.RECORD_ID );
- short dgId = findNewDrawingGroupId();
- dg.setOptions( (short) ( dgId << 4 ) );
- dg.setNumShapes( 0 );
- dg.setLastMSOSPID( -1 );
- dgg.addCluster( dgId, 0 );
- dgg.setDrawingsSaved( dgg.getDrawingsSaved() + 1 );
- dgMap.put( new Short( dgId ), dg );
- return dg;
- }
-
- /**
- * Allocates new shape id for the new drawing group id.
- *
- * @return a new shape id.
- */
- public int allocateShapeId(short drawingGroupId)
- {
- // Get the last shape id for this drawing group.
- EscherDgRecord dg = (EscherDgRecord) dgMap.get(new Short(drawingGroupId));
- int lastShapeId = dg.getLastMSOSPID();
-
-
- // Have we run out of shapes for this cluster?
- int newShapeId = 0;
- if (lastShapeId % 1024 == 1023)
- {
- // Yes:
- // Find the starting shape id of the next free cluster
- newShapeId = findFreeSPIDBlock();
- // Create a new cluster in the dgg record.
- dgg.addCluster(drawingGroupId, 1);
- }
- else
- {
- // No:
- // Find the cluster for this drawing group with free space.
- for (int i = 0; i < dgg.getFileIdClusters().length; i++)
- {
- EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
- if (c.getDrawingGroupId() == drawingGroupId)
- {
- if (c.getNumShapeIdsUsed() != 1024)
- {
- // Increment the number of shapes used for this cluster.
- c.incrementShapeId();
- }
- }
- // If the last shape id = -1 then we know to find a free block;
- if (dg.getLastMSOSPID() == -1)
- {
- newShapeId = findFreeSPIDBlock();
- }
- else
- {
- // The new shape id to be the last shapeid of this cluster + 1
- newShapeId = dg.getLastMSOSPID() + 1;
- }
- }
- }
- // Increment the total number of shapes used in the dgg.
- dgg.setNumShapesSaved(dgg.getNumShapesSaved() + 1);
- // Is the new shape id >= max shape id for dgg?
- if (newShapeId >= dgg.getShapeIdMax())
- {
- // Yes:
- // Set the max shape id = new shape id + 1
- dgg.setShapeIdMax(newShapeId + 1);
- }
- // Set last shape id for this drawing group.
- dg.setLastMSOSPID(newShapeId);
- // Increased the number of shapes used for this drawing group.
- dg.incrementShapeCount();
-
-
- return newShapeId;
- }
-
- //////////// Non-public methods /////////////
- short findNewDrawingGroupId()
- {
- short dgId = 1;
- while ( drawingGroupExists( dgId ) )
- dgId++;
- return dgId;
- }
-
- boolean drawingGroupExists( short dgId )
- {
- for ( int i = 0; i < dgg.getFileIdClusters().length; i++ )
- {
- if ( dgg.getFileIdClusters()[i].getDrawingGroupId() == dgId )
- return true;
- }
- return false;
- }
-
- int findFreeSPIDBlock()
- {
- int max = dgg.getShapeIdMax();
- int next = ( ( max / 1024 ) + 1 ) * 1024;
- return next;
- }
-
- public EscherDggRecord getDgg()
- {
- return dgg;
- }
-
-}
diff --git a/src/java/org/apache/poi/hssf/model/DrawingManager2.java b/src/java/org/apache/poi/hssf/model/DrawingManager2.java
new file mode 100644
index 000000000..5efd53bd0
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/model/DrawingManager2.java
@@ -0,0 +1,130 @@
+/* ====================================================================
+ Copyright 2004 Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.model;
+
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherDggRecord;
+
+import java.util.List;
+import java.util.ArrayList;
+
+
+/**
+ * Provides utilities to manage drawing groups.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public class DrawingManager2
+{
+ EscherDggRecord dgg;
+ List drawingGroups = new ArrayList( );
+
+
+ public DrawingManager2( EscherDggRecord dgg )
+ {
+ this.dgg = dgg;
+ }
+
+ public EscherDgRecord createDgRecord()
+ {
+ EscherDgRecord dg = new EscherDgRecord();
+ dg.setRecordId( EscherDgRecord.RECORD_ID );
+ short dgId = findNewDrawingGroupId();
+ dg.setOptions( (short) ( dgId << 4 ) );
+ dg.setNumShapes( 0 );
+ dg.setLastMSOSPID( -1 );
+ drawingGroups.add(dg);
+ dgg.addCluster( dgId, 0 );
+ dgg.setDrawingsSaved( dgg.getDrawingsSaved() + 1 );
+ return dg;
+ }
+
+ /**
+ * Allocates new shape id for the new drawing group id.
+ *
+ * @return a new shape id.
+ */
+ public int allocateShapeId(short drawingGroupId)
+ {
+ dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
+
+ // Add to existing cluster if space available
+ for (int i = 0; i < dgg.getFileIdClusters().length; i++)
+ {
+ EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
+ if (c.getDrawingGroupId() == drawingGroupId && c.getNumShapeIdsUsed() != 1024)
+ {
+ int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
+ c.incrementShapeId();
+ EscherDgRecord dg = getDrawingGroup(drawingGroupId);
+ dg.setNumShapes( dg.getNumShapes() + 1 );
+ dg.setLastMSOSPID( result );
+ if (result >= dgg.getShapeIdMax())
+ dgg.setShapeIdMax( result + 1 );
+ return result;
+ }
+ }
+
+ // Create new cluster
+ dgg.addCluster( drawingGroupId, 0 );
+ dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
+ EscherDgRecord dg = getDrawingGroup(drawingGroupId);
+ dg.setNumShapes( dg.getNumShapes() + 1 );
+ int result = (1024 * dgg.getFileIdClusters().length);
+ dg.setLastMSOSPID( result );
+ if (result >= dgg.getShapeIdMax())
+ dgg.setShapeIdMax( result + 1 );
+ return result;
+ }
+
+ //////////// Non-public methods /////////////
+ short findNewDrawingGroupId()
+ {
+ short dgId = 1;
+ while ( drawingGroupExists( dgId ) )
+ dgId++;
+ return dgId;
+ }
+
+ EscherDgRecord getDrawingGroup(int drawingGroupId)
+ {
+ return (EscherDgRecord) drawingGroups.get(drawingGroupId-1);
+ }
+
+ boolean drawingGroupExists( short dgId )
+ {
+ for ( int i = 0; i < dgg.getFileIdClusters().length; i++ )
+ {
+ if ( dgg.getFileIdClusters()[i].getDrawingGroupId() == dgId )
+ return true;
+ }
+ return false;
+ }
+
+ int findFreeSPIDBlock()
+ {
+ int max = dgg.getShapeIdMax();
+ int next = ( ( max / 1024 ) + 1 ) * 1024;
+ return next;
+ }
+
+ public EscherDggRecord getDgg()
+ {
+ return dgg;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/model/PictureShape.java b/src/java/org/apache/poi/hssf/model/PictureShape.java
new file mode 100644
index 000000000..d17cd0516
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/model/PictureShape.java
@@ -0,0 +1,131 @@
+
+/* ====================================================================
+ Copyright 2002-2004 Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.model;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.usermodel.*;
+
+/**
+ * Represents a picture shape and creates all specific low level records.
+ *
+ * @author Glen Stampoultzis (glens at apache.org)
+ */
+public class PictureShape
+ extends AbstractShape
+{
+ private EscherContainerRecord spContainer;
+ private ObjRecord objRecord;
+
+ /**
+ * Creates the line shape from the highlevel user shape. All low level
+ * records are created at this point.
+ *
+ * @param hssfShape The user model shape.
+ * @param shapeId The identifier to use for this shape.
+ */
+ PictureShape( HSSFSimpleShape hssfShape, int shapeId )
+ {
+ spContainer = createSpContainer(hssfShape, shapeId);
+ objRecord = createObjRecord(hssfShape, shapeId);
+ }
+
+ /**
+ * Creates the lowerlevel escher records for this shape.
+ */
+ private EscherContainerRecord createSpContainer(HSSFSimpleShape hssfShape, int shapeId)
+ {
+ HSSFPicture shape = (HSSFPicture) hssfShape;
+
+ EscherContainerRecord spContainer = new EscherContainerRecord();
+ EscherSpRecord sp = new EscherSpRecord();
+ EscherOptRecord opt = new EscherOptRecord();
+ EscherRecord anchor;
+ EscherClientDataRecord clientData = new EscherClientDataRecord();
+
+ spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER );
+ spContainer.setOptions( (short) 0x000F );
+ sp.setRecordId( EscherSpRecord.RECORD_ID );
+ sp.setOptions( (short) ( (EscherAggregate.ST_PICTUREFRAME << 4) | 0x2 ) );
+
+ sp.setShapeId( shapeId );
+ sp.setFlags( EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE );
+ opt.setRecordId( EscherOptRecord.RECORD_ID );
+// opt.addEscherProperty( new EscherBoolProperty( EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00800080 ) );
+ opt.addEscherProperty( new EscherSimpleProperty( EscherProperties.BLIP__BLIPTODISPLAY, false, true, shape.getPictureIndex() ) );
+// opt.addEscherProperty( new EscherComplexProperty( EscherProperties.BLIP__BLIPFILENAME, true, new byte[] { (byte)0x74, (byte)0x00, (byte)0x65, (byte)0x00, (byte)0x73, (byte)0x00, (byte)0x74, (byte)0x00, (byte)0x00, (byte)0x00 } ) );
+// opt.addEscherProperty( new EscherSimpleProperty( EscherProperties.FILL__FILLTYPE, 0x00000003 ) );
+ addStandardOptions(shape, opt);
+ HSSFAnchor userAnchor = shape.getAnchor();
+ if (userAnchor.isHorizontallyFlipped())
+ sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
+ if (userAnchor.isVerticallyFlipped())
+ sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
+ anchor = createAnchor(userAnchor);
+ clientData.setRecordId( EscherClientDataRecord.RECORD_ID );
+ clientData.setOptions( (short) 0x0000 );
+
+ spContainer.addChildRecord(sp);
+ spContainer.addChildRecord(opt);
+ spContainer.addChildRecord(anchor);
+ spContainer.addChildRecord(clientData);
+
+ return spContainer;
+ }
+
+ /**
+ * Creates the low level OBJ record for this shape.
+ */
+ private ObjRecord createObjRecord(HSSFShape hssfShape, int shapeId)
+ {
+ HSSFShape shape = hssfShape;
+
+ ObjRecord obj = new ObjRecord();
+ CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
+ c.setObjectType((short) ((HSSFSimpleShape)shape).getShapeType());
+// c.setObjectId((short) ( 1 ));
+ c.setObjectId((short) ( shapeId ));
+ c.setLocked(true);
+ c.setPrintable(true);
+ c.setAutofill(true);
+ c.setAutoline(true);
+// c.setReserved2( 0x012C0A84 );
+ c.setReserved2( 0x0 );
+// UnknownRecord sub1 = new UnknownRecord( (short)0x7, (short)0x2, new byte[] { 0x09, 0x00 } );
+// UnknownRecord sub2 = new UnknownRecord( (short)0x8, (short)0x2, new byte[] { 0x01, 0x00 } );
+ EndSubRecord e = new EndSubRecord();
+
+ obj.addSubRecord(c);
+// obj.addSubRecord( sub1 );
+// obj.addSubRecord( sub2 );
+ obj.addSubRecord(e);
+
+ return obj;
+ }
+
+ public EscherContainerRecord getSpContainer()
+ {
+ return spContainer;
+ }
+
+ public ObjRecord getObjRecord()
+ {
+ return objRecord;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
new file mode 100644
index 000000000..7ee394511
--- /dev/null
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
@@ -0,0 +1,39 @@
+package org.apache.poi.hssf.usermodel;
+
+/**
+ * Represents a escher picture. Eg. A GIF, JPEG etc...
+ *
+ * @author Glen Stampoultzis
+ * @version $Id$
+ */
+public class HSSFPicture
+ extends HSSFSimpleShape
+{
+ public static final int PICTURE_TYPE_EMF = 0; // Windows Enhanced Metafile
+ public static final int PICTURE_TYPE_WMF = 1; // Windows Metafile
+ public static final int PICTURE_TYPE_PICT = 2; // Macintosh PICT
+ public static final int PICTURE_TYPE_JPEG = 3; // JFIF
+ public static final int PICTURE_TYPE_PNG = 4; // PNG
+ public static final int PICTURE_TYPE_DIB = 5; // Windows DIB
+
+ int pictureIndex;
+
+ /**
+ * Constructs a picture object.
+ */
+ HSSFPicture( HSSFShape parent, HSSFAnchor anchor )
+ {
+ super( parent, anchor );
+ setShapeType(OBJECT_TYPE_PICTURE);
+ }
+
+ public int getPictureIndex()
+ {
+ return pictureIndex;
+ }
+
+ public void setPictureIndex( int pictureIndex )
+ {
+ this.pictureIndex = pictureIndex;
+ }
+}
diff --git a/src/java/org/apache/poi/util/ArrayUtil.java b/src/java/org/apache/poi/util/ArrayUtil.java
new file mode 100644
index 000000000..a7846ca08
--- /dev/null
+++ b/src/java/org/apache/poi/util/ArrayUtil.java
@@ -0,0 +1,51 @@
+/* ====================================================================
+ Copyright 2003-2004 Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.util;
+
+/**
+ * Utility classes for dealing with arrays.
+ *
+ * @author Glen Stampoultzis
+ * @version $Id$
+ */
+public class ArrayUtil
+{
+ /**
+ * This is really a debugging version of System.arraycopy()
.
+ * Use it to provide better exception messages when copying arrays around.
+ * For production use it's better to use the original for speed.
+ */
+ public static void arraycopy(byte[] src, int src_position, byte[] dst, int dst_position, int length)
+ {
+ if (src_position < 0)
+ throw new IllegalArgumentException("src_position was less than 0. Actual value " + src_position);
+ if (src_position >= src.length)
+ throw new IllegalArgumentException( "src_position was greater than src array size. Tried to write starting at position " + src_position + " but the array length is " + src.length );
+ if (src_position + length > src.length)
+ throw new IllegalArgumentException("src_position + length would overrun the src array. Expected end at " + (src_position + length) + " actual end at " + src.length);
+ if (dst_position < 0)
+ throw new IllegalArgumentException("dst_position was less than 0. Actual value " + dst_position);
+ if (dst_position >= dst.length)
+ throw new IllegalArgumentException( "dst_position was greater than dst array size. Tried to write starting at position " + dst_position + " but the array length is " + dst.length );
+ if (dst_position + length > dst.length)
+ throw new IllegalArgumentException("dst_position + length would overrun the dst array. Expected end at " + (dst_position + length) + " actual end at " + dst.length);
+
+ System.arraycopy( src, src_position, dst, dst_position, length);
+ }
+
+
+}
diff --git a/src/testcases/org/apache/poi/hssf/model/SheetTest.java b/src/testcases/org/apache/poi/hssf/model/SheetTest.java
deleted file mode 100644
index fa58834bb..000000000
--- a/src/testcases/org/apache/poi/hssf/model/SheetTest.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/* ====================================================================
- Copyright 2003-2004 Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.model;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.hssf.record.ColumnInfoRecord;
-import org.apache.poi.hssf.record.MergeCellsRecord;
-import org.apache.poi.hssf.record.PageBreakRecord;
-import org.apache.poi.hssf.record.RowRecord;
-import org.apache.poi.hssf.record.StringRecord;
-
-/**
- * @author Tony Poppleton
- */
-public class SheetTest extends TestCase
-{
- /**
- * Constructor for SheetTest.
- * @param arg0
- */
- public SheetTest(String arg0)
- {
- super(arg0);
- }
-
- public void testAddMergedRegion()
- {
- Sheet sheet = Sheet.createSheet();
- int regionsToAdd = 4096;
- int startRecords = sheet.getRecords().size();
-
- //simple test that adds a load of regions
- for (int n = 0; n < regionsToAdd; n++)
- {
- int index = sheet.addMergedRegion(0, (short) 0, 1, (short) 1);
- assertTrue("Merged region index expected to be " + n + " got " + index, index == n);
- }
-
- //test all the regions were indeed added
- assertTrue(sheet.getNumMergedRegions() == regionsToAdd);
-
- //test that the regions were spread out over the appropriate number of records
- int recordsAdded = sheet.getRecords().size() - startRecords;
- int recordsExpected = regionsToAdd/1027;
- if ((regionsToAdd % 1027) != 0)
- recordsExpected++;
- assertTrue("The " + regionsToAdd + " merged regions should have been spread out over " + recordsExpected + " records, not " + recordsAdded, recordsAdded == recordsExpected);
- }
-
- public void testRemoveMergedRegion()
- {
- Sheet sheet = Sheet.createSheet();
- int regionsToAdd = 4096;
-
- for (int n = 0; n < regionsToAdd; n++)
- sheet.addMergedRegion(0, (short) 0, 1, (short) 1);
-
- int records = sheet.getRecords().size();
-
- //remove a third from the beginning
- for (int n = 0; n < regionsToAdd/3; n++)
- {
- sheet.removeMergedRegion(0);
- //assert they have been deleted
- assertTrue("Num of regions should be " + (regionsToAdd - n - 1) + " not " + sheet.getNumMergedRegions(), sheet.getNumMergedRegions() == regionsToAdd - n - 1);
- }
-
- //assert any record removing was done
- int recordsRemoved = (regionsToAdd/3)/1027; //doesn't work for particular values of regionsToAdd
- assertTrue("Expected " + recordsRemoved + " record to be removed from the starting " + records + ". Currently there are " + sheet.getRecords().size() + " records", records - sheet.getRecords().size() == recordsRemoved);
- }
-
- /**
- * Bug: 22922 (Reported by Xuemin Guan)
- *
- * Remove mergedregion fails when a sheet loses records after an initial CreateSheet - * fills up the records. - * - */ - public void testMovingMergedRegion() { - List records = new ArrayList(); - - MergeCellsRecord merged = new MergeCellsRecord(); - merged.addArea(0, (short)0, 1, (short)2); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(new RowRecord()); - records.add(merged); - - Sheet sheet = Sheet.createSheet(records, 0); - sheet.records.remove(0); - - //stub object to throw off list INDEX operations - sheet.removeMergedRegion(0); - assertEquals("Should be no more merged regions", 0, sheet.getNumMergedRegions()); - } - - public void testGetMergedRegionAt() - { - //TODO - } - - public void testGetNumMergedRegions() - { - //TODO - } - - public void testGetCellWidth() - { - try{ - Sheet sheet = Sheet.createSheet(); - ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo(); - - //prepare test model - nci.setFirstColumn((short)5); - nci.setLastColumn((short)10); - nci.setColumnWidth((short)100); - Field f = Sheet.class.getDeclaredField("columnSizes"); - f.setAccessible(true); - List columnSizes = new ArrayList(); - f.set(sheet,columnSizes); - columnSizes.add(nci); - sheet.records.add(1 + sheet.dimsloc, nci); - sheet.dimsloc++; - - assertEquals((short)100,sheet.getColumnWidth((short)5)); - assertEquals((short)100,sheet.getColumnWidth((short)6)); - assertEquals((short)100,sheet.getColumnWidth((short)7)); - assertEquals((short)100,sheet.getColumnWidth((short)8)); - assertEquals((short)100,sheet.getColumnWidth((short)9)); - assertEquals((short)100,sheet.getColumnWidth((short)10)); - - sheet.setColumnWidth((short)6,(short)200); - - assertEquals((short)100,sheet.getColumnWidth((short)5)); - assertEquals((short)200,sheet.getColumnWidth((short)6)); - assertEquals((short)100,sheet.getColumnWidth((short)7)); - assertEquals((short)100,sheet.getColumnWidth((short)8)); - assertEquals((short)100,sheet.getColumnWidth((short)9)); - assertEquals((short)100,sheet.getColumnWidth((short)10)); - - - } - catch(Exception e){e.printStackTrace();fail(e.getMessage());} - - } - - /** - * Makes sure all rows registered for this sheet are aggregated, they were being skipped - * - */ - public void testRowAggregation() { - List records = new ArrayList(); - RowRecord row = new RowRecord(); - row.setRowNumber(0); - records.add(row); - - row = new RowRecord(); - row.setRowNumber(1); - records.add(row); - - records.add(new StringRecord()); - - row = new RowRecord(); - row.setRowNumber(2); - records.add(row); - - - Sheet sheet = Sheet.createSheet(records, 0); - assertNotNull("Row [2] was skipped", sheet.getRow(2)); - - } - - /** - * Make sure page break functionality works (in memory) - * - */ - public void testRowPageBreaks(){ - short colFrom = 0; - short colTo = 255; - - Sheet sheet = Sheet.createSheet(); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(0, colFrom, colTo); - sheet.setRowBreak(0, colFrom, colTo); - - assertTrue("no row break at 0", sheet.isRowBroken(0)); - assertEquals("1 row break available", 1, sheet.getNumRowBreaks()); - - sheet.setRowBreak(10, colFrom, colTo); - sheet.setRowBreak(11, colFrom, colTo); - - assertTrue("no row break at 10", sheet.isRowBroken(10)); - assertTrue("no row break at 11", sheet.isRowBroken(11)); - assertEquals("3 row break available", 3, sheet.getNumRowBreaks()); - - - boolean is10 = false; - boolean is0 = false; - boolean is11 = false; - - Iterator iterator = sheet.getRowBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 10 && main != 11) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 10) is10= true; - if (main == 11) is11 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is10 && is11); - - sheet.removeRowBreak(11); - assertFalse("row should be removed", sheet.isRowBroken(11)); - - sheet.removeRowBreak(0); - assertFalse("row should be removed", sheet.isRowBroken(0)); - - sheet.removeRowBreak(10); - assertFalse("row should be removed", sheet.isRowBroken(10)); - - assertEquals("no more breaks", 0, sheet.getNumRowBreaks()); - - - } - - /** - * Make sure column pag breaks works properly (in-memory) - * - */ - public void testColPageBreaks(){ - short rowFrom = 0; - short rowTo = (short)65535; - - Sheet sheet = Sheet.createSheet(); - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)0, rowFrom, rowTo); - - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); - assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); - - sheet.setColumnBreak((short)1, rowFrom, rowTo); - sheet.setColumnBreak((short)10, rowFrom, rowTo); - sheet.setColumnBreak((short)15, rowFrom, rowTo); - - assertTrue("no col break at 1", sheet.isColumnBroken((short)1)); - assertTrue("no col break at 10", sheet.isColumnBroken((short)10)); - assertTrue("no col break at 15", sheet.isColumnBroken((short)15)); - assertEquals("4 col break available", 4, sheet.getNumColumnBreaks()); - - boolean is10 = false; - boolean is0 = false; - boolean is1 = false; - boolean is15 = false; - - Iterator iterator = sheet.getColumnBreaks(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int main = (int)breakItem.main; - if (main != 0 && main != 1 && main != 10 && main != 15) fail("Invalid page break"); - if (main == 0) is0 = true; - if (main == 1) is1 = true; - if (main == 10) is10= true; - if (main == 15) is15 = true; - } - - assertTrue("one of the breaks didnt make it", is0 && is1 && is10 && is15); - - sheet.removeColumnBreak((short)15); - assertFalse("column break should not be there", sheet.isColumnBroken((short)15)); - - sheet.removeColumnBreak((short)0); - assertFalse("column break should not be there", sheet.isColumnBroken((short)0)); - - sheet.removeColumnBreak((short)1); - assertFalse("column break should not be there", sheet.isColumnBroken((short)1)); - - sheet.removeColumnBreak((short)10); - assertFalse("column break should not be there", sheet.isColumnBroken((short)10)); - - assertEquals("no more breaks", 0, sheet.getNumColumnBreaks()); - } - -} - - - diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingManager.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingManager.java deleted file mode 100644 index 94fa9b35c..000000000 --- a/src/testcases/org/apache/poi/hssf/model/TestDrawingManager.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ==================================================================== - Copyright 2003-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ -package org.apache.poi.hssf.model; - -import junit.framework.TestCase; -import org.apache.poi.ddf.EscherDggRecord; -import org.apache.poi.ddf.EscherDgRecord; - -public class TestDrawingManager extends TestCase -{ - public void testFindFreeSPIDBlock() throws Exception - { - EscherDggRecord dgg = new EscherDggRecord(); - DrawingManager dm = new DrawingManager( dgg ); - dgg.setShapeIdMax( 1024 ); - assertEquals( 2048, dm.findFreeSPIDBlock() ); - dgg.setShapeIdMax( 1025 ); - assertEquals( 2048, dm.findFreeSPIDBlock() ); - dgg.setShapeIdMax( 2047 ); - assertEquals( 2048, dm.findFreeSPIDBlock() ); - } - - public void testFindNewDrawingGroupId() throws Exception - { - EscherDggRecord dgg = new EscherDggRecord(); - dgg.setDrawingsSaved( 1 ); - dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[]{ - new EscherDggRecord.FileIdCluster( 2, 10 )} ); - DrawingManager dm = new DrawingManager( dgg ); - assertEquals( 1, dm.findNewDrawingGroupId() ); - dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[]{ - new EscherDggRecord.FileIdCluster( 1, 10 ), - new EscherDggRecord.FileIdCluster( 2, 10 )} ); - assertEquals( 3, dm.findNewDrawingGroupId() ); - } - - public void testDrawingGroupExists() throws Exception - { - EscherDggRecord dgg = new EscherDggRecord(); - dgg.setDrawingsSaved( 1 ); - dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[]{ - new EscherDggRecord.FileIdCluster( 2, 10 )} ); - DrawingManager dm = new DrawingManager( dgg ); - assertFalse( dm.drawingGroupExists( (short) 1 ) ); - assertTrue( dm.drawingGroupExists( (short) 2 ) ); - assertFalse( dm.drawingGroupExists( (short) 3 ) ); - } - - public void testCreateDgRecord() throws Exception - { - EscherDggRecord dgg = new EscherDggRecord(); - dgg.setDrawingsSaved( 0 ); - dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[]{} ); - DrawingManager dm = new DrawingManager( dgg ); - - EscherDgRecord dgRecord = dm.createDgRecord(); - assertEquals( -1, dgRecord.getLastMSOSPID() ); - assertEquals( 0, dgRecord.getNumShapes() ); - assertEquals( 1, dm.getDgg().getDrawingsSaved() ); - assertEquals( 1, dm.getDgg().getFileIdClusters().length ); - assertEquals( 1, dm.getDgg().getFileIdClusters()[0].getDrawingGroupId() ); - assertEquals( 0, dm.getDgg().getFileIdClusters()[0].getNumShapeIdsUsed() ); - } - - public void testAllocateShapeId() throws Exception - { - EscherDggRecord dgg = new EscherDggRecord(); - dgg.setDrawingsSaved( 0 ); - dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[]{} ); - DrawingManager dm = new DrawingManager( dgg ); - - EscherDgRecord dg = dm.createDgRecord(); - int shapeId = dm.allocateShapeId( dg.getDrawingGroupId() ); - assertEquals( 1024, shapeId ); - assertEquals( 1025, dgg.getShapeIdMax() ); - assertEquals( 1, dgg.getDrawingsSaved() ); - assertEquals( 1, dgg.getFileIdClusters()[0].getDrawingGroupId() ); - assertEquals( 1, dgg.getFileIdClusters()[0].getNumShapeIdsUsed() ); - assertEquals( 1024, dg.getLastMSOSPID() ); - assertEquals( 1, dg.getNumShapes() ); - } - -} diff --git a/src/testcases/org/apache/poi/hssf/model/TestDrawingManager2.java b/src/testcases/org/apache/poi/hssf/model/TestDrawingManager2.java new file mode 100644 index 000000000..3fbd933e7 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/model/TestDrawingManager2.java @@ -0,0 +1,66 @@ +package org.apache.poi.hssf.model; + +import junit.framework.TestCase; +import org.apache.poi.ddf.EscherDggRecord; +import org.apache.poi.ddf.EscherDgRecord; + +public class TestDrawingManager2 extends TestCase +{ + private DrawingManager2 drawingManager2; + private EscherDggRecord dgg; + + protected void setUp() throws Exception + { + super.setUp(); + dgg = new EscherDggRecord(); + dgg.setFileIdClusters( new EscherDggRecord.FileIdCluster[0] ); + drawingManager2 = new DrawingManager2( dgg ); + } + + public void testCreateDgRecord() throws Exception + { + EscherDgRecord dgRecord1 = drawingManager2.createDgRecord(); + assertEquals( 1, dgRecord1.getDrawingGroupId() ); + assertEquals( -1, dgRecord1.getLastMSOSPID() ); + + EscherDgRecord dgRecord2 = drawingManager2.createDgRecord(); + assertEquals( 2, dgRecord2.getDrawingGroupId() ); + assertEquals( -1, dgRecord2.getLastMSOSPID() ); + + assertEquals( 2, dgg.getDrawingsSaved( ) ); + assertEquals( 2, dgg.getFileIdClusters().length ); + assertEquals( 3, dgg.getNumIdClusters() ); + assertEquals( 0, dgg.getNumShapesSaved() ); + } + + public void testAllocateShapeId() throws Exception + { + EscherDgRecord dgRecord1 = drawingManager2.createDgRecord(); + EscherDgRecord dgRecord2 = drawingManager2.createDgRecord(); + + assertEquals( 1024, drawingManager2.allocateShapeId( (short)1 ) ); + assertEquals( 1024, dgRecord1.getLastMSOSPID() ); + assertEquals( 1025, dgg.getShapeIdMax() ); + assertEquals( 1025, drawingManager2.allocateShapeId( (short)1 ) ); + assertEquals( 1025, dgRecord1.getLastMSOSPID() ); + assertEquals( 1026, dgg.getShapeIdMax() ); + assertEquals( 1026, drawingManager2.allocateShapeId( (short)1 ) ); + assertEquals( 1026, dgRecord1.getLastMSOSPID() ); + assertEquals( 1027, dgg.getShapeIdMax() ); + assertEquals( 2048, drawingManager2.allocateShapeId( (short)2 ) ); + assertEquals( 2048, dgRecord2.getLastMSOSPID() ); + assertEquals( 2049, dgg.getShapeIdMax() ); + + for (int i = 0; i < 1021; i++) + { + drawingManager2.allocateShapeId( (short)1 ); + assertEquals( 2049, dgg.getShapeIdMax() ); + } + assertEquals( 3072, drawingManager2.allocateShapeId( (short) 1 ) ); + assertEquals( 3073, dgg.getShapeIdMax() ); + + assertEquals( 2, dgg.getDrawingsSaved() ); + assertEquals( 4, dgg.getNumIdClusters() ); + assertEquals( 1026, dgg.getNumShapesSaved() ); + } +} \ No newline at end of file diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestColumnInfoRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestColumnInfoRecordsAggregate.java new file mode 100644 index 000000000..6d841e669 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestColumnInfoRecordsAggregate.java @@ -0,0 +1,59 @@ +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.aggregates; + +import junit.framework.TestCase; +import org.apache.poi.hssf.record.ColumnInfoRecord; + +/** + * @author Glen Stampoultzis + */ +public class TestColumnInfoRecordsAggregate extends TestCase +{ + ColumnInfoRecordsAggregate columnInfoRecordsAggregate; + + public void testGetRecordSize() throws Exception + { + columnInfoRecordsAggregate = new ColumnInfoRecordsAggregate(); + columnInfoRecordsAggregate.insertColumn( createColumn( (short)1, (short)3 )); + columnInfoRecordsAggregate.insertColumn( createColumn( (short)4, (short)7 )); + columnInfoRecordsAggregate.insertColumn( createColumn( (short)8, (short)8 )); +// columnInfoRecordsAggregate.setColumn( (short)2, new Short( (short)200 ), new Integer( 1 ), new Boolean( true ), null); + columnInfoRecordsAggregate.groupColumnRange( (short)2, (short)5, true ); + System.out.println( "columnInfoRecordsAggregate = " + columnInfoRecordsAggregate.getNumColumns() ); + + assertEquals(columnInfoRecordsAggregate.getRecordSize(), columnInfoRecordsAggregate.serialize().length); + + columnInfoRecordsAggregate = new ColumnInfoRecordsAggregate(); + columnInfoRecordsAggregate.groupColumnRange( (short)3, (short)6, true ); + + assertEquals(columnInfoRecordsAggregate.getRecordSize(), serializedSize()); + } + + private int serializedSize() + { + return columnInfoRecordsAggregate.serialize(0, new byte[columnInfoRecordsAggregate.getRecordSize()]); + } + + private ColumnInfoRecord createColumn( short firstCol, short lastCol ) + { + ColumnInfoRecord columnInfoRecord = new ColumnInfoRecord( ); + columnInfoRecord.setFirstColumn(firstCol); + columnInfoRecord.setLastColumn(lastCol); + return columnInfoRecord; + } +} \ No newline at end of file