diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java
index 002fa30b83..b4e57404e0 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawing.java
@@ -17,12 +17,119 @@
package org.apache.poi.hwpf.usermodel;
/**
- * User-friendly interface to office drawing objects
+ * User-friendly interface to office drawing objects.
+ *
+ * Some properties and enumeration constants description are quotes from the
+ * following sources:
+ *
+ * - [MS-ODRAW] — v20110608; Office Drawing Binary File Format; Copyright (c)
+ * 2011 Microsoft Corporation.
+ *
*
* @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
*/
public interface OfficeDrawing
{
+
+ public enum HorizontalPositioning {
+
+ /**
+ * The shape is horizontally offset by an absolute distance from the
+ * page element.
+ */
+ ABSOLUTE,
+
+ /**
+ * The shape is horizontally positioned at the center of the page
+ * element.
+ */
+ CENTER,
+
+ /**
+ * The shape is horizontally positioned like {@link #LEFT} on
+ * odd-numbered pages and like {@link #RIGHT} on even-numbered pages.
+ */
+ INSIDE,
+
+ /**
+ * The shape is horizontally positioned at the left side of the page
+ * element.
+ */
+ LEFT,
+
+ /**
+ * The shape is horizontally positioned like {@link #RIGHT} on
+ * odd-numbered pages and like {@link #LEFT} on even-numbered pages.
+ */
+ OUTSIDE,
+
+ /**
+ * The shape is horizontally positioned at the right side of the page
+ * element.
+ */
+ RIGHT;
+ }
+
+ public enum HorizontalRelativeElement {
+ CHAR, MARGIN, PAGE, TEXT;
+ }
+
+ public enum VerticalPositioning {
+
+ /**
+ * The shape is vertically offset by an absolute distance from the page
+ * element
+ */
+ ABSOLUTE,
+
+ /**
+ * The shape is vertically positioned at the bottom of the page element
+ */
+ BOTTOM,
+
+ /**
+ * The shape is vertically positioned in the center of the page element
+ */
+ CENTER,
+
+ /**
+ * The shape is vertically positioned like msopvTop on odd-numbered
+ * pages and like msopvBottom on even-numbered pages
+ */
+ INSIDE,
+
+ /**
+ * The shape is vertically positioned like {@link #BOTTOM} on
+ * odd-numbered pages and like {@link #TOP} on even-numbered pages
+ */
+ OUTSIDE,
+
+ /**
+ * The shape is vertically positioned at the top of the page element
+ */
+ TOP;
+ }
+
+ public enum VerticalRelativeElement {
+ LINE, MARGIN, PAGE, TEXT;
+ }
+
+ /**
+ * Returns the type of horizontal positioning to use for a shape
+ *
+ * @return the type of horizontal positioning to use for a shape
+ */
+ public HorizontalPositioning getHorizontalPositioning();
+
+ /**
+ * Specifies a page element relative to which a shape is horizontally
+ * positioned
+ *
+ * @return a page element relative to which a shape is horizontally
+ * positioned
+ */
+ public HorizontalRelativeElement getHorizontalRelative();
+
/**
* Returns picture data if this shape has (single?) associated picture data
*/
@@ -54,4 +161,19 @@ public interface OfficeDrawing
*/
int getShapeId();
+ /**
+ * Specifies the type of vertical positioning to use for a shape
+ *
+ * @return return the type of vertical positioning to use for a shape
+ */
+ public VerticalPositioning getVerticalPositioning();
+
+ /**
+ * Specifies a page element relative to which a shape is vertically
+ * positioned
+ *
+ * @return a page element relative to which a shape is vertically positioned
+ */
+ public VerticalRelativeElement getVerticalRelativeElement();
+
}
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java
index 370cacd707..2d4c2a1a30 100644
--- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java
+++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java
@@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import org.apache.poi.ddf.EscherTertiaryOptRecord;
+
import org.apache.poi.ddf.DefaultEscherRecordFactory;
import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherBlipRecord;
@@ -49,22 +51,6 @@ public class OfficeDrawingsImpl implements OfficeDrawings
this._mainStream = mainStream;
}
- private EscherContainerRecord getEscherShapeRecordContainer(
- final int shapeId )
- {
- for ( EscherContainerRecord spContainer : _escherRecordHolder
- .getSpContainers() )
- {
- EscherSpRecord escherSpRecord = spContainer
- .getChildById( (short) 0xF00A );
- if ( escherSpRecord != null
- && escherSpRecord.getShapeId() == shapeId )
- return spContainer;
- }
-
- return null;
- }
-
private EscherBlipRecord getBitmapRecord( int bitmapIndex )
{
List extends EscherContainerRecord> bContainers = _escherRecordHolder
@@ -117,10 +103,94 @@ public class OfficeDrawingsImpl implements OfficeDrawings
return null;
}
+ private EscherContainerRecord getEscherShapeRecordContainer(
+ final int shapeId )
+ {
+ for ( EscherContainerRecord spContainer : _escherRecordHolder
+ .getSpContainers() )
+ {
+ EscherSpRecord escherSpRecord = spContainer
+ .getChildById( (short) 0xF00A );
+ if ( escherSpRecord != null
+ && escherSpRecord.getShapeId() == shapeId )
+ return spContainer;
+ }
+
+ return null;
+ }
+
private OfficeDrawing getOfficeDrawing( final FSPA fspa )
{
return new OfficeDrawing()
{
+ public HorizontalPositioning getHorizontalPositioning()
+ {
+ int value = getTertiaryPropertyValue(
+ EscherProperties.GROUPSHAPE__POSH, -1 );
+
+ switch ( value )
+ {
+ case 0:
+ return HorizontalPositioning.ABSOLUTE;
+ case 1:
+ return HorizontalPositioning.LEFT;
+ case 2:
+ return HorizontalPositioning.CENTER;
+ case 3:
+ return HorizontalPositioning.RIGHT;
+ case 4:
+ return HorizontalPositioning.INSIDE;
+ case 5:
+ return HorizontalPositioning.OUTSIDE;
+ }
+
+ return HorizontalPositioning.ABSOLUTE;
+ }
+
+ public HorizontalRelativeElement getHorizontalRelative()
+ {
+ int value = getTertiaryPropertyValue(
+ EscherProperties.GROUPSHAPE__POSRELH, -1 );
+
+ switch ( value )
+ {
+ case 1:
+ return HorizontalRelativeElement.MARGIN;
+ case 2:
+ return HorizontalRelativeElement.PAGE;
+ case 3:
+ return HorizontalRelativeElement.TEXT;
+ case 4:
+ return HorizontalRelativeElement.CHAR;
+ }
+
+ return HorizontalRelativeElement.TEXT;
+ }
+
+ public byte[] getPictureData()
+ {
+ EscherContainerRecord shapeDescription = getEscherShapeRecordContainer( getShapeId() );
+ if ( shapeDescription == null )
+ return null;
+
+ EscherOptRecord escherOptRecord = shapeDescription
+ .getChildById( EscherOptRecord.RECORD_ID );
+ if ( escherOptRecord == null )
+ return null;
+
+ EscherSimpleProperty escherProperty = escherOptRecord
+ .lookup( EscherProperties.BLIP__BLIPTODISPLAY );
+ if ( escherProperty == null )
+ return null;
+
+ int bitmapIndex = escherProperty.getPropertyValue();
+ EscherBlipRecord escherBlipRecord = getBitmapRecord( bitmapIndex );
+ if ( escherBlipRecord == null )
+ return null;
+
+ return escherBlipRecord.getPicturedata();
+ }
+
public int getRectangleBottom()
{
return fspa.getYaBottom();
@@ -146,28 +216,69 @@ public class OfficeDrawingsImpl implements OfficeDrawings
return fspa.getSpid();
}
- public byte[] getPictureData()
+ private int getTertiaryPropertyValue( int propertyId,
+ int defaultValue )
{
EscherContainerRecord shapeDescription = getEscherShapeRecordContainer( getShapeId() );
if ( shapeDescription == null )
- return null;
+ return defaultValue;
- EscherOptRecord escherOptRecord = shapeDescription
- .getChildById( (short) 0xF00B );
- if ( escherOptRecord == null )
- return null;
+ EscherTertiaryOptRecord escherTertiaryOptRecord = shapeDescription
+ .getChildById( EscherTertiaryOptRecord.RECORD_ID );
+ if ( escherTertiaryOptRecord == null )
+ return defaultValue;
- EscherSimpleProperty escherProperty = escherOptRecord
- .lookup( EscherProperties.BLIP__BLIPTODISPLAY );
+ EscherSimpleProperty escherProperty = escherTertiaryOptRecord
+ .lookup( propertyId );
if ( escherProperty == null )
- return null;
+ return defaultValue;
+ int value = escherProperty.getPropertyValue();
- int bitmapIndex = escherProperty.getPropertyValue();
- EscherBlipRecord escherBlipRecord = getBitmapRecord( bitmapIndex );
- if ( escherBlipRecord == null )
- return null;
+ return value;
+ }
- return escherBlipRecord.getPicturedata();
+ public VerticalPositioning getVerticalPositioning()
+ {
+ int value = getTertiaryPropertyValue(
+ EscherProperties.GROUPSHAPE__POSV, -1 );
+
+ switch ( value )
+ {
+ case 0:
+ return VerticalPositioning.ABSOLUTE;
+ case 1:
+ return VerticalPositioning.TOP;
+ case 2:
+ return VerticalPositioning.CENTER;
+ case 3:
+ return VerticalPositioning.BOTTOM;
+ case 4:
+ return VerticalPositioning.INSIDE;
+ case 5:
+ return VerticalPositioning.OUTSIDE;
+ }
+
+ return VerticalPositioning.ABSOLUTE;
+ }
+
+ public VerticalRelativeElement getVerticalRelativeElement()
+ {
+ int value = getTertiaryPropertyValue(
+ EscherProperties.GROUPSHAPE__POSV, -1 );
+
+ switch ( value )
+ {
+ case 1:
+ return VerticalRelativeElement.MARGIN;
+ case 2:
+ return VerticalRelativeElement.PAGE;
+ case 3:
+ return VerticalRelativeElement.TEXT;
+ case 4:
+ return VerticalRelativeElement.LINE;
+ }
+
+ return VerticalRelativeElement.TEXT;
}
@Override