package org.apache.poi.ddf;
-import org.apache.poi.util.LittleEndian;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
/**
* Escher array properties are the most wierd construction ever invented
*
* @author Glen Stampoultzis (glens at superlinksoftware.com)
*/
-public final class EscherArrayProperty extends EscherComplexProperty {
+public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> {
/**
* The size of the header that goes at the
* start of the array, before the data
}
return sizeOfElements;
}
+
+ public Iterator<byte[]> iterator() {
+ return new Iterator<byte[]>(){
+ int idx = 0;
+ public boolean hasNext() {
+ return (idx < getNumberOfElementsInArray());
+ }
+
+ public byte[] next() {
+ if (!hasNext()) throw new NoSuchElementException();
+ return getElement(idx++);
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("not yet implemented");
+ }
+ };
+ }
+
+
}
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.ddf;\r
+\r
+import org.apache.poi.util.BitField;\r
+import org.apache.poi.util.LittleEndian;\r
+\r
+/**\r
+ * An OfficeArtCOLORREF structure entry which also handles color extension opid data\r
+ */\r
+public class EscherColorRef {\r
+ int opid = -1;\r
+ int colorRef = 0;\r
+\r
+ public enum SysIndexSource {\r
+ /** Use the fill color of the shape. */\r
+ FILL_COLOR(0xF0),\r
+ /** If the shape contains a line, use the line color of the shape. Otherwise, use the fill color. */\r
+ LINE_OR_FILL_COLOR(0xF1),\r
+ /** Use the line color of the shape. */\r
+ LINE_COLOR(0xF2),\r
+ /** Use the shadow color of the shape. */\r
+ SHADOW_COLOR(0xF3),\r
+ /** Use the current, or last-used, color. */\r
+ CURRENT_OR_LAST_COLOR(0xF4),\r
+ /** Use the fill background color of the shape. */\r
+ FILL_BACKGROUND_COLOR(0xF5),\r
+ /** Use the line background color of the shape. */\r
+ LINE_BACKGROUND_COLOR(0xF6),\r
+ /** If the shape contains a fill, use the fill color of the shape. Otherwise, use the line color. */\r
+ FILL_OR_LINE_COLOR(0xF7)\r
+ ;\r
+ int value;\r
+ SysIndexSource(int value) { this.value = value; }\r
+ }\r
+\r
+ /**\r
+ * The following enum specifies values that indicate special procedural properties that\r
+ * are used to modify the color components of another color. These values are combined with\r
+ * those of the {@link SysIndexSource} enum or with a user-specified color.\r
+ * The first six values are mutually exclusive.\r
+ */\r
+ public enum SysIndexProcedure {\r
+ /**\r
+ * Darken the color by the value that is specified in the blue field.\r
+ * A blue value of 0xFF specifies that the color is to be left unchanged,\r
+ * whereas a blue value of 0x00 specifies that the color is to be completely darkened.\r
+ */\r
+ DARKEN_COLOR(0x01),\r
+ /**\r
+ * Lighten the color by the value that is specified in the blue field.\r
+ * A blue value of 0xFF specifies that the color is to be left unchanged,\r
+ * whereas a blue value of 0x00 specifies that the color is to be completely lightened.\r
+ */\r
+ LIGHTEN_COLOR(0x02),\r
+ /**\r
+ * Add a gray level RGB value. The blue field contains the gray level to add:\r
+ * NewColor = SourceColor + gray\r
+ */\r
+ ADD_GRAY_LEVEL(0x03),\r
+ /**\r
+ * Subtract a gray level RGB value. The blue field contains the gray level to subtract:\r
+ * NewColor = SourceColor - gray\r
+ */\r
+ SUB_GRAY_LEVEL(0x04),\r
+ /**\r
+ * Reverse-subtract a gray level RGB value. The blue field contains the gray level from\r
+ * which to subtract:\r
+ * NewColor = gray - SourceColor\r
+ */\r
+ REVERSE_GRAY_LEVEL(0x05),\r
+ /**\r
+ * If the color component being modified is less than the parameter contained in the blue\r
+ * field, set it to the minimum intensity. If the color component being modified is greater\r
+ * than or equal to the parameter, set it to the maximum intensity.\r
+ */\r
+ THRESHOLD(0x06),\r
+ /**\r
+ * After making other modifications, invert the color.\r
+ * This enum value is only for documentation and won't be directly returned.\r
+ */\r
+ INVERT_AFTER(0x20),\r
+ /**\r
+ * After making other modifications, invert the color by toggling just the high bit of each\r
+ * color channel.\r
+ * This enum value is only for documentation and won't be directly returned.\r
+ */\r
+ INVERT_HIGHBIT_AFTER(0x40)\r
+ ;\r
+ BitField mask;\r
+ SysIndexProcedure(int mask) {\r
+ this.mask = new BitField(mask);\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * A bit that specifies whether the system color scheme will be used to determine the color. \r
+ * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index\r
+ * into the system color table. Values less than 0x00F0 map directly to system colors.\r
+ */\r
+ private static final BitField FLAG_SYS_INDEX = new BitField(0x10000000);\r
+\r
+ /**\r
+ * A bit that specifies whether the current application-defined color scheme will be used\r
+ * to determine the color. A value of 0x1 specifies that red will be treated as an index\r
+ * into the current color scheme table. If this value is 0x1, green and blue MUST be 0x00.\r
+ */\r
+ private static final BitField FLAG_SCHEME_INDEX = new BitField(0x08000000);\r
+ \r
+ /**\r
+ * A bit that specifies whether the color is a standard RGB color.\r
+ * 0x0 : The RGB color MAY use halftone dithering to display.\r
+ * 0x1 : The color MUST be a solid color.\r
+ */\r
+ private static final BitField FLAG_SYSTEM_RGB = new BitField(0x04000000);\r
+ \r
+ /**\r
+ * A bit that specifies whether the current palette will be used to determine the color.\r
+ * A value of 0x1 specifies that red, green, and blue contain an RGB value that will be\r
+ * matched in the current color palette. This color MUST be solid.\r
+ */\r
+ private static final BitField FLAG_PALETTE_RGB = new BitField(0x02000000);\r
+\r
+ /**\r
+ * A bit that specifies whether the current palette will be used to determine the color.\r
+ * A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index into \r
+ * the current color palette. This color MAY be dithered. If this value is 0x1, blue MUST be 0x00.\r
+ */\r
+ private static final BitField FLAG_PALETTE_INDEX = new BitField(0x01000000);\r
+ \r
+ /**\r
+ * An unsigned integer that specifies the intensity of the blue color channel. A value\r
+ * of 0x00 has the minimum blue intensity. A value of 0xFF has the maximum blue intensity.\r
+ */\r
+ private static final BitField FLAG_BLUE = new BitField(0x00FF0000);\r
+ \r
+ /**\r
+ * An unsigned integer that specifies the intensity of the green color channel. A value\r
+ * of 0x00 has the minimum green intensity. A value of 0xFF has the maximum green intensity.\r
+ */\r
+ private static final BitField FLAG_GREEN = new BitField(0x0000FF00);\r
+ \r
+ /**\r
+ * An unsigned integer that specifies the intensity of the red color channel. A value\r
+ * of 0x00 has the minimum red intensity. A value of 0xFF has the maximum red intensity.\r
+ */\r
+ private static final BitField FLAG_RED = new BitField(0x000000FF);\r
+ \r
+ public EscherColorRef(int colorRef) {\r
+ this.colorRef = colorRef;\r
+ }\r
+ \r
+ public EscherColorRef(byte[] source, int start, int len) {\r
+ assert(len == 4 || len == 6);\r
+ \r
+ int offset = start;\r
+ if (len == 6) {\r
+ opid = LittleEndian.getUShort(source, offset);\r
+ offset += 2;\r
+ }\r
+ colorRef = LittleEndian.getInt(source, offset);\r
+ }\r
+ \r
+ public boolean hasSysIndexFlag() {\r
+ return FLAG_SYS_INDEX.isSet(colorRef);\r
+ }\r
+ \r
+ public void setSysIndexFlag(boolean flag) {\r
+ FLAG_SYS_INDEX.setBoolean(colorRef, flag);\r
+ }\r
+ \r
+ public boolean hasSchemeIndexFlag() {\r
+ return FLAG_SCHEME_INDEX.isSet(colorRef);\r
+ }\r
+ \r
+ public void setSchemeIndexFlag(boolean flag) {\r
+ FLAG_SCHEME_INDEX.setBoolean(colorRef, flag);\r
+ }\r
+ \r
+ public boolean hasSystemRGBFlag() {\r
+ return FLAG_SYSTEM_RGB.isSet(colorRef);\r
+ }\r
+ \r
+ public void setSystemRGBFlag(boolean flag) {\r
+ FLAG_SYSTEM_RGB.setBoolean(colorRef, flag);\r
+ }\r
+ \r
+ public boolean hasPaletteRGBFlag() {\r
+ return FLAG_PALETTE_RGB.isSet(colorRef);\r
+ }\r
+ \r
+ public void setPaletteRGBFlag(boolean flag) {\r
+ FLAG_PALETTE_RGB.setBoolean(colorRef, flag);\r
+ }\r
+ \r
+ public boolean hasPaletteIndexFlag() {\r
+ return FLAG_PALETTE_INDEX.isSet(colorRef);\r
+ }\r
+ \r
+ public void setPaletteIndexFlag(boolean flag) {\r
+ FLAG_PALETTE_INDEX.setBoolean(colorRef, flag);\r
+ }\r
+\r
+ public int[] getRGB() {\r
+ int rgb[] = {\r
+ FLAG_RED.getValue(colorRef),\r
+ FLAG_GREEN.getValue(colorRef),\r
+ FLAG_BLUE.getValue(colorRef)\r
+ };\r
+ return rgb;\r
+ }\r
+ \r
+ /**\r
+ * @return {@link SysIndexSource} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null\r
+ */\r
+ public SysIndexSource getSysIndexSource() {\r
+ if (!hasSysIndexFlag()) return null;\r
+ int val = FLAG_RED.getValue(colorRef);\r
+ for (SysIndexSource sis : SysIndexSource.values()) {\r
+ if (sis.value == val) return sis;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ /**\r
+ * Return the {@link SysIndexProcedure} - for invert flag use {@link #getSysIndexInvert()}\r
+ * @return {@link SysIndexProcedure} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null\r
+ */\r
+ public SysIndexProcedure getSysIndexProcedure() {\r
+ if (!hasSysIndexFlag()) return null;\r
+ int val = FLAG_RED.getValue(colorRef);\r
+ for (SysIndexProcedure sip : SysIndexProcedure.values()) {\r
+ if (sip == SysIndexProcedure.INVERT_AFTER || sip == SysIndexProcedure.INVERT_HIGHBIT_AFTER) continue;\r
+ if (sip.mask.isSet(val)) return sip;\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ /**\r
+ * @return 0 for no invert flag, 1 for {@link SysIndexProcedure#INVERT_AFTER} and\r
+ * 2 for {@link SysIndexProcedure#INVERT_HIGHBIT_AFTER} \r
+ */\r
+ public int getSysIndexInvert() {\r
+ if (!hasSysIndexFlag()) return 0;\r
+ int val = FLAG_GREEN.getValue(colorRef);\r
+ if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) return 1;\r
+ if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) return 2;\r
+ return 0;\r
+ }\r
+ \r
+ /**\r
+ * @return index of the scheme color or -1 if {@link #hasSchemeIndexFlag()} is {@code false}\r
+ * \r
+ * @see org.apache.poi.hslf.record.ColorSchemeAtom#getColor(int)\r
+ */\r
+ public int getSchemeIndex() {\r
+ if (!hasSchemeIndexFlag()) return -1;\r
+ return FLAG_RED.getValue(colorRef);\r
+ }\r
+ \r
+ /**\r
+ * @return index of current palette (color) or -1 if {@link #hasPaletteIndexFlag()} is {@code false}\r
+ */\r
+ public int getPaletteIndex() {\r
+ if (!hasPaletteIndexFlag()) return -1;\r
+ return (FLAG_GREEN.getValue(colorRef) << 8) & FLAG_RED.getValue(colorRef);\r
+ }\r
+}\r
public static double toPoints(long emu){\r
return (double)emu/EMU_PER_POINT;\r
}\r
+ \r
+ /**\r
+ * Converts a value of type FixedPoint to a decimal number\r
+ *\r
+ * @param fixedPoint\r
+ * @return decimal number\r
+ * \r
+ * @see <a href="http://msdn.microsoft.com/en-us/library/dd910765(v=office.12).aspx">[MS-OSHARED] - 2.2.1.6 FixedPoint</a>\r
+ */\r
+ public static double fixedPointToDecimal(int fixedPoint) {\r
+ int i = (fixedPoint >> 16);\r
+ int f = (fixedPoint >> 0) & 0xFFFF;\r
+ double decimal = (i + f/65536.0);\r
+ return decimal;\r
+ }\r
}\r
public int getControlIndex(){
int idx = -1;
- OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
+ OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
if(oe != null) idx = oe.getOptions();
return idx;
}
package org.apache.poi.hslf.model;
-import org.apache.poi.ddf.*;
-import org.apache.poi.hslf.record.*;
+import java.awt.Color;
+import java.util.List;
+
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.usermodel.PictureData;
import org.apache.poi.hslf.usermodel.SlideShow;
-import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
-import java.util.List;
-
-import java.awt.*;
+import org.apache.poi.util.POILogger;
/**
* Represents functionality provided by the 'Fill Effects' dialog in PowerPoint.
* @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);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty prop = Shape.getEscherProperty(opt, EscherProperties.FILL__FILLTYPE);
return prop == null ? FILL_SOLID : prop.getPropertyValue();
}
/**
*/
protected void afterInsert(Sheet sh){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
- EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if(p != null) {
int idx = p.getPropertyValue();
EscherBSERecord bse = getEscherBSERecord(idx);
SlideShow ppt = sheet.getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
if(bstore == null) {
logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
return null;
}
- List lst = bstore.getChildRecords();
+ List<EscherRecord> lst = bstore.getChildRecords();
return (EscherBSERecord)lst.get(idx-1);
}
* @param type type of the fill
*/
public void setFillType(int type){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
+ EscherOptRecord opt = shape.getEscherOptRecord();
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLTYPE, type);
}
* Foreground color
*/
public Color getForegroundColor(){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
- EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
* Foreground color
*/
public void setForegroundColor(Color color){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
+ EscherOptRecord opt = shape.getEscherOptRecord();
if (color == null) {
Shape.setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150000);
}
* Background color
*/
public Color getBackgroundColor(){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
- EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST);
if(p != null && (p.getPropertyValue() & 0x10) == 0) return null;
* Background color
*/
public void setBackgroundColor(Color color){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
+ EscherOptRecord opt = shape.getEscherOptRecord();
if (color == null) {
Shape.setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, -1);
}
* <code>PictureData</code> 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);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if (p == null) return null;
SlideShow ppt = shape.getSheet().getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
java.util.List<EscherRecord> lst = bstore.getChildRecords();
int idx = p.getPropertyValue();
* @param idx 0-based index of the picture added to this ppt by <code>SlideShow.addPicture</code> method.
*/
public void setPictureData(int idx){
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
+ EscherOptRecord opt = shape.getEscherOptRecord();
Shape.setEscherProperty(opt, (short)(EscherProperties.FILL__PATTERNTEXTURE + 0x4000), idx);
if( idx != 0 ) {
if( shape.getSheet() != null ) {
EscherOptRecord opt = getEscherOptRecord();
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 0x4));
- EscherArrayProperty verticesProp = (EscherArrayProperty)getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__VERTICES + 0x4000));
- if(verticesProp == null) verticesProp = (EscherArrayProperty)getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
+ EscherArrayProperty verticesProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__VERTICES + 0x4000));
+ if(verticesProp == null) verticesProp = getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
- EscherArrayProperty segmentsProp = (EscherArrayProperty)getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000));
- if(segmentsProp == null) segmentsProp = (EscherArrayProperty)getEscherProperty(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
+ EscherArrayProperty segmentsProp = getEscherProperty(opt, (short)(EscherProperties.GEOMETRY__SEGMENTINFO + 0x4000));
+ if(segmentsProp == null) segmentsProp = getEscherProperty(opt, EscherProperties.GEOMETRY__SEGMENTINFO);
//sanity check
if(verticesProp == null) {
* @param idx the index of the movie
*/
public void setMovieIndex(int idx){
- OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
+ OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
oe.setOptions(idx);
- AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
+ AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if(an != null) {
AnimationInfoAtom ai = an.getAnimationInfoAtom();
ai.setDimColor(0x07000000);
}
public void setAutoPlay(boolean flag){
- AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
+ AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if(an != null){
an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag);
updateClientData();
}
public boolean isAutoPlay(){
- AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID);
+ AnimationInfo an = getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if(an != null){
return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic);
}
* @return UNC or local path to a video file
*/
public String getPath(){
- OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
+ OEShapeAtom oe = getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
int idx = oe.getOptions();
SlideShow ppt = getSheet().getSlideShow();
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;
+import org.apache.poi.util.Units;
/**
*/
public int getPictureIndex(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPTODISPLAY);
return prop == null ? 0 : prop.getPropertyValue();
}
SlideShow ppt = getSheet().getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
if(bstore == null) {
logger.log(POILogger.DEBUG, "EscherContainerRecord.BSTORE_CONTAINER was not found ");
return null;
*/
public String getPictureName(){
EscherOptRecord opt = getEscherOptRecord();
- EscherComplexProperty prop = (EscherComplexProperty)getEscherProperty(opt, EscherProperties.BLIP__BLIPFILENAME);
+ EscherComplexProperty prop = getEscherProperty(opt, EscherProperties.BLIP__BLIPFILENAME);
if (prop == null) return null;
String name = StringUtil.getFromUnicodeLE(prop.getComplexData());
return name.trim();
/**
* @return the fractional property or 0 if not defined
- *
- * @see <a href="http://msdn.microsoft.com/en-us/library/dd910765(v=office.12).aspx">2.2.1.6 FixedPoint</a>
*/
private static double getFractProp(EscherOptRecord opt, short propertyId) {
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, propertyId);
+ EscherSimpleProperty prop = getEscherProperty(opt, propertyId);
if (prop == null) return 0;
int fixedPoint = prop.getPropertyValue();
- int i = (fixedPoint >> 16);
- int f = (fixedPoint >> 0) & 0xFFFF;
- double fp = i + f/65536.0;
- return fp;
+ return Units.fixedPointToDecimal(fixedPoint);
}
}
\ No newline at end of file
import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.Units;
import java.util.*;
import java.awt.*;
* @see org.apache.poi.hslf.record.RecordTypes
*/
public int getShapeType(){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
return spRecord.getShapeType();
}
* @see org.apache.poi.hslf.record.RecordTypes
*/
public void setShapeType(int type){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
spRecord.setShapeType( (short) type );
spRecord.setVersion( (short) 0x2 );
}
* @return the anchor of this shape
*/
public Rectangle2D getAnchor2D(){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
Rectangle2D anchor=null;
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
- EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
+ EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
if(rec == null){
logger.log(POILogger.WARN, "EscherSpRecord.FLAG_CHILD is set but EscherChildAnchorRecord was not found");
- EscherClientAnchorRecord clrec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
+ EscherClientAnchorRecord clrec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
anchor = new Rectangle2D.Float(
(float)clrec.getCol1()*POINT_DPI/MASTER_DPI,
}
}
else {
- EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
+ EscherClientAnchorRecord rec = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
anchor = new java.awt.Rectangle();
anchor = new Rectangle2D.Float(
(float)rec.getCol1()*POINT_DPI/MASTER_DPI,
* @param anchor new anchor
*/
public void setAnchor(Rectangle2D anchor){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
- EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
+ EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(EscherChildAnchorRecord.RECORD_ID);
rec.setDx1((int)(anchor.getX()*MASTER_DPI/POINT_DPI));
rec.setDy1((int)(anchor.getY()*MASTER_DPI/POINT_DPI));
rec.setDx2((int)((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI));
rec.setDy2((int)((anchor.getHeight() + anchor.getY())*MASTER_DPI/POINT_DPI));
}
else {
- EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
+ EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(EscherClientAnchorRecord.RECORD_ID);
rec.setFlag((short)(anchor.getY()*MASTER_DPI/POINT_DPI));
rec.setCol1((short)(anchor.getX()*MASTER_DPI/POINT_DPI));
rec.setDx1((short)(((anchor.getWidth() + anchor.getX())*MASTER_DPI/POINT_DPI)));
*
* @return escher record or <code>null</code> if not found.
*/
- public static EscherRecord getEscherChild(EscherContainerRecord owner, int recordId){
- for ( Iterator<EscherRecord> iterator = owner.getChildIterator(); iterator.hasNext(); )
- {
- EscherRecord escherRecord = iterator.next();
- if (escherRecord.getRecordId() == recordId)
- return escherRecord;
- }
- return null;
+ public static <T extends EscherRecord> T getEscherChild(EscherContainerRecord owner, int recordId){
+ return owner.getChildById((short)recordId);
}
+ public <T extends EscherRecord> T getEscherChild(int recordId){
+ return _escherContainer.getChildById((short)recordId);
+ }
+
/**
* Returns escher property by id.
*
* @return escher property or <code>null</code> if not found.
*/
- public static EscherProperty getEscherProperty(EscherOptRecord opt, int propId){
- if(opt != null) for ( Iterator iterator = opt.getEscherProperties().iterator(); iterator.hasNext(); )
- {
- EscherProperty prop = (EscherProperty) iterator.next();
- if (prop.getPropertyNumber() == propId)
- return prop;
- }
- return null;
+ public static <T extends EscherProperty> T getEscherProperty(EscherOptRecord opt, int propId){
+ return opt.lookup(propId);
}
/**
* @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){
+ java.util.List<EscherProperty> props = opt.getEscherProperties();
+ for ( Iterator<EscherProperty> iterator = props.iterator(); iterator.hasNext(); ) {
+ if (iterator.next().getPropertyNumber() == propId){
iterator.remove();
+ break;
}
}
if (value != -1) {
*/
public int getEscherProperty(short propId){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, propId);
+ EscherSimpleProperty prop = getEscherProperty(opt, propId);
return prop == null ? 0 : prop.getPropertyValue();
}
*/
public int getEscherProperty(short propId, int defaultValue){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, propId);
+ EscherSimpleProperty prop = getEscherProperty(opt, propId);
return prop == null ? defaultValue : prop.getPropertyValue();
}
Color getColor(short colorProperty, short opacityProperty, int defaultColor){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty p = (EscherSimpleProperty)getEscherProperty(opt, colorProperty);
+ EscherSimpleProperty p = getEscherProperty(opt, colorProperty);
if(p == null && defaultColor == -1) return null;
- int val = p == null ? defaultColor : p.getPropertyValue();
-
- int a = (val >> 24) & 0xFF;
- int b = (val >> 16) & 0xFF;
- int g = (val >> 8) & 0xFF;
- int r = (val >> 0) & 0xFF;
+ int val = (p == null) ? defaultColor : p.getPropertyValue();
- boolean fPaletteIndex = (a & 1) != 0;
- boolean fPaletteRGB = (a & (1 << 1)) != 0;
- boolean fSystemRGB = (a & (1 << 2)) != 0;
- boolean fSchemeIndex = (a & (1 << 3)) != 0;
- boolean fSysIndex = (a & (1 << 4)) != 0;
+ EscherColorRef ecr = new EscherColorRef(val);
+
+ boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
+ boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
+ boolean fSystemRGB = ecr.hasSystemRGBFlag();
+ boolean fSchemeIndex = ecr.hasSchemeIndexFlag();
+ boolean fSysIndex = ecr.hasSysIndexFlag();
+
+ int rgb[] = ecr.getRGB();
Sheet sheet = getSheet();
- if (fSchemeIndex && sheet != null)
- {
+ if (fSchemeIndex && sheet != null) {
//red is the index to the color scheme
ColorSchemeAtom ca = sheet.getColorScheme();
- int schemeColor = ca.getColor(r);
+ int schemeColor = ca.getColor(ecr.getSchemeIndex());
- r = (schemeColor >> 0) & 0xFF;
- g = (schemeColor >> 8) & 0xFF;
- b = (schemeColor >> 16) & 0xFF;
+ rgb[0] = (schemeColor >> 0) & 0xFF;
+ rgb[1] = (schemeColor >> 8) & 0xFF;
+ rgb[2] = (schemeColor >> 16) & 0xFF;
} else if (fPaletteIndex){
//TODO
} else if (fPaletteRGB){
//TODO
}
- EscherSimpleProperty op = (EscherSimpleProperty)getEscherProperty(opt, opacityProperty);
+ EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
int defaultOpacity = 0x00010000;
- int opacity = op == null ? defaultOpacity : op.getPropertyValue();
- int i = (opacity >> 16);
- int f = (opacity >> 0) & 0xFFFF ;
- double alpha = (i + f/65536.0)*255;
- return new Color(r, g, b, (int)alpha);
+ int opacity = (op == null) ? defaultOpacity : op.getPropertyValue();
+ double alpha = Units.fixedPointToDecimal(opacity)*255.0;
+ return new Color(rgb[0], rgb[1], rgb[2], (int)alpha);
}
Color toRGB(int val){
* @return id for the shape.
*/
public int getShapeId(){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
return spRecord == null ? 0 : spRecord.getShapeId();
}
* @param id of the shape
*/
public void setShapeId(int id){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
if(spRecord != null) spRecord.setShapeId(id);
}
return getLogicalAnchor2D();
}
- protected EscherOptRecord getEscherOptRecord() {
- return (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+ public EscherOptRecord getEscherOptRecord() {
+ return getEscherChild(EscherOptRecord.RECORD_ID);
+ }
+
+ /**
+ * Whether the shape is horizontally flipped
+ *
+ * @return whether the shape is horizontally flipped
+ */
+ public boolean getFlipHorizontal(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
+ }
+
+ /**
+ * Whether the shape is vertically flipped
+ *
+ * @return whether the shape is vertically flipped
+ */
+ public boolean getFlipVertical(){
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
+ return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
+ }
+
+ /**
+ * Rotation angle in degrees
+ *
+ * @return rotation angle in degrees
+ */
+ public int getRotation(){
+ int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
+ int angle = (rot >> 16) % 360;
+
+ return angle;
+ }
+
+ /**
+ * Rotate this shape
+ *
+ * @param theta the rotation angle in degrees
+ */
+ public void setRotation(int theta){
+ setEscherProperty(EscherProperties.TRANSFORM__ROTATION, (theta << 16));
}
}
if(opt != null){
try {
EscherPropertyFactory f = new EscherPropertyFactory();
- List props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
+ List<EscherProperty> props = f.createProperties( opt.serialize(), 8, opt.getInstance() );
EscherSimpleProperty p = (EscherSimpleProperty)props.get(0);
if(p.getPropertyNumber() == 0x39F && p.getPropertyValue() == 1){
group = new Table(spContainer, parent);
break;
case ShapeTypes.HostControl:
case ShapeTypes.PictureFrame: {
- InteractiveInfo info = (InteractiveInfo)getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
- OEShapeAtom oes = (OEShapeAtom)getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
+ InteractiveInfo info = getClientDataRecord(spContainer, RecordTypes.InteractiveInfo.typeID);
+ OEShapeAtom oes = getClientDataRecord(spContainer, RecordTypes.OEShapeAtom.typeID);
if(info != null && info.getInteractiveInfoAtom() != null){
switch(info.getInteractiveInfoAtom().getAction()){
case InteractiveInfoAtom.ACTION_OLE:
shape = new Line(spContainer, parent);
break;
case ShapeTypes.NotPrimitive: {
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
+ EscherOptRecord opt = Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.GEOMETRY__VERTICES);
if(prop != null)
shape = new Freeform(spContainer, parent);
}
- protected static Record getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
+ @SuppressWarnings("unchecked")
+ protected static <T extends Record> T getClientDataRecord(EscherContainerRecord spContainer, int recordType) {
Record oep = null;
for (Iterator<EscherRecord> it = spContainer.getChildIterator(); it.hasNext();) {
EscherRecord obj = it.next();
Record[] records = Record.findChildRecords(data, 8, data.length - 8);
for (int j = 0; j < records.length; j++) {
if (records[j].getRecordType() == recordType) {
- return records[j];
+ return (T)records[j];
}
}
}
}
- return oep;
+ return (T)oep;
}
}
*/
public void setAnchor(java.awt.Rectangle anchor){
- EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChild(0);
-
- EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID);
+ EscherClientAnchorRecord clientAnchor = getEscherChild(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];
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);
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
spgr.setRectX1(anchor.x*MASTER_DPI/POINT_DPI);
spgr.setRectY1(anchor.y*MASTER_DPI/POINT_DPI);
* @param anchor the coordinate space of this group
*/
public void setCoordinates(Rectangle2D anchor){
- EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChild(0);
- EscherSpgrRecord spgr = (EscherSpgrRecord)getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID);
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
int x1 = (int)Math.round(anchor.getX()*MASTER_DPI/POINT_DPI);
int y1 = (int)Math.round(anchor.getY()*MASTER_DPI/POINT_DPI);
* @return the coordinate space of this group
*/
public Rectangle2D getCoordinates(){
- EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChild(0);
- EscherSpgrRecord spgr = (EscherSpgrRecord)getEscherChild(spContainer, EscherSpgrRecord.RECORD_ID);
+ EscherSpgrRecord spgr = getEscherChild(EscherSpgrRecord.RECORD_ID);
Rectangle2D.Float anchor = new Rectangle2D.Float();
anchor.x = (float)spgr.getRectX1()*POINT_DPI/MASTER_DPI;
* @return the anchor of this shape group
*/
public Rectangle2D getAnchor2D(){
- EscherContainerRecord spContainer = (EscherContainerRecord)_escherContainer.getChild(0);
- EscherClientAnchorRecord clientAnchor = (EscherClientAnchorRecord)getEscherChild(spContainer, EscherClientAnchorRecord.RECORD_ID);
+ EscherClientAnchorRecord clientAnchor = getEscherChild(EscherClientAnchorRecord.RECORD_ID);
Rectangle2D.Float anchor = new Rectangle2D.Float();
if(clientAnchor == null){
logger.log(POILogger.INFO, "EscherClientAnchorRecord was not found for shape group. Searching for EscherChildAnchorRecord.");
- EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(spContainer, EscherChildAnchorRecord.RECORD_ID);
+ EscherChildAnchorRecord rec = getEscherChild(EscherChildAnchorRecord.RECORD_ID);
anchor = new Rectangle2D.Float(
(float)rec.getDx1()*POINT_DPI/MASTER_DPI,
(float)rec.getDy1()*POINT_DPI/MASTER_DPI,
* @return type of the shape.
*/
public int getShapeType(){
- EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
- EscherSpRecord spRecord = groupInfoContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
return spRecord.getOptions() >> 4;
}
graphics.setTransform(at);
}
+
+ @Override
+ public <T extends EscherRecord> T getEscherChild(int recordId){
+ EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
+ return groupInfoContainer.getChildById((short)recordId);
+ }
}
placeholderId = oep.getPlaceholderId();
} else {
//special case for files saved in Office 2007
- RoundTripHFPlaceholder12 hldr = (RoundTripHFPlaceholder12)tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
+ RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
if(hldr != null) placeholderId = hldr.getPlaceholderId();
}
if(placeholderId == type){
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
-import java.util.List;
-import org.apache.poi.ddf.*;
+import org.apache.poi.ddf.DefaultEscherRecordFactory;
+import org.apache.poi.ddf.EscherChildAnchorRecord;
+import org.apache.poi.ddf.EscherClientAnchorRecord;
+import org.apache.poi.ddf.EscherClientDataRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.hslf.record.InteractiveInfo;
*/
public double getLineWidth(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
double width = prop == null ? DEFAULT_LINE_WIDTH : (double)prop.getPropertyValue()/EMU_PER_POINT;
return width;
}
public Color getLineColor(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty p = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
+ EscherSimpleProperty p = getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
if(p != null && (p.getPropertyValue() & 0x8) == 0) return null;
Color clr = getColor(EscherProperties.LINESTYLE__COLOR, EscherProperties.LINESTYLE__OPACITY, -1);
public int getLineDashing(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINEDASHING);
return prop == null ? Line.PEN_SOLID : prop.getPropertyValue();
}
*/
public int getLineStyle(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.LINESTYLE__LINESTYLE);
return prop == null ? Line.LINE_SIMPLE : prop.getPropertyValue();
}
getFill().setForegroundColor(color);
}
- /**
- * Whether the shape is horizontally flipped
- *
- * @return whether the shape is horizontally flipped
- */
- public boolean getFlipHorizontal(){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
- return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPHORIZ) != 0;
- }
-
- /**
- * Whether the shape is vertically flipped
- *
- * @return whether the shape is vertically flipped
- */
- public boolean getFlipVertical(){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
- return (spRecord.getFlags()& EscherSpRecord.FLAG_FLIPVERT) != 0;
- }
-
- /**
- * Rotation angle in degrees
- *
- * @return rotation angle in degrees
- */
- public int getRotation(){
- int rot = getEscherProperty(EscherProperties.TRANSFORM__ROTATION);
- int angle = (rot >> 16) % 360;
-
- return angle;
- }
-
- /**
- * Rotate this shape
- *
- * @param theta the rotation angle in degrees
- */
- public void setRotation(int theta){
- setEscherProperty(EscherProperties.TRANSFORM__ROTATION, (theta << 16));
- }
-
/**
*
* @return 'absolute' anchor of this shape relative to the parent sheet
//if it is a groupped shape see if we need to transform the coordinates
if (_parent != null){
- List<Shape> lst = new ArrayList<Shape>();
- lst.add(_parent);
- Shape top = _parent;
- while(top.getParent() != null) {
- top = top.getParent();
- lst.add(top);
+ ArrayList<ShapeGroup> lst = new ArrayList<ShapeGroup>();
+ for (Shape top=this; (top = top.getParent()) != null; ) {
+ lst.add(0, (ShapeGroup)top);
}
AffineTransform tx = new AffineTransform();
- for(int i = lst.size() - 1; i >= 0; i--) {
- ShapeGroup prnt = (ShapeGroup)lst.get(i);
+ for(ShapeGroup prnt : lst) {
Rectangle2D exterior = prnt.getAnchor2D();
Rectangle2D interior = prnt.getCoordinates();
tx.translate(exterior.getX(), exterior.getY());
tx.scale(scaleX, scaleY);
tx.translate(-interior.getX(), -interior.getY());
+
}
anchor = tx.createTransformedShape(anchor).getBounds2D();
}
*
* @param recordType type of the record to search
*/
- protected Record getClientDataRecord(int recordType) {
+ @SuppressWarnings("unchecked")
+ protected <T extends Record> T getClientDataRecord(int recordType) {
Record[] records = getClientRecords();
if(records != null) for (int i = 0; i < records.length; i++) {
if(records[i].getRecordType() == recordType){
- return records[i];
+ return (T)records[i];
}
}
return null;
*/
protected Record[] getClientRecords() {
if(_clientData == null){
- EscherRecord r = Shape.getEscherChild(getSpContainer(), EscherClientDataRecord.RECORD_ID);
+ EscherRecord r = getEscherChild(EscherClientDataRecord.RECORD_ID);
//ddf can return EscherContainerRecord with recordId=EscherClientDataRecord.RECORD_ID
//convert in to EscherClientDataRecord on the fly
if(r != null && !(r instanceof EscherClientDataRecord)){
// Grab text from SlideListWithTexts entries
int i=0;
for(i=0; i<textRuns.size(); i++) {
- _runs[i] = (TextRun)textRuns.get(i);
+ _runs[i] = textRuns.get(i);
_runs[i].setSheet(this);
}
// Grab text from slide's PPDrawing
protected EscherTextboxWrapper getEscherTextboxWrapper(){
if(_txtbox == null){
- EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
+ EscherTextboxRecord textRecord = getEscherChild(EscherTextboxRecord.RECORD_ID);
if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
}
return _txtbox;
*/
public int getVerticalAlignment(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
int valign = TextShape.AnchorTop;
if (prop == null){
/**
*/
public float getMarginBottom(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
return (float)val/EMU_PER_POINT;
}
*/
public float getMarginLeft(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT);
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
return (float)val/EMU_PER_POINT;
}
*/
public float getMarginRight(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
return (float)val/EMU_PER_POINT;
}
*/
public float getMarginTop(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
return (float)val/EMU_PER_POINT;
}
*/
public int getWordWrap(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
return prop == null ? WrapSquare : prop.getPropertyValue();
}
*/
public int getTextId(){
EscherOptRecord opt = getEscherOptRecord();
- EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
+ EscherSimpleProperty prop = getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
return prop == null ? 0 : prop.getPropertyValue();
}
logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
}
} else {
- EscherSpRecord escherSpRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ EscherSpRecord escherSpRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int shapeId = escherSpRecord.getShapeId();
if(runs != null) for (int i = 0; i < runs.length; i++) {
if(runs[i].getShapeId() == shapeId){
* @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
*/
public OEPlaceholderAtom getPlaceholderAtom(){
- return (OEPlaceholderAtom)getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
+ return getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
}
/**
package org.apache.poi.hslf.model;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-import java.io.*;
-import java.awt.*;
+import java.awt.Color;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.util.List;
-import org.apache.poi.ddf.*;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.usermodel.SlideShow;
-import org.apache.poi.hslf.HSLFSlideShow;
-import org.apache.poi.POIDataSamples;
+import org.junit.Test;
/**
*
* @author Yegor Kozlov
*/
-public final class TestBackground extends TestCase {
+public final class TestBackground {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
/**
* Default background for slide, shape and slide master.
*/
- public void testDefaults() {
+ @Test
+ public void defaults() {
SlideShow ppt = new SlideShow();
assertEquals(Fill.FILL_SOLID, ppt.getSlidesMasters()[0].getBackground().getFill().getFillType());
/**
* Read fill information from an reference ppt file
*/
- public void testReadBackground() throws Exception {
+ @Test
+ public void readBackground() throws Exception {
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("backgrounds.ppt"));
Fill fill;
Shape shape;
/**
* Create a ppt with various fill effects
*/
- public void testBackgroundPicture() throws Exception {
+ @Test
+ public void backgroundPicture() throws Exception {
SlideShow ppt = new SlideShow();
Slide slide;
Fill fill;
}
private int getFillPictureRefCount(Shape shape, Fill fill) {
- EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(shape.getSpContainer(), EscherOptRecord.RECORD_ID);
- EscherSimpleProperty p = (EscherSimpleProperty)Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
+ EscherOptRecord opt = shape.getEscherOptRecord();
+ EscherSimpleProperty p = Shape.getEscherProperty(opt, EscherProperties.FILL__PATTERNTEXTURE);
if(p != null) {
int idx = p.getPropertyValue();
SlideShow ppt = sheet.getSlideShow();
Document doc = ppt.getDocumentRecord();
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
- EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
- List lst = bstore.getChildRecords();
+ EscherContainerRecord bstore = Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
+ List<EscherRecord> lst = bstore.getChildRecords();
return ((EscherBSERecord)lst.get(idx-1)).getRef();
}
return 0;
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 org.apache.poi.ddf.*;
-import org.apache.poi.POIDataSamples;
-
-import java.awt.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Color;
+import java.awt.Dimension;
import java.awt.Rectangle;
-import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherDggRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
+import org.apache.poi.ddf.EscherSimpleProperty;
+import org.apache.poi.hslf.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.RichTextRun;
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.junit.Before;
+import org.junit.Test;
+
/**
* Test drawing shapes via Graphics2D
*
* @author Yegor Kozlov
*/
-public final class TestShapes extends TestCase {
+public final class TestShapes {
private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
private SlideShow ppt;
private SlideShow pptB;
- protected void setUp() throws Exception {
- ppt = new SlideShow(_slTests.openResourceAsStream("empty.ppt"));
-
- pptB = new SlideShow(_slTests.openResourceAsStream("empty_textbox.ppt"));
+ @Before
+ public void setUp() throws Exception {
+ InputStream is1 = null, is2 = null;
+ try {
+ is1 = _slTests.openResourceAsStream("empty.ppt");
+ ppt = new SlideShow(is1);
+ is2 = _slTests.openResourceAsStream("empty_textbox.ppt");
+ pptB = new SlideShow(is2);
+ } finally {
+ is1.close();
+ is2.close();
+ }
}
- public void testGraphics() throws Exception {
+ @Test
+ public void graphics() throws Exception {
Slide slide = ppt.createSlide();
Line line = new Line();
* Verify that we can read TextBox shapes
* @throws Exception
*/
- public void testTextBoxRead() throws Exception {
+ @Test
+ public void textBoxRead() throws Exception {
ppt = new SlideShow(_slTests.openResourceAsStream("with_textbox.ppt"));
Slide sl = ppt.getSlides()[0];
Shape[] sh = sl.getShapes();
* Verify that we can add TextBox shapes to a slide
* and set some of the style attributes
*/
- public void testTextBoxWriteBytes() throws Exception {
+ @Test
+ public void textBoxWriteBytes() throws Exception {
ppt = new SlideShow();
Slide sl = ppt.createSlide();
RichTextRun rt;
/**
* Test with an empty text box
*/
- public void testEmptyTextBox() {
+ @Test
+ public void emptyTextBox() {
assertEquals(2, pptB.getSlides().length);
Slide s1 = pptB.getSlides()[0];
Slide s2 = pptB.getSlides()[1];
* 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 {
+ @Test
+ public void textBoxSet() throws Exception {
textBoxSet("with_textbox.ppt");
textBoxSet("basic_test_ppt_file.ppt");
textBoxSet("next_test_ppt_file.ppt");
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream(filename));
Slide[] sl = ppt.getSlides();
for (int k = 0; k < sl.length; k++) {
- ArrayList lst1 = new ArrayList();
+ ArrayList<String> lst1 = new ArrayList<String>();
TextRun[] txt = sl[k].getTextRuns();
for (int i = 0; i < txt.length; i++) {
lst1.add(txt[i].getText());
}
- ArrayList lst2 = new ArrayList();
+ ArrayList<String> lst2 = new ArrayList<String>();
Shape[] sh = sl[k].getShapes();
for (int i = 0; i < sh.length; i++) {
if (sh[i] instanceof TextShape){
/**
* Test adding shapes to <code>ShapeGroup</code>
*/
- public void testShapeGroup() throws Exception {
+ @Test
+ public void shapeGroup() throws Exception {
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
/**
* Test functionality of Sheet.removeShape(Shape shape)
*/
- public void testRemoveShapes() throws IOException {
+ @Test
+ public void removeShapes() throws IOException {
String file = "with_textbox.ppt";
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream(file));
Slide sl = ppt.getSlides()[0];
assertEquals("expected 0 shaped in " + file, 0, sl.getShapes().length);
}
- public void testLineWidth() {
+ @Test
+ public void lineWidth() {
SimpleShape sh = new AutoShape(ShapeTypes.RightTriangle);
- EscherOptRecord opt = (EscherOptRecord)SimpleShape.getEscherChild(sh.getSpContainer(), EscherOptRecord.RECORD_ID);
- EscherSimpleProperty prop = (EscherSimpleProperty)SimpleShape.getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
+ EscherOptRecord opt = sh.getEscherOptRecord();
+ EscherSimpleProperty prop = SimpleShape.getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
assertNull(prop);
- assertEquals(SimpleShape.DEFAULT_LINE_WIDTH, sh.getLineWidth());
+ assertEquals(SimpleShape.DEFAULT_LINE_WIDTH, sh.getLineWidth(), 0);
sh.setLineWidth(1.0);
- prop = (EscherSimpleProperty)SimpleShape.getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
+ prop = SimpleShape.getEscherProperty(opt, EscherProperties.LINESTYLE__LINEWIDTH);
assertNotNull(prop);
- assertEquals(1.0, sh.getLineWidth());
+ assertEquals(1.0, sh.getLineWidth(), 0);
}
- public void testShapeId() {
+ @Test
+ public void shapeId() {
SlideShow ppt = new SlideShow();
Slide slide = ppt.createSlide();
Shape shape = null;
assertEquals(numClusters + 1, dgg.getNumIdClusters());
}
- public void testLineColor() throws IOException {
+ @Test
+ public void lineColor() throws IOException {
SlideShow ppt = new SlideShow(_slTests.openResourceAsStream("51731.ppt"));
Shape[] shape = ppt.getSlides()[0].getShapes();
TextShape sh3 = (TextShape)shape[2];
assertEquals("Text in a black border", sh3.getText());
assertEquals(Color.black, sh3.getLineColor());
- assertEquals(0.75, sh3.getLineWidth());
+ assertEquals(0.75, sh3.getLineWidth(), 0);
TextShape sh4 = (TextShape)shape[3];
assertEquals("Border width is 5 pt", sh4.getText());
assertEquals(Color.black, sh4.getLineColor());
- assertEquals(5.0, sh4.getLineWidth());
+ assertEquals(5.0, sh4.getLineWidth(), 0);
}
}
import junit.framework.AssertionFailedError;
import org.apache.poi.POIDataSamples;
+import org.apache.poi.ddf.EscherArrayProperty;
+import org.apache.poi.ddf.EscherColorRef;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.HSLFTestDataSamples;
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
+import org.apache.poi.hslf.model.AutoShape;
import org.apache.poi.hslf.model.Background;
import org.apache.poi.hslf.model.Fill;
import org.apache.poi.hslf.model.HeadersFooters;
import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
import org.apache.poi.hslf.record.TextHeaderAtom;
+import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;
+import org.apache.poi.util.Units;
import org.junit.Test;
/**
inputStream.close();
}
}
+
+ @Test
+ public void bug46441() throws Exception {
+ InputStream inputStream = new FileInputStream(_slTests.getFile("bug46441.ppt"));
+ try {
+ SlideShow slideShow = new SlideShow(inputStream);
+ AutoShape as = (AutoShape)slideShow.getSlides()[0].getShapes()[0];
+ EscherOptRecord opt = as.getEscherOptRecord();
+ EscherArrayProperty ep = Shape.getEscherProperty(opt, EscherProperties.FILL__SHADECOLORS);
+ double exp[][] = {
+ // r, g, b, position
+ { 94, 158, 255, 0 },
+ { 133, 194, 255, 0.399994 },
+ { 196, 214, 235, 0.699997 },
+ { 255, 235, 250, 1 }
+ };
+
+ int i = 0;
+ for (byte data[] : ep) {
+ EscherColorRef ecr = new EscherColorRef(data, 0, 4);
+ int rgb[] = ecr.getRGB();
+ double pos = Units.fixedPointToDecimal(LittleEndian.getInt(data, 4));
+ assertEquals((int)exp[i][0], rgb[0]);
+ assertEquals((int)exp[i][1], rgb[1]);
+ assertEquals((int)exp[i][2], rgb[2]);
+ assertEquals(exp[i][3], pos, 0.01);
+ i++;
+ }
+ } finally {
+ inputStream.close();
+ }
+ }
}