Test and fix for bug #46441
Use generics on Shape.getEscherChild() and SimpleShape.getClientDataRecord() to minimize casting Unify access to Shape.getEscherOptRecord() git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1649152 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
be0d5df4b7
commit
0ea9f5fff9
@ -17,8 +17,11 @@
|
||||
|
||||
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
|
||||
@ -26,7 +29,7 @@ import org.apache.poi.util.HexDump;
|
||||
*
|
||||
* @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
|
||||
@ -205,4 +208,24 @@ public final class EscherArrayProperty extends EscherComplexProperty {
|
||||
}
|
||||
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");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
283
src/java/org/apache/poi/ddf/EscherColorRef.java
Normal file
283
src/java/org/apache/poi/ddf/EscherColorRef.java
Normal file
@ -0,0 +1,283 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package org.apache.poi.ddf;
|
||||
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* An OfficeArtCOLORREF structure entry which also handles color extension opid data
|
||||
*/
|
||||
public class EscherColorRef {
|
||||
int opid = -1;
|
||||
int colorRef = 0;
|
||||
|
||||
public enum SysIndexSource {
|
||||
/** Use the fill color of the shape. */
|
||||
FILL_COLOR(0xF0),
|
||||
/** If the shape contains a line, use the line color of the shape. Otherwise, use the fill color. */
|
||||
LINE_OR_FILL_COLOR(0xF1),
|
||||
/** Use the line color of the shape. */
|
||||
LINE_COLOR(0xF2),
|
||||
/** Use the shadow color of the shape. */
|
||||
SHADOW_COLOR(0xF3),
|
||||
/** Use the current, or last-used, color. */
|
||||
CURRENT_OR_LAST_COLOR(0xF4),
|
||||
/** Use the fill background color of the shape. */
|
||||
FILL_BACKGROUND_COLOR(0xF5),
|
||||
/** Use the line background color of the shape. */
|
||||
LINE_BACKGROUND_COLOR(0xF6),
|
||||
/** If the shape contains a fill, use the fill color of the shape. Otherwise, use the line color. */
|
||||
FILL_OR_LINE_COLOR(0xF7)
|
||||
;
|
||||
int value;
|
||||
SysIndexSource(int value) { this.value = value; }
|
||||
}
|
||||
|
||||
/**
|
||||
* The following enum specifies values that indicate special procedural properties that
|
||||
* are used to modify the color components of another color. These values are combined with
|
||||
* those of the {@link SysIndexSource} enum or with a user-specified color.
|
||||
* The first six values are mutually exclusive.
|
||||
*/
|
||||
public enum SysIndexProcedure {
|
||||
/**
|
||||
* Darken the color by the value that is specified in the blue field.
|
||||
* A blue value of 0xFF specifies that the color is to be left unchanged,
|
||||
* whereas a blue value of 0x00 specifies that the color is to be completely darkened.
|
||||
*/
|
||||
DARKEN_COLOR(0x01),
|
||||
/**
|
||||
* Lighten the color by the value that is specified in the blue field.
|
||||
* A blue value of 0xFF specifies that the color is to be left unchanged,
|
||||
* whereas a blue value of 0x00 specifies that the color is to be completely lightened.
|
||||
*/
|
||||
LIGHTEN_COLOR(0x02),
|
||||
/**
|
||||
* Add a gray level RGB value. The blue field contains the gray level to add:
|
||||
* NewColor = SourceColor + gray
|
||||
*/
|
||||
ADD_GRAY_LEVEL(0x03),
|
||||
/**
|
||||
* Subtract a gray level RGB value. The blue field contains the gray level to subtract:
|
||||
* NewColor = SourceColor - gray
|
||||
*/
|
||||
SUB_GRAY_LEVEL(0x04),
|
||||
/**
|
||||
* Reverse-subtract a gray level RGB value. The blue field contains the gray level from
|
||||
* which to subtract:
|
||||
* NewColor = gray - SourceColor
|
||||
*/
|
||||
REVERSE_GRAY_LEVEL(0x05),
|
||||
/**
|
||||
* If the color component being modified is less than the parameter contained in the blue
|
||||
* field, set it to the minimum intensity. If the color component being modified is greater
|
||||
* than or equal to the parameter, set it to the maximum intensity.
|
||||
*/
|
||||
THRESHOLD(0x06),
|
||||
/**
|
||||
* After making other modifications, invert the color.
|
||||
* This enum value is only for documentation and won't be directly returned.
|
||||
*/
|
||||
INVERT_AFTER(0x20),
|
||||
/**
|
||||
* After making other modifications, invert the color by toggling just the high bit of each
|
||||
* color channel.
|
||||
* This enum value is only for documentation and won't be directly returned.
|
||||
*/
|
||||
INVERT_HIGHBIT_AFTER(0x40)
|
||||
;
|
||||
BitField mask;
|
||||
SysIndexProcedure(int mask) {
|
||||
this.mask = new BitField(mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the system color scheme will be used to determine the color.
|
||||
* A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index
|
||||
* into the system color table. Values less than 0x00F0 map directly to system colors.
|
||||
*/
|
||||
private static final BitField FLAG_SYS_INDEX = new BitField(0x10000000);
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the current application-defined color scheme will be used
|
||||
* to determine the color. A value of 0x1 specifies that red will be treated as an index
|
||||
* into the current color scheme table. If this value is 0x1, green and blue MUST be 0x00.
|
||||
*/
|
||||
private static final BitField FLAG_SCHEME_INDEX = new BitField(0x08000000);
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the color is a standard RGB color.
|
||||
* 0x0 : The RGB color MAY use halftone dithering to display.
|
||||
* 0x1 : The color MUST be a solid color.
|
||||
*/
|
||||
private static final BitField FLAG_SYSTEM_RGB = new BitField(0x04000000);
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the current palette will be used to determine the color.
|
||||
* A value of 0x1 specifies that red, green, and blue contain an RGB value that will be
|
||||
* matched in the current color palette. This color MUST be solid.
|
||||
*/
|
||||
private static final BitField FLAG_PALETTE_RGB = new BitField(0x02000000);
|
||||
|
||||
/**
|
||||
* A bit that specifies whether the current palette will be used to determine the color.
|
||||
* A value of 0x1 specifies that green and red will be treated as an unsigned 16-bit index into
|
||||
* the current color palette. This color MAY be dithered. If this value is 0x1, blue MUST be 0x00.
|
||||
*/
|
||||
private static final BitField FLAG_PALETTE_INDEX = new BitField(0x01000000);
|
||||
|
||||
/**
|
||||
* An unsigned integer that specifies the intensity of the blue color channel. A value
|
||||
* of 0x00 has the minimum blue intensity. A value of 0xFF has the maximum blue intensity.
|
||||
*/
|
||||
private static final BitField FLAG_BLUE = new BitField(0x00FF0000);
|
||||
|
||||
/**
|
||||
* An unsigned integer that specifies the intensity of the green color channel. A value
|
||||
* of 0x00 has the minimum green intensity. A value of 0xFF has the maximum green intensity.
|
||||
*/
|
||||
private static final BitField FLAG_GREEN = new BitField(0x0000FF00);
|
||||
|
||||
/**
|
||||
* An unsigned integer that specifies the intensity of the red color channel. A value
|
||||
* of 0x00 has the minimum red intensity. A value of 0xFF has the maximum red intensity.
|
||||
*/
|
||||
private static final BitField FLAG_RED = new BitField(0x000000FF);
|
||||
|
||||
public EscherColorRef(int colorRef) {
|
||||
this.colorRef = colorRef;
|
||||
}
|
||||
|
||||
public EscherColorRef(byte[] source, int start, int len) {
|
||||
assert(len == 4 || len == 6);
|
||||
|
||||
int offset = start;
|
||||
if (len == 6) {
|
||||
opid = LittleEndian.getUShort(source, offset);
|
||||
offset += 2;
|
||||
}
|
||||
colorRef = LittleEndian.getInt(source, offset);
|
||||
}
|
||||
|
||||
public boolean hasSysIndexFlag() {
|
||||
return FLAG_SYS_INDEX.isSet(colorRef);
|
||||
}
|
||||
|
||||
public void setSysIndexFlag(boolean flag) {
|
||||
FLAG_SYS_INDEX.setBoolean(colorRef, flag);
|
||||
}
|
||||
|
||||
public boolean hasSchemeIndexFlag() {
|
||||
return FLAG_SCHEME_INDEX.isSet(colorRef);
|
||||
}
|
||||
|
||||
public void setSchemeIndexFlag(boolean flag) {
|
||||
FLAG_SCHEME_INDEX.setBoolean(colorRef, flag);
|
||||
}
|
||||
|
||||
public boolean hasSystemRGBFlag() {
|
||||
return FLAG_SYSTEM_RGB.isSet(colorRef);
|
||||
}
|
||||
|
||||
public void setSystemRGBFlag(boolean flag) {
|
||||
FLAG_SYSTEM_RGB.setBoolean(colorRef, flag);
|
||||
}
|
||||
|
||||
public boolean hasPaletteRGBFlag() {
|
||||
return FLAG_PALETTE_RGB.isSet(colorRef);
|
||||
}
|
||||
|
||||
public void setPaletteRGBFlag(boolean flag) {
|
||||
FLAG_PALETTE_RGB.setBoolean(colorRef, flag);
|
||||
}
|
||||
|
||||
public boolean hasPaletteIndexFlag() {
|
||||
return FLAG_PALETTE_INDEX.isSet(colorRef);
|
||||
}
|
||||
|
||||
public void setPaletteIndexFlag(boolean flag) {
|
||||
FLAG_PALETTE_INDEX.setBoolean(colorRef, flag);
|
||||
}
|
||||
|
||||
public int[] getRGB() {
|
||||
int rgb[] = {
|
||||
FLAG_RED.getValue(colorRef),
|
||||
FLAG_GREEN.getValue(colorRef),
|
||||
FLAG_BLUE.getValue(colorRef)
|
||||
};
|
||||
return rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link SysIndexSource} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null
|
||||
*/
|
||||
public SysIndexSource getSysIndexSource() {
|
||||
if (!hasSysIndexFlag()) return null;
|
||||
int val = FLAG_RED.getValue(colorRef);
|
||||
for (SysIndexSource sis : SysIndexSource.values()) {
|
||||
if (sis.value == val) return sis;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link SysIndexProcedure} - for invert flag use {@link #getSysIndexInvert()}
|
||||
* @return {@link SysIndexProcedure} if {@link #hasSysIndexFlag()} is {@code true}, otherwise null
|
||||
*/
|
||||
public SysIndexProcedure getSysIndexProcedure() {
|
||||
if (!hasSysIndexFlag()) return null;
|
||||
int val = FLAG_RED.getValue(colorRef);
|
||||
for (SysIndexProcedure sip : SysIndexProcedure.values()) {
|
||||
if (sip == SysIndexProcedure.INVERT_AFTER || sip == SysIndexProcedure.INVERT_HIGHBIT_AFTER) continue;
|
||||
if (sip.mask.isSet(val)) return sip;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 0 for no invert flag, 1 for {@link SysIndexProcedure#INVERT_AFTER} and
|
||||
* 2 for {@link SysIndexProcedure#INVERT_HIGHBIT_AFTER}
|
||||
*/
|
||||
public int getSysIndexInvert() {
|
||||
if (!hasSysIndexFlag()) return 0;
|
||||
int val = FLAG_GREEN.getValue(colorRef);
|
||||
if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) return 1;
|
||||
if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of the scheme color or -1 if {@link #hasSchemeIndexFlag()} is {@code false}
|
||||
*
|
||||
* @see org.apache.poi.hslf.record.ColorSchemeAtom#getColor(int)
|
||||
*/
|
||||
public int getSchemeIndex() {
|
||||
if (!hasSchemeIndexFlag()) return -1;
|
||||
return FLAG_RED.getValue(colorRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return index of current palette (color) or -1 if {@link #hasPaletteIndexFlag()} is {@code false}
|
||||
*/
|
||||
public int getPaletteIndex() {
|
||||
if (!hasPaletteIndexFlag()) return -1;
|
||||
return (FLAG_GREEN.getValue(colorRef) << 8) & FLAG_RED.getValue(colorRef);
|
||||
}
|
||||
}
|
@ -40,4 +40,19 @@ public class Units {
|
||||
public static double toPoints(long emu){
|
||||
return (double)emu/EMU_PER_POINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value of type FixedPoint to a decimal number
|
||||
*
|
||||
* @param fixedPoint
|
||||
* @return decimal number
|
||||
*
|
||||
* @see <a href="http://msdn.microsoft.com/en-us/library/dd910765(v=office.12).aspx">[MS-OSHARED] - 2.2.1.6 FixedPoint</a>
|
||||
*/
|
||||
public static double fixedPointToDecimal(int fixedPoint) {
|
||||
int i = (fixedPoint >> 16);
|
||||
int f = (fixedPoint >> 0) & 0xFFFF;
|
||||
double decimal = (i + f/65536.0);
|
||||
return decimal;
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ public final class ActiveXShape extends Picture {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -17,15 +17,20 @@
|
||||
|
||||
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 org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import java.awt.Color;
|
||||
import java.util.List;
|
||||
|
||||
import java.awt.*;
|
||||
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.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Represents functionality provided by the 'Fill Effects' dialog in PowerPoint.
|
||||
@ -112,16 +117,16 @@ public final class Fill {
|
||||
* @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);
|
||||
@ -138,12 +143,12 @@ public final class Fill {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -154,7 +159,7 @@ public final class Fill {
|
||||
* @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);
|
||||
}
|
||||
|
||||
@ -162,8 +167,8 @@ public final class Fill {
|
||||
* 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;
|
||||
|
||||
@ -175,7 +180,7 @@ public final class Fill {
|
||||
* 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);
|
||||
}
|
||||
@ -190,8 +195,8 @@ public final class Fill {
|
||||
* 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;
|
||||
|
||||
@ -202,7 +207,7 @@ public final class Fill {
|
||||
* 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);
|
||||
}
|
||||
@ -216,8 +221,8 @@ public final class Fill {
|
||||
* <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();
|
||||
@ -225,7 +230,7 @@ public final class Fill {
|
||||
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();
|
||||
@ -249,7 +254,7 @@ public final class Fill {
|
||||
* @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 ) {
|
||||
|
@ -179,11 +179,11 @@ public final class Freeform extends AutoShape {
|
||||
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) {
|
||||
|
@ -116,10 +116,10 @@ public final class MovieShape extends Picture {
|
||||
* @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);
|
||||
@ -131,7 +131,7 @@ public final class MovieShape extends Picture {
|
||||
}
|
||||
|
||||
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();
|
||||
@ -139,7 +139,7 @@ public final class MovieShape extends Picture {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -150,7 +150,7 @@ public final class MovieShape extends Picture {
|
||||
* @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();
|
||||
|
@ -41,6 +41,7 @@ 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.StringUtil;
|
||||
import org.apache.poi.util.Units;
|
||||
|
||||
|
||||
/**
|
||||
@ -120,7 +121,7 @@ public class Picture extends SimpleShape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -202,7 +203,7 @@ public class Picture extends SimpleShape {
|
||||
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;
|
||||
@ -223,7 +224,7 @@ public class Picture extends SimpleShape {
|
||||
*/
|
||||
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();
|
||||
@ -289,16 +290,11 @@ public class Picture extends SimpleShape {
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import org.apache.poi.ddf.*;
|
||||
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.*;
|
||||
@ -129,7 +130,7 @@ public abstract class Shape {
|
||||
* @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();
|
||||
}
|
||||
|
||||
@ -138,7 +139,7 @@ public abstract class Shape {
|
||||
* @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 );
|
||||
}
|
||||
@ -161,15 +162,15 @@ public abstract class Shape {
|
||||
* @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,
|
||||
@ -187,7 +188,7 @@ public abstract class Shape {
|
||||
}
|
||||
}
|
||||
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,
|
||||
@ -210,17 +211,17 @@ public abstract class Shape {
|
||||
* @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)));
|
||||
@ -246,29 +247,21 @@ public abstract class Shape {
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279,11 +272,11 @@ public abstract class Shape {
|
||||
* @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) {
|
||||
@ -310,7 +303,7 @@ public abstract class Shape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -321,7 +314,7 @@ public abstract class Shape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -365,32 +358,30 @@ public abstract class Shape {
|
||||
|
||||
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 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;
|
||||
|
||||
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){
|
||||
@ -401,13 +392,11 @@ public abstract class Shape {
|
||||
//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){
|
||||
@ -436,7 +425,7 @@ public abstract class Shape {
|
||||
* @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();
|
||||
}
|
||||
|
||||
@ -446,7 +435,7 @@ public abstract class Shape {
|
||||
* @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);
|
||||
}
|
||||
|
||||
@ -484,7 +473,48 @@ public abstract class Shape {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ public final class ShapeFactory {
|
||||
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);
|
||||
@ -91,8 +91,8 @@ public final class ShapeFactory {
|
||||
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:
|
||||
@ -115,7 +115,7 @@ public final class ShapeFactory {
|
||||
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);
|
||||
@ -134,7 +134,8 @@ public final class ShapeFactory {
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
@ -143,12 +144,12 @@ public final class ShapeFactory {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -100,9 +100,7 @@ public class ShapeGroup extends Shape{
|
||||
*/
|
||||
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];
|
||||
@ -116,7 +114,7 @@ public class ShapeGroup extends Shape{
|
||||
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);
|
||||
@ -131,8 +129,7 @@ public class ShapeGroup extends Shape{
|
||||
* @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);
|
||||
@ -153,8 +150,7 @@ public class ShapeGroup extends Shape{
|
||||
* @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;
|
||||
@ -237,12 +233,11 @@ public class ShapeGroup extends Shape{
|
||||
* @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,
|
||||
@ -266,8 +261,7 @@ public class ShapeGroup extends Shape{
|
||||
* @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;
|
||||
}
|
||||
|
||||
@ -291,4 +285,10 @@ public class ShapeGroup extends Shape{
|
||||
|
||||
graphics.setTransform(at);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends EscherRecord> T getEscherChild(int recordId){
|
||||
EscherContainerRecord groupInfoContainer = (EscherContainerRecord)_escherContainer.getChild(0);
|
||||
return groupInfoContainer.getChildById((short)recordId);
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ public abstract class Sheet {
|
||||
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){
|
||||
|
@ -23,9 +23,16 @@ import java.awt.geom.AffineTransform;
|
||||
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;
|
||||
@ -103,7 +110,7 @@ public abstract class SimpleShape extends Shape {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -139,7 +146,7 @@ public abstract class SimpleShape extends Shape {
|
||||
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);
|
||||
@ -154,7 +161,7 @@ public abstract class SimpleShape extends Shape {
|
||||
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();
|
||||
}
|
||||
|
||||
@ -186,7 +193,7 @@ public abstract class SimpleShape extends Shape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -206,47 +213,6 @@ public abstract class SimpleShape extends Shape {
|
||||
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
|
||||
@ -256,17 +222,13 @@ public abstract class SimpleShape extends Shape {
|
||||
|
||||
//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();
|
||||
|
||||
@ -276,6 +238,7 @@ public abstract class SimpleShape extends Shape {
|
||||
tx.translate(exterior.getX(), exterior.getY());
|
||||
tx.scale(scaleX, scaleY);
|
||||
tx.translate(-interior.getX(), -interior.getY());
|
||||
|
||||
}
|
||||
anchor = tx.createTransformedShape(anchor).getBounds2D();
|
||||
}
|
||||
@ -314,12 +277,13 @@ public abstract class SimpleShape extends Shape {
|
||||
*
|
||||
* @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;
|
||||
@ -332,7 +296,7 @@ public abstract class SimpleShape extends Shape {
|
||||
*/
|
||||
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)){
|
||||
|
@ -88,7 +88,7 @@ public final class Slide extends Sheet
|
||||
// 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
|
||||
|
@ -225,7 +225,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
|
||||
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;
|
||||
@ -281,7 +281,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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){
|
||||
/**
|
||||
@ -352,7 +352,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -377,7 +377,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -402,7 +402,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -426,7 +426,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -450,7 +450,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -469,7 +469,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@ -561,7 +561,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
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){
|
||||
@ -593,7 +593,7 @@ public abstract class TextShape extends SimpleShape {
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,17 +17,25 @@
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
@ -35,13 +43,14 @@ import org.apache.poi.POIDataSamples;
|
||||
*
|
||||
* @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());
|
||||
@ -57,7 +66,8 @@ public final class TestBackground extends TestCase {
|
||||
/**
|
||||
* 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;
|
||||
@ -88,7 +98,8 @@ public final class TestBackground extends TestCase {
|
||||
/**
|
||||
* 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;
|
||||
@ -191,8 +202,8 @@ public final class TestBackground extends TestCase {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@ -200,8 +211,8 @@ public final class TestBackground extends TestCase {
|
||||
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;
|
||||
|
@ -17,38 +17,60 @@
|
||||
|
||||
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 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.*;
|
||||
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();
|
||||
@ -92,7 +114,8 @@ public final class TestShapes extends TestCase {
|
||||
* 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();
|
||||
@ -127,7 +150,8 @@ public final class TestShapes extends TestCase {
|
||||
* 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;
|
||||
@ -180,7 +204,8 @@ public final class TestShapes extends TestCase {
|
||||
/**
|
||||
* 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];
|
||||
@ -194,7 +219,8 @@ public final class TestShapes extends TestCase {
|
||||
* 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");
|
||||
@ -207,13 +233,13 @@ public final class TestShapes extends TestCase {
|
||||
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){
|
||||
@ -229,7 +255,8 @@ public final class TestShapes extends TestCase {
|
||||
/**
|
||||
* 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();
|
||||
@ -280,7 +307,8 @@ public final class TestShapes extends TestCase {
|
||||
/**
|
||||
* 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];
|
||||
@ -304,21 +332,23 @@ public final class TestShapes extends TestCase {
|
||||
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;
|
||||
@ -367,7 +397,8 @@ public final class TestShapes extends TestCase {
|
||||
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();
|
||||
|
||||
@ -384,11 +415,11 @@ public final class TestShapes extends TestCase {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -37,9 +37,14 @@ import java.util.Set;
|
||||
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;
|
||||
@ -59,7 +64,9 @@ import org.apache.poi.hslf.record.Record;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -625,4 +632,36 @@ public final class TestBugs {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
test-data/slideshow/bug46441.ppt
Normal file
BIN
test-data/slideshow/bug46441.ppt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user