Updates from Yegor: New shape and picture stuff (see bug 39256)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@393576 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9e9dc0e4d9
commit
1bb312f416
65
src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java
Normal file
65
src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
Copyright 2002-2004 Apache Software Foundation
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a autoshape in a PowerPoint drawing
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class AutoShape extends SimpleShape {
|
||||||
|
|
||||||
|
protected AutoShape(EscherContainerRecord escherRecord, Shape parent){
|
||||||
|
super(escherRecord, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoShape(int type, Shape parent){
|
||||||
|
super(null, parent);
|
||||||
|
_escherContainer = createSpContainer(type, parent instanceof ShapeGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoShape(int type){
|
||||||
|
this(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected EscherContainerRecord createSpContainer(int shapeType, boolean isChild){
|
||||||
|
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
||||||
|
|
||||||
|
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
|
short type = (short)((shapeType << 4) | 0x2);
|
||||||
|
spRecord.setOptions(type);
|
||||||
|
|
||||||
|
//set default properties for a line
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
|
||||||
|
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLCOLOR, 134217732));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__FILLBACKCOLOR, 134217728));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.FILL__NOFILLHITTEST, 1048592));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__COLOR, 134217729));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524296));
|
||||||
|
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.SHADOWSTYLE__COLOR, 134217730));
|
||||||
|
|
||||||
|
opt.sortProperties();
|
||||||
|
|
||||||
|
return spcont;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -107,13 +107,12 @@ public class Line extends SimpleShape {
|
|||||||
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
||||||
|
|
||||||
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
short type = (ShapeTypes.Line << 4) + 2;
|
short type = (ShapeTypes.Line << 4) | 0x2;
|
||||||
spRecord.setOptions(type);
|
spRecord.setOptions(type);
|
||||||
|
|
||||||
//set default properties for a line
|
//set default properties for a line
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
|
||||||
|
|
||||||
//opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 4));
|
|
||||||
opt.sortProperties();
|
opt.sortProperties();
|
||||||
|
|
||||||
return spcont;
|
return spcont;
|
||||||
|
@ -139,6 +139,34 @@ public class PPGraphics2D extends Graphics2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawString(String string, float x, float y){
|
public void drawString(String string, float x, float y){
|
||||||
|
|
||||||
|
TextBox txt = new TextBox(group);
|
||||||
|
txt.setMarginBottom(0);
|
||||||
|
txt.setMarginTop(0);
|
||||||
|
txt.setMarginLeft(0);
|
||||||
|
txt.setMarginRight(0);
|
||||||
|
txt.setText(string);
|
||||||
|
txt.setWordWrap(TextBox.WrapNone);
|
||||||
|
|
||||||
|
if (font != null){
|
||||||
|
txt.setFontSize(font.getSize());
|
||||||
|
txt.setFontName(font.getName());
|
||||||
|
//if(getColor() != null) txt.setFontColor(getColor());
|
||||||
|
if (font.isBold()) txt.setBold(true);
|
||||||
|
if (font.isItalic()) txt.setItalic(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
txt.resizeToFitText();
|
||||||
|
int height = (int)txt.getAnchor().getHeight();
|
||||||
|
|
||||||
|
/*
|
||||||
|
In powerpoint anchor of a shape is its top left corner.
|
||||||
|
Java graphics sets string coordinates by the baseline of the first character
|
||||||
|
so we need to shift down by the height of the textbox
|
||||||
|
*/
|
||||||
|
txt.moveTo((int)x, (int)(y - height));
|
||||||
|
|
||||||
|
group.addShape(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fill(Shape shape){
|
public void fill(Shape shape){
|
||||||
@ -212,7 +240,7 @@ public class PPGraphics2D extends Graphics2D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void drawOval(int x, int y, int width, int height) {
|
public void drawOval(int x, int y, int width, int height) {
|
||||||
Ellipse ellipse = new Ellipse();
|
AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse);
|
||||||
ellipse.setAnchor(new java.awt.Rectangle(x-width/2, y-height/2, width, height));
|
ellipse.setAnchor(new java.awt.Rectangle(x-width/2, y-height/2, width, height));
|
||||||
if (stroke instanceof BasicStroke){
|
if (stroke instanceof BasicStroke){
|
||||||
BasicStroke bs = (BasicStroke)stroke;
|
BasicStroke bs = (BasicStroke)stroke;
|
||||||
|
@ -3,11 +3,14 @@ package org.apache.poi.hslf.model;
|
|||||||
import org.apache.poi.ddf.*;
|
import org.apache.poi.ddf.*;
|
||||||
import org.apache.poi.hslf.usermodel.PictureData;
|
import org.apache.poi.hslf.usermodel.PictureData;
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.hslf.record.Document;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,16 +125,49 @@ public class Picture extends SimpleShape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set default size of the picture
|
* Resize this picture to the default size.
|
||||||
*
|
|
||||||
* @param ppt presentation which holds the picture
|
|
||||||
*/
|
*/
|
||||||
public void setDefaultSize(SlideShow ppt) throws IOException {
|
public void setDefaultSize(){
|
||||||
int idx = getPictureIndex();
|
PictureData pict = getPictureData();
|
||||||
|
try {
|
||||||
PictureData pict = ppt.getPictures()[idx-1];
|
BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
|
||||||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
|
setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight()));
|
||||||
|
} catch (IOException e){
|
||||||
setAnchor(new java.awt.Rectangle(0, 0, img.getWidth()*6, img.getHeight()*6));
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the picture data for this picture.
|
||||||
|
*
|
||||||
|
* @return the picture data for this picture.
|
||||||
|
*/
|
||||||
|
public PictureData getPictureData(){
|
||||||
|
SlideShow ppt = getSheet().getSlideShow();
|
||||||
|
PictureData[] pict = ppt.getPictureData();
|
||||||
|
Document doc = ppt.getDocumentRecord();
|
||||||
|
EscherContainerRecord dggContainer = doc.getPPDrawingGroup().getDggContainer();
|
||||||
|
EscherContainerRecord bstore = (EscherContainerRecord)Shape.getEscherChild(dggContainer, EscherContainerRecord.BSTORE_CONTAINER);
|
||||||
|
|
||||||
|
List lst = bstore.getChildRecords();
|
||||||
|
int idx = getPictureIndex()-1;
|
||||||
|
EscherBSERecord bse = (EscherBSERecord)lst.get(idx);
|
||||||
|
for ( int i = 0; i < pict.length; i++ ) {
|
||||||
|
if (Arrays.equals(bse.getUid(), pict[i].getUID())){
|
||||||
|
return pict[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default set the orininal image size
|
||||||
|
*/
|
||||||
|
protected void afterInsert(Sheet sh){
|
||||||
|
java.awt.Rectangle anchor = getAnchor();
|
||||||
|
if (anchor.equals(new java.awt.Rectangle())){
|
||||||
|
setDefaultSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,39 +21,31 @@ import org.apache.poi.ddf.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a line in a PowerPoint drawing
|
* Represents a rectangle shae in a PowerPoint drawing
|
||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public class Rectangle extends SimpleShape {
|
public class Rectangle extends TextBox {
|
||||||
|
|
||||||
protected Rectangle(EscherContainerRecord escherRecord, Shape parent){
|
protected Rectangle(EscherContainerRecord escherRecord, Shape parent){
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rectangle(Shape parent){
|
public Rectangle(Shape parent){
|
||||||
super(null, parent);
|
super(parent);
|
||||||
_escherContainer = createSpContainer(parent instanceof ShapeGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rectangle(){
|
public Rectangle(){
|
||||||
this(null);
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EscherContainerRecord createSpContainer(boolean isChild){
|
protected EscherContainerRecord createSpContainer(boolean isChild){
|
||||||
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
||||||
spcont.setOptions((short)15);
|
|
||||||
|
|
||||||
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
short type = (ShapeTypes.Rectangle << 4) + 2;
|
short type = (ShapeTypes.Rectangle << 4) + 2;
|
||||||
spRecord.setOptions(type);
|
spRecord.setOptions(type);
|
||||||
|
|
||||||
//set default properties for a rectangle
|
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
|
|
||||||
|
|
||||||
opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 4));
|
|
||||||
opt.sortProperties();
|
|
||||||
|
|
||||||
return spcont;
|
return spcont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,13 +22,47 @@ import java.awt.*;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* <p>
|
||||||
* Represents a Shape which is the elemental object that composes a drawing.
|
* Represents a Shape which is the elemental object that composes a drawing.
|
||||||
|
* This class is a wrapper around EscherSpContainer which holds all information
|
||||||
|
* about a shape in PowerPoint document.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* When you add a shape, you usually specify the dimensions of the shape and the position
|
||||||
|
* of the upper<EFBFBD>left corner of the bounding box for the shape relative to the upper<EFBFBD>left
|
||||||
|
* corner of the page, worksheet, or slide. Distances in the drawing layer are measured
|
||||||
|
* in points (72 points = 1 inch).
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
public abstract class Shape {
|
public abstract class Shape {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In Escher absolute distances are specified in
|
||||||
|
* English Metric Units (EMUs), occasionally referred to as A units;
|
||||||
|
* there are 360000 EMUs per centimeter, 914400 EMUs per inch, 12700 EMUs per point.
|
||||||
|
*/
|
||||||
|
public static final int EMU_PER_INCH = 914400;
|
||||||
public static final int EMU_PER_POINT = 12700;
|
public static final int EMU_PER_POINT = 12700;
|
||||||
|
public static final int EMU_PER_CENTIMETER = 360000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Master DPI (576 pixels per inch).
|
||||||
|
* Used by the reference coordinate system in PowerPoint.
|
||||||
|
*/
|
||||||
|
public static final int MASTER_DPI = 576;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pixels DPI (96 pixels per inch)
|
||||||
|
*/
|
||||||
|
public static final int PIXEL_DPI = 96;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Points DPI (72 pixels per inch)
|
||||||
|
*/
|
||||||
|
public static final int POINT_DPI = 72;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Either EscherSpContainer or EscheSpgrContainer record
|
* Either EscherSpContainer or EscheSpgrContainer record
|
||||||
@ -42,6 +76,11 @@ public abstract class Shape {
|
|||||||
*/
|
*/
|
||||||
protected Shape _parent;
|
protected Shape _parent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>Sheet</code> this shape belongs to
|
||||||
|
*/
|
||||||
|
protected Sheet _sheet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
|
* Create a Shape object. This constructor is used when an existing Shape is read from from a PowerPoint document.
|
||||||
*
|
*
|
||||||
@ -86,25 +125,25 @@ public abstract class Shape {
|
|||||||
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
|
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
|
||||||
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
|
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
|
||||||
anchor = new java.awt.Rectangle();
|
anchor = new java.awt.Rectangle();
|
||||||
anchor.x = rec.getDx1();
|
anchor.x = rec.getDx1()*POINT_DPI/MASTER_DPI;
|
||||||
anchor.y = rec.getDy1();
|
anchor.y = rec.getDy1()*POINT_DPI/MASTER_DPI;
|
||||||
anchor.width = rec.getDx2() - anchor.x;
|
anchor.width = (rec.getDx2() - anchor.x)*POINT_DPI/MASTER_DPI;
|
||||||
anchor.height = rec.getDy2() - anchor.y;
|
anchor.height = (rec.getDy2() - anchor.y)*POINT_DPI/MASTER_DPI;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
|
EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
|
||||||
anchor = new java.awt.Rectangle();
|
anchor = new java.awt.Rectangle();
|
||||||
anchor.y = rec.getFlag();
|
anchor.y = rec.getFlag()*POINT_DPI/MASTER_DPI;
|
||||||
anchor.x = rec.getCol1();
|
anchor.x = rec.getCol1()*POINT_DPI/MASTER_DPI;
|
||||||
anchor.width = rec.getDx1() - anchor.x;
|
anchor.width = (rec.getDx1() - rec.getCol1())*POINT_DPI/MASTER_DPI;
|
||||||
anchor.height = rec.getRow1() - anchor.y;
|
anchor.height = (rec.getRow1() - rec.getFlag())*POINT_DPI/MASTER_DPI;
|
||||||
}
|
}
|
||||||
return anchor;
|
return anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the anchor (the bounding box rectangle) of this shape.
|
* Sets the anchor (the bounding box rectangle) of this shape.
|
||||||
* All coordinates should be expressed in Master units (576 dpi).
|
* All coordinates should be expressed in poitns (72 dpi).
|
||||||
*
|
*
|
||||||
* @param anchor new anchor
|
* @param anchor new anchor
|
||||||
*/
|
*/
|
||||||
@ -113,17 +152,17 @@ public abstract class Shape {
|
|||||||
int flags = spRecord.getFlags();
|
int flags = spRecord.getFlags();
|
||||||
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
|
if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
|
||||||
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
|
EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
|
||||||
rec.setDx1(anchor.x);
|
rec.setDx1(anchor.x*MASTER_DPI/POINT_DPI);
|
||||||
rec.setDy1(anchor.y);
|
rec.setDy1(anchor.y*MASTER_DPI/POINT_DPI);
|
||||||
rec.setDx2(anchor.width + anchor.x);
|
rec.setDx2((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI);
|
||||||
rec.setDy2(anchor.height + anchor.y);
|
rec.setDy2((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
|
EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
|
||||||
rec.setFlag((short)anchor.y);
|
rec.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
|
||||||
rec.setCol1((short)anchor.x);
|
rec.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
|
||||||
rec.setDx1((short)(anchor.width + anchor.x));
|
rec.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
|
||||||
rec.setRow1((short)(anchor.height + anchor.y));
|
rec.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -171,11 +210,11 @@ public abstract class Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an escher property in the opt record.
|
* Set an escher property for this shape.
|
||||||
*
|
*
|
||||||
* @param opt The opt record to set the properties to.
|
* @param opt The opt record to set the properties to.
|
||||||
* @param propId The id of the property. One of the constants defined in EscherOptRecord.
|
* @param propId The id of the property. One of the constants defined in EscherOptRecord.
|
||||||
* @param value value of the property
|
* @param value value of the property. If value = -1 then the property is removed.
|
||||||
*/
|
*/
|
||||||
public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
|
public static void setEscherProperty(EscherOptRecord opt, short propId, int value){
|
||||||
java.util.List props = opt.getEscherProperties();
|
java.util.List props = opt.getEscherProperties();
|
||||||
@ -198,4 +237,33 @@ public abstract class Shape {
|
|||||||
public EscherContainerRecord getSpContainer(){
|
public EscherContainerRecord getSpContainer(){
|
||||||
return _escherContainer;
|
return _escherContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event which fires when a shape is inserted in the sheet.
|
||||||
|
* In some cases we need to propagate changes to upper level containers.
|
||||||
|
* <br>
|
||||||
|
* Default implementation does nothing.
|
||||||
|
*
|
||||||
|
* @param sh - owning shape
|
||||||
|
*/
|
||||||
|
protected void afterInsert(Sheet sh){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the <code>SlideShow</code> this shape belongs to
|
||||||
|
*/
|
||||||
|
public Sheet getSheet(){
|
||||||
|
return _sheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the <code>SlideShow</code> this shape belongs to
|
||||||
|
*
|
||||||
|
* @param sheet owner of this shape
|
||||||
|
*/
|
||||||
|
public void setSheet(Sheet sheet){
|
||||||
|
_sheet = sheet;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,9 @@ import org.apache.poi.ddf.EscherContainerRecord;
|
|||||||
*/
|
*/
|
||||||
public class ShapeFactory {
|
public class ShapeFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new shape from the data provided.
|
||||||
|
*/
|
||||||
public static Shape createShape(EscherContainerRecord spContainer, Shape parent){
|
public static Shape createShape(EscherContainerRecord spContainer, Shape parent){
|
||||||
if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
|
if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
|
||||||
return new ShapeGroup(spContainer, parent);
|
return new ShapeGroup(spContainer, parent);
|
||||||
@ -36,6 +39,8 @@ public class ShapeFactory {
|
|||||||
int type = spRecord.getOptions() >> 4;
|
int type = spRecord.getOptions() >> 4;
|
||||||
switch (type){
|
switch (type){
|
||||||
case ShapeTypes.TextBox:
|
case ShapeTypes.TextBox:
|
||||||
|
shape = new TextBox(spContainer, parent);
|
||||||
|
break;
|
||||||
case ShapeTypes.Rectangle:
|
case ShapeTypes.Rectangle:
|
||||||
shape = new Rectangle(spContainer, parent);
|
shape = new Rectangle(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
@ -45,14 +50,11 @@ public class ShapeFactory {
|
|||||||
case ShapeTypes.Line:
|
case ShapeTypes.Line:
|
||||||
shape = new Line(spContainer, parent);
|
shape = new Line(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
case ShapeTypes.Ellipse:
|
|
||||||
shape = new Ellipse(spContainer, parent);
|
|
||||||
break;
|
|
||||||
case ShapeTypes.NotPrimitive:
|
case ShapeTypes.NotPrimitive:
|
||||||
shape = new ShapeGroup(spContainer, parent);
|
shape = new ShapeGroup(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
shape = new SimpleShape(spContainer, parent);
|
shape = new AutoShape(spContainer, parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return shape;
|
return shape;
|
||||||
|
@ -27,11 +27,21 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class ShapeGroup extends Shape{
|
public class ShapeGroup extends Shape{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ShapeGroup. This constructor is used when a new shape is created.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public ShapeGroup(){
|
public ShapeGroup(){
|
||||||
this(null, null);
|
this(null, null);
|
||||||
_escherContainer = createSpContainer(false);
|
_escherContainer = createSpContainer(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a ShapeGroup object and initilize it from the supplied Record container.
|
||||||
|
*
|
||||||
|
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
|
||||||
|
* @param parent the parent of the shape
|
||||||
|
*/
|
||||||
protected ShapeGroup(EscherContainerRecord escherRecord, Shape parent){
|
protected ShapeGroup(EscherContainerRecord escherRecord, Shape parent){
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
|
@ -82,9 +82,9 @@ public class ShapeTypes {
|
|||||||
public static final int Chevron = 55;
|
public static final int Chevron = 55;
|
||||||
public static final int Pentagon = 56;
|
public static final int Pentagon = 56;
|
||||||
public static final int NoSmoking = 57;
|
public static final int NoSmoking = 57;
|
||||||
public static final int Seal8 = 58;
|
public static final int Star8 = 58;
|
||||||
public static final int Seal16 = 59;
|
public static final int Star16 = 59;
|
||||||
public static final int Seal32 = 60;
|
public static final int Star32 = 60;
|
||||||
public static final int WedgeRectCallout = 61;
|
public static final int WedgeRectCallout = 61;
|
||||||
public static final int WedgeRRectCallout = 62;
|
public static final int WedgeRRectCallout = 62;
|
||||||
public static final int WedgeEllipseCallout = 63;
|
public static final int WedgeEllipseCallout = 63;
|
||||||
@ -116,7 +116,7 @@ public class ShapeTypes {
|
|||||||
public static final int LeftUpArrow = 89;
|
public static final int LeftUpArrow = 89;
|
||||||
public static final int BentUpArrow = 90;
|
public static final int BentUpArrow = 90;
|
||||||
public static final int BentArrow = 91;
|
public static final int BentArrow = 91;
|
||||||
public static final int Seal24 = 92;
|
public static final int Star24 = 92;
|
||||||
public static final int StripedRightArrow = 93;
|
public static final int StripedRightArrow = 93;
|
||||||
public static final int NotchedRightArrow = 94;
|
public static final int NotchedRightArrow = 94;
|
||||||
public static final int BlockArc = 95;
|
public static final int BlockArc = 95;
|
||||||
@ -211,7 +211,7 @@ public class ShapeTypes {
|
|||||||
public static final int Moon = 184;
|
public static final int Moon = 184;
|
||||||
public static final int BracketPair = 185;
|
public static final int BracketPair = 185;
|
||||||
public static final int BracePair = 186;
|
public static final int BracePair = 186;
|
||||||
public static final int Seal4 = 187;
|
public static final int Star4 = 187;
|
||||||
public static final int DoubleWave = 188;
|
public static final int DoubleWave = 188;
|
||||||
public static final int ActionButtonBlank = 189;
|
public static final int ActionButtonBlank = 189;
|
||||||
public static final int ActionButtonHome = 190;
|
public static final int ActionButtonHome = 190;
|
||||||
|
@ -23,6 +23,7 @@ import org.apache.poi.ddf.EscherContainerRecord;
|
|||||||
import org.apache.poi.ddf.EscherDgRecord;
|
import org.apache.poi.ddf.EscherDgRecord;
|
||||||
import org.apache.poi.ddf.EscherRecord;
|
import org.apache.poi.ddf.EscherRecord;
|
||||||
import org.apache.poi.hslf.record.*;
|
import org.apache.poi.hslf.record.*;
|
||||||
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -38,6 +39,11 @@ import java.util.Vector;
|
|||||||
|
|
||||||
public abstract class Sheet
|
public abstract class Sheet
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The <code>SlideShow</code> we belong to
|
||||||
|
*/
|
||||||
|
private SlideShow _slideShow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all the TextRuns in the sheet.
|
* Returns an array of all the TextRuns in the sheet.
|
||||||
*/
|
*/
|
||||||
@ -59,7 +65,19 @@ public abstract class Sheet
|
|||||||
* Fetch the PPDrawing from the underlying record
|
* Fetch the PPDrawing from the underlying record
|
||||||
*/
|
*/
|
||||||
protected abstract PPDrawing getPPDrawing();
|
protected abstract PPDrawing getPPDrawing();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the SlideShow we're attached to
|
||||||
|
*/
|
||||||
|
public SlideShow getSlideShow() { return _slideShow; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the SlideShow we're attached to
|
||||||
|
*/
|
||||||
|
public void setSlideShow(SlideShow ss) { _slideShow = ss; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a given PPDrawing, grab all the TextRuns
|
* For a given PPDrawing, grab all the TextRuns
|
||||||
*/
|
*/
|
||||||
@ -149,7 +167,9 @@ public abstract class Sheet
|
|||||||
ArrayList shapes = new ArrayList();
|
ArrayList shapes = new ArrayList();
|
||||||
for (int i=1;i<ch.size();i++) {
|
for (int i=1;i<ch.size();i++) {
|
||||||
EscherContainerRecord sp = (EscherContainerRecord)ch.get(i);
|
EscherContainerRecord sp = (EscherContainerRecord)ch.get(i);
|
||||||
shapes.add(ShapeFactory.createShape(sp, null));
|
Shape sh = ShapeFactory.createShape(sp, null);
|
||||||
|
sh.setSheet(this);
|
||||||
|
shapes.add(sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Shape[])shapes.toArray(new Shape[shapes.size()]);
|
return (Shape[])shapes.toArray(new Shape[shapes.size()]);
|
||||||
@ -169,5 +189,8 @@ public abstract class Sheet
|
|||||||
|
|
||||||
EscherDgRecord dg = (EscherDgRecord)Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
|
EscherDgRecord dg = (EscherDgRecord)Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
|
||||||
dg.setNumShapes(dg.getNumShapes()+1);
|
dg.setNumShapes(dg.getNumShapes()+1);
|
||||||
|
|
||||||
|
shape.setSheet(this);
|
||||||
|
shape.afterInsert(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,12 @@ import java.awt.*;
|
|||||||
*/
|
*/
|
||||||
public class SimpleShape extends Shape {
|
public class SimpleShape extends Shape {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a SimpleShape object and initialize it from the supplied Record container.
|
||||||
|
*
|
||||||
|
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
|
||||||
|
* @param parent the parent of the shape
|
||||||
|
*/
|
||||||
protected SimpleShape(EscherContainerRecord escherRecord, Shape parent){
|
protected SimpleShape(EscherContainerRecord escherRecord, Shape parent){
|
||||||
super(escherRecord, parent);
|
super(escherRecord, parent);
|
||||||
}
|
}
|
||||||
@ -102,12 +108,12 @@ public class SimpleShape extends Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return color of the line
|
* @return color of the line. If color is not set returns <code>java.awt.Color.black</code>
|
||||||
*/
|
*/
|
||||||
public Color getLineColor(){
|
public Color getLineColor(){
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
EscherRGBProperty prop = (EscherRGBProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR);
|
EscherRGBProperty prop = (EscherRGBProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR);
|
||||||
Color color = null;
|
Color color = Color.black;
|
||||||
if (prop != null){
|
if (prop != null){
|
||||||
Color swp = new Color(prop.getRgbColor());
|
Color swp = new Color(prop.getRgbColor());
|
||||||
color = new Color(swp.getBlue(), swp.getGreen(), swp.getRed());
|
color = new Color(swp.getBlue(), swp.getGreen(), swp.getRed());
|
||||||
@ -136,6 +142,11 @@ public class SimpleShape extends Shape {
|
|||||||
return prop == null ? Line.LineSolid : prop.getPropertyValue();
|
return prop == null ? Line.LineSolid : prop.getPropertyValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color used to fill this shape.
|
||||||
|
*
|
||||||
|
* @param color the background color
|
||||||
|
*/
|
||||||
public void setFillColor(Color color){
|
public void setFillColor(Color color){
|
||||||
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
||||||
|
490
src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
Normal file
490
src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
|
||||||
|
/* ====================================================================
|
||||||
|
Copyright 2002-2004 Apache Software Foundation
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
|
||||||
|
package org.apache.poi.hslf.model;
|
||||||
|
|
||||||
|
import org.apache.poi.ddf.*;
|
||||||
|
import org.apache.poi.hslf.record.*;
|
||||||
|
import org.apache.poi.hslf.usermodel.RichTextRun;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.font.FontRenderContext;
|
||||||
|
import java.awt.font.TextLayout;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a TextFrame shape in PowerPoint.
|
||||||
|
* <p>
|
||||||
|
* Contains the text in a text frame as well as the properties and methods
|
||||||
|
* that control alignment and anchoring of the text.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Yegor Kozlov
|
||||||
|
*/
|
||||||
|
public class TextBox extends SimpleShape {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How to anchor the text
|
||||||
|
*/
|
||||||
|
public static final int AnchorTop = 0;
|
||||||
|
public static final int AnchorMiddle = 1;
|
||||||
|
public static final int AnchorBottom = 2;
|
||||||
|
public static final int AnchorTopCentered = 3;
|
||||||
|
public static final int AnchorMiddleCentered = 4;
|
||||||
|
public static final int AnchorBottomCentered = 5;
|
||||||
|
public static final int AnchorTopBaseline = 6;
|
||||||
|
public static final int AnchorBottomBaseline = 7;
|
||||||
|
public static final int AnchorTopCenteredBaseline = 8;
|
||||||
|
public static final int AnchorBottomCenteredBaseline = 9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How to wrap the text
|
||||||
|
*/
|
||||||
|
public static final int WrapSquare = 0;
|
||||||
|
public static final int WrapByPoints = 1;
|
||||||
|
public static final int WrapNone = 2;
|
||||||
|
public static final int WrapTopBottom = 3;
|
||||||
|
public static final int WrapThrough = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How to align the text
|
||||||
|
*/
|
||||||
|
public static final int AlignLeft = 0;
|
||||||
|
public static final int AlignCenter = 1;
|
||||||
|
public static final int AlignRight = 2;
|
||||||
|
public static final int AlignJustify = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default font size
|
||||||
|
*/
|
||||||
|
public static final int DefaultFontSize = 24;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low-level object which holds actual text and format data
|
||||||
|
*/
|
||||||
|
protected TextRun _txtrun;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escher container which holds text attributes such as
|
||||||
|
* TextHeaderAtom, TextBytesAtom ot TextCharsAtom, StyleTextPropAtom etc.
|
||||||
|
*/
|
||||||
|
protected EscherTextboxWrapper _txtbox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a TextBox object and initialize it from the supplied Record container.
|
||||||
|
*
|
||||||
|
* @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape
|
||||||
|
* @param parent the parent of the shape
|
||||||
|
*/
|
||||||
|
protected TextBox(EscherContainerRecord escherRecord, Shape parent){
|
||||||
|
super(escherRecord, parent);
|
||||||
|
|
||||||
|
EscherTextboxRecord textbox = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
|
||||||
|
_txtbox = new EscherTextboxWrapper(textbox);
|
||||||
|
|
||||||
|
TextHeaderAtom tha = null;
|
||||||
|
TextBytesAtom tba = null;
|
||||||
|
StyleTextPropAtom sta = null;
|
||||||
|
Record[] child = _txtbox.getChildRecords();
|
||||||
|
for (int i = 0; i < child.length; i++) {
|
||||||
|
if (child[i] instanceof TextHeaderAtom) tha = (TextHeaderAtom)child[i];
|
||||||
|
else if (child[i] instanceof TextBytesAtom) tba = (TextBytesAtom)child[i];
|
||||||
|
else if (child[i] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)child[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
_txtrun = new TextRun(tha,tba,sta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TextBox. This constructor is used when a new shape is created.
|
||||||
|
*
|
||||||
|
* @param parent the parent of this Shape. For example, if this text box is a cell
|
||||||
|
* in a table then the parent is Table.
|
||||||
|
*/
|
||||||
|
public TextBox(Shape parent){
|
||||||
|
super(null, parent);
|
||||||
|
_escherContainer = createSpContainer(parent instanceof ShapeGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TextBox. This constructor is used when a new shape is created.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public TextBox(){
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new textBox and initialize internal structures
|
||||||
|
*
|
||||||
|
* @return the created <code>EscherContainerRecord</code> which holds shape data
|
||||||
|
*/
|
||||||
|
protected EscherContainerRecord createSpContainer(boolean isChild){
|
||||||
|
EscherContainerRecord spcont = super.createSpContainer(isChild);
|
||||||
|
|
||||||
|
EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
|
||||||
|
short type = (ShapeTypes.TextBox << 4) | 0x2;
|
||||||
|
spRecord.setOptions(type);
|
||||||
|
|
||||||
|
//set default properties for a textbox
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0);
|
||||||
|
|
||||||
|
setEscherProperty(opt, EscherProperties.FILL__FILLCOLOR, 134217732);
|
||||||
|
setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 134217728);
|
||||||
|
setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 1048576);
|
||||||
|
setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 134217729);
|
||||||
|
setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 524288);
|
||||||
|
setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 134217730);
|
||||||
|
|
||||||
|
opt.sortProperties();
|
||||||
|
|
||||||
|
//create EscherTextboxWrapper
|
||||||
|
_txtbox = new EscherTextboxWrapper();
|
||||||
|
|
||||||
|
TextHeaderAtom tha = new TextHeaderAtom();
|
||||||
|
_txtbox.appendChildRecord(tha);
|
||||||
|
|
||||||
|
TextBytesAtom tba = new TextBytesAtom();
|
||||||
|
_txtbox.appendChildRecord(tba);
|
||||||
|
|
||||||
|
StyleTextPropAtom sta = new StyleTextPropAtom(0);
|
||||||
|
_txtbox.appendChildRecord(sta);
|
||||||
|
|
||||||
|
_txtrun = new TextRun(tha,tba,sta);
|
||||||
|
_txtrun.setText("");
|
||||||
|
spcont.addChildRecord(_txtbox.getEscherRecord());
|
||||||
|
|
||||||
|
return spcont;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text contained in this text frame.
|
||||||
|
*
|
||||||
|
* @return the text string for this textbox.
|
||||||
|
*/
|
||||||
|
public String getText(){
|
||||||
|
return _txtrun.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text contained in this text frame.
|
||||||
|
*
|
||||||
|
* @param text the text string used by this object.
|
||||||
|
*/
|
||||||
|
public void setText(String text){
|
||||||
|
_txtrun.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a textbox is added to a sheet we need to tell upper-level
|
||||||
|
* <code>PPDrawing</code> about it.
|
||||||
|
*
|
||||||
|
* @param sh the sheet we are adding to
|
||||||
|
*/
|
||||||
|
protected void afterInsert(Sheet sh){
|
||||||
|
PPDrawing ppdrawing = sh.getPPDrawing();
|
||||||
|
ppdrawing.addTextboxWrapper(_txtbox);
|
||||||
|
// Ensure the escher layer knows about the added records
|
||||||
|
try {
|
||||||
|
_txtbox.writeOut(null);
|
||||||
|
} catch (IOException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the bounds of this <code>TextFrame</code>.
|
||||||
|
* <code>Note</b>, this is very primitive estimation, the precision is poor.
|
||||||
|
*
|
||||||
|
* @return the bounds of this <code>TextFrame</code>.
|
||||||
|
*/
|
||||||
|
protected Dimension getTextSize(){
|
||||||
|
FontRenderContext frc = new FontRenderContext(null, true, true);
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
int size = rt.getFontSize();
|
||||||
|
if (size == -1) size = TextBox.DefaultFontSize;
|
||||||
|
int style = 0;
|
||||||
|
if (rt.isBold()) style |= Font.BOLD;
|
||||||
|
if (rt.isItalic()) style |= Font.ITALIC;
|
||||||
|
String fntname = rt.getFontName();
|
||||||
|
if (fntname == null) //get the default font from Document.Environment.FontCollection
|
||||||
|
fntname = getSheet().getSlideShow().getDocumentRecord().getEnvironment().getFontCollection().getFontWithId(0);
|
||||||
|
Font font = new Font(fntname, style, size);
|
||||||
|
|
||||||
|
TextLayout layout = new TextLayout(getText(), font, frc);
|
||||||
|
int width = Math.round(layout.getAdvance());
|
||||||
|
width += getMarginLeft() + getMarginRight();
|
||||||
|
int height = Math.round(layout.getAscent());
|
||||||
|
height += getMarginTop() + getMarginBottom();
|
||||||
|
return new Dimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the size of the TextBox so it encompasses the text inside it.
|
||||||
|
*/
|
||||||
|
public void resizeToFitText(){
|
||||||
|
Dimension size = getTextSize();
|
||||||
|
java.awt.Rectangle anchor = getAnchor();
|
||||||
|
anchor.setSize(size);
|
||||||
|
setAnchor(anchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of vertical alignment for the text.
|
||||||
|
* One of the <code>Anchor*</code> constants defined in this class.
|
||||||
|
*
|
||||||
|
* @return the type of alignment
|
||||||
|
*/
|
||||||
|
public int getVerticalAlignment(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
|
||||||
|
return prop == null ? AlignCenter : prop.getPropertyValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of vertical alignment for the text.
|
||||||
|
* One of the <code>Anchor*</code> constants defined in this class.
|
||||||
|
*
|
||||||
|
* @param align - the type of alignment
|
||||||
|
*/
|
||||||
|
public void setVerticalAlignment(int align){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT, align);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the distance (in points) between the bottom of the text frame
|
||||||
|
* and the bottom of the inscribed rectangle of the shape that contains the text.
|
||||||
|
* Default value is 1/20 inch.
|
||||||
|
*
|
||||||
|
* @return the botom margin
|
||||||
|
*/
|
||||||
|
public int getMarginBottom(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
|
||||||
|
int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
|
||||||
|
return val/EMU_PER_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the botom margin.
|
||||||
|
* @see #getMarginBottom()
|
||||||
|
*
|
||||||
|
* @param margin the bottom margin
|
||||||
|
*/
|
||||||
|
public void setMarginBottom(int margin){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM, margin*EMU_PER_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distance (in EMUs) between the left edge of the text frame
|
||||||
|
* and the left edge of the inscribed rectangle of the shape that contains
|
||||||
|
* the text.
|
||||||
|
* Default value is 1/10 inch.
|
||||||
|
*
|
||||||
|
* @return the left margin
|
||||||
|
*/
|
||||||
|
public int getMarginLeft(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTBOTTOM);
|
||||||
|
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
|
||||||
|
return val/EMU_PER_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left margin.
|
||||||
|
* @see #getMarginLeft()
|
||||||
|
*
|
||||||
|
* @param margin the left margin
|
||||||
|
*/
|
||||||
|
public void setMarginLeft(int margin){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTLEFT, margin*EMU_PER_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distance (in EMUs) between the right edge of the
|
||||||
|
* text frame and the right edge of the inscribed rectangle of the shape
|
||||||
|
* that contains the text.
|
||||||
|
* Default value is 1/10 inch.
|
||||||
|
*
|
||||||
|
* @return the right margin
|
||||||
|
*/
|
||||||
|
public int getMarginRight(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT);
|
||||||
|
int val = prop == null ? EMU_PER_INCH/10 : prop.getPropertyValue();
|
||||||
|
return val/EMU_PER_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the right margin.
|
||||||
|
* @see #getMarginRight()
|
||||||
|
*
|
||||||
|
* @param margin the right margin
|
||||||
|
*/
|
||||||
|
public void setMarginRight(int margin){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTRIGHT, margin*EMU_PER_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the distance (in EMUs) between the top of the text frame
|
||||||
|
* and the top of the inscribed rectangle of the shape that contains the text.
|
||||||
|
* Default value is 1/20 inch.
|
||||||
|
*
|
||||||
|
* @return the top margin
|
||||||
|
*/
|
||||||
|
public int getMarginTop(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTTOP);
|
||||||
|
int val = prop == null ? EMU_PER_INCH/20 : prop.getPropertyValue();
|
||||||
|
return val/EMU_PER_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the top margin.
|
||||||
|
* @see #getMarginTop()
|
||||||
|
*
|
||||||
|
* @param margin the top margin
|
||||||
|
*/
|
||||||
|
public void setMarginTop(int margin){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTTOP, margin*EMU_PER_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value indicating word wrap.
|
||||||
|
* One of the <code>Wrap*</code> constants defined in this class.
|
||||||
|
*
|
||||||
|
* @return the value indicating word wrap
|
||||||
|
*/
|
||||||
|
public int getWordWrap(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT);
|
||||||
|
return prop == null ? WrapSquare : prop.getPropertyValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies how the text should be wrapped
|
||||||
|
*
|
||||||
|
* @param wrap the value indicating how the text should be wrapped
|
||||||
|
*/
|
||||||
|
public void setWordWrap(int wrap){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__WRAPTEXT, wrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id for the text.
|
||||||
|
*/
|
||||||
|
public int getTextId(){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__TEXTID);
|
||||||
|
return prop == null ? 0 : prop.getPropertyValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets text ID
|
||||||
|
*
|
||||||
|
* @param id of the text
|
||||||
|
*/
|
||||||
|
public void setTextId(int id){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
setEscherProperty(opt, EscherProperties.TEXT__TEXTID, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color used to fill this shape.
|
||||||
|
*
|
||||||
|
* @param color the background color
|
||||||
|
*/
|
||||||
|
public void setBackgroundColor(Color color){
|
||||||
|
EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
|
||||||
|
int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();
|
||||||
|
setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array of RichTextRun objects which control text formatting in this text box
|
||||||
|
*/
|
||||||
|
public RichTextRun[] getRichTextRuns(){
|
||||||
|
return _txtrun.getRichTextRuns();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the <code>Font</code> object for this text frame
|
||||||
|
*
|
||||||
|
* @param size the size of the font
|
||||||
|
*/
|
||||||
|
public void setFontSize(int size){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
rt.setFontSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the size of the font applied to this text shape
|
||||||
|
*/
|
||||||
|
public int getFontSize(){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
return rt.getFontSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to use bold or not
|
||||||
|
*
|
||||||
|
* @param bold <code>true</code> if the text should be bold, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public void setBold(boolean bold){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
rt.setBold(bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to use italic or not
|
||||||
|
*
|
||||||
|
* @param italic <code>true</code> if the text should be italic, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public void setItalic(boolean italic){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
rt.setItalic(italic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to use underline or not
|
||||||
|
*
|
||||||
|
* @param underline <code>true</code> if the text should be underlined, <code>false</code> otherwise
|
||||||
|
*/
|
||||||
|
public void setUnderline(boolean underline){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
rt.setUnderlined(underline);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font of this text shape
|
||||||
|
*
|
||||||
|
* @param name the name of the font to be applied to this text shape
|
||||||
|
*/
|
||||||
|
public void setFontName(String name){
|
||||||
|
RichTextRun rt = _txtrun.getRichTextRuns()[0];
|
||||||
|
rt.setFontName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -47,7 +47,7 @@ public class EscherTextboxWrapper extends RecordContainer
|
|||||||
/**
|
/**
|
||||||
* Creates the wrapper for the given DDF Escher Record and children
|
* Creates the wrapper for the given DDF Escher Record and children
|
||||||
*/
|
*/
|
||||||
protected EscherTextboxWrapper(EscherTextboxRecord textbox) {
|
public EscherTextboxWrapper(EscherTextboxRecord textbox) {
|
||||||
_escherRecord = textbox;
|
_escherRecord = textbox;
|
||||||
_type = (long)_escherRecord.getRecordId();
|
_type = (long)_escherRecord.getRecordId();
|
||||||
|
|
||||||
@ -55,7 +55,18 @@ public class EscherTextboxWrapper extends RecordContainer
|
|||||||
byte[] data = _escherRecord.getData();
|
byte[] data = _escherRecord.getData();
|
||||||
_children = Record.findChildRecords(data,0,data.length);
|
_children = Record.findChildRecords(data,0,data.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new, empty wrapper for DDF Escher Records and their children
|
||||||
|
*/
|
||||||
|
public EscherTextboxWrapper() {
|
||||||
|
_escherRecord = new EscherTextboxRecord();
|
||||||
|
_escherRecord.setRecordId(EscherTextboxRecord.RECORD_ID);
|
||||||
|
_escherRecord.setOptions((short)15);
|
||||||
|
|
||||||
|
_children = new Record[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the type of the escher record (normally in the 0xFnnn range)
|
* Return the type of the escher record (normally in the 0xFnnn range)
|
||||||
|
@ -262,4 +262,15 @@ public class PPDrawing extends RecordAtom
|
|||||||
dgContainer
|
dgContainer
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new EscherTextboxWrapper to this <code>PPDrawing</code>.
|
||||||
|
*/
|
||||||
|
public void addTextboxWrapper(EscherTextboxWrapper txtbox){
|
||||||
|
EscherTextboxWrapper[] tw = new EscherTextboxWrapper[textboxWrappers.length + 1];
|
||||||
|
System.arraycopy(textboxWrappers, 0, tw, 0, textboxWrappers.length);
|
||||||
|
|
||||||
|
tw[textboxWrappers.length] = txtbox;
|
||||||
|
textboxWrappers = tw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,18 @@ public class TextBytesAtom extends RecordAtom
|
|||||||
_text = new byte[len-8];
|
_text = new byte[len-8];
|
||||||
System.arraycopy(source,start+8,_text,0,len-8);
|
System.arraycopy(source,start+8,_text,0,len-8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty TextBytes Atom
|
||||||
|
*/
|
||||||
|
public TextBytesAtom() {
|
||||||
|
_header = new byte[8];
|
||||||
|
LittleEndian.putUShort(_header, 0, 0);
|
||||||
|
LittleEndian.putUShort(_header, 2, (int)_type);
|
||||||
|
LittleEndian.putInt(_header, 4, 0);
|
||||||
|
|
||||||
|
_text = new byte[]{};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are of type 4008
|
* We are of type 4008
|
||||||
|
@ -75,6 +75,18 @@ public class TextHeaderAtom extends RecordAtom implements ParentAwareRecord
|
|||||||
// Grab the type
|
// Grab the type
|
||||||
textType = (int)LittleEndian.getInt(source,start+8);
|
textType = (int)LittleEndian.getInt(source,start+8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new TextHeader Atom, for an unknown type of text
|
||||||
|
*/
|
||||||
|
public TextHeaderAtom() {
|
||||||
|
_header = new byte[8];
|
||||||
|
LittleEndian.putUShort(_header, 0, 0);
|
||||||
|
LittleEndian.putUShort(_header, 2, (int)_type);
|
||||||
|
LittleEndian.putInt(_header, 4, 4);
|
||||||
|
|
||||||
|
textType = OTHER_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are of type 3999
|
* We are of type 3999
|
||||||
|
@ -25,6 +25,7 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents the image data contained in the Presentation.
|
* A class that represents the image data contained in the Presentation.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @author Yegor Kozlov
|
* @author Yegor Kozlov
|
||||||
*/
|
*/
|
||||||
@ -35,6 +36,9 @@ public class PictureData {
|
|||||||
*/
|
*/
|
||||||
public static final int HEADER_SIZE = 25;
|
public static final int HEADER_SIZE = 25;
|
||||||
|
|
||||||
|
protected static final int JPEG_HEADER = -266516832;
|
||||||
|
protected static final int PNG_HEADER = -266441216;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binary data of the picture
|
* Binary data of the picture
|
||||||
*/
|
*/
|
||||||
@ -118,11 +122,27 @@ public class PictureData {
|
|||||||
*/
|
*/
|
||||||
public void setType(int format){
|
public void setType(int format){
|
||||||
switch (format){
|
switch (format){
|
||||||
case Picture.JPEG: LittleEndian.putInt(header, 0, -266516832); break;
|
case Picture.JPEG: LittleEndian.putInt(header, 0, PictureData.JPEG_HEADER); break;
|
||||||
case Picture.PNG: LittleEndian.putInt(header, 0, -266441216); break;
|
case Picture.PNG: LittleEndian.putInt(header, 0, PictureData.PNG_HEADER); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns type of this picture.
|
||||||
|
* Must be one of the static constans defined in the <code>Picture<code> class.
|
||||||
|
*
|
||||||
|
* @return type of this picture.
|
||||||
|
*/
|
||||||
|
public int getType(){
|
||||||
|
int format = 0;
|
||||||
|
int val = LittleEndian.getInt(header, 0);
|
||||||
|
switch (val){
|
||||||
|
case PictureData.JPEG_HEADER: format = Picture.JPEG; break;
|
||||||
|
case PictureData.PNG_HEADER: format = Picture.PNG; break;
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the header of the Picture
|
* Returns the header of the Picture
|
||||||
*
|
*
|
||||||
|
@ -401,6 +401,7 @@ public class SlideShow
|
|||||||
_notes = new Notes[notesV.size()];
|
_notes = new Notes[notesV.size()];
|
||||||
for(int i=0; i<_notes.length; i++) {
|
for(int i=0; i<_notes.length; i++) {
|
||||||
_notes[i] = (Notes)notesV.get(i);
|
_notes[i] = (Notes)notesV.get(i);
|
||||||
|
_notes[i].setSlideShow(this);
|
||||||
|
|
||||||
// Now supply ourselves to all the rich text runs
|
// Now supply ourselves to all the rich text runs
|
||||||
// of this note's TextRuns
|
// of this note's TextRuns
|
||||||
@ -418,6 +419,7 @@ public class SlideShow
|
|||||||
_slides = new Slide[slidesV.size()];
|
_slides = new Slide[slidesV.size()];
|
||||||
for(int i=0; i<_slides.length; i++) {
|
for(int i=0; i<_slides.length; i++) {
|
||||||
_slides[i] = (Slide)slidesV.get(i);
|
_slides[i] = (Slide)slidesV.get(i);
|
||||||
|
_slides[i].setSlideShow(this);
|
||||||
|
|
||||||
// Now supply ourselves to all the rich text runs
|
// Now supply ourselves to all the rich text runs
|
||||||
// of this slide's TextRuns
|
// of this slide's TextRuns
|
||||||
@ -472,9 +474,9 @@ public class SlideShow
|
|||||||
//public MetaSheet[] getMetaSheets() { return _msheets; }
|
//public MetaSheet[] getMetaSheets() { return _msheets; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the pictures attached to the SlideShow
|
* Returns the data of all the pictures attached to the SlideShow
|
||||||
*/
|
*/
|
||||||
public PictureData[] getPictures() throws IOException {
|
public PictureData[] getPictureData() {
|
||||||
return _hslfSlideShow.getPictures();
|
return _hslfSlideShow.getPictures();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,7 +485,20 @@ public class SlideShow
|
|||||||
*/
|
*/
|
||||||
public Dimension getPageSize(){
|
public Dimension getPageSize(){
|
||||||
DocumentAtom docatom = _documentRecord.getDocumentAtom();
|
DocumentAtom docatom = _documentRecord.getDocumentAtom();
|
||||||
return new Dimension((int)docatom.getSlideSizeX(), (int)docatom.getSlideSizeY());
|
int pgx = (int)docatom.getSlideSizeX()*Shape.POINT_DPI/Shape.MASTER_DPI;
|
||||||
|
int pgy = (int)docatom.getSlideSizeY()*Shape.POINT_DPI/Shape.MASTER_DPI;
|
||||||
|
return new Dimension(pgx, pgy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the current page size
|
||||||
|
*
|
||||||
|
* @param pgsize page size (in points)
|
||||||
|
*/
|
||||||
|
public void setPageSize(Dimension pgsize){
|
||||||
|
DocumentAtom docatom = _documentRecord.getDocumentAtom();
|
||||||
|
docatom.setSlideSizeX(pgsize.width*Shape.MASTER_DPI/Shape.POINT_DPI);
|
||||||
|
docatom.setSlideSizeY(pgsize.height*Shape.MASTER_DPI/Shape.POINT_DPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -491,9 +506,9 @@ public class SlideShow
|
|||||||
*/
|
*/
|
||||||
protected FontCollection getFontCollection() { return _fonts; }
|
protected FontCollection getFontCollection() { return _fonts; }
|
||||||
/**
|
/**
|
||||||
* Helper method for usermodel: Get the document record
|
* Helper method for usermodel and model: Get the document record
|
||||||
*/
|
*/
|
||||||
protected Document getDocumentRecord() { return _documentRecord; }
|
public Document getDocumentRecord() { return _documentRecord; }
|
||||||
|
|
||||||
|
|
||||||
/* ===============================================================
|
/* ===============================================================
|
||||||
@ -607,6 +622,7 @@ public class SlideShow
|
|||||||
usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
|
usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
|
||||||
|
|
||||||
// All done and added
|
// All done and added
|
||||||
|
slide.setSlideShow(this);
|
||||||
return slide;
|
return slide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,14 @@ package org.apache.poi.hslf.model;
|
|||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import org.apache.poi.hslf.usermodel.SlideShow;
|
import org.apache.poi.hslf.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.hslf.usermodel.RichTextRun;
|
||||||
import org.apache.poi.hslf.HSLFSlideShow;
|
import org.apache.poi.hslf.HSLFSlideShow;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test drawing shapes via Graphics2D
|
* Test drawing shapes via Graphics2D
|
||||||
@ -36,21 +38,23 @@ public class TestShapes extends TestCase {
|
|||||||
String dirname = System.getProperty("HSLF.testdata.path");
|
String dirname = System.getProperty("HSLF.testdata.path");
|
||||||
String filename = dirname + "/empty.ppt";
|
String filename = dirname + "/empty.ppt";
|
||||||
ppt = new SlideShow(new HSLFSlideShow(filename));
|
ppt = new SlideShow(new HSLFSlideShow(filename));
|
||||||
getClass().getResourceAsStream("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGraphics() throws Exception {
|
public void testGraphics() throws Exception {
|
||||||
Slide slide = ppt.createSlide();
|
Slide slide = ppt.createSlide();
|
||||||
|
|
||||||
Line line = new Line();
|
Line line = new Line();
|
||||||
line.setAnchor(new Rectangle(1296, 2544, 1344, 528));
|
java.awt.Rectangle lineAnchor = new java.awt.Rectangle(100, 200, 50, 60);
|
||||||
|
line.setAnchor(lineAnchor);
|
||||||
|
System.out.println(line.getAnchor());
|
||||||
line.setLineWidth(3);
|
line.setLineWidth(3);
|
||||||
line.setLineStyle(Line.LineDashSys);
|
line.setLineStyle(Line.LineDashSys);
|
||||||
line.setLineColor(Color.red);
|
line.setLineColor(Color.red);
|
||||||
slide.addShape(line);
|
slide.addShape(line);
|
||||||
|
|
||||||
Ellipse ellipse = new Ellipse();
|
AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse);
|
||||||
ellipse.setAnchor(new Rectangle(4000, 1000, 1000, 1000));
|
java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111);
|
||||||
|
ellipse.setAnchor(ellipseAnchor);
|
||||||
ellipse.setLineWidth(2);
|
ellipse.setLineWidth(2);
|
||||||
ellipse.setLineStyle(Line.LineSolid);
|
ellipse.setLineStyle(Line.LineSolid);
|
||||||
ellipse.setLineColor(Color.green);
|
ellipse.setLineColor(Color.green);
|
||||||
@ -64,17 +68,103 @@ public class TestShapes extends TestCase {
|
|||||||
//read ppt from byte array
|
//read ppt from byte array
|
||||||
|
|
||||||
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
|
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
|
||||||
assertEquals(ppt.getSlides().length, 1);
|
assertEquals(1, ppt.getSlides().length);
|
||||||
|
|
||||||
slide = ppt.getSlides()[0];
|
slide = ppt.getSlides()[0];
|
||||||
Shape[] shape = slide.getShapes();
|
Shape[] shape = slide.getShapes();
|
||||||
assertEquals(shape.length, 2);
|
assertEquals(2, shape.length);
|
||||||
|
|
||||||
assertTrue(shape[0] instanceof Line); //group shape
|
assertTrue(shape[0] instanceof Line); //group shape
|
||||||
assertEquals(shape[0].getAnchor(), new Rectangle(1296, 2544, 1344, 528)); //group shape
|
assertEquals(lineAnchor, shape[0].getAnchor()); //group shape
|
||||||
|
|
||||||
assertTrue(shape[1] instanceof Ellipse); //group shape
|
assertTrue(shape[1] instanceof AutoShape); //group shape
|
||||||
assertEquals(shape[1].getAnchor(), new Rectangle(4000, 1000, 1000, 1000)); //group shape
|
assertEquals(ellipseAnchor, shape[1].getAnchor()); //group shape
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that we can read TextBox shapes
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testTextBoxRead() throws Exception {
|
||||||
|
String dirname = System.getProperty("HSLF.testdata.path");
|
||||||
|
String filename = dirname + "/with_textbox.ppt";
|
||||||
|
ppt = new SlideShow(new HSLFSlideShow(filename));
|
||||||
|
Slide sl = ppt.getSlides()[0];
|
||||||
|
Shape[] sh = sl.getShapes();
|
||||||
|
for (int i = 0; i < sh.length; i++) {
|
||||||
|
assertTrue(sh[i] instanceof TextBox);
|
||||||
|
TextBox txtbox = (TextBox)sh[i];
|
||||||
|
String text = txtbox.getText();
|
||||||
|
assertNotNull(text);
|
||||||
|
|
||||||
|
assertEquals(txtbox.getRichTextRuns().length, 1);
|
||||||
|
RichTextRun rt = txtbox.getRichTextRuns()[0];
|
||||||
|
|
||||||
|
if (text.equals("Hello, World!!!")){
|
||||||
|
assertEquals(32, rt.getFontSize());
|
||||||
|
assertTrue(rt.isBold());
|
||||||
|
assertTrue(rt.isItalic());
|
||||||
|
} else if (text.equals("I am just a poor boy")){
|
||||||
|
assertEquals(44, rt.getFontSize());
|
||||||
|
assertTrue(rt.isBold());
|
||||||
|
} else if (text.equals("This is Times New Roman")){
|
||||||
|
assertEquals(16, rt.getFontSize());
|
||||||
|
assertTrue(rt.isBold());
|
||||||
|
assertTrue(rt.isItalic());
|
||||||
|
assertTrue(rt.isUnderlined());
|
||||||
|
} else if (text.equals("Plain Text")){
|
||||||
|
assertEquals(18, rt.getFontSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that we can add TextBox shapes to a slide
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testTextBoxWrite() throws Exception {
|
||||||
|
ppt = new SlideShow();
|
||||||
|
Slide sl = ppt.createSlide();
|
||||||
|
|
||||||
|
TextBox txtbox = new TextBox();
|
||||||
|
txtbox.setText("Hello, World!");
|
||||||
|
txtbox.setFontSize(42);
|
||||||
|
txtbox.setBold(true);
|
||||||
|
txtbox.setItalic(true);
|
||||||
|
|
||||||
|
sl.addShape(txtbox);
|
||||||
|
|
||||||
|
txtbox = new TextBox();
|
||||||
|
txtbox.setText("Plain text in default font");
|
||||||
|
sl.addShape(txtbox);
|
||||||
|
|
||||||
|
assertEquals(sl.getShapes().length, 2);
|
||||||
|
|
||||||
|
//serialize and read again
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
ppt.write(out);
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
|
||||||
|
sl = ppt.getSlides()[0];
|
||||||
|
assertEquals(sl.getShapes().length, 2);
|
||||||
|
|
||||||
|
Shape[] sh = sl.getShapes();
|
||||||
|
for (int i = 0; i < sh.length; i++) {
|
||||||
|
assertTrue(sh[i] instanceof TextBox);
|
||||||
|
txtbox = (TextBox)sh[i];
|
||||||
|
String text = txtbox.getText();
|
||||||
|
assertNotNull(text);
|
||||||
|
|
||||||
|
assertEquals(txtbox.getRichTextRuns().length, 1);
|
||||||
|
RichTextRun rt = txtbox.getRichTextRuns()[0];
|
||||||
|
|
||||||
|
if (text.equals("Hello, World!")){
|
||||||
|
assertEquals(42, rt.getFontSize());
|
||||||
|
assertTrue(rt.isBold());
|
||||||
|
assertTrue(rt.isItalic());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,37 @@ public class TestPictures extends TestCase{
|
|||||||
|
|
||||||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
|
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
|
||||||
assertNotNull(img);
|
assertNotNull(img);
|
||||||
|
assertEquals(Picture.PNG, pict[i].getType());
|
||||||
}
|
}
|
||||||
ppt.close();
|
ppt.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReadPicturesForSlide() throws Exception {
|
||||||
|
|
||||||
|
SlideShow ppt = new SlideShow(new HSLFSlideShow(filename));
|
||||||
|
|
||||||
|
Slide[] slide = ppt.getSlides();
|
||||||
|
for (int i = 0; i < slide.length; i++) {
|
||||||
|
Slide sl = slide[i];
|
||||||
|
Shape[] sh = sl.getShapes();
|
||||||
|
for (int j = 0; j < sh.length; j++) {
|
||||||
|
Shape shape = sh[j];
|
||||||
|
if (shape instanceof Picture){
|
||||||
|
Picture picture = (Picture)shape;
|
||||||
|
|
||||||
|
PictureData pictdata = picture.getPictureData();
|
||||||
|
assertEquals(Picture.PNG, pictdata.getType());
|
||||||
|
|
||||||
|
//raw data.
|
||||||
|
byte[] data = pictdata.getData();
|
||||||
|
BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
|
||||||
|
assertNotNull(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testSerializePictures() throws Exception {
|
public void testSerializePictures() throws Exception {
|
||||||
HSLFSlideShow ppt = new HSLFSlideShow(filename);
|
HSLFSlideShow ppt = new HSLFSlideShow(filename);
|
||||||
PictureData[] pict = ppt.getPictures();
|
PictureData[] pict = ppt.getPictures();
|
||||||
@ -78,12 +105,10 @@ public class TestPictures extends TestCase{
|
|||||||
idx = ppt.addPicture(new File(dirname + "/clock.jpg"), Picture.JPEG);
|
idx = ppt.addPicture(new File(dirname + "/clock.jpg"), Picture.JPEG);
|
||||||
slide = ppt.createSlide();
|
slide = ppt.createSlide();
|
||||||
pict = new Picture(idx);
|
pict = new Picture(idx);
|
||||||
pict.setDefaultSize(ppt);
|
|
||||||
slide.addShape(pict);
|
slide.addShape(pict);
|
||||||
|
|
||||||
idx = ppt.addPicture(new File(dirname + "/painting.png"), Picture.PNG);
|
idx = ppt.addPicture(new File(dirname + "/painting.png"), Picture.PNG);
|
||||||
pict = new Picture(idx);
|
pict = new Picture(idx);
|
||||||
pict.setDefaultSize(ppt);
|
|
||||||
slide.addShape(pict);
|
slide.addShape(pict);
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
@ -91,7 +116,7 @@ public class TestPictures extends TestCase{
|
|||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
|
ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
|
||||||
assertTrue(ppt.getPictures().length == 2 );
|
assertTrue(ppt.getPictureData().length == 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user