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