aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlen Stampoultzis <glens@apache.org>2005-05-01 11:26:18 +0000
committerGlen Stampoultzis <glens@apache.org>2005-05-01 11:26:18 +0000
commit585f86a986ea2d6f23a61ce6c552fc0f6194798f (patch)
tree881e2b617dbbfaaa025a322d224b7c62b8e0e32d /src
parent3c991cfc7a0e09e5ee0b11fd8ad401aabbaf32fd (diff)
downloadpoi-585f86a986ea2d6f23a61ce6c552fc0f6194798f.tar.gz
poi-585f86a986ea2d6f23a61ce6c552fc0f6194798f.zip
Added image support for POI. See the quick guide for details. Sponsored through superlink software.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353660 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/hssf/quick-guide.xml56
-rw-r--r--src/documentation/content/xdocs/status.xml1
-rw-r--r--src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java53
-rw-r--r--src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java12
-rw-r--r--src/java/org/apache/poi/ddf/EscherBSERecord.java63
-rw-r--r--src/java/org/apache/poi/ddf/EscherBlipRecord.java358
-rw-r--r--src/java/org/apache/poi/ddf/EscherBlipWMFRecord.java435
-rw-r--r--src/java/org/apache/poi/ddf/EscherBoolProperty.java4
-rw-r--r--src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java2
-rw-r--r--src/java/org/apache/poi/ddf/EscherClientDataRecord.java2
-rw-r--r--src/java/org/apache/poi/ddf/EscherDggRecord.java11
-rw-r--r--src/java/org/apache/poi/ddf/EscherProperty.java2
-rw-r--r--src/java/org/apache/poi/ddf/EscherPropertyFactory.java18
-rw-r--r--src/java/org/apache/poi/ddf/EscherRGBProperty.java2
-rw-r--r--src/java/org/apache/poi/ddf/EscherSimpleProperty.java1
-rw-r--r--src/java/org/apache/poi/hssf/dev/BiffViewer.java59
-rw-r--r--src/java/org/apache/poi/hssf/model/AbstractShape.java5
-rw-r--r--src/java/org/apache/poi/hssf/model/ConvertAnchor.java2
-rw-r--r--src/java/org/apache/poi/hssf/model/Sheet.java30
-rw-r--r--src/java/org/apache/poi/hssf/model/Workbook.java88
-rw-r--r--src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java74
-rw-r--r--src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java100
-rw-r--r--src/java/org/apache/poi/hssf/record/DrawingRecord.java8
-rw-r--r--src/java/org/apache/poi/hssf/record/EscherAggregate.java13
-rw-r--r--src/java/org/apache/poi/hssf/record/ObjRecord.java8
-rw-r--r--src/java/org/apache/poi/hssf/record/RecordFactory.java18
-rw-r--r--src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java7
-rw-r--r--src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java2
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java24
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java17
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java11
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java4
-rw-r--r--src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java94
-rw-r--r--src/java/org/apache/poi/util/DrawingDump.java15
-rw-r--r--src/java/org/apache/poi/util/HexDump.java2
-rw-r--r--src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java3
-rw-r--r--src/testcases/org/apache/poi/ddf/TestEscherBlipWMFRecord.java (renamed from src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java)14
-rw-r--r--src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java2
-rw-r--r--src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java2
-rw-r--r--src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java2
-rw-r--r--src/testcases/org/apache/poi/hssf/model/TestSheet.java238
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestDrawingGroupRecord.java91
-rw-r--r--src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java13
-rw-r--r--src/testcases/org/apache/poi/util/TestHexDump.java6
-rw-r--r--src/testcases/org/apache/poi/util/TestLittleEndian.java8
45 files changed, 1491 insertions, 489 deletions
diff --git a/src/documentation/content/xdocs/hssf/quick-guide.xml b/src/documentation/content/xdocs/hssf/quick-guide.xml
index 3ea0ad8afd..d4ecc43116 100644
--- a/src/documentation/content/xdocs/hssf/quick-guide.xml
+++ b/src/documentation/content/xdocs/hssf/quick-guide.xml
@@ -31,20 +31,21 @@
<li><link href="#CustomColors">Custom colors</link></li>
<li><link href="#ReadWriteWorkbook">Reading and writing</link></li>
<li><link href="#NewLinesInCells">Use newlines in cells.</link></li>
- <li><link href="#DataFormats">Create user defined data formats.</link></li>
+ <li><link href="#DataFormats">Create user defined data formats</link></li>
<li><link href="#FitTo">Fit Sheet to One Page</link></li>
- <li><link href="#PrintArea2">Set print area for a sheet.</link></li>
- <li><link href="#FooterPageNumbers">Set page numbers on the footer of a sheet.</link></li>
- <li><link href="#ShiftRows">Shift rows.</link></li>
- <li><link href="#SelectSheet">Set a sheet as selected.</link></li>
- <li><link href="#Zoom">Set the zoom magnification for a sheet.</link></li>
- <li><link href="#Splits">Create split and freeze panes.</link></li>
- <li><link href="#Repeating">Repeating rows and columns.</link></li>
- <li><link href="#HeaderFooter">Headers and Footers.</link></li>
- <li><link href="#DrawingShapes">Drawing Shapes.</link></li>
- <li><link href="#StylingShapes">Styling Shapes.</link></li>
- <li><link href="#Graphics2d">Shapes and Graphics2d.</link></li>
- <li><link href="#Outlining">Outlining.</link></li>
+ <li><link href="#PrintArea2">Set print area for a sheet</link></li>
+ <li><link href="#FooterPageNumbers">Set page numbers on the footer of a sheet</link></li>
+ <li><link href="#ShiftRows">Shift rows</link></li>
+ <li><link href="#SelectSheet">Set a sheet as selected</link></li>
+ <li><link href="#Zoom">Set the zoom magnification for a sheet</link></li>
+ <li><link href="#Splits">Create split and freeze panes</link></li>
+ <li><link href="#Repeating">Repeating rows and columns</link></li>
+ <li><link href="#HeaderFooter">Headers and Footers</link></li>
+ <li><link href="#DrawingShapes">Drawing Shapes</link></li>
+ <li><link href="#StylingShapes">Styling Shapes</link></li>
+ <li><link href="#Graphics2d">Shapes and Graphics2d</link></li>
+ <li><link href="#Outlining">Outlining</link></li>
+ <li><link href="#Images">Images</link></li>
</ul>
</section>
<section><title>Features</title>
@@ -940,5 +941,34 @@
</section>
</section>
</section>
+ <anchor id="Images"/>
+ <section>
+ <title>Images</title>
+ <p>
+ Images are part of the drawing support. To add an image just
+ call <code>createPicture()</code> on the drawing patriarch.
+ At the time of writing the following types are supported:
+ </p>
+ <ul>
+ <li>PNG</li>
+ <li>JPG</li>
+ <li>DIB</li>
+ </ul>
+ <p>
+ It is not currently possible to read existing images and it
+ should be noted that any existing drawings may be erased
+ once you add a image to a sheet.
+ </p>
+ <source>
+ // Create the drawing patriarch. This is the top level container for
+ // all shapes. This will clear out any existing shapes for that sheet.
+ HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
+
+ HSSFClientAnchor anchor;
+ anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7);
+ anchor.setAnchorType( 2 );
+ patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
+ </source>
+ </section>
</body>
</document>
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 8f4ffbf828..4a87113c90 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -14,6 +14,7 @@
<release version="unreleased" date="???">
<action dev="POI-DEVELOPERS" type="fix" context="All">Bugzilla Bug 29976 [PATCH] HSSF hyperlink formula size problem</action>
+ <action dev="POI-DEVELOPERS" type="add" context="All">Image writing support</action>
</release>
<release version="2.5.1-FINAL" date="29 Feburary 2004">
diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java
index e6520a0a15..693b78235d 100644
--- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java
+++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/OfficeDrawing.java
@@ -19,9 +19,7 @@ package org.apache.poi.hssf.usermodel.examples;
import org.apache.poi.hssf.usermodel.*;
-import java.io.IOException;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
+import java.io.*;
/**
* Demonstrates how to use the office drawing capabilities of POI.
@@ -39,12 +37,14 @@ public class OfficeDrawing
HSSFSheet sheet2 = wb.createSheet("second sheet");
HSSFSheet sheet3 = wb.createSheet("third sheet");
HSSFSheet sheet4 = wb.createSheet("fourth sheet");
+ HSSFSheet sheet5 = wb.createSheet("fifth sheet");
// Draw stuff in them
drawSheet1( sheet1 );
drawSheet2( sheet2 );
drawSheet3( sheet3 );
drawSheet4( sheet4, wb );
+ drawSheet5( sheet5, wb );
// Write the file out.
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
@@ -143,6 +143,53 @@ public class OfficeDrawing
textbox3.setNoFill(true); // make it transparent
}
+ private static void drawSheet5( HSSFSheet sheet5, HSSFWorkbook wb ) throws IOException
+ {
+
+ // Create the drawing patriarch. This is the top level container for
+ // all shapes. This will clear out any existing shapes for that sheet.
+ HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
+
+ HSSFClientAnchor anchor;
+ anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7);
+ anchor.setAnchorType( 2 );
+ patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
+
+ anchor = new HSSFClientAnchor(0,0,0,255,(short)4,2,(short)5,7);
+ anchor.setAnchorType( 2 );
+ patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4edited.png", wb ));
+
+ anchor = new HSSFClientAnchor(0,0,1023,255,(short)6,2,(short)8,7);
+ anchor.setAnchorType( 2 );
+ HSSFPicture picture = patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4s.png", wb ));
+ picture.setLineStyle( picture.LINESTYLE_DASHDOTGEL );
+
+ }
+
+ private static int loadPicture( String path, HSSFWorkbook wb ) throws IOException
+ {
+ int pictureIndex;
+ FileInputStream fis = null;
+ ByteArrayOutputStream bos = null;
+ try
+ {
+ fis = new FileInputStream( path);
+ bos = new ByteArrayOutputStream( );
+ int c;
+ while ( (c = fis.read()) != -1)
+ bos.write( c );
+ pictureIndex = wb.addPicture( bos.toByteArray(), HSSFWorkbook.PICTURE_TYPE_PNG );
+ }
+ finally
+ {
+ if (fis != null)
+ fis.close();
+ if (bos != null)
+ bos.close();
+ }
+ return pictureIndex;
+ }
+
private static void drawOval( HSSFPatriarch patriarch )
{
// Create an oval and style to taste.
diff --git a/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java b/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java
index 69076710a1..1aa9c6ee7f 100644
--- a/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java
+++ b/src/java/org/apache/poi/ddf/DefaultEscherRecordFactory.java
@@ -66,7 +66,17 @@ public class DefaultEscherRecordFactory
}
else if ( header.getRecordId() >= EscherBlipRecord.RECORD_ID_START && header.getRecordId() <= EscherBlipRecord.RECORD_ID_END )
{
- EscherBlipRecord r = new EscherBlipRecord();
+ EscherBlipRecord r;
+ if (header.getRecordId() == EscherBitmapBlip.RECORD_ID_DIB ||
+ header.getRecordId() == EscherBitmapBlip.RECORD_ID_JPEG ||
+ header.getRecordId() == EscherBitmapBlip.RECORD_ID_PNG)
+ {
+ r = new EscherBitmapBlip();
+ }
+ else
+ {
+ r = new EscherBlipRecord();
+ }
r.setRecordId( header.getRecordId() );
r.setOptions( header.getOptions() );
return r;
diff --git a/src/java/org/apache/poi/ddf/EscherBSERecord.java b/src/java/org/apache/poi/ddf/EscherBSERecord.java
index 42504954ed..b8165ba0be 100644
--- a/src/java/org/apache/poi/ddf/EscherBSERecord.java
+++ b/src/java/org/apache/poi/ddf/EscherBSERecord.java
@@ -17,15 +17,15 @@
package org.apache.poi.ddf;
-import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
/**
* The BSE record is related closely to the <code>EscherBlipRecord</code> and stores
- * extra information about the blip.
+ * extra information about the blip. A blip record is actually stored inside
+ * the BSE record even though the BSE record isn't actually a container record.
*
* @author Glen Stampoultzis
* @see EscherBlipRecord
@@ -56,6 +56,7 @@ public class EscherBSERecord
private byte field_9_name;
private byte field_10_unused2;
private byte field_11_unused3;
+ private EscherBlipRecord field_12_blipRecord;
private byte[] remainingData;
@@ -85,9 +86,28 @@ public class EscherBSERecord
field_10_unused2 = data[pos + 34];
field_11_unused3 = data[pos + 35];
bytesRemaining -= 36;
+ int bytesRead = 0;
+ if (bytesRemaining > 0)
+ {
+ field_12_blipRecord = (EscherBlipRecord) recordFactory.createRecord( data, pos + 36 );
+ bytesRead = field_12_blipRecord.fillFields( data, pos + 36, recordFactory );
+ }
+ pos += 36 + bytesRead;
+ bytesRemaining -= bytesRead;
+// if (field_1_blipTypeWin32 == BT_PNG)
+// {
+// byte[] uid = new byte[16];
+// System.arraycopy( data, pos + 36, uid, 0, 16 );
+// byte[] puid = new byte[16];
+// System.arraycopy( data, pos + 52, puid, 0, 16 );
+// byte tag = data[pos+68];
+// System.out.println( HexDump.dump( data, 0, 0 ) );
+// byte[] pngBytes = EscherBlipRecord.decompress( data, pos+69, bytesRemaining);
+// }
+
remainingData = new byte[bytesRemaining];
- System.arraycopy( data, pos + 36, remainingData, 0, bytesRemaining );
- return bytesRemaining + 8 + 36;
+ System.arraycopy( data, pos, remainingData, 0, bytesRemaining );
+ return bytesRemaining + 8 + 36 + (field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize()) ;
}
@@ -104,9 +124,14 @@ public class EscherBSERecord
{
listener.beforeRecordSerialize( offset, getRecordId(), this );
+ if (remainingData == null)
+ remainingData = new byte[0];
+
LittleEndian.putShort( data, offset, getOptions() );
LittleEndian.putShort( data, offset + 2, getRecordId() );
- int remainingBytes = remainingData.length + 36;
+ if (remainingData == null) remainingData = new byte[0];
+ int blipSize = field_12_blipRecord == null ? 0 : field_12_blipRecord.getRecordSize();
+ int remainingBytes = remainingData.length + 36 + blipSize;
LittleEndian.putInt( data, offset + 4, remainingBytes );
data[offset + 8] = field_1_blipTypeWin32;
@@ -121,8 +146,15 @@ public class EscherBSERecord
data[offset + 41] = field_9_name;
data[offset + 42] = field_10_unused2;
data[offset + 43] = field_11_unused3;
- System.arraycopy( remainingData, 0, data, offset + 44, remainingData.length );
- int pos = offset + 8 + 36 + remainingData.length;
+ int bytesWritten = 0;
+ if (field_12_blipRecord != null)
+ {
+ bytesWritten = field_12_blipRecord.serialize( offset + 44, data, new NullEscherSerializationListener() );
+ }
+ if (remainingData == null)
+ remainingData = new byte[0];
+ System.arraycopy( remainingData, 0, data, offset + 44 + bytesWritten, remainingData.length );
+ int pos = offset + 8 + 36 + remainingData.length + bytesWritten;
listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this);
return pos - offset;
@@ -135,7 +167,7 @@ public class EscherBSERecord
*/
public int getRecordSize()
{
- return 8 + 1 + 1 + 16 + 2 + 4 + 4 + 4 + 1 + 1 + 1 + 1 + remainingData.length;
+ return 8 + 1 + 1 + 16 + 2 + 4 + 4 + 4 + 1 + 1 + 1 + 1 + field_12_blipRecord.getRecordSize() + (remainingData == null ? 0 : remainingData.length);
}
/**
@@ -312,6 +344,16 @@ public class EscherBSERecord
this.field_11_unused3 = unused3;
}
+ public EscherBlipRecord getBlipRecord()
+ {
+ return field_12_blipRecord;
+ }
+
+ public void setBlipRecord( EscherBlipRecord field_12_blipRecord )
+ {
+ this.field_12_blipRecord = field_12_blipRecord;
+ }
+
/**
* Any remaining data in this record.
*/
@@ -360,9 +402,8 @@ public class EscherBSERecord
" Name: " + field_9_name + nl +
" Unused2: " + field_10_unused2 + nl +
" Unused3: " + field_11_unused3 + nl +
+ " blipRecord: " + field_12_blipRecord + nl +
" Extra Data:" + nl + extraData;
-
-
}
/**
diff --git a/src/java/org/apache/poi/ddf/EscherBlipRecord.java b/src/java/org/apache/poi/ddf/EscherBlipRecord.java
index dc000887d6..43d90141a9 100644
--- a/src/java/org/apache/poi/ddf/EscherBlipRecord.java
+++ b/src/java/org/apache/poi/ddf/EscherBlipRecord.java
@@ -17,24 +17,14 @@
package org.apache.poi.ddf;
-import org.apache.poi.hssf.record.RecordFormatException;
-import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.HexDump;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.zip.InflaterInputStream;
-import java.util.zip.DeflaterOutputStream;
/**
- * The blip record is used to hold details about large binary objects that occur in escher such
- * as JPEG, GIF, PICT and WMF files. The contents of the stream is usually compressed. Inflate
- * can be used to decompress the data.
- *
* @author Glen Stampoultzis
- * @see java.util.zip.Inflater
+ * @version $Id$
*/
public class EscherBlipRecord
extends EscherRecord
@@ -42,21 +32,14 @@ public class EscherBlipRecord
public static final short RECORD_ID_START = (short) 0xF018;
public static final short RECORD_ID_END = (short) 0xF117;
public static final String RECORD_DESCRIPTION = "msofbtBlip";
+
private static final int HEADER_SIZE = 8;
- private byte[] field_1_secondaryUID;
- private int field_2_cacheOfSize;
- private int field_3_boundaryTop;
- private int field_4_boundaryLeft;
- private int field_5_boundaryWidth;
- private int field_6_boundaryHeight;
- private int field_7_width;
- private int field_8_height;
- private int field_9_cacheOfSavedSize;
- private byte field_10_compressionFlag;
- private byte field_11_filter;
- private byte[] field_12_data;
+ protected byte[] field_pictureData;
+ public EscherBlipRecord()
+ {
+ }
/**
* This method deserializes the record from a byte array.
@@ -66,44 +49,27 @@ public class EscherBlipRecord
* @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
- )
+ public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory )
{
int bytesAfterHeader = readHeader( data, offset );
int pos = offset + HEADER_SIZE;
- int size = 0;
- field_1_secondaryUID = new byte[16];
- System.arraycopy( data, pos + size, field_1_secondaryUID, 0, 16 ); size += 16;
- field_2_cacheOfSize = LittleEndian.getInt( data, pos + size );size+=4;
- field_3_boundaryTop = LittleEndian.getInt( data, pos + size );size+=4;
- field_4_boundaryLeft = LittleEndian.getInt( data, pos + size );size+=4;
- field_5_boundaryWidth = LittleEndian.getInt( data, pos + size );size+=4;
- field_6_boundaryHeight = LittleEndian.getInt( data, pos + size );size+=4;
- field_7_width = LittleEndian.getInt( data, pos + size );size+=4;
- field_8_height = LittleEndian.getInt( data, pos + size );size+=4;
- field_9_cacheOfSavedSize = LittleEndian.getInt( data, pos + size );size+=4;
- field_10_compressionFlag = data[pos + size]; size++;
- field_11_filter = data[pos + size]; size++;
+ field_pictureData = new byte[bytesAfterHeader];
+ System.arraycopy(data, pos, field_pictureData, 0, bytesAfterHeader);
- int bytesRemaining = bytesAfterHeader - size;
- field_12_data = new byte[bytesRemaining];
- System.arraycopy(data, pos + size, field_12_data, 0, bytesRemaining);
-
- return bytesRemaining + HEADER_SIZE + bytesAfterHeader;
+ return bytesAfterHeader + 8;
}
-
/**
- * This method serializes this escher record into a byte array.
- *
- * @param offset The offset into <code>data</code> to start writing the record data to.
- * @param data The byte array to serialize to.
- * @param listener A listener to retrieve start and end callbacks. Use a <code>NullEscherSerailizationListener</code> to ignore these events.
- * @return The number of bytes written.
+ * Serializes the record to an existing byte array.
*
- * @see NullEscherSerializationListener
+ * @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 )
{
@@ -111,25 +77,11 @@ public class EscherBlipRecord
LittleEndian.putShort( data, offset, getOptions() );
LittleEndian.putShort( data, offset + 2, getRecordId() );
- int remainingBytes = field_12_data.length + 36;
- LittleEndian.putInt( data, offset + 4, remainingBytes );
- int pos = offset + HEADER_SIZE;
- System.arraycopy(field_1_secondaryUID, 0, data, pos, 16 ); pos += 16;
- LittleEndian.putInt( data, pos, field_2_cacheOfSize); pos += 4;
- LittleEndian.putInt( data, pos, field_3_boundaryTop); pos += 4;
- LittleEndian.putInt( data, pos, field_4_boundaryLeft); pos += 4;
- LittleEndian.putInt( data, pos, field_5_boundaryWidth); pos += 4;
- LittleEndian.putInt( data, pos, field_6_boundaryHeight); pos += 4;
- LittleEndian.putInt( data, pos, field_7_width); pos += 4;
- LittleEndian.putInt( data, pos, field_8_height); pos += 4;
- LittleEndian.putInt( data, pos, field_9_cacheOfSavedSize); pos += 4;
- data[pos++] = field_10_compressionFlag;
- data[pos++] = field_11_filter;
- System.arraycopy(field_12_data, 0, data, pos, field_12_data.length); pos += field_12_data.length;
+ System.arraycopy( field_pictureData, 0, data, offset + 4, field_pictureData.length );
- listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this);
- return pos - offset;
+ listener.afterRecordSerialize(offset + 4 + field_pictureData.length, getRecordId(), field_pictureData.length + 4, this);
+ return field_pictureData.length + 4;
}
/**
@@ -139,7 +91,7 @@ public class EscherBlipRecord
*/
public int getRecordSize()
{
- return 58 + field_12_data.length;
+ return field_pictureData.length + 4;
}
/**
@@ -150,203 +102,6 @@ public class EscherBlipRecord
return "Blip";
}
- /**
- * Retrieve the secondary UID
- */
- public byte[] getSecondaryUID()
- {
- return field_1_secondaryUID;
- }
-
- /**
- * Set the secondary UID
- */
- public void setSecondaryUID( byte[] field_1_secondaryUID )
- {
- this.field_1_secondaryUID = field_1_secondaryUID;
- }
-
- /**
- * Retrieve the cache of the metafile size
- */
- public int getCacheOfSize()
- {
- return field_2_cacheOfSize;
- }
-
- /**
- * Set the cache of the metafile size
- */
- public void setCacheOfSize( int field_2_cacheOfSize )
- {
- this.field_2_cacheOfSize = field_2_cacheOfSize;
- }
-
- /**
- * Retrieve the top boundary of the metafile drawing commands
- */
- public int getBoundaryTop()
- {
- return field_3_boundaryTop;
- }
-
- /**
- * Set the top boundary of the metafile drawing commands
- */
- public void setBoundaryTop( int field_3_boundaryTop )
- {
- this.field_3_boundaryTop = field_3_boundaryTop;
- }
-
- /**
- * Retrieve the left boundary of the metafile drawing commands
- */
- public int getBoundaryLeft()
- {
- return field_4_boundaryLeft;
- }
-
- /**
- * Set the left boundary of the metafile drawing commands
- */
- public void setBoundaryLeft( int field_4_boundaryLeft )
- {
- this.field_4_boundaryLeft = field_4_boundaryLeft;
- }
-
- /**
- * Retrieve the boundary width of the metafile drawing commands
- */
- public int getBoundaryWidth()
- {
- return field_5_boundaryWidth;
- }
-
- /**
- * Set the boundary width of the metafile drawing commands
- */
- public void setBoundaryWidth( int field_5_boundaryWidth )
- {
- this.field_5_boundaryWidth = field_5_boundaryWidth;
- }
-
- /**
- * Retrieve the boundary height of the metafile drawing commands
- */
- public int getBoundaryHeight()
- {
- return field_6_boundaryHeight;
- }
-
- /**
- * Set the boundary height of the metafile drawing commands
- */
- public void setBoundaryHeight( int field_6_boundaryHeight )
- {
- this.field_6_boundaryHeight = field_6_boundaryHeight;
- }
-
- /**
- * Retrieve the width of the metafile in EMU's (English Metric Units).
- */
- public int getWidth()
- {
- return field_7_width;
- }
-
- /**
- * Set the width of the metafile in EMU's (English Metric Units).
- */
- public void setWidth( int width )
- {
- this.field_7_width = width;
- }
-
- /**
- * Retrieve the height of the metafile in EMU's (English Metric Units).
- */
- public int getHeight()
- {
- return field_8_height;
- }
-
- /**
- * Set the height of the metafile in EMU's (English Metric Units).
- */
- public void setHeight( int height )
- {
- this.field_8_height = height;
- }
-
- /**
- * Retrieve the cache of the saved size
- */
- public int getCacheOfSavedSize()
- {
- return field_9_cacheOfSavedSize;
- }
-
- /**
- * Set the cache of the saved size
- */
- public void setCacheOfSavedSize( int field_9_cacheOfSavedSize )
- {
- this.field_9_cacheOfSavedSize = field_9_cacheOfSavedSize;
- }
-
- /**
- * Is the contents of the blip compressed?
- */
- public byte getCompressionFlag()
- {
- return field_10_compressionFlag;
- }
-
- /**
- * Set whether the contents of the blip is compressed
- */
- public void setCompressionFlag( byte field_10_compressionFlag )
- {
- this.field_10_compressionFlag = field_10_compressionFlag;
- }
-
- /**
- * Filter should always be 0
- */
- public byte getFilter()
- {
- return field_11_filter;
- }
-
- /**
- * Filter should always be 0
- */
- public void setFilter( byte field_11_filter )
- {
- this.field_11_filter = field_11_filter;
- }
-
- /**
- * The BLIP data
- */
- public byte[] getData()
- {
- return field_12_data;
- }
-
- /**
- * The BLIP data
- */
- public void setData( byte[] field_12_data )
- {
- this.field_12_data = field_12_data;
- }
-
- /**
- * The string representation of this record.
- *
- * @return A string
- */
public String toString()
{
String nl = System.getProperty( "line.separator" );
@@ -355,7 +110,7 @@ public class EscherBlipRecord
ByteArrayOutputStream b = new ByteArrayOutputStream();
try
{
- HexDump.dump( this.field_12_data, 0, b, 0 );
+ HexDump.dump( this.field_pictureData, 0, b, 0 );
extraData = b.toString();
}
catch ( Exception e )
@@ -365,70 +120,7 @@ public class EscherBlipRecord
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
" Options: 0x" + HexDump.toHex( getOptions() ) + nl +
- " Secondary UID: " + HexDump.toHex( field_1_secondaryUID ) + nl +
- " CacheOfSize: " + field_2_cacheOfSize + nl +
- " BoundaryTop: " + field_3_boundaryTop + nl +
- " BoundaryLeft: " + field_4_boundaryLeft + nl +
- " BoundaryWidth: " + field_5_boundaryWidth + nl +
- " BoundaryHeight: " + field_6_boundaryHeight + nl +
- " X: " + field_7_width + nl +
- " Y: " + field_8_height + nl +
- " CacheOfSavedSize: " + field_9_cacheOfSavedSize + nl +
- " CompressionFlag: " + field_10_compressionFlag + nl +
- " Filter: " + field_11_filter + nl +
- " Data:" + nl + extraData;
- }
-
- /**
- * Compress the contents of the provided array
- *
- * @param data An uncompressed byte array
- * @see DeflaterOutputStream#write(int b)
- */
- public static byte[] compress( byte[] data )
- {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream( out );
- try
- {
- for ( int i = 0; i < data.length; i++ )
- deflaterOutputStream.write( data[i] );
- }
- catch ( IOException e )
- {
- throw new RecordFormatException( e.toString() );
- }
+ " Extra Data:" + nl + extraData;
- return out.toByteArray();
}
-
- /**
- * Decompresses a byte array.
- *
- * @param data The compressed byte array
- * @param pos The starting position into the byte array
- * @param length The number of compressed bytes to decompress
- * @return An uncompressed byte array
- * @see InflaterInputStream#read
- */
- public static byte[] decompress( byte[] data, int pos, int length )
- {
- byte[] compressedData = new byte[length];
- System.arraycopy( data, pos + 50, compressedData, 0, length );
- InputStream compressedInputStream = new ByteArrayInputStream( compressedData );
- InflaterInputStream inflaterInputStream = new InflaterInputStream( compressedInputStream );
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int c;
- try
- {
- while ( ( c = inflaterInputStream.read() ) != -1 )
- out.write( c );
- }
- catch ( IOException e )
- {
- throw new RecordFormatException( e.toString() );
- }
- return out.toByteArray();
- }
-
}
diff --git a/src/java/org/apache/poi/ddf/EscherBlipWMFRecord.java b/src/java/org/apache/poi/ddf/EscherBlipWMFRecord.java
new file mode 100644
index 0000000000..d4e9d19469
--- /dev/null
+++ b/src/java/org/apache/poi/ddf/EscherBlipWMFRecord.java
@@ -0,0 +1,435 @@
+
+/* ====================================================================
+ 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.ddf;
+
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * The blip record is used to hold details about large binary objects that occur in escher such
+ * as JPEG, GIF, PICT and WMF files. The contents of the stream is usually compressed. Inflate
+ * can be used to decompress the data.
+ *
+ * @author Glen Stampoultzis
+ * @see java.util.zip.Inflater
+ */
+public class EscherBlipWMFRecord
+ extends EscherBlipRecord
+{
+// public static final short RECORD_ID_START = (short) 0xF018;
+// public static final short RECORD_ID_END = (short) 0xF117;
+ public static final String RECORD_DESCRIPTION = "msofbtBlip";
+ private static final int HEADER_SIZE = 8;
+
+ private byte[] field_1_secondaryUID;
+ private int field_2_cacheOfSize;
+ private int field_3_boundaryTop;
+ private int field_4_boundaryLeft;
+ private int field_5_boundaryWidth;
+ private int field_6_boundaryHeight;
+ private int field_7_width;
+ private int field_8_height;
+ private int field_9_cacheOfSavedSize;
+ private byte field_10_compressionFlag;
+ private byte field_11_filter;
+ private byte[] field_12_data;
+
+
+ /**
+ * 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 <code>data</code>.
+ * @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;
+
+ int size = 0;
+ field_1_secondaryUID = new byte[16];
+ System.arraycopy( data, pos + size, field_1_secondaryUID, 0, 16 ); size += 16;
+ field_2_cacheOfSize = LittleEndian.getInt( data, pos + size );size+=4;
+ field_3_boundaryTop = LittleEndian.getInt( data, pos + size );size+=4;
+ field_4_boundaryLeft = LittleEndian.getInt( data, pos + size );size+=4;
+ field_5_boundaryWidth = LittleEndian.getInt( data, pos + size );size+=4;
+ field_6_boundaryHeight = LittleEndian.getInt( data, pos + size );size+=4;
+ field_7_width = LittleEndian.getInt( data, pos + size );size+=4;
+ field_8_height = LittleEndian.getInt( data, pos + size );size+=4;
+ field_9_cacheOfSavedSize = LittleEndian.getInt( data, pos + size );size+=4;
+ field_10_compressionFlag = data[pos + size]; size++;
+ field_11_filter = data[pos + size]; size++;
+
+ int bytesRemaining = bytesAfterHeader - size;
+ field_12_data = new byte[bytesRemaining];
+ System.arraycopy(data, pos + size, field_12_data, 0, bytesRemaining);
+ size += bytesRemaining;
+
+ return HEADER_SIZE + size;
+ }
+
+
+ /**
+ * This method serializes this escher record into a byte array.
+ *
+ * @param offset The offset into <code>data</code> to start writing the record data to.
+ * @param data The byte array to serialize to.
+ * @param listener A listener to retrieve start and end callbacks. Use a <code>NullEscherSerailizationListener</code> to ignore these events.
+ * @return The number of bytes written.
+ *
+ * @see NullEscherSerializationListener
+ */
+ 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() );
+ int remainingBytes = field_12_data.length + 36;
+ LittleEndian.putInt( data, offset + 4, remainingBytes );
+
+ int pos = offset + HEADER_SIZE;
+ System.arraycopy(field_1_secondaryUID, 0, data, pos, 16 ); pos += 16;
+ LittleEndian.putInt( data, pos, field_2_cacheOfSize); pos += 4;
+ LittleEndian.putInt( data, pos, field_3_boundaryTop); pos += 4;
+ LittleEndian.putInt( data, pos, field_4_boundaryLeft); pos += 4;
+ LittleEndian.putInt( data, pos, field_5_boundaryWidth); pos += 4;
+ LittleEndian.putInt( data, pos, field_6_boundaryHeight); pos += 4;
+ LittleEndian.putInt( data, pos, field_7_width); pos += 4;
+ LittleEndian.putInt( data, pos, field_8_height); pos += 4;
+ LittleEndian.putInt( data, pos, field_9_cacheOfSavedSize); pos += 4;
+ data[pos++] = field_10_compressionFlag;
+ data[pos++] = field_11_filter;
+ System.arraycopy(field_12_data, 0, data, pos, field_12_data.length); pos += field_12_data.length;
+
+ listener.afterRecordSerialize(pos, getRecordId(), pos - offset, this);
+ return pos - offset;
+ }
+
+ /**
+ * Returns the number of bytes that are required to serialize this record.
+ *
+ * @return Number of bytes
+ */
+ public int getRecordSize()
+ {
+ return 58 + field_12_data.length;
+ }
+
+ /**
+ * The short name for this record
+ */
+ public String getRecordName()
+ {
+ return "Blip";
+ }
+
+ /**
+ * Retrieve the secondary UID
+ */
+ public byte[] getSecondaryUID()
+ {
+ return field_1_secondaryUID;
+ }
+
+ /**
+ * Set the secondary UID
+ */
+ public void setSecondaryUID( byte[] field_1_secondaryUID )
+ {
+ this.field_1_secondaryUID = field_1_secondaryUID;
+ }
+
+ /**
+ * Retrieve the cache of the metafile size
+ */
+ public int getCacheOfSize()
+ {
+ return field_2_cacheOfSize;
+ }
+
+ /**
+ * Set the cache of the metafile size
+ */
+ public void setCacheOfSize( int field_2_cacheOfSize )
+ {
+ this.field_2_cacheOfSize = field_2_cacheOfSize;
+ }
+
+ /**
+ * Retrieve the top boundary of the metafile drawing commands
+ */
+ public int getBoundaryTop()
+ {
+ return field_3_boundaryTop;
+ }
+
+ /**
+ * Set the top boundary of the metafile drawing commands
+ */
+ public void setBoundaryTop( int field_3_boundaryTop )
+ {
+ this.field_3_boundaryTop = field_3_boundaryTop;
+ }
+
+ /**
+ * Retrieve the left boundary of the metafile drawing commands
+ */
+ public int getBoundaryLeft()
+ {
+ return field_4_boundaryLeft;
+ }
+
+ /**
+ * Set the left boundary of the metafile drawing commands
+ */
+ public void setBoundaryLeft( int field_4_boundaryLeft )
+ {
+ this.field_4_boundaryLeft = field_4_boundaryLeft;
+ }
+
+ /**
+ * Retrieve the boundary width of the metafile drawing commands
+ */
+ public int getBoundaryWidth()
+ {
+ return field_5_boundaryWidth;
+ }
+
+ /**
+ * Set the boundary width of the metafile drawing commands
+ */
+ public void setBoundaryWidth( int field_5_boundaryWidth )
+ {
+ this.field_5_boundaryWidth = field_5_boundaryWidth;
+ }
+
+ /**
+ * Retrieve the boundary height of the metafile drawing commands
+ */
+ public int getBoundaryHeight()
+ {
+ return field_6_boundaryHeight;
+ }
+
+ /**
+ * Set the boundary height of the metafile drawing commands
+ */
+ public void setBoundaryHeight( int field_6_boundaryHeight )
+ {
+ this.field_6_boundaryHeight = field_6_boundaryHeight;
+ }
+
+ /**
+ * Retrieve the width of the metafile in EMU's (English Metric Units).
+ */
+ public int getWidth()
+ {
+ return field_7_width;
+ }
+
+ /**
+ * Set the width of the metafile in EMU's (English Metric Units).
+ */
+ public void setWidth( int width )
+ {
+ this.field_7_width = width;
+ }
+
+ /**
+ * Retrieve the height of the metafile in EMU's (English Metric Units).
+ */
+ public int getHeight()
+ {
+ return field_8_height;
+ }
+
+ /**
+ * Set the height of the metafile in EMU's (English Metric Units).
+ */
+ public void setHeight( int height )
+ {
+ this.field_8_height = height;
+ }
+
+ /**
+ * Retrieve the cache of the saved size
+ */
+ public int getCacheOfSavedSize()
+ {
+ return field_9_cacheOfSavedSize;
+ }
+
+ /**
+ * Set the cache of the saved size
+ */
+ public void setCacheOfSavedSize( int field_9_cacheOfSavedSize )
+ {
+ this.field_9_cacheOfSavedSize = field_9_cacheOfSavedSize;
+ }
+
+ /**
+ * Is the contents of the blip compressed?
+ */
+ public byte getCompressionFlag()
+ {
+ return field_10_compressionFlag;
+ }
+
+ /**
+ * Set whether the contents of the blip is compressed
+ */
+ public void setCompressionFlag( byte field_10_compressionFlag )
+ {
+ this.field_10_compressionFlag = field_10_compressionFlag;
+ }
+
+ /**
+ * Filter should always be 0
+ */
+ public byte getFilter()
+ {
+ return field_11_filter;
+ }
+
+ /**
+ * Filter should always be 0
+ */
+ public void setFilter( byte field_11_filter )
+ {
+ this.field_11_filter = field_11_filter;
+ }
+
+ /**
+ * The BLIP data
+ */
+ public byte[] getData()
+ {
+ return field_12_data;
+ }
+
+ /**
+ * The BLIP data
+ */
+ public void setData( byte[] field_12_data )
+ {
+ this.field_12_data = field_12_data;
+ }
+
+ /**
+ * The string representation of this record.
+ *
+ * @return A string
+ */
+ public String toString()
+ {
+ String nl = System.getProperty( "line.separator" );
+
+ String extraData;
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ try
+ {
+ HexDump.dump( this.field_12_data, 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 +
+ " Secondary UID: " + HexDump.toHex( field_1_secondaryUID ) + nl +
+ " CacheOfSize: " + field_2_cacheOfSize + nl +
+ " BoundaryTop: " + field_3_boundaryTop + nl +
+ " BoundaryLeft: " + field_4_boundaryLeft + nl +
+ " BoundaryWidth: " + field_5_boundaryWidth + nl +
+ " BoundaryHeight: " + field_6_boundaryHeight + nl +
+ " X: " + field_7_width + nl +
+ " Y: " + field_8_height + nl +
+ " CacheOfSavedSize: " + field_9_cacheOfSavedSize + nl +
+ " CompressionFlag: " + field_10_compressionFlag + nl +
+ " Filter: " + field_11_filter + nl +
+ " Data:" + nl + extraData;
+ }
+
+ /**
+ * Compress the contents of the provided array
+ *
+ * @param data An uncompressed byte array
+ * @see DeflaterOutputStream#write(int b)
+ */
+ public static byte[] compress( byte[] data )
+ {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream( out );
+ try
+ {
+ for ( int i = 0; i < data.length; i++ )
+ deflaterOutputStream.write( data[i] );
+ }
+ catch ( IOException e )
+ {
+ throw new RecordFormatException( e.toString() );
+ }
+
+ return out.toByteArray();
+ }
+
+ /**
+ * Decompresses a byte array.
+ *
+ * @param data The compressed byte array
+ * @param pos The starting position into the byte array
+ * @param length The number of compressed bytes to decompress
+ * @return An uncompressed byte array
+ * @see InflaterInputStream#read
+ */
+ public static byte[] decompress( byte[] data, int pos, int length )
+ {
+ byte[] compressedData = new byte[length];
+ System.arraycopy( data, pos + 50, compressedData, 0, length );
+ InputStream compressedInputStream = new ByteArrayInputStream( compressedData );
+ InflaterInputStream inflaterInputStream = new InflaterInputStream( compressedInputStream );
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int c;
+ try
+ {
+ while ( ( c = inflaterInputStream.read() ) != -1 )
+ out.write( c );
+ }
+ catch ( IOException e )
+ {
+ throw new RecordFormatException( e.toString() );
+ }
+ return out.toByteArray();
+ }
+
+}
diff --git a/src/java/org/apache/poi/ddf/EscherBoolProperty.java b/src/java/org/apache/poi/ddf/EscherBoolProperty.java
index 67bd0243d9..e4f4c8b50a 100644
--- a/src/java/org/apache/poi/ddf/EscherBoolProperty.java
+++ b/src/java/org/apache/poi/ddf/EscherBoolProperty.java
@@ -32,12 +32,12 @@ public class EscherBoolProperty
/**
* Create an instance of an escher boolean property.
*
- * @param propertyNumber The property number
+ * @param propertyNumber The property number (or id)
* @param value The 32 bit value of this bool property
*/
public EscherBoolProperty( short propertyNumber, int value )
{
- super( propertyNumber, false, false, value );
+ super(propertyNumber, value);
}
/**
diff --git a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
index c2115eca79..d8bb4acfc1 100644
--- a/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
+++ b/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
@@ -154,7 +154,7 @@ public class EscherClientAnchorRecord
}
catch ( Exception e )
{
- extraData = "error";
+ extraData = "error\n";
}
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
diff --git a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
index 4eb3bdbc91..59cac729eb 100644
--- a/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
+++ b/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
@@ -119,7 +119,7 @@ public class EscherClientDataRecord
}
catch ( Exception e )
{
- extraData = "error";
+ extraData = "error\n";
}
return getClass().getName() + ":" + nl +
" RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
diff --git a/src/java/org/apache/poi/ddf/EscherDggRecord.java b/src/java/org/apache/poi/ddf/EscherDggRecord.java
index 38d5c7eeb9..c10c58ac10 100644
--- a/src/java/org/apache/poi/ddf/EscherDggRecord.java
+++ b/src/java/org/apache/poi/ddf/EscherDggRecord.java
@@ -17,11 +17,10 @@
package org.apache.poi.ddf;
+import org.apache.poi.hssf.record.RecordFormatException;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
-import org.apache.poi.hssf.record.RecordFormatException;
-import java.lang.reflect.Array;
import java.util.*;
/**
@@ -83,8 +82,8 @@ public class EscherDggRecord
int field_2_numIdClusters = LittleEndian.getInt( data, pos + size );size+=4;
field_3_numShapesSaved = LittleEndian.getInt( data, pos + size );size+=4;
field_4_drawingsSaved = LittleEndian.getInt( data, pos + size );size+=4;
- field_5_fileIdClusters = new FileIdCluster[field_2_numIdClusters-1];
- for (int i = 0; i < field_2_numIdClusters-1; i++)
+ field_5_fileIdClusters = new FileIdCluster[(bytesRemaining-size) / 8]; // Can't rely on field_2_numIdClusters
+ for (int i = 0; i < field_5_fileIdClusters.length; i++)
{
field_5_fileIdClusters[i] = new FileIdCluster(LittleEndian.getInt( data, pos + size ), LittleEndian.getInt( data, pos + size + 4 ));
size += 8;
@@ -114,6 +113,7 @@ public class EscherDggRecord
LittleEndian.putShort( data, pos, getRecordId() ); pos += 2;
int remainingBytes = getRecordSize() - 8;
LittleEndian.putInt( data, pos, remainingBytes ); pos += 4;
+
LittleEndian.putInt( data, pos, field_1_shapeIdMax ); pos += 4;
LittleEndian.putInt( data, pos, getNumIdClusters() ); pos += 4;
LittleEndian.putInt( data, pos, field_3_numShapesSaved ); pos += 4;
@@ -200,6 +200,9 @@ public class EscherDggRecord
this.field_1_shapeIdMax = field_1_shapeIdMax;
}
+ /**
+ * Number of id clusters + 1
+ */
public int getNumIdClusters()
{
return field_5_fileIdClusters.length + 1;
diff --git a/src/java/org/apache/poi/ddf/EscherProperty.java b/src/java/org/apache/poi/ddf/EscherProperty.java
index f07be8bed1..65097138a6 100644
--- a/src/java/org/apache/poi/ddf/EscherProperty.java
+++ b/src/java/org/apache/poi/ddf/EscherProperty.java
@@ -26,7 +26,7 @@ package org.apache.poi.ddf;
*/
abstract public class EscherProperty
{
- private short id;
+ protected short id;
/**
* The id is distinct from the actual property number. The id includes the property number the blip id
diff --git a/src/java/org/apache/poi/ddf/EscherPropertyFactory.java b/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
index 35dc6331ba..b59f7bae01 100644
--- a/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
+++ b/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
@@ -18,11 +18,10 @@
package org.apache.poi.ddf;
import org.apache.poi.util.LittleEndian;
-import org.apache.poi.hssf.record.RecordFormatException;
-import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
/**
* Generates a property given a reference into the byte array storing that property.
@@ -43,7 +42,7 @@ public class EscherPropertyFactory
List results = new ArrayList();
int pos = offset;
- int complexBytes = 0;
+
// while ( bytesRemaining >= 6 )
for (int i = 0; i < numProperties; i++)
{
@@ -54,21 +53,18 @@ public class EscherPropertyFactory
short propNumber = (short) ( propId & (short) 0x3FFF );
boolean isComplex = ( propId & (short) 0x8000 ) != 0;
boolean isBlipId = ( propId & (short) 0x4000 ) != 0;
- if ( isComplex )
- complexBytes = propData;
- else
- complexBytes = 0;
+
byte propertyType = EscherProperties.getPropertyType( (short) propNumber );
if ( propertyType == EscherPropertyMetaData.TYPE_BOOLEAN )
- results.add( new EscherBoolProperty( propNumber, propData ) );
+ results.add( new EscherBoolProperty( propId, propData ) );
else if ( propertyType == EscherPropertyMetaData.TYPE_RGB )
- results.add( new EscherRGBProperty( propNumber, propData ) );
+ results.add( new EscherRGBProperty( propId, propData ) );
else if ( propertyType == EscherPropertyMetaData.TYPE_SHAPEPATH )
- results.add( new EscherShapePathProperty( propNumber, propData ) );
+ results.add( new EscherShapePathProperty( propId, propData ) );
else
{
if ( !isComplex )
- results.add( new EscherSimpleProperty( propNumber, propData ) );
+ results.add( new EscherSimpleProperty( propId, propData ) );
else
{
if ( propertyType == EscherPropertyMetaData.TYPE_ARRAY)
diff --git a/src/java/org/apache/poi/ddf/EscherRGBProperty.java b/src/java/org/apache/poi/ddf/EscherRGBProperty.java
index b38f0fd764..e7dde24568 100644
--- a/src/java/org/apache/poi/ddf/EscherRGBProperty.java
+++ b/src/java/org/apache/poi/ddf/EscherRGBProperty.java
@@ -28,7 +28,7 @@ public class EscherRGBProperty
public EscherRGBProperty( short propertyNumber, int rgbColor )
{
- super( propertyNumber, false, false, rgbColor );
+ super( propertyNumber, rgbColor );
}
public int getRgbColor()
diff --git a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java
index de27ccadee..02d0595fe1 100644
--- a/src/java/org/apache/poi/ddf/EscherSimpleProperty.java
+++ b/src/java/org/apache/poi/ddf/EscherSimpleProperty.java
@@ -111,6 +111,7 @@ public class EscherSimpleProperty extends EscherProperty
public String toString()
{
return "propNum: " + getPropertyNumber()
+ + ", RAW: 0x" + HexDump.toHex( getId() )
+ ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() )
+ ", complex: " + isComplex()
+ ", blipId: " + isBlipId()
diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
index 754c1011ae..468cb63f43 100644
--- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java
+++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java
@@ -112,6 +112,23 @@ public class BiffViewer {
in.read(data);
loc += recsize;
Record record = createRecord(rectype, recsize, data );
+// if (record.getSid() == DrawingGroupRecord.sid)
+// {
+// if (activeRecord.getRecord().getSid() == DrawingGroupRecord.sid)
+// {
+// DrawingGroupRecord dg = (DrawingGroupRecord) activeRecord.getRecord();
+// System.out.println( "Joined" );
+// dg.join( (AbstractEscherHolderRecord) record );
+// }
+// else
+// {
+// records.add(record);
+// if (activeRecord != null)
+// activeRecord.dump();
+// activeRecord = new RecordDetails(rectype, recsize, startloc, data, record);
+// }
+// }
+// else
if (record.getSid() != ContinueRecord.sid)
{
records.add(record);
@@ -178,7 +195,6 @@ public class BiffViewer {
}
}
-
private static void dumpUnknownRecord(byte[] data) throws IOException {
// record hex dump it!
System.out.println(
@@ -630,29 +646,40 @@ public class BiffViewer {
*/
public static void main(String[] args) {
try {
- BiffViewer viewer = new BiffViewer(args);
+ System.setProperty("poi.deserialize.escher", "true");
- if ((args.length > 1) && args[1].equals("on")) {
- viewer.setDump(true);
+ if (args.length == 0)
+ {
+ System.out.println( "Biff viewer needs a filename" );
}
- if ((args.length > 1) && args[1].equals("bfd")) {
- POIFSFileSystem fs =
- new POIFSFileSystem(new FileInputStream(args[0]));
- InputStream stream =
- fs.createDocumentInputStream("Workbook");
- int size = stream.available();
- byte[] data = new byte[size];
-
- stream.read(data);
- HexDump.dump(data, 0, System.out, 0);
- } else {
- viewer.run();
+ else
+ {
+ BiffViewer viewer = new BiffViewer(args);
+ if ((args.length > 1) && args[1].equals("on")) {
+ viewer.setDump(true);
+ }
+ if ((args.length > 1) && args[1].equals("bfd")) {
+ POIFSFileSystem fs =
+ new POIFSFileSystem(new FileInputStream(args[0]));
+ InputStream stream =
+ fs.createDocumentInputStream("Workbook");
+ int size = stream.available();
+ byte[] data = new byte[size];
+
+ stream.read(data);
+ HexDump.dump(data, 0, System.out, 0);
+ } else {
+ viewer.run();
+ }
}
} catch (Exception e) {
e.printStackTrace();
}
}
+ /**
+ * This record supports dumping of completed continue records.
+ */
static class RecordDetails
{
short rectype, recsize;
diff --git a/src/java/org/apache/poi/hssf/model/AbstractShape.java b/src/java/org/apache/poi/hssf/model/AbstractShape.java
index 41f4ee73bb..60f24401c1 100644
--- a/src/java/org/apache/poi/hssf/model/AbstractShape.java
+++ b/src/java/org/apache/poi/hssf/model/AbstractShape.java
@@ -34,7 +34,7 @@ public abstract class AbstractShape
*/
public static AbstractShape createShape( HSSFShape hssfShape, int shapeId )
{
- AbstractShape shape = null;
+ AbstractShape shape;
if (hssfShape instanceof HSSFTextbox)
{
shape = new TextboxShape( (HSSFTextbox)hssfShape, shapeId );
@@ -48,6 +48,9 @@ public abstract class AbstractShape
HSSFSimpleShape simpleShape = (HSSFSimpleShape) hssfShape;
switch ( simpleShape.getShapeType() )
{
+ case HSSFSimpleShape.OBJECT_TYPE_PICTURE:
+ shape = new PictureShape( simpleShape, shapeId );
+ break;
case HSSFSimpleShape.OBJECT_TYPE_LINE:
shape = new LineShape( simpleShape, shapeId );
break;
diff --git a/src/java/org/apache/poi/hssf/model/ConvertAnchor.java b/src/java/org/apache/poi/hssf/model/ConvertAnchor.java
index 8f1943a81f..73e55209c2 100644
--- a/src/java/org/apache/poi/hssf/model/ConvertAnchor.java
+++ b/src/java/org/apache/poi/hssf/model/ConvertAnchor.java
@@ -37,7 +37,7 @@ public class ConvertAnchor
EscherClientAnchorRecord anchor = new EscherClientAnchorRecord();
anchor.setRecordId( EscherClientAnchorRecord.RECORD_ID );
anchor.setOptions( (short) 0x0000 );
- anchor.setFlag( (short) 0 );
+ anchor.setFlag( (short) a.getAnchorType() );
anchor.setCol1( (short) Math.min(a.getCol1(), a.getCol2()) );
anchor.setDx1( (short) Math.min(a.getDx1(), a.getDx2()) );
anchor.setRow1( (short) Math.min(a.getRow1(), a.getRow2()) );
diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java
index 99b26fe191..6d32288e31 100644
--- a/src/java/org/apache/poi/hssf/model/Sheet.java
+++ b/src/java/org/apache/poi/hssf/model/Sheet.java
@@ -19,17 +19,17 @@
package org.apache.poi.hssf.model;
import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
-import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List;
+import java.util.List; // normally I don't do this, buy we literally mean ALL
/**
* Low level model implementation of a Sheet (one workbook contains many sheets)
@@ -768,6 +768,26 @@ public class Sheet implements Model
}
}
+ //// uncomment to test record sizes ////
+// System.out.println( record.getClass().getName() );
+// byte[] data2 = new byte[record.getRecordSize()];
+// record.serialize(0, data2 ); // rec.length;
+// if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
+// && record instanceof RowRecordsAggregate == false
+// && record instanceof ValueRecordsAggregate == false
+// && record instanceof EscherAggregate == false)
+// {
+// throw new RuntimeException("Blah!!! Size off by " + ( LittleEndian.getUShort(data2, 2) - record.getRecordSize() - 4) + " records.");
+// }
+
+//asd: int len = record.serialize(pos + offset, data );
+
+ ///// DEBUG BEGIN /////
+//asd: if (len != record.getRecordSize())
+//asd: throw new IllegalStateException("Record size does not match serialized bytes. Serialized size = " + len + " but getRecordSize() returns " + record.getRecordSize() + ". Record object is " + record.getClass());
+ ///// DEBUG END /////
+
+//asd: pos += len; // rec.length;
}
if (log.check( POILogger.DEBUG ))
@@ -2023,9 +2043,9 @@ public class Sheet implements Model
{
int retval = 0;
- for (int k = 0; k < records.size(); k++)
+ for ( int k = 0; k < records.size(); k++ )
{
- retval += (( Record ) records.get(k)).getRecordSize();
+ retval += ( (Record) records.get( k ) ).getRecordSize();
}
//Add space for the IndexRecord
if (rows != null) {
@@ -2430,7 +2450,7 @@ public class Sheet implements Model
return margins;
}
- public int aggregateDrawingRecords(DrawingManager drawingManager)
+ public int aggregateDrawingRecords(DrawingManager2 drawingManager)
{
int loc = findFirstRecordLocBySid(DrawingRecord.sid);
boolean noDrawingRecordsFound = loc == -1;
diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java
index c7d4ae1fd6..8ec742baff 100644
--- a/src/java/org/apache/poi/hssf/model/Workbook.java
+++ b/src/java/org/apache/poi/hssf/model/Workbook.java
@@ -29,7 +29,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
-import java.io.UnsupportedEncodingException;
/**
* Low level model implementation of a Workbook. Provides creational methods
@@ -99,7 +98,8 @@ public class Workbook implements Model
protected int numfonts = 0; // hold the number of font records
private short maxformatid = -1; // holds the max format id
private boolean uses1904datewindowing = false; // whether 1904 date windowing is being used
- private DrawingManager drawingManager;
+ private DrawingManager2 drawingManager;
+ private List escherBSERecords = new ArrayList(); // EscherBSERecord
private static POILogger log = POILogFactory.getLogger(Workbook.class);
@@ -748,7 +748,12 @@ public class Workbook implements Model
{
record = sst.createExtSSTRecord(sstPos + offset);
}
- pos += record.serialize( pos + offset, data ); // rec.length;
+ int len = record.serialize( pos + offset, data );
+ ///// DEBUG BEGIN /////
+// if (len != record.getRecordSize())
+// throw new IllegalStateException("Record size does not match serialized bytes. Serialized size = " + len + " but getRecordSize() returns " + record.getRecordSize());
+ ///// DEBUG END /////
+ pos += len; // rec.length;
}
}
if (log.check( POILogger.DEBUG ))
@@ -2104,13 +2109,12 @@ public class Workbook implements Model
}
/**
- * Creates a drawing group record. If it already exists then it's left
- * alone.
+ * Creates a drawing group record. If it already exists then it's modified.
*/
public void createDrawingGroup()
{
- int dggLoc = findFirstRecordLocBySid(EscherContainerRecord.DGG_CONTAINER);
- if (dggLoc == -1)
+
+ if (drawingManager == null)
{
EscherContainerRecord dggContainer = new EscherContainerRecord();
EscherDggRecord dgg = new EscherDggRecord();
@@ -2125,11 +2129,23 @@ public class Workbook implements Model
dgg.setNumShapesSaved(0);
dgg.setDrawingsSaved(0);
dgg.setFileIdClusters(new EscherDggRecord.FileIdCluster[] {} );
- drawingManager = new DrawingManager(dgg);
+ drawingManager = new DrawingManager2(dgg);
+ EscherContainerRecord bstoreContainer = null;
+ if (escherBSERecords.size() > 0)
+ {
+ bstoreContainer = new EscherContainerRecord();
+ bstoreContainer.setRecordId( EscherContainerRecord.BSTORE_CONTAINER );
+ bstoreContainer.setOptions( (short) ( (escherBSERecords.size() << 4) | 0xF ) );
+ for ( Iterator iterator = escherBSERecords.iterator(); iterator.hasNext(); )
+ {
+ EscherRecord escherRecord = (EscherRecord) iterator.next();
+ bstoreContainer.addChildRecord( escherRecord );
+ }
+ }
opt.setRecordId((short) 0xF00B);
opt.setOptions((short) 0x0033);
opt.addEscherProperty( new EscherBoolProperty(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 524296) );
- opt.addEscherProperty( new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, 134217737) );
+ opt.addEscherProperty( new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, 0x08000041) );
opt.addEscherProperty( new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, 134217792) );
splitMenuColors.setRecordId((short) 0xF11E);
splitMenuColors.setOptions((short) 0x0040);
@@ -2139,17 +2155,61 @@ public class Workbook implements Model
splitMenuColors.setColor4(0x100000F7);
dggContainer.addChildRecord(dgg);
+ if (bstoreContainer != null)
+ dggContainer.addChildRecord( bstoreContainer );
dggContainer.addChildRecord(opt);
dggContainer.addChildRecord(splitMenuColors);
- DrawingGroupRecord drawingGroup = new DrawingGroupRecord();
- drawingGroup.addEscherRecord(dggContainer);
- int loc = findFirstRecordLocBySid(CountryRecord.sid);
- getRecords().add(loc+1, drawingGroup);
+ int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid);
+ if (dgLoc == -1)
+ {
+ DrawingGroupRecord drawingGroup = new DrawingGroupRecord();
+ drawingGroup.addEscherRecord(dggContainer);
+ int loc = findFirstRecordLocBySid(CountryRecord.sid);
+
+ getRecords().add(loc+1, drawingGroup);
+ }
+ else
+ {
+ DrawingGroupRecord drawingGroup = new DrawingGroupRecord();
+ drawingGroup.addEscherRecord(dggContainer);
+ getRecords().set(dgLoc, drawingGroup);
+ }
+
}
+
+ }
+
+ public int addBSERecord(EscherBSERecord e)
+ {
+ createDrawingGroup();
+
+ // maybe we don't need that as an instance variable anymore
+ escherBSERecords.add( e );
+
+ int dgLoc = findFirstRecordLocBySid(DrawingGroupRecord.sid);
+ DrawingGroupRecord drawingGroup = (DrawingGroupRecord) getRecords().get( dgLoc );
+
+ EscherContainerRecord dggContainer = (EscherContainerRecord) drawingGroup.getEscherRecord( 0 );
+ EscherContainerRecord bstoreContainer;
+ if (dggContainer.getChild( 1 ).getRecordId() == EscherContainerRecord.BSTORE_CONTAINER )
+ {
+ bstoreContainer = (EscherContainerRecord) dggContainer.getChild( 1 );
+ }
+ else
+ {
+ bstoreContainer = new EscherContainerRecord();
+ bstoreContainer.setRecordId( EscherContainerRecord.BSTORE_CONTAINER );
+ dggContainer.getChildRecords().add( 1, bstoreContainer );
+ }
+ bstoreContainer.setOptions( (short) ( (escherBSERecords.size() << 4) | 0xF ) );
+
+ bstoreContainer.addChildRecord( e );
+
+ return escherBSERecords.size();
}
- public DrawingManager getDrawingManager()
+ public DrawingManager2 getDrawingManager()
{
return drawingManager;
}
diff --git a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
index b2701e3fc4..a18724478e 100644
--- a/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
+++ b/src/java/org/apache/poi/hssf/record/AbstractEscherHolderRecord.java
@@ -88,7 +88,7 @@ public abstract class AbstractEscherHolderRecord
{
if (id != getSid())
{
- throw new RecordFormatException("Not a Bar record");
+ throw new RecordFormatException("Not an escher record");
}
}
@@ -102,15 +102,20 @@ public abstract class AbstractEscherHolderRecord
}
else
{
- EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
- int pos = offset;
- while ( pos < offset + size )
- {
- EscherRecord r = recordFactory.createRecord(data, pos);
- int bytesRead = r.fillFields(data, pos, recordFactory );
- escherRecords.add(r);
- pos += bytesRead;
- }
+ convertToEscherRecords( offset, size, data );
+ }
+ }
+
+ private void convertToEscherRecords( int offset, int size, byte[] data )
+ {
+ EscherRecordFactory recordFactory = new DefaultEscherRecordFactory();
+ int pos = offset;
+ while ( pos < offset + size )
+ {
+ EscherRecord r = recordFactory.createRecord(data, pos);
+ int bytesRead = r.fillFields(data, pos, recordFactory );
+ escherRecords.add(r);
+ pos += bytesRead;
}
}
@@ -120,6 +125,8 @@ public abstract class AbstractEscherHolderRecord
final String nl = System.getProperty("line.separator");
buffer.append('[' + getRecordName() + ']' + nl);
+ if (escherRecords.size() == 0)
+ buffer.append("No Escher Records Decoded" + nl);
for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
{
EscherRecord r = (EscherRecord) iterator.next();
@@ -138,10 +145,16 @@ public abstract class AbstractEscherHolderRecord
LittleEndian.putShort( data, 2 + offset, (short) ( getRecordSize() - 4 ) );
if ( escherRecords.size() == 0 && rawData != null )
{
- System.arraycopy( rawData, 0, data, offset + 4, rawData.length );
+ LittleEndian.putShort(data, 0 + offset, getSid());
+ LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
+ System.arraycopy( rawData, 0, data, 4 + offset, rawData.length);
+ return rawData.length + 4;
}
else
{
+ LittleEndian.putShort(data, 0 + offset, getSid());
+ LittleEndian.putShort(data, 2 + offset, (short)(getRecordSize() - 4));
+
int pos = offset + 4;
for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
{
@@ -255,6 +268,45 @@ public abstract class AbstractEscherHolderRecord
return (EscherRecord) escherRecords.get(index);
}
+ /**
+ * Big drawing group records are split but it's easier to deal with them
+ * as a whole group so we need to join them together.
+ */
+ public void join( AbstractEscherHolderRecord record )
+ {
+ int length = this.rawData.length + record.getRawData().length;
+ byte[] data = new byte[length];
+ System.arraycopy( rawData, 0, data, 0, rawData.length );
+ System.arraycopy( record.getRawData(), 0, data, rawData.length, record.getRawData().length );
+ rawData = data;
+ }
+
+ public void processContinueRecord( byte[] record )
+ {
+ int length = this.rawData.length + record.length;
+ byte[] data = new byte[length];
+ System.arraycopy( rawData, 0, data, 0, rawData.length );
+ System.arraycopy( record, 0, data, rawData.length, record.length );
+ rawData = data;
+ }
+
+ public byte[] getRawData()
+ {
+ return rawData;
+ }
+
+ public void setRawData( byte[] rawData )
+ {
+ this.rawData = rawData;
+ }
+
+ /**
+ * Convert raw data to escher records.
+ */
+ public void decode()
+ {
+ convertToEscherRecords(0, rawData.length, rawData );
+ }
} // END OF CLASS
diff --git a/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java b/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java
index d114666d49..675a0cdba6 100644
--- a/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java
+++ b/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java
@@ -16,10 +16,22 @@
package org.apache.poi.hssf.record;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.NullEscherSerializationListener;
+import org.apache.poi.util.ArrayUtil;
+import org.apache.poi.util.LittleEndian;
+
+import java.util.Iterator;
+import java.util.List;
+
+
public class DrawingGroupRecord extends AbstractEscherHolderRecord
{
public static final short sid = 0xEB;
+ static final int MAX_RECORD_SIZE = 8228;
+ private static final int MAX_DATA_SIZE = MAX_RECORD_SIZE - 4;
+
public DrawingGroupRecord()
{
}
@@ -43,4 +55,92 @@ public class DrawingGroupRecord extends AbstractEscherHolderRecord
{
return sid;
}
+
+ public int serialize(int offset, byte[] data)
+ {
+ byte[] rawData = getRawData();
+ if (getEscherRecords().size() == 0 && rawData != null)
+ {
+ return writeData( offset, data, rawData );
+ }
+ else
+ {
+ byte[] buffer = new byte[getRawDataSize()];
+ int pos = 0;
+ for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); )
+ {
+ EscherRecord r = (EscherRecord) iterator.next();
+ pos += r.serialize(pos, buffer, new NullEscherSerializationListener() );
+ }
+
+ return writeData( offset, data, buffer );
+ }
+ }
+
+ /**
+ * Size of record (including 4 byte headers for all sections)
+ */
+ public int getRecordSize()
+ {
+ return grossSizeFromDataSize( getRawDataSize() );
+ }
+
+ public int getRawDataSize()
+ {
+ List escherRecords = getEscherRecords();
+ byte[] rawData = getRawData();
+ if (escherRecords.size() == 0 && rawData != null)
+ {
+ return rawData.length;
+ }
+ else
+ {
+ int size = 0;
+ for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
+ {
+ EscherRecord r = (EscherRecord) iterator.next();
+ size += r.getRecordSize();
+ }
+ return size;
+ }
+ }
+
+ static int grossSizeFromDataSize(int dataSize)
+ {
+ return dataSize + ( (dataSize - 1) / MAX_DATA_SIZE + 1 ) * 4;
+ }
+
+ private int writeData( int offset, byte[] data, byte[] rawData )
+ {
+ int writtenActualData = 0;
+ int writtenRawData = 0;
+ while (writtenRawData < rawData.length)
+ {
+ int segmentLength = Math.min( rawData.length - writtenRawData, MAX_DATA_SIZE);
+ if (writtenRawData / MAX_DATA_SIZE >= 2)
+ writeContinueHeader( data, offset, segmentLength );
+ else
+ writeHeader( data, offset, segmentLength );
+ writtenActualData += 4;
+ offset += 4;
+ ArrayUtil.arraycopy( rawData, writtenRawData, data, offset, segmentLength );
+ offset += segmentLength;
+ writtenRawData += segmentLength;
+ writtenActualData += segmentLength;
+ }
+ return writtenActualData;
+ }
+
+ private void writeHeader( byte[] data, int offset, int sizeExcludingHeader )
+ {
+ LittleEndian.putShort(data, 0 + offset, getSid());
+ LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader);
+ }
+
+ private void writeContinueHeader( byte[] data, int offset, int sizeExcludingHeader )
+ {
+ LittleEndian.putShort(data, 0 + offset, ContinueRecord.sid);
+ LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader);
+ }
+
}
diff --git a/src/java/org/apache/poi/hssf/record/DrawingRecord.java b/src/java/org/apache/poi/hssf/record/DrawingRecord.java
index c17588c833..b2bf298de2 100644
--- a/src/java/org/apache/poi/hssf/record/DrawingRecord.java
+++ b/src/java/org/apache/poi/hssf/record/DrawingRecord.java
@@ -68,6 +68,14 @@ public class DrawingRecord extends Record
recordData = data;
}
+ public void processContinueRecord( byte[] record )
+ {
+ byte[] newBuffer = new byte[ recordData.length + record.length ];
+ System.arraycopy( recordData, 0, newBuffer, 0, recordData.length );
+ System.arraycopy( record, 0, newBuffer, recordData.length, record.length);
+ recordData = newBuffer;
+ }
+
public int serialize( int offset, byte[] data )
{
if (recordData == null)
diff --git a/src/java/org/apache/poi/hssf/record/EscherAggregate.java b/src/java/org/apache/poi/hssf/record/EscherAggregate.java
index e3f65d0bd8..e9bf9f9333 100644
--- a/src/java/org/apache/poi/hssf/record/EscherAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/EscherAggregate.java
@@ -20,7 +20,7 @@ import org.apache.poi.ddf.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.model.AbstractShape;
import org.apache.poi.hssf.model.TextboxShape;
-import org.apache.poi.hssf.model.DrawingManager;
+import org.apache.poi.hssf.model.DrawingManager2;
import org.apache.poi.hssf.model.ConvertAnchor;
import java.util.*;
@@ -256,10 +256,10 @@ public class EscherAggregate extends AbstractEscherHolderRecord
/** Maps shape container objects to their OBJ records */
private Map shapeToObj = new HashMap();
- private DrawingManager drawingManager;
+ private DrawingManager2 drawingManager;
private short drawingGroupId;
- public EscherAggregate( DrawingManager drawingManager )
+ public EscherAggregate( DrawingManager2 drawingManager )
{
this.drawingManager = drawingManager;
}
@@ -305,7 +305,7 @@ public class EscherAggregate extends AbstractEscherHolderRecord
/**
* Collapses the drawing records into an aggregate.
*/
- public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager drawingManager )
+ public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager2 drawingManager )
{
// Keep track of any shape records created so we can match them back to the object id's.
// Textbox objects are also treated as shape objects.
@@ -571,6 +571,9 @@ public class EscherAggregate extends AbstractEscherHolderRecord
escherParent.addChildRecord( shapeModel.getSpContainer() );
}
}
+// drawingManager.newCluster( (short)1 );
+// drawingManager.newCluster( (short)2 );
+
}
private void convertGroup( HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj )
@@ -678,7 +681,7 @@ public class EscherAggregate extends AbstractEscherHolderRecord
spContainer1.setRecordId( EscherContainerRecord.SP_CONTAINER );
spContainer1.setOptions( (short) 0x000F );
spgr.setRecordId( EscherSpgrRecord.RECORD_ID );
- spgr.setOptions( (short) 0x0001 ); // don't know what the 1 is for.
+ spgr.setOptions( (short) 0x0001 ); // version
spgr.setRectX1( patriarch.getX1() );
spgr.setRectY1( patriarch.getY1() );
spgr.setRectX2( patriarch.getX2() );
diff --git a/src/java/org/apache/poi/hssf/record/ObjRecord.java b/src/java/org/apache/poi/hssf/record/ObjRecord.java
index e5a3aa0b09..a2489be362 100644
--- a/src/java/org/apache/poi/hssf/record/ObjRecord.java
+++ b/src/java/org/apache/poi/hssf/record/ObjRecord.java
@@ -173,6 +173,14 @@ public class ObjRecord
return subrecords.add( o );
}
+ // made public to satisfy biffviewer
+
+ /* protected */
+ public void processContinueRecord( byte[] record )
+ {
+ super.processContinueRecord( record );
+ }
+
public Object clone()
{
ObjRecord rec = new ObjRecord();
diff --git a/src/java/org/apache/poi/hssf/record/RecordFactory.java b/src/java/org/apache/poi/hssf/record/RecordFactory.java
index 5d4bc9696d..b4f3697e2d 100644
--- a/src/java/org/apache/poi/hssf/record/RecordFactory.java
+++ b/src/java/org/apache/poi/hssf/record/RecordFactory.java
@@ -148,6 +148,7 @@ public class RecordFactory
{
short rectype = 0;
+ DrawingRecord lastDrawingRecord = new DrawingRecord( );
do
{
rectype = LittleEndian.readShort(in);
@@ -176,7 +177,13 @@ public class RecordFactory
if (record != null)
{
- if (rectype == ContinueRecord.sid &&
+ if (rectype == DrawingGroupRecord.sid
+ && last_record instanceof DrawingGroupRecord)
+ {
+ DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) last_record;
+ lastDGRecord.join((AbstractEscherHolderRecord) record);
+ }
+ else if (rectype == ContinueRecord.sid &&
! (last_record instanceof ContinueRecord) && // include continuation records after
! (last_record instanceof UnknownRecord) ) // unknown records or previous continuation records
{
@@ -185,11 +192,18 @@ public class RecordFactory
throw new RecordFormatException(
"First record is a ContinueRecord??");
}
- last_record.processContinueRecord(data);
+
+ // Drawing records have a very strange continue behaviour. There can actually be OBJ records mixed between the continues.
+ if (last_record instanceof ObjRecord)
+ lastDrawingRecord.processContinueRecord( data );
+ else
+ last_record.processContinueRecord(data);
}
else
{
last_record = record;
+ if (record instanceof DrawingRecord)
+ lastDrawingRecord = (DrawingRecord) record;
records.add(record);
}
}
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
index 6eb9b111da..a7f8126110 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/ColumnInfoRecordsAggregate.java
@@ -14,7 +14,7 @@ import java.util.List;
public class ColumnInfoRecordsAggregate
extends Record
{
- int size = 0;
+// int size = 0;
List records = null;
public ColumnInfoRecordsAggregate()
@@ -40,6 +40,9 @@ public class ColumnInfoRecordsAggregate
public int getRecordSize()
{
+ int size = 0;
+ for ( Iterator iterator = records.iterator(); iterator.hasNext(); )
+ size += ( (ColumnInfoRecord) iterator.next() ).getRecordSize();
return size;
}
@@ -68,7 +71,6 @@ public class ColumnInfoRecordsAggregate
*/
public void insertColumn( ColumnInfoRecord col )
{
- size += col.getRecordSize();
records.add( col );
}
@@ -78,7 +80,6 @@ public class ColumnInfoRecordsAggregate
*/
public void insertColumn( int idx, ColumnInfoRecord col )
{
- size += col.getRecordSize();
records.add( idx, col );
}
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
index 85e98f62ad..6a8e3554dc 100644
--- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
+++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
@@ -228,7 +228,7 @@ public class RowRecordsAggregate
/**
* called by the constructor, should set class level fields. Should throw
- * runtime exception for bad/icomplete data.
+ * runtime exception for bad/incomplete data.
*
* @param data raw data
* @param size size of data
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java
index 029cc77ff5..7be224b28a 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java
@@ -16,8 +16,7 @@
package org.apache.poi.hssf.usermodel;
-import org.apache.poi.ddf.EscherClientAnchorRecord;
-import org.apache.poi.ddf.EscherRecord;
+
/**
@@ -33,6 +32,7 @@ public class HSSFClientAnchor
int row1;
short col2;
int row2;
+ int anchorType;
/**
* Creates a new client anchor and defaults all the anchor positions to 0.
@@ -213,6 +213,26 @@ public class HSSFClientAnchor
return row1 > row2;
}
+ /**
+ * Gets the anchor type
+ * <p>
+ * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
+ */
+ public int getAnchorType()
+ {
+ return anchorType;
+ }
+
+ /**
+ * Sets the anchor type
+ * <p>
+ * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
+ */
+ public void setAnchorType( int anchorType )
+ {
+ this.anchorType = anchorType;
+ }
+
private void checkRange( int value, int minRange, int maxRange, String varName )
{
if (value < minRange || value > maxRange)
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
index c80982baec..771f48d84c 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java
@@ -78,6 +78,23 @@ public class HSSFPatriarch
}
/**
+ * Creates a picture.
+ *
+ * @param anchor the client anchor describes how this group is attached
+ * to the sheet.
+ * @return the newly created shape.
+ */
+ public HSSFPicture createPicture(HSSFClientAnchor anchor, int pictureIndex)
+ {
+ HSSFPicture shape = new HSSFPicture(null, anchor);
+ shape.setPictureIndex( pictureIndex );
+ shape.anchor = anchor;
+ shapes.add(shape);
+ return shape;
+ }
+
+
+ /**
* Creates a polygon
*
* @param anchor the client anchor describes how this group is attached
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index 991d79ceb7..75880ce50d 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -1220,19 +1220,22 @@ public class HSSFSheet
* Aggregates the drawing records and dumps the escher record hierarchy
* to the standard output.
*/
- public void dumpDrawingRecords()
+ public void dumpDrawingRecords(boolean fat)
{
sheet.aggregateDrawingRecords(book.getDrawingManager());
EscherAggregate r = (EscherAggregate) getSheet().findFirstRecordBySid(EscherAggregate.sid);
List escherRecords = r.getEscherRecords();
+ PrintWriter w = new PrintWriter(System.out);
for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
{
EscherRecord escherRecord = (EscherRecord) iterator.next();
- PrintWriter w = new PrintWriter(System.out);
- escherRecord.display(w, 0);
- w.close();
+ if (fat)
+ System.out.println(escherRecord.toString());
+ else
+ escherRecord.display(w, 0);
}
+ w.flush();
}
/**
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
index 9969cdcdad..3adaff9f8f 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
@@ -34,7 +34,7 @@ public class HSSFSimpleShape
// public final static short OBJECT_TYPE_CHART = 5;
// public final static short OBJECT_TYPE_TEXT = 6;
// public final static short OBJECT_TYPE_BUTTON = 7;
-// public final static short OBJECT_TYPE_PICTURE = 8;
+ public final static short OBJECT_TYPE_PICTURE = 8;
// public final static short OBJECT_TYPE_POLYGON = 9;
// public final static short OBJECT_TYPE_CHECKBOX = 11;
// public final static short OBJECT_TYPE_OPTION_BUTTON = 12;
@@ -63,6 +63,7 @@ public class HSSFSimpleShape
* @see #OBJECT_TYPE_LINE
* @see #OBJECT_TYPE_OVAL
* @see #OBJECT_TYPE_RECTANGLE
+ * @see #OBJECT_TYPE_PICTURE
*/
public int getShapeType() { return shapeType; }
@@ -74,6 +75,7 @@ public class HSSFSimpleShape
* @see #OBJECT_TYPE_LINE
* @see #OBJECT_TYPE_OVAL
* @see #OBJECT_TYPE_RECTANGLE
+ * @see #OBJECT_TYPE_PICTURE
*/
public void setShapeType( int shapeType ){ this.shapeType = shapeType; }
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index 8d6533252c..500b220f08 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -22,6 +22,9 @@
*/
package org.apache.poi.hssf.usermodel;
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherBitmapBlip;
+import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hssf.eventmodel.EventRecordFactory;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
@@ -38,6 +41,7 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -57,7 +61,6 @@ import java.util.Stack;
*/
public class HSSFWorkbook
- extends java.lang.Object
{
private static final int DEBUG = POILogger.DEBUG;
@@ -108,13 +111,31 @@ public class HSSFWorkbook
*/
private HSSFDataFormat formatter;
+
+ /// NOT YET SUPPORTED:
+ /** Extended windows meta file */
+ //public static final int PICTURE_TYPE_EMF = 2;
+ /** Windows Meta File */
+ //public static final int PICTURE_TYPE_WMF = 3;
+ /** Mac PICT format */
+ //public static final int PICTURE_TYPE_PICT = 4;
+
+ /** JPEG format */
+ public static final int PICTURE_TYPE_JPEG = 5;
+ /** PNG format */
+ public static final int PICTURE_TYPE_PNG = 6;
+ /** Device independant bitmap */
+ public static final int PICTURE_TYPE_DIB = 7;
+
+
private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
+
+
/**
* Creates new HSSFWorkbook from scratch (start here!)
*
*/
-
public HSSFWorkbook()
{
this(Workbook.createWorkbook());
@@ -159,8 +180,6 @@ public class HSSFWorkbook
EventRecordFactory factory = new EventRecordFactory();
-
-
List records = RecordFactory.createRecords(stream);
workbook = Workbook.createWorkbook(records);
@@ -796,8 +815,9 @@ public class HSSFWorkbook
// byte[] sb = (byte[])sheetbytes.get(k);
// System.arraycopy(sb, 0, retval, pos, sb.length);
- pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
- retval); // sb.length;
+ int len = ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
+ retval);
+ pos += len; // sb.length;
}
/* for (int k = pos; k < totalsize; k++)
{
@@ -1067,6 +1087,68 @@ public class HSSFWorkbook
workbook.getRecords().add(loc, r);
}
+ /**
+ * Spits out a list of all the drawing records in the workbook.
+ */
+ public void dumpDrawingGroupRecords(boolean fat)
+ {
+ DrawingGroupRecord r = (DrawingGroupRecord) workbook.findFirstRecordBySid( DrawingGroupRecord.sid );
+ r.decode();
+ List escherRecords = r.getEscherRecords();
+ PrintWriter w = new PrintWriter(System.out);
+ for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
+ {
+ EscherRecord escherRecord = (EscherRecord) iterator.next();
+ if (fat)
+ System.out.println(escherRecord.toString());
+ else
+ escherRecord.display(w, 0);
+ }
+ w.flush();
+ }
+ /**
+ * Adds a picture to the workbook.
+ *
+ * @param pictureData The bytes of the picture
+ * @param format The format of the picture. One of <code>PICTURE_TYPE_*</code>
+ *
+ * @return the index to this picture (1 based).
+ */
+ public int addPicture(byte[] pictureData, int format)
+ {
+ byte[] uid = newUID();
+ EscherBitmapBlip blipRecord = new EscherBitmapBlip();
+ blipRecord.setRecordId( (short) ( EscherBitmapBlip.RECORD_ID_START + format ) );
+ if (format == HSSFWorkbook.PICTURE_TYPE_PNG)
+ blipRecord.setOptions( (short) 0x6E00 ); // MSOBI
+ else if (format == HSSFWorkbook.PICTURE_TYPE_JPEG)
+ blipRecord.setOptions( (short) 0x46A0 ); // MSOBI
+ else if (format == HSSFWorkbook.PICTURE_TYPE_DIB)
+ blipRecord.setOptions( (short) 0x7A8 ); // MSOBI
+
+ blipRecord.setUID( uid );
+ blipRecord.setMarker( (byte) 0xFF );
+ blipRecord.setPictureData( pictureData );
+
+ EscherBSERecord r = new EscherBSERecord();
+ r.setRecordId( EscherBSERecord.RECORD_ID );
+ r.setOptions( (short) ( 0x0002 | ( format << 4 ) ) );
+ r.setBlipTypeMacOS( (byte) format );
+ r.setBlipTypeWin32( (byte) format );
+ r.setUid( uid );
+ r.setTag( (short) 0xFF );
+ r.setSize( pictureData.length + 25 );
+ r.setRef( 1 );
+ r.setOffset( 0 );
+ r.setBlipRecord( blipRecord );
+
+ return workbook.addBSERecord( r );
+ }
+ private byte[] newUID()
+ {
+ byte[] bytes = new byte[16];
+ return bytes;
+ }
}
diff --git a/src/java/org/apache/poi/util/DrawingDump.java b/src/java/org/apache/poi/util/DrawingDump.java
index 926d982ac9..5c801e1431 100644
--- a/src/java/org/apache/poi/util/DrawingDump.java
+++ b/src/java/org/apache/poi/util/DrawingDump.java
@@ -17,12 +17,11 @@
package org.apache.poi.util;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
/**
@@ -35,7 +34,15 @@ public class DrawingDump
POIFSFileSystem fs =
new POIFSFileSystem(new FileInputStream(args[0]));
HSSFWorkbook wb = new HSSFWorkbook(fs);
- HSSFSheet sheet = wb.getSheetAt(0);
- sheet.dumpDrawingRecords();
+ System.out.println( "Drawing group:" );
+ wb.dumpDrawingGroupRecords(true);
+
+ for (int sheetNum = 1; sheetNum <= wb.getNumberOfSheets(); sheetNum++)
+ {
+ System.out.println( "Sheet " + sheetNum + ":" );
+ HSSFSheet sheet = wb.getSheetAt(sheetNum - 1);
+ sheet.dumpDrawingRecords(true);
+ }
+
}
}
diff --git a/src/java/org/apache/poi/util/HexDump.java b/src/java/org/apache/poi/util/HexDump.java
index f6aeb59799..f6caba85c4 100644
--- a/src/java/org/apache/poi/util/HexDump.java
+++ b/src/java/org/apache/poi/util/HexDump.java
@@ -75,7 +75,7 @@ public class HexDump
{
if (data.length == 0)
{
- stream.write( "No Data".getBytes() );
+ stream.write( ("No Data" + System.getProperty( "line.separator")).getBytes() );
stream.flush();
return;
}
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java b/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java
index 8025e839e5..ce18f7025e 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java
@@ -98,8 +98,9 @@ public class TestEscherBSERecord extends TestCase
" Name: 5" + nl +
" Unused2: 6" + nl +
" Unused3: 7" + nl +
+ " blipRecord: null" + nl +
" Extra Data:" + nl +
- "No Data", record.toString() );
+ "No Data" + nl, record.toString() );
}
}
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherBlipWMFRecord.java
index 8b82135c41..aff89c29e3 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherBlipWMFRecord.java
@@ -21,7 +21,7 @@ import junit.framework.TestCase;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.HexRead;
-public class TestEscherBlipRecord extends TestCase
+public class TestEscherBlipWMFRecord extends TestCase
{
private String dataStr;
private byte[] data;
@@ -37,7 +37,7 @@ public class TestEscherBlipRecord extends TestCase
public void testSerialize() throws Exception
{
- EscherBlipRecord r = new EscherBlipRecord();
+ EscherBlipWMFRecord r = new EscherBlipWMFRecord();
r.setBoundaryLeft(1);
r.setBoundaryHeight(2);
r.setBoundaryTop(3);
@@ -52,7 +52,7 @@ public class TestEscherBlipRecord extends TestCase
(byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, });
r.setWidth(10);
r.setHeight(11);
- r.setRecordId(EscherBlipRecord.RECORD_ID_START);
+ r.setRecordId(EscherBlipWMFRecord.RECORD_ID_START);
r.setOptions((short)5420);
r.setData(new byte[] { (byte)0x01, (byte)0x02 } );
@@ -79,10 +79,10 @@ public class TestEscherBlipRecord extends TestCase
public void testFillFields() throws Exception
{
- EscherBlipRecord r = new EscherBlipRecord();
+ EscherBlipWMFRecord r = new EscherBlipWMFRecord();
r.fillFields( data, 0, new DefaultEscherRecordFactory());
- assertEquals( EscherBlipRecord.RECORD_ID_START, r.getRecordId() );
+ assertEquals( EscherBlipWMFRecord.RECORD_ID_START, r.getRecordId() );
assertEquals( 1, r.getBoundaryLeft() );
assertEquals( 2, r.getBoundaryHeight() );
assertEquals( 3, r.getBoundaryTop() );
@@ -100,12 +100,12 @@ public class TestEscherBlipRecord extends TestCase
public void testToString() throws Exception
{
- EscherBlipRecord r = new EscherBlipRecord();
+ EscherBlipWMFRecord r = new EscherBlipWMFRecord();
r.fillFields( data, 0, new DefaultEscherRecordFactory() );
String nl = System.getProperty("line.separator");
- assertEquals( "org.apache.poi.ddf.EscherBlipRecord:" + nl +
+ assertEquals( "org.apache.poi.ddf.EscherBlipWMFRecord:" + nl +
" RecordId: 0xF018" + nl +
" Options: 0x152C" + nl +
" Secondary UID: [01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, ]" + nl +
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java b/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java
index 473e03cc62..3fe0c762f8 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java
@@ -24,7 +24,7 @@ public class TestEscherBoolProperty extends TestCase
public void testToString() throws Exception
{
EscherBoolProperty p = new EscherBoolProperty((short)1, 1);
- assertEquals("propNum: 1, propName: unknown, complex: false, blipId: false, value: 1 (0x00000001)", p.toString());
+ assertEquals("propNum: 1, RAW: 0x0001, propName: unknown, complex: false, blipId: false, value: 1 (0x00000001)", p.toString());
}
}
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java
index 0491029d29..d8cdab4414 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java
@@ -58,7 +58,7 @@ public class TestEscherClientDataRecord extends TestCase
" RecordId: 0xF011" + nl +
" Options: 0x0002" + nl +
" Extra Data:" + nl +
- "No Data" ;
+ "No Data" + nl ;
assertEquals( expected, createRecord().toString() );
}
diff --git a/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java b/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java
index 8795de77ad..334eeb49df 100644
--- a/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java
+++ b/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java
@@ -150,7 +150,7 @@ public class TestEscherOptRecord extends TestCase
" recordId: 0x" + HexDump.toHex(EscherOptRecord.RECORD_ID) + nl +
" numchildren: 0" + nl +
" properties:" + nl +
- " propNum: 1, propName: unknown, complex: false, blipId: false, value: 1 (0x00000001)" + nl;
+ " propNum: 1, RAW: 0x0001, propName: unknown, complex: false, blipId: false, value: 1 (0x00000001)" + nl;
assertEquals( expected, r.toString());
}
diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheet.java b/src/testcases/org/apache/poi/hssf/model/TestSheet.java
index b11d93f015..8388788c49 100644
--- a/src/testcases/org/apache/poi/hssf/model/TestSheet.java
+++ b/src/testcases/org/apache/poi/hssf/model/TestSheet.java
@@ -19,16 +19,14 @@
package org.apache.poi.hssf.model;
import junit.framework.TestCase;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.record.BOFRecord;
-import org.apache.poi.hssf.record.EOFRecord;
-import org.apache.poi.hssf.record.DimensionsRecord;
+import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
-import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
-import java.util.List;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
/**
* Unit test for the Sheet class.
@@ -55,4 +53,232 @@ public class TestSheet extends TestCase
assertTrue( sheet.records.get(pos++) instanceof EOFRecord );
}
+ 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)
+ * <p>
+ * 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
+ }
+
+ /**
+ * 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/record/TestDrawingGroupRecord.java b/src/testcases/org/apache/poi/hssf/record/TestDrawingGroupRecord.java
index 20fbae92e3..f56bbddd73 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestDrawingGroupRecord.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestDrawingGroupRecord.java
@@ -23,6 +23,9 @@ import org.apache.poi.util.HexDump;
public class TestDrawingGroupRecord extends TestCase
{
+ static final int MAX_RECORD_SIZE = 8228;
+ private static final int MAX_DATA_SIZE = MAX_RECORD_SIZE - 4;
+
public void testGetRecordSize()
throws Exception
{
@@ -48,5 +51,93 @@ public class TestDrawingGroupRecord extends TestCase
assertEquals(28, size);
assertEquals(24, dggContainer.getRecordSize());
+
+
+ r = new DrawingGroupRecord( );
+ r.setRawData( new byte[MAX_DATA_SIZE] );
+ assertEquals( MAX_RECORD_SIZE, r.getRecordSize() );
+ r.setRawData( new byte[MAX_DATA_SIZE+1] );
+ assertEquals( MAX_RECORD_SIZE + 5, r.getRecordSize() );
+ r.setRawData( new byte[MAX_DATA_SIZE*2] );
+ assertEquals( MAX_RECORD_SIZE * 2, r.getRecordSize() );
+ r.setRawData( new byte[MAX_DATA_SIZE*2 + 1] );
+ assertEquals( MAX_RECORD_SIZE * 2 + 5, r.getRecordSize() );
+ }
+
+ public void testSerialize() throws Exception
+ {
+ // Check under max record size
+ DrawingGroupRecord r = new DrawingGroupRecord();
+ byte[] rawData = new byte[100];
+ rawData[0] = 100;
+ rawData[99] = (byte) 200;
+ r.setRawData( rawData );
+ byte[] buffer = new byte[r.getRecordSize()];
+ int size = r.serialize( 0, buffer );
+ assertEquals( 104, size );
+ assertEquals("[EB, 00, 64, 00, 64, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, C8, ]", HexDump.toHex(buffer));
+
+ // check at max record size
+ rawData = new byte[MAX_DATA_SIZE];
+ r.setRawData( rawData );
+ buffer = new byte[r.getRecordSize()];
+ size = r.serialize( 0, buffer );
+ assertEquals( MAX_RECORD_SIZE, size );
+
+ // check over max record size
+ rawData = new byte[MAX_DATA_SIZE+1];
+ rawData[rawData.length-1] = (byte) 255;
+ r.setRawData( rawData );
+ buffer = new byte[r.getRecordSize()];
+ size = r.serialize( 0, buffer );
+ assertEquals( MAX_RECORD_SIZE + 5, size );
+ assertEquals( "[EB, 00, 20, 20, ]", HexDump.toHex(cut(buffer, 0, 4) ));
+ assertEquals( "[00, EB, 00, 01, 00, FF, ]", HexDump.toHex(cut(buffer, MAX_RECORD_SIZE - 1, MAX_RECORD_SIZE + 5) ));
+
+ // check continue record
+ rawData = new byte[MAX_DATA_SIZE * 2 + 1];
+ rawData[rawData.length-1] = (byte) 255;
+ r.setRawData( rawData );
+ buffer = new byte[r.getRecordSize()];
+ size = r.serialize( 0, buffer );
+ assertEquals( MAX_RECORD_SIZE * 2 + 5, size );
+ assertEquals( MAX_RECORD_SIZE * 2 + 5, r.getRecordSize() );
+ assertEquals( "[EB, 00, 20, 20, ]", HexDump.toHex(cut(buffer, 0, 4) ));
+ assertEquals( "[EB, 00, 20, 20, ]", HexDump.toHex(cut(buffer, MAX_RECORD_SIZE, MAX_RECORD_SIZE + 4) ));
+ assertEquals( "[3C, 00, 01, 00, FF, ]", HexDump.toHex(cut(buffer, MAX_RECORD_SIZE * 2, MAX_RECORD_SIZE * 2 + 5) ));
+
+ // check continue record
+ rawData = new byte[664532];
+ r.setRawData( rawData );
+ buffer = new byte[r.getRecordSize()];
+ size = r.serialize( 0, buffer );
+ assertEquals( 664856, size );
+ assertEquals( 664856, r.getRecordSize() );
+ }
+
+ private byte[] cut( byte[] data, int fromInclusive, int toExclusive )
+ {
+ int length = toExclusive - fromInclusive;
+ byte[] result = new byte[length];
+ System.arraycopy( data, fromInclusive, result, 0, length);
+ return result;
+ }
+
+ public void testGrossSizeFromDataSize() throws Exception
+ {
+ for (int i = 0; i < MAX_RECORD_SIZE * 4; i += 11)
+ {
+ System.out.print( "data size = " + i + ", gross size = " + DrawingGroupRecord.grossSizeFromDataSize( i ) );
+ System.out.println( " Diff: " + (DrawingGroupRecord.grossSizeFromDataSize( i ) - i) );
+ }
+
+ assertEquals( 4, DrawingGroupRecord.grossSizeFromDataSize( 0 ) );
+ assertEquals( 5, DrawingGroupRecord.grossSizeFromDataSize( 1 ) );
+ assertEquals( MAX_RECORD_SIZE, DrawingGroupRecord.grossSizeFromDataSize( MAX_DATA_SIZE ) );
+ assertEquals( MAX_RECORD_SIZE + 5, DrawingGroupRecord.grossSizeFromDataSize( MAX_DATA_SIZE + 1 ) );
+ assertEquals( MAX_RECORD_SIZE * 2, DrawingGroupRecord.grossSizeFromDataSize( MAX_DATA_SIZE * 2 ) );
+ assertEquals( MAX_RECORD_SIZE * 2 + 5, DrawingGroupRecord.grossSizeFromDataSize( MAX_DATA_SIZE * 2 + 1 ) );
}
+
+
}
diff --git a/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java b/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
index 248e1e41f0..53323b8d0c 100644
--- a/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
+++ b/src/testcases/org/apache/poi/hssf/record/TestEscherAggregate.java
@@ -17,14 +17,13 @@
package org.apache.poi.hssf.record;
import junit.framework.TestCase;
-import org.apache.poi.util.HexRead;
-import org.apache.poi.util.HexDump;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherClientDataRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherDggRecord;
-import org.apache.poi.hssf.model.DrawingManager;
-import org.apache.poi.hssf.model.Sheet;
+import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.hssf.model.DrawingManager2;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.HexRead;
import java.util.ArrayList;
import java.util.List;
@@ -82,7 +81,7 @@ public class TestEscherAggregate extends TestCase
records.add( d2 );
records.add( r2 );
- DrawingManager drawingManager = new DrawingManager(new EscherDggRecord() );
+ DrawingManager2 drawingManager = new DrawingManager2(new EscherDggRecord() );
EscherAggregate aggregate = EscherAggregate.createAggregate( records, 0, drawingManager );
assertEquals( 1, aggregate.getEscherRecords().size() );
diff --git a/src/testcases/org/apache/poi/util/TestHexDump.java b/src/testcases/org/apache/poi/util/TestHexDump.java
index 6189d3e441..d19b79fe70 100644
--- a/src/testcases/org/apache/poi/util/TestHexDump.java
+++ b/src/testcases/org/apache/poi/util/TestHexDump.java
@@ -23,6 +23,7 @@ import junit.framework.*;
import java.io.*;
/**
+ * @author Glen Stampoultzis (glens at apache.org)
* @author Marc Johnson (mjohnson at apache dot org)
*/
@@ -281,7 +282,8 @@ public class TestHexDump
// verify proper behaviour with empty byte array
ByteArrayOutputStream os = new ByteArrayOutputStream( );
HexDump.dump( new byte[0], 0, os, 0 );
- assertEquals( "No Data", os.toString() );
+ assertEquals( "No Data" + System.getProperty( "line.separator"), os.toString() );
+
}
public void testToHex()
@@ -289,7 +291,7 @@ public class TestHexDump
{
assertEquals( "000A", HexDump.toHex((short)0xA));
assertEquals( "0A", HexDump.toHex((byte)0xA));
- assertEquals( "0000000A", HexDump.toHex((int)0xA));
+ assertEquals( "0000000A", HexDump.toHex(0xA));
assertEquals( "FFFF", HexDump.toHex((short)0xFFFF));
diff --git a/src/testcases/org/apache/poi/util/TestLittleEndian.java b/src/testcases/org/apache/poi/util/TestLittleEndian.java
index 4e63ac9685..98b8b63d7a 100644
--- a/src/testcases/org/apache/poi/util/TestLittleEndian.java
+++ b/src/testcases/org/apache/poi/util/TestLittleEndian.java
@@ -18,11 +18,12 @@
package org.apache.poi.util;
+import junit.framework.TestCase;
import org.apache.poi.util.LittleEndian.BufferUnderrunException;
-import java.io.*;
-
-import junit.framework.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
/**
* Class to test LittleEndian functionality
@@ -39,7 +40,6 @@ public class TestLittleEndian
*
* @param name
*/
-
public TestLittleEndian(String name)
{
super(name);