From e4d9311a5aced3ca99a3a27010b9f0321c1ae3b4 Mon Sep 17 00:00:00 2001 From: Henri Yandell Date: Fri, 22 Dec 2006 20:56:04 +0000 Subject: [PATCH] Applying dos2unix on some of the Java files. The copy2license script isn't picking up the dos line endings. Hopefully not a problem for anyone git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@489760 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/record/FilePassRecord.java | 212 +-- .../poi/hssf/record/WriteProtectRecord.java | 182 +- .../poi/hssf/record/formula/AreaErrPtg.java | 176 +- .../apache/poi/hssf/util/PaneInformation.java | 208 +-- .../src/org/apache/poi/hslf/blip/Bitmap.java | 94 +- .../src/org/apache/poi/hslf/blip/DIB.java | 162 +- .../src/org/apache/poi/hslf/blip/EMF.java | 184 +- .../src/org/apache/poi/hslf/blip/JPEG.java | 86 +- .../org/apache/poi/hslf/blip/Metafile.java | 246 +-- .../src/org/apache/poi/hslf/blip/PICT.java | 234 +-- .../src/org/apache/poi/hslf/blip/PNG.java | 136 +- .../src/org/apache/poi/hslf/blip/WMF.java | 374 ++-- .../poi/hslf/extractor/ImageExtractor.java | 156 +- .../org/apache/poi/hslf/model/AutoShape.java | 122 +- .../org/apache/poi/hslf/model/Background.java | 74 +- .../src/org/apache/poi/hslf/model/Fill.java | 456 ++--- .../src/org/apache/poi/hslf/model/Line.java | 256 +-- .../apache/poi/hslf/model/PPGraphics2D.java | 1024 +++++----- .../org/apache/poi/hslf/model/Picture.java | 358 ++-- .../apache/poi/hslf/model/Placeholder.java | 194 +- .../src/org/apache/poi/hslf/model/Shape.java | 614 +++--- .../apache/poi/hslf/model/ShapeFactory.java | 138 +- .../org/apache/poi/hslf/model/ShapeGroup.java | 360 ++-- .../org/apache/poi/hslf/model/ShapeTypes.java | 514 ++--- .../apache/poi/hslf/model/SimpleShape.java | 434 ++--- .../org/apache/poi/hslf/model/TextBox.java | 1008 +++++----- .../poi/hslf/record/OEPlaceholderAtom.java | 400 ++-- .../poi/hslf/record/OutlineTextRefAtom.java | 214 +-- .../poi/hslf/record/PPDrawingGroup.java | 206 +- .../poi/hslf/usermodel/PictureData.java | 426 ++--- .../poi/hssf/record/formula/functions/If.java | 78 +- .../formula/functions/LogicalFunction.java | 62 +- .../apache/poi/hwpf/model/SavedByEntry.java | 170 +- .../apache/poi/hwpf/model/SavedByTable.java | 242 +-- .../apache/poi/hslf/model/TestBackground.java | 364 ++-- .../poi/hslf/model/TestPPGraphics2D.java | 176 +- .../poi/hslf/model/TestSetBoldItalic.java | 166 +- .../org/apache/poi/hslf/model/TestShapes.java | 452 ++--- .../org/apache/poi/hslf/model/TestSlides.java | 366 ++-- .../poi/hslf/usermodel/TestPictures.java | 788 ++++---- .../poi/hwpf/model/TestSavedByTable.java | 182 +- .../poi/hpsf/basic/TestMetaDataIPI.java | 1652 ++++++++--------- .../record/formula/AbstractPtgTestCase.java | 122 +- .../hssf/usermodel/TestUnicodeWorkbook.java | 262 +-- .../poifs/filesystem/TestPropertySorter.java | 304 +-- 45 files changed, 7317 insertions(+), 7317 deletions(-) diff --git a/src/java/org/apache/poi/hssf/record/FilePassRecord.java b/src/java/org/apache/poi/hssf/record/FilePassRecord.java index b4ac4d0830..f1e593e8c8 100644 --- a/src/java/org/apache/poi/hssf/record/FilePassRecord.java +++ b/src/java/org/apache/poi/hssf/record/FilePassRecord.java @@ -1,106 +1,106 @@ - -/* ==================================================================== - Copyright 2002-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndian; - -/** - * Title: File Pass Record

- * Description: Indicates that the record after this record are encrypted. HSSF does not support encrypted excel workbooks - * and the presence of this record will cause processing to be aborted.

- * REFERENCE: PG 420 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

- * @author Jason Height (jheight at chariot dot net dot au) - * @version 3.0-pre - */ - -public class FilePassRecord - extends Record -{ - public final static short sid = 0x2F; - private int field_1_encryptedpassword; - - public FilePassRecord() - { - } - - /** - * Constructs a FILEPASS record and sets its fields appropriately. - * - * @param id id must be 0x84 or an exception will be throw upon validation - * @param size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - */ - - public FilePassRecord(RecordInputStream in) - { - super(in); - } - - protected void validateSid(short id) - { - if (id != sid) - { - throw new RecordFormatException("NOT A FILEPASS RECORD"); - } - } - - protected void fillFields(RecordInputStream in) - { - field_1_encryptedpassword = in.readInt(); - - //Whilst i have read in the password, HSSF currently has no plans to support/decrypt the remainder - //of this workbook - throw new RecordFormatException("HSSF does not currently support encrypted workbooks"); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[FILEPASS]\n"); - buffer.append(" .password = ").append(field_1_encryptedpassword) - .append("\n"); - buffer.append("[/FILEPASS]\n"); - return buffer.toString(); - } - - public int serialize(int offset, byte [] data) - { - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, ( short ) 0x4); - LittleEndian.putInt(data, 4 + offset, ( short ) field_1_encryptedpassword); - return getRecordSize(); - } - - public int getRecordSize() - { - return 8; - } - - public short getSid() - { - return sid; - } - - public Object clone() { - FilePassRecord rec = new FilePassRecord(); - rec.field_1_encryptedpassword = field_1_encryptedpassword; - return rec; - } -} + +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +package org.apache.poi.hssf.record; + +import org.apache.poi.util.LittleEndian; + +/** + * Title: File Pass Record

+ * Description: Indicates that the record after this record are encrypted. HSSF does not support encrypted excel workbooks + * and the presence of this record will cause processing to be aborted.

+ * REFERENCE: PG 420 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

+ * @author Jason Height (jheight at chariot dot net dot au) + * @version 3.0-pre + */ + +public class FilePassRecord + extends Record +{ + public final static short sid = 0x2F; + private int field_1_encryptedpassword; + + public FilePassRecord() + { + } + + /** + * Constructs a FILEPASS record and sets its fields appropriately. + * + * @param id id must be 0x84 or an exception will be throw upon validation + * @param size the size of the data area of the record + * @param data data of the record (should not contain sid/len) + */ + + public FilePassRecord(RecordInputStream in) + { + super(in); + } + + protected void validateSid(short id) + { + if (id != sid) + { + throw new RecordFormatException("NOT A FILEPASS RECORD"); + } + } + + protected void fillFields(RecordInputStream in) + { + field_1_encryptedpassword = in.readInt(); + + //Whilst i have read in the password, HSSF currently has no plans to support/decrypt the remainder + //of this workbook + throw new RecordFormatException("HSSF does not currently support encrypted workbooks"); + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + + buffer.append("[FILEPASS]\n"); + buffer.append(" .password = ").append(field_1_encryptedpassword) + .append("\n"); + buffer.append("[/FILEPASS]\n"); + return buffer.toString(); + } + + public int serialize(int offset, byte [] data) + { + LittleEndian.putShort(data, 0 + offset, sid); + LittleEndian.putShort(data, 2 + offset, ( short ) 0x4); + LittleEndian.putInt(data, 4 + offset, ( short ) field_1_encryptedpassword); + return getRecordSize(); + } + + public int getRecordSize() + { + return 8; + } + + public short getSid() + { + return sid; + } + + public Object clone() { + FilePassRecord rec = new FilePassRecord(); + rec.field_1_encryptedpassword = field_1_encryptedpassword; + return rec; + } +} diff --git a/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java b/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java index 4830e39ae9..ba21993f0d 100644 --- a/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java +++ b/src/java/org/apache/poi/hssf/record/WriteProtectRecord.java @@ -1,91 +1,91 @@ - -/* ==================================================================== - Copyright 2002-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - - -package org.apache.poi.hssf.record; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -/** - * Title: Write Protect Record

- * Description: Indicated that the sheet/workbook is write protected. - * REFERENCE: PG 425 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

- * @version 3.0-pre - */ - -public class WriteProtectRecord - extends Record -{ - public final static short sid = 0x86; - - public WriteProtectRecord() - { - } - - /** - * Constructs a WriteAccess record and sets its fields appropriately. - * - * @param id id must be 0x5c or an exception will be throw upon validation - * @param size the size of the data area of the record - * @param data data of the record (should not contain sid/len) - */ - - public WriteProtectRecord(RecordInputStream in) - { - super(in); - } - - protected void validateSid(short id) - { - if (id != sid) - { - throw new RecordFormatException("NOT A WRITEPROTECT RECORD"); - } - } - - protected void fillFields(RecordInputStream in) - { - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[WRITEPROTECT]\n"); - buffer.append("[/WRITEPROTECT]\n"); - return buffer.toString(); - } - - public int serialize(int offset, byte [] data) - { - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, (short)0); - - return getRecordSize(); - } - - public int getRecordSize() - { - return 4; - } - - public short getSid() - { - return sid; - } -} + +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +package org.apache.poi.hssf.record; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.StringUtil; + +/** + * Title: Write Protect Record

+ * Description: Indicated that the sheet/workbook is write protected. + * REFERENCE: PG 425 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

+ * @version 3.0-pre + */ + +public class WriteProtectRecord + extends Record +{ + public final static short sid = 0x86; + + public WriteProtectRecord() + { + } + + /** + * Constructs a WriteAccess record and sets its fields appropriately. + * + * @param id id must be 0x5c or an exception will be throw upon validation + * @param size the size of the data area of the record + * @param data data of the record (should not contain sid/len) + */ + + public WriteProtectRecord(RecordInputStream in) + { + super(in); + } + + protected void validateSid(short id) + { + if (id != sid) + { + throw new RecordFormatException("NOT A WRITEPROTECT RECORD"); + } + } + + protected void fillFields(RecordInputStream in) + { + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + + buffer.append("[WRITEPROTECT]\n"); + buffer.append("[/WRITEPROTECT]\n"); + return buffer.toString(); + } + + public int serialize(int offset, byte [] data) + { + LittleEndian.putShort(data, 0 + offset, sid); + LittleEndian.putShort(data, 2 + offset, (short)0); + + return getRecordSize(); + } + + public int getRecordSize() + { + return 4; + } + + public short getSid() + { + return sid; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java index 8144354f68..dc48c3d9a2 100644 --- a/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/AreaErrPtg.java @@ -1,88 +1,88 @@ -/* ==================================================================== - Copyright 2003-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.formula; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.BitField; - -import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.RecordInputStream; - -/** - * AreaErr - handles deleted cell area references. - * - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public class AreaErrPtg extends AreaPtg -{ - public final static byte sid = 0x2b; - - private AreaErrPtg() - { - //Required for clone methods - super(); - } - - public AreaErrPtg(RecordInputStream in) - { - super(in); - } - - public String toString() - { - StringBuffer buffer = new StringBuffer(); - - buffer.append("AreaErrPtg\n"); - buffer.append("firstRow = " + getFirstRow()).append("\n"); - buffer.append("lastRow = " + getLastRow()).append("\n"); - buffer.append("firstCol = " + getFirstColumn()).append("\n"); - buffer.append("lastCol = " + getLastColumn()).append("\n"); - buffer.append("firstColRowRel= " - + isFirstRowRelative()).append("\n"); - buffer.append("lastColRowRel = " - + isLastRowRelative()).append("\n"); - buffer.append("firstColRel = " + isFirstColRelative()).append("\n"); - buffer.append("lastColRel = " + isLastColRelative()).append("\n"); - return buffer.toString(); - } - - public void writeBytes(byte [] array, int offset) { - super.writeBytes(array, offset); - array[offset] = (byte) (sid + ptgClass); - } - - public String toFormulaString(Workbook book) - { - return "#REF!"; - } - - public Object clone() - { - AreaErrPtg ptg = new AreaErrPtg(); - ptg.setFirstRow(getFirstRow()); - ptg.setFirstColumn(getFirstColumn()); - ptg.setLastRow(getLastRow()); - ptg.setLastColumn(getLastColumn()); - ptg.setFirstColRelative(isFirstColRelative()); - ptg.setLastColRelative(isLastColRelative()); - ptg.setFirstRowRelative(isFirstRowRelative()); - ptg.setLastRowRelative(isLastRowRelative()); - ptg.setClass(ptgClass); - return ptg; - } -} - +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.BitField; + +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.RecordInputStream; + +/** + * AreaErr - handles deleted cell area references. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class AreaErrPtg extends AreaPtg +{ + public final static byte sid = 0x2b; + + private AreaErrPtg() + { + //Required for clone methods + super(); + } + + public AreaErrPtg(RecordInputStream in) + { + super(in); + } + + public String toString() + { + StringBuffer buffer = new StringBuffer(); + + buffer.append("AreaErrPtg\n"); + buffer.append("firstRow = " + getFirstRow()).append("\n"); + buffer.append("lastRow = " + getLastRow()).append("\n"); + buffer.append("firstCol = " + getFirstColumn()).append("\n"); + buffer.append("lastCol = " + getLastColumn()).append("\n"); + buffer.append("firstColRowRel= " + + isFirstRowRelative()).append("\n"); + buffer.append("lastColRowRel = " + + isLastRowRelative()).append("\n"); + buffer.append("firstColRel = " + isFirstColRelative()).append("\n"); + buffer.append("lastColRel = " + isLastColRelative()).append("\n"); + return buffer.toString(); + } + + public void writeBytes(byte [] array, int offset) { + super.writeBytes(array, offset); + array[offset] = (byte) (sid + ptgClass); + } + + public String toFormulaString(Workbook book) + { + return "#REF!"; + } + + public Object clone() + { + AreaErrPtg ptg = new AreaErrPtg(); + ptg.setFirstRow(getFirstRow()); + ptg.setFirstColumn(getFirstColumn()); + ptg.setLastRow(getLastRow()); + ptg.setLastColumn(getLastColumn()); + ptg.setFirstColRelative(isFirstColRelative()); + ptg.setLastColRelative(isLastColRelative()); + ptg.setFirstRowRelative(isFirstRowRelative()); + ptg.setLastRowRelative(isLastRowRelative()); + ptg.setClass(ptgClass); + return ptg; + } +} + diff --git a/src/java/org/apache/poi/hssf/util/PaneInformation.java b/src/java/org/apache/poi/hssf/util/PaneInformation.java index 4d5eeeeeec..db0072d4ec 100644 --- a/src/java/org/apache/poi/hssf/util/PaneInformation.java +++ b/src/java/org/apache/poi/hssf/util/PaneInformation.java @@ -1,104 +1,104 @@ -/* ==================================================================== - Copyright 2002-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.util; - -/** - * Holds information regarding a split plane or freeze plane for a sheet. - * - */ -public class PaneInformation -{ - /** Constant for active pane being the lower right*/ - public static final byte PANE_LOWER_RIGHT = (byte)0; - /** Constant for active pane being the upper right*/ - public static final byte PANE_UPPER_RIGHT = (byte)1; - /** Constant for active pane being the lower left*/ - public static final byte PANE_LOWER_LEFT = (byte)2; - /** Constant for active pane being the upper left*/ - public static final byte PANE_UPPER_LEFT = (byte)3; - - private short x; - private short y; - private short topRow; - private short leftColumn; - private byte activePane; - private boolean frozen = false; - - public PaneInformation(short x, short y, short top, short left, byte active, boolean frozen) { - this.x = x; - this.y = y; - this.topRow = top; - this.leftColumn = left; - this.activePane = active; - this.frozen = frozen; - } - - - /** - * Returns the vertical position of the split. - * @return 0 if there is no vertical spilt, - * or for a freeze pane the number of columns in the TOP pane, - * or for a split plane the position of the split in 1/20th of a point. - */ - public short getVerticalSplitPosition() { - return x; - } - - /** - * Returns the horizontal position of the split. - * @return 0 if there is no horizontal spilt, - * or for a freeze pane the number of rows in the LEFT pane, - * or for a split plane the position of the split in 1/20th of a point. - */ - public short getHorizontalSplitPosition() { - return y; - } - - /** - * For a horizontal split returns the top row in the BOTTOM pane. - * @return 0 if there is no horizontal split, or the top row of the bottom pane. - */ - public short getHorizontalSplitTopRow() { - return topRow; - } - - /** - * For a vertical split returns the left column in the RIGHT pane. - * @return 0 if there is no vertical split, or the left column in the RIGHT pane. - */ - public short getVerticalSplitLeftColumn() { - return leftColumn; - } - - /** - * Returns the active pane - * @see PANE_LOWER_RIGHT - * @see PANE_UPPER_RIGHT - * @see PANE_LOWER_LEFT - * @see PANE_UPPER_LEFT - * @return the active pane. - */ - public byte getActivePane() { - return activePane; - } - - /** Returns true if this is a Freeze pane, false if it is a split pane. - */ - public boolean isFreezePane() { - return frozen; - } -} +/* ==================================================================== + Copyright 2002-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.util; + +/** + * Holds information regarding a split plane or freeze plane for a sheet. + * + */ +public class PaneInformation +{ + /** Constant for active pane being the lower right*/ + public static final byte PANE_LOWER_RIGHT = (byte)0; + /** Constant for active pane being the upper right*/ + public static final byte PANE_UPPER_RIGHT = (byte)1; + /** Constant for active pane being the lower left*/ + public static final byte PANE_LOWER_LEFT = (byte)2; + /** Constant for active pane being the upper left*/ + public static final byte PANE_UPPER_LEFT = (byte)3; + + private short x; + private short y; + private short topRow; + private short leftColumn; + private byte activePane; + private boolean frozen = false; + + public PaneInformation(short x, short y, short top, short left, byte active, boolean frozen) { + this.x = x; + this.y = y; + this.topRow = top; + this.leftColumn = left; + this.activePane = active; + this.frozen = frozen; + } + + + /** + * Returns the vertical position of the split. + * @return 0 if there is no vertical spilt, + * or for a freeze pane the number of columns in the TOP pane, + * or for a split plane the position of the split in 1/20th of a point. + */ + public short getVerticalSplitPosition() { + return x; + } + + /** + * Returns the horizontal position of the split. + * @return 0 if there is no horizontal spilt, + * or for a freeze pane the number of rows in the LEFT pane, + * or for a split plane the position of the split in 1/20th of a point. + */ + public short getHorizontalSplitPosition() { + return y; + } + + /** + * For a horizontal split returns the top row in the BOTTOM pane. + * @return 0 if there is no horizontal split, or the top row of the bottom pane. + */ + public short getHorizontalSplitTopRow() { + return topRow; + } + + /** + * For a vertical split returns the left column in the RIGHT pane. + * @return 0 if there is no vertical split, or the left column in the RIGHT pane. + */ + public short getVerticalSplitLeftColumn() { + return leftColumn; + } + + /** + * Returns the active pane + * @see PANE_LOWER_RIGHT + * @see PANE_UPPER_RIGHT + * @see PANE_LOWER_LEFT + * @see PANE_UPPER_LEFT + * @return the active pane. + */ + public byte getActivePane() { + return activePane; + } + + /** Returns true if this is a Freeze pane, false if it is a split pane. + */ + public boolean isFreezePane() { + return frozen; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java b/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java index c37674d16a..7bd8421bd8 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/Bitmap.java @@ -1,47 +1,47 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.usermodel.PictureData; - -import java.io.IOException; -import java.io.ByteArrayOutputStream; - -/** - * Represents a bitmap picture data: JPEG or PNG. - * The data is not compressed and the exact file content is written in the stream. - * - * @author Yegor Kozlov - */ -public abstract class Bitmap extends PictureData { - - public byte[] getData(){ - byte[] rawdata = getRawData(); - byte[] imgdata = new byte[rawdata.length-17]; - System.arraycopy(rawdata, 17, imgdata, 0, imgdata.length); - return imgdata; - } - - public void setData(byte[] data) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] checksum = getChecksum(data); - out.write(checksum); - out.write(0); - out.write(data); - - setRawData(out.toByteArray()); - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.usermodel.PictureData; + +import java.io.IOException; +import java.io.ByteArrayOutputStream; + +/** + * Represents a bitmap picture data: JPEG or PNG. + * The data is not compressed and the exact file content is written in the stream. + * + * @author Yegor Kozlov + */ +public abstract class Bitmap extends PictureData { + + public byte[] getData(){ + byte[] rawdata = getRawData(); + byte[] imgdata = new byte[rawdata.length-17]; + System.arraycopy(rawdata, 17, imgdata, 0, imgdata.length); + return imgdata; + } + + public void setData(byte[] data) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] checksum = getChecksum(data); + out.write(checksum); + out.write(0); + out.write(data); + + setRawData(out.toByteArray()); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java b/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java index 362bbcb434..4f32d6f9fc 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/DIB.java @@ -1,81 +1,81 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.model.Picture; -import org.apache.poi.util.LittleEndian; - -import java.io.IOException; - -/** - * Represents a DIB picture data in a PPT file - * - * @author Yegor Kozlov - */ -public class DIB extends Bitmap { - /** - * Size of the BITMAPFILEHEADER structure preceding the actual DIB bytes - */ - public static final int HEADER_SIZE = 14; - - /** - * @return type of this picture - * @see org.apache.poi.hslf.model.Picture#DIB - */ - public int getType(){ - return Picture.DIB; - } - - /** - * DIB signature is 0x7A80 - * - * @return DIB signature (0x7A80) - */ - public int getSignature(){ - return 0x7A80; - } - - public byte[] getData(){ - byte[] data = super.getData(); - - // bitmap file-header, corresponds to a - // Windows BITMAPFILEHEADER structure - // (For more information, consult the Windows API Programmer's reference ) - byte[] header = new byte[HEADER_SIZE]; - //Specifies the file type. It must be set to the signature word BM (0x4D42) to indicate bitmap. - LittleEndian.putInt(header, 0, 0x4D42); - //Specifies the size, in bytes, of the bitmap file. - LittleEndian.putInt(header, 2, data.length); //DIB length including the header - //Reserved; set to zero - LittleEndian.putInt(header, 6, 0); - //the offset, in bytes, from the header to the bitmap bits (looks like it is always 2) - LittleEndian.putInt(header, 10, 2); - - //DIB data is the header + dib bytes - byte[] dib = new byte[header.length + data.length]; - System.arraycopy(header, 0, dib, 0, header.length); - System.arraycopy(data, 0, dib, header.length, data.length); - - return dib; - } - - public void setData(byte[] data) throws IOException { - //cut off the bitmap file-header - byte[] dib = new byte[data.length-HEADER_SIZE]; - System.arraycopy(data, HEADER_SIZE, dib, 0, dib.length); - super.setData(dib); - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.util.LittleEndian; + +import java.io.IOException; + +/** + * Represents a DIB picture data in a PPT file + * + * @author Yegor Kozlov + */ +public class DIB extends Bitmap { + /** + * Size of the BITMAPFILEHEADER structure preceding the actual DIB bytes + */ + public static final int HEADER_SIZE = 14; + + /** + * @return type of this picture + * @see org.apache.poi.hslf.model.Picture#DIB + */ + public int getType(){ + return Picture.DIB; + } + + /** + * DIB signature is 0x7A80 + * + * @return DIB signature (0x7A80) + */ + public int getSignature(){ + return 0x7A80; + } + + public byte[] getData(){ + byte[] data = super.getData(); + + // bitmap file-header, corresponds to a + // Windows BITMAPFILEHEADER structure + // (For more information, consult the Windows API Programmer's reference ) + byte[] header = new byte[HEADER_SIZE]; + //Specifies the file type. It must be set to the signature word BM (0x4D42) to indicate bitmap. + LittleEndian.putInt(header, 0, 0x4D42); + //Specifies the size, in bytes, of the bitmap file. + LittleEndian.putInt(header, 2, data.length); //DIB length including the header + //Reserved; set to zero + LittleEndian.putInt(header, 6, 0); + //the offset, in bytes, from the header to the bitmap bits (looks like it is always 2) + LittleEndian.putInt(header, 10, 2); + + //DIB data is the header + dib bytes + byte[] dib = new byte[header.length + data.length]; + System.arraycopy(header, 0, dib, 0, header.length); + System.arraycopy(data, 0, dib, header.length, data.length); + + return dib; + } + + public void setData(byte[] data) throws IOException { + //cut off the bitmap file-header + byte[] dib = new byte[data.length-HEADER_SIZE]; + System.arraycopy(data, HEADER_SIZE, dib, 0, dib.length); + super.setData(dib); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java index a50240368e..28cb0679f1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/EMF.java @@ -1,92 +1,92 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.model.Picture; -import org.apache.poi.hslf.model.Shape; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; - -/** - * Represents EMF (Windows Enhanced Metafile) picture data. - * - * @author Yegor Kozlov - */ -public class EMF extends Metafile { - - /** - * Extract compressed EMF data from a ppt - */ - public byte[] getData(){ - try { - byte[] rawdata = getRawData(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream is = new ByteArrayInputStream( rawdata ); - Header header = new Header(); - header.read(rawdata, CHECKSUM_SIZE); - is.skip(header.getSize() + CHECKSUM_SIZE); - - InflaterInputStream inflater = new InflaterInputStream( is ); - byte[] chunk = new byte[4096]; - int count; - while ((count = inflater.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - inflater.close(); - return out.toByteArray(); - } catch (IOException e){ - throw new RuntimeException(e); - } - } - - public void setData(byte[] data) throws IOException { - byte[] compressed = compress(data, 0, data.length); - - Header header = new Header(); - header.wmfsize = data.length; - //we don't have a EMF reader in java, have to set default image size 200x200 - header.bounds = new java.awt.Rectangle(0, 0, 200, 200); - header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, header.bounds.height*Shape.EMU_PER_POINT); - header.zipsize = compressed.length; - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(checksum); - header.write(out); - out.write(compressed); - - setRawData(out.toByteArray()); - } - - public int getType(){ - return Picture.EMF; - } - - /** - * EMF signature is 0x3D40 - * - * @return EMF signature (0x3D40) - */ - public int getSignature(){ - return 0x3D40; - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.hslf.model.Shape; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; + +/** + * Represents EMF (Windows Enhanced Metafile) picture data. + * + * @author Yegor Kozlov + */ +public class EMF extends Metafile { + + /** + * Extract compressed EMF data from a ppt + */ + public byte[] getData(){ + try { + byte[] rawdata = getRawData(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + InputStream is = new ByteArrayInputStream( rawdata ); + Header header = new Header(); + header.read(rawdata, CHECKSUM_SIZE); + is.skip(header.getSize() + CHECKSUM_SIZE); + + InflaterInputStream inflater = new InflaterInputStream( is ); + byte[] chunk = new byte[4096]; + int count; + while ((count = inflater.read(chunk)) >=0 ) { + out.write(chunk,0,count); + } + inflater.close(); + return out.toByteArray(); + } catch (IOException e){ + throw new RuntimeException(e); + } + } + + public void setData(byte[] data) throws IOException { + byte[] compressed = compress(data, 0, data.length); + + Header header = new Header(); + header.wmfsize = data.length; + //we don't have a EMF reader in java, have to set default image size 200x200 + header.bounds = new java.awt.Rectangle(0, 0, 200, 200); + header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, header.bounds.height*Shape.EMU_PER_POINT); + header.zipsize = compressed.length; + + byte[] checksum = getChecksum(data); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(checksum); + header.write(out); + out.write(compressed); + + setRawData(out.toByteArray()); + } + + public int getType(){ + return Picture.EMF; + } + + /** + * EMF signature is 0x3D40 + * + * @return EMF signature (0x3D40) + */ + public int getSignature(){ + return 0x3D40; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java b/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java index 852e4c6737..cdf5916fc2 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/JPEG.java @@ -1,43 +1,43 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.model.Picture; - -/** - * Represents a JPEG picture data in a PPT file - * - * @author Yegor Kozlov - */ -public class JPEG extends Bitmap { - - /** - * @return type of this picture - * @see org.apache.poi.hslf.model.Picture#JPEG - */ - public int getType(){ - return Picture.JPEG; - } - - /** - * JPEG signature is 0x46A0 - * - * @return JPEG signature (0x46A0) - */ - public int getSignature(){ - return 0x46A0; - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; + +/** + * Represents a JPEG picture data in a PPT file + * + * @author Yegor Kozlov + */ +public class JPEG extends Bitmap { + + /** + * @return type of this picture + * @see org.apache.poi.hslf.model.Picture#JPEG + */ + public int getType(){ + return Picture.JPEG; + } + + /** + * JPEG signature is 0x46A0 + * + * @return JPEG signature (0x46A0) + */ + public int getSignature(){ + return 0x46A0; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java b/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java index 1c00f21c56..c96c7b5aa7 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/Metafile.java @@ -1,123 +1,123 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hslf.usermodel.PictureData; - -import java.awt.*; -import java.io.*; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.InflaterInputStream; - -/** - * Represents a metafile picture which can be one of the following types: EMF, WMF, or PICT. - * A metafile is stored compressed using the ZIP deflate/inflate algorithm. - * - * @author Yegor Kozlov - */ -public abstract class Metafile extends PictureData { - - /** - * A structure which represents a 34-byte header preceeding the compressed metafile data - * - * @author Yegor Kozlov - */ - public static class Header{ - - /** - * size of the original file - */ - public int wmfsize; - - /** - * Boundary of the metafile drawing commands - */ - public Rectangle bounds; - - /** - * Size of the metafile in EMUs - */ - public Dimension size; - - /** - * size of the compressed metafile data - */ - public int zipsize; - - /** - * Reserved. Always 0. - */ - public int compression; - - /** - * Reserved. Always 254. - */ - public int filter = 254; - - public void read(byte[] data, int offset){ - int pos = offset; - wmfsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - int left = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int top = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int right = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int bottom = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - bounds = new Rectangle(left, top, right-left, bottom-top); - int width = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - int height = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - size = new Dimension(width, height); - - zipsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - compression = LittleEndian.getUnsignedByte(data, pos); pos++; - filter = LittleEndian.getUnsignedByte(data, pos); pos++; - } - - public void write(OutputStream out) throws IOException { - byte[] header = new byte[34]; - int pos = 0; - LittleEndian.putInt(header, pos, wmfsize); pos += LittleEndian.INT_SIZE; //hmf - - LittleEndian.putInt(header, pos, bounds.x); pos += LittleEndian.INT_SIZE; //left - LittleEndian.putInt(header, pos, bounds.y); pos += LittleEndian.INT_SIZE; //top - LittleEndian.putInt(header, pos, bounds.x + bounds.width); pos += LittleEndian.INT_SIZE; //right - LittleEndian.putInt(header, pos, bounds.y + bounds.height); pos += LittleEndian.INT_SIZE; //bottom - LittleEndian.putInt(header, pos, size.width); pos += LittleEndian.INT_SIZE; //inch - LittleEndian.putInt(header, pos, size.height); pos += LittleEndian.INT_SIZE; //inch - LittleEndian.putInt(header, pos, zipsize); pos += LittleEndian.INT_SIZE; //inch - - header[pos] = 0; pos ++; - header[pos] = (byte)filter; pos ++; - - out.write(header); - } - - public int getSize(){ - return 34; - } - } - - protected byte[] compress(byte[] bytes, int offset, int length) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DeflaterOutputStream deflater = new DeflaterOutputStream( out ); - deflater.write(bytes, offset, length); - deflater.close(); - return out.toByteArray(); - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.hslf.usermodel.PictureData; + +import java.awt.*; +import java.io.*; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.InflaterInputStream; + +/** + * Represents a metafile picture which can be one of the following types: EMF, WMF, or PICT. + * A metafile is stored compressed using the ZIP deflate/inflate algorithm. + * + * @author Yegor Kozlov + */ +public abstract class Metafile extends PictureData { + + /** + * A structure which represents a 34-byte header preceeding the compressed metafile data + * + * @author Yegor Kozlov + */ + public static class Header{ + + /** + * size of the original file + */ + public int wmfsize; + + /** + * Boundary of the metafile drawing commands + */ + public Rectangle bounds; + + /** + * Size of the metafile in EMUs + */ + public Dimension size; + + /** + * size of the compressed metafile data + */ + public int zipsize; + + /** + * Reserved. Always 0. + */ + public int compression; + + /** + * Reserved. Always 254. + */ + public int filter = 254; + + public void read(byte[] data, int offset){ + int pos = offset; + wmfsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + + int left = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + int top = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + int right = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + int bottom = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + + bounds = new Rectangle(left, top, right-left, bottom-top); + int width = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + int height = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + + size = new Dimension(width, height); + + zipsize = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + + compression = LittleEndian.getUnsignedByte(data, pos); pos++; + filter = LittleEndian.getUnsignedByte(data, pos); pos++; + } + + public void write(OutputStream out) throws IOException { + byte[] header = new byte[34]; + int pos = 0; + LittleEndian.putInt(header, pos, wmfsize); pos += LittleEndian.INT_SIZE; //hmf + + LittleEndian.putInt(header, pos, bounds.x); pos += LittleEndian.INT_SIZE; //left + LittleEndian.putInt(header, pos, bounds.y); pos += LittleEndian.INT_SIZE; //top + LittleEndian.putInt(header, pos, bounds.x + bounds.width); pos += LittleEndian.INT_SIZE; //right + LittleEndian.putInt(header, pos, bounds.y + bounds.height); pos += LittleEndian.INT_SIZE; //bottom + LittleEndian.putInt(header, pos, size.width); pos += LittleEndian.INT_SIZE; //inch + LittleEndian.putInt(header, pos, size.height); pos += LittleEndian.INT_SIZE; //inch + LittleEndian.putInt(header, pos, zipsize); pos += LittleEndian.INT_SIZE; //inch + + header[pos] = 0; pos ++; + header[pos] = (byte)filter; pos ++; + + out.write(header); + } + + public int getSize(){ + return 34; + } + } + + protected byte[] compress(byte[] bytes, int offset, int length) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + DeflaterOutputStream deflater = new DeflaterOutputStream( out ); + deflater.write(bytes, offset, length); + deflater.close(); + return out.toByteArray(); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java index f79eb197e5..07a2141277 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/PICT.java @@ -1,117 +1,117 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.model.Picture; -import org.apache.poi.hslf.model.Shape; -import org.apache.poi.util.LittleEndian; - -import java.io.*; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; - -/** - * Represents Macintosh PICT picture data. - * - * @author Yegor Kozlov - */ -public class PICT extends Metafile { - - public PICT(){ - super(); - } - - /** - * Extract compressed PICT data from a ppt - */ - public byte[] getData(){ - byte[] rawdata = getRawData(); - try { - byte[] macheader = new byte[512]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(macheader); - int pos = CHECKSUM_SIZE; - byte[] pict; - try { - pict = read(rawdata, pos); - } catch (IOException e){ - //weird MAC behaviour. - //if failed to read right after the checksum - skip 16 bytes and try again - pict = read(rawdata, pos + 16); - } - out.write(pict); - return out.toByteArray(); - } catch (IOException e){ - throw new RuntimeException(e); - } - } - - private byte[] read(byte[] data, int pos) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteArrayInputStream bis = new ByteArrayInputStream(data); - Header header = new Header(); - header.read(data, pos); - bis.skip(pos + header.getSize()); - InflaterInputStream inflater = new InflaterInputStream( bis ); - byte[] chunk = new byte[4096]; - int count; - while ((count = inflater.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - inflater.close(); - return out.toByteArray(); - } - - public void setData(byte[] data) throws IOException { - int pos = 512; //skip the first 512 bytes - they are MAC specific crap - byte[] compressed = compress(data, pos, data.length-pos); - - Header header = new Header(); - header.wmfsize = data.length - 512; - //we don't have a PICT reader in java, have to set default image size 200x200 - header.bounds = new java.awt.Rectangle(0, 0, 200, 200); - header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, - header.bounds.height*Shape.EMU_PER_POINT); - header.zipsize = compressed.length; - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(checksum); - - out.write(new byte[16]); //16-byte prefix which is safe to ignore - header.write(out); - out.write(compressed); - - setRawData(out.toByteArray()); - } - - /** - * @see org.apache.poi.hslf.model.Picture#PICT - */ - public int getType(){ - return Picture.PICT; - } - - /** - * PICT signature is 0x5430 - * - * @return PICT signature (0x5430) - */ - public int getSignature(){ - return 0x5430; - } - -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.hslf.model.Shape; +import org.apache.poi.util.LittleEndian; + +import java.io.*; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; + +/** + * Represents Macintosh PICT picture data. + * + * @author Yegor Kozlov + */ +public class PICT extends Metafile { + + public PICT(){ + super(); + } + + /** + * Extract compressed PICT data from a ppt + */ + public byte[] getData(){ + byte[] rawdata = getRawData(); + try { + byte[] macheader = new byte[512]; + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(macheader); + int pos = CHECKSUM_SIZE; + byte[] pict; + try { + pict = read(rawdata, pos); + } catch (IOException e){ + //weird MAC behaviour. + //if failed to read right after the checksum - skip 16 bytes and try again + pict = read(rawdata, pos + 16); + } + out.write(pict); + return out.toByteArray(); + } catch (IOException e){ + throw new RuntimeException(e); + } + } + + private byte[] read(byte[] data, int pos) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream bis = new ByteArrayInputStream(data); + Header header = new Header(); + header.read(data, pos); + bis.skip(pos + header.getSize()); + InflaterInputStream inflater = new InflaterInputStream( bis ); + byte[] chunk = new byte[4096]; + int count; + while ((count = inflater.read(chunk)) >=0 ) { + out.write(chunk,0,count); + } + inflater.close(); + return out.toByteArray(); + } + + public void setData(byte[] data) throws IOException { + int pos = 512; //skip the first 512 bytes - they are MAC specific crap + byte[] compressed = compress(data, pos, data.length-pos); + + Header header = new Header(); + header.wmfsize = data.length - 512; + //we don't have a PICT reader in java, have to set default image size 200x200 + header.bounds = new java.awt.Rectangle(0, 0, 200, 200); + header.size = new java.awt.Dimension(header.bounds.width*Shape.EMU_PER_POINT, + header.bounds.height*Shape.EMU_PER_POINT); + header.zipsize = compressed.length; + + byte[] checksum = getChecksum(data); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(checksum); + + out.write(new byte[16]); //16-byte prefix which is safe to ignore + header.write(out); + out.write(compressed); + + setRawData(out.toByteArray()); + } + + /** + * @see org.apache.poi.hslf.model.Picture#PICT + */ + public int getType(){ + return Picture.PICT; + } + + /** + * PICT signature is 0x5430 + * + * @return PICT signature (0x5430) + */ + public int getSignature(){ + return 0x5430; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java b/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java index db9c7822a2..3d316fa4b0 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/PNG.java @@ -1,68 +1,68 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.hslf.model.Picture; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; - -/** - * Represents a PNG picture data in a PPT file - * - * @author Yegor Kozlov - */ -public class PNG extends Bitmap { - - /** - * @return PNG data - */ - public byte[] getData(){ - byte[] data = super.getData(); - try { - //PNG created on MAC may have a 16-byte prefix which prevents successful reading. - //Just cut it off!. - BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data)); - if (bi == null){ - byte[] png = new byte[data.length-16]; - System.arraycopy(data, 16, png, 0, png.length); - data = png; - } - } catch (IOException e){ - throw new RuntimeException(e); - } - return data; - } - - /** - * @return type of this picture - * @see org.apache.poi.hslf.model.Picture#PNG - */ - public int getType(){ - return Picture.PNG; - } - - /** - * PNG signature is 0x6E00 - * - * @return PNG signature (0x6E00) - */ - public int getSignature(){ - return 0x6E00; - } -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.hslf.model.Picture; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +/** + * Represents a PNG picture data in a PPT file + * + * @author Yegor Kozlov + */ +public class PNG extends Bitmap { + + /** + * @return PNG data + */ + public byte[] getData(){ + byte[] data = super.getData(); + try { + //PNG created on MAC may have a 16-byte prefix which prevents successful reading. + //Just cut it off!. + BufferedImage bi = ImageIO.read(new ByteArrayInputStream(data)); + if (bi == null){ + byte[] png = new byte[data.length-16]; + System.arraycopy(data, 16, png, 0, png.length); + data = png; + } + } catch (IOException e){ + throw new RuntimeException(e); + } + return data; + } + + /** + * @return type of this picture + * @see org.apache.poi.hslf.model.Picture#PNG + */ + public int getType(){ + return Picture.PNG; + } + + /** + * PNG signature is 0x6E00 + * + * @return PNG signature (0x6E00) + */ + public int getSignature(){ + return 0x6E00; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java index 36ca266271..a32e355d89 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java +++ b/src/scratchpad/src/org/apache/poi/hslf/blip/WMF.java @@ -1,187 +1,187 @@ -/* ==================================================================== - 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.hslf.blip; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hslf.model.Picture; -import org.apache.poi.hslf.model.Shape; - -import java.io.*; -import java.util.zip.InflaterInputStream; -import java.util.zip.DeflaterOutputStream; - -/** - * Represents a WMF (Windows Metafile) picture data. - * - * @author Yegor Kozlov - */ -public class WMF extends Metafile { - - /** - * Extract compressed WMF data from a ppt - */ - public byte[] getData(){ - try { - byte[] rawdata = getRawData(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InputStream is = new ByteArrayInputStream( rawdata ); - Header header = new Header(); - header.read(rawdata, CHECKSUM_SIZE); - is.skip(header.getSize() + CHECKSUM_SIZE); - - AldusHeader aldus = new AldusHeader(); - aldus.left = header.bounds.x; - aldus.top = header.bounds.y; - aldus.right = header.bounds.x + header.bounds.width; - aldus.bottom = header.bounds.y + header.bounds.height; - aldus.write(out); - - InflaterInputStream inflater = new InflaterInputStream( is ); - byte[] chunk = new byte[4096]; - int count; - while ((count = inflater.read(chunk)) >=0 ) { - out.write(chunk,0,count); - } - inflater.close(); - return out.toByteArray(); - } catch (IOException e){ - throw new RuntimeException(e); - } - } - - public void setData(byte[] data) throws IOException { - int pos = 0; - AldusHeader aldus = new AldusHeader(); - aldus.read(data, pos); - pos += aldus.getSize(); - - byte[] compressed = compress(data, pos, data.length-pos); - - Header header = new Header(); - header.wmfsize = data.length - aldus.getSize(); - header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top); - //coefficiaent to translate from WMF dpi to 96pdi - int coeff = 96*Shape.EMU_PER_POINT/aldus.inch; - header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff); - header.zipsize = compressed.length; - - byte[] checksum = getChecksum(data); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - out.write(checksum); - header.write(out); - out.write(compressed); - - setRawData(out.toByteArray()); - } - - /** - * We are of type Picture.WMF - */ - public int getType(){ - return Picture.WMF; - } - - /** - * WMF signature is 0x2160 - */ - public int getSignature(){ - return 0x2160; - } - - - /** - * Aldus Placeable Metafile header - 22 byte structure before WMF data. - *

- */ - public static class AldusHeader{ - public static final int APMHEADER_KEY = 0x9AC6CDD7; - - public int handle; - public int left, top, right, bottom; - public int inch = 72; //default resolution is 72 dpi - public int reserved; - public int checksum; - - public void read(byte[] data, int offset){ - int pos = offset; - int key = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; //header key - if (key != APMHEADER_KEY) throw new RuntimeException("Not a valid WMF file"); - - handle = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - left = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - top = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - right = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - bottom = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - - inch = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; - reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; - - checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; - if (checksum != getChecksum()) - throw new RuntimeException("WMF checksum does not match the header data"); - } - - /** - * Returns a checksum value for the previous 10 shorts in the header. - * The checksum is calculated by XORing each short value to an initial value of 0: - */ - public int getChecksum(){ - int checksum = 0; - checksum ^= (APMHEADER_KEY & 0x0000FFFF); - checksum ^= ((APMHEADER_KEY & 0xFFFF0000) >> 16); - checksum ^= left; - checksum ^= top; - checksum ^= right; - checksum ^= bottom; - checksum ^= inch; - return checksum; - } - - public void write(OutputStream out) throws IOException { - byte[] header = new byte[22]; - int pos = 0; - LittleEndian.putInt(header, pos, APMHEADER_KEY); pos += LittleEndian.INT_SIZE; //header key - LittleEndian.putUShort(header, pos, 0); pos += LittleEndian.SHORT_SIZE; //hmf - LittleEndian.putUShort(header, pos, left); pos += LittleEndian.SHORT_SIZE; //left - LittleEndian.putUShort(header, pos, top); pos += LittleEndian.SHORT_SIZE; //top - LittleEndian.putUShort(header, pos, right); pos += LittleEndian.SHORT_SIZE; //right - LittleEndian.putUShort(header, pos, bottom); pos += LittleEndian.SHORT_SIZE; //bottom - LittleEndian.putUShort(header, pos, inch); pos += LittleEndian.SHORT_SIZE; //inch - LittleEndian.putInt(header, pos, 0); pos += LittleEndian.INT_SIZE; //reserved - - checksum = getChecksum(); - LittleEndian.putUShort(header, pos, checksum); - - out.write(header); - } - - public int getSize(){ - return 22; - } - } - -} +/* ==================================================================== + 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.hslf.blip; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.hslf.model.Shape; + +import java.io.*; +import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; + +/** + * Represents a WMF (Windows Metafile) picture data. + * + * @author Yegor Kozlov + */ +public class WMF extends Metafile { + + /** + * Extract compressed WMF data from a ppt + */ + public byte[] getData(){ + try { + byte[] rawdata = getRawData(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + InputStream is = new ByteArrayInputStream( rawdata ); + Header header = new Header(); + header.read(rawdata, CHECKSUM_SIZE); + is.skip(header.getSize() + CHECKSUM_SIZE); + + AldusHeader aldus = new AldusHeader(); + aldus.left = header.bounds.x; + aldus.top = header.bounds.y; + aldus.right = header.bounds.x + header.bounds.width; + aldus.bottom = header.bounds.y + header.bounds.height; + aldus.write(out); + + InflaterInputStream inflater = new InflaterInputStream( is ); + byte[] chunk = new byte[4096]; + int count; + while ((count = inflater.read(chunk)) >=0 ) { + out.write(chunk,0,count); + } + inflater.close(); + return out.toByteArray(); + } catch (IOException e){ + throw new RuntimeException(e); + } + } + + public void setData(byte[] data) throws IOException { + int pos = 0; + AldusHeader aldus = new AldusHeader(); + aldus.read(data, pos); + pos += aldus.getSize(); + + byte[] compressed = compress(data, pos, data.length-pos); + + Header header = new Header(); + header.wmfsize = data.length - aldus.getSize(); + header.bounds = new java.awt.Rectangle((short)aldus.left, (short)aldus.top, (short)aldus.right-(short)aldus.left, (short)aldus.bottom-(short)aldus.top); + //coefficiaent to translate from WMF dpi to 96pdi + int coeff = 96*Shape.EMU_PER_POINT/aldus.inch; + header.size = new java.awt.Dimension(header.bounds.width*coeff, header.bounds.height*coeff); + header.zipsize = compressed.length; + + byte[] checksum = getChecksum(data); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + out.write(checksum); + header.write(out); + out.write(compressed); + + setRawData(out.toByteArray()); + } + + /** + * We are of type Picture.WMF + */ + public int getType(){ + return Picture.WMF; + } + + /** + * WMF signature is 0x2160 + */ + public int getSignature(){ + return 0x2160; + } + + + /** + * Aldus Placeable Metafile header - 22 byte structure before WMF data. + * + */ + public static class AldusHeader{ + public static final int APMHEADER_KEY = 0x9AC6CDD7; + + public int handle; + public int left, top, right, bottom; + public int inch = 72; //default resolution is 72 dpi + public int reserved; + public int checksum; + + public void read(byte[] data, int offset){ + int pos = offset; + int key = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; //header key + if (key != APMHEADER_KEY) throw new RuntimeException("Not a valid WMF file"); + + handle = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + left = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + top = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + right = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + bottom = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + + inch = LittleEndian.getUShort(data, pos); pos += LittleEndian.SHORT_SIZE; + reserved = LittleEndian.getInt(data, pos); pos += LittleEndian.INT_SIZE; + + checksum = LittleEndian.getShort(data, pos); pos += LittleEndian.SHORT_SIZE; + if (checksum != getChecksum()) + throw new RuntimeException("WMF checksum does not match the header data"); + } + + /** + * Returns a checksum value for the previous 10 shorts in the header. + * The checksum is calculated by XORing each short value to an initial value of 0: + */ + public int getChecksum(){ + int checksum = 0; + checksum ^= (APMHEADER_KEY & 0x0000FFFF); + checksum ^= ((APMHEADER_KEY & 0xFFFF0000) >> 16); + checksum ^= left; + checksum ^= top; + checksum ^= right; + checksum ^= bottom; + checksum ^= inch; + return checksum; + } + + public void write(OutputStream out) throws IOException { + byte[] header = new byte[22]; + int pos = 0; + LittleEndian.putInt(header, pos, APMHEADER_KEY); pos += LittleEndian.INT_SIZE; //header key + LittleEndian.putUShort(header, pos, 0); pos += LittleEndian.SHORT_SIZE; //hmf + LittleEndian.putUShort(header, pos, left); pos += LittleEndian.SHORT_SIZE; //left + LittleEndian.putUShort(header, pos, top); pos += LittleEndian.SHORT_SIZE; //top + LittleEndian.putUShort(header, pos, right); pos += LittleEndian.SHORT_SIZE; //right + LittleEndian.putUShort(header, pos, bottom); pos += LittleEndian.SHORT_SIZE; //bottom + LittleEndian.putUShort(header, pos, inch); pos += LittleEndian.SHORT_SIZE; //inch + LittleEndian.putInt(header, pos, 0); pos += LittleEndian.INT_SIZE; //reserved + + checksum = getChecksum(); + LittleEndian.putUShort(header, pos, checksum); + + out.write(header); + } + + public int getSize(){ + return 22; + } + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java b/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java index e778f313ed..7382eeac4b 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hslf/extractor/ImageExtractor.java @@ -1,78 +1,78 @@ - -/* ==================================================================== - 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.hslf.extractor; - -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.usermodel.PictureData; -import org.apache.poi.hslf.HSLFSlideShow; -import org.apache.poi.hslf.model.Picture; - -import java.io.IOException; -import java.io.FileOutputStream; - -/** - * Utility to extract pictures from a PowerPoint file. - * - * @author Yegor Kozlov - */ -public class ImageExtractor { - public static void main(String args[]) throws IOException { - if (args.length < 1) { - System.err.println("Usage:"); - System.err.println("\tImageExtractor "); - return; - } - SlideShow ppt = new SlideShow(new HSLFSlideShow(args[0])); - - //extract all pictures contained in the presentation - PictureData[] pdata = ppt.getPictureData(); - for (int i = 0; i < pdata.length; i++) { - PictureData pict = pdata[i]; - - // picture data - byte[] data = pict.getData(); - - int type = pict.getType(); - String ext; - switch (type) { - case Picture.JPEG: - ext = ".jpg"; - break; - case Picture.PNG: - ext = ".png"; - break; - case Picture.WMF: - ext = ".wmf"; - break; - case Picture.EMF: - ext = ".emf"; - break; - case Picture.PICT: - ext = ".pict"; - break; - case Picture.DIB: - ext = ".dib"; - break; - default: - continue; - } - FileOutputStream out = new FileOutputStream("pict_" + i + ext); - out.write(data); - out.close(); - } - } -} + +/* ==================================================================== + 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.hslf.extractor; + +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.usermodel.PictureData; +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.model.Picture; + +import java.io.IOException; +import java.io.FileOutputStream; + +/** + * Utility to extract pictures from a PowerPoint file. + * + * @author Yegor Kozlov + */ +public class ImageExtractor { + public static void main(String args[]) throws IOException { + if (args.length < 1) { + System.err.println("Usage:"); + System.err.println("\tImageExtractor "); + return; + } + SlideShow ppt = new SlideShow(new HSLFSlideShow(args[0])); + + //extract all pictures contained in the presentation + PictureData[] pdata = ppt.getPictureData(); + for (int i = 0; i < pdata.length; i++) { + PictureData pict = pdata[i]; + + // picture data + byte[] data = pict.getData(); + + int type = pict.getType(); + String ext; + switch (type) { + case Picture.JPEG: + ext = ".jpg"; + break; + case Picture.PNG: + ext = ".png"; + break; + case Picture.WMF: + ext = ".wmf"; + break; + case Picture.EMF: + ext = ".emf"; + break; + case Picture.PICT: + ext = ".pict"; + break; + case Picture.DIB: + ext = ".dib"; + break; + default: + continue; + } + FileOutputStream out = new FileOutputStream("pict_" + i + ext); + out.write(data); + out.close(); + } + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java index 1686d36da6..58f658eb20 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java @@ -1,61 +1,61 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; - -/** - * Represents a autoshape in a PowerPoint drawing - * - * @author Yegor Kozlov - */ -public class AutoShape extends SimpleShape { - - protected AutoShape(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - public AutoShape(int type, Shape parent){ - super(null, parent); - _escherContainer = createSpContainer(type, parent instanceof ShapeGroup); - } - - public AutoShape(int type){ - this(type, null); - } - - protected EscherContainerRecord createSpContainer(int shapeType, boolean isChild){ - EscherContainerRecord spcont = super.createSpContainer(isChild); - - EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); - short type = (short)((shapeType << 4) | 0x2); - spRecord.setOptions(type); - - //set default properties for an autoshape - EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008)); - opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002)); - - return spcont; - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; + +/** + * Represents a autoshape in a PowerPoint drawing + * + * @author Yegor Kozlov + */ +public class AutoShape extends SimpleShape { + + protected AutoShape(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + public AutoShape(int type, Shape parent){ + super(null, parent); + _escherContainer = createSpContainer(type, parent instanceof ShapeGroup); + } + + public AutoShape(int type){ + this(type, null); + } + + protected EscherContainerRecord createSpContainer(int shapeType, boolean isChild){ + EscherContainerRecord spcont = super.createSpContainer(isChild); + + EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); + short type = (short)((shapeType << 4) | 0x2); + spRecord.setOptions(type); + + //set default properties for an autoshape + EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); + + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLCOLOR, 0x8000004)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLBACKCOLOR, 0x8000000)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__NOFILLHITTEST, 0x100010)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__COLOR, 0x8000001)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80008)); + opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHADOWSTYLE__COLOR, 0x8000002)); + + return spcont; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Background.java b/src/scratchpad/src/org/apache/poi/hslf/model/Background.java index 87faedfbe3..494e8075b1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Background.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Background.java @@ -1,37 +1,37 @@ - -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.EscherContainerRecord; - -/** - * Background shape - * - * @author Yegor Kozlov - */ -public class Background extends Shape { - - protected Background(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - protected EscherContainerRecord createSpContainer(boolean isChild){ - return null; - } - -} + +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.EscherContainerRecord; + +/** + * Background shape + * + * @author Yegor Kozlov + */ +public class Background extends Shape { + + protected Background(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + protected EscherContainerRecord createSpContainer(boolean isChild){ + return null; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java index fbe5e98ef6..09fa574c5f 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Fill.java @@ -1,228 +1,228 @@ - -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.record.*; -import org.apache.poi.hslf.usermodel.PictureData; -import org.apache.poi.hslf.usermodel.SlideShow; - -import java.awt.*; -import java.util.*; - -/** - * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint. - * - * @author Yegor Kozlov - */ -public class Fill { - /** - * Fill with a solid color - */ - public static final int FILL_SOLID = 0; - - /** - * Fill with a pattern (bitmap) - */ - public static final int FILL_PATTERN = 1; - - /** - * A texture (pattern with its own color map) - */ - public static final int FILL_TEXTURE = 2; - - /** - * Center a picture in the shape - */ - public static final int FILL_PICTURE = 3; - - /** - * Shade from start to end points - */ - public static final int FILL_SHADE = 4; - - /** - * Shade from bounding rectangle to end point - */ - public static final int FILL_SHADE_CENTER = 5; - - /** - * Shade from shape outline to end point - */ - public static final int FILL_SHADE_SHAPE = 6; - - /** - * Similar to FILL_SHADE, but the fill angle - * is additionally scaled by the aspect ratio of - * the shape. If shape is square, it is the same as FILL_SHADE - */ - public static final int FILL_SHADE_SCALE = 7; - - /** - * shade to title - */ - public static final int FILL_SHADE_TITLE = 8; - - /** - * Use the background fill color/pattern - */ - public static final int FILL_BACKGROUND = 9; - - - - /** - * The shape this background applies to - */ - protected Shape shape; - - /** - * Construct a Fill object for a shape. - * Fill information will be read from shape's escher properties. - * - * @param shape the shape this background applies to - */ - public Fill(Shape shape){ - this.shape = shape; - } - - /** - * Returns fill type. - * Must be one of the FILL_* constants defined in this class. - * - * @return type of fill - */ - public int getFillType(){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE); - return prop == null ? FILL_SOLID : prop.getPropertyValue(); - } - - /** - * Sets fill type. - * Must be one of the FILL_* constants defined in this class. - * - * @param type type of the fill - */ - public void setFillType(int type){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); - } - - /** - * Foreground color - */ - public Color getForegroundColor(){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - EscherSimpleProperty p1 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR); - EscherSimpleProperty p2 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); - - int p2val = p2 == null ? 0 : p2.getPropertyValue(); - - Color clr = null; - if (p1 != null && (p2val & 0x10) != 0){ - int rgb = p1.getPropertyValue(); - clr = shape.getColor(rgb); - } - return clr; - } - - /** - * Foreground color - */ - public void setForegroundColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - if (color == null) { - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1); - } - else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); - } - } - - /** - * Background color - */ - public Color getBackgroundColor(){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - EscherSimpleProperty p1 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR); - EscherSimpleProperty p2 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); - - int p2val = p2 == null ? 0 : p2.getPropertyValue(); - - Color clr = null; - if (p1 != null && (p2val & 0x10) != 0){ - int rgb = p1.getPropertyValue(); - clr = shape.getColor(rgb); - } - return clr; - } - - /** - * Background color - */ - public void setBackgroundColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - if (color == null) { - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1); - } - else { - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); - } - } - - /** - * PictureData object used in a texture, pattern of picture fill. - */ - public PictureData getPictureData(){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); - if (p == null) return null; - - SlideShow ppt = shape.getSheet().getSlideShow(); - PictureData[] pict = ppt.getPictureData(); - Document doc = ppt.getDocumentRecord(); - - EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); - EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); - - java.util.List lst = bstore.getChildRecords(); - int idx = p.getPropertyValue(); - EscherBSERecord bse = (EscherBSERecord)lst.get(idx); - for ( int i = 0; i < pict.length; i++ ) { - if (pict[i].getOffset() == bse.getOffset()){ - return pict[i]; - } - } - throw new RuntimeException("Picture data not found: \n" + - " bse: " + bse + " at " + bse.getOffset() ); - - } - - /** - * Assign picture used to fill the underlying shape. - * - * @param idx 0-based index of the picture added to this ppt by SlideShow.addPicture method. - */ - public void setPictureData(int idx){ - EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); - Shape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx); - } - -} + +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.usermodel.PictureData; +import org.apache.poi.hslf.usermodel.SlideShow; + +import java.awt.*; +import java.util.*; + +/** + * Represents functionality provided by the 'Fill Effects' dialog in PowerPoint. + * + * @author Yegor Kozlov + */ +public class Fill { + /** + * Fill with a solid color + */ + public static final int FILL_SOLID = 0; + + /** + * Fill with a pattern (bitmap) + */ + public static final int FILL_PATTERN = 1; + + /** + * A texture (pattern with its own color map) + */ + public static final int FILL_TEXTURE = 2; + + /** + * Center a picture in the shape + */ + public static final int FILL_PICTURE = 3; + + /** + * Shade from start to end points + */ + public static final int FILL_SHADE = 4; + + /** + * Shade from bounding rectangle to end point + */ + public static final int FILL_SHADE_CENTER = 5; + + /** + * Shade from shape outline to end point + */ + public static final int FILL_SHADE_SHAPE = 6; + + /** + * Similar to FILL_SHADE, but the fill angle + * is additionally scaled by the aspect ratio of + * the shape. If shape is square, it is the same as FILL_SHADE + */ + public static final int FILL_SHADE_SCALE = 7; + + /** + * shade to title + */ + public static final int FILL_SHADE_TITLE = 8; + + /** + * Use the background fill color/pattern + */ + public static final int FILL_BACKGROUND = 9; + + + + /** + * The shape this background applies to + */ + protected Shape shape; + + /** + * Construct a Fill object for a shape. + * Fill information will be read from shape's escher properties. + * + * @param shape the shape this background applies to + */ + public Fill(Shape shape){ + this.shape = shape; + } + + /** + * Returns fill type. + * Must be one of the FILL_* constants defined in this class. + * + * @return type of fill + */ + public int getFillType(){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE); + return prop == null ? FILL_SOLID : prop.getPropertyValue(); + } + + /** + * Sets fill type. + * Must be one of the FILL_* constants defined in this class. + * + * @param type type of the fill + */ + public void setFillType(int type){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + Shape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type); + } + + /** + * Foreground color + */ + public Color getForegroundColor(){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + EscherSimpleProperty p1 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR); + EscherSimpleProperty p2 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); + + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + + Color clr = null; + if (p1 != null && (p2val & 0x10) != 0){ + int rgb = p1.getPropertyValue(); + clr = shape.getColor(rgb); + } + return clr; + } + + /** + * Foreground color + */ + public void setForegroundColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + if (color == null) { + Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, -1); + } + else { + int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); + Shape.setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); + } + } + + /** + * Background color + */ + public Color getBackgroundColor(){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + EscherSimpleProperty p1 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR); + EscherSimpleProperty p2 = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); + + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + + Color clr = null; + if (p1 != null && (p2val & 0x10) != 0){ + int rgb = p1.getPropertyValue(); + clr = shape.getColor(rgb); + } + return clr; + } + + /** + * Background color + */ + public void setBackgroundColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + if (color == null) { + Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1); + } + else { + int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); + Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); + } + } + + /** + * PictureData object used in a texture, pattern of picture fill. + */ + public PictureData getPictureData(){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE); + if (p == null) return null; + + SlideShow ppt = shape.getSheet().getSlideShow(); + PictureData[] pict = ppt.getPictureData(); + Document doc = ppt.getDocumentRecord(); + + EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); + EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); + + java.util.List lst = bstore.getChildRecords(); + int idx = p.getPropertyValue(); + EscherBSERecord bse = (EscherBSERecord)lst.get(idx); + for ( int i = 0; i < pict.length; i++ ) { + if (pict[i].getOffset() == bse.getOffset()){ + return pict[i]; + } + } + throw new RuntimeException("Picture data not found: \n" + + " bse: " + bse + " at " + bse.getOffset() ); + + } + + /** + * Assign picture used to fill the underlying shape. + * + * @param idx 0-based index of the picture added to this ppt by SlideShow.addPicture method. + */ + public void setPictureData(int idx){ + EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID); + Shape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java index 938a6a06cf..0abcaa6543 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Line.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Line.java @@ -1,128 +1,128 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; - -/** - * Represents a line in a PowerPoint drawing - * - * @author Yegor Kozlov - */ -public class Line extends SimpleShape { - /** - * Solid (continuous) pen - */ - public static final int PEN_SOLID = 1; - /** - * PS_DASH system dash style - */ - public static final int PEN_PS_DASH = 2; - /** - * PS_DOT system dash style - */ - public static final int PEN_DOT = 3; - /** - * PS_DASHDOT system dash style - */ - public static final int PEN_DASHDOT = 4; - /** - * PS_DASHDOTDOT system dash style - */ - public static final int PEN_DASHDOTDOT = 5; - /** - * square dot style - */ - public static final int PEN_DOTGEL = 6; - /** - * dash style - */ - public static final int PEN_DASH = 7; - /** - * long dash style - */ - public static final int PEN_LONGDASHGEL = 8; - /** - * dash short dash - */ - public static final int PEN_DASHDOTGEL = 9; - /** - * long dash short dash - */ - public static final int PEN_LONGDASHDOTGEL = 10; - /** - * long dash short dash short dash - */ - public static final int PEN_LONGDASHDOTDOTGEL = 11; - - /** - * Single line (of width lineWidth) - */ - public static final int LINE_SIMPLE = 0; - /** - * Double lines of equal width - */ - public static final int LINE_DOUBLE = 1; - /** - * Double lines, one thick, one thin - */ - public static final int LINE_THICKTHIN = 2; - /** - * Double lines, reverse order - */ - public static final int LINE_THINTHICK = 3; - /** - * Three lines, thin, thick, thin - */ - public static final int LINE_TRIPLE = 4; - - - protected Line(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - public Line(Shape parent){ - super(null, parent); - _escherContainer = createSpContainer(parent instanceof ShapeGroup); - } - - public Line(){ - this(null); - } - - protected EscherContainerRecord createSpContainer(boolean isChild){ - EscherContainerRecord spcont = super.createSpContainer(isChild); - - EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); - short type = (ShapeTypes.Line << 4) | 0x2; - spRecord.setOptions(type); - - //set default properties for a line - EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - - //default line properties - setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, 4); - setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, 0x10000); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0xA0008); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - - return spcont; - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; + +/** + * Represents a line in a PowerPoint drawing + * + * @author Yegor Kozlov + */ +public class Line extends SimpleShape { + /** + * Solid (continuous) pen + */ + public static final int PEN_SOLID = 1; + /** + * PS_DASH system dash style + */ + public static final int PEN_PS_DASH = 2; + /** + * PS_DOT system dash style + */ + public static final int PEN_DOT = 3; + /** + * PS_DASHDOT system dash style + */ + public static final int PEN_DASHDOT = 4; + /** + * PS_DASHDOTDOT system dash style + */ + public static final int PEN_DASHDOTDOT = 5; + /** + * square dot style + */ + public static final int PEN_DOTGEL = 6; + /** + * dash style + */ + public static final int PEN_DASH = 7; + /** + * long dash style + */ + public static final int PEN_LONGDASHGEL = 8; + /** + * dash short dash + */ + public static final int PEN_DASHDOTGEL = 9; + /** + * long dash short dash + */ + public static final int PEN_LONGDASHDOTGEL = 10; + /** + * long dash short dash short dash + */ + public static final int PEN_LONGDASHDOTDOTGEL = 11; + + /** + * Single line (of width lineWidth) + */ + public static final int LINE_SIMPLE = 0; + /** + * Double lines of equal width + */ + public static final int LINE_DOUBLE = 1; + /** + * Double lines, one thick, one thin + */ + public static final int LINE_THICKTHIN = 2; + /** + * Double lines, reverse order + */ + public static final int LINE_THINTHICK = 3; + /** + * Three lines, thin, thick, thin + */ + public static final int LINE_TRIPLE = 4; + + + protected Line(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + public Line(Shape parent){ + super(null, parent); + _escherContainer = createSpContainer(parent instanceof ShapeGroup); + } + + public Line(){ + this(null); + } + + protected EscherContainerRecord createSpContainer(boolean isChild){ + EscherContainerRecord spcont = super.createSpContainer(isChild); + + EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); + short type = (ShapeTypes.Line << 4) | 0x2; + spRecord.setOptions(type); + + //set default properties for a line + EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); + + //default line properties + setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, 4); + setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, 0x10000); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); + setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0xA0008); + setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); + + return spcont; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java index 5e1463a75e..c8353d0685 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java @@ -1,512 +1,512 @@ -/* ==================================================================== - 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.hslf.model; - - -import java.awt.*; -import java.awt.Shape; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.image.*; -import java.awt.image.renderable.RenderableImage; -import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; -import java.text.AttributedCharacterIterator; -import java.util.Map; -import java.util.ArrayList; - -import org.apache.poi.ddf.EscherProperties; -import org.apache.poi.hslf.usermodel.RichTextRun; - -/** - * Translates Graphics2D calls into PowerPoint. - * - * @author Yegor Kozlov - */ -public class PPGraphics2D extends Graphics2D { - //The group to write the graphics calls into. - private ShapeGroup group; - - private AffineTransform transform; - private Stroke stroke; - private Paint paint; - private Font font; - private Color foreground; - private Color background = Color.white; - private Shape clip; - int count = 0; - /** - * Construct Java Graphics object which translates graphic calls in ppt drawing layer. - * - * @param group The shape group to write the graphics calls into. - */ - public PPGraphics2D(ShapeGroup group){ - this.group = group; - transform = new AffineTransform(); - } - - /** - * @return the shape group being used for drawing - */ - public ShapeGroup getShapeGroup(){ - return group; - } - - public Font getFont(){ - return font; - } - - public void setFont(Font font){ - this.font = font; - } - - public Color getColor(){ - return foreground; - } - - public void setColor(Color color) { - this.foreground = color; - } - - public Stroke getStroke(){ - return stroke; - } - - public void setStroke(Stroke s){ - this.stroke = s; - } - - public Paint getPaint(){ - return paint; - } - - public void setPaint(Paint paint){ - this.paint = paint; - if (paint instanceof Color) setColor((Color)paint); - } - - public AffineTransform getTransform(){ - return (AffineTransform)transform.clone(); - } - - public void setTransform(AffineTransform trans) { - transform = (AffineTransform)trans.clone(); - } - - public void draw(Shape shape){ - if(clip != null) { - java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); - if (bounds.width == 0) bounds.width = 1; - if (bounds.height == 0) bounds.height = 1; - if (!clip.getBounds().contains(bounds)) { - return; - } - } - - PathIterator it = shape.getPathIterator(transform); - double[] prev = null; - double[] coords = new double[6]; - double[] first = new double[6]; - if(!it.isDone()) it.currentSegment(first); //first point - while(!it.isDone()){ - int type = it.currentSegment(coords); - if (prev != null ){ - Line line = new Line(group); - if (stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)stroke; - line.setLineWidth(bs.getLineWidth()); - float[] dash = bs.getDashArray(); - if (dash != null) line.setLineDashing(Line.PEN_DASH); - } - if(getColor() != null) line.setLineColor(getColor()); - if (type == PathIterator.SEG_LINETO) { - line.setAnchor(new java.awt.Rectangle((int)prev[0], (int)prev[1], (int)(coords[0] - prev[0]), (int)(coords[1] - prev[1]))); - } else if (type == PathIterator.SEG_CLOSE){ - line.setAnchor(new java.awt.Rectangle((int)coords[0], (int)coords[1], (int)(first[0] - coords[0]), (int)(first[1] - coords[1]))); - } - group.addShape(line); - } - prev = new double[]{coords[0], coords[1]}; - it.next(); - } - - } - - public void drawString(String string, float x, float y){ - TextBox txt = new TextBox(group); - txt.getTextRun().supplySlideShow(group.getSheet().getSlideShow()); - txt.getTextRun().setSheet(group.getSheet()); - txt.setText(string); - - RichTextRun rt = txt.getTextRun().getRichTextRuns()[0]; - rt.setFontSize(font.getSize()); - rt.setFontName(font.getFamily()); - - if(getColor() != null) rt.setFontColor(getColor()); - if (font.isBold()) rt.setBold(true); - if (font.isItalic()) rt.setItalic(true); - - txt.setMarginBottom(0); - txt.setMarginTop(0); - txt.setMarginLeft(0); - txt.setMarginRight(0); - txt.setWordWrap(TextBox.WrapNone); - - if (!"".equals(string)) txt.resizeToFitText(); - int height = (int)txt.getAnchor().getHeight(); - - /* - In powerpoint anchor of a shape is its top left corner. - Java graphics sets string coordinates by the baseline of the first character - so we need to shift down by the height of the textbox - */ - txt.moveTo((int)x, (int)(y - height)); - - if(clip != null) { - if (!clip.getBounds().contains(txt.getAnchor())) { - ;//return; - } - } - group.addShape(txt); - } - - public void fill(Shape shape){ - if(clip != null) { - java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); - if (bounds.width == 0) bounds.width = 1; - if (bounds.height == 0) bounds.height = 1; - if (!clip.getBounds().contains(bounds)) { - return; - } - } - PathIterator it = shape.getPathIterator(transform); - ArrayList pnt = new ArrayList(); - double[] coords = new double[6]; - while(!it.isDone()){ - int type = it.currentSegment(coords); - if (type != PathIterator.SEG_CLOSE) { - pnt.add(new Point((int)coords[0], (int)coords[1])); - } - it.next(); - } - int[] xPoints= new int[pnt.size()]; - int[] yPoints= new int[pnt.size()]; - for (int i = 0; i < pnt.size(); i++) { - Point p = (Point)pnt.get(i); - xPoints[i] = p.x; - yPoints[i] = p.y; - } - - AutoShape r = new AutoShape(ShapeTypes.Rectangle); - if (paint instanceof Color){ - Color color = (Color)paint; - r.setFillColor(color); - } - if(getColor() != null) r.setLineColor(getColor()); - if (stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)stroke; - r.setLineWidth(bs.getLineWidth()); - float[] dash = bs.getDashArray(); - if (dash != null) r.setLineDashing(Line.PEN_DASH); - } - - java.awt.Rectangle bounds = transform.createTransformedShape(shape).getBounds(); - r.setAnchor(bounds); - group.addShape(r); - } - - public void translate(int x, int y) { - AffineTransform at = new AffineTransform(); - at.translate(x, y); - transform.concatenate(at); - } - - public void clip(Shape shape) { - this.clip = transform.createTransformedShape(shape); - //update size of the escher group which holds the drawing - group.setAnchor(clip.getBounds()); - } - - public Shape getClip() { - return clip; - } - - public void scale(double sx, double sy) { - AffineTransform at = new AffineTransform(); - at.scale(sx, sy); - transform.concatenate(at); - } - //=============================================== - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - throw new RuntimeException("Not implemented"); - } - - public void drawString(String str, int x, int y) { - throw new RuntimeException("Not implemented"); - } - - public void fillOval(int x, int y, int width, int height) { - throw new RuntimeException("Not implemented"); - } - - public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - throw new RuntimeException("Not implemented"); - } - - public void fillArc(int x, int y, int width, int height, - int startAngle, int arcAngle) { - throw new RuntimeException("Not implemented"); - } - - public void setPaintMode() { - throw new RuntimeException("Not implemented"); - } - - public void drawArc(int x, int y, int width, int height, - int startAngle, int arcAngle) { - throw new RuntimeException("Not implemented"); - } - - - public void drawPolyline(int xPoints[], int yPoints[], - int nPoints) { - throw new RuntimeException("Not implemented"); - } - - public Graphics create() { - throw new RuntimeException("Not implemented"); - } - - public void drawOval(int x, int y, int width, int height) { - AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse); - ellipse.setAnchor(new java.awt.Rectangle(x-width/2, y-height/2, width, height)); - if (stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)stroke; - ellipse.setLineWidth(bs.getLineWidth()); - } - if(getColor() != null) ellipse.setLineColor(getColor()); - if (paint instanceof Color){ - Color color = (Color)paint; - ellipse.setFillColor(color); - } - - group.addShape(ellipse); - } - - public void setXORMode(Color color1) { - throw new RuntimeException("Not implemented"); - } - - - public boolean drawImage(Image img, int x, int y, - Color bgcolor, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - public boolean drawImage(Image img, int x, int y, - int width, int height, - Color bgcolor, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - public boolean drawImage(Image img, - int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - public boolean drawImage(Image img, int x, int y, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - public boolean drawImage(Image img, int x, int y, - int width, int height, - ImageObserver observer) { - throw new RuntimeException("Not implemented"); - } - - public void dispose() { - throw new RuntimeException("Not implemented"); - } - - public void drawLine(int x1, int y1, int x2, int y2) { - Line line = new Line(); - line.setAnchor(new java.awt.Rectangle(x1, y1, x2-x1, y2-y1)); - if (stroke instanceof BasicStroke){ - BasicStroke bs = (BasicStroke)stroke; - line.setLineWidth(bs.getLineWidth()); - } - if(getColor() != null) line.setLineColor(getColor()); - group.addShape(line); - } - - public void fillPolygon(int xPoints[], int yPoints[], - int nPoints) { - throw new RuntimeException("Not implemented"); - } - - public FontMetrics getFontMetrics(Font f) { - throw new RuntimeException("Not implemented"); - } - - public void fillRect(int x, int y, int width, int height) { - throw new RuntimeException("Not implemented"); - } - - public void drawPolygon(int xPoints[], int yPoints[], - int nPoints) { - throw new RuntimeException("Not implemented"); - } - - public void clipRect(int x, int y, int width, int height) { - throw new RuntimeException("Not implemented"); - } - - public void setClip(Shape clip) { - throw new RuntimeException("Not implemented"); - } - - public java.awt.Rectangle getClipBounds() { - throw new RuntimeException("Not implemented"); - } - - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - throw new RuntimeException("Not implemented"); - } - - public void clearRect(int x, int y, int width, int height) { - throw new RuntimeException("Not implemented"); - } - - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - throw new RuntimeException("Not implemented"); - } - - public void setClip(int x, int y, int width, int height) { - throw new RuntimeException("Not implemented"); - } - - public void rotate(double d) { - throw new RuntimeException("Not implemented"); - - } - - public void rotate(double d, double d1, double d2) { - throw new RuntimeException("Not implemented"); - } - - public void shear(double d, double d1) { - throw new RuntimeException("Not implemented"); - } - - public FontRenderContext getFontRenderContext() { - return new FontRenderContext(transform, true, true); - } - - public void transform(AffineTransform affinetransform) { - throw new RuntimeException("Not implemented"); - } - - public void drawImage(BufferedImage bufferedimage, BufferedImageOp op, int x, int y) { - throw new RuntimeException("Not implemented"); - } - - public void setBackground(Color c) { - throw new RuntimeException("Not implemented"); - } - - public void drawRenderedImage(RenderedImage renderedimage, AffineTransform affinetransform) { - throw new RuntimeException("Not implemented"); - } - - public Color getBackground() { - throw new RuntimeException("Not implemented"); - } - - public void setComposite(Composite composite) { - throw new RuntimeException("Not implemented"); - - } - - public Composite getComposite() { - throw new RuntimeException("Not implemented"); - } - - public Object getRenderingHint(java.awt.RenderingHints.Key key) { - throw new RuntimeException("Not implemented"); - } - - public boolean drawImage(Image image, AffineTransform affinetransform, ImageObserver imageobserver) { - throw new RuntimeException("Not implemented"); - } - - public void setRenderingHint(java.awt.RenderingHints.Key key, Object obj) { - throw new RuntimeException("Not implemented"); - } - - - public void drawGlyphVector(GlyphVector g, float x, float y) { - throw new RuntimeException("Not implemented"); - - } - - public GraphicsConfiguration getDeviceConfiguration() { - throw new RuntimeException("Not implemented"); - } - - public void addRenderingHints(Map map) { - throw new RuntimeException("Not implemented"); - } - - public void translate(double d, double d1) { - - throw new RuntimeException("Not implemented"); - } - - public void drawString(AttributedCharacterIterator attributedcharacteriterator, float x, float y) { - throw new RuntimeException("Not implemented"); - } - - public boolean hit(java.awt.Rectangle rectangle, Shape shape, boolean flag) { - throw new RuntimeException("Not implemented"); - } - - public RenderingHints getRenderingHints() { - throw new RuntimeException("Not implemented"); - } - - public void setRenderingHints(Map map) { - throw new RuntimeException("Not implemented"); - - } - - public void drawRenderableImage(RenderableImage renderableimage, AffineTransform affinetransform) { - throw new RuntimeException("Not implemented"); - } -} +/* ==================================================================== + 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.hslf.model; + + +import java.awt.*; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.image.*; +import java.awt.image.renderable.RenderableImage; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.text.AttributedCharacterIterator; +import java.util.Map; +import java.util.ArrayList; + +import org.apache.poi.ddf.EscherProperties; +import org.apache.poi.hslf.usermodel.RichTextRun; + +/** + * Translates Graphics2D calls into PowerPoint. + * + * @author Yegor Kozlov + */ +public class PPGraphics2D extends Graphics2D { + //The group to write the graphics calls into. + private ShapeGroup group; + + private AffineTransform transform; + private Stroke stroke; + private Paint paint; + private Font font; + private Color foreground; + private Color background = Color.white; + private Shape clip; + int count = 0; + /** + * Construct Java Graphics object which translates graphic calls in ppt drawing layer. + * + * @param group The shape group to write the graphics calls into. + */ + public PPGraphics2D(ShapeGroup group){ + this.group = group; + transform = new AffineTransform(); + } + + /** + * @return the shape group being used for drawing + */ + public ShapeGroup getShapeGroup(){ + return group; + } + + public Font getFont(){ + return font; + } + + public void setFont(Font font){ + this.font = font; + } + + public Color getColor(){ + return foreground; + } + + public void setColor(Color color) { + this.foreground = color; + } + + public Stroke getStroke(){ + return stroke; + } + + public void setStroke(Stroke s){ + this.stroke = s; + } + + public Paint getPaint(){ + return paint; + } + + public void setPaint(Paint paint){ + this.paint = paint; + if (paint instanceof Color) setColor((Color)paint); + } + + public AffineTransform getTransform(){ + return (AffineTransform)transform.clone(); + } + + public void setTransform(AffineTransform trans) { + transform = (AffineTransform)trans.clone(); + } + + public void draw(Shape shape){ + if(clip != null) { + java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); + if (bounds.width == 0) bounds.width = 1; + if (bounds.height == 0) bounds.height = 1; + if (!clip.getBounds().contains(bounds)) { + return; + } + } + + PathIterator it = shape.getPathIterator(transform); + double[] prev = null; + double[] coords = new double[6]; + double[] first = new double[6]; + if(!it.isDone()) it.currentSegment(first); //first point + while(!it.isDone()){ + int type = it.currentSegment(coords); + if (prev != null ){ + Line line = new Line(group); + if (stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)stroke; + line.setLineWidth(bs.getLineWidth()); + float[] dash = bs.getDashArray(); + if (dash != null) line.setLineDashing(Line.PEN_DASH); + } + if(getColor() != null) line.setLineColor(getColor()); + if (type == PathIterator.SEG_LINETO) { + line.setAnchor(new java.awt.Rectangle((int)prev[0], (int)prev[1], (int)(coords[0] - prev[0]), (int)(coords[1] - prev[1]))); + } else if (type == PathIterator.SEG_CLOSE){ + line.setAnchor(new java.awt.Rectangle((int)coords[0], (int)coords[1], (int)(first[0] - coords[0]), (int)(first[1] - coords[1]))); + } + group.addShape(line); + } + prev = new double[]{coords[0], coords[1]}; + it.next(); + } + + } + + public void drawString(String string, float x, float y){ + TextBox txt = new TextBox(group); + txt.getTextRun().supplySlideShow(group.getSheet().getSlideShow()); + txt.getTextRun().setSheet(group.getSheet()); + txt.setText(string); + + RichTextRun rt = txt.getTextRun().getRichTextRuns()[0]; + rt.setFontSize(font.getSize()); + rt.setFontName(font.getFamily()); + + if(getColor() != null) rt.setFontColor(getColor()); + if (font.isBold()) rt.setBold(true); + if (font.isItalic()) rt.setItalic(true); + + txt.setMarginBottom(0); + txt.setMarginTop(0); + txt.setMarginLeft(0); + txt.setMarginRight(0); + txt.setWordWrap(TextBox.WrapNone); + + if (!"".equals(string)) txt.resizeToFitText(); + int height = (int)txt.getAnchor().getHeight(); + + /* + In powerpoint anchor of a shape is its top left corner. + Java graphics sets string coordinates by the baseline of the first character + so we need to shift down by the height of the textbox + */ + txt.moveTo((int)x, (int)(y - height)); + + if(clip != null) { + if (!clip.getBounds().contains(txt.getAnchor())) { + ;//return; + } + } + group.addShape(txt); + } + + public void fill(Shape shape){ + if(clip != null) { + java.awt.Rectangle bounds = getTransform().createTransformedShape(shape).getBounds(); + if (bounds.width == 0) bounds.width = 1; + if (bounds.height == 0) bounds.height = 1; + if (!clip.getBounds().contains(bounds)) { + return; + } + } + PathIterator it = shape.getPathIterator(transform); + ArrayList pnt = new ArrayList(); + double[] coords = new double[6]; + while(!it.isDone()){ + int type = it.currentSegment(coords); + if (type != PathIterator.SEG_CLOSE) { + pnt.add(new Point((int)coords[0], (int)coords[1])); + } + it.next(); + } + int[] xPoints= new int[pnt.size()]; + int[] yPoints= new int[pnt.size()]; + for (int i = 0; i < pnt.size(); i++) { + Point p = (Point)pnt.get(i); + xPoints[i] = p.x; + yPoints[i] = p.y; + } + + AutoShape r = new AutoShape(ShapeTypes.Rectangle); + if (paint instanceof Color){ + Color color = (Color)paint; + r.setFillColor(color); + } + if(getColor() != null) r.setLineColor(getColor()); + if (stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)stroke; + r.setLineWidth(bs.getLineWidth()); + float[] dash = bs.getDashArray(); + if (dash != null) r.setLineDashing(Line.PEN_DASH); + } + + java.awt.Rectangle bounds = transform.createTransformedShape(shape).getBounds(); + r.setAnchor(bounds); + group.addShape(r); + } + + public void translate(int x, int y) { + AffineTransform at = new AffineTransform(); + at.translate(x, y); + transform.concatenate(at); + } + + public void clip(Shape shape) { + this.clip = transform.createTransformedShape(shape); + //update size of the escher group which holds the drawing + group.setAnchor(clip.getBounds()); + } + + public Shape getClip() { + return clip; + } + + public void scale(double sx, double sy) { + AffineTransform at = new AffineTransform(); + at.scale(sx, sy); + transform.concatenate(at); + } + //=============================================== + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + throw new RuntimeException("Not implemented"); + } + + public void drawString(String str, int x, int y) { + throw new RuntimeException("Not implemented"); + } + + public void fillOval(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { + throw new RuntimeException("Not implemented"); + } + + public void fillArc(int x, int y, int width, int height, + int startAngle, int arcAngle) { + throw new RuntimeException("Not implemented"); + } + + public void setPaintMode() { + throw new RuntimeException("Not implemented"); + } + + public void drawArc(int x, int y, int width, int height, + int startAngle, int arcAngle) { + throw new RuntimeException("Not implemented"); + } + + + public void drawPolyline(int xPoints[], int yPoints[], + int nPoints) { + throw new RuntimeException("Not implemented"); + } + + public Graphics create() { + throw new RuntimeException("Not implemented"); + } + + public void drawOval(int x, int y, int width, int height) { + AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse); + ellipse.setAnchor(new java.awt.Rectangle(x-width/2, y-height/2, width, height)); + if (stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)stroke; + ellipse.setLineWidth(bs.getLineWidth()); + } + if(getColor() != null) ellipse.setLineColor(getColor()); + if (paint instanceof Color){ + Color color = (Color)paint; + ellipse.setFillColor(color); + } + + group.addShape(ellipse); + } + + public void setXORMode(Color color1) { + throw new RuntimeException("Not implemented"); + } + + + public boolean drawImage(Image img, int x, int y, + Color bgcolor, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + public boolean drawImage(Image img, int x, int y, + int width, int height, + Color bgcolor, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + + public boolean drawImage(Image img, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + public boolean drawImage(Image img, + int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + public boolean drawImage(Image img, int x, int y, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + public boolean drawImage(Image img, int x, int y, + int width, int height, + ImageObserver observer) { + throw new RuntimeException("Not implemented"); + } + + public void dispose() { + throw new RuntimeException("Not implemented"); + } + + public void drawLine(int x1, int y1, int x2, int y2) { + Line line = new Line(); + line.setAnchor(new java.awt.Rectangle(x1, y1, x2-x1, y2-y1)); + if (stroke instanceof BasicStroke){ + BasicStroke bs = (BasicStroke)stroke; + line.setLineWidth(bs.getLineWidth()); + } + if(getColor() != null) line.setLineColor(getColor()); + group.addShape(line); + } + + public void fillPolygon(int xPoints[], int yPoints[], + int nPoints) { + throw new RuntimeException("Not implemented"); + } + + public FontMetrics getFontMetrics(Font f) { + throw new RuntimeException("Not implemented"); + } + + public void fillRect(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + public void drawPolygon(int xPoints[], int yPoints[], + int nPoints) { + throw new RuntimeException("Not implemented"); + } + + public void clipRect(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + public void setClip(Shape clip) { + throw new RuntimeException("Not implemented"); + } + + public java.awt.Rectangle getClipBounds() { + throw new RuntimeException("Not implemented"); + } + + public void drawString(AttributedCharacterIterator iterator, int x, int y) { + throw new RuntimeException("Not implemented"); + } + + public void clearRect(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + public void copyArea(int x, int y, int width, int height, int dx, int dy) { + throw new RuntimeException("Not implemented"); + } + + public void setClip(int x, int y, int width, int height) { + throw new RuntimeException("Not implemented"); + } + + public void rotate(double d) { + throw new RuntimeException("Not implemented"); + + } + + public void rotate(double d, double d1, double d2) { + throw new RuntimeException("Not implemented"); + } + + public void shear(double d, double d1) { + throw new RuntimeException("Not implemented"); + } + + public FontRenderContext getFontRenderContext() { + return new FontRenderContext(transform, true, true); + } + + public void transform(AffineTransform affinetransform) { + throw new RuntimeException("Not implemented"); + } + + public void drawImage(BufferedImage bufferedimage, BufferedImageOp op, int x, int y) { + throw new RuntimeException("Not implemented"); + } + + public void setBackground(Color c) { + throw new RuntimeException("Not implemented"); + } + + public void drawRenderedImage(RenderedImage renderedimage, AffineTransform affinetransform) { + throw new RuntimeException("Not implemented"); + } + + public Color getBackground() { + throw new RuntimeException("Not implemented"); + } + + public void setComposite(Composite composite) { + throw new RuntimeException("Not implemented"); + + } + + public Composite getComposite() { + throw new RuntimeException("Not implemented"); + } + + public Object getRenderingHint(java.awt.RenderingHints.Key key) { + throw new RuntimeException("Not implemented"); + } + + public boolean drawImage(Image image, AffineTransform affinetransform, ImageObserver imageobserver) { + throw new RuntimeException("Not implemented"); + } + + public void setRenderingHint(java.awt.RenderingHints.Key key, Object obj) { + throw new RuntimeException("Not implemented"); + } + + + public void drawGlyphVector(GlyphVector g, float x, float y) { + throw new RuntimeException("Not implemented"); + + } + + public GraphicsConfiguration getDeviceConfiguration() { + throw new RuntimeException("Not implemented"); + } + + public void addRenderingHints(Map map) { + throw new RuntimeException("Not implemented"); + } + + public void translate(double d, double d1) { + + throw new RuntimeException("Not implemented"); + } + + public void drawString(AttributedCharacterIterator attributedcharacteriterator, float x, float y) { + throw new RuntimeException("Not implemented"); + } + + public boolean hit(java.awt.Rectangle rectangle, Shape shape, boolean flag) { + throw new RuntimeException("Not implemented"); + } + + public RenderingHints getRenderingHints() { + throw new RuntimeException("Not implemented"); + } + + public void setRenderingHints(Map map) { + throw new RuntimeException("Not implemented"); + + } + + public void drawRenderableImage(RenderableImage renderableimage, AffineTransform affinetransform) { + throw new RuntimeException("Not implemented"); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java index 3be79efbd1..4ae8676f58 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java @@ -1,179 +1,179 @@ -package org.apache.poi.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.usermodel.PictureData; -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.hslf.blip.Bitmap; - -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.awt.*; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.List; -import java.util.Arrays; - - -/** - * Represents a picture in a PowerPoint document. - *

- * The information about an image in PowerPoint document is stored in - * two places: - *

  • EscherBSE container in the Document keeps information about image - * type, image index to refer by slides etc. - *
  • "Pictures" OLE stream holds the actual data of the image. - *

    - * - * @author Yegor Kozlov - */ -public class Picture extends SimpleShape { - - /** - * Windows Enhanced Metafile (EMF) - */ - public static final int EMF = 2; - - /** - * Windows Metafile (WMF) - */ - public static final int WMF = 3; - - /** - * Macintosh PICT - */ - public static final int PICT = 4; - - /** - * JPEG - */ - public static final int JPEG = 5; - - /** - * PNG - */ - public static final int PNG = 6; - - /** - * Windows DIB (BMP) - */ - public static final byte DIB = 7; - - /** - * Create a new Picture - * - * @param idx the index of the picture - */ - public Picture(int idx){ - super(null, null); - _escherContainer = createSpContainer(idx); - } - - /** - * Create a Picture object - * - * @param escherRecord the EscherSpContainer record which holds information about - * this picture in the Slide - * @param parent the parent shape of this picture - */ - protected Picture(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - /** - * Returns index associated with this picture. - * Index starts with 1 and points to a EscherBSE record which - * holds information about this picture. - * - * @return the index to this picture (1 based). - */ - public int getPictureIndex(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY + 0x4000); - return prop.getPropertyValue(); - } - - /** - * Create a new Picture and populate the inital structure of the EscherSp record which holds information about this picture. - - * @param idx the index of the picture which referes to EscherBSE container. - * @return the create Picture object - */ - protected EscherContainerRecord createSpContainer(int idx) { - EscherContainerRecord spContainer = super.createSpContainer(false); - spContainer.setOptions((short)15); - - EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setOptions((short)((ShapeTypes.PictureFrame << 4) | 0x2)); - - //set default properties for a picture - EscherOptRecord opt = (EscherOptRecord)getEscherChild(spContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 8388736); - - //another weird feature of powerpoint: for picture id we must add 0x4000. - setEscherProperty(opt, (short)(EscherProperties.BLIP__BLIPTODISPLAY + 0x4000), idx); - - return spContainer; - } - - /** - * Resize this picture to the default size. - */ - public void setDefaultSize(){ - PictureData pict = getPictureData(); - if (pict instanceof Bitmap){ - BufferedImage img = null; - try { - img = ImageIO.read(new ByteArrayInputStream(pict.getData())); - } - catch (IOException e){} - catch (NegativeArraySizeException ne) {} - - if(img != null) { - // Valid image, set anchor from it - setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight())); - } else { - // Invalid image, go with the default metafile size - setAnchor(new java.awt.Rectangle(0, 0, 200, 200)); - } - } else { - //default size of a metafile picture is 200x200 - setAnchor(new java.awt.Rectangle(50, 50, 200, 200)); - } - } - - /** - * Returns the picture data for this picture. - * - * @return the picture data for this picture. - */ - public PictureData getPictureData(){ - SlideShow ppt = getSheet().getSlideShow(); - PictureData[] pict = ppt.getPictureData(); - Document doc = ppt.getDocumentRecord(); - EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); - EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); - - List lst = bstore.getChildRecords(); - int idx = getPictureIndex()-1; - EscherBSERecord bse = (EscherBSERecord)lst.get(idx); - for ( int i = 0; i < pict.length; i++ ) { - if (pict[i].getOffset() == bse.getOffset()){ - return pict[i]; - } - } - System.err.println("Warning - no picture found for our BSE offset " + bse.getOffset()); - return null; - } - - /** - * By default set the orininal image size - */ - protected void afterInsert(Sheet sh){ - java.awt.Rectangle anchor = getAnchor(); - if (anchor.equals(new java.awt.Rectangle())){ - setDefaultSize(); - } - } - -} +package org.apache.poi.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.hslf.usermodel.PictureData; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.record.Document; +import org.apache.poi.hslf.blip.Bitmap; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.awt.*; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; +import java.util.Arrays; + + +/** + * Represents a picture in a PowerPoint document. + *

    + * The information about an image in PowerPoint document is stored in + * two places: + *

  • EscherBSE container in the Document keeps information about image + * type, image index to refer by slides etc. + *
  • "Pictures" OLE stream holds the actual data of the image. + *

    + * + * @author Yegor Kozlov + */ +public class Picture extends SimpleShape { + + /** + * Windows Enhanced Metafile (EMF) + */ + public static final int EMF = 2; + + /** + * Windows Metafile (WMF) + */ + public static final int WMF = 3; + + /** + * Macintosh PICT + */ + public static final int PICT = 4; + + /** + * JPEG + */ + public static final int JPEG = 5; + + /** + * PNG + */ + public static final int PNG = 6; + + /** + * Windows DIB (BMP) + */ + public static final byte DIB = 7; + + /** + * Create a new Picture + * + * @param idx the index of the picture + */ + public Picture(int idx){ + super(null, null); + _escherContainer = createSpContainer(idx); + } + + /** + * Create a Picture object + * + * @param escherRecord the EscherSpContainer record which holds information about + * this picture in the Slide + * @param parent the parent shape of this picture + */ + protected Picture(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + /** + * Returns index associated with this picture. + * Index starts with 1 and points to a EscherBSE record which + * holds information about this picture. + * + * @return the index to this picture (1 based). + */ + public int getPictureIndex(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY + 0x4000); + return prop.getPropertyValue(); + } + + /** + * Create a new Picture and populate the inital structure of the EscherSp record which holds information about this picture. + + * @param idx the index of the picture which referes to EscherBSE container. + * @return the create Picture object + */ + protected EscherContainerRecord createSpContainer(int idx) { + EscherContainerRecord spContainer = super.createSpContainer(false); + spContainer.setOptions((short)15); + + EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); + spRecord.setOptions((short)((ShapeTypes.PictureFrame << 4) | 0x2)); + + //set default properties for a picture + EscherOptRecord opt = (EscherOptRecord)getEscherChild(spContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 8388736); + + //another weird feature of powerpoint: for picture id we must add 0x4000. + setEscherProperty(opt, (short)(EscherProperties.BLIP__BLIPTODISPLAY + 0x4000), idx); + + return spContainer; + } + + /** + * Resize this picture to the default size. + */ + public void setDefaultSize(){ + PictureData pict = getPictureData(); + if (pict instanceof Bitmap){ + BufferedImage img = null; + try { + img = ImageIO.read(new ByteArrayInputStream(pict.getData())); + } + catch (IOException e){} + catch (NegativeArraySizeException ne) {} + + if(img != null) { + // Valid image, set anchor from it + setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight())); + } else { + // Invalid image, go with the default metafile size + setAnchor(new java.awt.Rectangle(0, 0, 200, 200)); + } + } else { + //default size of a metafile picture is 200x200 + setAnchor(new java.awt.Rectangle(50, 50, 200, 200)); + } + } + + /** + * Returns the picture data for this picture. + * + * @return the picture data for this picture. + */ + public PictureData getPictureData(){ + SlideShow ppt = getSheet().getSlideShow(); + PictureData[] pict = ppt.getPictureData(); + Document doc = ppt.getDocumentRecord(); + EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer(); + EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER); + + List lst = bstore.getChildRecords(); + int idx = getPictureIndex()-1; + EscherBSERecord bse = (EscherBSERecord)lst.get(idx); + for ( int i = 0; i < pict.length; i++ ) { + if (pict[i].getOffset() == bse.getOffset()){ + return pict[i]; + } + } + System.err.println("Warning - no picture found for our BSE offset " + bse.getOffset()); + return null; + } + + /** + * By default set the orininal image size + */ + protected void afterInsert(Sheet sh){ + java.awt.Rectangle anchor = getAnchor(); + if (anchor.equals(new java.awt.Rectangle())){ + setDefaultSize(); + } + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java b/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java index 228eddb205..07da283c60 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Placeholder.java @@ -1,97 +1,97 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.record.OEPlaceholderAtom; - -import java.util.List; -import java.io.ByteArrayOutputStream; - -/** - * Represents a Placeholder in PowerPoint. - * - * @author Yegor Kozlov - */ -public class Placeholder extends TextBox { - - protected Placeholder(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - public Placeholder(Shape parent){ - super(parent); - } - - public Placeholder(){ - super(); - } - - /** - * Create a new Placeholder and initialize internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(boolean isChild){ - EscherContainerRecord spcont = super.createSpContainer(isChild); - - EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER); - - EscherClientDataRecord cldata = new EscherClientDataRecord(); - cldata.setOptions((short)15); - - EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - - //Placeholders can't be grouped - setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144); - - //OEPlaceholderAtom tells powerpoint that this shape is a placeholder - // - OEPlaceholderAtom oep = new OEPlaceholderAtom(); - /** - * Extarct from MSDN: - * - * There is a special case when the placeholder does not have a position in the layout. - * This occurs when the user has moved the placeholder from its original position. - * In this case the placeholder ID is -1. - */ - oep.setPlacementId(-1); - - oep.setPlaceholderId(OEPlaceholderAtom.Body); - - //convert hslf into ddf record - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - oep.writeOut(out); - } catch(Exception e){ - throw new RuntimeException(e); - } - cldata.setRemainingData(out.toByteArray()); - - //append placeholder container before EscherTextboxRecord - List lst = spcont.getChildRecords(); - for (int i = 0; i < lst.size(); i++) { - EscherRecord rec = (EscherRecord)lst.get(i); - if(rec.getRecordId() == EscherTextboxRecord.RECORD_ID){ - lst.add(i++, cldata); - } - } - - return spcont; - } -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.hslf.record.OEPlaceholderAtom; + +import java.util.List; +import java.io.ByteArrayOutputStream; + +/** + * Represents a Placeholder in PowerPoint. + * + * @author Yegor Kozlov + */ +public class Placeholder extends TextBox { + + protected Placeholder(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + public Placeholder(Shape parent){ + super(parent); + } + + public Placeholder(){ + super(); + } + + /** + * Create a new Placeholder and initialize internal structures + * + * @return the created EscherContainerRecord which holds shape data + */ + protected EscherContainerRecord createSpContainer(boolean isChild){ + EscherContainerRecord spcont = super.createSpContainer(isChild); + + EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); + spRecord.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER); + + EscherClientDataRecord cldata = new EscherClientDataRecord(); + cldata.setOptions((short)15); + + EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); + + //Placeholders can't be grouped + setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 262144); + + //OEPlaceholderAtom tells powerpoint that this shape is a placeholder + // + OEPlaceholderAtom oep = new OEPlaceholderAtom(); + /** + * Extarct from MSDN: + * + * There is a special case when the placeholder does not have a position in the layout. + * This occurs when the user has moved the placeholder from its original position. + * In this case the placeholder ID is -1. + */ + oep.setPlacementId(-1); + + oep.setPlaceholderId(OEPlaceholderAtom.Body); + + //convert hslf into ddf record + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + oep.writeOut(out); + } catch(Exception e){ + throw new RuntimeException(e); + } + cldata.setRemainingData(out.toByteArray()); + + //append placeholder container before EscherTextboxRecord + List lst = spcont.getChildRecords(); + for (int i = 0; i < lst.size(); i++) { + EscherRecord rec = (EscherRecord)lst.get(i); + if(rec.getRecordId() == EscherTextboxRecord.RECORD_ID){ + lst.add(i++, cldata); + } + } + + return spcont; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java index a4d5276345..ed8dbb6155 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java @@ -1,307 +1,307 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.model.ShapeTypes; -import org.apache.poi.hslf.record.ColorSchemeAtom; - -import java.util.Iterator; -import java.awt.*; - -/** - *

    - * Represents a Shape which is the elemental object that composes a drawing. - * This class is a wrapper around EscherSpContainer which holds all information - * about a shape in PowerPoint document. - *

    - *

    - * When you add a shape, you usually specify the dimensions of the shape and the position - * of the upper�left corner of the bounding box for the shape relative to the upper�left - * corner of the page, worksheet, or slide. Distances in the drawing layer are measured - * in points (72 points = 1 inch). - *

    - *

    - * - * @author Yegor Kozlov - */ -public abstract class Shape { - - /** - * In Escher absolute distances are specified in - * English Metric Units (EMUs), occasionally referred to as A units; - * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point. - */ - public static final int EMU_PER_INCH = 914400; - public static final int EMU_PER_POINT = 12700; - public static final int EMU_PER_CENTIMETER = 360000; - - /** - * Master DPI (576 pixels per inch). - * Used by the reference coordinate system in PowerPoint. - */ - public static final int MASTER_DPI = 576; - - /** - * Pixels DPI (96 pixels per inch) - */ - public static final int PIXEL_DPI = 96; - - /** - * Points DPI (72 pixels per inch) - */ - public static final int POINT_DPI = 72; - - /** - * Either EscherSpContainer or EscheSpgrContainer record - * which holds information about this shape. - */ - protected EscherContainerRecord _escherContainer; - - /** - * Parent of this shape. - * null for the topmost shapes. - */ - protected Shape _parent; - - /** - * The Sheet this shape belongs to - */ - protected Sheet _sheet; - - /** - * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of this Shape - */ - protected Shape(EscherContainerRecord escherRecord, Shape parent){ - _escherContainer = escherRecord; - _parent = parent; - } - - /** - * Creates the lowerlevel escher records for this shape. - */ - protected abstract EscherContainerRecord createSpContainer(boolean isChild); - - /** - * @return the parent of this shape - */ - public Shape getParent(){ - return _parent; - } - - /** - * @return name of the shape. - */ - public String getShapeName(){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - return ShapeTypes.typeName(spRecord.getOptions() >> 4); - } - - /** - * @return type of the shape. - * @see org.apache.poi.hslf.record.RecordTypes - */ - public int getShapeType(){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - return spRecord.getOptions() >> 4; - } - - /** - * @param type type of the shape. - * @see org.apache.poi.hslf.record.RecordTypes - */ - public void setShapeType(int type){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - spRecord.setOptions((short)(type << 4 | 0x2)); - } - - /** - * Returns the anchor (the bounding box rectangle) of this shape. - * All coordinates are expressed in points (72 dpi). - * - * @return the anchor of this shape - */ - public java.awt.Rectangle getAnchor(){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - java.awt.Rectangle anchor=null; - if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ - EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID); - anchor = new java.awt.Rectangle(); - anchor.x = rec.getDx1()*POINT_DPI/MASTER_DPI; - anchor.y = rec.getDy1()*POINT_DPI/MASTER_DPI; - anchor.width = (rec.getDx2() - anchor.x)*POINT_DPI/MASTER_DPI; - anchor.height = (rec.getDy2() - anchor.y)*POINT_DPI/MASTER_DPI; - } - else { - EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID); - anchor = new java.awt.Rectangle(); - anchor.y = rec.getFlag()*POINT_DPI/MASTER_DPI; - anchor.x = rec.getCol1()*POINT_DPI/MASTER_DPI; - anchor.width = (rec.getDx1() - rec.getCol1())*POINT_DPI/MASTER_DPI; - anchor.height = (rec.getRow1() - rec.getFlag())*POINT_DPI/MASTER_DPI; - } - return anchor; - } - - /** - * Sets the anchor (the bounding box rectangle) of this shape. - * All coordinates should be expressed in points (72 dpi). - * - * @param anchor new anchor - */ - public void setAnchor(java.awt.Rectangle anchor){ - EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ - EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID); - rec.setDx1(anchor.x*MASTER_DPI/POINT_DPI); - rec.setDy1(anchor.y*MASTER_DPI/POINT_DPI); - rec.setDx2((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI); - rec.setDy2((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI); - } - else { - EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID); - rec.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI)); - rec.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI)); - rec.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI)); - rec.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI)); - } - - } - - /** - * Moves the top left corner of the shape to the specified point. - * - * @param x the x coordinate of the top left corner of the shape - * @param y the y coordinate of the top left corner of the shape - */ - public void moveTo(int x, int y){ - java.awt.Rectangle anchor = getAnchor(); - anchor.setLocation(x, y); - setAnchor(anchor); - } - - /** - * Helper method to return escher child by record ID - * - * @return escher record or null if not found. - */ - public static EscherRecord getEscherChild(EscherContainerRecord owner, int recordId){ - for ( Iterator iterator = owner.getChildRecords().iterator(); iterator.hasNext(); ) - { - EscherRecord escherRecord = (EscherRecord) iterator.next(); - if (escherRecord.getRecordId() == recordId) - return escherRecord; - } - return null; - } - - /** - * Returns escher property by id. - * - * @return escher property or null if not found. - */ - public static EscherProperty getEscherProperty(EscherOptRecord opt, int propId){ - for ( Iterator iterator = opt.getEscherProperties().iterator(); iterator.hasNext(); ) - { - EscherProperty prop = (EscherProperty) iterator.next(); - if (prop.getId() == propId) - return prop; - } - return null; - } - - /** - * Set an escher property for this shape. - * - * @param opt The opt record to set the properties to. - * @param propId The id of the property. One of the constants defined in EscherOptRecord. - * @param value value of the property. If value = -1 then the property is removed. - */ - public static void setEscherProperty(EscherOptRecord opt, short propId, int value){ - java.util.List props = opt.getEscherProperties(); - for ( Iterator iterator = props.iterator(); iterator.hasNext(); ) { - EscherProperty prop = (EscherProperty) iterator.next(); - if (prop.getId() == propId){ - iterator.remove(); - } - } - if (value != -1) { - opt.addEscherProperty(new EscherSimpleProperty(propId, value)); - opt.sortProperties(); - } - } - - /** - * @return The shape container and it's children that can represent this - * shape. - */ - public EscherContainerRecord getSpContainer(){ - return _escherContainer; - } - - /** - * Event which fires when a shape is inserted in the sheet. - * In some cases we need to propagate changes to upper level containers. - *
    - * Default implementation does nothing. - * - * @param sh - owning shape - */ - protected void afterInsert(Sheet sh){ - - } - - /** - * @return the SlideShow this shape belongs to - */ - public Sheet getSheet(){ - return _sheet; - } - - /** - * Assign the SlideShow this shape belongs to - * - * @param sheet owner of this shape - */ - public void setSheet(Sheet sheet){ - _sheet = sheet; - } - - protected Color getColor(int rgb){ - if (rgb >= 0x8000000) { - int idx = rgb - 0x8000000; - ColorSchemeAtom ca = getSheet().getColorScheme(); - if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); - } - Color tmp = new Color(rgb, true); - return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); - } - - /** - * Fill properties of this shape - * - * @return fill properties of this shape - */ - public Fill getFill(){ - return new Fill(this); - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.hslf.model.ShapeTypes; +import org.apache.poi.hslf.record.ColorSchemeAtom; + +import java.util.Iterator; +import java.awt.*; + +/** + *

    + * Represents a Shape which is the elemental object that composes a drawing. + * This class is a wrapper around EscherSpContainer which holds all information + * about a shape in PowerPoint document. + *

    + *

    + * When you add a shape, you usually specify the dimensions of the shape and the position + * of the upper�left corner of the bounding box for the shape relative to the upper�left + * corner of the page, worksheet, or slide. Distances in the drawing layer are measured + * in points (72 points = 1 inch). + *

    + *

    + * + * @author Yegor Kozlov + */ +public abstract class Shape { + + /** + * In Escher absolute distances are specified in + * English Metric Units (EMUs), occasionally referred to as A units; + * there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point. + */ + public static final int EMU_PER_INCH = 914400; + public static final int EMU_PER_POINT = 12700; + public static final int EMU_PER_CENTIMETER = 360000; + + /** + * Master DPI (576 pixels per inch). + * Used by the reference coordinate system in PowerPoint. + */ + public static final int MASTER_DPI = 576; + + /** + * Pixels DPI (96 pixels per inch) + */ + public static final int PIXEL_DPI = 96; + + /** + * Points DPI (72 pixels per inch) + */ + public static final int POINT_DPI = 72; + + /** + * Either EscherSpContainer or EscheSpgrContainer record + * which holds information about this shape. + */ + protected EscherContainerRecord _escherContainer; + + /** + * Parent of this shape. + * null for the topmost shapes. + */ + protected Shape _parent; + + /** + * The Sheet this shape belongs to + */ + protected Sheet _sheet; + + /** + * Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document. + * + * @param escherRecord EscherSpContainer container which holds information about this shape + * @param parent the parent of this Shape + */ + protected Shape(EscherContainerRecord escherRecord, Shape parent){ + _escherContainer = escherRecord; + _parent = parent; + } + + /** + * Creates the lowerlevel escher records for this shape. + */ + protected abstract EscherContainerRecord createSpContainer(boolean isChild); + + /** + * @return the parent of this shape + */ + public Shape getParent(){ + return _parent; + } + + /** + * @return name of the shape. + */ + public String getShapeName(){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + return ShapeTypes.typeName(spRecord.getOptions() >> 4); + } + + /** + * @return type of the shape. + * @see org.apache.poi.hslf.record.RecordTypes + */ + public int getShapeType(){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + return spRecord.getOptions() >> 4; + } + + /** + * @param type type of the shape. + * @see org.apache.poi.hslf.record.RecordTypes + */ + public void setShapeType(int type){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + spRecord.setOptions((short)(type << 4 | 0x2)); + } + + /** + * Returns the anchor (the bounding box rectangle) of this shape. + * All coordinates are expressed in points (72 dpi). + * + * @return the anchor of this shape + */ + public java.awt.Rectangle getAnchor(){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + int flags = spRecord.getFlags(); + java.awt.Rectangle anchor=null; + if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ + EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID); + anchor = new java.awt.Rectangle(); + anchor.x = rec.getDx1()*POINT_DPI/MASTER_DPI; + anchor.y = rec.getDy1()*POINT_DPI/MASTER_DPI; + anchor.width = (rec.getDx2() - anchor.x)*POINT_DPI/MASTER_DPI; + anchor.height = (rec.getDy2() - anchor.y)*POINT_DPI/MASTER_DPI; + } + else { + EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID); + anchor = new java.awt.Rectangle(); + anchor.y = rec.getFlag()*POINT_DPI/MASTER_DPI; + anchor.x = rec.getCol1()*POINT_DPI/MASTER_DPI; + anchor.width = (rec.getDx1() - rec.getCol1())*POINT_DPI/MASTER_DPI; + anchor.height = (rec.getRow1() - rec.getFlag())*POINT_DPI/MASTER_DPI; + } + return anchor; + } + + /** + * Sets the anchor (the bounding box rectangle) of this shape. + * All coordinates should be expressed in points (72 dpi). + * + * @param anchor new anchor + */ + public void setAnchor(java.awt.Rectangle anchor){ + EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID); + int flags = spRecord.getFlags(); + if ((flags & EscherSpRecord.FLAG_CHILD) != 0){ + EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID); + rec.setDx1(anchor.x*MASTER_DPI/POINT_DPI); + rec.setDy1(anchor.y*MASTER_DPI/POINT_DPI); + rec.setDx2((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI); + rec.setDy2((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI); + } + else { + EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID); + rec.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI)); + rec.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI)); + rec.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI)); + rec.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI)); + } + + } + + /** + * Moves the top left corner of the shape to the specified point. + * + * @param x the x coordinate of the top left corner of the shape + * @param y the y coordinate of the top left corner of the shape + */ + public void moveTo(int x, int y){ + java.awt.Rectangle anchor = getAnchor(); + anchor.setLocation(x, y); + setAnchor(anchor); + } + + /** + * Helper method to return escher child by record ID + * + * @return escher record or null if not found. + */ + public static EscherRecord getEscherChild(EscherContainerRecord owner, int recordId){ + for ( Iterator iterator = owner.getChildRecords().iterator(); iterator.hasNext(); ) + { + EscherRecord escherRecord = (EscherRecord) iterator.next(); + if (escherRecord.getRecordId() == recordId) + return escherRecord; + } + return null; + } + + /** + * Returns escher property by id. + * + * @return escher property or null if not found. + */ + public static EscherProperty getEscherProperty(EscherOptRecord opt, int propId){ + for ( Iterator iterator = opt.getEscherProperties().iterator(); iterator.hasNext(); ) + { + EscherProperty prop = (EscherProperty) iterator.next(); + if (prop.getId() == propId) + return prop; + } + return null; + } + + /** + * Set an escher property for this shape. + * + * @param opt The opt record to set the properties to. + * @param propId The id of the property. One of the constants defined in EscherOptRecord. + * @param value value of the property. If value = -1 then the property is removed. + */ + public static void setEscherProperty(EscherOptRecord opt, short propId, int value){ + java.util.List props = opt.getEscherProperties(); + for ( Iterator iterator = props.iterator(); iterator.hasNext(); ) { + EscherProperty prop = (EscherProperty) iterator.next(); + if (prop.getId() == propId){ + iterator.remove(); + } + } + if (value != -1) { + opt.addEscherProperty(new EscherSimpleProperty(propId, value)); + opt.sortProperties(); + } + } + + /** + * @return The shape container and it's children that can represent this + * shape. + */ + public EscherContainerRecord getSpContainer(){ + return _escherContainer; + } + + /** + * Event which fires when a shape is inserted in the sheet. + * In some cases we need to propagate changes to upper level containers. + *
    + * Default implementation does nothing. + * + * @param sh - owning shape + */ + protected void afterInsert(Sheet sh){ + + } + + /** + * @return the SlideShow this shape belongs to + */ + public Sheet getSheet(){ + return _sheet; + } + + /** + * Assign the SlideShow this shape belongs to + * + * @param sheet owner of this shape + */ + public void setSheet(Sheet sheet){ + _sheet = sheet; + } + + protected Color getColor(int rgb){ + if (rgb >= 0x8000000) { + int idx = rgb - 0x8000000; + ColorSchemeAtom ca = getSheet().getColorScheme(); + if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); + } + Color tmp = new Color(rgb, true); + return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); + } + + /** + * Fill properties of this shape + * + * @return fill properties of this shape + */ + public Fill getFill(){ + return new Fill(this); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index f7108ce85f..653071bd11 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -1,69 +1,69 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; - -/** - * Create a Shape object depending on its type - * - * @author Yegor Kozlov - */ -public class ShapeFactory { - - /** - * Create a new shape from the data provided. - */ - public static Shape createShape(EscherContainerRecord spContainer, Shape parent){ - if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ - return new ShapeGroup(spContainer, parent); - } - - Shape shape; - EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); - - int type = spRecord.getOptions() >> 4; - switch (type){ - case ShapeTypes.TextBox: - shape = new TextBox(spContainer, parent); - break; - case ShapeTypes.Rectangle: - EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID); - if (txtbox == null) - shape = new AutoShape(spContainer, parent); - else - shape = new TextBox(spContainer, parent); - break; - case ShapeTypes.PictureFrame: - shape = new Picture(spContainer, parent); - break; - case ShapeTypes.Line: - shape = new Line(spContainer, parent); - break; - case ShapeTypes.NotPrimitive: - if ((spRecord.getFlags() & EscherSpRecord.FLAG_GROUP) != 0) - shape = new ShapeGroup(spContainer, parent); - else - shape = new AutoShape(spContainer, parent); - break; - default: - shape = new AutoShape(spContainer, parent); - break; - } - return shape; - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; + +/** + * Create a Shape object depending on its type + * + * @author Yegor Kozlov + */ +public class ShapeFactory { + + /** + * Create a new shape from the data provided. + */ + public static Shape createShape(EscherContainerRecord spContainer, Shape parent){ + if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){ + return new ShapeGroup(spContainer, parent); + } + + Shape shape; + EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID); + + int type = spRecord.getOptions() >> 4; + switch (type){ + case ShapeTypes.TextBox: + shape = new TextBox(spContainer, parent); + break; + case ShapeTypes.Rectangle: + EscherTextboxRecord txtbox = (EscherTextboxRecord)Shape.getEscherChild(spContainer, EscherTextboxRecord.RECORD_ID); + if (txtbox == null) + shape = new AutoShape(spContainer, parent); + else + shape = new TextBox(spContainer, parent); + break; + case ShapeTypes.PictureFrame: + shape = new Picture(spContainer, parent); + break; + case ShapeTypes.Line: + shape = new Line(spContainer, parent); + break; + case ShapeTypes.NotPrimitive: + if ((spRecord.getFlags() & EscherSpRecord.FLAG_GROUP) != 0) + shape = new ShapeGroup(spContainer, parent); + else + shape = new AutoShape(spContainer, parent); + break; + default: + shape = new AutoShape(spContainer, parent); + break; + } + return shape; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java index 0a23d27e9f..310d321cfb 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java @@ -1,180 +1,180 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.LittleEndian; - -import java.util.ArrayList; -import java.util.List; - -/** - * Represents a group of shapes. - * - * @author Yegor Kozlov - */ -public class ShapeGroup extends Shape{ - - /** - * Create a new ShapeGroup. This constructor is used when a new shape is created. - * - */ - public ShapeGroup(){ - this(null, null); - _escherContainer = createSpContainer(false); - } - - /** - * Create a ShapeGroup object and initilize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected ShapeGroup(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - /** - * @return the shapes contained in this group container - */ - public Shape[] getShapes() { - // Out escher container record should contain serveral - // SpContainers, the first of which is the group shape itself - List lst = _escherContainer.getChildRecords(); - - ArrayList shapeList = new ArrayList(); - // Don't include the first SpContainer, it is always NotPrimitive - for (int i = 1; i < lst.size(); i++){ - EscherRecord r = (EscherRecord)lst.get(i); - if(r instanceof EscherContainerRecord) { - // Create the Shape for it - EscherContainerRecord container = (EscherContainerRecord)r; - Shape shape = ShapeFactory.createShape(container, this); - shapeList.add( shape ); - } else { - // Should we do anything special with these non - // Container records? - System.err.println("Shape contained non container escher record, was " + r.getClass().getName()); - } - } - - // Put the shapes into an array, and return - Shape[] shapes = (Shape[])shapeList.toArray(new Shape[shapeList.size()]); - return shapes; - } - - /** - * Sets the anchor (the bounding box rectangle) of this shape. - * All coordinates should be expressed in Master units (576 dpi). - * - * @param anchor new anchor - */ - public void setAnchor(java.awt.Rectangle anchor){ - - EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChildRecords().get(0); - - EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID); - //hack. internal variable EscherClientAnchorRecord.shortRecord can be - //initialized only in fillFields(). We need to set shortRecord=false; - byte[] header = new byte[16]; - LittleEndian.putUShort(header, 0, 0); - LittleEndian.putUShort(header, 2, 0); - LittleEndian.putInt(header, 4, 8); - clientAnchor.fillFields(header, 0, null); - - clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI)); - clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI)); - clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI)); - clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI)); - - EscherSpgrRecord spgr = (EscherSpgrRecord)getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID); - - spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI); - spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI); - spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI); - spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI); - } - - /** - * Create a new ShapeGroup and create an instance of EscherSpgrContainer which represents a group of shapes - */ - protected EscherContainerRecord createSpContainer(boolean isChild) { - EscherContainerRecord spgr = new EscherContainerRecord(); - spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER); - spgr.setOptions((short)15); - - //The group itself is a shape, and always appears as the first EscherSpContainer in the group container. - EscherContainerRecord spcont = new EscherContainerRecord(); - spcont.setRecordId(EscherContainerRecord.SP_CONTAINER); - spcont.setOptions((short)15); - - EscherSpgrRecord spg = new EscherSpgrRecord(); - spg.setOptions((short)1); - spcont.addChildRecord(spg); - - EscherSpRecord sp = new EscherSpRecord(); - short type = (ShapeTypes.NotPrimitive << 4) + 2; - sp.setOptions(type); - sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP); - spcont.addChildRecord(sp); - - EscherClientAnchorRecord anchor = new EscherClientAnchorRecord(); - spcont.addChildRecord(anchor); - - spgr.addChildRecord(spcont); - return spgr; - } - - /** - * Add a shape to this group. - * - * @param shape - the Shape to add - */ - public void addShape(Shape shape){ - _escherContainer.addChildRecord(shape.getSpContainer()); - - Sheet sheet = getSheet(); - shape.setSheet(sheet); - shape.afterInsert(sheet); - - if(shape instanceof TextBox) { - TextBox tbox = (TextBox)shape; - getSheet().getPPDrawing().addTextboxWrapper(tbox._txtbox); - } - } - - /** - * Moves this ShapeGroup to the specified location. - *

    - * @param x the x coordinate of the top left corner of the shape in new location - * @param y the y coordinate of the top left corner of the shape in new location - */ - public void moveTo(int x, int y){ - java.awt.Rectangle anchor = getAnchor(); - int dx = x - anchor.x; - int dy = y - anchor.y; - anchor.translate(dx, dy); - setAnchor(anchor); - - Shape[] shape = getShapes(); - for (int i = 0; i < shape.length; i++) { - java.awt.Rectangle chanchor = shape[i].getAnchor(); - chanchor.translate(dx, dy); - shape[i].setAnchor(chanchor); - } - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.util.LittleEndian; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a group of shapes. + * + * @author Yegor Kozlov + */ +public class ShapeGroup extends Shape{ + + /** + * Create a new ShapeGroup. This constructor is used when a new shape is created. + * + */ + public ShapeGroup(){ + this(null, null); + _escherContainer = createSpContainer(false); + } + + /** + * Create a ShapeGroup object and initilize it from the supplied Record container. + * + * @param escherRecord EscherSpContainer container which holds information about this shape + * @param parent the parent of the shape + */ + protected ShapeGroup(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + /** + * @return the shapes contained in this group container + */ + public Shape[] getShapes() { + // Out escher container record should contain serveral + // SpContainers, the first of which is the group shape itself + List lst = _escherContainer.getChildRecords(); + + ArrayList shapeList = new ArrayList(); + // Don't include the first SpContainer, it is always NotPrimitive + for (int i = 1; i < lst.size(); i++){ + EscherRecord r = (EscherRecord)lst.get(i); + if(r instanceof EscherContainerRecord) { + // Create the Shape for it + EscherContainerRecord container = (EscherContainerRecord)r; + Shape shape = ShapeFactory.createShape(container, this); + shapeList.add( shape ); + } else { + // Should we do anything special with these non + // Container records? + System.err.println("Shape contained non container escher record, was " + r.getClass().getName()); + } + } + + // Put the shapes into an array, and return + Shape[] shapes = (Shape[])shapeList.toArray(new Shape[shapeList.size()]); + return shapes; + } + + /** + * Sets the anchor (the bounding box rectangle) of this shape. + * All coordinates should be expressed in Master units (576 dpi). + * + * @param anchor new anchor + */ + public void setAnchor(java.awt.Rectangle anchor){ + + EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChildRecords().get(0); + + EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID); + //hack. internal variable EscherClientAnchorRecord.shortRecord can be + //initialized only in fillFields(). We need to set shortRecord=false; + byte[] header = new byte[16]; + LittleEndian.putUShort(header, 0, 0); + LittleEndian.putUShort(header, 2, 0); + LittleEndian.putInt(header, 4, 8); + clientAnchor.fillFields(header, 0, null); + + clientAnchor.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI)); + clientAnchor.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI)); + clientAnchor.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI)); + clientAnchor.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI)); + + EscherSpgrRecord spgr = (EscherSpgrRecord)getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID); + + spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI); + spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI); + spgr.setRectX2((anchor.x + anchor.width)*MASTER_DPI/POINT_DPI); + spgr.setRectY2((anchor.y + anchor.height)*MASTER_DPI/POINT_DPI); + } + + /** + * Create a new ShapeGroup and create an instance of EscherSpgrContainer which represents a group of shapes + */ + protected EscherContainerRecord createSpContainer(boolean isChild) { + EscherContainerRecord spgr = new EscherContainerRecord(); + spgr.setRecordId(EscherContainerRecord.SPGR_CONTAINER); + spgr.setOptions((short)15); + + //The group itself is a shape, and always appears as the first EscherSpContainer in the group container. + EscherContainerRecord spcont = new EscherContainerRecord(); + spcont.setRecordId(EscherContainerRecord.SP_CONTAINER); + spcont.setOptions((short)15); + + EscherSpgrRecord spg = new EscherSpgrRecord(); + spg.setOptions((short)1); + spcont.addChildRecord(spg); + + EscherSpRecord sp = new EscherSpRecord(); + short type = (ShapeTypes.NotPrimitive << 4) + 2; + sp.setOptions(type); + sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_GROUP); + spcont.addChildRecord(sp); + + EscherClientAnchorRecord anchor = new EscherClientAnchorRecord(); + spcont.addChildRecord(anchor); + + spgr.addChildRecord(spcont); + return spgr; + } + + /** + * Add a shape to this group. + * + * @param shape - the Shape to add + */ + public void addShape(Shape shape){ + _escherContainer.addChildRecord(shape.getSpContainer()); + + Sheet sheet = getSheet(); + shape.setSheet(sheet); + shape.afterInsert(sheet); + + if(shape instanceof TextBox) { + TextBox tbox = (TextBox)shape; + getSheet().getPPDrawing().addTextboxWrapper(tbox._txtbox); + } + } + + /** + * Moves this ShapeGroup to the specified location. + *

    + * @param x the x coordinate of the top left corner of the shape in new location + * @param y the y coordinate of the top left corner of the shape in new location + */ + public void moveTo(int x, int y){ + java.awt.Rectangle anchor = getAnchor(); + int dx = x - anchor.x; + int dy = y - anchor.y; + anchor.translate(dx, dy); + setAnchor(anchor); + + Shape[] shape = getShapes(); + for (int i = 0; i < shape.length; i++) { + java.awt.Rectangle chanchor = shape[i].getAnchor(); + chanchor.translate(dx, dy); + shape[i].setAnchor(chanchor); + } + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java index 30966d5865..6edb0f6456 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java @@ -1,257 +1,257 @@ -/* ==================================================================== - 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.hslf.model; - -import java.util.HashMap; -import java.lang.reflect.Field; - -/** - * Contains all known shape types in PowerPoint - * - * @author Yegor Kozlov - */ -public class ShapeTypes { - public static final int NotPrimitive = 0; - public static final int Rectangle = 1; - public static final int RoundRectangle = 2; - public static final int Ellipse = 3; - public static final int Diamond = 4; - public static final int IsocelesTriangle = 5; - public static final int RightTriangle = 6; - public static final int Parallelogram = 7; - public static final int Trapezoid = 8; - public static final int Hexagon = 9; - public static final int Octagon = 10; - public static final int Plus = 11; - public static final int Star = 12; - public static final int Arrow = 13; - public static final int ThickArrow = 14; - public static final int HomePlate = 15; - public static final int Cube = 16; - public static final int Balloon = 17; - public static final int Seal = 18; - public static final int Arc = 19; - public static final int Line = 20; - public static final int Plaque = 21; - public static final int Can = 22; - public static final int Donut = 23; - public static final int TextSimple = 24; - public static final int TextOctagon = 25; - public static final int TextHexagon = 26; - public static final int TextCurve = 27; - public static final int TextWave = 28; - public static final int TextRing = 29; - public static final int TextOnCurve = 30; - public static final int TextOnRing = 31; - public static final int StraightConnector1 = 32; - public static final int BentConnector2 = 33; - public static final int BentConnector3 = 34; - public static final int BentConnector4 = 35; - public static final int BentConnector5 = 36; - public static final int CurvedConnector2 = 37; - public static final int CurvedConnector3 = 38; - public static final int CurvedConnector4 = 39; - public static final int CurvedConnector5 = 40; - public static final int Callout1 = 41; - public static final int Callout2 = 42; - public static final int Callout3 = 43; - public static final int AccentCallout1 = 44; - public static final int AccentCallout2 = 45; - public static final int AccentCallout3 = 46; - public static final int BorderCallout1 = 47; - public static final int BorderCallout2 = 48; - public static final int BorderCallout3 = 49; - public static final int AccentBorderCallout1 = 50; - public static final int AccentBorderCallout2 = 51; - public static final int AccentBorderCallout3 = 52; - public static final int Ribbon = 53; - public static final int Ribbon2 = 54; - public static final int Chevron = 55; - public static final int Pentagon = 56; - public static final int NoSmoking = 57; - public static final int Star8 = 58; - public static final int Star16 = 59; - public static final int Star32 = 60; - public static final int WedgeRectCallout = 61; - public static final int WedgeRRectCallout = 62; - public static final int WedgeEllipseCallout = 63; - public static final int Wave = 64; - public static final int FoldedCorner = 65; - public static final int LeftArrow = 66; - public static final int DownArrow = 67; - public static final int UpArrow = 68; - public static final int LeftRightArrow = 69; - public static final int UpDownArrow = 70; - public static final int IrregularSeal1 = 71; - public static final int IrregularSeal2 = 72; - public static final int LightningBolt = 73; - public static final int Heart = 74; - public static final int PictureFrame = 75; - public static final int QuadArrow = 76; - public static final int LeftArrowCallout = 77; - public static final int RightArrowCallout = 78; - public static final int UpArrowCallout = 79; - public static final int DownArrowCallout = 80; - public static final int LeftRightArrowCallout = 81; - public static final int UpDownArrowCallout = 82; - public static final int QuadArrowCallout = 83; - public static final int Bevel = 84; - public static final int LeftBracket = 85; - public static final int RightBracket = 86; - public static final int LeftBrace = 87; - public static final int RightBrace = 88; - public static final int LeftUpArrow = 89; - public static final int BentUpArrow = 90; - public static final int BentArrow = 91; - public static final int Star24 = 92; - public static final int StripedRightArrow = 93; - public static final int NotchedRightArrow = 94; - public static final int BlockArc = 95; - public static final int SmileyFace = 96; - public static final int VerticalScroll = 97; - public static final int HorizontalScroll = 98; - public static final int CircularArrow = 99; - public static final int NotchedCircularArrow = 100; - public static final int UturnArrow = 101; - public static final int CurvedRightArrow = 102; - public static final int CurvedLeftArrow = 103; - public static final int CurvedUpArrow = 104; - public static final int CurvedDownArrow = 105; - public static final int CloudCallout = 106; - public static final int EllipseRibbon = 107; - public static final int EllipseRibbon2 = 108; - public static final int FlowChartProcess = 109; - public static final int FlowChartDecision = 110; - public static final int FlowChartInputOutput = 111; - public static final int FlowChartPredefinedProcess = 112; - public static final int FlowChartInternalStorage = 113; - public static final int FlowChartDocument = 114; - public static final int FlowChartMultidocument = 115; - public static final int FlowChartTerminator = 116; - public static final int FlowChartPreparation = 117; - public static final int FlowChartManualInput = 118; - public static final int FlowChartManualOperation = 119; - public static final int FlowChartConnector = 120; - public static final int FlowChartPunchedCard = 121; - public static final int FlowChartPunchedTape = 122; - public static final int FlowChartSummingJunction = 123; - public static final int FlowChartOr = 124; - public static final int FlowChartCollate = 125; - public static final int FlowChartSort = 126; - public static final int FlowChartExtract = 127; - public static final int FlowChartMerge = 128; - public static final int FlowChartOfflineStorage = 129; - public static final int FlowChartOnlineStorage = 130; - public static final int FlowChartMagneticTape = 131; - public static final int FlowChartMagneticDisk = 132; - public static final int FlowChartMagneticDrum = 133; - public static final int FlowChartDisplay = 134; - public static final int FlowChartDelay = 135; - public static final int TextPlainText = 136; - public static final int TextStop = 137; - public static final int TextTriangle = 138; - public static final int TextTriangleInverted = 139; - public static final int TextChevron = 140; - public static final int TextChevronInverted = 141; - public static final int TextRingInside = 142; - public static final int TextRingOutside = 143; - public static final int TextArchUpCurve = 144; - public static final int TextArchDownCurve = 145; - public static final int TextCircleCurve = 146; - public static final int TextButtonCurve = 147; - public static final int TextArchUpPour = 148; - public static final int TextArchDownPour = 149; - public static final int TextCirclePour = 150; - public static final int TextButtonPour = 151; - public static final int TextCurveUp = 152; - public static final int TextCurveDown = 153; - public static final int TextCascadeUp = 154; - public static final int TextCascadeDown = 155; - public static final int TextWave1 = 156; - public static final int TextWave2 = 157; - public static final int TextWave3 = 158; - public static final int TextWave4 = 159; - public static final int TextInflate = 160; - public static final int TextDeflate = 161; - public static final int TextInflateBottom = 162; - public static final int TextDeflateBottom = 163; - public static final int TextInflateTop = 164; - public static final int TextDeflateTop = 165; - public static final int TextDeflateInflate = 166; - public static final int TextDeflateInflateDeflate = 167; - public static final int TextFadeRight = 168; - public static final int TextFadeLeft = 169; - public static final int TextFadeUp = 170; - public static final int TextFadeDown = 171; - public static final int TextSlantUp = 172; - public static final int TextSlantDown = 173; - public static final int TextCanUp = 174; - public static final int TextCanDown = 175; - public static final int FlowChartAlternateProcess = 176; - public static final int FlowChartOffpageConnector = 177; - public static final int Callout90 = 178; - public static final int AccentCallout90 = 179; - public static final int BorderCallout90 = 180; - public static final int AccentBorderCallout90 = 181; - public static final int LeftRightUpArrow = 182; - public static final int Sun = 183; - public static final int Moon = 184; - public static final int BracketPair = 185; - public static final int BracePair = 186; - public static final int Star4 = 187; - public static final int DoubleWave = 188; - public static final int ActionButtonBlank = 189; - public static final int ActionButtonHome = 190; - public static final int ActionButtonHelp = 191; - public static final int ActionButtonInformation = 192; - public static final int ActionButtonForwardNext = 193; - public static final int ActionButtonBackPrevious = 194; - public static final int ActionButtonEnd = 195; - public static final int ActionButtonBeginning = 196; - public static final int ActionButtonReturn = 197; - public static final int ActionButtonDocument = 198; - public static final int ActionButtonSound = 199; - public static final int ActionButtonMovie = 200; - public static final int HostControl = 201; - public static final int TextBox = 202; - - /** - * Return name of the shape by id - * @param type - the id of the shape, one of the static constants defined in this class - * @return the name of the shape - */ - public static String typeName(int type) { - String name = (String)types.get(new Integer(type)); - return name; - } - - public static HashMap types; - static { - types = new HashMap(); - try { - Field[] f = ShapeTypes.class.getFields(); - for (int i = 0; i < f.length; i++){ - Object val = f[i].get(null); - if (val instanceof Integer) { - types.put(val, f[i].getName()); - } - } - } catch (IllegalAccessException e){ - throw new RuntimeException("Failed to initialize shape types"); - } - } - -} +/* ==================================================================== + 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.hslf.model; + +import java.util.HashMap; +import java.lang.reflect.Field; + +/** + * Contains all known shape types in PowerPoint + * + * @author Yegor Kozlov + */ +public class ShapeTypes { + public static final int NotPrimitive = 0; + public static final int Rectangle = 1; + public static final int RoundRectangle = 2; + public static final int Ellipse = 3; + public static final int Diamond = 4; + public static final int IsocelesTriangle = 5; + public static final int RightTriangle = 6; + public static final int Parallelogram = 7; + public static final int Trapezoid = 8; + public static final int Hexagon = 9; + public static final int Octagon = 10; + public static final int Plus = 11; + public static final int Star = 12; + public static final int Arrow = 13; + public static final int ThickArrow = 14; + public static final int HomePlate = 15; + public static final int Cube = 16; + public static final int Balloon = 17; + public static final int Seal = 18; + public static final int Arc = 19; + public static final int Line = 20; + public static final int Plaque = 21; + public static final int Can = 22; + public static final int Donut = 23; + public static final int TextSimple = 24; + public static final int TextOctagon = 25; + public static final int TextHexagon = 26; + public static final int TextCurve = 27; + public static final int TextWave = 28; + public static final int TextRing = 29; + public static final int TextOnCurve = 30; + public static final int TextOnRing = 31; + public static final int StraightConnector1 = 32; + public static final int BentConnector2 = 33; + public static final int BentConnector3 = 34; + public static final int BentConnector4 = 35; + public static final int BentConnector5 = 36; + public static final int CurvedConnector2 = 37; + public static final int CurvedConnector3 = 38; + public static final int CurvedConnector4 = 39; + public static final int CurvedConnector5 = 40; + public static final int Callout1 = 41; + public static final int Callout2 = 42; + public static final int Callout3 = 43; + public static final int AccentCallout1 = 44; + public static final int AccentCallout2 = 45; + public static final int AccentCallout3 = 46; + public static final int BorderCallout1 = 47; + public static final int BorderCallout2 = 48; + public static final int BorderCallout3 = 49; + public static final int AccentBorderCallout1 = 50; + public static final int AccentBorderCallout2 = 51; + public static final int AccentBorderCallout3 = 52; + public static final int Ribbon = 53; + public static final int Ribbon2 = 54; + public static final int Chevron = 55; + public static final int Pentagon = 56; + public static final int NoSmoking = 57; + public static final int Star8 = 58; + public static final int Star16 = 59; + public static final int Star32 = 60; + public static final int WedgeRectCallout = 61; + public static final int WedgeRRectCallout = 62; + public static final int WedgeEllipseCallout = 63; + public static final int Wave = 64; + public static final int FoldedCorner = 65; + public static final int LeftArrow = 66; + public static final int DownArrow = 67; + public static final int UpArrow = 68; + public static final int LeftRightArrow = 69; + public static final int UpDownArrow = 70; + public static final int IrregularSeal1 = 71; + public static final int IrregularSeal2 = 72; + public static final int LightningBolt = 73; + public static final int Heart = 74; + public static final int PictureFrame = 75; + public static final int QuadArrow = 76; + public static final int LeftArrowCallout = 77; + public static final int RightArrowCallout = 78; + public static final int UpArrowCallout = 79; + public static final int DownArrowCallout = 80; + public static final int LeftRightArrowCallout = 81; + public static final int UpDownArrowCallout = 82; + public static final int QuadArrowCallout = 83; + public static final int Bevel = 84; + public static final int LeftBracket = 85; + public static final int RightBracket = 86; + public static final int LeftBrace = 87; + public static final int RightBrace = 88; + public static final int LeftUpArrow = 89; + public static final int BentUpArrow = 90; + public static final int BentArrow = 91; + public static final int Star24 = 92; + public static final int StripedRightArrow = 93; + public static final int NotchedRightArrow = 94; + public static final int BlockArc = 95; + public static final int SmileyFace = 96; + public static final int VerticalScroll = 97; + public static final int HorizontalScroll = 98; + public static final int CircularArrow = 99; + public static final int NotchedCircularArrow = 100; + public static final int UturnArrow = 101; + public static final int CurvedRightArrow = 102; + public static final int CurvedLeftArrow = 103; + public static final int CurvedUpArrow = 104; + public static final int CurvedDownArrow = 105; + public static final int CloudCallout = 106; + public static final int EllipseRibbon = 107; + public static final int EllipseRibbon2 = 108; + public static final int FlowChartProcess = 109; + public static final int FlowChartDecision = 110; + public static final int FlowChartInputOutput = 111; + public static final int FlowChartPredefinedProcess = 112; + public static final int FlowChartInternalStorage = 113; + public static final int FlowChartDocument = 114; + public static final int FlowChartMultidocument = 115; + public static final int FlowChartTerminator = 116; + public static final int FlowChartPreparation = 117; + public static final int FlowChartManualInput = 118; + public static final int FlowChartManualOperation = 119; + public static final int FlowChartConnector = 120; + public static final int FlowChartPunchedCard = 121; + public static final int FlowChartPunchedTape = 122; + public static final int FlowChartSummingJunction = 123; + public static final int FlowChartOr = 124; + public static final int FlowChartCollate = 125; + public static final int FlowChartSort = 126; + public static final int FlowChartExtract = 127; + public static final int FlowChartMerge = 128; + public static final int FlowChartOfflineStorage = 129; + public static final int FlowChartOnlineStorage = 130; + public static final int FlowChartMagneticTape = 131; + public static final int FlowChartMagneticDisk = 132; + public static final int FlowChartMagneticDrum = 133; + public static final int FlowChartDisplay = 134; + public static final int FlowChartDelay = 135; + public static final int TextPlainText = 136; + public static final int TextStop = 137; + public static final int TextTriangle = 138; + public static final int TextTriangleInverted = 139; + public static final int TextChevron = 140; + public static final int TextChevronInverted = 141; + public static final int TextRingInside = 142; + public static final int TextRingOutside = 143; + public static final int TextArchUpCurve = 144; + public static final int TextArchDownCurve = 145; + public static final int TextCircleCurve = 146; + public static final int TextButtonCurve = 147; + public static final int TextArchUpPour = 148; + public static final int TextArchDownPour = 149; + public static final int TextCirclePour = 150; + public static final int TextButtonPour = 151; + public static final int TextCurveUp = 152; + public static final int TextCurveDown = 153; + public static final int TextCascadeUp = 154; + public static final int TextCascadeDown = 155; + public static final int TextWave1 = 156; + public static final int TextWave2 = 157; + public static final int TextWave3 = 158; + public static final int TextWave4 = 159; + public static final int TextInflate = 160; + public static final int TextDeflate = 161; + public static final int TextInflateBottom = 162; + public static final int TextDeflateBottom = 163; + public static final int TextInflateTop = 164; + public static final int TextDeflateTop = 165; + public static final int TextDeflateInflate = 166; + public static final int TextDeflateInflateDeflate = 167; + public static final int TextFadeRight = 168; + public static final int TextFadeLeft = 169; + public static final int TextFadeUp = 170; + public static final int TextFadeDown = 171; + public static final int TextSlantUp = 172; + public static final int TextSlantDown = 173; + public static final int TextCanUp = 174; + public static final int TextCanDown = 175; + public static final int FlowChartAlternateProcess = 176; + public static final int FlowChartOffpageConnector = 177; + public static final int Callout90 = 178; + public static final int AccentCallout90 = 179; + public static final int BorderCallout90 = 180; + public static final int AccentBorderCallout90 = 181; + public static final int LeftRightUpArrow = 182; + public static final int Sun = 183; + public static final int Moon = 184; + public static final int BracketPair = 185; + public static final int BracePair = 186; + public static final int Star4 = 187; + public static final int DoubleWave = 188; + public static final int ActionButtonBlank = 189; + public static final int ActionButtonHome = 190; + public static final int ActionButtonHelp = 191; + public static final int ActionButtonInformation = 192; + public static final int ActionButtonForwardNext = 193; + public static final int ActionButtonBackPrevious = 194; + public static final int ActionButtonEnd = 195; + public static final int ActionButtonBeginning = 196; + public static final int ActionButtonReturn = 197; + public static final int ActionButtonDocument = 198; + public static final int ActionButtonSound = 199; + public static final int ActionButtonMovie = 200; + public static final int HostControl = 201; + public static final int TextBox = 202; + + /** + * Return name of the shape by id + * @param type - the id of the shape, one of the static constants defined in this class + * @return the name of the shape + */ + public static String typeName(int type) { + String name = (String)types.get(new Integer(type)); + return name; + } + + public static HashMap types; + static { + types = new HashMap(); + try { + Field[] f = ShapeTypes.class.getFields(); + for (int i = 0; i < f.length; i++){ + Object val = f[i].get(null); + if (val instanceof Integer) { + types.put(val, f[i].getName()); + } + } + } catch (IllegalAccessException e){ + throw new RuntimeException("Failed to initialize shape types"); + } + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java index 7fc1ba4aef..3a96e4c8d6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java @@ -1,217 +1,217 @@ -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hslf.record.ColorSchemeAtom; - -import java.awt.*; - -/** - * An abstract simple (non-group) shape. - * This is the parent class for all primitive shapes like Line, Rectangle, etc. - * - * @author Yegor Kozlov - */ -public class SimpleShape extends Shape { - - /** - * Create a SimpleShape object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected SimpleShape(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - } - - /** - * Create a new Shape - * - * @param isChild true if the Line is inside a group, false otherwise - * @return the record container which holds this shape - */ - protected EscherContainerRecord createSpContainer(boolean isChild) { - EscherContainerRecord spContainer = new EscherContainerRecord(); - spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); - spContainer.setOptions((short)15); - - EscherSpRecord sp = new EscherSpRecord(); - int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE; - if (isChild) flags |= EscherSpRecord.FLAG_CHILD; - sp.setFlags(flags); - spContainer.addChildRecord(sp); - - EscherOptRecord opt = new EscherOptRecord(); - opt.setRecordId(EscherOptRecord.RECORD_ID); - spContainer.addChildRecord(opt); - - EscherRecord anchor; - if(isChild) anchor = new EscherChildAnchorRecord(); - else { - anchor = new EscherClientAnchorRecord(); - - //hack. internal variable EscherClientAnchorRecord.shortRecord can be - //initialized only in fillFields(). We need to set shortRecord=false; - byte[] header = new byte[16]; - LittleEndian.putUShort(header, 0, 0); - LittleEndian.putUShort(header, 2, 0); - LittleEndian.putInt(header, 4, 8); - anchor.fillFields(header, 0, null); - } - spContainer.addChildRecord(anchor); - - return spContainer; - } - - /** - * Returns width of the line in in points - */ - public double getLineWidth(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH); - return prop == null ? 0 : (double)prop.getPropertyValue()/EMU_PER_POINT; - } - - /** - * Sets the width of line in in points - * @param width the width of line in in points - */ - public void setLineWidth(double width){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH, (int)(width*EMU_PER_POINT)); - } - - /** - * Sets the color of line - * - * @param color new color of the line - */ - public void setLineColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, color == null ? 0x180010 : 0x180018); - } - - /** - * @return color of the line. If color is not set returns java.awt.Color.black - */ - public Color getLineColor(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - - EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR); - EscherSimpleProperty p2 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH); - int p2val = p2 == null ? 0 : p2.getPropertyValue(); - Color clr = null; - if (p1 != null && (p2val & 0x8) != 0){ - int rgb = p1.getPropertyValue(); - if (rgb >= 0x8000000) { - int idx = rgb % 0x8000000; - ColorSchemeAtom ca = getSheet().getColorScheme(); - if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); - } - Color tmp = new Color(rgb, true); - clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); - } - return clr; - } - - /** - * Gets line dashing. One of the PEN_* constants defined in this class. - * - * @return dashing of the line. - */ - public int getLineDashing(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); - return prop == null ? Line.PEN_SOLID : prop.getPropertyValue(); - } - - /** - * Sets line dashing. One of the PEN_* constants defined in this class. - * - * @param pen new style of the line. - */ - public void setLineDashing(int pen){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - - setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == Line.PEN_SOLID ? -1 : pen); - } - - /** - * Sets line style. One of the constants defined in this class. - * - * @param style new style of the line. - */ - public void setLineStyle(int style){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == Line.LINE_SIMPLE ? -1 : style); - } - - /** - * Returns line style. One of the constants defined in this class. - * - * @return style of the line. - */ - public int getLineStyle(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE); - return prop == null ? Line.LINE_SIMPLE : prop.getPropertyValue(); - } - - /** - * The color used to fill this shape. - * - * @param color the background color - */ - public Color getFillColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR); - EscherSimpleProperty p2= (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); - - int p2val = p2 == null ? 0 : p2.getPropertyValue(); - - Color clr = null; - if (p1 != null && (p2val & 0x10) != 0){ - int rgb = p1.getPropertyValue(); - if (rgb >= 0x8000000) { - int idx = rgb % 0x8000000; - ColorSchemeAtom ca = getSheet().getColorScheme(); - rgb = ca.getColor(idx); - } - Color tmp = new Color(rgb, true); - clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); - } - return clr; - } - - /** - * The color used to fill this shape. - * - * @param color the background color - */ - public void setFillColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, color == null ? 0x150010 : 0x150011); - } - -} +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.hslf.record.ColorSchemeAtom; + +import java.awt.*; + +/** + * An abstract simple (non-group) shape. + * This is the parent class for all primitive shapes like Line, Rectangle, etc. + * + * @author Yegor Kozlov + */ +public class SimpleShape extends Shape { + + /** + * Create a SimpleShape object and initialize it from the supplied Record container. + * + * @param escherRecord EscherSpContainer container which holds information about this shape + * @param parent the parent of the shape + */ + protected SimpleShape(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + } + + /** + * Create a new Shape + * + * @param isChild true if the Line is inside a group, false otherwise + * @return the record container which holds this shape + */ + protected EscherContainerRecord createSpContainer(boolean isChild) { + EscherContainerRecord spContainer = new EscherContainerRecord(); + spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); + spContainer.setOptions((short)15); + + EscherSpRecord sp = new EscherSpRecord(); + int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE; + if (isChild) flags |= EscherSpRecord.FLAG_CHILD; + sp.setFlags(flags); + spContainer.addChildRecord(sp); + + EscherOptRecord opt = new EscherOptRecord(); + opt.setRecordId(EscherOptRecord.RECORD_ID); + spContainer.addChildRecord(opt); + + EscherRecord anchor; + if(isChild) anchor = new EscherChildAnchorRecord(); + else { + anchor = new EscherClientAnchorRecord(); + + //hack. internal variable EscherClientAnchorRecord.shortRecord can be + //initialized only in fillFields(). We need to set shortRecord=false; + byte[] header = new byte[16]; + LittleEndian.putUShort(header, 0, 0); + LittleEndian.putUShort(header, 2, 0); + LittleEndian.putInt(header, 4, 8); + anchor.fillFields(header, 0, null); + } + spContainer.addChildRecord(anchor); + + return spContainer; + } + + /** + * Returns width of the line in in points + */ + public double getLineWidth(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH); + return prop == null ? 0 : (double)prop.getPropertyValue()/EMU_PER_POINT; + } + + /** + * Sets the width of line in in points + * @param width the width of line in in points + */ + public void setLineWidth(double width){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH, (int)(width*EMU_PER_POINT)); + } + + /** + * Sets the color of line + * + * @param color new color of the line + */ + public void setLineColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); + setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, rgb); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, color == null ? 0x180010 : 0x180018); + } + + /** + * @return color of the line. If color is not set returns java.awt.Color.black + */ + public Color getLineColor(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + + EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR); + EscherSimpleProperty p2 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH); + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + Color clr = null; + if (p1 != null && (p2val & 0x8) != 0){ + int rgb = p1.getPropertyValue(); + if (rgb >= 0x8000000) { + int idx = rgb % 0x8000000; + ColorSchemeAtom ca = getSheet().getColorScheme(); + if(idx >= 0 && idx <= 7) rgb = ca.getColor(idx); + } + Color tmp = new Color(rgb, true); + clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); + } + return clr; + } + + /** + * Gets line dashing. One of the PEN_* constants defined in this class. + * + * @return dashing of the line. + */ + public int getLineDashing(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING); + return prop == null ? Line.PEN_SOLID : prop.getPropertyValue(); + } + + /** + * Sets line dashing. One of the PEN_* constants defined in this class. + * + * @param pen new style of the line. + */ + public void setLineDashing(int pen){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + + setEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING, pen == Line.PEN_SOLID ? -1 : pen); + } + + /** + * Sets line style. One of the constants defined in this class. + * + * @param style new style of the line. + */ + public void setLineStyle(int style){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE, style == Line.LINE_SIMPLE ? -1 : style); + } + + /** + * Returns line style. One of the constants defined in this class. + * + * @return style of the line. + */ + public int getLineStyle(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE); + return prop == null ? Line.LINE_SIMPLE : prop.getPropertyValue(); + } + + /** + * The color used to fill this shape. + * + * @param color the background color + */ + public Color getFillColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty p1 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__FILLCOLOR); + EscherSimpleProperty p2= (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST); + + int p2val = p2 == null ? 0 : p2.getPropertyValue(); + + Color clr = null; + if (p1 != null && (p2val & 0x10) != 0){ + int rgb = p1.getPropertyValue(); + if (rgb >= 0x8000000) { + int idx = rgb % 0x8000000; + ColorSchemeAtom ca = getSheet().getColorScheme(); + rgb = ca.getColor(idx); + } + Color tmp = new Color(rgb, true); + clr = new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed()); + } + return clr; + } + + /** + * The color used to fill this shape. + * + * @param color the background color + */ + public void setFillColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); + setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, rgb); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, color == null ? 0x150010 : 0x150011); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java index da8098facb..2f852712b1 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java @@ -1,504 +1,504 @@ - -/* ==================================================================== - 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.hslf.model; - -import org.apache.poi.ddf.*; -import org.apache.poi.hslf.record.*; -import org.apache.poi.hslf.usermodel.RichTextRun; - -import java.awt.*; -import java.awt.font.FontRenderContext; -import java.awt.font.TextLayout; -import java.io.IOException; -import java.util.Vector; - -/** - * Represents a TextFrame shape in PowerPoint. - *

    - * Contains the text in a text frame as well as the properties and methods - * that control alignment and anchoring of the text. - *

    - * - * @author Yegor Kozlov - */ -public class TextBox extends SimpleShape { - - /** - * How to anchor the text - */ - public static final int AnchorTop = 0; - public static final int AnchorMiddle = 1; - public static final int AnchorBottom = 2; - public static final int AnchorTopCentered = 3; - public static final int AnchorMiddleCentered = 4; - public static final int AnchorBottomCentered = 5; - public static final int AnchorTopBaseline = 6; - public static final int AnchorBottomBaseline = 7; - public static final int AnchorTopCenteredBaseline = 8; - public static final int AnchorBottomCenteredBaseline = 9; - - /** - * How to wrap the text - */ - public static final int WrapSquare = 0; - public static final int WrapByPoints = 1; - public static final int WrapNone = 2; - public static final int WrapTopBottom = 3; - public static final int WrapThrough = 4; - - /** - * How to align the text - */ - public static final int AlignLeft = 0; - public static final int AlignCenter = 1; - public static final int AlignRight = 2; - public static final int AlignJustify = 3; - - /** - * Low-level object which holds actual text and format data - */ - protected TextRun _txtrun; - - /** - * Escher container which holds text attributes such as - * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc. - */ - protected EscherTextboxWrapper _txtbox; - - /** - * Is the TextBox missing the text records which actually - * store the text? - */ - private boolean _missingTextRecords = false; - - /** - * Create a TextBox object and initialize it from the supplied Record container. - * - * @param escherRecord EscherSpContainer container which holds information about this shape - * @param parent the parent of the shape - */ - protected TextBox(EscherContainerRecord escherRecord, Shape parent){ - super(escherRecord, parent); - - EscherTextboxRecord textbox = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID); - _txtbox = new EscherTextboxWrapper(textbox); - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - * @param parent the parent of this Shape. For example, if this text box is a cell - * in a table then the parent is Table. - */ - public TextBox(Shape parent){ - super(null, parent); - _escherContainer = createSpContainer(parent instanceof ShapeGroup); - } - - /** - * Create a new TextBox. This constructor is used when a new shape is created. - * - */ - public TextBox(){ - this(null); - } - - /** - * Create a new textBox and initialize internal structures - * - * @return the created EscherContainerRecord which holds shape data - */ - protected EscherContainerRecord createSpContainer(boolean isChild){ - EscherContainerRecord spcont = super.createSpContainer(isChild); - - EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); - short type = (ShapeTypes.TextBox << 4) | 0x2; - spRecord.setOptions(type); - - //set default properties for a textbox - EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0); - - setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, 0x8000004); - setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 0x8000000); - setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); - setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); - setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); - setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); - - //create EscherTextboxWrapper - _txtbox = new EscherTextboxWrapper(); - - TextHeaderAtom tha = new TextHeaderAtom(); - tha.setParentRecord(_txtbox); // TextHeaderAtom is parent aware - _txtbox.appendChildRecord(tha); - - TextCharsAtom tca = new TextCharsAtom(); - _txtbox.appendChildRecord(tca); - - StyleTextPropAtom sta = new StyleTextPropAtom(0); - _txtbox.appendChildRecord(sta); - - _txtrun = new TextRun(tha,tca,sta); - _txtrun.setText(""); - spcont.addChildRecord(_txtbox.getEscherRecord()); - - return spcont; - } - - /** - * Returns the text contained in this text frame. - * - * @return the text string for this textbox. - */ - public String getText(){ - return _txtrun.getText(); - } - - /** - * Sets the text contained in this text frame. - * - * @param text the text string used by this object. - */ - public void setText(String text){ - _txtrun.setText(text); - } - - /** - * When a textbox is added to a sheet we need to tell upper-level - * PPDrawing about it. - * - * @param sh the sheet we are adding to - */ - protected void afterInsert(Sheet sh){ - PPDrawing ppdrawing = sh.getPPDrawing(); - ppdrawing.addTextboxWrapper(_txtbox); - // Ensure the escher layer knows about the added records - try { - _txtbox.writeOut(null); - } catch (IOException e){ - throw new RuntimeException(e); - } - if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText(); - } - - /** - * Adjust the size of the TextBox so it encompasses the text inside it. - */ - public void resizeToFitText(){ - try{ - FontRenderContext frc = new FontRenderContext(null, true, true); - RichTextRun rt = _txtrun.getRichTextRuns()[0]; - int size = rt.getFontSize(); - int style = 0; - if (rt.isBold()) style |= Font.BOLD; - if (rt.isItalic()) style |= Font.ITALIC; - String fntname = rt.getFontName(); - Font font = new Font(fntname, style, size); - - TextLayout layout = new TextLayout(getText(), font, frc); - int width = Math.round(layout.getAdvance()); - int height = Math.round(layout.getAscent()); - - Dimension txsize = new Dimension(width, height); - java.awt.Rectangle anchor = getAnchor(); - anchor.setSize(txsize); - setAnchor(anchor); - } catch (Exception e){ - e.printStackTrace(); - - } - } - - /** - * Returns the type of vertical alignment for the text. - * One of the Anchor* constants defined in this class. - * - * @return the type of alignment - */ - public int getVerticalAlignment(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT); - int valign; - if (prop == null){ - int type = getTextRun().getRunType(); - switch (type){ - case TextHeaderAtom.TITLE_TYPE: - case TextHeaderAtom.CENTER_TITLE_TYPE: - valign = TextBox.AnchorMiddle; - break; - default: - valign = TextBox.AnchorTop; - break; - } - } else { - valign = prop.getPropertyValue(); - } - return valign; - } - - /** - * Sets the type of vertical alignment for the text. - * One of the Anchor* constants defined in this class. - * - * @param align - the type of alignment - */ - public void setVerticalAlignment(int align){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT, align); - } - /** - * Returns the distance (in points) between the bottom of the text frame - * and the bottom of the inscribed rectangle of the shape that contains the text. - * Default value is 1/20 inch. - * - * @return the botom margin - */ - public int getMarginBottom(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM); - int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue(); - return val/EMU_PER_POINT; - } - - /** - * Sets the botom margin. - * @see #getMarginBottom() - * - * @param margin the bottom margin - */ - public void setMarginBottom(int margin){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM, margin*EMU_PER_POINT); - } - - /** - * Returns the distance (in EMUs) between the left edge of the text frame - * and the left edge of the inscribed rectangle of the shape that contains - * the text. - * Default value is 1/10 inch. - * - * @return the left margin - */ - public int getMarginLeft(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM); - int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue(); - return val/EMU_PER_POINT; - } - - /** - * Sets the left margin. - * @see #getMarginLeft() - * - * @param margin the left margin - */ - public void setMarginLeft(int margin){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT, margin*EMU_PER_POINT); - } - - /** - * Returns the distance (in EMUs) between the right edge of the - * text frame and the right edge of the inscribed rectangle of the shape - * that contains the text. - * Default value is 1/10 inch. - * - * @return the right margin - */ - public int getMarginRight(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT); - int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue(); - return val/EMU_PER_POINT; - } - - /** - * Sets the right margin. - * @see #getMarginRight() - * - * @param margin the right margin - */ - public void setMarginRight(int margin){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT, margin*EMU_PER_POINT); - } - - /** - * Returns the distance (in EMUs) between the top of the text frame - * and the top of the inscribed rectangle of the shape that contains the text. - * Default value is 1/20 inch. - * - * @return the top margin - */ - public int getMarginTop(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP); - int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue(); - return val/EMU_PER_POINT; - } - - /** - * Sets the top margin. - * @see #getMarginTop() - * - * @param margin the top margin - */ - public void setMarginTop(int margin){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTTOP, margin*EMU_PER_POINT); - } - - - /** - * Returns the value indicating word wrap. - * One of the Wrap* constants defined in this class. - * - * @return the value indicating word wrap - */ - public int getWordWrap(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT); - return prop == null ? WrapSquare : prop.getPropertyValue(); - } - - /** - * Specifies how the text should be wrapped - * - * @param wrap the value indicating how the text should be wrapped - */ - public void setWordWrap(int wrap){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT, wrap); - } - - /** - * @return id for the text. - */ - public int getTextId(){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID); - return prop == null ? 0 : prop.getPropertyValue(); - } - - /** - * Sets text ID - * - * @param id of the text - */ - public void setTextId(int id){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - setEscherProperty(opt, EscherProperties.TEXT__TEXTID, id); - } - - /** - * The color used to fill this shape. - * - * @param color the background color - */ - public void setBackgroundColor(Color color){ - EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); - int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); - setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); - } - - /** - * @return the TextRun object for this text box - */ - public TextRun getTextRun(){ - return _txtrun; - } - - public void setSheet(Sheet sheet){ - _sheet = sheet; - - // Initialize _txtrun object. - // (We can't do it in the constructor because the sheet - // is not assigned then, it's only built once we have - // all the records) - if(_txtrun == null) initTextRun(); - if(_txtrun == null) { - // No text records found, skip - _missingTextRecords = true; - return; - } else { - _missingTextRecords = false; - } - - // Supply the sheet to our child RichTextRuns - _txtrun.setSheet(sheet); - RichTextRun[] rt = _txtrun.getRichTextRuns(); - for (int i = 0; i < rt.length; i++) { - rt[i].supplySlideShow(_sheet.getSlideShow()); - } - } - - private void initTextRun(){ - TextHeaderAtom tha = null; - TextCharsAtom tca = null; - TextBytesAtom tba = null; - StyleTextPropAtom sta = null; - OutlineTextRefAtom ota = null; - - // Find the interesting child records - Record[] child = _txtbox.getChildRecords(); - for (int i = 0; i < child.length; i++) { - if (child[i] instanceof TextHeaderAtom) tha = (TextHeaderAtom)child[i]; - else if (child[i] instanceof TextBytesAtom) tba = (TextBytesAtom)child[i]; - else if (child[i] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)child[i]; - else if (child[i] instanceof OutlineTextRefAtom) ota = (OutlineTextRefAtom)child[i]; - else if (child[i] instanceof TextCharsAtom) tca = (TextCharsAtom)child[i]; - } - - // Special handling for cases where there's an OutlineTextRefAtom - if (ota != null) { - // TextHeaderAtom, TextBytesAtom and StyleTextPropAtom are - // stored outside of EscherContainerRecord - int idx = ota.getTextIndex(); - Slide sl = (Slide)getSheet(); - Record[] rec = sl.getSlideAtomsSet().getSlideRecords(); - for (int i = 0, j = 0; i < rec.length; i++) { - if(rec[i].getRecordType() == RecordTypes.TextHeaderAtom.typeID){ - if(j++ == idx) { //we found j-th TextHeaderAtom, read the text data - for (int k = i; k < rec.length; k++) { - if (rec[k] instanceof TextHeaderAtom) { - if (tha != null) break; - else tha = (TextHeaderAtom)rec[k]; - } - else if (rec[k] instanceof TextBytesAtom) tba = (TextBytesAtom)rec[k]; - else if (rec[k] instanceof TextCharsAtom) tca = (TextCharsAtom)rec[k]; - else if (rec[k] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)rec[k]; - } - } - } - } - } - - // If we found the records we needed, create a TextRun - if(tba != null) { - // Bytes based Text Run - _txtrun = new TextRun(tha,tba,sta); - } else if (tca != null) { - // Characters (unicode) based Text Run - _txtrun = new TextRun(tha,tca,sta); - } else { - // Empty text box - System.err.println("Warning - no text records found for TextBox"); - } - } -} + +/* ==================================================================== + 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.hslf.model; + +import org.apache.poi.ddf.*; +import org.apache.poi.hslf.record.*; +import org.apache.poi.hslf.usermodel.RichTextRun; + +import java.awt.*; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; +import java.io.IOException; +import java.util.Vector; + +/** + * Represents a TextFrame shape in PowerPoint. + *

    + * Contains the text in a text frame as well as the properties and methods + * that control alignment and anchoring of the text. + *

    + * + * @author Yegor Kozlov + */ +public class TextBox extends SimpleShape { + + /** + * How to anchor the text + */ + public static final int AnchorTop = 0; + public static final int AnchorMiddle = 1; + public static final int AnchorBottom = 2; + public static final int AnchorTopCentered = 3; + public static final int AnchorMiddleCentered = 4; + public static final int AnchorBottomCentered = 5; + public static final int AnchorTopBaseline = 6; + public static final int AnchorBottomBaseline = 7; + public static final int AnchorTopCenteredBaseline = 8; + public static final int AnchorBottomCenteredBaseline = 9; + + /** + * How to wrap the text + */ + public static final int WrapSquare = 0; + public static final int WrapByPoints = 1; + public static final int WrapNone = 2; + public static final int WrapTopBottom = 3; + public static final int WrapThrough = 4; + + /** + * How to align the text + */ + public static final int AlignLeft = 0; + public static final int AlignCenter = 1; + public static final int AlignRight = 2; + public static final int AlignJustify = 3; + + /** + * Low-level object which holds actual text and format data + */ + protected TextRun _txtrun; + + /** + * Escher container which holds text attributes such as + * TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc. + */ + protected EscherTextboxWrapper _txtbox; + + /** + * Is the TextBox missing the text records which actually + * store the text? + */ + private boolean _missingTextRecords = false; + + /** + * Create a TextBox object and initialize it from the supplied Record container. + * + * @param escherRecord EscherSpContainer container which holds information about this shape + * @param parent the parent of the shape + */ + protected TextBox(EscherContainerRecord escherRecord, Shape parent){ + super(escherRecord, parent); + + EscherTextboxRecord textbox = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID); + _txtbox = new EscherTextboxWrapper(textbox); + } + + /** + * Create a new TextBox. This constructor is used when a new shape is created. + * + * @param parent the parent of this Shape. For example, if this text box is a cell + * in a table then the parent is Table. + */ + public TextBox(Shape parent){ + super(null, parent); + _escherContainer = createSpContainer(parent instanceof ShapeGroup); + } + + /** + * Create a new TextBox. This constructor is used when a new shape is created. + * + */ + public TextBox(){ + this(null); + } + + /** + * Create a new textBox and initialize internal structures + * + * @return the created EscherContainerRecord which holds shape data + */ + protected EscherContainerRecord createSpContainer(boolean isChild){ + EscherContainerRecord spcont = super.createSpContainer(isChild); + + EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID); + short type = (ShapeTypes.TextBox << 4) | 0x2; + spRecord.setOptions(type); + + //set default properties for a textbox + EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0); + + setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, 0x8000004); + setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 0x8000000); + setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000); + setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001); + setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000); + setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002); + + //create EscherTextboxWrapper + _txtbox = new EscherTextboxWrapper(); + + TextHeaderAtom tha = new TextHeaderAtom(); + tha.setParentRecord(_txtbox); // TextHeaderAtom is parent aware + _txtbox.appendChildRecord(tha); + + TextCharsAtom tca = new TextCharsAtom(); + _txtbox.appendChildRecord(tca); + + StyleTextPropAtom sta = new StyleTextPropAtom(0); + _txtbox.appendChildRecord(sta); + + _txtrun = new TextRun(tha,tca,sta); + _txtrun.setText(""); + spcont.addChildRecord(_txtbox.getEscherRecord()); + + return spcont; + } + + /** + * Returns the text contained in this text frame. + * + * @return the text string for this textbox. + */ + public String getText(){ + return _txtrun.getText(); + } + + /** + * Sets the text contained in this text frame. + * + * @param text the text string used by this object. + */ + public void setText(String text){ + _txtrun.setText(text); + } + + /** + * When a textbox is added to a sheet we need to tell upper-level + * PPDrawing about it. + * + * @param sh the sheet we are adding to + */ + protected void afterInsert(Sheet sh){ + PPDrawing ppdrawing = sh.getPPDrawing(); + ppdrawing.addTextboxWrapper(_txtbox); + // Ensure the escher layer knows about the added records + try { + _txtbox.writeOut(null); + } catch (IOException e){ + throw new RuntimeException(e); + } + if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText(); + } + + /** + * Adjust the size of the TextBox so it encompasses the text inside it. + */ + public void resizeToFitText(){ + try{ + FontRenderContext frc = new FontRenderContext(null, true, true); + RichTextRun rt = _txtrun.getRichTextRuns()[0]; + int size = rt.getFontSize(); + int style = 0; + if (rt.isBold()) style |= Font.BOLD; + if (rt.isItalic()) style |= Font.ITALIC; + String fntname = rt.getFontName(); + Font font = new Font(fntname, style, size); + + TextLayout layout = new TextLayout(getText(), font, frc); + int width = Math.round(layout.getAdvance()); + int height = Math.round(layout.getAscent()); + + Dimension txsize = new Dimension(width, height); + java.awt.Rectangle anchor = getAnchor(); + anchor.setSize(txsize); + setAnchor(anchor); + } catch (Exception e){ + e.printStackTrace(); + + } + } + + /** + * Returns the type of vertical alignment for the text. + * One of the Anchor* constants defined in this class. + * + * @return the type of alignment + */ + public int getVerticalAlignment(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT); + int valign; + if (prop == null){ + int type = getTextRun().getRunType(); + switch (type){ + case TextHeaderAtom.TITLE_TYPE: + case TextHeaderAtom.CENTER_TITLE_TYPE: + valign = TextBox.AnchorMiddle; + break; + default: + valign = TextBox.AnchorTop; + break; + } + } else { + valign = prop.getPropertyValue(); + } + return valign; + } + + /** + * Sets the type of vertical alignment for the text. + * One of the Anchor* constants defined in this class. + * + * @param align - the type of alignment + */ + public void setVerticalAlignment(int align){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT, align); + } + /** + * Returns the distance (in points) between the bottom of the text frame + * and the bottom of the inscribed rectangle of the shape that contains the text. + * Default value is 1/20 inch. + * + * @return the botom margin + */ + public int getMarginBottom(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM); + int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue(); + return val/EMU_PER_POINT; + } + + /** + * Sets the botom margin. + * @see #getMarginBottom() + * + * @param margin the bottom margin + */ + public void setMarginBottom(int margin){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM, margin*EMU_PER_POINT); + } + + /** + * Returns the distance (in EMUs) between the left edge of the text frame + * and the left edge of the inscribed rectangle of the shape that contains + * the text. + * Default value is 1/10 inch. + * + * @return the left margin + */ + public int getMarginLeft(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM); + int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue(); + return val/EMU_PER_POINT; + } + + /** + * Sets the left margin. + * @see #getMarginLeft() + * + * @param margin the left margin + */ + public void setMarginLeft(int margin){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT, margin*EMU_PER_POINT); + } + + /** + * Returns the distance (in EMUs) between the right edge of the + * text frame and the right edge of the inscribed rectangle of the shape + * that contains the text. + * Default value is 1/10 inch. + * + * @return the right margin + */ + public int getMarginRight(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT); + int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue(); + return val/EMU_PER_POINT; + } + + /** + * Sets the right margin. + * @see #getMarginRight() + * + * @param margin the right margin + */ + public void setMarginRight(int margin){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT, margin*EMU_PER_POINT); + } + + /** + * Returns the distance (in EMUs) between the top of the text frame + * and the top of the inscribed rectangle of the shape that contains the text. + * Default value is 1/20 inch. + * + * @return the top margin + */ + public int getMarginTop(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP); + int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue(); + return val/EMU_PER_POINT; + } + + /** + * Sets the top margin. + * @see #getMarginTop() + * + * @param margin the top margin + */ + public void setMarginTop(int margin){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTTOP, margin*EMU_PER_POINT); + } + + + /** + * Returns the value indicating word wrap. + * One of the Wrap* constants defined in this class. + * + * @return the value indicating word wrap + */ + public int getWordWrap(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT); + return prop == null ? WrapSquare : prop.getPropertyValue(); + } + + /** + * Specifies how the text should be wrapped + * + * @param wrap the value indicating how the text should be wrapped + */ + public void setWordWrap(int wrap){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT, wrap); + } + + /** + * @return id for the text. + */ + public int getTextId(){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID); + return prop == null ? 0 : prop.getPropertyValue(); + } + + /** + * Sets text ID + * + * @param id of the text + */ + public void setTextId(int id){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + setEscherProperty(opt, EscherProperties.TEXT__TEXTID, id); + } + + /** + * The color used to fill this shape. + * + * @param color the background color + */ + public void setBackgroundColor(Color color){ + EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID); + int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); + setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb); + } + + /** + * @return the TextRun object for this text box + */ + public TextRun getTextRun(){ + return _txtrun; + } + + public void setSheet(Sheet sheet){ + _sheet = sheet; + + // Initialize _txtrun object. + // (We can't do it in the constructor because the sheet + // is not assigned then, it's only built once we have + // all the records) + if(_txtrun == null) initTextRun(); + if(_txtrun == null) { + // No text records found, skip + _missingTextRecords = true; + return; + } else { + _missingTextRecords = false; + } + + // Supply the sheet to our child RichTextRuns + _txtrun.setSheet(sheet); + RichTextRun[] rt = _txtrun.getRichTextRuns(); + for (int i = 0; i < rt.length; i++) { + rt[i].supplySlideShow(_sheet.getSlideShow()); + } + } + + private void initTextRun(){ + TextHeaderAtom tha = null; + TextCharsAtom tca = null; + TextBytesAtom tba = null; + StyleTextPropAtom sta = null; + OutlineTextRefAtom ota = null; + + // Find the interesting child records + Record[] child = _txtbox.getChildRecords(); + for (int i = 0; i < child.length; i++) { + if (child[i] instanceof TextHeaderAtom) tha = (TextHeaderAtom)child[i]; + else if (child[i] instanceof TextBytesAtom) tba = (TextBytesAtom)child[i]; + else if (child[i] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)child[i]; + else if (child[i] instanceof OutlineTextRefAtom) ota = (OutlineTextRefAtom)child[i]; + else if (child[i] instanceof TextCharsAtom) tca = (TextCharsAtom)child[i]; + } + + // Special handling for cases where there's an OutlineTextRefAtom + if (ota != null) { + // TextHeaderAtom, TextBytesAtom and StyleTextPropAtom are + // stored outside of EscherContainerRecord + int idx = ota.getTextIndex(); + Slide sl = (Slide)getSheet(); + Record[] rec = sl.getSlideAtomsSet().getSlideRecords(); + for (int i = 0, j = 0; i < rec.length; i++) { + if(rec[i].getRecordType() == RecordTypes.TextHeaderAtom.typeID){ + if(j++ == idx) { //we found j-th TextHeaderAtom, read the text data + for (int k = i; k < rec.length; k++) { + if (rec[k] instanceof TextHeaderAtom) { + if (tha != null) break; + else tha = (TextHeaderAtom)rec[k]; + } + else if (rec[k] instanceof TextBytesAtom) tba = (TextBytesAtom)rec[k]; + else if (rec[k] instanceof TextCharsAtom) tca = (TextCharsAtom)rec[k]; + else if (rec[k] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)rec[k]; + } + } + } + } + } + + // If we found the records we needed, create a TextRun + if(tba != null) { + // Bytes based Text Run + _txtrun = new TextRun(tha,tba,sta); + } else if (tca != null) { + // Characters (unicode) based Text Run + _txtrun = new TextRun(tha,tca,sta); + } else { + // Empty text box + System.err.println("Warning - no text records found for TextBox"); + } + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java index 7c588b98f9..6b81f3867d 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java @@ -1,200 +1,200 @@ - -/* ==================================================================== - 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.hslf.record; - -import org.apache.poi.util.LittleEndian; -import java.io.IOException; -import java.io.OutputStream; - -/** - * OEPlaceholderAtom (3011). - *

    - * Atom that describes the placeholder. - *

    - * - * @author Yegor Kozlov - */ - -public class OEPlaceholderAtom extends RecordAtom{ - - public static final int PLACEHOLDER_FULLSIZE = 0; - public static final int PLACEHOLDER_HALFSIZE = 1; - public static final int PLACEHOLDER_QUARTSIZE = 2; - - public static final byte None = 0; - - public static final byte MasterTitle = 1; - - public static final byte MasterBody = 2; - - public static final byte MasterCenteredTitle = 3; - - public static final byte MasterNotesSlideImage = 4; - - public static final byte MasterNotesBodyImage = 5; - - public static final byte MasterDate = 6; - - public static final byte MasterSlideNumber = 7; - - public static final byte MasterFooter = 8; - - public static final byte MasterHeader = 9; - - public static final byte MasterSubtitle = 10; - - public static final byte GenericTextObject = 11; - - public static final byte Title = 12; - - public static final byte Body = 13; - - public static final byte NotesBody = 14; - - public static final byte CenteredTitle = 15; - - public static final byte Subtitle = 16; - - public static final byte VerticalTextTitle = 17; - - public static final byte VerticalTextBody = 18; - - public static final byte NotesSlideImage = 19; - - public static final byte Object = 20; - - public static final byte Graph = 21; - - public static final byte Table = 22; - - public static final byte ClipArt = 23; - - public static final byte OrganizationChart = 24; - - public static final byte MediaClip = 25; - - private byte[] _header; - - private int placementId; - private int placeholderId; - private int placeholderSize; - - - /** - * Create a new instance of OEPlaceholderAtom - */ - public OEPlaceholderAtom(){ - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 8); - - placementId = 0; - placeholderId = 0; - placeholderSize = 0; - } - - /** - * Build an instance of OEPlaceholderAtom from on-disk data - */ - protected OEPlaceholderAtom(byte[] source, int start, int len) { - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - placementId = LittleEndian.getInt(source, start); - placeholderId = LittleEndian.getUnsignedByte(source, start+4); - placeholderSize = LittleEndian.getUnsignedByte(source, start+5); - } - - /** - * @return type of this record {@link RecordTypes#OEPlaceholderAtom}. - */ - public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; } - - /** - * Returns the placement Id. - * - * @return the placement Id. - */ - public int getPlacementId(){ - return placementId; - } - - /** - * Sets the placement Id. - * - * @param id the placement Id. - */ - public void setPlacementId(int id){ - placementId = id; - } - - /** - * Returns the placeholder Id. - * - * @return the placeholder Id. - */ - public int getPlaceholderId(){ - return placeholderId; - } - - /** - * Sets the placeholder Id. - * - * @param id the placeholder Id. - */ - public void setPlaceholderId(byte id){ - placeholderId = id; - } - - /** - * Returns the placeholder size. - * Must be one of the PLACEHOLDER_* static constants defined in this class. - * - * @return the placeholder size. - */ - public int getPlaceholderSize(){ - return placeholderSize; - } - - /** - * Sets the placeholder size. - * Must be one of the PLACEHOLDER_* static constants defined in this class. - * - * @param size the placeholder size. - */ - public void setPlaceholderSize(byte size){ - placeholderSize = size; - } - - /** - * Write the contents of the record back, so it can be written - * to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - - byte[] recdata = new byte[8]; - LittleEndian.putInt(recdata, 0, placementId); - recdata[4] = (byte)placeholderId; - recdata[5] = (byte)placeholderSize; - - out.write(recdata); - } -} + +/* ==================================================================== + 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.hslf.record; + +import org.apache.poi.util.LittleEndian; +import java.io.IOException; +import java.io.OutputStream; + +/** + * OEPlaceholderAtom (3011). + *

    + * Atom that describes the placeholder. + *

    + * + * @author Yegor Kozlov + */ + +public class OEPlaceholderAtom extends RecordAtom{ + + public static final int PLACEHOLDER_FULLSIZE = 0; + public static final int PLACEHOLDER_HALFSIZE = 1; + public static final int PLACEHOLDER_QUARTSIZE = 2; + + public static final byte None = 0; + + public static final byte MasterTitle = 1; + + public static final byte MasterBody = 2; + + public static final byte MasterCenteredTitle = 3; + + public static final byte MasterNotesSlideImage = 4; + + public static final byte MasterNotesBodyImage = 5; + + public static final byte MasterDate = 6; + + public static final byte MasterSlideNumber = 7; + + public static final byte MasterFooter = 8; + + public static final byte MasterHeader = 9; + + public static final byte MasterSubtitle = 10; + + public static final byte GenericTextObject = 11; + + public static final byte Title = 12; + + public static final byte Body = 13; + + public static final byte NotesBody = 14; + + public static final byte CenteredTitle = 15; + + public static final byte Subtitle = 16; + + public static final byte VerticalTextTitle = 17; + + public static final byte VerticalTextBody = 18; + + public static final byte NotesSlideImage = 19; + + public static final byte Object = 20; + + public static final byte Graph = 21; + + public static final byte Table = 22; + + public static final byte ClipArt = 23; + + public static final byte OrganizationChart = 24; + + public static final byte MediaClip = 25; + + private byte[] _header; + + private int placementId; + private int placeholderId; + private int placeholderSize; + + + /** + * Create a new instance of OEPlaceholderAtom + */ + public OEPlaceholderAtom(){ + _header = new byte[8]; + LittleEndian.putUShort(_header, 0, 0); + LittleEndian.putUShort(_header, 2, (int)getRecordType()); + LittleEndian.putInt(_header, 4, 8); + + placementId = 0; + placeholderId = 0; + placeholderSize = 0; + } + + /** + * Build an instance of OEPlaceholderAtom from on-disk data + */ + protected OEPlaceholderAtom(byte[] source, int start, int len) { + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + placementId = LittleEndian.getInt(source, start); + placeholderId = LittleEndian.getUnsignedByte(source, start+4); + placeholderSize = LittleEndian.getUnsignedByte(source, start+5); + } + + /** + * @return type of this record {@link RecordTypes#OEPlaceholderAtom}. + */ + public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; } + + /** + * Returns the placement Id. + * + * @return the placement Id. + */ + public int getPlacementId(){ + return placementId; + } + + /** + * Sets the placement Id. + * + * @param id the placement Id. + */ + public void setPlacementId(int id){ + placementId = id; + } + + /** + * Returns the placeholder Id. + * + * @return the placeholder Id. + */ + public int getPlaceholderId(){ + return placeholderId; + } + + /** + * Sets the placeholder Id. + * + * @param id the placeholder Id. + */ + public void setPlaceholderId(byte id){ + placeholderId = id; + } + + /** + * Returns the placeholder size. + * Must be one of the PLACEHOLDER_* static constants defined in this class. + * + * @return the placeholder size. + */ + public int getPlaceholderSize(){ + return placeholderSize; + } + + /** + * Sets the placeholder size. + * Must be one of the PLACEHOLDER_* static constants defined in this class. + * + * @param size the placeholder size. + */ + public void setPlaceholderSize(byte size){ + placeholderSize = size; + } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + + byte[] recdata = new byte[8]; + LittleEndian.putInt(recdata, 0, placementId); + recdata[4] = (byte)placeholderId; + recdata[5] = (byte)placeholderSize; + + out.write(recdata); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java index ed92d8a7e5..5abcb5d4a4 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java @@ -1,107 +1,107 @@ -/* ==================================================================== - 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.hslf.record; - -import org.apache.poi.util.LittleEndian; - -import java.io.OutputStream; -import java.io.IOException; - -/** - * OEPlaceholderAtom (3998). - *
    - * What MSDN says about OutlineTextRefAtom: - *

    - * Appears in a slide to indicate a text that is already contained in the document, - * in a SlideListWithText containter. Sometimes slide texts are not contained - * within the slide container to be able to delay loading a slide and still display - * the title and body text in outline view. - *

    - * - * @author Yegor Kozlov - */ - -public class OutlineTextRefAtom extends RecordAtom { - /** - * record header - */ - private byte[] _header; - - /** - * the text's index within the SlideListWithText (0 for title, 1..n for the nth body) - */ - private int _index; - - /** - * Build an instance of OutlineTextRefAtom from on-disk data - */ - protected OutlineTextRefAtom(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Grab the record data - _index = LittleEndian.getInt(source, start+8); - } - - /** - * Create a new instance of FontEntityAtom - */ - protected OutlineTextRefAtom() { - _index = 0; - - _header = new byte[8]; - LittleEndian.putUShort(_header, 0, 0); - LittleEndian.putUShort(_header, 2, (int)getRecordType()); - LittleEndian.putInt(_header, 4, 4); - } - - public long getRecordType() { - return RecordTypes.OutlineTextRefAtom.typeID; - } - - /** - * Write the contents of the record back, so it can be written to disk - */ - public void writeOut(OutputStream out) throws IOException { - out.write(_header); - - byte[] recdata = new byte[4]; - LittleEndian.putInt(recdata, 0, _index); - out.write(recdata); - } - - /** - * Sets text's index within the SlideListWithText container - * (0 for title, 1..n for the nth body). - * - * @param idx 0-based text's index - */ - public void setTextIndex(int idx){ - _index = idx; - } - - /** - * Return text's index within the SlideListWithText container - * (0 for title, 1..n for the nth body). - * - * @return idx text's index - */ - public int getTextIndex(){ - return _index; - } - -} +/* ==================================================================== + 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.hslf.record; + +import org.apache.poi.util.LittleEndian; + +import java.io.OutputStream; +import java.io.IOException; + +/** + * OEPlaceholderAtom (3998). + *
    + * What MSDN says about OutlineTextRefAtom: + *

    + * Appears in a slide to indicate a text that is already contained in the document, + * in a SlideListWithText containter. Sometimes slide texts are not contained + * within the slide container to be able to delay loading a slide and still display + * the title and body text in outline view. + *

    + * + * @author Yegor Kozlov + */ + +public class OutlineTextRefAtom extends RecordAtom { + /** + * record header + */ + private byte[] _header; + + /** + * the text's index within the SlideListWithText (0 for title, 1..n for the nth body) + */ + private int _index; + + /** + * Build an instance of OutlineTextRefAtom from on-disk data + */ + protected OutlineTextRefAtom(byte[] source, int start, int len) { + // Get the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Grab the record data + _index = LittleEndian.getInt(source, start+8); + } + + /** + * Create a new instance of FontEntityAtom + */ + protected OutlineTextRefAtom() { + _index = 0; + + _header = new byte[8]; + LittleEndian.putUShort(_header, 0, 0); + LittleEndian.putUShort(_header, 2, (int)getRecordType()); + LittleEndian.putInt(_header, 4, 4); + } + + public long getRecordType() { + return RecordTypes.OutlineTextRefAtom.typeID; + } + + /** + * Write the contents of the record back, so it can be written to disk + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + + byte[] recdata = new byte[4]; + LittleEndian.putInt(recdata, 0, _index); + out.write(recdata); + } + + /** + * Sets text's index within the SlideListWithText container + * (0 for title, 1..n for the nth body). + * + * @param idx 0-based text's index + */ + public void setTextIndex(int idx){ + _index = idx; + } + + /** + * Return text's index within the SlideListWithText container + * (0 for title, 1..n for the nth body). + * + * @return idx text's index + */ + public int getTextIndex(){ + return _index; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java index f877d2a4a1..93b2fd7888 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java @@ -1,103 +1,103 @@ -package org.apache.poi.hslf.record; - -import org.apache.poi.ddf.*; -import org.apache.poi.util.LittleEndian; - -import java.io.OutputStream; -import java.io.IOException; -import java.io.ByteArrayOutputStream; -import java.util.List; -import java.util.Iterator; - -/** - * Container records which always exists inside Document. - * It always acts as a holder for escher DGG container - * which may contain which Escher BStore container information - * about pictures containes in the presentation (if any). - * - * @author Yegor Kozlov - */ -public class PPDrawingGroup extends RecordAtom { - - private byte[] _header; - private EscherContainerRecord dggContainer; - - protected PPDrawingGroup(byte[] source, int start, int len) { - // Get the header - _header = new byte[8]; - System.arraycopy(source,start,_header,0,8); - - // Get the contents for now - byte[] contents = new byte[len]; - System.arraycopy(source,start,contents,0,len); - - DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory(); - EscherRecord child = erf.createRecord(contents, 0); - child.fillFields( contents, 0, erf ); - dggContainer = (EscherContainerRecord)child.getChild(0); - } - - /** - * We are type 1035 - */ - public long getRecordType() { - return RecordTypes.PPDrawingGroup.typeID; - } - - /** - * We're pretending to be an atom, so return null - */ - public Record[] getChildRecords() { - return null; - } - - public void writeOut(OutputStream out) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - List child = dggContainer.getChildRecords(); - for (int i = 0; i < child.size(); i++) { - EscherRecord r = (EscherRecord)child.get(i); - if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){ - EscherContainerRecord bstore = (EscherContainerRecord)r; - - ByteArrayOutputStream b2 = new ByteArrayOutputStream(); - List blip = bstore.getChildRecords(); - for (Iterator it=blip.iterator(); it.hasNext();) { - EscherBSERecord bse = (EscherBSERecord)it.next(); - byte[] b = new byte[36+8]; - bse.serialize(0, b); - b2.write(b); - } - byte[] bstorehead = new byte[8]; - LittleEndian.putShort(bstorehead, 0, bstore.getOptions()); - LittleEndian.putShort(bstorehead, 2, bstore.getRecordId()); - LittleEndian.putInt(bstorehead, 4, b2.size()); - bout.write(bstorehead); - bout.write(b2.toByteArray()); - - } else { - bout.write(r.serialize()); - } - } - int size = bout.size(); - - // Update the size (header bytes 5-8) - LittleEndian.putInt(_header,4,size+8); - - // Write out our header - out.write(_header); - - byte[] dgghead = new byte[8]; - LittleEndian.putShort(dgghead, 0, dggContainer.getOptions()); - LittleEndian.putShort(dgghead, 2, dggContainer.getRecordId()); - LittleEndian.putInt(dgghead, 4, size); - out.write(dgghead); - - // Finally, write out the children - out.write(bout.toByteArray()); - - } - - public EscherContainerRecord getDggContainer(){ - return dggContainer; - } -} +package org.apache.poi.hslf.record; + +import org.apache.poi.ddf.*; +import org.apache.poi.util.LittleEndian; + +import java.io.OutputStream; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Iterator; + +/** + * Container records which always exists inside Document. + * It always acts as a holder for escher DGG container + * which may contain which Escher BStore container information + * about pictures containes in the presentation (if any). + * + * @author Yegor Kozlov + */ +public class PPDrawingGroup extends RecordAtom { + + private byte[] _header; + private EscherContainerRecord dggContainer; + + protected PPDrawingGroup(byte[] source, int start, int len) { + // Get the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Get the contents for now + byte[] contents = new byte[len]; + System.arraycopy(source,start,contents,0,len); + + DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory(); + EscherRecord child = erf.createRecord(contents, 0); + child.fillFields( contents, 0, erf ); + dggContainer = (EscherContainerRecord)child.getChild(0); + } + + /** + * We are type 1035 + */ + public long getRecordType() { + return RecordTypes.PPDrawingGroup.typeID; + } + + /** + * We're pretending to be an atom, so return null + */ + public Record[] getChildRecords() { + return null; + } + + public void writeOut(OutputStream out) throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + List child = dggContainer.getChildRecords(); + for (int i = 0; i < child.size(); i++) { + EscherRecord r = (EscherRecord)child.get(i); + if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){ + EscherContainerRecord bstore = (EscherContainerRecord)r; + + ByteArrayOutputStream b2 = new ByteArrayOutputStream(); + List blip = bstore.getChildRecords(); + for (Iterator it=blip.iterator(); it.hasNext();) { + EscherBSERecord bse = (EscherBSERecord)it.next(); + byte[] b = new byte[36+8]; + bse.serialize(0, b); + b2.write(b); + } + byte[] bstorehead = new byte[8]; + LittleEndian.putShort(bstorehead, 0, bstore.getOptions()); + LittleEndian.putShort(bstorehead, 2, bstore.getRecordId()); + LittleEndian.putInt(bstorehead, 4, b2.size()); + bout.write(bstorehead); + bout.write(b2.toByteArray()); + + } else { + bout.write(r.serialize()); + } + } + int size = bout.size(); + + // Update the size (header bytes 5-8) + LittleEndian.putInt(_header,4,size+8); + + // Write out our header + out.write(_header); + + byte[] dgghead = new byte[8]; + LittleEndian.putShort(dgghead, 0, dggContainer.getOptions()); + LittleEndian.putShort(dgghead, 2, dggContainer.getRecordId()); + LittleEndian.putInt(dgghead, 4, size); + out.write(dgghead); + + // Finally, write out the children + out.write(bout.toByteArray()); + + } + + public EscherContainerRecord getDggContainer(){ + return dggContainer; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java index 2c9f714244..28dff9ea53 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java @@ -1,213 +1,213 @@ -/* ==================================================================== - 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.hslf.usermodel; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.hslf.model.Picture; -import org.apache.poi.hslf.blip.*; - -import java.io.OutputStream; -import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * A class that represents image data contained in a slide show. - * - * @author Yegor Kozlov - */ -public abstract class PictureData { - - /** - * Size of the image checksum calculated using MD5 algorithm. - */ - protected static final int CHECKSUM_SIZE = 16; - - /** - * Binary data of the picture - */ - private byte[] rawdata; - /** - * The offset to the picture in the stream - */ - protected int offset; - - /** - * Returns type of this picture. - * Must be one of the static constants defined in the Picture class. - * - * @return type of this picture. - */ - public abstract int getType(); - - /** - * Returns the binary data of this Picture - * @return picture data - */ - public abstract byte[] getData(); - - /** - * Set picture data - */ - public abstract void setData(byte[] data) throws IOException; - - /** - * Blip signature. - */ - protected abstract int getSignature(); - - /** - * Returns the raw binary data of this Picture excluding the first 8 bytes - * which hold image signature and size of the image data. - * - * @return picture data - */ - public byte[] getRawData(){ - return rawdata; - } - - public void setRawData(byte[] data){ - rawdata = data; - } - - /** - * File offset in the 'Pictures' stream - * - * @return offset in the 'Pictures' stream - */ - public int getOffset(){ - return offset; - } - - /** - * Set offset of this picture in the 'Pictures' stream. - * We need to set it when a new picture is created. - * - * @param offset in the 'Pictures' stream - */ - public void setOffset(int offset){ - this.offset = offset; - } - - /** - * Returns 16-byte checksum of this picture - */ - public byte[] getUID(){ - byte[] uid = new byte[16]; - System.arraycopy(rawdata, 0, uid, 0, uid.length); - return uid; - } - - - /** - * Compute 16-byte checksum of this picture using MD5 algorithm. - */ - public static byte[] getChecksum(byte[] data) { - MessageDigest sha; - try { - sha = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e){ - throw new RuntimeException(e.getMessage()); - } - sha.update(data); - return sha.digest(); - } - - /** - * Write this picture into OutputStream - */ - public void write(OutputStream out) throws IOException { - byte[] data; - - data = new byte[LittleEndian.SHORT_SIZE]; - LittleEndian.putUShort(data, 0, getSignature()); - out.write(data); - - data = new byte[LittleEndian.SHORT_SIZE]; - LittleEndian.putUShort(data, 0, getType() + 0xF018); - out.write(data); - - byte[] rawdata = getRawData(); - - data = new byte[LittleEndian.INT_SIZE]; - LittleEndian.putInt(data, 0, rawdata.length); - out.write(data); - - out.write(rawdata); - } - - /** - * Create an instance of PictureData by type. - * - * @param type type of the picture data. - * Must be one of the static constants defined in the Picture class. - * @return concrete instance of PictureData - */ - public static PictureData create(int type){ - PictureData pict; - switch (type){ - case Picture.EMF: - pict = new EMF(); - break; - case Picture.WMF: - pict = new WMF(); - break; - case Picture.PICT: - pict = new PICT(); - break; - case Picture.JPEG: - pict = new JPEG(); - break; - case Picture.PNG: - pict = new PNG(); - break; - case Picture.DIB: - pict = new DIB(); - break; - default: - throw new IllegalArgumentException("Unsupported picture type: " + type); - } - return pict; - } - - /** - * Return 24 byte header which preceeds the actual picture data. - *

    - * The header consists of 2-byte signature, 2-byte type, - * 4-byte image size and 16-byte checksum of the image data. - *

    - * - * @return the 24 byte header which preceeds the actual picture data. - */ - public byte[] getHeader() { - byte[] header = new byte[16 + 8]; - LittleEndian.putInt(header, 0, getSignature()); - LittleEndian.putInt(header, 4, getRawData().length); - System.arraycopy(rawdata, 0, header, 8, 16); - return header; - } - - /** - * Return image size in bytes - * - * @return the size of the picture in bytes - * @deprecated Use getData().length instead. - */ - public int getSize(){ - return getData().length; - } - -} +/* ==================================================================== + 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.hslf.usermodel; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.hslf.model.Picture; +import org.apache.poi.hslf.blip.*; + +import java.io.OutputStream; +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * A class that represents image data contained in a slide show. + * + * @author Yegor Kozlov + */ +public abstract class PictureData { + + /** + * Size of the image checksum calculated using MD5 algorithm. + */ + protected static final int CHECKSUM_SIZE = 16; + + /** + * Binary data of the picture + */ + private byte[] rawdata; + /** + * The offset to the picture in the stream + */ + protected int offset; + + /** + * Returns type of this picture. + * Must be one of the static constants defined in the Picture class. + * + * @return type of this picture. + */ + public abstract int getType(); + + /** + * Returns the binary data of this Picture + * @return picture data + */ + public abstract byte[] getData(); + + /** + * Set picture data + */ + public abstract void setData(byte[] data) throws IOException; + + /** + * Blip signature. + */ + protected abstract int getSignature(); + + /** + * Returns the raw binary data of this Picture excluding the first 8 bytes + * which hold image signature and size of the image data. + * + * @return picture data + */ + public byte[] getRawData(){ + return rawdata; + } + + public void setRawData(byte[] data){ + rawdata = data; + } + + /** + * File offset in the 'Pictures' stream + * + * @return offset in the 'Pictures' stream + */ + public int getOffset(){ + return offset; + } + + /** + * Set offset of this picture in the 'Pictures' stream. + * We need to set it when a new picture is created. + * + * @param offset in the 'Pictures' stream + */ + public void setOffset(int offset){ + this.offset = offset; + } + + /** + * Returns 16-byte checksum of this picture + */ + public byte[] getUID(){ + byte[] uid = new byte[16]; + System.arraycopy(rawdata, 0, uid, 0, uid.length); + return uid; + } + + + /** + * Compute 16-byte checksum of this picture using MD5 algorithm. + */ + public static byte[] getChecksum(byte[] data) { + MessageDigest sha; + try { + sha = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e){ + throw new RuntimeException(e.getMessage()); + } + sha.update(data); + return sha.digest(); + } + + /** + * Write this picture into OutputStream + */ + public void write(OutputStream out) throws IOException { + byte[] data; + + data = new byte[LittleEndian.SHORT_SIZE]; + LittleEndian.putUShort(data, 0, getSignature()); + out.write(data); + + data = new byte[LittleEndian.SHORT_SIZE]; + LittleEndian.putUShort(data, 0, getType() + 0xF018); + out.write(data); + + byte[] rawdata = getRawData(); + + data = new byte[LittleEndian.INT_SIZE]; + LittleEndian.putInt(data, 0, rawdata.length); + out.write(data); + + out.write(rawdata); + } + + /** + * Create an instance of PictureData by type. + * + * @param type type of the picture data. + * Must be one of the static constants defined in the Picture class. + * @return concrete instance of PictureData + */ + public static PictureData create(int type){ + PictureData pict; + switch (type){ + case Picture.EMF: + pict = new EMF(); + break; + case Picture.WMF: + pict = new WMF(); + break; + case Picture.PICT: + pict = new PICT(); + break; + case Picture.JPEG: + pict = new JPEG(); + break; + case Picture.PNG: + pict = new PNG(); + break; + case Picture.DIB: + pict = new DIB(); + break; + default: + throw new IllegalArgumentException("Unsupported picture type: " + type); + } + return pict; + } + + /** + * Return 24 byte header which preceeds the actual picture data. + *

    + * The header consists of 2-byte signature, 2-byte type, + * 4-byte image size and 16-byte checksum of the image data. + *

    + * + * @return the 24 byte header which preceeds the actual picture data. + */ + public byte[] getHeader() { + byte[] header = new byte[16 + 8]; + LittleEndian.putInt(header, 0, getSignature()); + LittleEndian.putInt(header, 4, getRawData().length); + System.arraycopy(rawdata, 0, header, 8, 16); + return header; + } + + /** + * Return image size in bytes + * + * @return the size of the picture in bytes + * @deprecated Use getData().length instead. + */ + public int getSize(){ + return getData().length; + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java index 15dc990d50..e26d57a9e9 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java +++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java @@ -1,39 +1,39 @@ -/* - * Created on Nov 25, 2006 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class If implements Function { - - public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { - Eval retval = null; - Eval evalWhenFalse = BoolEval.FALSE; - switch (evals.length) { - case 3: - evalWhenFalse = evals[2]; - case 2: - BoolEval beval = (BoolEval) evals[0]; - if (beval.getBooleanValue()) { - retval = evals[1]; - } - else { - retval = evalWhenFalse; - } - break; - default: - retval = ErrorEval.UNKNOWN_ERROR; - } - return retval; - } - - -} +/* + * Created on Nov 25, 2006 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class If implements Function { + + public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { + Eval retval = null; + Eval evalWhenFalse = BoolEval.FALSE; + switch (evals.length) { + case 3: + evalWhenFalse = evals[2]; + case 2: + BoolEval beval = (BoolEval) evals[0]; + if (beval.getBooleanValue()) { + retval = evals[1]; + } + else { + retval = evalWhenFalse; + } + break; + default: + retval = ErrorEval.UNKNOWN_ERROR; + } + return retval; + } + + +} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java index 57e18888dd..f54fbff5ce 100644 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java +++ b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java @@ -1,31 +1,31 @@ -/* - * Created on Nov 25, 2006 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class LogicalFunction implements Function { - - /** - * recursively evaluate any RefEvals - * @param reval - * @return - */ - protected ValueEval xlateRefEval(RefEval reval) { - ValueEval retval = (ValueEval) reval.getInnerValueEval(); - - if (retval instanceof RefEval) { - RefEval re = (RefEval) retval; - retval = xlateRefEval(re); - } - - return retval; - } -} +/* + * Created on Nov 25, 2006 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class LogicalFunction implements Function { + + /** + * recursively evaluate any RefEvals + * @param reval + * @return + */ + protected ValueEval xlateRefEval(RefEval reval) { + ValueEval retval = (ValueEval) reval.getInnerValueEval(); + + if (retval instanceof RefEval) { + RefEval re = (RefEval) retval; + retval = xlateRefEval(re); + } + + return retval; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java b/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java index 82fbacd6b2..c140429517 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java @@ -1,85 +1,85 @@ -/* ==================================================================== - 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.hwpf.model; - - -/** - * A single entry in the {@link SavedByTable}. - * - * @author Daniel Noll - */ -public class SavedByEntry -{ - private String userName; - private String saveLocation; - - public SavedByEntry(String userName, String saveLocation) - { - this.userName = userName; - this.saveLocation = saveLocation; - } - - public String getUserName() - { - return userName; - } - - public String getSaveLocation() - { - return saveLocation; - } - - /** - * Compares this object with another, for equality. - * - * @param other the object to compare to this one. - * @return true iff the other object is equal to this one. - */ - public boolean equals(Object other) - { - if (other == this) return true; - if (!(other instanceof SavedByEntry)) return false; - SavedByEntry that = (SavedByEntry) other; - return that.userName.equals(userName) && - that.saveLocation.equals(saveLocation); - } - - /** - * Generates a hash code for consistency with {@link #equals(Object)}. - * - * @return the hash code. - */ - public int hashCode() - { - int hash = 29; - hash = hash * 13 + userName.hashCode(); - hash = hash * 13 + saveLocation.hashCode(); - return hash; - } - - /** - * Returns a string for display. - * - * @return the string. - */ - public String toString() - { - return "SavedByEntry[userName=" + getUserName() + - ",saveLocation=" + getSaveLocation() + "]"; - } -} +/* ==================================================================== + 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.hwpf.model; + + +/** + * A single entry in the {@link SavedByTable}. + * + * @author Daniel Noll + */ +public class SavedByEntry +{ + private String userName; + private String saveLocation; + + public SavedByEntry(String userName, String saveLocation) + { + this.userName = userName; + this.saveLocation = saveLocation; + } + + public String getUserName() + { + return userName; + } + + public String getSaveLocation() + { + return saveLocation; + } + + /** + * Compares this object with another, for equality. + * + * @param other the object to compare to this one. + * @return true iff the other object is equal to this one. + */ + public boolean equals(Object other) + { + if (other == this) return true; + if (!(other instanceof SavedByEntry)) return false; + SavedByEntry that = (SavedByEntry) other; + return that.userName.equals(userName) && + that.saveLocation.equals(saveLocation); + } + + /** + * Generates a hash code for consistency with {@link #equals(Object)}. + * + * @return the hash code. + */ + public int hashCode() + { + int hash = 29; + hash = hash * 13 + userName.hashCode(); + hash = hash * 13 + saveLocation.hashCode(); + return hash; + } + + /** + * Returns a string for display. + * + * @return the string. + */ + public String toString() + { + return "SavedByEntry[userName=" + getUserName() + + ",saveLocation=" + getSaveLocation() + "]"; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByTable.java index d24a8ecc83..f5c29433b5 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByTable.java @@ -1,121 +1,121 @@ -/* ==================================================================== - 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.hwpf.model; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.apache.poi.util.LittleEndian; -import org.apache.poi.util.StringUtil; - -import org.apache.poi.hwpf.model.io.HWPFOutputStream; - -/** - * String table containing the history of the last few revisions ("saves") of the document. - * Read-only for the time being. - * - * @author Daniel Noll - */ -public class SavedByTable -{ - /** - * A value that I don't know what it does, but is maintained for accuracy. - */ - private short unknownValue = -1; - - /** - * Array of entries. - */ - private SavedByEntry[] entries; - - /** - * Constructor to read the table from the table stream. - * - * @param tableStream the table stream. - * @param offset the offset into the byte array. - * @param size the size of the table in the byte array. - */ - public SavedByTable(byte[] tableStream, int offset, int size) - { - // Read the value that I don't know what it does. :-) - unknownValue = LittleEndian.getShort(tableStream, offset); - offset += 2; - - // The stored int is the number of strings, and there are two strings per entry. - int numEntries = LittleEndian.getInt(tableStream, offset) / 2; - offset += 4; - - entries = new SavedByEntry[numEntries]; - for (int i = 0; i < numEntries; i++) - { - int len = LittleEndian.getShort(tableStream, offset); - offset += 2; - String userName = StringUtil.getFromUnicodeLE(tableStream, offset, len); - offset += len * 2; - len = LittleEndian.getShort(tableStream, offset); - offset += 2; - String saveLocation = StringUtil.getFromUnicodeLE(tableStream, offset, len); - offset += len * 2; - - entries[i] = new SavedByEntry(userName, saveLocation); - } - } - - /** - * Gets the entries. The returned list cannot be modified. - * - * @return the list of entries. - */ - public List getEntries() - { - return Collections.unmodifiableList(Arrays.asList(entries)); - } - - /** - * Writes this table to the table stream. - * - * @param tableStream the table stream to write to. - * @throws IOException if an error occurs while writing. - */ - public void writeTo(HWPFOutputStream tableStream) - throws IOException - { - byte[] header = new byte[6]; - LittleEndian.putShort(header, 0, unknownValue); - LittleEndian.putInt(header, 2, entries.length * 2); - tableStream.write(header); - - for (int i = 0; i < entries.length; i++) - { - writeStringValue(tableStream, entries[i].getUserName()); - writeStringValue(tableStream, entries[i].getSaveLocation()); - } - } - - private void writeStringValue(HWPFOutputStream tableStream, String value) - throws IOException - { - byte[] buf = new byte[value.length() * 2 + 2]; - LittleEndian.putShort(buf, 0, (short) value.length()); - StringUtil.putUnicodeLE(value, buf, 2); - tableStream.write(buf); - } -} - +/* ==================================================================== + 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.hwpf.model; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.StringUtil; + +import org.apache.poi.hwpf.model.io.HWPFOutputStream; + +/** + * String table containing the history of the last few revisions ("saves") of the document. + * Read-only for the time being. + * + * @author Daniel Noll + */ +public class SavedByTable +{ + /** + * A value that I don't know what it does, but is maintained for accuracy. + */ + private short unknownValue = -1; + + /** + * Array of entries. + */ + private SavedByEntry[] entries; + + /** + * Constructor to read the table from the table stream. + * + * @param tableStream the table stream. + * @param offset the offset into the byte array. + * @param size the size of the table in the byte array. + */ + public SavedByTable(byte[] tableStream, int offset, int size) + { + // Read the value that I don't know what it does. :-) + unknownValue = LittleEndian.getShort(tableStream, offset); + offset += 2; + + // The stored int is the number of strings, and there are two strings per entry. + int numEntries = LittleEndian.getInt(tableStream, offset) / 2; + offset += 4; + + entries = new SavedByEntry[numEntries]; + for (int i = 0; i < numEntries; i++) + { + int len = LittleEndian.getShort(tableStream, offset); + offset += 2; + String userName = StringUtil.getFromUnicodeLE(tableStream, offset, len); + offset += len * 2; + len = LittleEndian.getShort(tableStream, offset); + offset += 2; + String saveLocation = StringUtil.getFromUnicodeLE(tableStream, offset, len); + offset += len * 2; + + entries[i] = new SavedByEntry(userName, saveLocation); + } + } + + /** + * Gets the entries. The returned list cannot be modified. + * + * @return the list of entries. + */ + public List getEntries() + { + return Collections.unmodifiableList(Arrays.asList(entries)); + } + + /** + * Writes this table to the table stream. + * + * @param tableStream the table stream to write to. + * @throws IOException if an error occurs while writing. + */ + public void writeTo(HWPFOutputStream tableStream) + throws IOException + { + byte[] header = new byte[6]; + LittleEndian.putShort(header, 0, unknownValue); + LittleEndian.putInt(header, 2, entries.length * 2); + tableStream.write(header); + + for (int i = 0; i < entries.length; i++) + { + writeStringValue(tableStream, entries[i].getUserName()); + writeStringValue(tableStream, entries[i].getSaveLocation()); + } + } + + private void writeStringValue(HWPFOutputStream tableStream, String value) + throws IOException + { + byte[] buf = new byte[value.length() * 2 + 2]; + LittleEndian.putShort(buf, 0, (short) value.length()); + StringUtil.putUnicodeLE(value, buf, 2); + tableStream.write(buf); + } +} + diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java index 0c36150e96..84eafaa4fd 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestBackground.java @@ -1,182 +1,182 @@ -/* ==================================================================== - 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.hslf.model; - -import junit.framework.TestCase; - -import java.io.*; -import java.awt.*; - -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.HSLFSlideShow; - -/** - * Test Fill object. - * - * @author Yegor Kozlov - */ -public class TestBackground extends TestCase { - - /** - * Default background for slide, shape and slide master. - */ - public void testDefaults() throws Exception { - SlideShow ppt = new SlideShow(); - - assertEquals(Fill.FILL_SOLID, ppt.getSlidesMasters()[0].getBackground().getFill().getFillType()); - - Slide slide = ppt.createSlide(); - assertTrue(slide.getFollowMasterBackground()); - assertEquals(Fill.FILL_SOLID, slide.getBackground().getFill().getFillType()); - - Shape shape = new AutoShape(ShapeTypes.Rectangle); - assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); - } - - /** - * Read fill information from an reference ppt file - */ - public void testReadBackground() throws Exception { - SlideShow ppt = new SlideShow(new HSLFSlideShow(System.getProperty("HSLF.testdata.path") + "/backgrounds.ppt")); - Fill fill; - Shape shape; - - Slide[] slide = ppt.getSlides(); - - fill = slide[0].getBackground().getFill(); - assertEquals(Fill.FILL_PICTURE, fill.getFillType()); - shape = slide[0].getShapes()[0]; - assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); - - fill = slide[1].getBackground().getFill(); - assertEquals(Fill.FILL_PATTERN, fill.getFillType()); - shape = slide[1].getShapes()[0]; - assertEquals(Fill.FILL_BACKGROUND, shape.getFill().getFillType()); - - fill = slide[2].getBackground().getFill(); - assertEquals(Fill.FILL_TEXTURE, fill.getFillType()); - shape = slide[2].getShapes()[0]; - assertEquals(Fill.FILL_PICTURE, shape.getFill().getFillType()); - - fill = slide[3].getBackground().getFill(); - assertEquals(Fill.FILL_SHADE_CENTER, fill.getFillType()); - shape = slide[3].getShapes()[0]; - assertEquals(Fill.FILL_SHADE, shape.getFill().getFillType()); - } - - /** - * Create a ppt with various fill effects - */ - public void testBackgroundPicture() throws Exception { - SlideShow ppt = new SlideShow(); - Slide slide; - Fill fill; - Shape shape; - int idx; - - //slide 1 - slide = ppt.createSlide(); - slide.setFollowMasterBackground(false); - fill = slide.getBackground().getFill(); - idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); - fill.setFillType(Fill.FILL_PICTURE); - fill.setPictureData(idx); - - shape = new AutoShape(ShapeTypes.Rectangle); - shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); - fill = shape.getFill(); - fill.setFillType(Fill.FILL_SOLID); - slide.addShape(shape); - - //slide 2 - slide = ppt.createSlide(); - slide.setFollowMasterBackground(false); - fill = slide.getBackground().getFill(); - idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); - fill.setFillType(Fill.FILL_PATTERN); - fill.setPictureData(idx); - fill.setBackgroundColor(Color.green); - fill.setForegroundColor(Color.red); - - shape = new AutoShape(ShapeTypes.Rectangle); - shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); - fill = shape.getFill(); - fill.setFillType(Fill.FILL_BACKGROUND); - slide.addShape(shape); - - //slide 3 - slide = ppt.createSlide(); - slide.setFollowMasterBackground(false); - fill = slide.getBackground().getFill(); - idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); - fill.setFillType(Fill.FILL_TEXTURE); - fill.setPictureData(idx); - - shape = new AutoShape(ShapeTypes.Rectangle); - shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); - fill = shape.getFill(); - fill.setFillType(Fill.FILL_PICTURE); - idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/clock.jpg"), Picture.JPEG); - fill.setPictureData(idx); - slide.addShape(shape); - - // slide 4 - slide = ppt.createSlide(); - slide.setFollowMasterBackground(false); - fill = slide.getBackground().getFill(); - fill.setFillType(Fill.FILL_SHADE_CENTER); - fill.setBackgroundColor(Color.white); - fill.setForegroundColor(Color.darkGray); - - shape = new AutoShape(ShapeTypes.Rectangle); - shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); - fill = shape.getFill(); - fill.setFillType(Fill.FILL_SHADE); - fill.setBackgroundColor(Color.red); - fill.setForegroundColor(Color.green); - slide.addShape(shape); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - Slide[] slides = ppt.getSlides(); - - fill = slides[0].getBackground().getFill(); - assertEquals(Fill.FILL_PICTURE, fill.getFillType()); - shape = slides[0].getShapes()[0]; - assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); - - fill = slides[1].getBackground().getFill(); - assertEquals(Fill.FILL_PATTERN, fill.getFillType()); - shape = slides[1].getShapes()[0]; - assertEquals(Fill.FILL_BACKGROUND, shape.getFill().getFillType()); - - fill = slides[2].getBackground().getFill(); - assertEquals(Fill.FILL_TEXTURE, fill.getFillType()); - shape = slides[2].getShapes()[0]; - assertEquals(Fill.FILL_PICTURE, shape.getFill().getFillType()); - - fill = slides[3].getBackground().getFill(); - assertEquals(Fill.FILL_SHADE_CENTER, fill.getFillType()); - shape = slides[3].getShapes()[0]; - assertEquals(Fill.FILL_SHADE, shape.getFill().getFillType()); - - } - -} +/* ==================================================================== + 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.hslf.model; + +import junit.framework.TestCase; + +import java.io.*; +import java.awt.*; + +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.HSLFSlideShow; + +/** + * Test Fill object. + * + * @author Yegor Kozlov + */ +public class TestBackground extends TestCase { + + /** + * Default background for slide, shape and slide master. + */ + public void testDefaults() throws Exception { + SlideShow ppt = new SlideShow(); + + assertEquals(Fill.FILL_SOLID, ppt.getSlidesMasters()[0].getBackground().getFill().getFillType()); + + Slide slide = ppt.createSlide(); + assertTrue(slide.getFollowMasterBackground()); + assertEquals(Fill.FILL_SOLID, slide.getBackground().getFill().getFillType()); + + Shape shape = new AutoShape(ShapeTypes.Rectangle); + assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); + } + + /** + * Read fill information from an reference ppt file + */ + public void testReadBackground() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow(System.getProperty("HSLF.testdata.path") + "/backgrounds.ppt")); + Fill fill; + Shape shape; + + Slide[] slide = ppt.getSlides(); + + fill = slide[0].getBackground().getFill(); + assertEquals(Fill.FILL_PICTURE, fill.getFillType()); + shape = slide[0].getShapes()[0]; + assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); + + fill = slide[1].getBackground().getFill(); + assertEquals(Fill.FILL_PATTERN, fill.getFillType()); + shape = slide[1].getShapes()[0]; + assertEquals(Fill.FILL_BACKGROUND, shape.getFill().getFillType()); + + fill = slide[2].getBackground().getFill(); + assertEquals(Fill.FILL_TEXTURE, fill.getFillType()); + shape = slide[2].getShapes()[0]; + assertEquals(Fill.FILL_PICTURE, shape.getFill().getFillType()); + + fill = slide[3].getBackground().getFill(); + assertEquals(Fill.FILL_SHADE_CENTER, fill.getFillType()); + shape = slide[3].getShapes()[0]; + assertEquals(Fill.FILL_SHADE, shape.getFill().getFillType()); + } + + /** + * Create a ppt with various fill effects + */ + public void testBackgroundPicture() throws Exception { + SlideShow ppt = new SlideShow(); + Slide slide; + Fill fill; + Shape shape; + int idx; + + //slide 1 + slide = ppt.createSlide(); + slide.setFollowMasterBackground(false); + fill = slide.getBackground().getFill(); + idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); + fill.setFillType(Fill.FILL_PICTURE); + fill.setPictureData(idx); + + shape = new AutoShape(ShapeTypes.Rectangle); + shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); + fill = shape.getFill(); + fill.setFillType(Fill.FILL_SOLID); + slide.addShape(shape); + + //slide 2 + slide = ppt.createSlide(); + slide.setFollowMasterBackground(false); + fill = slide.getBackground().getFill(); + idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); + fill.setFillType(Fill.FILL_PATTERN); + fill.setPictureData(idx); + fill.setBackgroundColor(Color.green); + fill.setForegroundColor(Color.red); + + shape = new AutoShape(ShapeTypes.Rectangle); + shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); + fill = shape.getFill(); + fill.setFillType(Fill.FILL_BACKGROUND); + slide.addShape(shape); + + //slide 3 + slide = ppt.createSlide(); + slide.setFollowMasterBackground(false); + fill = slide.getBackground().getFill(); + idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/tomcat.png"), Picture.PNG); + fill.setFillType(Fill.FILL_TEXTURE); + fill.setPictureData(idx); + + shape = new AutoShape(ShapeTypes.Rectangle); + shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); + fill = shape.getFill(); + fill.setFillType(Fill.FILL_PICTURE); + idx = ppt.addPicture(new File(System.getProperty("HSLF.testdata.path") + "/clock.jpg"), Picture.JPEG); + fill.setPictureData(idx); + slide.addShape(shape); + + // slide 4 + slide = ppt.createSlide(); + slide.setFollowMasterBackground(false); + fill = slide.getBackground().getFill(); + fill.setFillType(Fill.FILL_SHADE_CENTER); + fill.setBackgroundColor(Color.white); + fill.setForegroundColor(Color.darkGray); + + shape = new AutoShape(ShapeTypes.Rectangle); + shape.setAnchor(new java.awt.Rectangle(100, 100, 200, 200)); + fill = shape.getFill(); + fill.setFillType(Fill.FILL_SHADE); + fill.setBackgroundColor(Color.red); + fill.setForegroundColor(Color.green); + slide.addShape(shape); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + Slide[] slides = ppt.getSlides(); + + fill = slides[0].getBackground().getFill(); + assertEquals(Fill.FILL_PICTURE, fill.getFillType()); + shape = slides[0].getShapes()[0]; + assertEquals(Fill.FILL_SOLID, shape.getFill().getFillType()); + + fill = slides[1].getBackground().getFill(); + assertEquals(Fill.FILL_PATTERN, fill.getFillType()); + shape = slides[1].getShapes()[0]; + assertEquals(Fill.FILL_BACKGROUND, shape.getFill().getFillType()); + + fill = slides[2].getBackground().getFill(); + assertEquals(Fill.FILL_TEXTURE, fill.getFillType()); + shape = slides[2].getShapes()[0]; + assertEquals(Fill.FILL_PICTURE, shape.getFill().getFillType()); + + fill = slides[3].getBackground().getFill(); + assertEquals(Fill.FILL_SHADE_CENTER, fill.getFillType()); + shape = slides[3].getShapes()[0]; + assertEquals(Fill.FILL_SHADE, shape.getFill().getFillType()); + + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java index 2b7d6cc601..c5bb16e4f1 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestPPGraphics2D.java @@ -1,88 +1,88 @@ -/* ==================================================================== - 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.hslf.model; - -import junit.framework.TestCase; -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.HSLFSlideShow; - -import java.awt.*; -import java.awt.Rectangle; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; - -/** - * Test drawing shapes via Graphics2D - * - * @author Yegor Kozlov - */ -public class TestPPGraphics2D extends TestCase { - private SlideShow ppt; - - protected void setUp() throws Exception { - String dirname = System.getProperty("HSLF.testdata.path"); - String filename = dirname + "/empty.ppt"; - ppt = new SlideShow(new HSLFSlideShow(filename)); - } - - public void testGraphics() throws Exception { - // Starts off empty - assertEquals(0, ppt.getSlides().length); - - // Add a slide - Slide slide = ppt.createSlide(); - assertEquals(1, ppt.getSlides().length); - - // Add some stuff into it - ShapeGroup group = new ShapeGroup(); - Dimension pgsize = ppt.getPageSize(); - java.awt.Rectangle bounds = new java.awt.Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight()); - group.setAnchor(bounds); - slide.addShape(group); - - PPGraphics2D graphics = new PPGraphics2D(group); - graphics.setColor(Color.blue); - graphics.draw(new Rectangle(1296, 2544, 1344, 0)); - - graphics.setColor(Color.red); - graphics.setStroke(new BasicStroke((float)2.5)); - graphics.drawLine(500, 500, 1500, 2500); - - graphics.setColor(Color.green); - graphics.setPaint(Color.gray); - graphics.drawOval(4000, 1000, 1000, 1000); - - // Write the file out - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - // And read it back in - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertEquals(1, ppt.getSlides().length); - - slide = ppt.getSlides()[0]; - Shape[] shape = slide.getShapes(); - assertEquals(shape.length, 1); //group shape - - assertTrue(shape[0] instanceof ShapeGroup); //group shape - - group = (ShapeGroup)shape[0]; - shape = group.getShapes(); - assertEquals(shape.length, 7); - } - -} +/* ==================================================================== + 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.hslf.model; + +import junit.framework.TestCase; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.HSLFSlideShow; + +import java.awt.*; +import java.awt.Rectangle; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + +/** + * Test drawing shapes via Graphics2D + * + * @author Yegor Kozlov + */ +public class TestPPGraphics2D extends TestCase { + private SlideShow ppt; + + protected void setUp() throws Exception { + String dirname = System.getProperty("HSLF.testdata.path"); + String filename = dirname + "/empty.ppt"; + ppt = new SlideShow(new HSLFSlideShow(filename)); + } + + public void testGraphics() throws Exception { + // Starts off empty + assertEquals(0, ppt.getSlides().length); + + // Add a slide + Slide slide = ppt.createSlide(); + assertEquals(1, ppt.getSlides().length); + + // Add some stuff into it + ShapeGroup group = new ShapeGroup(); + Dimension pgsize = ppt.getPageSize(); + java.awt.Rectangle bounds = new java.awt.Rectangle(0, 0, (int)pgsize.getWidth(), (int)pgsize.getHeight()); + group.setAnchor(bounds); + slide.addShape(group); + + PPGraphics2D graphics = new PPGraphics2D(group); + graphics.setColor(Color.blue); + graphics.draw(new Rectangle(1296, 2544, 1344, 0)); + + graphics.setColor(Color.red); + graphics.setStroke(new BasicStroke((float)2.5)); + graphics.drawLine(500, 500, 1500, 2500); + + graphics.setColor(Color.green); + graphics.setPaint(Color.gray); + graphics.drawOval(4000, 1000, 1000, 1000); + + // Write the file out + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + // And read it back in + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertEquals(1, ppt.getSlides().length); + + slide = ppt.getSlides()[0]; + Shape[] shape = slide.getShapes(); + assertEquals(shape.length, 1); //group shape + + assertTrue(shape[0] instanceof ShapeGroup); //group shape + + group = (ShapeGroup)shape[0]; + shape = group.getShapes(); + assertEquals(shape.length, 7); + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java index 7e53ebc226..b03ce94bb7 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSetBoldItalic.java @@ -1,83 +1,83 @@ -/* ==================================================================== - 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.hslf.model; - -import junit.framework.TestCase; -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.usermodel.RichTextRun; -import org.apache.poi.hslf.HSLFSlideShow; - -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; - -/** - * Test setting text properties of newly added TextBoxes - * - * @author Yegor Kozlov - */ -public class TestSetBoldItalic extends TestCase { - /** - * Verify that we can add TextBox shapes to a slide - * and set some of the style attributes - */ - public void testTextBoxWrite() throws Exception { - //String dirname = System.getProperty("HSLF.testdata.path"); - //String filename = dirname + "/with_textbox.ppt"; - //new SlideShow(new HSLFSlideShow(filename)); - - SlideShow ppt = new SlideShow(); - Slide sl = ppt.createSlide(); - RichTextRun rt; - - String val = "Hello, World!"; - - // Create a new textbox, and give it lots of properties - TextBox txtbox = new TextBox(); - rt = txtbox.getTextRun().getRichTextRuns()[0]; - txtbox.setText(val); - rt.setFontSize(42); - rt.setBold(true); - rt.setItalic(true); - rt.setUnderlined(false); - sl.addShape(txtbox); - - // Check it before save - rt = txtbox.getTextRun().getRichTextRuns()[0]; - assertEquals(val, rt.getText()); - assertEquals(42, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - - // Serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - sl = ppt.getSlides()[0]; - - txtbox = (TextBox)sl.getShapes()[0]; - rt = txtbox.getTextRun().getRichTextRuns()[0]; - - // Check after save - assertEquals(val, rt.getText()); - assertEquals(42, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - assertFalse(rt.isUnderlined()); - } - -} +/* ==================================================================== + 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.hslf.model; + +import junit.framework.TestCase; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.usermodel.RichTextRun; +import org.apache.poi.hslf.HSLFSlideShow; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + +/** + * Test setting text properties of newly added TextBoxes + * + * @author Yegor Kozlov + */ +public class TestSetBoldItalic extends TestCase { + /** + * Verify that we can add TextBox shapes to a slide + * and set some of the style attributes + */ + public void testTextBoxWrite() throws Exception { + //String dirname = System.getProperty("HSLF.testdata.path"); + //String filename = dirname + "/with_textbox.ppt"; + //new SlideShow(new HSLFSlideShow(filename)); + + SlideShow ppt = new SlideShow(); + Slide sl = ppt.createSlide(); + RichTextRun rt; + + String val = "Hello, World!"; + + // Create a new textbox, and give it lots of properties + TextBox txtbox = new TextBox(); + rt = txtbox.getTextRun().getRichTextRuns()[0]; + txtbox.setText(val); + rt.setFontSize(42); + rt.setBold(true); + rt.setItalic(true); + rt.setUnderlined(false); + sl.addShape(txtbox); + + // Check it before save + rt = txtbox.getTextRun().getRichTextRuns()[0]; + assertEquals(val, rt.getText()); + assertEquals(42, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + + // Serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + sl = ppt.getSlides()[0]; + + txtbox = (TextBox)sl.getShapes()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; + + // Check after save + assertEquals(val, rt.getText()); + assertEquals(42, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + assertFalse(rt.isUnderlined()); + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java index 2c3a6d1899..2e732e04ae 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java @@ -1,226 +1,226 @@ -/* ==================================================================== - 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.hslf.model; - -import junit.framework.TestCase; -import org.apache.poi.hslf.usermodel.SlideShow; -import org.apache.poi.hslf.usermodel.RichTextRun; -import org.apache.poi.hslf.HSLFSlideShow; - -import java.awt.*; -import java.awt.Rectangle; -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; -import java.util.ArrayList; - -/** - * Test drawing shapes via Graphics2D - * - * @author Yegor Kozlov - */ -public class TestShapes extends TestCase { - private SlideShow ppt; - private SlideShow pptB; - - protected void setUp() throws Exception { - String dirname = System.getProperty("HSLF.testdata.path"); - String filename = dirname + "/empty.ppt"; - ppt = new SlideShow(new HSLFSlideShow(filename)); - - String filenameB = dirname + "/empty_textbox.ppt"; - pptB = new SlideShow(new HSLFSlideShow(filenameB)); - } - - public void testGraphics() throws Exception { - Slide slide = ppt.createSlide(); - - Line line = new Line(); - java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60); - line.setAnchor(lineAnchor); - line.setLineWidth(3); - line.setLineStyle(Line.PEN_DASH); - line.setLineColor(Color.red); - slide.addShape(line); - - AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse); - java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111); - ellipse.setAnchor(ellipseAnchor); - ellipse.setLineWidth(2); - ellipse.setLineStyle(Line.PEN_SOLID); - ellipse.setLineColor(Color.green); - ellipse.setFillColor(Color.lightGray); - slide.addShape(ellipse); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - //read ppt from byte array - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertEquals(1, ppt.getSlides().length); - - slide = ppt.getSlides()[0]; - Shape[] shape = slide.getShapes(); - assertEquals(2, shape.length); - - assertTrue(shape[0] instanceof Line); //group shape - assertEquals(lineAnchor, shape[0].getAnchor()); //group shape - - assertTrue(shape[1] instanceof AutoShape); //group shape - assertEquals(ellipseAnchor, shape[1].getAnchor()); //group shape - } - - /** - * Verify that we can read TextBox shapes - * @throws Exception - */ - public void testTextBoxRead() throws Exception { - String dirname = System.getProperty("HSLF.testdata.path"); - String filename = dirname + "/with_textbox.ppt"; - ppt = new SlideShow(new HSLFSlideShow(filename)); - Slide sl = ppt.getSlides()[0]; - Shape[] sh = sl.getShapes(); - for (int i = 0; i < sh.length; i++) { - assertTrue(sh[i] instanceof TextBox); - TextBox txtbox = (TextBox)sh[i]; - String text = txtbox.getText(); - assertNotNull(text); - - assertEquals(txtbox.getTextRun().getRichTextRuns().length, 1); - RichTextRun rt = txtbox.getTextRun().getRichTextRuns()[0]; - - if (text.equals("Hello, World!!!")){ - assertEquals(32, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - } else if (text.equals("I am just a poor boy")){ - assertEquals(44, rt.getFontSize()); - assertTrue(rt.isBold()); - } else if (text.equals("This is Times New Roman")){ - assertEquals(16, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - assertTrue(rt.isUnderlined()); - } else if (text.equals("Plain Text")){ - assertEquals(18, rt.getFontSize()); - } - } - } - - /** - * Verify that we can add TextBox shapes to a slide - * and set some of the style attributes - */ - public void testTextBoxWriteBytes() throws Exception { - ppt = new SlideShow(); - Slide sl = ppt.createSlide(); - RichTextRun rt; - - String val = "Hello, World!"; - - // Create a new textbox, and give it lots of properties - TextBox txtbox = new TextBox(); - rt = txtbox.getTextRun().getRichTextRuns()[0]; - txtbox.setText(val); - rt.setFontName("Arial"); - rt.setFontSize(42); - rt.setBold(true); - rt.setItalic(true); - rt.setUnderlined(false); - rt.setFontColor(Color.red); - sl.addShape(txtbox); - - // Check it before save - rt = txtbox.getTextRun().getRichTextRuns()[0]; - assertEquals(val, rt.getText()); - assertEquals(42, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - assertFalse(rt.isUnderlined()); - assertEquals("Arial", rt.getFontName()); - assertEquals(Color.red, rt.getFontColor()); - - // Serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - txtbox = (TextBox)sl.getShapes()[0]; - rt = txtbox.getTextRun().getRichTextRuns()[0]; - - // Check after save - assertEquals(val, rt.getText()); - assertEquals(42, rt.getFontSize()); - assertTrue(rt.isBold()); - assertTrue(rt.isItalic()); - assertFalse(rt.isUnderlined()); - assertEquals("Arial", rt.getFontName()); - assertEquals(Color.red, rt.getFontColor()); - } - - /** - * Test with an empty text box - */ - public void testEmptyTextBox() throws Exception { - assertEquals(2, pptB.getSlides().length); - Slide s1 = pptB.getSlides()[0]; - Slide s2 = pptB.getSlides()[1]; - - // Check we can get the shapes count - assertEquals(2, s1.getShapes().length); - assertEquals(2, s2.getShapes().length); - } - - /** - * If you iterate over text shapes in a slide and collect them in a set - * it must be the same as returned by Slide.getTextRuns(). - */ - public void testTextBoxSet() throws Exception { - textBoxSet("/with_textbox.ppt"); - textBoxSet("/basic_test_ppt_file.ppt"); - textBoxSet("/next_test_ppt_file.ppt"); - textBoxSet("/Single_Coloured_Page.ppt"); - textBoxSet("/Single_Coloured_Page_With_Fonts_and_Alignments.ppt"); - textBoxSet("/incorrect_slide_order.ppt"); - } - - private void textBoxSet(String filename) throws Exception { - String dirname = System.getProperty("HSLF.testdata.path"); - SlideShow ppt = new SlideShow(new HSLFSlideShow(dirname + filename)); - Slide[] sl = ppt.getSlides(); - for (int k = 0; k < sl.length; k++) { - ArrayList lst1 = new ArrayList(); - TextRun[] txt = sl[k].getTextRuns(); - for (int i = 0; i < txt.length; i++) { - lst1.add(txt[i].getText()); - } - - ArrayList lst2 = new ArrayList(); - Shape[] sh = sl[k].getShapes(); - for (int i = 0; i < sh.length; i++) { - if (sh[i] instanceof TextBox){ - TextBox tbox = (TextBox)sh[i]; - lst2.add(tbox.getText()); - } - } - assertTrue(lst1.containsAll(lst2)); - assertTrue(lst2.containsAll(lst1)); - } - } -} +/* ==================================================================== + 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.hslf.model; + +import junit.framework.TestCase; +import org.apache.poi.hslf.usermodel.SlideShow; +import org.apache.poi.hslf.usermodel.RichTextRun; +import org.apache.poi.hslf.HSLFSlideShow; + +import java.awt.*; +import java.awt.Rectangle; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; + +/** + * Test drawing shapes via Graphics2D + * + * @author Yegor Kozlov + */ +public class TestShapes extends TestCase { + private SlideShow ppt; + private SlideShow pptB; + + protected void setUp() throws Exception { + String dirname = System.getProperty("HSLF.testdata.path"); + String filename = dirname + "/empty.ppt"; + ppt = new SlideShow(new HSLFSlideShow(filename)); + + String filenameB = dirname + "/empty_textbox.ppt"; + pptB = new SlideShow(new HSLFSlideShow(filenameB)); + } + + public void testGraphics() throws Exception { + Slide slide = ppt.createSlide(); + + Line line = new Line(); + java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60); + line.setAnchor(lineAnchor); + line.setLineWidth(3); + line.setLineStyle(Line.PEN_DASH); + line.setLineColor(Color.red); + slide.addShape(line); + + AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse); + java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111); + ellipse.setAnchor(ellipseAnchor); + ellipse.setLineWidth(2); + ellipse.setLineStyle(Line.PEN_SOLID); + ellipse.setLineColor(Color.green); + ellipse.setFillColor(Color.lightGray); + slide.addShape(ellipse); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + //read ppt from byte array + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertEquals(1, ppt.getSlides().length); + + slide = ppt.getSlides()[0]; + Shape[] shape = slide.getShapes(); + assertEquals(2, shape.length); + + assertTrue(shape[0] instanceof Line); //group shape + assertEquals(lineAnchor, shape[0].getAnchor()); //group shape + + assertTrue(shape[1] instanceof AutoShape); //group shape + assertEquals(ellipseAnchor, shape[1].getAnchor()); //group shape + } + + /** + * Verify that we can read TextBox shapes + * @throws Exception + */ + public void testTextBoxRead() throws Exception { + String dirname = System.getProperty("HSLF.testdata.path"); + String filename = dirname + "/with_textbox.ppt"; + ppt = new SlideShow(new HSLFSlideShow(filename)); + Slide sl = ppt.getSlides()[0]; + Shape[] sh = sl.getShapes(); + for (int i = 0; i < sh.length; i++) { + assertTrue(sh[i] instanceof TextBox); + TextBox txtbox = (TextBox)sh[i]; + String text = txtbox.getText(); + assertNotNull(text); + + assertEquals(txtbox.getTextRun().getRichTextRuns().length, 1); + RichTextRun rt = txtbox.getTextRun().getRichTextRuns()[0]; + + if (text.equals("Hello, World!!!")){ + assertEquals(32, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + } else if (text.equals("I am just a poor boy")){ + assertEquals(44, rt.getFontSize()); + assertTrue(rt.isBold()); + } else if (text.equals("This is Times New Roman")){ + assertEquals(16, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + assertTrue(rt.isUnderlined()); + } else if (text.equals("Plain Text")){ + assertEquals(18, rt.getFontSize()); + } + } + } + + /** + * Verify that we can add TextBox shapes to a slide + * and set some of the style attributes + */ + public void testTextBoxWriteBytes() throws Exception { + ppt = new SlideShow(); + Slide sl = ppt.createSlide(); + RichTextRun rt; + + String val = "Hello, World!"; + + // Create a new textbox, and give it lots of properties + TextBox txtbox = new TextBox(); + rt = txtbox.getTextRun().getRichTextRuns()[0]; + txtbox.setText(val); + rt.setFontName("Arial"); + rt.setFontSize(42); + rt.setBold(true); + rt.setItalic(true); + rt.setUnderlined(false); + rt.setFontColor(Color.red); + sl.addShape(txtbox); + + // Check it before save + rt = txtbox.getTextRun().getRichTextRuns()[0]; + assertEquals(val, rt.getText()); + assertEquals(42, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + assertFalse(rt.isUnderlined()); + assertEquals("Arial", rt.getFontName()); + assertEquals(Color.red, rt.getFontColor()); + + // Serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + txtbox = (TextBox)sl.getShapes()[0]; + rt = txtbox.getTextRun().getRichTextRuns()[0]; + + // Check after save + assertEquals(val, rt.getText()); + assertEquals(42, rt.getFontSize()); + assertTrue(rt.isBold()); + assertTrue(rt.isItalic()); + assertFalse(rt.isUnderlined()); + assertEquals("Arial", rt.getFontName()); + assertEquals(Color.red, rt.getFontColor()); + } + + /** + * Test with an empty text box + */ + public void testEmptyTextBox() throws Exception { + assertEquals(2, pptB.getSlides().length); + Slide s1 = pptB.getSlides()[0]; + Slide s2 = pptB.getSlides()[1]; + + // Check we can get the shapes count + assertEquals(2, s1.getShapes().length); + assertEquals(2, s2.getShapes().length); + } + + /** + * If you iterate over text shapes in a slide and collect them in a set + * it must be the same as returned by Slide.getTextRuns(). + */ + public void testTextBoxSet() throws Exception { + textBoxSet("/with_textbox.ppt"); + textBoxSet("/basic_test_ppt_file.ppt"); + textBoxSet("/next_test_ppt_file.ppt"); + textBoxSet("/Single_Coloured_Page.ppt"); + textBoxSet("/Single_Coloured_Page_With_Fonts_and_Alignments.ppt"); + textBoxSet("/incorrect_slide_order.ppt"); + } + + private void textBoxSet(String filename) throws Exception { + String dirname = System.getProperty("HSLF.testdata.path"); + SlideShow ppt = new SlideShow(new HSLFSlideShow(dirname + filename)); + Slide[] sl = ppt.getSlides(); + for (int k = 0; k < sl.length; k++) { + ArrayList lst1 = new ArrayList(); + TextRun[] txt = sl[k].getTextRuns(); + for (int i = 0; i < txt.length; i++) { + lst1.add(txt[i].getText()); + } + + ArrayList lst2 = new ArrayList(); + Shape[] sh = sl[k].getShapes(); + for (int i = 0; i < sh.length; i++) { + if (sh[i] instanceof TextBox){ + TextBox tbox = (TextBox)sh[i]; + lst2.add(tbox.getText()); + } + } + assertTrue(lst1.containsAll(lst2)); + assertTrue(lst2.containsAll(lst1)); + } + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlides.java b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlides.java index ded6519b1b..c20f983d56 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlides.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/model/TestSlides.java @@ -1,183 +1,183 @@ -/* ==================================================================== - 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.hslf.model; - -import junit.framework.TestCase; -import org.apache.poi.hslf.HSLFSlideShow; -import org.apache.poi.hslf.usermodel.SlideShow; - -import java.io.ByteArrayOutputStream; -import java.io.ByteArrayInputStream; - -/** - * Test adding new slides to a ppt. - * - * Note - uses the same empty PPT file as the core "new Slideshow" - * stuff does - * @author Yegor Kozlov - */ -public class TestSlides extends TestCase { - - /** - * Add 1 slide to an empty ppt. - * @throws Exception - */ - public void testAddSlides1() throws Exception { - SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); - assertTrue(ppt.getSlides().length == 0); - - Slide s1 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 1); - assertEquals(3, s1._getSheetRefId()); - assertEquals(256, s1._getSheetNumber()); - assertEquals(1, s1.getSlideNumber()); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertTrue(ppt.getSlides().length == 1); - } - - /** - * Add 2 slides to an empty ppt - * @throws Exception - */ - public void testAddSlides2() throws Exception { - SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); - assertTrue(ppt.getSlides().length == 0); - - Slide s1 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 1); - assertEquals(3, s1._getSheetRefId()); - assertEquals(256, s1._getSheetNumber()); - assertEquals(1, s1.getSlideNumber()); - - Slide s2 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 2); - assertEquals(4, s2._getSheetRefId()); - assertEquals(257, s2._getSheetNumber()); - assertEquals(2, s2.getSlideNumber()); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertTrue(ppt.getSlides().length == 2); - } - - /** - * Add 3 slides to an empty ppt - * @throws Exception - */ - public void testAddSlides3() throws Exception { - SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); - assertTrue(ppt.getSlides().length == 0); - - Slide s1 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 1); - assertEquals(3, s1._getSheetRefId()); - assertEquals(256, s1._getSheetNumber()); - assertEquals(1, s1.getSlideNumber()); - - Slide s2 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 2); - assertEquals(4, s2._getSheetRefId()); - assertEquals(257, s2._getSheetNumber()); - assertEquals(2, s2.getSlideNumber()); - - Slide s3 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 3); - assertEquals(5, s3._getSheetRefId()); - assertEquals(258, s3._getSheetNumber()); - assertEquals(3, s3.getSlideNumber()); - - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertTrue(ppt.getSlides().length == 3); - - // Check IDs are still right - s1 = ppt.getSlides()[0]; - assertEquals(256, s1._getSheetNumber()); - assertEquals(3, s1._getSheetRefId()); - s2 = ppt.getSlides()[1]; - assertEquals(257, s2._getSheetNumber()); - assertEquals(4, s2._getSheetRefId()); - s3 = ppt.getSlides()[2];; - assertTrue(ppt.getSlides().length == 3); - assertEquals(258, s3._getSheetNumber()); - assertEquals(5, s3._getSheetRefId()); - } - - /** - * Add slides to ppt which already has two slides - */ - public void testAddSlides2to3() throws Exception { - String dirname = System.getProperty("HSLF.testdata.path"); - SlideShow ppt = new SlideShow(new HSLFSlideShow(dirname + "/basic_test_ppt_file.ppt")); - - assertTrue(ppt.getSlides().length == 2); - - // First slide is 256 / 4 - Slide s1 = ppt.getSlides()[0]; - assertEquals(256, s1._getSheetNumber()); - assertEquals(4, s1._getSheetRefId()); - - // Last slide is 257 / 6 - Slide s2 = ppt.getSlides()[1]; - assertEquals(257, s2._getSheetNumber()); - assertEquals(6, s2._getSheetRefId()); - - // Add another slide, goes in at the end - Slide s3 = ppt.createSlide(); - assertTrue(ppt.getSlides().length == 3); - assertEquals(258, s3._getSheetNumber()); - assertEquals(8, s3._getSheetRefId()); - - - // Serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - assertTrue(ppt.getSlides().length == 3); - - - // Check IDs are still right - s1 = ppt.getSlides()[0]; - assertEquals(256, s1._getSheetNumber()); - assertEquals(4, s1._getSheetRefId()); - s2 = ppt.getSlides()[1]; - assertEquals(257, s2._getSheetNumber()); - assertEquals(6, s2._getSheetRefId()); - s3 = ppt.getSlides()[2];; - assertTrue(ppt.getSlides().length == 3); - assertEquals(258, s3._getSheetNumber()); - assertEquals(8, s3._getSheetRefId()); - } - -} +/* ==================================================================== + 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.hslf.model; + +import junit.framework.TestCase; +import org.apache.poi.hslf.HSLFSlideShow; +import org.apache.poi.hslf.usermodel.SlideShow; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + +/** + * Test adding new slides to a ppt. + * + * Note - uses the same empty PPT file as the core "new Slideshow" + * stuff does + * @author Yegor Kozlov + */ +public class TestSlides extends TestCase { + + /** + * Add 1 slide to an empty ppt. + * @throws Exception + */ + public void testAddSlides1() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); + assertTrue(ppt.getSlides().length == 0); + + Slide s1 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 1); + assertEquals(3, s1._getSheetRefId()); + assertEquals(256, s1._getSheetNumber()); + assertEquals(1, s1.getSlideNumber()); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertTrue(ppt.getSlides().length == 1); + } + + /** + * Add 2 slides to an empty ppt + * @throws Exception + */ + public void testAddSlides2() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); + assertTrue(ppt.getSlides().length == 0); + + Slide s1 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 1); + assertEquals(3, s1._getSheetRefId()); + assertEquals(256, s1._getSheetNumber()); + assertEquals(1, s1.getSlideNumber()); + + Slide s2 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 2); + assertEquals(4, s2._getSheetRefId()); + assertEquals(257, s2._getSheetNumber()); + assertEquals(2, s2.getSlideNumber()); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertTrue(ppt.getSlides().length == 2); + } + + /** + * Add 3 slides to an empty ppt + * @throws Exception + */ + public void testAddSlides3() throws Exception { + SlideShow ppt = new SlideShow(new HSLFSlideShow( TestSlides.class.getResourceAsStream("/org/apache/poi/hslf/data/empty.ppt") )); + assertTrue(ppt.getSlides().length == 0); + + Slide s1 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 1); + assertEquals(3, s1._getSheetRefId()); + assertEquals(256, s1._getSheetNumber()); + assertEquals(1, s1.getSlideNumber()); + + Slide s2 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 2); + assertEquals(4, s2._getSheetRefId()); + assertEquals(257, s2._getSheetNumber()); + assertEquals(2, s2.getSlideNumber()); + + Slide s3 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 3); + assertEquals(5, s3._getSheetRefId()); + assertEquals(258, s3._getSheetNumber()); + assertEquals(3, s3.getSlideNumber()); + + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertTrue(ppt.getSlides().length == 3); + + // Check IDs are still right + s1 = ppt.getSlides()[0]; + assertEquals(256, s1._getSheetNumber()); + assertEquals(3, s1._getSheetRefId()); + s2 = ppt.getSlides()[1]; + assertEquals(257, s2._getSheetNumber()); + assertEquals(4, s2._getSheetRefId()); + s3 = ppt.getSlides()[2];; + assertTrue(ppt.getSlides().length == 3); + assertEquals(258, s3._getSheetNumber()); + assertEquals(5, s3._getSheetRefId()); + } + + /** + * Add slides to ppt which already has two slides + */ + public void testAddSlides2to3() throws Exception { + String dirname = System.getProperty("HSLF.testdata.path"); + SlideShow ppt = new SlideShow(new HSLFSlideShow(dirname + "/basic_test_ppt_file.ppt")); + + assertTrue(ppt.getSlides().length == 2); + + // First slide is 256 / 4 + Slide s1 = ppt.getSlides()[0]; + assertEquals(256, s1._getSheetNumber()); + assertEquals(4, s1._getSheetRefId()); + + // Last slide is 257 / 6 + Slide s2 = ppt.getSlides()[1]; + assertEquals(257, s2._getSheetNumber()); + assertEquals(6, s2._getSheetRefId()); + + // Add another slide, goes in at the end + Slide s3 = ppt.createSlide(); + assertTrue(ppt.getSlides().length == 3); + assertEquals(258, s3._getSheetNumber()); + assertEquals(8, s3._getSheetRefId()); + + + // Serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + assertTrue(ppt.getSlides().length == 3); + + + // Check IDs are still right + s1 = ppt.getSlides()[0]; + assertEquals(256, s1._getSheetNumber()); + assertEquals(4, s1._getSheetRefId()); + s2 = ppt.getSlides()[1]; + assertEquals(257, s2._getSheetNumber()); + assertEquals(6, s2._getSheetRefId()); + s3 = ppt.getSlides()[2];; + assertTrue(ppt.getSlides().length == 3); + assertEquals(258, s3._getSheetNumber()); + assertEquals(8, s3._getSheetRefId()); + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java index d61245e231..298d34165d 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java @@ -1,394 +1,394 @@ -/* ==================================================================== - 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.hslf.usermodel; - -import org.apache.poi.hslf.*; -import org.apache.poi.hslf.blip.*; -import org.apache.poi.hslf.model.*; -import junit.framework.TestCase; - -import java.io.*; -import java.util.Arrays; - -/** - * Test adding/reading pictures - * - * @author Yegor Kozlov - */ -public class TestPictures extends TestCase{ - - protected File cwd; - - public void setUp() throws Exception { - cwd = new File(System.getProperty("HSLF.testdata.path")); - } - - /** - * Test read/write Macintosh PICT - */ - public void testPICT() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "cow.pict"); - int idx = ppt.addPicture(img, Picture.PICT); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can read this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.PICT, pictures[0].getType()); - assertTrue(pictures[0] instanceof PICT); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertEquals(src_bytes.length, ppt_bytes.length); - //in PICT the first 512 bytes are MAC specific and may not be preserved, ignore them - byte[] b1 = new byte[src_bytes.length-512]; - System.arraycopy(src_bytes, 512, b1, 0, b1.length); - byte[] b2 = new byte[ppt_bytes.length-512]; - System.arraycopy(ppt_bytes, 512, b2, 0, b2.length); - assertTrue(Arrays.equals(b1, b2)); - } - - /** - * Test read/write WMF - */ - public void testWMF() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "santa.wmf"); - int idx = ppt.addPicture(img, Picture.WMF); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can read this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.WMF, pictures[0].getType()); - assertTrue(pictures[0] instanceof WMF); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertEquals(src_bytes.length, ppt_bytes.length); - //in WMF the first 22 bytes - is a metafile header - byte[] b1 = new byte[src_bytes.length-22]; - System.arraycopy(src_bytes, 22, b1, 0, b1.length); - byte[] b2 = new byte[ppt_bytes.length-22]; - System.arraycopy(ppt_bytes, 22, b2, 0, b2.length); - assertTrue(Arrays.equals(b1, b2)); - } - - /** - * Test read/write EMF - */ - public void testEMF() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "wrench.emf"); - int idx = ppt.addPicture(img, Picture.EMF); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can get this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.EMF, pictures[0].getType()); - assertTrue(pictures[0] instanceof EMF); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - } - - /** - * Test read/write PNG - */ - public void testPNG() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "tomcat.png"); - int idx = ppt.addPicture(img, Picture.PNG); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can read this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.PNG, pictures[0].getType()); - assertTrue(pictures[0] instanceof PNG); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - } - - /** - * Test read/write JPEG - */ - public void testJPEG() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "clock.jpg"); - int idx = ppt.addPicture(img, Picture.JPEG); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can read this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.JPEG, pictures[0].getType()); - assertTrue(pictures[0] instanceof JPEG); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - } - - /** - * Test read/write DIB - */ - public void testDIB() throws Exception { - SlideShow ppt = new SlideShow(); - - Slide slide = ppt.createSlide(); - File img = new File(cwd, "sci_cec.dib"); - - // Check we can read the test DIB image - assertTrue(img.exists()); - - // Add the image - int idx = ppt.addPicture(img, Picture.DIB); - Picture pict = new Picture(idx); - assertEquals(idx, pict.getPictureIndex()); - slide.addShape(pict); - - //serialize and read again - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ppt.write(out); - out.close(); - - ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); - - //make sure we can read this picture shape and it refers to the correct picture data - Shape[] sh = ppt.getSlides()[0].getShapes(); - assertEquals(1, sh.length); - pict = (Picture)sh[0]; - assertEquals(idx, pict.getPictureIndex()); - - //check picture data - PictureData[] pictures = ppt.getPictureData(); - //the Picture shape refers to the PictureData object in the Presentation - assertEquals(pict.getPictureData(), pictures[0]); - - assertEquals(1, pictures.length); - assertEquals(Picture.DIB, pictures[0].getType()); - assertTrue(pictures[0] instanceof DIB); - //compare the content of the initial file with what is stored in the PictureData - byte[] src_bytes = read(img); - byte[] ppt_bytes = pictures[0].getData(); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - } - - /** - * Read file into a byte array - */ - protected byte[] read(File f) throws IOException { - byte[] bytes = new byte[(int)f.length()]; - FileInputStream is = new FileInputStream(f); - is.read(bytes); - is.close(); - return bytes; - } - - /** - * Read pictures in different formats from a reference slide show - */ - public void testReadPictures() throws Exception { - - byte[] src_bytes, ppt_bytes, b1, b2; - Picture pict; - PictureData pdata; - - SlideShow ppt = new SlideShow(new HSLFSlideShow(new File(cwd, "pictures.ppt").getPath())); - Slide[] slides = ppt.getSlides(); - PictureData[] pictures = ppt.getPictureData(); - assertEquals(5, pictures.length); - - pict = (Picture)slides[0].getShapes()[0]; //the first slide contains JPEG - pdata = pict.getPictureData(); - assertTrue(pdata instanceof JPEG); - assertEquals(Picture.JPEG, pdata.getType()); - src_bytes = pdata.getData(); - ppt_bytes = read(new File(cwd, "clock.jpg")); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - - pict = (Picture)slides[1].getShapes()[0]; //the second slide contains PNG - pdata = pict.getPictureData(); - assertTrue(pdata instanceof PNG); - assertEquals(Picture.PNG, pdata.getType()); - src_bytes = pdata.getData(); - ppt_bytes = read(new File(cwd, "tomcat.png")); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - - pict = (Picture)slides[2].getShapes()[0]; //the third slide contains WMF - pdata = pict.getPictureData(); - assertTrue(pdata instanceof WMF); - assertEquals(Picture.WMF, pdata.getType()); - src_bytes = pdata.getData(); - ppt_bytes = read(new File(cwd, "santa.wmf")); - assertEquals(src_bytes.length, ppt_bytes.length); - //ignore the first 22 bytes - it is a WMF metafile header - b1 = new byte[src_bytes.length-22]; - System.arraycopy(src_bytes, 22, b1, 0, b1.length); - b2 = new byte[ppt_bytes.length-22]; - System.arraycopy(ppt_bytes, 22, b2, 0, b2.length); - assertTrue(Arrays.equals(b1, b2)); - - pict = (Picture)slides[3].getShapes()[0]; //the forth slide contains PICT - pdata = pict.getPictureData(); - assertTrue(pdata instanceof PICT); - assertEquals(Picture.PICT, pdata.getType()); - src_bytes = pdata.getData(); - ppt_bytes = read(new File(cwd, "cow.pict")); - assertEquals(src_bytes.length, ppt_bytes.length); - //ignore the first 512 bytes - it is a MAC specific crap - b1 = new byte[src_bytes.length-512]; - System.arraycopy(src_bytes, 512, b1, 0, b1.length); - b2 = new byte[ppt_bytes.length-512]; - System.arraycopy(ppt_bytes, 512, b2, 0, b2.length); - assertTrue(Arrays.equals(b1, b2)); - - pict = (Picture)slides[4].getShapes()[0]; //the fifth slide contains EMF - pdata = pict.getPictureData(); - assertTrue(pdata instanceof EMF); - assertEquals(Picture.EMF, pdata.getType()); - src_bytes = pdata.getData(); - ppt_bytes = read(new File(cwd, "wrench.emf")); - assertTrue(Arrays.equals(src_bytes, ppt_bytes)); - - } - - /** - * Test that on a party corrupt powerpoint document, which has - * crazy pictures of type 0, we do our best. - */ - public void testZeroPictureType() throws Exception { - HSLFSlideShow hslf = new HSLFSlideShow(new File(cwd, "PictureTypeZero.ppt").getPath()); - - // Should still have 2 real pictures - assertEquals(2, hslf.getPictures().length); - // Both are real pictures, both WMF - assertEquals(Picture.WMF, hslf.getPictures()[0].getType()); - assertEquals(Picture.WMF, hslf.getPictures()[1].getType()); - - // TODO: DISABLED: Pending bug #41176 - - // Now test what happens when we use the SlideShow interface - //SlideShow ppt = new SlideShow(hslf); - } -} +/* ==================================================================== + 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.hslf.usermodel; + +import org.apache.poi.hslf.*; +import org.apache.poi.hslf.blip.*; +import org.apache.poi.hslf.model.*; +import junit.framework.TestCase; + +import java.io.*; +import java.util.Arrays; + +/** + * Test adding/reading pictures + * + * @author Yegor Kozlov + */ +public class TestPictures extends TestCase{ + + protected File cwd; + + public void setUp() throws Exception { + cwd = new File(System.getProperty("HSLF.testdata.path")); + } + + /** + * Test read/write Macintosh PICT + */ + public void testPICT() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "cow.pict"); + int idx = ppt.addPicture(img, Picture.PICT); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can read this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.PICT, pictures[0].getType()); + assertTrue(pictures[0] instanceof PICT); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertEquals(src_bytes.length, ppt_bytes.length); + //in PICT the first 512 bytes are MAC specific and may not be preserved, ignore them + byte[] b1 = new byte[src_bytes.length-512]; + System.arraycopy(src_bytes, 512, b1, 0, b1.length); + byte[] b2 = new byte[ppt_bytes.length-512]; + System.arraycopy(ppt_bytes, 512, b2, 0, b2.length); + assertTrue(Arrays.equals(b1, b2)); + } + + /** + * Test read/write WMF + */ + public void testWMF() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "santa.wmf"); + int idx = ppt.addPicture(img, Picture.WMF); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can read this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.WMF, pictures[0].getType()); + assertTrue(pictures[0] instanceof WMF); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertEquals(src_bytes.length, ppt_bytes.length); + //in WMF the first 22 bytes - is a metafile header + byte[] b1 = new byte[src_bytes.length-22]; + System.arraycopy(src_bytes, 22, b1, 0, b1.length); + byte[] b2 = new byte[ppt_bytes.length-22]; + System.arraycopy(ppt_bytes, 22, b2, 0, b2.length); + assertTrue(Arrays.equals(b1, b2)); + } + + /** + * Test read/write EMF + */ + public void testEMF() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "wrench.emf"); + int idx = ppt.addPicture(img, Picture.EMF); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can get this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.EMF, pictures[0].getType()); + assertTrue(pictures[0] instanceof EMF); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + } + + /** + * Test read/write PNG + */ + public void testPNG() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "tomcat.png"); + int idx = ppt.addPicture(img, Picture.PNG); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can read this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.PNG, pictures[0].getType()); + assertTrue(pictures[0] instanceof PNG); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + } + + /** + * Test read/write JPEG + */ + public void testJPEG() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "clock.jpg"); + int idx = ppt.addPicture(img, Picture.JPEG); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can read this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.JPEG, pictures[0].getType()); + assertTrue(pictures[0] instanceof JPEG); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + } + + /** + * Test read/write DIB + */ + public void testDIB() throws Exception { + SlideShow ppt = new SlideShow(); + + Slide slide = ppt.createSlide(); + File img = new File(cwd, "sci_cec.dib"); + + // Check we can read the test DIB image + assertTrue(img.exists()); + + // Add the image + int idx = ppt.addPicture(img, Picture.DIB); + Picture pict = new Picture(idx); + assertEquals(idx, pict.getPictureIndex()); + slide.addShape(pict); + + //serialize and read again + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ppt.write(out); + out.close(); + + ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray()))); + + //make sure we can read this picture shape and it refers to the correct picture data + Shape[] sh = ppt.getSlides()[0].getShapes(); + assertEquals(1, sh.length); + pict = (Picture)sh[0]; + assertEquals(idx, pict.getPictureIndex()); + + //check picture data + PictureData[] pictures = ppt.getPictureData(); + //the Picture shape refers to the PictureData object in the Presentation + assertEquals(pict.getPictureData(), pictures[0]); + + assertEquals(1, pictures.length); + assertEquals(Picture.DIB, pictures[0].getType()); + assertTrue(pictures[0] instanceof DIB); + //compare the content of the initial file with what is stored in the PictureData + byte[] src_bytes = read(img); + byte[] ppt_bytes = pictures[0].getData(); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + } + + /** + * Read file into a byte array + */ + protected byte[] read(File f) throws IOException { + byte[] bytes = new byte[(int)f.length()]; + FileInputStream is = new FileInputStream(f); + is.read(bytes); + is.close(); + return bytes; + } + + /** + * Read pictures in different formats from a reference slide show + */ + public void testReadPictures() throws Exception { + + byte[] src_bytes, ppt_bytes, b1, b2; + Picture pict; + PictureData pdata; + + SlideShow ppt = new SlideShow(new HSLFSlideShow(new File(cwd, "pictures.ppt").getPath())); + Slide[] slides = ppt.getSlides(); + PictureData[] pictures = ppt.getPictureData(); + assertEquals(5, pictures.length); + + pict = (Picture)slides[0].getShapes()[0]; //the first slide contains JPEG + pdata = pict.getPictureData(); + assertTrue(pdata instanceof JPEG); + assertEquals(Picture.JPEG, pdata.getType()); + src_bytes = pdata.getData(); + ppt_bytes = read(new File(cwd, "clock.jpg")); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + + pict = (Picture)slides[1].getShapes()[0]; //the second slide contains PNG + pdata = pict.getPictureData(); + assertTrue(pdata instanceof PNG); + assertEquals(Picture.PNG, pdata.getType()); + src_bytes = pdata.getData(); + ppt_bytes = read(new File(cwd, "tomcat.png")); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + + pict = (Picture)slides[2].getShapes()[0]; //the third slide contains WMF + pdata = pict.getPictureData(); + assertTrue(pdata instanceof WMF); + assertEquals(Picture.WMF, pdata.getType()); + src_bytes = pdata.getData(); + ppt_bytes = read(new File(cwd, "santa.wmf")); + assertEquals(src_bytes.length, ppt_bytes.length); + //ignore the first 22 bytes - it is a WMF metafile header + b1 = new byte[src_bytes.length-22]; + System.arraycopy(src_bytes, 22, b1, 0, b1.length); + b2 = new byte[ppt_bytes.length-22]; + System.arraycopy(ppt_bytes, 22, b2, 0, b2.length); + assertTrue(Arrays.equals(b1, b2)); + + pict = (Picture)slides[3].getShapes()[0]; //the forth slide contains PICT + pdata = pict.getPictureData(); + assertTrue(pdata instanceof PICT); + assertEquals(Picture.PICT, pdata.getType()); + src_bytes = pdata.getData(); + ppt_bytes = read(new File(cwd, "cow.pict")); + assertEquals(src_bytes.length, ppt_bytes.length); + //ignore the first 512 bytes - it is a MAC specific crap + b1 = new byte[src_bytes.length-512]; + System.arraycopy(src_bytes, 512, b1, 0, b1.length); + b2 = new byte[ppt_bytes.length-512]; + System.arraycopy(ppt_bytes, 512, b2, 0, b2.length); + assertTrue(Arrays.equals(b1, b2)); + + pict = (Picture)slides[4].getShapes()[0]; //the fifth slide contains EMF + pdata = pict.getPictureData(); + assertTrue(pdata instanceof EMF); + assertEquals(Picture.EMF, pdata.getType()); + src_bytes = pdata.getData(); + ppt_bytes = read(new File(cwd, "wrench.emf")); + assertTrue(Arrays.equals(src_bytes, ppt_bytes)); + + } + + /** + * Test that on a party corrupt powerpoint document, which has + * crazy pictures of type 0, we do our best. + */ + public void testZeroPictureType() throws Exception { + HSLFSlideShow hslf = new HSLFSlideShow(new File(cwd, "PictureTypeZero.ppt").getPath()); + + // Should still have 2 real pictures + assertEquals(2, hslf.getPictures().length); + // Both are real pictures, both WMF + assertEquals(Picture.WMF, hslf.getPictures()[0].getType()); + assertEquals(Picture.WMF, hslf.getPictures()[1].getType()); + + // TODO: DISABLED: Pending bug #41176 + + // Now test what happens when we use the SlideShow interface + //SlideShow ppt = new SlideShow(hslf); + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSavedByTable.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSavedByTable.java index bc0a6c0bee..2db5fc5c24 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSavedByTable.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestSavedByTable.java @@ -1,91 +1,91 @@ - -/* ==================================================================== - 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.hwpf.model; - -import java.io.*; -import java.util.*; -import junit.framework.*; - -import org.apache.poi.hwpf.*; -import org.apache.poi.hwpf.model.*; -import org.apache.poi.util.*; - -/** - * Unit test for {@link SavedByTable} and {@link SavedByEntry}. - * - * @author Daniel Noll - */ -public class TestSavedByTable - extends TestCase -{ - /** Data dir */ - private File testFile = new File(new File(System.getProperty("HWPF.testdata.path")), "saved-by-table.doc"); - - /** The expected entries in the test document. */ - private List expected = Arrays.asList(new Object[] { - new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), - new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), - new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), - new SavedByEntry("JPratt", "C:\\TEMP\\Iraq - security.doc"), - new SavedByEntry("JPratt", "A:\\Iraq - security.doc"), - new SavedByEntry("ablackshaw", "C:\\ABlackshaw\\Iraq - security.doc"), - new SavedByEntry("ablackshaw", "C:\\ABlackshaw\\A;Iraq - security.doc"), - new SavedByEntry("ablackshaw", "A:\\Iraq - security.doc"), - new SavedByEntry("MKhan", "C:\\TEMP\\Iraq - security.doc"), - new SavedByEntry("MKhan", "C:\\WINNT\\Profiles\\mkhan\\Desktop\\Iraq.doc") - }); - - /** - * Tests reading in the entries, comparing them against the expected entries. - * Then tests writing the document out and reading the entries yet again. - * - * @throws Exception if an unexpected error occurs. - */ - public void testReadWrite() - throws Exception - { - // This document is widely available on the internet as "blair.doc". - // I tried stripping the content and saving the document but my version - // of Word (from Office XP) strips this table out. - InputStream stream = new BufferedInputStream(new FileInputStream(testFile)); - HWPFDocument doc; - try - { - doc = new HWPFDocument(stream); - } - finally - { - stream.close(); - } - - // Check what we just read. - assertEquals("List of saved-by entries was not as expected", - expected, doc.getSavedByTable().getEntries()); - - // Now write the entire document out, and read it back in... - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - doc.write(byteStream); - InputStream copyStream = new ByteArrayInputStream(byteStream.toByteArray()); - HWPFDocument copy = new HWPFDocument(copyStream); - - // And check again. - assertEquals("List of saved-by entries was incorrect after writing", - expected, copy.getSavedByTable().getEntries()); - } -} + +/* ==================================================================== + 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.hwpf.model; + +import java.io.*; +import java.util.*; +import junit.framework.*; + +import org.apache.poi.hwpf.*; +import org.apache.poi.hwpf.model.*; +import org.apache.poi.util.*; + +/** + * Unit test for {@link SavedByTable} and {@link SavedByEntry}. + * + * @author Daniel Noll + */ +public class TestSavedByTable + extends TestCase +{ + /** Data dir */ + private File testFile = new File(new File(System.getProperty("HWPF.testdata.path")), "saved-by-table.doc"); + + /** The expected entries in the test document. */ + private List expected = Arrays.asList(new Object[] { + new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), + new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), + new SavedByEntry("cic22", "C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd"), + new SavedByEntry("JPratt", "C:\\TEMP\\Iraq - security.doc"), + new SavedByEntry("JPratt", "A:\\Iraq - security.doc"), + new SavedByEntry("ablackshaw", "C:\\ABlackshaw\\Iraq - security.doc"), + new SavedByEntry("ablackshaw", "C:\\ABlackshaw\\A;Iraq - security.doc"), + new SavedByEntry("ablackshaw", "A:\\Iraq - security.doc"), + new SavedByEntry("MKhan", "C:\\TEMP\\Iraq - security.doc"), + new SavedByEntry("MKhan", "C:\\WINNT\\Profiles\\mkhan\\Desktop\\Iraq.doc") + }); + + /** + * Tests reading in the entries, comparing them against the expected entries. + * Then tests writing the document out and reading the entries yet again. + * + * @throws Exception if an unexpected error occurs. + */ + public void testReadWrite() + throws Exception + { + // This document is widely available on the internet as "blair.doc". + // I tried stripping the content and saving the document but my version + // of Word (from Office XP) strips this table out. + InputStream stream = new BufferedInputStream(new FileInputStream(testFile)); + HWPFDocument doc; + try + { + doc = new HWPFDocument(stream); + } + finally + { + stream.close(); + } + + // Check what we just read. + assertEquals("List of saved-by entries was not as expected", + expected, doc.getSavedByTable().getEntries()); + + // Now write the entire document out, and read it back in... + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + doc.write(byteStream); + InputStream copyStream = new ByteArrayInputStream(byteStream.toByteArray()); + HWPFDocument copy = new HWPFDocument(copyStream); + + // And check again. + assertEquals("List of saved-by entries was incorrect after writing", + expected, copy.getSavedByTable().getEntries()); + } +} diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestMetaDataIPI.java b/src/testcases/org/apache/poi/hpsf/basic/TestMetaDataIPI.java index 00fcd2e501..2079d57e64 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestMetaDataIPI.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestMetaDataIPI.java @@ -1,827 +1,827 @@ -/* ==================================================================== - Copyright 2002-2006 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.hpsf.basic; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Date; -import java.util.Random; - -import junit.framework.TestCase; - -import org.apache.poi.hpsf.CustomProperties; -import org.apache.poi.hpsf.DocumentSummaryInformation; -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.NoPropertySetStreamException; -import org.apache.poi.hpsf.PropertySet; -import org.apache.poi.hpsf.PropertySetFactory; -import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; -import org.apache.poi.hpsf.WritingNotSupportedException; -import org.apache.poi.poifs.filesystem.DirectoryEntry; -import org.apache.poi.poifs.filesystem.DocumentEntry; -import org.apache.poi.poifs.filesystem.DocumentInputStream; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -/** - * Basing on: src/examples/src/org/apache/poi/hpsf/examples/ModifyDocumentSummaryInformation.java - * This class tests reading and writing of meta data. No actual document is created. All information - * is stored in a virtal document in a ByteArrayOutputStream - * @author Matthias Günter - * @since 2006-03-03 - * @version $Id: TestEmptyProperties.java 353563 2004-06-22 16:16:33Z klute $ - */ -public class TestMetaDataIPI extends TestCase{ - - private ByteArrayOutputStream bout= null; //our store - private POIFSFileSystem poifs=null; - DirectoryEntry dir = null; - DocumentSummaryInformation dsi=null; - SummaryInformation si=null; - - /** - * Standard constructor - * @param s - */ - public TestMetaDataIPI(String s ){ - super(s); - } - - /** - * Setup is used to get the document ready. Gets the DocumentSummaryInformation and the - * SummaryInformation to reasonable values - */ - public void setUp(){ - bout=new ByteArrayOutputStream(); - poifs= new POIFSFileSystem(); - dir = poifs.getRoot(); - dsi=null; - try - { - DocumentEntry dsiEntry = (DocumentEntry) - dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - DocumentInputStream dis = new DocumentInputStream(dsiEntry); - PropertySet ps = new PropertySet(dis); - dis.close(); - dsi = new DocumentSummaryInformation(ps); - - - } - catch (FileNotFoundException ex) - { - /* There is no document summary information yet. We have to create a - * new one. */ - dsi = PropertySetFactory.newDocumentSummaryInformation(); - assertNotNull(dsi); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } catch (NoPropertySetStreamException e) { - e.printStackTrace(); - fail(); - } catch (MarkUnsupportedException e) { - e.printStackTrace(); - fail(); - } catch (UnexpectedPropertySetTypeException e) { - e.printStackTrace(); - fail(); - } - assertNotNull(dsi); - try - { - DocumentEntry dsiEntry = (DocumentEntry) - dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); - DocumentInputStream dis = new DocumentInputStream(dsiEntry); - PropertySet ps = new PropertySet(dis); - dis.close(); - si = new SummaryInformation(ps); - - - } - catch (FileNotFoundException ex) - { - /* There is no document summary information yet. We have to create a - * new one. */ - si = PropertySetFactory.newSummaryInformation(); - assertNotNull(si); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } catch (NoPropertySetStreamException e) { - e.printStackTrace(); - fail(); - } catch (MarkUnsupportedException e) { - e.printStackTrace(); - fail(); - } catch (UnexpectedPropertySetTypeException e) { - e.printStackTrace(); - fail(); - } - assertNotNull(dsi); - - - } - - /** - * Setting a lot of things to null. - */ - public void tearDown(){ - bout=null; - poifs=null; - dir=null; - dsi=null; - - } - - - /** - * Closes the ByteArrayOutputStream and reads it into a ByteArrayInputStream. - * When finished writing information this method is used in the tests to - * start reading from the created document and then the see if the results match. - * - */ - public void closeAndReOpen(){ - - try { - dsi.write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME); - si.write(dir,SummaryInformation.DEFAULT_STREAM_NAME); - } catch (WritingNotSupportedException e) { - e.printStackTrace(); - fail(); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } - - si=null; - dsi=null; - try { - - poifs.writeFilesystem(bout); - bout.flush(); - - } catch (IOException e) { - - e.printStackTrace(); - fail(); - } - - InputStream is=new ByteArrayInputStream(bout.toByteArray()); - assertNotNull(is); - POIFSFileSystem poifs=null; - try { - poifs = new POIFSFileSystem(is); - } catch (IOException e) { - - e.printStackTrace(); - fail(); - } - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } - assertNotNull(poifs); - /* Read the document summary information. */ - DirectoryEntry dir = poifs.getRoot(); - - try - { - DocumentEntry dsiEntry = (DocumentEntry) - dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); - DocumentInputStream dis = new DocumentInputStream(dsiEntry); - PropertySet ps = new PropertySet(dis); - dis.close(); - dsi = new DocumentSummaryInformation(ps); - } - catch (FileNotFoundException ex) - { - fail(); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } catch (NoPropertySetStreamException e) { - e.printStackTrace(); - fail(); - } catch (MarkUnsupportedException e) { - e.printStackTrace(); - fail(); - } catch (UnexpectedPropertySetTypeException e) { - e.printStackTrace(); - fail(); - } - try - { - DocumentEntry dsiEntry = (DocumentEntry) - dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); - DocumentInputStream dis = new DocumentInputStream(dsiEntry); - PropertySet ps = new PropertySet(dis); - dis.close(); - si = new SummaryInformation(ps); - - - } - catch (FileNotFoundException ex) - { - /* There is no document summary information yet. We have to create a - * new one. */ - si = PropertySetFactory.newSummaryInformation(); - assertNotNull(si); - } catch (IOException e) { - e.printStackTrace(); - fail(); - } catch (NoPropertySetStreamException e) { - e.printStackTrace(); - fail(); - } catch (MarkUnsupportedException e) { - e.printStackTrace(); - fail(); - } catch (UnexpectedPropertySetTypeException e) { - e.printStackTrace(); - fail(); - } - } - - /** - * Sets the most important information in DocumentSummaryInformation and Summary Information and rereads it - * - */ - public void testOne(){ - - //DocumentSummaryInformation - dsi.setCompany("xxxCompanyxxx"); - dsi.setManager("xxxManagerxxx"); - dsi.setCategory("xxxCategoryxxx"); - - //SummaryInformation - si.setTitle("xxxTitlexxx"); - si.setAuthor("xxxAuthorxxx"); - si.setComments("xxxCommentsxxx"); - si.setKeywords("xxxKeyWordsxxx"); - si.setSubject("xxxSubjectxxx"); - - //Custom Properties (in DocumentSummaryInformation - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - customProperties = new CustomProperties(); - } - - /* Insert some custom properties into the container. */ - customProperties.put("Key1", "Value1"); - customProperties.put("Schlüssel2", "Wert2"); - customProperties.put("Sample Integer", new Integer(12345)); - customProperties.put("Sample Boolean", new Boolean(true)); - Date date=new Date(); - customProperties.put("Sample Date", date); - customProperties.put("Sample Double", new Double(-1.0001)); - customProperties.put("Sample Negative Integer", new Integer(-100000)); - - dsi.setCustomProperties(customProperties); - - //start reading - closeAndReOpen(); - - //testing - assertNotNull(dsi); - assertNotNull(si); - - assertEquals("Category","xxxCategoryxxx",dsi.getCategory()); - assertEquals("Company","xxxCompanyxxx",dsi.getCompany()); - assertEquals("Manager","xxxManagerxxx",dsi.getManager()); - - assertEquals("","xxxAuthorxxx",si.getAuthor()); - assertEquals("","xxxTitlexxx",si.getTitle()); - assertEquals("","xxxCommentsxxx",si.getComments()); - assertEquals("","xxxKeyWordsxxx",si.getKeywords()); - assertEquals("","xxxSubjectxxx",si.getSubject()); - - - /* Read the custom properties. If there are no custom properties yet, - * the application has to create a new CustomProperties object. It will - * serve as a container for custom properties. */ - customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - fail(); - } - - /* Insert some custom properties into the container. */ - String a1=(String) customProperties.get("Key1"); - assertEquals("Key1","Value1",a1); - String a2=(String) customProperties.get("Schlüssel2"); - assertEquals("Schlüssel2","Wert2",a2); - Integer a3=(Integer) customProperties.get("Sample Integer"); - assertEquals("Sample Number",new Integer(12345),a3); - Boolean a4=(Boolean) customProperties.get("Sample Boolean"); - assertEquals("Sample Boolean",new Boolean(true),a4); - Date a5=(Date) customProperties.get("Sample Date"); - assertEquals("Custom Date:",date,a5); - - Double a6=(Double) customProperties.get("Sample Double"); - assertEquals("Custom Float",new Double(-1.0001),a6); - - Integer a7=(Integer) customProperties.get("Sample Negative Integer"); - assertEquals("Neg", new Integer(-100000),a7); - } - - - /** - * multiplies a string - * @param s Input String - * @return the multiplied String - */ - public String elongate(String s){ - StringBuffer sb=new StringBuffer(); - for (int i=0;i<10000;i++){ - sb.append(s); - sb.append(" "); - } - return sb.toString(); - } - - - - /** - * Test very long input in each of the fields (approx 30-60KB each) - * - */ -public void testTwo(){ - - String company=elongate("company"); - String manager=elongate("manager"); - String category=elongate("category"); - String title=elongate("title"); - String author=elongate("author"); - String comments=elongate("comments"); - String keywords=elongate("keywords"); - String subject=elongate("subject"); - String p1=elongate("p1"); - String p2=elongate("p2"); - String k1=elongate("k1"); - String k2=elongate("k2"); - - dsi.setCompany(company); - dsi.setManager(manager); - dsi.setCategory(category); - - si.setTitle(title); - si.setAuthor(author); - si.setComments(comments); - si.setKeywords(keywords); - si.setSubject(subject); - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - customProperties = new CustomProperties(); - } - - /* Insert some custom properties into the container. */ - customProperties.put(k1, p1); - customProperties.put(k2, p2); - customProperties.put("Sample Number", new Integer(12345)); - customProperties.put("Sample Boolean", new Boolean(true)); - Date date=new Date(); - customProperties.put("Sample Date", date); - - dsi.setCustomProperties(customProperties); - - - closeAndReOpen(); - - assertNotNull(dsi); - assertNotNull(si); - /* Change the category to "POI example". Any former category value will - * be lost. If there has been no category yet, it will be created. */ - assertEquals("Category",category,dsi.getCategory()); - assertEquals("Company",company,dsi.getCompany()); - assertEquals("Manager",manager,dsi.getManager()); - - assertEquals("",author,si.getAuthor()); - assertEquals("",title,si.getTitle()); - assertEquals("",comments,si.getComments()); - assertEquals("",keywords,si.getKeywords()); - assertEquals("",subject,si.getSubject()); - - - /* Read the custom properties. If there are no custom properties - * yet, the application has to create a new CustomProperties object. - * It will serve as a container for custom properties. */ - customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - fail(); - } - - /* Insert some custom properties into the container. */ - String a1=(String) customProperties.get(k1); - assertEquals("Key1",p1,a1); - String a2=(String) customProperties.get(k2); - assertEquals("Schlüssel2",p2,a2); - Integer a3=(Integer) customProperties.get("Sample Number"); - assertEquals("Sample Number",new Integer(12345),a3); - Boolean a4=(Boolean) customProperties.get("Sample Boolean"); - assertEquals("Sample Boolean",new Boolean(true),a4); - Date a5=(Date) customProperties.get("Sample Date"); - assertEquals("Custom Date:",date,a5); - - - } - - -/** - * adds strange characters to the string - * @param s Input String - * @return the multiplied String - */ -public String strangize(String s){ - StringBuffer sb=new StringBuffer(); - String[] umlaute= {"ä","ü","ö","Ü","$","Ö","Ü","É","Ö","@","ç","&"}; - char j=0; - Random rand=new Random(); - for (int i=0;i<5;i++){ - sb.append(s); - sb.append(" "); - j=(char) rand.nextInt(220); - j+=33; - // System.out.println(j); - sb.append(">"); - sb.append(new Character(j)); - sb.append("="); - sb.append(umlaute[rand.nextInt(umlaute.length)]); - sb.append("<"); - } - - return sb.toString(); -} - - -/** - * Tests with strange characters in keys and data (Umlaute etc.) - * - */ -public void testThree(){ - - String company=strangize("company"); - String manager=strangize("manager"); - String category=strangize("category"); - String title=strangize("title"); - String author=strangize("author"); - String comments=strangize("comments"); - String keywords=strangize("keywords"); - String subject=strangize("subject"); - String p1=strangize("p1"); - String p2=strangize("p2"); - String k1=strangize("k1"); - String k2=strangize("k2"); - - dsi.setCompany(company); - dsi.setManager(manager); - dsi.setCategory(category); - - si.setTitle(title); - si.setAuthor(author); - si.setComments(comments); - si.setKeywords(keywords); - si.setSubject(subject); - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - customProperties = new CustomProperties(); - } - - /* Insert some custom properties into the container. */ - customProperties.put(k1, p1); - customProperties.put(k2, p2); - customProperties.put("Sample Number", new Integer(12345)); - customProperties.put("Sample Boolean", new Boolean(false)); - Date date=new Date(0); - customProperties.put("Sample Date", date); - - dsi.setCustomProperties(customProperties); - - - closeAndReOpen(); - - assertNotNull(dsi); - assertNotNull(si); - /* Change the category to "POI example". Any former category value will - * be lost. If there has been no category yet, it will be created. */ - assertEquals("Category",category,dsi.getCategory()); - assertEquals("Company",company,dsi.getCompany()); - assertEquals("Manager",manager,dsi.getManager()); - - assertEquals("",author,si.getAuthor()); - assertEquals("",title,si.getTitle()); - assertEquals("",comments,si.getComments()); - assertEquals("",keywords,si.getKeywords()); - assertEquals("",subject,si.getSubject()); - - - /* Read the custom properties. If there are no custom properties yet, - * the application has to create a new CustomProperties object. It will - * serve as a container for custom properties. */ - customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - fail(); - } - - /* Insert some custom properties into the container. */ - // System.out.println(k1); - String a1=(String) customProperties.get(k1); - assertEquals("Key1",p1,a1); - String a2=(String) customProperties.get(k2); - assertEquals("Schlüssel2",p2,a2); - Integer a3=(Integer) customProperties.get("Sample Number"); - assertEquals("Sample Number",new Integer(12345),a3); - Boolean a4=(Boolean) customProperties.get("Sample Boolean"); - assertEquals("Sample Boolean",new Boolean(false),a4); - Date a5=(Date) customProperties.get("Sample Date"); - assertEquals("Custom Date:",date,a5); - - - } - - /** - * Iterative testing: writing, reading etc. - * - */ - public void testFour(){ - for (int i=1;i<100;i++){ - setUp(); - testThree(); - tearDown(); - } - } - - - - /** - * adds strange characters to the string with the adding of unicode characters - * @param s Input String - * @return the multiplied String - */ - public String strangizeU(String s){ - - StringBuffer sb=new StringBuffer(); - String[] umlaute= {"ä","ü","ö","Ü","$","Ö","Ü","É","Ö","@","ç","&"}; - char j=0; - Random rand=new Random(); - for (int i=0;i<5;i++){ - sb.append(s); - sb.append(" "); - j=(char) rand.nextInt(220); - j+=33; - // System.out.println(j); - sb.append(">"); - sb.append(new Character(j)); - sb.append("="); - sb.append(umlaute[rand.nextInt(umlaute.length)]); - sb.append("<"); - } - sb.append("äöü\uD840\uDC00"); - return sb.toString(); - } - /** - * Unicode test - * - */ - public void testUnicode(){ - String company=strangizeU("company"); - String manager=strangizeU("manager"); - String category=strangizeU("category"); - String title=strangizeU("title"); - String author=strangizeU("author"); - String comments=strangizeU("comments"); - String keywords=strangizeU("keywords"); - String subject=strangizeU("subject"); - String p1=strangizeU("p1"); - String p2=strangizeU("p2"); - String k1=strangizeU("k1"); - String k2=strangizeU("k2"); - - dsi.setCompany(company); - dsi.setManager(manager); - dsi.setCategory(category); - - si.setTitle(title); - si.setAuthor(author); - si.setComments(comments); - si.setKeywords(keywords); - si.setSubject(subject); - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - customProperties = new CustomProperties(); - } - - /* Insert some custom properties into the container. */ - customProperties.put(k1, p1); - customProperties.put(k2, p2); - customProperties.put("Sample Number", new Integer(12345)); - customProperties.put("Sample Boolean", new Boolean(true)); - Date date=new Date(); - customProperties.put("Sample Date", date); - - dsi.setCustomProperties(customProperties); - - - closeAndReOpen(); - - assertNotNull(dsi); - assertNotNull(si); - /* Change the category to "POI example". Any former category value will - * be lost. If there has been no category yet, it will be created. */ - assertEquals("Category",category,dsi.getCategory()); - assertEquals("Company",company,dsi.getCompany()); - assertEquals("Manager",manager,dsi.getManager()); - - assertEquals("",author,si.getAuthor()); - assertEquals("",title,si.getTitle()); - assertEquals("",comments,si.getComments()); - assertEquals("",keywords,si.getKeywords()); - assertEquals("",subject,si.getSubject()); - - - /* Read the custom properties. If there are no custom properties yet, - * the application has to create a new CustomProperties object. It will - * serve as a container for custom properties. */ - customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - fail(); - } - - /* Insert some custom properties into the container. */ - // System.out.println(k1); - String a1=(String) customProperties.get(k1); - assertEquals("Key1",p1,a1); - String a2=(String) customProperties.get(k2); - assertEquals("Schlüssel2",p2,a2); - Integer a3=(Integer) customProperties.get("Sample Number"); - assertEquals("Sample Number",new Integer(12345),a3); - Boolean a4=(Boolean) customProperties.get("Sample Boolean"); - assertEquals("Sample Boolean",new Boolean(true),a4); - Date a5=(Date) customProperties.get("Sample Date"); - assertEquals("Custom Date:",date,a5); - - - - } - - - /** - * Iterative testing of the unicode test - * - */ - public void testSix(){ - for (int i=1;i<100;i++){ - setUp(); - testUnicode(); - tearDown(); - } - } - - - /** - * Tests conversion in custom fields and errors - * - */ - public void testConvAndExistance(){ - - - CustomProperties customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - customProperties = new CustomProperties(); - } - - /* Insert some custom properties into the container. */ - customProperties.put("int", new Integer(12345)); - customProperties.put("negint", new Integer(-12345)); - customProperties.put("long", new Long(12345)); - customProperties.put("neglong", new Long(-12345)); - customProperties.put("boolean", new Boolean(true)); - customProperties.put("string", "a String"); - //customProperties.put("float", new Float(12345.0)); is not valid - //customProperties.put("negfloat", new Float(-12345.1)); is not valid - customProperties.put("double", new Double(12345.2)); - customProperties.put("negdouble", new Double(-12345.3)); - //customProperties.put("char", new Character('a')); is not valid - - Date date=new Date(); - customProperties.put("date", date); - - dsi.setCustomProperties(customProperties); - - - closeAndReOpen(); - - assertNotNull(dsi); - assertNotNull(si); - /* Change the category to "POI example". Any former category value will - * be lost. If there has been no category yet, it will be created. */ - assertNull(dsi.getCategory()); - assertNull(dsi.getCompany()); - assertNull(dsi.getManager()); - - assertNull(si.getAuthor()); - assertNull(si.getTitle()); - assertNull(si.getComments()); - assertNull(si.getKeywords()); - assertNull(si.getSubject()); - - - /* Read the custom properties. If there are no custom properties - * yet, the application has to create a new CustomProperties object. - * It will serve as a container for custom properties. */ - customProperties = dsi.getCustomProperties(); - if (customProperties == null){ - fail(); - } - - /* Insert some custom properties into the container. */ - - Integer a3=(Integer) customProperties.get("int"); - assertEquals("int",new Integer(12345),a3); - - a3=(Integer) customProperties.get("negint"); - assertEquals("negint",new Integer(-12345),a3); - - Long al=(Long) customProperties.get("neglong"); - assertEquals("neglong",new Long(-12345),al); - - al=(Long) customProperties.get("long"); - assertEquals("long",new Long(12345),al); - - Boolean a4=(Boolean) customProperties.get("boolean"); - assertEquals("boolean",new Boolean(true),a4); - - Date a5=(Date) customProperties.get("date"); - assertEquals("Custom Date:",date,a5); - - Double d=(Double) customProperties.get("double"); - assertEquals("int",new Double(12345.2),d); - - d=(Double) customProperties.get("negdouble"); - assertEquals("string",new Double(-12345.3),d); - - String s=(String) customProperties.get("string"); - assertEquals("sring","a String",s); - - Object o=null; - - o=customProperties.get("string"); - if (!(o instanceof String)){ - fail(); - } - o=customProperties.get("boolean"); - if (!(o instanceof Boolean)){ - fail(); - } - - o=customProperties.get("int"); - if (!(o instanceof Integer)){ - fail(); - } - o=customProperties.get("negint"); - if (!(o instanceof Integer)){ - fail(); - } - - o=customProperties.get("long"); - if (!(o instanceof Long)){ - fail(); - } - o=customProperties.get("neglong"); - if (!(o instanceof Long)){ - fail(); - } - - o=customProperties.get("double"); - if (!(o instanceof Double)){ - fail(); - } - o=customProperties.get("negdouble"); - if (!(o instanceof Double)){ - fail(); - } - - o=customProperties.get("date"); - if (!(o instanceof Date)){ - fail(); - } - } - - - +/* ==================================================================== + Copyright 2002-2006 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.hpsf.basic; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Random; + +import junit.framework.TestCase; + +import org.apache.poi.hpsf.CustomProperties; +import org.apache.poi.hpsf.DocumentSummaryInformation; +import org.apache.poi.hpsf.MarkUnsupportedException; +import org.apache.poi.hpsf.NoPropertySetStreamException; +import org.apache.poi.hpsf.PropertySet; +import org.apache.poi.hpsf.PropertySetFactory; +import org.apache.poi.hpsf.SummaryInformation; +import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; +import org.apache.poi.hpsf.WritingNotSupportedException; +import org.apache.poi.poifs.filesystem.DirectoryEntry; +import org.apache.poi.poifs.filesystem.DocumentEntry; +import org.apache.poi.poifs.filesystem.DocumentInputStream; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +/** + * Basing on: src/examples/src/org/apache/poi/hpsf/examples/ModifyDocumentSummaryInformation.java + * This class tests reading and writing of meta data. No actual document is created. All information + * is stored in a virtal document in a ByteArrayOutputStream + * @author Matthias Günter + * @since 2006-03-03 + * @version $Id: TestEmptyProperties.java 353563 2004-06-22 16:16:33Z klute $ + */ +public class TestMetaDataIPI extends TestCase{ + + private ByteArrayOutputStream bout= null; //our store + private POIFSFileSystem poifs=null; + DirectoryEntry dir = null; + DocumentSummaryInformation dsi=null; + SummaryInformation si=null; + + /** + * Standard constructor + * @param s + */ + public TestMetaDataIPI(String s ){ + super(s); + } + + /** + * Setup is used to get the document ready. Gets the DocumentSummaryInformation and the + * SummaryInformation to reasonable values + */ + public void setUp(){ + bout=new ByteArrayOutputStream(); + poifs= new POIFSFileSystem(); + dir = poifs.getRoot(); + dsi=null; + try + { + DocumentEntry dsiEntry = (DocumentEntry) + dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); + DocumentInputStream dis = new DocumentInputStream(dsiEntry); + PropertySet ps = new PropertySet(dis); + dis.close(); + dsi = new DocumentSummaryInformation(ps); + + + } + catch (FileNotFoundException ex) + { + /* There is no document summary information yet. We have to create a + * new one. */ + dsi = PropertySetFactory.newDocumentSummaryInformation(); + assertNotNull(dsi); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } catch (NoPropertySetStreamException e) { + e.printStackTrace(); + fail(); + } catch (MarkUnsupportedException e) { + e.printStackTrace(); + fail(); + } catch (UnexpectedPropertySetTypeException e) { + e.printStackTrace(); + fail(); + } + assertNotNull(dsi); + try + { + DocumentEntry dsiEntry = (DocumentEntry) + dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); + DocumentInputStream dis = new DocumentInputStream(dsiEntry); + PropertySet ps = new PropertySet(dis); + dis.close(); + si = new SummaryInformation(ps); + + + } + catch (FileNotFoundException ex) + { + /* There is no document summary information yet. We have to create a + * new one. */ + si = PropertySetFactory.newSummaryInformation(); + assertNotNull(si); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } catch (NoPropertySetStreamException e) { + e.printStackTrace(); + fail(); + } catch (MarkUnsupportedException e) { + e.printStackTrace(); + fail(); + } catch (UnexpectedPropertySetTypeException e) { + e.printStackTrace(); + fail(); + } + assertNotNull(dsi); + + + } + + /** + * Setting a lot of things to null. + */ + public void tearDown(){ + bout=null; + poifs=null; + dir=null; + dsi=null; + + } + + + /** + * Closes the ByteArrayOutputStream and reads it into a ByteArrayInputStream. + * When finished writing information this method is used in the tests to + * start reading from the created document and then the see if the results match. + * + */ + public void closeAndReOpen(){ + + try { + dsi.write(dir, DocumentSummaryInformation.DEFAULT_STREAM_NAME); + si.write(dir,SummaryInformation.DEFAULT_STREAM_NAME); + } catch (WritingNotSupportedException e) { + e.printStackTrace(); + fail(); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } + + si=null; + dsi=null; + try { + + poifs.writeFilesystem(bout); + bout.flush(); + + } catch (IOException e) { + + e.printStackTrace(); + fail(); + } + + InputStream is=new ByteArrayInputStream(bout.toByteArray()); + assertNotNull(is); + POIFSFileSystem poifs=null; + try { + poifs = new POIFSFileSystem(is); + } catch (IOException e) { + + e.printStackTrace(); + fail(); + } + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } + assertNotNull(poifs); + /* Read the document summary information. */ + DirectoryEntry dir = poifs.getRoot(); + + try + { + DocumentEntry dsiEntry = (DocumentEntry) + dir.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME); + DocumentInputStream dis = new DocumentInputStream(dsiEntry); + PropertySet ps = new PropertySet(dis); + dis.close(); + dsi = new DocumentSummaryInformation(ps); + } + catch (FileNotFoundException ex) + { + fail(); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } catch (NoPropertySetStreamException e) { + e.printStackTrace(); + fail(); + } catch (MarkUnsupportedException e) { + e.printStackTrace(); + fail(); + } catch (UnexpectedPropertySetTypeException e) { + e.printStackTrace(); + fail(); + } + try + { + DocumentEntry dsiEntry = (DocumentEntry) + dir.getEntry(SummaryInformation.DEFAULT_STREAM_NAME); + DocumentInputStream dis = new DocumentInputStream(dsiEntry); + PropertySet ps = new PropertySet(dis); + dis.close(); + si = new SummaryInformation(ps); + + + } + catch (FileNotFoundException ex) + { + /* There is no document summary information yet. We have to create a + * new one. */ + si = PropertySetFactory.newSummaryInformation(); + assertNotNull(si); + } catch (IOException e) { + e.printStackTrace(); + fail(); + } catch (NoPropertySetStreamException e) { + e.printStackTrace(); + fail(); + } catch (MarkUnsupportedException e) { + e.printStackTrace(); + fail(); + } catch (UnexpectedPropertySetTypeException e) { + e.printStackTrace(); + fail(); + } + } + + /** + * Sets the most important information in DocumentSummaryInformation and Summary Information and rereads it + * + */ + public void testOne(){ + + //DocumentSummaryInformation + dsi.setCompany("xxxCompanyxxx"); + dsi.setManager("xxxManagerxxx"); + dsi.setCategory("xxxCategoryxxx"); + + //SummaryInformation + si.setTitle("xxxTitlexxx"); + si.setAuthor("xxxAuthorxxx"); + si.setComments("xxxCommentsxxx"); + si.setKeywords("xxxKeyWordsxxx"); + si.setSubject("xxxSubjectxxx"); + + //Custom Properties (in DocumentSummaryInformation + CustomProperties customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + customProperties = new CustomProperties(); + } + + /* Insert some custom properties into the container. */ + customProperties.put("Key1", "Value1"); + customProperties.put("Schlüssel2", "Wert2"); + customProperties.put("Sample Integer", new Integer(12345)); + customProperties.put("Sample Boolean", new Boolean(true)); + Date date=new Date(); + customProperties.put("Sample Date", date); + customProperties.put("Sample Double", new Double(-1.0001)); + customProperties.put("Sample Negative Integer", new Integer(-100000)); + + dsi.setCustomProperties(customProperties); + + //start reading + closeAndReOpen(); + + //testing + assertNotNull(dsi); + assertNotNull(si); + + assertEquals("Category","xxxCategoryxxx",dsi.getCategory()); + assertEquals("Company","xxxCompanyxxx",dsi.getCompany()); + assertEquals("Manager","xxxManagerxxx",dsi.getManager()); + + assertEquals("","xxxAuthorxxx",si.getAuthor()); + assertEquals("","xxxTitlexxx",si.getTitle()); + assertEquals("","xxxCommentsxxx",si.getComments()); + assertEquals("","xxxKeyWordsxxx",si.getKeywords()); + assertEquals("","xxxSubjectxxx",si.getSubject()); + + + /* Read the custom properties. If there are no custom properties yet, + * the application has to create a new CustomProperties object. It will + * serve as a container for custom properties. */ + customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + fail(); + } + + /* Insert some custom properties into the container. */ + String a1=(String) customProperties.get("Key1"); + assertEquals("Key1","Value1",a1); + String a2=(String) customProperties.get("Schlüssel2"); + assertEquals("Schlüssel2","Wert2",a2); + Integer a3=(Integer) customProperties.get("Sample Integer"); + assertEquals("Sample Number",new Integer(12345),a3); + Boolean a4=(Boolean) customProperties.get("Sample Boolean"); + assertEquals("Sample Boolean",new Boolean(true),a4); + Date a5=(Date) customProperties.get("Sample Date"); + assertEquals("Custom Date:",date,a5); + + Double a6=(Double) customProperties.get("Sample Double"); + assertEquals("Custom Float",new Double(-1.0001),a6); + + Integer a7=(Integer) customProperties.get("Sample Negative Integer"); + assertEquals("Neg", new Integer(-100000),a7); + } + + + /** + * multiplies a string + * @param s Input String + * @return the multiplied String + */ + public String elongate(String s){ + StringBuffer sb=new StringBuffer(); + for (int i=0;i<10000;i++){ + sb.append(s); + sb.append(" "); + } + return sb.toString(); + } + + + + /** + * Test very long input in each of the fields (approx 30-60KB each) + * + */ +public void testTwo(){ + + String company=elongate("company"); + String manager=elongate("manager"); + String category=elongate("category"); + String title=elongate("title"); + String author=elongate("author"); + String comments=elongate("comments"); + String keywords=elongate("keywords"); + String subject=elongate("subject"); + String p1=elongate("p1"); + String p2=elongate("p2"); + String k1=elongate("k1"); + String k2=elongate("k2"); + + dsi.setCompany(company); + dsi.setManager(manager); + dsi.setCategory(category); + + si.setTitle(title); + si.setAuthor(author); + si.setComments(comments); + si.setKeywords(keywords); + si.setSubject(subject); + CustomProperties customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + customProperties = new CustomProperties(); + } + + /* Insert some custom properties into the container. */ + customProperties.put(k1, p1); + customProperties.put(k2, p2); + customProperties.put("Sample Number", new Integer(12345)); + customProperties.put("Sample Boolean", new Boolean(true)); + Date date=new Date(); + customProperties.put("Sample Date", date); + + dsi.setCustomProperties(customProperties); + + + closeAndReOpen(); + + assertNotNull(dsi); + assertNotNull(si); + /* Change the category to "POI example". Any former category value will + * be lost. If there has been no category yet, it will be created. */ + assertEquals("Category",category,dsi.getCategory()); + assertEquals("Company",company,dsi.getCompany()); + assertEquals("Manager",manager,dsi.getManager()); + + assertEquals("",author,si.getAuthor()); + assertEquals("",title,si.getTitle()); + assertEquals("",comments,si.getComments()); + assertEquals("",keywords,si.getKeywords()); + assertEquals("",subject,si.getSubject()); + + + /* Read the custom properties. If there are no custom properties + * yet, the application has to create a new CustomProperties object. + * It will serve as a container for custom properties. */ + customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + fail(); + } + + /* Insert some custom properties into the container. */ + String a1=(String) customProperties.get(k1); + assertEquals("Key1",p1,a1); + String a2=(String) customProperties.get(k2); + assertEquals("Schlüssel2",p2,a2); + Integer a3=(Integer) customProperties.get("Sample Number"); + assertEquals("Sample Number",new Integer(12345),a3); + Boolean a4=(Boolean) customProperties.get("Sample Boolean"); + assertEquals("Sample Boolean",new Boolean(true),a4); + Date a5=(Date) customProperties.get("Sample Date"); + assertEquals("Custom Date:",date,a5); + + + } + + +/** + * adds strange characters to the string + * @param s Input String + * @return the multiplied String + */ +public String strangize(String s){ + StringBuffer sb=new StringBuffer(); + String[] umlaute= {"ä","ü","ö","Ü","$","Ö","Ü","É","Ö","@","ç","&"}; + char j=0; + Random rand=new Random(); + for (int i=0;i<5;i++){ + sb.append(s); + sb.append(" "); + j=(char) rand.nextInt(220); + j+=33; + // System.out.println(j); + sb.append(">"); + sb.append(new Character(j)); + sb.append("="); + sb.append(umlaute[rand.nextInt(umlaute.length)]); + sb.append("<"); + } + + return sb.toString(); +} + + +/** + * Tests with strange characters in keys and data (Umlaute etc.) + * + */ +public void testThree(){ + + String company=strangize("company"); + String manager=strangize("manager"); + String category=strangize("category"); + String title=strangize("title"); + String author=strangize("author"); + String comments=strangize("comments"); + String keywords=strangize("keywords"); + String subject=strangize("subject"); + String p1=strangize("p1"); + String p2=strangize("p2"); + String k1=strangize("k1"); + String k2=strangize("k2"); + + dsi.setCompany(company); + dsi.setManager(manager); + dsi.setCategory(category); + + si.setTitle(title); + si.setAuthor(author); + si.setComments(comments); + si.setKeywords(keywords); + si.setSubject(subject); + CustomProperties customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + customProperties = new CustomProperties(); + } + + /* Insert some custom properties into the container. */ + customProperties.put(k1, p1); + customProperties.put(k2, p2); + customProperties.put("Sample Number", new Integer(12345)); + customProperties.put("Sample Boolean", new Boolean(false)); + Date date=new Date(0); + customProperties.put("Sample Date", date); + + dsi.setCustomProperties(customProperties); + + + closeAndReOpen(); + + assertNotNull(dsi); + assertNotNull(si); + /* Change the category to "POI example". Any former category value will + * be lost. If there has been no category yet, it will be created. */ + assertEquals("Category",category,dsi.getCategory()); + assertEquals("Company",company,dsi.getCompany()); + assertEquals("Manager",manager,dsi.getManager()); + + assertEquals("",author,si.getAuthor()); + assertEquals("",title,si.getTitle()); + assertEquals("",comments,si.getComments()); + assertEquals("",keywords,si.getKeywords()); + assertEquals("",subject,si.getSubject()); + + + /* Read the custom properties. If there are no custom properties yet, + * the application has to create a new CustomProperties object. It will + * serve as a container for custom properties. */ + customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + fail(); + } + + /* Insert some custom properties into the container. */ + // System.out.println(k1); + String a1=(String) customProperties.get(k1); + assertEquals("Key1",p1,a1); + String a2=(String) customProperties.get(k2); + assertEquals("Schlüssel2",p2,a2); + Integer a3=(Integer) customProperties.get("Sample Number"); + assertEquals("Sample Number",new Integer(12345),a3); + Boolean a4=(Boolean) customProperties.get("Sample Boolean"); + assertEquals("Sample Boolean",new Boolean(false),a4); + Date a5=(Date) customProperties.get("Sample Date"); + assertEquals("Custom Date:",date,a5); + + + } + + /** + * Iterative testing: writing, reading etc. + * + */ + public void testFour(){ + for (int i=1;i<100;i++){ + setUp(); + testThree(); + tearDown(); + } + } + + + + /** + * adds strange characters to the string with the adding of unicode characters + * @param s Input String + * @return the multiplied String + */ + public String strangizeU(String s){ + + StringBuffer sb=new StringBuffer(); + String[] umlaute= {"ä","ü","ö","Ü","$","Ö","Ü","É","Ö","@","ç","&"}; + char j=0; + Random rand=new Random(); + for (int i=0;i<5;i++){ + sb.append(s); + sb.append(" "); + j=(char) rand.nextInt(220); + j+=33; + // System.out.println(j); + sb.append(">"); + sb.append(new Character(j)); + sb.append("="); + sb.append(umlaute[rand.nextInt(umlaute.length)]); + sb.append("<"); + } + sb.append("äöü\uD840\uDC00"); + return sb.toString(); + } + /** + * Unicode test + * + */ + public void testUnicode(){ + String company=strangizeU("company"); + String manager=strangizeU("manager"); + String category=strangizeU("category"); + String title=strangizeU("title"); + String author=strangizeU("author"); + String comments=strangizeU("comments"); + String keywords=strangizeU("keywords"); + String subject=strangizeU("subject"); + String p1=strangizeU("p1"); + String p2=strangizeU("p2"); + String k1=strangizeU("k1"); + String k2=strangizeU("k2"); + + dsi.setCompany(company); + dsi.setManager(manager); + dsi.setCategory(category); + + si.setTitle(title); + si.setAuthor(author); + si.setComments(comments); + si.setKeywords(keywords); + si.setSubject(subject); + CustomProperties customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + customProperties = new CustomProperties(); + } + + /* Insert some custom properties into the container. */ + customProperties.put(k1, p1); + customProperties.put(k2, p2); + customProperties.put("Sample Number", new Integer(12345)); + customProperties.put("Sample Boolean", new Boolean(true)); + Date date=new Date(); + customProperties.put("Sample Date", date); + + dsi.setCustomProperties(customProperties); + + + closeAndReOpen(); + + assertNotNull(dsi); + assertNotNull(si); + /* Change the category to "POI example". Any former category value will + * be lost. If there has been no category yet, it will be created. */ + assertEquals("Category",category,dsi.getCategory()); + assertEquals("Company",company,dsi.getCompany()); + assertEquals("Manager",manager,dsi.getManager()); + + assertEquals("",author,si.getAuthor()); + assertEquals("",title,si.getTitle()); + assertEquals("",comments,si.getComments()); + assertEquals("",keywords,si.getKeywords()); + assertEquals("",subject,si.getSubject()); + + + /* Read the custom properties. If there are no custom properties yet, + * the application has to create a new CustomProperties object. It will + * serve as a container for custom properties. */ + customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + fail(); + } + + /* Insert some custom properties into the container. */ + // System.out.println(k1); + String a1=(String) customProperties.get(k1); + assertEquals("Key1",p1,a1); + String a2=(String) customProperties.get(k2); + assertEquals("Schlüssel2",p2,a2); + Integer a3=(Integer) customProperties.get("Sample Number"); + assertEquals("Sample Number",new Integer(12345),a3); + Boolean a4=(Boolean) customProperties.get("Sample Boolean"); + assertEquals("Sample Boolean",new Boolean(true),a4); + Date a5=(Date) customProperties.get("Sample Date"); + assertEquals("Custom Date:",date,a5); + + + + } + + + /** + * Iterative testing of the unicode test + * + */ + public void testSix(){ + for (int i=1;i<100;i++){ + setUp(); + testUnicode(); + tearDown(); + } + } + + + /** + * Tests conversion in custom fields and errors + * + */ + public void testConvAndExistance(){ + + + CustomProperties customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + customProperties = new CustomProperties(); + } + + /* Insert some custom properties into the container. */ + customProperties.put("int", new Integer(12345)); + customProperties.put("negint", new Integer(-12345)); + customProperties.put("long", new Long(12345)); + customProperties.put("neglong", new Long(-12345)); + customProperties.put("boolean", new Boolean(true)); + customProperties.put("string", "a String"); + //customProperties.put("float", new Float(12345.0)); is not valid + //customProperties.put("negfloat", new Float(-12345.1)); is not valid + customProperties.put("double", new Double(12345.2)); + customProperties.put("negdouble", new Double(-12345.3)); + //customProperties.put("char", new Character('a')); is not valid + + Date date=new Date(); + customProperties.put("date", date); + + dsi.setCustomProperties(customProperties); + + + closeAndReOpen(); + + assertNotNull(dsi); + assertNotNull(si); + /* Change the category to "POI example". Any former category value will + * be lost. If there has been no category yet, it will be created. */ + assertNull(dsi.getCategory()); + assertNull(dsi.getCompany()); + assertNull(dsi.getManager()); + + assertNull(si.getAuthor()); + assertNull(si.getTitle()); + assertNull(si.getComments()); + assertNull(si.getKeywords()); + assertNull(si.getSubject()); + + + /* Read the custom properties. If there are no custom properties + * yet, the application has to create a new CustomProperties object. + * It will serve as a container for custom properties. */ + customProperties = dsi.getCustomProperties(); + if (customProperties == null){ + fail(); + } + + /* Insert some custom properties into the container. */ + + Integer a3=(Integer) customProperties.get("int"); + assertEquals("int",new Integer(12345),a3); + + a3=(Integer) customProperties.get("negint"); + assertEquals("negint",new Integer(-12345),a3); + + Long al=(Long) customProperties.get("neglong"); + assertEquals("neglong",new Long(-12345),al); + + al=(Long) customProperties.get("long"); + assertEquals("long",new Long(12345),al); + + Boolean a4=(Boolean) customProperties.get("boolean"); + assertEquals("boolean",new Boolean(true),a4); + + Date a5=(Date) customProperties.get("date"); + assertEquals("Custom Date:",date,a5); + + Double d=(Double) customProperties.get("double"); + assertEquals("int",new Double(12345.2),d); + + d=(Double) customProperties.get("negdouble"); + assertEquals("string",new Double(-12345.3),d); + + String s=(String) customProperties.get("string"); + assertEquals("sring","a String",s); + + Object o=null; + + o=customProperties.get("string"); + if (!(o instanceof String)){ + fail(); + } + o=customProperties.get("boolean"); + if (!(o instanceof Boolean)){ + fail(); + } + + o=customProperties.get("int"); + if (!(o instanceof Integer)){ + fail(); + } + o=customProperties.get("negint"); + if (!(o instanceof Integer)){ + fail(); + } + + o=customProperties.get("long"); + if (!(o instanceof Long)){ + fail(); + } + o=customProperties.get("neglong"); + if (!(o instanceof Long)){ + fail(); + } + + o=customProperties.get("double"); + if (!(o instanceof Double)){ + fail(); + } + o=customProperties.get("negdouble"); + if (!(o instanceof Double)){ + fail(); + } + + o=customProperties.get("date"); + if (!(o instanceof Date)){ + fail(); + } + } + + + } \ No newline at end of file diff --git a/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java b/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java index 71d85c8657..6203f775ca 100644 --- a/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/AbstractPtgTestCase.java @@ -1,61 +1,61 @@ - -/* ==================================================================== - Copyright 2003-2004 Apache Software Foundation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.formula; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * Convenient abstract class to reduce the amount of boilerplate code needed - * in ptg-related unit tests. - * - * @author Daniel Noll (daniel at nuix dot com dot au) - */ -public class AbstractPtgTestCase extends TestCase -{ - /** Directory containing the test data. */ - private static String dataDir = System.getProperty("HSSF.testdata.path"); - - /** - * Loads a workbook from the given filename in the test data dir. - * - * @param filename the filename. - * @return the loaded workbook. - * @throws IOException if an error occurs loading the workbook. - */ - protected static HSSFWorkbook loadWorkbook(String filename) - throws IOException { - File file = new File(dataDir, filename); - InputStream stream = new BufferedInputStream(new FileInputStream(file)); - try - { - return new HSSFWorkbook(stream); - } - finally - { - stream.close(); - } - } -} + +/* ==================================================================== + Copyright 2003-2004 Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Convenient abstract class to reduce the amount of boilerplate code needed + * in ptg-related unit tests. + * + * @author Daniel Noll (daniel at nuix dot com dot au) + */ +public class AbstractPtgTestCase extends TestCase +{ + /** Directory containing the test data. */ + private static String dataDir = System.getProperty("HSSF.testdata.path"); + + /** + * Loads a workbook from the given filename in the test data dir. + * + * @param filename the filename. + * @return the loaded workbook. + * @throws IOException if an error occurs loading the workbook. + */ + protected static HSSFWorkbook loadWorkbook(String filename) + throws IOException { + File file = new File(dataDir, filename); + InputStream stream = new BufferedInputStream(new FileInputStream(file)); + try + { + return new HSSFWorkbook(stream); + } + finally + { + stream.close(); + } + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java index eabf78961f..44917c4dd1 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestUnicodeWorkbook.java @@ -1,131 +1,131 @@ -package org.apache.poi.hssf.usermodel; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileInputStream; - -import org.apache.poi.util.TempFile; - -import junit.framework.TestCase; - -public class TestUnicodeWorkbook extends TestCase { - - public TestUnicodeWorkbook(String s) { - super(s); - } - - /** Tests that all of the unicode capable string fields can be set, written and then read back - * - * - */ - public void testUnicodeInAll() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook(); - //Create a unicode dataformat (contains euro symbol) - HSSFDataFormat df = wb.createDataFormat(); - final String formatStr = "_([$\u20ac-2]\\\\\\ * #,##0.00_);_([$\u20ac-2]\\\\\\ * \\\\\\(#,##0.00\\\\\\);_([$\u20ac-2]\\\\\\ *\\\"\\-\\\\\"??_);_(@_)"; - short fmt = df.getFormat(formatStr); - - //Create a unicode sheet name (euro symbol) - HSSFSheet s = wb.createSheet("\u20ac"); - - //Set a unicode header (you guessed it the euro symbol) - HSSFHeader h = s.getHeader(); - h.setCenter("\u20ac"); - h.setLeft("\u20ac"); - h.setRight("\u20ac"); - - //Set a unicode footer - HSSFFooter f = s.getFooter(); - f.setCenter("\u20ac"); - f.setLeft("\u20ac"); - f.setRight("\u20ac"); - - HSSFRow r = s.createRow(0); - HSSFCell c = r.createCell((short)1); - c.setCellValue(12.34); - c.getCellStyle().setDataFormat(fmt); - - HSSFCell c2 = r.createCell((short)2); - c.setCellValue(new HSSFRichTextString("\u20ac")); - - HSSFCell c3 = r.createCell((short)3); - String formulaString = "TEXT(12.34,\"\u20ac###,##\")"; - c3.setCellFormula(formulaString); - - - File tempFile = TempFile.createTempFile("unicode", "test.xls"); - FileOutputStream stream = new FileOutputStream(tempFile); - wb.write(stream); - - wb = null; - FileInputStream in = new FileInputStream(tempFile); - wb = new HSSFWorkbook(in); - - //Test the sheetname - s = wb.getSheet("\u20ac"); - assertNotNull(s); - - //Test the header - h = s.getHeader(); - assertEquals(h.getCenter(), "\u20ac"); - assertEquals(h.getLeft(), "\u20ac"); - assertEquals(h.getRight(), "\u20ac"); - - //Test the footer - f = s.getFooter(); - assertEquals(f.getCenter(), "\u20ac"); - assertEquals(f.getLeft(), "\u20ac"); - assertEquals(f.getRight(), "\u20ac"); - - //Test the dataformat - r = s.getRow(0); - c = r.getCell((short)1); - df = wb.createDataFormat(); - assertEquals(formatStr, df.getFormat(c.getCellStyle().getDataFormat())); - - //Test the cell string value - c2 = r.getCell((short)2); - assertEquals(c.getRichStringCellValue().getString(), "\u20ac"); - - //Test the cell formula - c3 = r.getCell((short)3); - assertEquals(c3.getCellFormula(), formulaString); - } - - /** Tests Bug38230 - * That a Umlat is written and then read back. - * It should have been written as a compressed unicode. - * - * - * - */ - public void testUmlatReadWrite() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook(); - - //Create a unicode sheet name (euro symbol) - HSSFSheet s = wb.createSheet("test"); - - HSSFRow r = s.createRow(0); - HSSFCell c = r.createCell((short)1); - c.setCellValue(new HSSFRichTextString("\u00e4")); - - //Confirm that the sring will be compressed - assertEquals(c.getRichStringCellValue().getUnicodeString().getOptionFlags(), 0); - - File tempFile = TempFile.createTempFile("umlat", "test.xls"); - FileOutputStream stream = new FileOutputStream(tempFile); - wb.write(stream); - - wb = null; - FileInputStream in = new FileInputStream(tempFile); - wb = new HSSFWorkbook(in); - - //Test the sheetname - s = wb.getSheet("test"); - assertNotNull(s); - - c = r.getCell((short)1); - assertEquals(c.getRichStringCellValue().getString(), "\u00e4"); - } - -} +package org.apache.poi.hssf.usermodel; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileInputStream; + +import org.apache.poi.util.TempFile; + +import junit.framework.TestCase; + +public class TestUnicodeWorkbook extends TestCase { + + public TestUnicodeWorkbook(String s) { + super(s); + } + + /** Tests that all of the unicode capable string fields can be set, written and then read back + * + * + */ + public void testUnicodeInAll() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook(); + //Create a unicode dataformat (contains euro symbol) + HSSFDataFormat df = wb.createDataFormat(); + final String formatStr = "_([$\u20ac-2]\\\\\\ * #,##0.00_);_([$\u20ac-2]\\\\\\ * \\\\\\(#,##0.00\\\\\\);_([$\u20ac-2]\\\\\\ *\\\"\\-\\\\\"??_);_(@_)"; + short fmt = df.getFormat(formatStr); + + //Create a unicode sheet name (euro symbol) + HSSFSheet s = wb.createSheet("\u20ac"); + + //Set a unicode header (you guessed it the euro symbol) + HSSFHeader h = s.getHeader(); + h.setCenter("\u20ac"); + h.setLeft("\u20ac"); + h.setRight("\u20ac"); + + //Set a unicode footer + HSSFFooter f = s.getFooter(); + f.setCenter("\u20ac"); + f.setLeft("\u20ac"); + f.setRight("\u20ac"); + + HSSFRow r = s.createRow(0); + HSSFCell c = r.createCell((short)1); + c.setCellValue(12.34); + c.getCellStyle().setDataFormat(fmt); + + HSSFCell c2 = r.createCell((short)2); + c.setCellValue(new HSSFRichTextString("\u20ac")); + + HSSFCell c3 = r.createCell((short)3); + String formulaString = "TEXT(12.34,\"\u20ac###,##\")"; + c3.setCellFormula(formulaString); + + + File tempFile = TempFile.createTempFile("unicode", "test.xls"); + FileOutputStream stream = new FileOutputStream(tempFile); + wb.write(stream); + + wb = null; + FileInputStream in = new FileInputStream(tempFile); + wb = new HSSFWorkbook(in); + + //Test the sheetname + s = wb.getSheet("\u20ac"); + assertNotNull(s); + + //Test the header + h = s.getHeader(); + assertEquals(h.getCenter(), "\u20ac"); + assertEquals(h.getLeft(), "\u20ac"); + assertEquals(h.getRight(), "\u20ac"); + + //Test the footer + f = s.getFooter(); + assertEquals(f.getCenter(), "\u20ac"); + assertEquals(f.getLeft(), "\u20ac"); + assertEquals(f.getRight(), "\u20ac"); + + //Test the dataformat + r = s.getRow(0); + c = r.getCell((short)1); + df = wb.createDataFormat(); + assertEquals(formatStr, df.getFormat(c.getCellStyle().getDataFormat())); + + //Test the cell string value + c2 = r.getCell((short)2); + assertEquals(c.getRichStringCellValue().getString(), "\u20ac"); + + //Test the cell formula + c3 = r.getCell((short)3); + assertEquals(c3.getCellFormula(), formulaString); + } + + /** Tests Bug38230 + * That a Umlat is written and then read back. + * It should have been written as a compressed unicode. + * + * + * + */ + public void testUmlatReadWrite() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook(); + + //Create a unicode sheet name (euro symbol) + HSSFSheet s = wb.createSheet("test"); + + HSSFRow r = s.createRow(0); + HSSFCell c = r.createCell((short)1); + c.setCellValue(new HSSFRichTextString("\u00e4")); + + //Confirm that the sring will be compressed + assertEquals(c.getRichStringCellValue().getUnicodeString().getOptionFlags(), 0); + + File tempFile = TempFile.createTempFile("umlat", "test.xls"); + FileOutputStream stream = new FileOutputStream(tempFile); + wb.write(stream); + + wb = null; + FileInputStream in = new FileInputStream(tempFile); + wb = new HSSFWorkbook(in); + + //Test the sheetname + s = wb.getSheet("test"); + assertNotNull(s); + + c = r.getCell((short)1); + assertEquals(c.getRichStringCellValue().getString(), "\u00e4"); + } + +} diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPropertySorter.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPropertySorter.java index 7ddd2cca9d..2c5bc954b4 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPropertySorter.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPropertySorter.java @@ -1,152 +1,152 @@ - -/* ==================================================================== - 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.poifs.filesystem; - -import junit.framework.TestCase; -import junit.framework.ComparisonFailure; - -import java.io.*; -import java.util.*; - -import org.apache.poi.poifs.property.DirectoryProperty; -import org.apache.poi.poifs.property.Property; - -/** - * Verify the order of entries DirectoryProperty . - *

    - * In particular it is important to serialize ROOT._VBA_PROJECT_CUR.VBA node. - * See bug 39234 in bugzilla. Thanks to Bill Seddon for providing the solution. - *

    - * - * @author Yegor Kozlov - */ -public class TestPropertySorter extends TestCase { - - //the correct order of entries in the test file - protected static final String[] _entries = { - "dir", "JML", "UTIL", "Loader", "Sheet1", "Sheet2", "Sheet3", - "__SRP_0", "__SRP_1", "__SRP_2", "__SRP_3", "__SRP_4", "__SRP_5", - "ThisWorkbook", "_VBA_PROJECT", - }; - - protected File testFile; - - public void setUp(){ - String home = System.getProperty("HSSF.testdata.path"); - testFile = new File(home + "/39234.xls"); - } - - /** - * Test sorting of properties in DirectoryProperty - */ - public void testSortProperties() throws IOException { - InputStream is = new FileInputStream(testFile); - POIFSFileSystem fs = new POIFSFileSystem(is); - is.close(); - Property[] props = getVBAProperties(fs); - - assertEquals(_entries.length, props.length); - - // (1). See that there is a problem with the old case-sensitive property comparartor - Arrays.sort(props, new CaseSensitivePropertyComparator()); - try { - for (int i = 0; i < props.length; i++) { - assertEquals(_entries[i], props[i].getName()); - } - fail("case-sensitive property comparator returns properties in wrong order"); - } catch (ComparisonFailure e){ - ; // as expected - } - - // (2) Verify that the fixed proeprty comparator works right - Arrays.sort(props, new DirectoryProperty.PropertyComparator()); - for (int i = 0; i < props.length; i++) { - assertEquals(_entries[i], props[i].getName()); - } - } - - /** - * Serialize file system and verify that the order of properties is the same as in the original file. - */ - public void testSerialization() throws IOException { - InputStream is = new FileInputStream(testFile); - POIFSFileSystem fs = new POIFSFileSystem(is); - is.close(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - fs.writeFilesystem(out); - out.close(); - is = new ByteArrayInputStream(out.toByteArray()); - fs = new POIFSFileSystem(is); - is.close(); - Property[] props = getVBAProperties(fs); - Arrays.sort(props, new DirectoryProperty.PropertyComparator()); - - assertEquals(_entries.length, props.length); - for (int i = 0; i < props.length; i++) { - assertEquals(_entries[i], props[i].getName()); - } - } - - /** - * @return array of properties read from ROOT._VBA_PROJECT_CUR.VBA node - */ - protected Property[] getVBAProperties(POIFSFileSystem fs) throws IOException { - String _VBA_PROJECT_CUR = "_VBA_PROJECT_CUR"; - String VBA = "VBA"; - - DirectoryEntry root = fs.getRoot(); - DirectoryEntry vba_project = (DirectoryEntry)root.getEntry(_VBA_PROJECT_CUR); - - DirectoryNode vba = (DirectoryNode)vba_project.getEntry(VBA); - DirectoryProperty p = (DirectoryProperty)vba.getProperty(); - - ArrayList lst = new ArrayList(); - for (Iterator it = p.getChildren(); it.hasNext();){ - Property ch = (Property)it.next(); - lst.add(ch); - } - return (Property [])lst.toArray(new Property[ 0 ]); - } - - /** - * Old version of case-sensitive PropertyComparator to demonstrate the problem - */ - private class CaseSensitivePropertyComparator implements Comparator - { - - public boolean equals(Object o) - { - return this == o; - } - - public int compare(Object o1, Object o2) - { - String name1 = (( Property ) o1).getName(); - String name2 = (( Property ) o2).getName(); - int result = name1.length() - name2.length(); - - if (result == 0) - { - result = name1.compareTo(name2); - } - return result; - } - } - -} + +/* ==================================================================== + 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.poifs.filesystem; + +import junit.framework.TestCase; +import junit.framework.ComparisonFailure; + +import java.io.*; +import java.util.*; + +import org.apache.poi.poifs.property.DirectoryProperty; +import org.apache.poi.poifs.property.Property; + +/** + * Verify the order of entries DirectoryProperty . + *

    + * In particular it is important to serialize ROOT._VBA_PROJECT_CUR.VBA node. + * See bug 39234 in bugzilla. Thanks to Bill Seddon for providing the solution. + *

    + * + * @author Yegor Kozlov + */ +public class TestPropertySorter extends TestCase { + + //the correct order of entries in the test file + protected static final String[] _entries = { + "dir", "JML", "UTIL", "Loader", "Sheet1", "Sheet2", "Sheet3", + "__SRP_0", "__SRP_1", "__SRP_2", "__SRP_3", "__SRP_4", "__SRP_5", + "ThisWorkbook", "_VBA_PROJECT", + }; + + protected File testFile; + + public void setUp(){ + String home = System.getProperty("HSSF.testdata.path"); + testFile = new File(home + "/39234.xls"); + } + + /** + * Test sorting of properties in DirectoryProperty + */ + public void testSortProperties() throws IOException { + InputStream is = new FileInputStream(testFile); + POIFSFileSystem fs = new POIFSFileSystem(is); + is.close(); + Property[] props = getVBAProperties(fs); + + assertEquals(_entries.length, props.length); + + // (1). See that there is a problem with the old case-sensitive property comparartor + Arrays.sort(props, new CaseSensitivePropertyComparator()); + try { + for (int i = 0; i < props.length; i++) { + assertEquals(_entries[i], props[i].getName()); + } + fail("case-sensitive property comparator returns properties in wrong order"); + } catch (ComparisonFailure e){ + ; // as expected + } + + // (2) Verify that the fixed proeprty comparator works right + Arrays.sort(props, new DirectoryProperty.PropertyComparator()); + for (int i = 0; i < props.length; i++) { + assertEquals(_entries[i], props[i].getName()); + } + } + + /** + * Serialize file system and verify that the order of properties is the same as in the original file. + */ + public void testSerialization() throws IOException { + InputStream is = new FileInputStream(testFile); + POIFSFileSystem fs = new POIFSFileSystem(is); + is.close(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + fs.writeFilesystem(out); + out.close(); + is = new ByteArrayInputStream(out.toByteArray()); + fs = new POIFSFileSystem(is); + is.close(); + Property[] props = getVBAProperties(fs); + Arrays.sort(props, new DirectoryProperty.PropertyComparator()); + + assertEquals(_entries.length, props.length); + for (int i = 0; i < props.length; i++) { + assertEquals(_entries[i], props[i].getName()); + } + } + + /** + * @return array of properties read from ROOT._VBA_PROJECT_CUR.VBA node + */ + protected Property[] getVBAProperties(POIFSFileSystem fs) throws IOException { + String _VBA_PROJECT_CUR = "_VBA_PROJECT_CUR"; + String VBA = "VBA"; + + DirectoryEntry root = fs.getRoot(); + DirectoryEntry vba_project = (DirectoryEntry)root.getEntry(_VBA_PROJECT_CUR); + + DirectoryNode vba = (DirectoryNode)vba_project.getEntry(VBA); + DirectoryProperty p = (DirectoryProperty)vba.getProperty(); + + ArrayList lst = new ArrayList(); + for (Iterator it = p.getChildren(); it.hasNext();){ + Property ch = (Property)it.next(); + lst.add(ch); + } + return (Property [])lst.toArray(new Property[ 0 ]); + } + + /** + * Old version of case-sensitive PropertyComparator to demonstrate the problem + */ + private class CaseSensitivePropertyComparator implements Comparator + { + + public boolean equals(Object o) + { + return this == o; + } + + public int compare(Object o1, Object o2) + { + String name1 = (( Property ) o1).getName(); + String name2 = (( Property ) o2).getName(); + int result = name1.length() - name2.length(); + + if (result == 0) + { + result = name1.compareTo(name2); + } + return result; + } + } + +} -- 2.39.5