Added such improvements:
1. Each shape contains EscherContainerRecord(SpContainer). Shapes get and set all properties into EscherOptRecord. 2. HSSFShapeGroup takes coordinates from EscherSpgrRecord. 3. Added tests for creating new HSSFSimpleShape from scratch and reading from existing file 4. Improved work with anchors. git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1351484 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
1b76a7e345
commit
74f75bebd8
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
contributor license agreements. See the NOTICE file distributed with
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
@ -38,6 +37,14 @@ public class EscherClientAnchorRecord
|
|||||||
public static final short RECORD_ID = (short) 0xF010;
|
public static final short RECORD_ID = (short) 0xF010;
|
||||||
public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor";
|
public static final String RECORD_DESCRIPTION = "MsofbtClientAnchor";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bit[0] - fMove (1 bit): A bit that specifies whether the shape will be kept intact when the cells are moved.
|
||||||
|
* bit[1] - fSize (1 bit): A bit that specifies whether the shape will be kept intact when the cells are resized. If fMove is 1, the value MUST be 1.
|
||||||
|
* bit[2-4] - reserved, MUST be 0 and MUST be ignored
|
||||||
|
* bit[5-15]- Undefined and MUST be ignored.
|
||||||
|
*
|
||||||
|
* it can take values: 0, 2, 3
|
||||||
|
*/
|
||||||
private short field_1_flag;
|
private short field_1_flag;
|
||||||
private short field_2_col1;
|
private short field_2_col1;
|
||||||
private short field_3_dx1;
|
private short field_3_dx1;
|
||||||
|
@ -38,6 +38,10 @@ public class EscherRGBProperty
|
|||||||
return propertyValue;
|
return propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRgbColor(int color){
|
||||||
|
this.propertyValue = color;
|
||||||
|
}
|
||||||
|
|
||||||
public byte getRed()
|
public byte getRed()
|
||||||
{
|
{
|
||||||
return (byte) ( propertyValue & 0xFF );
|
return (byte) ( propertyValue & 0xFF );
|
||||||
|
@ -80,6 +80,10 @@ public class EscherSimpleProperty extends EscherProperty
|
|||||||
return propertyValue;
|
return propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPropertyValue(int propertyValue) {
|
||||||
|
this.propertyValue = propertyValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if one escher property is equal to another.
|
* Returns true if one escher property is equal to another.
|
||||||
*/
|
*/
|
||||||
|
@ -18,40 +18,64 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
|
import org.apache.poi.ddf.EscherRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An anchor is what specifics the position of a shape within a client object
|
* An anchor is what specifics the position of a shape within a client object
|
||||||
* or within another containing shape.
|
* or within another containing shape.
|
||||||
*
|
*
|
||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public abstract class HSSFAnchor
|
public abstract class HSSFAnchor {
|
||||||
{
|
|
||||||
int dx1;
|
|
||||||
int dy1;
|
|
||||||
int dx2;
|
|
||||||
int dy2;
|
|
||||||
|
|
||||||
public HSSFAnchor()
|
public HSSFAnchor() {
|
||||||
{
|
createEscherAnchor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSSFAnchor( int dx1, int dy1, int dx2, int dy2 )
|
public HSSFAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||||
{
|
createEscherAnchor();
|
||||||
this.dx1 = dx1;
|
setDx1(dx1);
|
||||||
this.dy1 = dy1;
|
setDy1(dy1);
|
||||||
this.dx2 = dx2;
|
setDx2(dx2);
|
||||||
this.dy2 = dy2;
|
setDy2(dy2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDx1(){ return dx1; }
|
public static HSSFAnchor createAnchorFromEscher(EscherContainerRecord container){
|
||||||
public void setDx1( int dx1 ){ this.dx1 = dx1; }
|
if (null != container.getChildById(EscherChildAnchorRecord.RECORD_ID)){
|
||||||
public int getDy1(){ return dy1; }
|
return new HSSFChildAnchor((EscherChildAnchorRecord) container.getChildById(EscherChildAnchorRecord.RECORD_ID));
|
||||||
public void setDy1( int dy1 ){ this.dy1 = dy1; }
|
} else {
|
||||||
public int getDy2(){ return dy2; }
|
if (null != container.getChildById(EscherClientAnchorRecord.RECORD_ID)){
|
||||||
public void setDy2( int dy2 ){ this.dy2 = dy2; }
|
return new HSSFClientAnchor((EscherClientAnchorRecord) container.getChildById(EscherClientAnchorRecord.RECORD_ID));
|
||||||
public int getDx2(){ return dx2; }
|
}
|
||||||
public void setDx2( int dx2 ){ this.dx2 = dx2; }
|
return null;
|
||||||
|
// throw new IllegalArgumentException("continer must have anchor record");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int getDx1();
|
||||||
|
|
||||||
|
public abstract void setDx1(int dx1);
|
||||||
|
|
||||||
|
public abstract int getDy1();
|
||||||
|
|
||||||
|
public abstract void setDy1(int dy1);
|
||||||
|
|
||||||
|
public abstract int getDy2();
|
||||||
|
|
||||||
|
public abstract void setDy2(int dy2);
|
||||||
|
|
||||||
|
public abstract int getDx2();
|
||||||
|
|
||||||
|
public abstract void setDx2(int dx2);
|
||||||
|
|
||||||
public abstract boolean isHorizontallyFlipped();
|
public abstract boolean isHorizontallyFlipped();
|
||||||
|
|
||||||
public abstract boolean isVerticallyFlipped();
|
public abstract boolean isVerticallyFlipped();
|
||||||
|
|
||||||
|
public abstract EscherRecord getEscherAnchor();
|
||||||
|
|
||||||
|
protected abstract void createEscherAnchor();
|
||||||
}
|
}
|
||||||
|
@ -19,39 +19,100 @@ package org.apache.poi.hssf.usermodel;
|
|||||||
|
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherRecord;
|
||||||
|
|
||||||
public final class HSSFChildAnchor extends HSSFAnchor {
|
public final class HSSFChildAnchor extends HSSFAnchor {
|
||||||
|
|
||||||
private EscherChildAnchorRecord escherChildAnchorRecord;
|
private EscherChildAnchorRecord _escherChildAnchor;
|
||||||
|
|
||||||
public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) {
|
public HSSFChildAnchor(EscherChildAnchorRecord escherChildAnchorRecord) {
|
||||||
this.escherChildAnchorRecord = escherChildAnchorRecord;
|
this._escherChildAnchor = escherChildAnchorRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSSFChildAnchor()
|
public HSSFChildAnchor() {
|
||||||
{
|
_escherChildAnchor = new EscherChildAnchorRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HSSFChildAnchor( int dx1, int dy1, int dx2, int dy2 )
|
public HSSFChildAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||||
{
|
super(dx1, dy1, dx2, dy2);
|
||||||
super( dx1, dy1, dx2, dy2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAnchor(int dx1, int dy1, int dx2, int dy2)
|
@Override
|
||||||
{
|
public int getDx1() {
|
||||||
this.dx1 = dx1;
|
return _escherChildAnchor.getDx1();
|
||||||
this.dy1 = dy1;
|
|
||||||
this.dx2 = dx2;
|
|
||||||
this.dy2 = dy2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHorizontallyFlipped()
|
@Override
|
||||||
{
|
public void setDx1(int dx1) {
|
||||||
return dx1 > dx2;
|
_escherChildAnchor.setDx1(dx1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVerticallyFlipped()
|
@Override
|
||||||
{
|
public int getDy1() {
|
||||||
return dy1 > dy2;
|
return _escherChildAnchor.getDy1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDy1(int dy1) {
|
||||||
|
_escherChildAnchor.setDy1(dy1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDy2() {
|
||||||
|
return _escherChildAnchor.getDy2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDy2(int dy2) {
|
||||||
|
_escherChildAnchor.setDy2(dy2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDx2() {
|
||||||
|
return _escherChildAnchor.getDx2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDx2(int dx2) {
|
||||||
|
_escherChildAnchor.setDx2(dx2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnchor(int dx1, int dy1, int dx2, int dy2) {
|
||||||
|
setDx1(dx1);
|
||||||
|
setDy1(dy1);
|
||||||
|
setDx2(dx2);
|
||||||
|
setDy2(dy2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHorizontallyFlipped() {
|
||||||
|
return getDx1() > getDx2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVerticallyFlipped() {
|
||||||
|
return getDy1() > getDy2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EscherRecord getEscherAnchor() {
|
||||||
|
return _escherChildAnchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createEscherAnchor() {
|
||||||
|
_escherChildAnchor = new EscherChildAnchorRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (obj == this)
|
||||||
|
return true;
|
||||||
|
if (obj.getClass() != getClass())
|
||||||
|
return false;
|
||||||
|
HSSFChildAnchor anchor = (HSSFChildAnchor) obj;
|
||||||
|
|
||||||
|
return anchor.getDx1() == getDx1() && anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1()
|
||||||
|
&& anchor.getDy2() == getDy2();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherRecord;
|
||||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A client anchor is attached to an excel worksheet. It anchors against a
|
* A client anchor is attached to an excel worksheet. It anchors against a
|
||||||
* top-left and buttom-right cell.
|
* top-left and buttom-right cell.
|
||||||
@ -28,42 +28,34 @@ import org.apache.poi.ss.usermodel.ClientAnchor;
|
|||||||
* @author Glen Stampoultzis (glens at apache.org)
|
* @author Glen Stampoultzis (glens at apache.org)
|
||||||
*/
|
*/
|
||||||
public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
||||||
short col1;
|
|
||||||
int row1;
|
|
||||||
short col2;
|
|
||||||
int row2;
|
|
||||||
int anchorType;
|
|
||||||
|
|
||||||
private EscherClientAnchorRecord escherClientAnchorRecord;
|
private EscherClientAnchorRecord _escherClientAnchor;
|
||||||
|
|
||||||
public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) {
|
public HSSFClientAnchor(EscherClientAnchorRecord escherClientAnchorRecord) {
|
||||||
this.escherClientAnchorRecord = escherClientAnchorRecord;
|
this._escherClientAnchor = escherClientAnchorRecord;
|
||||||
//TODO set properties or read properties from EscherRecord ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new client anchor and defaults all the anchor positions to 0.
|
* Creates a new client anchor and defaults all the anchor positions to 0.
|
||||||
*/
|
*/
|
||||||
public HSSFClientAnchor()
|
public HSSFClientAnchor() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new client anchor and sets the top-left and bottom-right
|
* Creates a new client anchor and sets the top-left and bottom-right
|
||||||
* coordinates of the anchor.
|
* coordinates of the anchor.
|
||||||
*
|
*
|
||||||
* @param dx1 the x coordinate within the first cell.
|
* @param dx1 the x coordinate within the first cell.
|
||||||
* @param dy1 the y coordinate within the first cell.
|
* @param dy1 the y coordinate within the first cell.
|
||||||
* @param dx2 the x coordinate within the second cell.
|
* @param dx2 the x coordinate within the second cell.
|
||||||
* @param dy2 the y coordinate within the second cell.
|
* @param dy2 the y coordinate within the second cell.
|
||||||
* @param col1 the column (0 based) of the first cell.
|
* @param col1 the column (0 based) of the first cell.
|
||||||
* @param row1 the row (0 based) of the first cell.
|
* @param row1 the row (0 based) of the first cell.
|
||||||
* @param col2 the column (0 based) of the second cell.
|
* @param col2 the column (0 based) of the second cell.
|
||||||
* @param row2 the row (0 based) of the second cell.
|
* @param row2 the row (0 based) of the second cell.
|
||||||
*/
|
*/
|
||||||
public HSSFClientAnchor( int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2 )
|
public HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2) {
|
||||||
{
|
super(dx1, dy1, dx2, dy2);
|
||||||
super( dx1, dy1, dx2, dy2 );
|
|
||||||
|
|
||||||
checkRange(dx1, 0, 1023, "dx1");
|
checkRange(dx1, 0, 1023, "dx1");
|
||||||
checkRange(dx2, 0, 1023, "dx2");
|
checkRange(dx2, 0, 1023, "dx2");
|
||||||
@ -74,35 +66,30 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
|||||||
checkRange(row1, 0, 255 * 256, "row1");
|
checkRange(row1, 0, 255 * 256, "row1");
|
||||||
checkRange(row2, 0, 255 * 256, "row2");
|
checkRange(row2, 0, 255 * 256, "row2");
|
||||||
|
|
||||||
this.col1 = col1;
|
setCol1(col1);
|
||||||
this.row1 = row1;
|
setCol2(col2);
|
||||||
this.col2 = col2;
|
setRow1(row1);
|
||||||
this.row2 = row2;
|
setRow2(row2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the height of a client anchor in points.
|
* Calculates the height of a client anchor in points.
|
||||||
*
|
*
|
||||||
* @param sheet the sheet the anchor will be attached to
|
* @param sheet the sheet the anchor will be attached to
|
||||||
* @return the shape height.
|
* @return the shape height.
|
||||||
*/
|
*/
|
||||||
public float getAnchorHeightInPoints(HSSFSheet sheet )
|
public float getAnchorHeightInPoints(HSSFSheet sheet) {
|
||||||
{
|
|
||||||
int y1 = getDy1();
|
int y1 = getDy1();
|
||||||
int y2 = getDy2();
|
int y2 = getDy2();
|
||||||
int row1 = Math.min( getRow1(), getRow2() );
|
int row1 = Math.min(getRow1(), getRow2());
|
||||||
int row2 = Math.max( getRow1(), getRow2() );
|
int row2 = Math.max(getRow1(), getRow2());
|
||||||
|
|
||||||
float points = 0;
|
float points = 0;
|
||||||
if (row1 == row2)
|
if (row1 == row2) {
|
||||||
{
|
|
||||||
points = ((y2 - y1) / 256.0f) * getRowHeightInPoints(sheet, row2);
|
points = ((y2 - y1) / 256.0f) * getRowHeightInPoints(sheet, row2);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
points += ((256.0f - y1) / 256.0f) * getRowHeightInPoints(sheet, row1);
|
points += ((256.0f - y1) / 256.0f) * getRowHeightInPoints(sheet, row1);
|
||||||
for (int i = row1 + 1; i < row2; i++)
|
for (int i = row1 + 1; i < row2; i++) {
|
||||||
{
|
|
||||||
points += getRowHeightInPoints(sheet, i);
|
points += getRowHeightInPoints(sheet, i);
|
||||||
}
|
}
|
||||||
points += (y2 / 256.0f) * getRowHeightInPoints(sheet, row2);
|
points += (y2 / 256.0f) * getRowHeightInPoints(sheet, row2);
|
||||||
@ -111,8 +98,7 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getRowHeightInPoints(HSSFSheet sheet, int rowNum)
|
private float getRowHeightInPoints(HSSFSheet sheet, int rowNum) {
|
||||||
{
|
|
||||||
HSSFRow row = sheet.getRow(rowNum);
|
HSSFRow row = sheet.getRow(rowNum);
|
||||||
if (row == null) {
|
if (row == null) {
|
||||||
return sheet.getDefaultRowHeightInPoints();
|
return sheet.getDefaultRowHeightInPoints();
|
||||||
@ -120,55 +106,48 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
|||||||
return row.getHeightInPoints();
|
return row.getHeightInPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getCol1()
|
public short getCol1() {
|
||||||
{
|
return _escherClientAnchor.getCol1();
|
||||||
return col1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCol1( short col1 )
|
public void setCol1(short col1) {
|
||||||
{
|
|
||||||
checkRange(col1, 0, 255, "col1");
|
checkRange(col1, 0, 255, "col1");
|
||||||
this.col1 = col1;
|
_escherClientAnchor.setCol1(col1);
|
||||||
}
|
|
||||||
public void setCol1( int col1 ){
|
|
||||||
setCol1((short)col1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getCol2()
|
public void setCol1(int col1) {
|
||||||
{
|
setCol1((short) col1);
|
||||||
return col2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCol2( short col2 )
|
public short getCol2() {
|
||||||
{
|
return _escherClientAnchor.getCol2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCol2(short col2) {
|
||||||
checkRange(col2, 0, 255, "col2");
|
checkRange(col2, 0, 255, "col2");
|
||||||
this.col2 = col2;
|
_escherClientAnchor.setCol2(col2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCol2( int col2 ){
|
public void setCol2(int col2) {
|
||||||
setCol2((short)col2);
|
setCol2((short) col2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRow1()
|
public int getRow1() {
|
||||||
{
|
return _escherClientAnchor.getRow1();
|
||||||
return row1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRow1( int row1 )
|
public void setRow1(int row1) {
|
||||||
{
|
|
||||||
checkRange(row1, 0, 256 * 256, "row1");
|
checkRange(row1, 0, 256 * 256, "row1");
|
||||||
this.row1 = row1;
|
_escherClientAnchor.setRow1(Integer.valueOf(row1).shortValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRow2()
|
public int getRow2() {
|
||||||
{
|
return _escherClientAnchor.getRow2();
|
||||||
return row2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRow2( int row2 )
|
public void setRow2(int row2) {
|
||||||
{
|
|
||||||
checkRange(row2, 0, 256 * 256, "row2");
|
checkRange(row2, 0, 256 * 256, "row2");
|
||||||
this.row2 = row2;
|
_escherClientAnchor.setRow2(Integer.valueOf(row2).shortValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -179,79 +158,139 @@ public final class HSSFClientAnchor extends HSSFAnchor implements ClientAnchor {
|
|||||||
* @param y1 the y coordinate within the first cell.
|
* @param y1 the y coordinate within the first cell.
|
||||||
* @param x2 the x coordinate within the second cell.
|
* @param x2 the x coordinate within the second cell.
|
||||||
* @param y2 the y coordinate within the second cell.
|
* @param y2 the y coordinate within the second cell.
|
||||||
* @param col1 the column (0 based) of the first cell.
|
* @param col1 the column (0 based) of the first cell.
|
||||||
* @param row1 the row (0 based) of the first cell.
|
* @param row1 the row (0 based) of the first cell.
|
||||||
* @param col2 the column (0 based) of the second cell.
|
* @param col2 the column (0 based) of the second cell.
|
||||||
* @param row2 the row (0 based) of the second cell.
|
* @param row2 the row (0 based) of the second cell.
|
||||||
*/
|
*/
|
||||||
public void setAnchor( short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2 )
|
public void setAnchor(short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2) {
|
||||||
{
|
checkRange(getDx1(), 0, 1023, "dx1");
|
||||||
checkRange(dx1, 0, 1023, "dx1");
|
checkRange(getDx2(), 0, 1023, "dx2");
|
||||||
checkRange(dx2, 0, 1023, "dx2");
|
checkRange(getDy1(), 0, 255, "dy1");
|
||||||
checkRange(dy1, 0, 255, "dy1");
|
checkRange(getDy2(), 0, 255, "dy2");
|
||||||
checkRange(dy2, 0, 255, "dy2");
|
checkRange(getCol1(), 0, 255, "col1");
|
||||||
checkRange(col1, 0, 255, "col1");
|
checkRange(getCol2(), 0, 255, "col2");
|
||||||
checkRange(col2, 0, 255, "col2");
|
checkRange(getRow1(), 0, 255 * 256, "row1");
|
||||||
checkRange(row1, 0, 255 * 256, "row1");
|
checkRange(getRow2(), 0, 255 * 256, "row2");
|
||||||
checkRange(row2, 0, 255 * 256, "row2");
|
|
||||||
|
|
||||||
this.col1 = col1;
|
setCol1(col1);
|
||||||
this.row1 = row1;
|
setRow1(row1);
|
||||||
this.dx1 = x1;
|
setDx1(x1);
|
||||||
this.dy1 = y1;
|
setDy1(y1);
|
||||||
this.col2 = col2;
|
setCol2(col2);
|
||||||
this.row2 = row2;
|
setRow2(row2);
|
||||||
this.dx2 = x2;
|
setDx2(x2);
|
||||||
this.dy2 = y2;
|
setDy2(y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the anchor goes from right to left.
|
* @return true if the anchor goes from right to left.
|
||||||
*/
|
*/
|
||||||
public boolean isHorizontallyFlipped()
|
public boolean isHorizontallyFlipped() {
|
||||||
{
|
if (getCol1() == getCol2()) {
|
||||||
if (col1 == col2) {
|
return getDx1() > getDx2();
|
||||||
return dx1 > dx2;
|
|
||||||
}
|
}
|
||||||
return col1 > col2;
|
return getCol1() > getCol2();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the anchor goes from bottom to top.
|
* @return true if the anchor goes from bottom to top.
|
||||||
*/
|
*/
|
||||||
public boolean isVerticallyFlipped()
|
public boolean isVerticallyFlipped() {
|
||||||
{
|
if (getRow1() == getRow2()) {
|
||||||
if (row1 == row2) {
|
return getDy1() > getDy2();
|
||||||
return dy1 > dy2;
|
|
||||||
}
|
}
|
||||||
return row1 > row2;
|
return getRow1() > getRow2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EscherRecord getEscherAnchor() {
|
||||||
|
return _escherClientAnchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createEscherAnchor() {
|
||||||
|
_escherClientAnchor = new EscherClientAnchorRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the anchor type
|
* Gets the anchor type
|
||||||
* <p>
|
* <p/>
|
||||||
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
||||||
*/
|
*/
|
||||||
public int getAnchorType()
|
public int getAnchorType() {
|
||||||
{
|
return _escherClientAnchor.getFlag();
|
||||||
return anchorType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the anchor type
|
* Sets the anchor type
|
||||||
* <p>
|
* <p/>
|
||||||
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
* 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = Don't move or size with cells.
|
||||||
*/
|
*/
|
||||||
public void setAnchorType( int anchorType )
|
public void setAnchorType(int anchorType) {
|
||||||
{
|
// if (0 != anchorType && 2 != anchorType && 3 != anchorType){
|
||||||
this.anchorType = anchorType;
|
// throw new IllegalArgumentException("Anchor type of shape can take only such values: 0, 2, 3");
|
||||||
|
// }
|
||||||
|
_escherClientAnchor.setFlag(Integer.valueOf(anchorType).shortValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRange( int value, int minRange, int maxRange, String varName )
|
private void checkRange(int value, int minRange, int maxRange, String varName) {
|
||||||
{
|
|
||||||
if (value < minRange || value > maxRange)
|
if (value < minRange || value > maxRange)
|
||||||
throw new IllegalArgumentException(varName + " must be between " + minRange + " and " + maxRange);
|
throw new IllegalArgumentException(varName + " must be between " + minRange + " and " + maxRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (obj == this)
|
||||||
|
return true;
|
||||||
|
if (obj.getClass() != getClass())
|
||||||
|
return false;
|
||||||
|
HSSFClientAnchor anchor = (HSSFClientAnchor) obj;
|
||||||
|
|
||||||
|
return anchor.getCol1() == getCol1() && anchor.getCol2() == getCol2() && anchor.getDx1() == getDx1()
|
||||||
|
&& anchor.getDx2() == getDx2() && anchor.getDy1() == getDy1() && anchor.getDy2() == getDy2()
|
||||||
|
&& anchor.getRow1() == getRow1() && anchor.getRow2() == getRow2() && anchor.getAnchorType() == getAnchorType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDx1() {
|
||||||
|
return _escherClientAnchor.getDx1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDx1(int dx1) {
|
||||||
|
_escherClientAnchor.setDx1(Integer.valueOf(dx1).shortValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDy1() {
|
||||||
|
return _escherClientAnchor.getDy1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDy1(int dy1) {
|
||||||
|
_escherClientAnchor.setDy1(Integer.valueOf(dy1).shortValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDy2() {
|
||||||
|
return _escherClientAnchor.getDy2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDy2(int dy2) {
|
||||||
|
_escherClientAnchor.setDy2(Integer.valueOf(dy2).shortValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDx2() {
|
||||||
|
return _escherClientAnchor.getDx2();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDx2(int dx2) {
|
||||||
|
_escherClientAnchor.setDx2(Integer.valueOf(dx2).shortValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public class HSSFComment extends HSSFTextbox implements Comment {
|
|||||||
setShapeType(OBJECT_TYPE_COMMENT);
|
setShapeType(OBJECT_TYPE_COMMENT);
|
||||||
|
|
||||||
//default color for comments
|
//default color for comments
|
||||||
_fillColor = 0x08000050;
|
setFillColor(0x08000050);
|
||||||
|
|
||||||
//by default comments are hidden
|
//by default comments are hidden
|
||||||
_visible = false;
|
_visible = false;
|
||||||
|
@ -145,8 +145,8 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
|||||||
float w = 0;
|
float w = 0;
|
||||||
|
|
||||||
//space in the leftmost cell
|
//space in the leftmost cell
|
||||||
w += getColumnWidthInPixels(anchor.col1)*(1 - (float)anchor.dx1/1024);
|
w += getColumnWidthInPixels(anchor.getCol1())*(1 - (float)anchor.getDx1()/1024);
|
||||||
short col2 = (short)(anchor.col1 + 1);
|
short col2 = (short)(anchor.getCol1() + 1);
|
||||||
int dx2 = 0;
|
int dx2 = 0;
|
||||||
|
|
||||||
while(w < scaledWidth){
|
while(w < scaledWidth){
|
||||||
@ -160,12 +160,12 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
|||||||
double delta = w - scaledWidth;
|
double delta = w - scaledWidth;
|
||||||
dx2 = (int)((cw-delta)/cw*1024);
|
dx2 = (int)((cw-delta)/cw*1024);
|
||||||
}
|
}
|
||||||
anchor.col2 = col2;
|
anchor.setCol2(col2);
|
||||||
anchor.dx2 = dx2;
|
anchor.setDx2(dx2);
|
||||||
|
|
||||||
float h = 0;
|
float h = 0;
|
||||||
h += (1 - (float)anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
|
h += (1 - (float)anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1());
|
||||||
int row2 = anchor.row1 + 1;
|
int row2 = anchor.getRow1() + 1;
|
||||||
int dy2 = 0;
|
int dy2 = 0;
|
||||||
|
|
||||||
while(h < scaledHeight){
|
while(h < scaledHeight){
|
||||||
@ -177,8 +177,8 @@ public final class HSSFPicture extends HSSFSimpleShape implements Picture {
|
|||||||
double delta = h - scaledHeight;
|
double delta = h - scaledHeight;
|
||||||
dy2 = (int)((ch-delta)/ch*256);
|
dy2 = (int)((ch-delta)/ch*256);
|
||||||
}
|
}
|
||||||
anchor.row2 = row2;
|
anchor.setRow2(row2);
|
||||||
anchor.dy2 = dy2;
|
anchor.setDy2(dy2);
|
||||||
|
|
||||||
return anchor;
|
return anchor;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package org.apache.poi.hssf.usermodel;
|
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherContainerRecord;
|
|
||||||
import org.apache.poi.hssf.record.ObjRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Evgeniy Berlog
|
|
||||||
* @date 08.06.12
|
|
||||||
*/
|
|
||||||
public class HSSFRectangle extends HSSFShape{
|
|
||||||
|
|
||||||
public HSSFRectangle(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
|
||||||
super(spContainer, objRecord);
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
import org.apache.poi.ddf.EscherContainerRecord;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hssf.record.ObjRecord;
|
import org.apache.poi.hssf.record.ObjRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,6 +28,8 @@ import org.apache.poi.hssf.record.ObjRecord;
|
|||||||
public abstract class HSSFShape {
|
public abstract class HSSFShape {
|
||||||
public static final int LINEWIDTH_ONE_PT = 12700;
|
public static final int LINEWIDTH_ONE_PT = 12700;
|
||||||
public static final int LINEWIDTH_DEFAULT = 9525;
|
public static final int LINEWIDTH_DEFAULT = 9525;
|
||||||
|
public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040;
|
||||||
|
public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009;
|
||||||
|
|
||||||
public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
|
public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
|
||||||
public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
|
public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
|
||||||
@ -45,50 +47,53 @@ public abstract class HSSFShape {
|
|||||||
// TODO - make all these fields private
|
// TODO - make all these fields private
|
||||||
HSSFShape parent;
|
HSSFShape parent;
|
||||||
HSSFAnchor anchor;
|
HSSFAnchor anchor;
|
||||||
HSSFPatriarch _patriarch;
|
HSSFPatriarch _patriarch;
|
||||||
private int _lineStyleColor = 0x08000040;
|
|
||||||
int _fillColor = 0x08000009;
|
|
||||||
private int _lineWidth = LINEWIDTH_DEFAULT; // 12700 = 1pt
|
|
||||||
private int _lineStyle = LINESTYLE_SOLID;
|
|
||||||
private boolean _noFill = false;
|
|
||||||
|
|
||||||
private EscherContainerRecord spContainer;
|
protected EscherContainerRecord _escherContainer;
|
||||||
private ObjRecord objRecord;
|
protected ObjRecord _objRecord;
|
||||||
|
protected final EscherOptRecord _optRecord;
|
||||||
|
|
||||||
public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord){
|
public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||||
this.spContainer = spContainer;
|
this._escherContainer = spContainer;
|
||||||
this.objRecord = objRecord;
|
this._objRecord = objRecord;
|
||||||
|
this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||||
|
this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new shape with the specified parent and anchor.
|
* Create a new shape with the specified parent and anchor.
|
||||||
*/
|
*/
|
||||||
public HSSFShape( HSSFShape parent, HSSFAnchor anchor )
|
public HSSFShape(HSSFShape parent, HSSFAnchor anchor) {
|
||||||
{
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.anchor = anchor;
|
this.anchor = anchor;
|
||||||
|
this._escherContainer = new EscherContainerRecord();
|
||||||
|
_optRecord = new EscherOptRecord();
|
||||||
|
_optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
|
||||||
|
_optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
|
||||||
|
_optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
|
||||||
|
_optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
|
||||||
|
_optRecord.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EscherContainerRecord getSpContainer() {
|
public EscherContainerRecord getEscherContainer() {
|
||||||
return spContainer;
|
return _escherContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjRecord getObjRecord() {
|
public ObjRecord getObjRecord() {
|
||||||
return objRecord;
|
return _objRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the parent shape.
|
* Gets the parent shape.
|
||||||
*/
|
*/
|
||||||
public HSSFShape getParent()
|
public HSSFShape getParent() {
|
||||||
{
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the anchor that is used by this shape.
|
* @return the anchor that is used by this shape.
|
||||||
*/
|
*/
|
||||||
public HSSFAnchor getAnchor()
|
public HSSFAnchor getAnchor() {
|
||||||
{
|
|
||||||
return anchor;
|
return anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,26 +101,29 @@ public abstract class HSSFShape {
|
|||||||
* Sets a particular anchor. A top-level shape must have an anchor of
|
* Sets a particular anchor. A top-level shape must have an anchor of
|
||||||
* HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
|
* HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
|
||||||
*
|
*
|
||||||
* @param anchor the anchor to use.
|
* @param anchor the anchor to use.
|
||||||
* @throws IllegalArgumentException when the wrong anchor is used for
|
* @throws IllegalArgumentException when the wrong anchor is used for
|
||||||
* this particular shape.
|
* this particular shape.
|
||||||
*
|
|
||||||
* @see HSSFChildAnchor
|
* @see HSSFChildAnchor
|
||||||
* @see HSSFClientAnchor
|
* @see HSSFClientAnchor
|
||||||
*/
|
*/
|
||||||
public void setAnchor( HSSFAnchor anchor )
|
public void setAnchor(HSSFAnchor anchor) {
|
||||||
{
|
if (parent == null) {
|
||||||
if ( parent == null )
|
if (anchor instanceof HSSFChildAnchor)
|
||||||
{
|
throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet.");
|
||||||
if ( anchor instanceof HSSFChildAnchor )
|
EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID);
|
||||||
throw new IllegalArgumentException( "Must use client anchors for shapes directly attached to sheet." );
|
if (null != anch) {
|
||||||
|
_escherContainer.removeChildRecord(anch);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (anchor instanceof HSSFClientAnchor)
|
||||||
|
throw new IllegalArgumentException("Must use child anchors for shapes attached to groups.");
|
||||||
|
EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID);
|
||||||
|
if (null != anch) {
|
||||||
|
_escherContainer.removeChildRecord(anch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
_escherContainer.addChildRecord(anchor.getEscherAnchor());
|
||||||
{
|
|
||||||
if ( anchor instanceof HSSFClientAnchor )
|
|
||||||
throw new IllegalArgumentException( "Must use child anchors for shapes attached to groups." );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.anchor = anchor;
|
this.anchor = anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,92 +131,141 @@ public abstract class HSSFShape {
|
|||||||
* The color applied to the lines of this shape.
|
* The color applied to the lines of this shape.
|
||||||
*/
|
*/
|
||||||
public int getLineStyleColor() {
|
public int getLineStyleColor() {
|
||||||
return _lineStyleColor;
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
|
||||||
|
return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color applied to the lines of this shape.
|
* The color applied to the lines of this shape.
|
||||||
*/
|
*/
|
||||||
public void setLineStyleColor(int lineStyleColor) {
|
public void setLineStyleColor(int lineStyleColor) {
|
||||||
_lineStyleColor = lineStyleColor;
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
|
||||||
|
if (null == rgbProperty) {
|
||||||
|
rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor);
|
||||||
|
_optRecord.addEscherProperty(rgbProperty);
|
||||||
|
} else {
|
||||||
|
rgbProperty.setRgbColor(lineStyleColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color applied to the lines of this shape.
|
* The color applied to the lines of this shape.
|
||||||
*/
|
*/
|
||||||
public void setLineStyleColor(int red, int green, int blue) {
|
public void setLineStyleColor(int red, int green, int blue) {
|
||||||
this._lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
|
int lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
|
||||||
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
|
||||||
|
if (null == rgbProperty) {
|
||||||
|
rgbProperty = new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor);
|
||||||
|
_optRecord.addEscherProperty(rgbProperty);
|
||||||
|
} else {
|
||||||
|
rgbProperty.setRgbColor(lineStyleColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color used to fill this shape.
|
* The color used to fill this shape.
|
||||||
*/
|
*/
|
||||||
public int getFillColor()
|
public int getFillColor() {
|
||||||
{
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
|
||||||
return _fillColor;
|
return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color used to fill this shape.
|
* The color used to fill this shape.
|
||||||
*/
|
*/
|
||||||
public void setFillColor(int fillColor) {
|
public void setFillColor(int fillColor) {
|
||||||
_fillColor = fillColor;
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
|
||||||
|
if (null == rgbProperty) {
|
||||||
|
rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor);
|
||||||
|
_optRecord.addEscherProperty(rgbProperty);
|
||||||
|
} else {
|
||||||
|
rgbProperty.setRgbColor(fillColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color used to fill this shape.
|
* The color used to fill this shape.
|
||||||
*/
|
*/
|
||||||
public void setFillColor( int red, int green, int blue )
|
public void setFillColor(int red, int green, int blue) {
|
||||||
{
|
int fillColor = ((blue) << 16) | ((green) << 8) | red;
|
||||||
this._fillColor = ((blue) << 16) | ((green) << 8) | red;
|
EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
|
||||||
|
if (null == rgbProperty) {
|
||||||
|
rgbProperty = new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor);
|
||||||
|
_optRecord.addEscherProperty(rgbProperty);
|
||||||
|
} else {
|
||||||
|
rgbProperty.setRgbColor(fillColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return returns with width of the line in EMUs. 12700 = 1 pt.
|
* @return returns with width of the line in EMUs. 12700 = 1 pt.
|
||||||
*/
|
*/
|
||||||
public int getLineWidth() {
|
public int getLineWidth() {
|
||||||
return _lineWidth;
|
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH);
|
||||||
|
return property.getPropertyValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the width of the line. 12700 = 1 pt.
|
* Sets the width of the line. 12700 = 1 pt.
|
||||||
*
|
*
|
||||||
* @param lineWidth width in EMU's. 12700EMU's = 1 pt
|
* @param lineWidth width in EMU's. 12700EMU's = 1 pt
|
||||||
*
|
|
||||||
* @see HSSFShape#LINEWIDTH_ONE_PT
|
* @see HSSFShape#LINEWIDTH_ONE_PT
|
||||||
*/
|
*/
|
||||||
public void setLineWidth(int lineWidth) {
|
public void setLineWidth(int lineWidth) {
|
||||||
_lineWidth = lineWidth;
|
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH);
|
||||||
|
if (null == property) {
|
||||||
|
property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth);
|
||||||
|
_optRecord.addEscherProperty(property);
|
||||||
|
} else {
|
||||||
|
property.setPropertyValue(lineWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return One of the constants in LINESTYLE_*
|
* @return One of the constants in LINESTYLE_*
|
||||||
*/
|
*/
|
||||||
public int getLineStyle() {
|
public int getLineStyle() {
|
||||||
return _lineStyle;
|
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING);
|
||||||
|
if (null == property){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return property.getPropertyValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the line style.
|
* Sets the line style.
|
||||||
*
|
*
|
||||||
* @param lineStyle One of the constants in LINESTYLE_*
|
* @param lineStyle One of the constants in LINESTYLE_*
|
||||||
*/
|
*/
|
||||||
public void setLineStyle(int lineStyle) {
|
public void setLineStyle(int lineStyle) {
|
||||||
_lineStyle = lineStyle;
|
EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING);
|
||||||
|
if (null == property) {
|
||||||
|
property = new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle);
|
||||||
|
_optRecord.addEscherProperty(property);
|
||||||
|
} else {
|
||||||
|
property.setPropertyValue(lineStyle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return <code>true</code> if this shape is not filled with a color.
|
* @return <code>true</code> if this shape is not filled with a color.
|
||||||
*/
|
*/
|
||||||
public boolean isNoFill() {
|
public boolean isNoFill() {
|
||||||
return _noFill;
|
EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
|
||||||
|
return property.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this shape is filled or transparent.
|
* Sets whether this shape is filled or transparent.
|
||||||
*/
|
*/
|
||||||
public void setNoFill(boolean noFill) {
|
public void setNoFill(boolean noFill) {
|
||||||
_noFill = noFill;
|
EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
|
||||||
|
if (null == property) {
|
||||||
|
property = new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? 1 : 0);
|
||||||
|
_optRecord.addEscherProperty(property);
|
||||||
|
} else {
|
||||||
|
property.setPropertyValue(noFill ? 1 : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,25 +39,25 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author evgeniy
|
* @author Evgeniy Berlog
|
||||||
* date: 05.06.12
|
* date: 05.06.12
|
||||||
*/
|
*/
|
||||||
public class HSSFShapeFactory {
|
public class HSSFShapeFactory {
|
||||||
|
|
||||||
private static final Map<Short, Class> shapeTypeToClass = new HashMap<Short, Class>(HSSFShapeType.values().length);
|
private static final Map<Short, HSSFShapeType> shapeTypeToClass = new HashMap<Short, HSSFShapeType>(HSSFShapeType.values().length);
|
||||||
private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass);
|
private static final ReflectionConstructorShapeCreator shapeCreator = new ReflectionConstructorShapeCreator(shapeTypeToClass);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (HSSFShapeType type: HSSFShapeType.values()){
|
for (HSSFShapeType type: HSSFShapeType.values()){
|
||||||
shapeTypeToClass.put(type.getType(), type.getShape());
|
shapeTypeToClass.put(type.getType(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ReflectionConstructorShapeCreator {
|
private static class ReflectionConstructorShapeCreator {
|
||||||
|
|
||||||
private final Map<Short, Class> shapeTypeToClass;
|
private final Map<Short, HSSFShapeType> shapeTypeToClass;
|
||||||
|
|
||||||
private ReflectionConstructorShapeCreator(Map<Short, Class> shapeTypeToClass) {
|
private ReflectionConstructorShapeCreator(Map<Short, HSSFShapeType> shapeTypeToClass) {
|
||||||
this.shapeTypeToClass = shapeTypeToClass;
|
this.shapeTypeToClass = shapeTypeToClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public class HSSFShapeFactory {
|
|||||||
if (!shapeTypeToClass.containsKey(type)){
|
if (!shapeTypeToClass.containsKey(type)){
|
||||||
return new HSSFUnknownShape(spContainer, objRecord);
|
return new HSSFUnknownShape(spContainer, objRecord);
|
||||||
}
|
}
|
||||||
Class clazz = shapeTypeToClass.get(type);
|
Class clazz = shapeTypeToClass.get(type).getShape();
|
||||||
if (null == clazz){
|
if (null == clazz){
|
||||||
//System.out.println("No class attached to shape type: "+type);
|
//System.out.println("No class attached to shape type: "+type);
|
||||||
return new HSSFUnknownShape(spContainer, objRecord);
|
return new HSSFUnknownShape(spContainer, objRecord);
|
||||||
@ -81,26 +81,6 @@ public class HSSFShapeFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HSSFShape createShape(EscherRecord container, ObjRecord objRecord){
|
|
||||||
if (0 == container.getChildRecords().size()){
|
|
||||||
throw new IllegalArgumentException("Couldn't create shape from empty escher container");
|
|
||||||
}
|
|
||||||
if (container.getChild(0) instanceof EscherSpgrRecord){
|
|
||||||
return new HSSFShapeGroup((EscherContainerRecord) container, objRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO implement cases for all shapes
|
|
||||||
return new HSSFUnknownShape(container, objRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HSSFShapeGroup createShapeGroup(){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HSSFShapeGroup createSimpleShape(EscherRecord container, ObjRecord objRecord){
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out){
|
public static void createShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out){
|
||||||
if(container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
|
if(container.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
|
||||||
HSSFShapeGroup group = new HSSFShapeGroup(container,
|
HSSFShapeGroup group = new HSSFShapeGroup(container,
|
||||||
@ -111,10 +91,6 @@ public class HSSFShapeFactory {
|
|||||||
EscherContainerRecord spContainer = children.get(i);
|
EscherContainerRecord spContainer = children.get(i);
|
||||||
if(i == 0){
|
if(i == 0){
|
||||||
EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
EscherSpgrRecord spgr = (EscherSpgrRecord)spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
||||||
group.setCoordinates(
|
|
||||||
spgr.getRectX1(), spgr.getRectY1(),
|
|
||||||
spgr.getRectX2(), spgr.getRectY2()
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
createShapeTree(spContainer, agg, group);
|
createShapeTree(spContainer, agg, group);
|
||||||
}
|
}
|
||||||
|
@ -41,32 +41,23 @@ public class HSSFShapeGroup
|
|||||||
implements HSSFShapeContainer
|
implements HSSFShapeContainer
|
||||||
{
|
{
|
||||||
List<HSSFShape> shapes = new ArrayList<HSSFShape>();
|
List<HSSFShape> shapes = new ArrayList<HSSFShape>();
|
||||||
int x1 = 0;
|
private EscherSpgrRecord _spgrRecord;
|
||||||
int y1 = 0 ;
|
|
||||||
int x2 = 1023;
|
|
||||||
int y2 = 255;
|
|
||||||
|
|
||||||
public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) {
|
public HSSFShapeGroup(EscherContainerRecord spgrContainer, ObjRecord objRecord) {
|
||||||
super(spgrContainer, objRecord);
|
super(spgrContainer, objRecord);
|
||||||
|
|
||||||
// read internal and external coordinates from spgrContainer
|
// read internal and external coordinates from spgrContainer
|
||||||
EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0);
|
EscherContainerRecord spContainer = spgrContainer.getChildContainers().get(0);
|
||||||
|
_spgrRecord = (EscherSpgrRecord) spContainer.getChild(0);
|
||||||
for(EscherRecord ch : spContainer.getChildRecords()){
|
for(EscherRecord ch : spContainer.getChildRecords()){
|
||||||
switch(ch.getRecordId()) {
|
switch(ch.getRecordId()) {
|
||||||
case EscherSpgrRecord.RECORD_ID:
|
case EscherSpgrRecord.RECORD_ID:
|
||||||
EscherSpgrRecord spgr = (EscherSpgrRecord)ch;
|
|
||||||
setCoordinates(
|
|
||||||
spgr.getRectX1(), spgr.getRectY1(),
|
|
||||||
spgr.getRectX2(), spgr.getRectY2()
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case EscherClientAnchorRecord.RECORD_ID:
|
case EscherClientAnchorRecord.RECORD_ID:
|
||||||
this.anchor = EscherAggregate.toClientAnchor((EscherClientAnchorRecord)ch);
|
anchor = new HSSFClientAnchor((EscherClientAnchorRecord)ch);
|
||||||
// TODO anchor = new HSSFClientAnchor((EscherChildAnchorRecord)ch);
|
|
||||||
break;
|
break;
|
||||||
case EscherChildAnchorRecord.RECORD_ID:
|
case EscherChildAnchorRecord.RECORD_ID:
|
||||||
this.anchor = EscherAggregate.toChildAnchor((EscherChildAnchorRecord)ch);
|
anchor = new HSSFChildAnchor((EscherChildAnchorRecord)ch);
|
||||||
// TODO anchor = new HSSFChildAnchor((EscherClientAnchorRecord)ch);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,6 +67,11 @@ public class HSSFShapeGroup
|
|||||||
public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
|
public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
|
||||||
{
|
{
|
||||||
super( parent, anchor );
|
super( parent, anchor );
|
||||||
|
_spgrRecord = new EscherSpgrRecord();
|
||||||
|
_spgrRecord.setRectX1(0);
|
||||||
|
_spgrRecord.setRectX2(1023);
|
||||||
|
_spgrRecord.setRectY1(0);
|
||||||
|
_spgrRecord.setRectY2(255);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,10 +167,10 @@ public class HSSFShapeGroup
|
|||||||
*/
|
*/
|
||||||
public void setCoordinates( int x1, int y1, int x2, int y2 )
|
public void setCoordinates( int x1, int y1, int x2, int y2 )
|
||||||
{
|
{
|
||||||
this.x1 = x1;
|
_spgrRecord.setRectX1(x1);
|
||||||
this.y1 = y1;
|
_spgrRecord.setRectX2(x2);
|
||||||
this.x2 = x2;
|
_spgrRecord.setRectY1(y1);
|
||||||
this.y2 = y2;
|
_spgrRecord.setRectY2(y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +178,7 @@ public class HSSFShapeGroup
|
|||||||
*/
|
*/
|
||||||
public int getX1()
|
public int getX1()
|
||||||
{
|
{
|
||||||
return x1;
|
return _spgrRecord.getRectX1();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,7 +186,7 @@ public class HSSFShapeGroup
|
|||||||
*/
|
*/
|
||||||
public int getY1()
|
public int getY1()
|
||||||
{
|
{
|
||||||
return y1;
|
return _spgrRecord.getRectY1();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,7 +194,7 @@ public class HSSFShapeGroup
|
|||||||
*/
|
*/
|
||||||
public int getX2()
|
public int getX2()
|
||||||
{
|
{
|
||||||
return x2;
|
return _spgrRecord.getRectX2();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,7 +202,7 @@ public class HSSFShapeGroup
|
|||||||
*/
|
*/
|
||||||
public int getY2()
|
public int getY2()
|
||||||
{
|
{
|
||||||
return y2;
|
return _spgrRecord.getRectY2();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.usermodel;
|
package org.apache.poi.hssf.usermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
|
||||||
|
import org.apache.poi.hssf.record.ObjRecord;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a simple shape such as a line, rectangle or oval.
|
* Represents a simple shape such as a line, rectangle or oval.
|
||||||
*
|
*
|
||||||
@ -52,7 +56,13 @@ public class HSSFSimpleShape
|
|||||||
|
|
||||||
int shapeType = OBJECT_TYPE_LINE;
|
int shapeType = OBJECT_TYPE_LINE;
|
||||||
|
|
||||||
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor )
|
public HSSFSimpleShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
|
||||||
|
super(spContainer, objRecord);
|
||||||
|
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) objRecord.getSubRecords().get(0);
|
||||||
|
setShapeType(cod.getObjectType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor)
|
||||||
{
|
{
|
||||||
super( parent, anchor );
|
super( parent, anchor );
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
package org.apache.poi.hssf.usermodel.drawing;
|
package org.apache.poi.hssf.usermodel.drawing;
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFRectangle;
|
import org.apache.poi.hssf.usermodel.HSSFSimpleShape;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Evgeniy Berlog
|
* @author Evgeniy Berlog
|
||||||
* date: 08.06.12
|
* date: 08.06.12
|
||||||
*/
|
*/
|
||||||
public enum HSSFShapeType {
|
public enum HSSFShapeType {
|
||||||
NOT_PRIMITIVE(0x0, null),
|
NOT_PRIMITIVE((short)0x0, null, (short)0),
|
||||||
RECTANGLE(0x1, HSSFRectangle.class),
|
RECTANGLE((short)0x1, HSSFSimpleShape.class, HSSFSimpleShape.OBJECT_TYPE_RECTANGLE),
|
||||||
ROUND_RECTANGLE(0x2, null);
|
ROUND_RECTANGLE((short)0x2, null, null);
|
||||||
|
|
||||||
private Short type;
|
private Short type;
|
||||||
private Class shape;
|
private Class shape;
|
||||||
|
private Short objectId;
|
||||||
|
|
||||||
HSSFShapeType(Integer type, Class shape) {
|
private HSSFShapeType(Short type, Class shape, Short objectId) {
|
||||||
this.type = type.shortValue();
|
this.type = type;
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
|
this.objectId = objectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Short getType() {
|
public Short getType() {
|
||||||
|
160
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
Normal file
160
src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
package org.apache.poi.hssf.model;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
|
import org.apache.poi.hssf.usermodel.*;
|
||||||
|
import org.apache.poi.util.HexDump;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Evgeniy Berlog
|
||||||
|
* date: 12.06.12
|
||||||
|
*/
|
||||||
|
public class TestDrawingShapes extends TestCase{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSSFShape tree bust be built correctly
|
||||||
|
* Check file with such records structure:
|
||||||
|
* -patriarch
|
||||||
|
* --shape
|
||||||
|
* --group
|
||||||
|
* ---group
|
||||||
|
* ----shape
|
||||||
|
* ----shape
|
||||||
|
* ---shape
|
||||||
|
* ---group
|
||||||
|
* ----shape
|
||||||
|
* ----shape
|
||||||
|
*/
|
||||||
|
public void testDrawingGroups(){
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||||
|
HSSFSheet sheet = wb.getSheet("groups");
|
||||||
|
HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
|
||||||
|
assertEquals(patriarch.getChildren().size(), 2);
|
||||||
|
HSSFShapeGroup group = (HSSFShapeGroup) patriarch.getChildren().get(1);
|
||||||
|
assertEquals(3, group.getChildren().size());
|
||||||
|
HSSFShapeGroup group1 = (HSSFShapeGroup) group.getChildren().get(0);
|
||||||
|
assertEquals(2, group1.getChildren().size());
|
||||||
|
group1 = (HSSFShapeGroup) group.getChildren().get(2);
|
||||||
|
assertEquals(2, group1.getChildren().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testHSSFShapeCompatibility() {
|
||||||
|
HSSFShape shape = new HSSFSimpleShape(null, new HSSFClientAnchor());
|
||||||
|
assertEquals(0x08000040, shape.getLineStyleColor());
|
||||||
|
assertEquals(0x08000009, shape.getFillColor());
|
||||||
|
assertEquals(HSSFShape.LINEWIDTH_DEFAULT, shape.getLineWidth());
|
||||||
|
assertEquals(HSSFShape.LINESTYLE_SOLID, shape.getLineStyle());
|
||||||
|
assertFalse(shape.isNoFill());
|
||||||
|
|
||||||
|
AbstractShape sp = AbstractShape.createShape(shape, 1);
|
||||||
|
EscherContainerRecord spContainer = sp.getSpContainer();
|
||||||
|
EscherOptRecord opt =
|
||||||
|
spContainer.getChildById(EscherOptRecord.RECORD_ID);
|
||||||
|
|
||||||
|
assertEquals(7, opt.getEscherProperties().size());
|
||||||
|
assertEquals(true,
|
||||||
|
((EscherBoolProperty)opt.lookup(EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE)).isTrue());
|
||||||
|
assertEquals(0x00000004,
|
||||||
|
((EscherSimpleProperty)opt.lookup(EscherProperties.GEOMETRY__SHAPEPATH)).getPropertyValue());
|
||||||
|
assertEquals(0x08000009,
|
||||||
|
((EscherSimpleProperty)opt.lookup(EscherProperties.FILL__FILLCOLOR)).getPropertyValue());
|
||||||
|
assertEquals(true,
|
||||||
|
((EscherBoolProperty)opt.lookup(EscherProperties.FILL__NOFILLHITTEST)).isTrue());
|
||||||
|
assertEquals(0x08000040,
|
||||||
|
((EscherSimpleProperty)opt.lookup(EscherProperties.LINESTYLE__COLOR)).getPropertyValue());
|
||||||
|
assertEquals(true,
|
||||||
|
((EscherBoolProperty)opt.lookup(EscherProperties.LINESTYLE__NOLINEDRAWDASH)).isTrue());
|
||||||
|
assertEquals(true,
|
||||||
|
((EscherBoolProperty)opt.lookup(EscherProperties.GROUPSHAPE__PRINT)).isTrue());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* create a rectangle, save the workbook, read back and verify that all shape properties are there
|
||||||
|
*/
|
||||||
|
public void testReadWriteRectangle() throws IOException {
|
||||||
|
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
HSSFSheet sheet = wb.createSheet();
|
||||||
|
|
||||||
|
HSSFPatriarch drawing = sheet.createDrawingPatriarch();
|
||||||
|
HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 200, 200, (short)2, 2, (short)15, 15);
|
||||||
|
anchor.setAnchorType(2);
|
||||||
|
assertEquals(anchor.getAnchorType(), 2);
|
||||||
|
|
||||||
|
HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
|
||||||
|
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||||
|
rectangle.setLineWidth(10000);
|
||||||
|
rectangle.setFillColor(777);
|
||||||
|
assertEquals(rectangle.getFillColor(), 777);
|
||||||
|
assertEquals(10000, rectangle.getLineWidth());
|
||||||
|
rectangle.setLineStyle(10);
|
||||||
|
assertEquals(10, rectangle.getLineStyle());
|
||||||
|
rectangle.setLineStyleColor(1111);
|
||||||
|
rectangle.setNoFill(true);
|
||||||
|
assertEquals(rectangle.getLineStyleColor(), 1111);
|
||||||
|
assertEquals(rectangle.isNoFill(), true);
|
||||||
|
|
||||||
|
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||||
|
sheet = wb.getSheetAt(0);
|
||||||
|
drawing = sheet.getDrawingPatriarch();
|
||||||
|
assertEquals(1, drawing.getChildren().size());
|
||||||
|
|
||||||
|
HSSFSimpleShape rectangle2 =
|
||||||
|
(HSSFSimpleShape)drawing.getChildren().get(0);
|
||||||
|
assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE,
|
||||||
|
rectangle2.getShapeType());
|
||||||
|
assertEquals(10000, rectangle2.getLineWidth());
|
||||||
|
assertEquals(10, rectangle2.getLineStyle());
|
||||||
|
assertEquals(anchor, rectangle2.getAnchor());
|
||||||
|
assertEquals(rectangle2.getLineStyleColor(), 1111);
|
||||||
|
assertEquals(rectangle2.getFillColor(), 777);
|
||||||
|
assertEquals(rectangle2.isNoFill(), true);
|
||||||
|
|
||||||
|
rectangle2.setFillColor(3333);
|
||||||
|
rectangle2.setLineStyle(9);
|
||||||
|
rectangle2.setLineStyleColor(4444);
|
||||||
|
rectangle2.setNoFill(false);
|
||||||
|
rectangle2.setLineWidth(77);
|
||||||
|
rectangle2.getAnchor().setDx1(2);
|
||||||
|
rectangle2.getAnchor().setDx2(3);
|
||||||
|
rectangle2.getAnchor().setDy1(4);
|
||||||
|
rectangle2.getAnchor().setDy2(5);
|
||||||
|
|
||||||
|
wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||||
|
sheet = wb.getSheetAt(0);
|
||||||
|
drawing = sheet.getDrawingPatriarch();
|
||||||
|
assertEquals(1, drawing.getChildren().size());
|
||||||
|
rectangle2 = (HSSFSimpleShape)drawing.getChildren().get(0);
|
||||||
|
assertEquals(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE, rectangle2.getShapeType());
|
||||||
|
assertEquals(77, rectangle2.getLineWidth());
|
||||||
|
assertEquals(9, rectangle2.getLineStyle());
|
||||||
|
assertEquals(rectangle2.getLineStyleColor(), 4444);
|
||||||
|
assertEquals(rectangle2.getFillColor(), 3333);
|
||||||
|
assertEquals(rectangle2.getAnchor().getDx1(), 2);
|
||||||
|
assertEquals(rectangle2.getAnchor().getDx2(), 3);
|
||||||
|
assertEquals(rectangle2.getAnchor().getDy1(), 4);
|
||||||
|
assertEquals(rectangle2.getAnchor().getDy2(), 5);
|
||||||
|
assertEquals(rectangle2.isNoFill(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* assert shape properties when reading shapes from a existing workbook */
|
||||||
|
public void testReadExistingRectangle() {
|
||||||
|
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls");
|
||||||
|
HSSFSheet sheet = wb.getSheet("rectangles");
|
||||||
|
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
|
||||||
|
assertEquals(1, drawing.getChildren().size());
|
||||||
|
|
||||||
|
for(HSSFShape shape : drawing.getChildren()){
|
||||||
|
assertEquals(shape.isNoFill(), true);
|
||||||
|
assertEquals(shape.getLineStyle(), HSSFShape.LINESTYLE_DASHDOTGEL);
|
||||||
|
assertEquals(shape.getLineStyleColor(), 0x616161);
|
||||||
|
assertEquals(HexDump.toHex(shape.getFillColor()), shape.getFillColor(), 0x2CE03D);
|
||||||
|
assertEquals(shape.getLineWidth(), HSSFShape.LINEWIDTH_ONE_PT*2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
209
src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java
Normal file
209
src/testcases/org/apache/poi/hssf/model/TestHSSFAnchor.java
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
package org.apache.poi.hssf.model;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.poi.ddf.EscherChildAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherClientAnchorRecord;
|
||||||
|
import org.apache.poi.ddf.EscherContainerRecord;
|
||||||
|
import org.apache.poi.hssf.usermodel.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Evgeniy Berlog
|
||||||
|
* @date 12.06.12
|
||||||
|
*/
|
||||||
|
public class TestHSSFAnchor extends TestCase {
|
||||||
|
|
||||||
|
public void testCreateClientAnchorFromContainer(){
|
||||||
|
EscherContainerRecord container = new EscherContainerRecord();
|
||||||
|
EscherClientAnchorRecord escher = new EscherClientAnchorRecord();
|
||||||
|
escher.setFlag((short) 3);
|
||||||
|
escher.setCol1((short)11);
|
||||||
|
escher.setCol2((short)12);
|
||||||
|
escher.setRow1((short)13);
|
||||||
|
escher.setRow2((short) 14);
|
||||||
|
escher.setDx1((short) 15);
|
||||||
|
escher.setDx2((short) 16);
|
||||||
|
escher.setDy1((short) 17);
|
||||||
|
escher.setDy2((short) 18);
|
||||||
|
container.addChildRecord(escher);
|
||||||
|
|
||||||
|
HSSFClientAnchor anchor = (HSSFClientAnchor) HSSFAnchor.createAnchorFromEscher(container);
|
||||||
|
assertEquals(anchor.getCol1(), 11);
|
||||||
|
assertEquals(escher.getCol1(), 11);
|
||||||
|
assertEquals(anchor.getCol2(), 12);
|
||||||
|
assertEquals(escher.getCol2(), 12);
|
||||||
|
assertEquals(anchor.getRow1(), 13);
|
||||||
|
assertEquals(escher.getRow1(), 13);
|
||||||
|
assertEquals(anchor.getRow2(), 14);
|
||||||
|
assertEquals(escher.getRow2(), 14);
|
||||||
|
assertEquals(anchor.getDx1(), 15);
|
||||||
|
assertEquals(escher.getDx1(), 15);
|
||||||
|
assertEquals(anchor.getDx2(), 16);
|
||||||
|
assertEquals(escher.getDx2(), 16);
|
||||||
|
assertEquals(anchor.getDy1(), 17);
|
||||||
|
assertEquals(escher.getDy1(), 17);
|
||||||
|
assertEquals(anchor.getDy2(), 18);
|
||||||
|
assertEquals(escher.getDy2(), 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateChildAnchorFromContainer(){
|
||||||
|
EscherContainerRecord container = new EscherContainerRecord();
|
||||||
|
EscherChildAnchorRecord escher = new EscherChildAnchorRecord();
|
||||||
|
escher.setDx1((short) 15);
|
||||||
|
escher.setDx2((short) 16);
|
||||||
|
escher.setDy1((short) 17);
|
||||||
|
escher.setDy2((short) 18);
|
||||||
|
container.addChildRecord(escher);
|
||||||
|
|
||||||
|
HSSFChildAnchor anchor = (HSSFChildAnchor) HSSFAnchor.createAnchorFromEscher(container);
|
||||||
|
assertEquals(anchor.getDx1(), 15);
|
||||||
|
assertEquals(escher.getDx1(), 15);
|
||||||
|
assertEquals(anchor.getDx2(), 16);
|
||||||
|
assertEquals(escher.getDx2(), 16);
|
||||||
|
assertEquals(anchor.getDy1(), 17);
|
||||||
|
assertEquals(escher.getDy1(), 17);
|
||||||
|
assertEquals(anchor.getDy2(), 18);
|
||||||
|
assertEquals(escher.getDy2(), 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testShapeEscherMustHaveAnchorRecord(){
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
HSSFSheet sheet = wb.createSheet();
|
||||||
|
|
||||||
|
HSSFPatriarch drawing = sheet.createDrawingPatriarch();
|
||||||
|
HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 200, 200, (short)2, 2, (short)15, 15);
|
||||||
|
anchor.setAnchorType(2);
|
||||||
|
|
||||||
|
HSSFSimpleShape rectangle = drawing.createSimpleShape(anchor);
|
||||||
|
rectangle.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
|
||||||
|
|
||||||
|
rectangle.setAnchor(anchor);
|
||||||
|
|
||||||
|
assertNotNull(anchor.getEscherAnchor());
|
||||||
|
assertNotNull(rectangle.getEscherContainer());
|
||||||
|
assertTrue(anchor.getEscherAnchor().equals(rectangle.getEscherContainer().getChildById(EscherClientAnchorRecord.RECORD_ID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testClientAnchorFromEscher(){
|
||||||
|
EscherClientAnchorRecord escher = new EscherClientAnchorRecord();
|
||||||
|
escher.setCol1((short)11);
|
||||||
|
escher.setCol2((short)12);
|
||||||
|
escher.setRow1((short)13);
|
||||||
|
escher.setRow2((short) 14);
|
||||||
|
escher.setDx1((short) 15);
|
||||||
|
escher.setDx2((short) 16);
|
||||||
|
escher.setDy1((short) 17);
|
||||||
|
escher.setDy2((short) 18);
|
||||||
|
|
||||||
|
HSSFClientAnchor anchor = new HSSFClientAnchor(escher);
|
||||||
|
assertEquals(anchor.getCol1(), 11);
|
||||||
|
assertEquals(escher.getCol1(), 11);
|
||||||
|
assertEquals(anchor.getCol2(), 12);
|
||||||
|
assertEquals(escher.getCol2(), 12);
|
||||||
|
assertEquals(anchor.getRow1(), 13);
|
||||||
|
assertEquals(escher.getRow1(), 13);
|
||||||
|
assertEquals(anchor.getRow2(), 14);
|
||||||
|
assertEquals(escher.getRow2(), 14);
|
||||||
|
assertEquals(anchor.getDx1(), 15);
|
||||||
|
assertEquals(escher.getDx1(), 15);
|
||||||
|
assertEquals(anchor.getDx2(), 16);
|
||||||
|
assertEquals(escher.getDx2(), 16);
|
||||||
|
assertEquals(anchor.getDy1(), 17);
|
||||||
|
assertEquals(escher.getDy1(), 17);
|
||||||
|
assertEquals(anchor.getDy2(), 18);
|
||||||
|
assertEquals(escher.getDy2(), 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testClientAnchorFromScratch(){
|
||||||
|
HSSFClientAnchor anchor = new HSSFClientAnchor();
|
||||||
|
EscherClientAnchorRecord escher = (EscherClientAnchorRecord) anchor.getEscherAnchor();
|
||||||
|
anchor.setAnchor((short)11, 12, 13, 14, (short)15, 16, 17, 18);
|
||||||
|
|
||||||
|
assertEquals(anchor.getCol1(), 11);
|
||||||
|
assertEquals(escher.getCol1(), 11);
|
||||||
|
assertEquals(anchor.getCol2(), 15);
|
||||||
|
assertEquals(escher.getCol2(), 15);
|
||||||
|
assertEquals(anchor.getRow1(), 12);
|
||||||
|
assertEquals(escher.getRow1(), 12);
|
||||||
|
assertEquals(anchor.getRow2(), 16);
|
||||||
|
assertEquals(escher.getRow2(), 16);
|
||||||
|
assertEquals(anchor.getDx1(), 13);
|
||||||
|
assertEquals(escher.getDx1(), 13);
|
||||||
|
assertEquals(anchor.getDx2(), 17);
|
||||||
|
assertEquals(escher.getDx2(), 17);
|
||||||
|
assertEquals(anchor.getDy1(), 14);
|
||||||
|
assertEquals(escher.getDy1(), 14);
|
||||||
|
assertEquals(anchor.getDy2(), 18);
|
||||||
|
assertEquals(escher.getDy2(), 18);
|
||||||
|
|
||||||
|
anchor.setCol1(111);
|
||||||
|
assertEquals(anchor.getCol1(), 111);
|
||||||
|
assertEquals(escher.getCol1(), 111);
|
||||||
|
anchor.setCol2(112);
|
||||||
|
assertEquals(anchor.getCol2(), 112);
|
||||||
|
assertEquals(escher.getCol2(), 112);
|
||||||
|
anchor.setRow1(113);
|
||||||
|
assertEquals(anchor.getRow1(), 113);
|
||||||
|
assertEquals(escher.getRow1(), 113);
|
||||||
|
anchor.setRow2(114);
|
||||||
|
assertEquals(anchor.getRow2(), 114);
|
||||||
|
assertEquals(escher.getRow2(), 114);
|
||||||
|
anchor.setDx1(115);
|
||||||
|
assertEquals(anchor.getDx1(), 115);
|
||||||
|
assertEquals(escher.getDx1(), 115);
|
||||||
|
anchor.setDx2(116);
|
||||||
|
assertEquals(anchor.getDx2(), 116);
|
||||||
|
assertEquals(escher.getDx2(), 116);
|
||||||
|
anchor.setDy1(117);
|
||||||
|
assertEquals(anchor.getDy1(), 117);
|
||||||
|
assertEquals(escher.getDy1(), 117);
|
||||||
|
anchor.setDy2(118);
|
||||||
|
assertEquals(anchor.getDy2(), 118);
|
||||||
|
assertEquals(escher.getDy2(), 118);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChildAnchorFromEscher(){
|
||||||
|
EscherChildAnchorRecord escher = new EscherChildAnchorRecord();
|
||||||
|
escher.setDx1((short) 15);
|
||||||
|
escher.setDx2((short) 16);
|
||||||
|
escher.setDy1((short) 17);
|
||||||
|
escher.setDy2((short) 18);
|
||||||
|
|
||||||
|
HSSFChildAnchor anchor = new HSSFChildAnchor(escher);
|
||||||
|
assertEquals(anchor.getDx1(), 15);
|
||||||
|
assertEquals(escher.getDx1(), 15);
|
||||||
|
assertEquals(anchor.getDx2(), 16);
|
||||||
|
assertEquals(escher.getDx2(), 16);
|
||||||
|
assertEquals(anchor.getDy1(), 17);
|
||||||
|
assertEquals(escher.getDy1(), 17);
|
||||||
|
assertEquals(anchor.getDy2(), 18);
|
||||||
|
assertEquals(escher.getDy2(), 18);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChildAnchorFromScratch(){
|
||||||
|
HSSFChildAnchor anchor = new HSSFChildAnchor();
|
||||||
|
EscherChildAnchorRecord escher = (EscherChildAnchorRecord) anchor.getEscherAnchor();
|
||||||
|
anchor.setAnchor(11, 12, 13, 14);
|
||||||
|
|
||||||
|
assertEquals(anchor.getDx1(), 11);
|
||||||
|
assertEquals(escher.getDx1(), 11);
|
||||||
|
assertEquals(anchor.getDx2(), 13);
|
||||||
|
assertEquals(escher.getDx2(), 13);
|
||||||
|
assertEquals(anchor.getDy1(), 12);
|
||||||
|
assertEquals(escher.getDy1(), 12);
|
||||||
|
assertEquals(anchor.getDy2(), 14);
|
||||||
|
assertEquals(escher.getDy2(), 14);
|
||||||
|
|
||||||
|
anchor.setDx1(115);
|
||||||
|
assertEquals(anchor.getDx1(), 115);
|
||||||
|
assertEquals(escher.getDx1(), 115);
|
||||||
|
anchor.setDx2(116);
|
||||||
|
assertEquals(anchor.getDx2(), 116);
|
||||||
|
assertEquals(escher.getDx2(), 116);
|
||||||
|
anchor.setDy1(117);
|
||||||
|
assertEquals(anchor.getDy1(), 117);
|
||||||
|
assertEquals(escher.getDy1(), 117);
|
||||||
|
anchor.setDy2(118);
|
||||||
|
assertEquals(anchor.getDy2(), 118);
|
||||||
|
assertEquals(escher.getDy2(), 118);
|
||||||
|
}
|
||||||
|
}
|
BIN
test-data/spreadsheet/drawings.xls
Normal file
BIN
test-data/spreadsheet/drawings.xls
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user