You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ni...@apache.org on 2006/04/12 20:49:10 UTC

svn commit: r393576 - in /jakarta/poi/trunk/src/scratchpad: src/org/apache/poi/hslf/model/ src/org/apache/poi/hslf/record/ src/org/apache/poi/hslf/usermodel/ testcases/org/apache/poi/hslf/model/ testcases/org/apache/poi/hslf/usermodel/

Author: nick
Date: Wed Apr 12 11:48:53 2006
New Revision: 393576

URL: http://svn.apache.org/viewcvs?rev=393576&view=rev
Log:
Updates from Yegor: New shape and picture stuff (see bug 39256)

Added:
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
Modified:
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java?rev=393576&view=auto
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShape.java Wed Apr 12 11:48:53 2006
@@ -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;
+    }
+
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Line.java Wed Apr 12 11:48:53 2006
@@ -107,13 +107,12 @@
         EscherContainerRecord spcont = super.createSpContainer(isChild);
 
         EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
-        short type = (ShapeTypes.Line << 4) + 2;
+        short type = (ShapeTypes.Line << 4) | 0x2;
         spRecord.setOptions(type);
   
         //set default properties for a line
         EscherOptRecord opt = (EscherOptRecord)getEscherChild(spcont, EscherOptRecord.RECORD_ID);
 
-        //opt.addEscherProperty(new EscherSimpleProperty(EscherProperties.GEOMETRY__SHAPEPATH, 4));
         opt.sortProperties();
 
         return spcont;

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/PPGraphics2D.java Wed Apr 12 11:48:53 2006
@@ -139,6 +139,34 @@
     }
 
     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){
@@ -212,7 +240,7 @@
     }
 
     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));
         if (stroke instanceof BasicStroke){
             BasicStroke bs = (BasicStroke)stroke;

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java Wed Apr 12 11:48:53 2006
@@ -3,11 +3,14 @@
 import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.usermodel.PictureData;
 import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.hslf.record.Document;
 
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.util.List;
+import java.util.Arrays;
 
 
 /**
@@ -122,16 +125,49 @@
     }
 
     /**
-     * Set default size of the picture
-     *
-     * @param ppt presentation which holds the picture
+     * Resize this picture to the default size.
      */
-    public void setDefaultSize(SlideShow ppt) throws IOException {
-        int idx = getPictureIndex();
+    public void setDefaultSize(){
+        PictureData pict = getPictureData();
+        try {
+            BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
+            setAnchor(new java.awt.Rectangle(0, 0, img.getWidth(), img.getHeight()));
+        } catch (IOException e){
+            throw new RuntimeException(e);
+        }
+    }
 
-        PictureData pict = ppt.getPictures()[idx-1];
-        BufferedImage img = ImageIO.read(new ByteArrayInputStream(pict.getData()));
+    /**
+     * 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;
+    }
 
-        setAnchor(new java.awt.Rectangle(0, 0, img.getWidth()*6, img.getHeight()*6));
+    /**
+     * 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();
+        }
     }
+
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Rectangle.java Wed Apr 12 11:48:53 2006
@@ -21,38 +21,30 @@
 import java.awt.*;
 
 /**
- * Represents a line in a PowerPoint drawing
+ * Represents a rectangle shae in a PowerPoint drawing
  *
  *  @author Yegor Kozlov
  */
-public class Rectangle extends SimpleShape {
+public class Rectangle extends TextBox {
 
     protected Rectangle(EscherContainerRecord escherRecord, Shape parent){
         super(escherRecord, parent);
     }
 
     public Rectangle(Shape parent){
-        super(null, parent);
-        _escherContainer = createSpContainer(parent instanceof ShapeGroup);
+        super(parent);
     }
 
     public Rectangle(){
-        this(null);
+        super();
     }
 
     protected EscherContainerRecord createSpContainer(boolean isChild){
         EscherContainerRecord spcont = super.createSpContainer(isChild);
-        spcont.setOptions((short)15);
 
         EscherSpRecord spRecord = spcont.getChildById(EscherSpRecord.RECORD_ID);
         short type = (ShapeTypes.Rectangle << 4) + 2;
         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;
     }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java Wed Apr 12 11:48:53 2006
@@ -22,13 +22,47 @@
 import java.util.Iterator;
 
 /**
+ *  <p>
   * 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�left corner of the bounding box for the shape relative to the upper�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
  */
 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_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
@@ -43,6 +77,11 @@
     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.
      *
      * @param escherRecord       <code>EscherSpContainer</code> container which holds information about this shape
@@ -86,25 +125,25 @@
         if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
             EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
             anchor = new java.awt.Rectangle();
-            anchor.x = rec.getDx1();
-            anchor.y = rec.getDy1();
-            anchor.width = rec.getDx2() - anchor.x;
-            anchor.height = rec.getDy2() - anchor.y;
+            anchor.x = rec.getDx1()*POINT_DPI/MASTER_DPI;
+            anchor.y = rec.getDy1()*POINT_DPI/MASTER_DPI;
+            anchor.width = (rec.getDx2() - anchor.x)*POINT_DPI/MASTER_DPI;
+            anchor.height = (rec.getDy2() - anchor.y)*POINT_DPI/MASTER_DPI;
         }
         else {
             EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
             anchor = new java.awt.Rectangle();
-            anchor.y = rec.getFlag();
-            anchor.x = rec.getCol1();
-            anchor.width = rec.getDx1() - anchor.x;
-            anchor.height = rec.getRow1() - anchor.y;
+            anchor.y = rec.getFlag()*POINT_DPI/MASTER_DPI;
+            anchor.x = rec.getCol1()*POINT_DPI/MASTER_DPI;
+            anchor.width = (rec.getDx1() - rec.getCol1())*POINT_DPI/MASTER_DPI;
+            anchor.height = (rec.getRow1() - rec.getFlag())*POINT_DPI/MASTER_DPI;
         }
         return anchor;
     }
 
     /**
      * 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
      */
@@ -113,17 +152,17 @@
         int flags = spRecord.getFlags();
         if ((flags & EscherSpRecord.FLAG_CHILD) != 0){
             EscherChildAnchorRecord rec = (EscherChildAnchorRecord)getEscherChild(_escherContainer, EscherChildAnchorRecord.RECORD_ID);
-            rec.setDx1(anchor.x);
-            rec.setDy1(anchor.y);
-            rec.setDx2(anchor.width + anchor.x);
-            rec.setDy2(anchor.height + anchor.y);
+            rec.setDx1(anchor.x*MASTER_DPI/POINT_DPI);
+            rec.setDy1(anchor.y*MASTER_DPI/POINT_DPI);
+            rec.setDx2((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI);
+            rec.setDy2((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI);
         }
         else {
             EscherClientAnchorRecord rec = (EscherClientAnchorRecord)getEscherChild(_escherContainer, EscherClientAnchorRecord.RECORD_ID);
-            rec.setFlag((short)anchor.y);
-            rec.setCol1((short)anchor.x);
-            rec.setDx1((short)(anchor.width + anchor.x));
-            rec.setRow1((short)(anchor.height + anchor.y));
+            rec.setFlag((short)(anchor.y*MASTER_DPI/POINT_DPI));
+            rec.setCol1((short)(anchor.x*MASTER_DPI/POINT_DPI));
+            rec.setDx1((short)((anchor.width + anchor.x)*MASTER_DPI/POINT_DPI));
+            rec.setRow1((short)((anchor.height + anchor.y)*MASTER_DPI/POINT_DPI));
         }
 
     }
@@ -171,11 +210,11 @@
     }
 
     /**
-     * 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 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){
         java.util.List props = opt.getEscherProperties();
@@ -198,4 +237,33 @@
     public EscherContainerRecord getSpContainer(){
         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;
+    }
+
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java Wed Apr 12 11:48:53 2006
@@ -25,6 +25,9 @@
  */
 public class ShapeFactory {
 
+    /**
+     * Create a new shape from the data provided.  
+     */
     public static Shape createShape(EscherContainerRecord spContainer, Shape parent){
         if (spContainer.getRecordId() == EscherContainerRecord.SPGR_CONTAINER){
             return new ShapeGroup(spContainer, parent);
@@ -36,6 +39,8 @@
         int type = spRecord.getOptions() >> 4;
         switch (type){
             case ShapeTypes.TextBox:
+                shape = new TextBox(spContainer, parent);
+                break;
             case ShapeTypes.Rectangle:
                 shape = new Rectangle(spContainer, parent);
                 break;
@@ -45,14 +50,11 @@
             case ShapeTypes.Line:
                 shape = new Line(spContainer, parent);
                 break;
-            case ShapeTypes.Ellipse:
-                shape = new Ellipse(spContainer, parent);
-                break;
             case ShapeTypes.NotPrimitive:
                 shape = new ShapeGroup(spContainer, parent);
                 break;
             default:
-                shape = new SimpleShape(spContainer, parent);
+                shape = new AutoShape(spContainer, parent);
                 break;
         }
         return shape;

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java Wed Apr 12 11:48:53 2006
@@ -27,11 +27,21 @@
  */
 public class ShapeGroup extends Shape{
 
+    /**
+      * Create a new ShapeGroup. This constructor is used when a new shape is created.
+      *
+      */
     public ShapeGroup(){
         this(null, null);
         _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){
         super(escherRecord, parent);
     }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeTypes.java Wed Apr 12 11:48:53 2006
@@ -82,9 +82,9 @@
     public static final int Chevron = 55;
     public static final int Pentagon = 56;
     public static final int NoSmoking = 57;
-    public static final int Seal8 = 58;
-    public static final int Seal16 = 59;
-    public static final int Seal32 = 60;
+    public static final int Star8 = 58;
+    public static final int Star16 = 59;
+    public static final int Star32 = 60;
     public static final int WedgeRectCallout = 61;
     public static final int WedgeRRectCallout = 62;
     public static final int WedgeEllipseCallout = 63;
@@ -116,7 +116,7 @@
     public static final int LeftUpArrow = 89;
     public static final int BentUpArrow = 90;
     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 NotchedRightArrow = 94;
     public static final int BlockArc = 95;
@@ -211,7 +211,7 @@
     public static final int Moon = 184;
     public static final int BracketPair = 185;
     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 ActionButtonBlank = 189;
     public static final int ActionButtonHome = 190;

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java Wed Apr 12 11:48:53 2006
@@ -23,6 +23,7 @@
 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;
@@ -39,6 +40,11 @@
 public abstract class Sheet
 {
   /**
+   * The <code>SlideShow</code> we belong to
+   */
+  private SlideShow _slideShow; 
+  
+  /**
    * Returns an array of all the TextRuns in the sheet.
    */
   public abstract TextRun[] getTextRuns();
@@ -59,7 +65,19 @@
    * 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
    */
@@ -149,7 +167,9 @@
 	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()]);
@@ -169,5 +189,8 @@
 
 	EscherDgRecord dg = (EscherDgRecord)Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
 	dg.setNumShapes(dg.getNumShapes()+1);
+	
+	shape.setSheet(this);
+	shape.afterInsert(this);
   }
 } 

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java Wed Apr 12 11:48:53 2006
@@ -29,6 +29,12 @@
  */
 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){
         super(escherRecord, parent);
     }
@@ -102,12 +108,12 @@
     }
 
     /**
-     * @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(){
         EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
         EscherRGBProperty prop = (EscherRGBProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__COLOR);
-        Color color = null;
+        Color color = Color.black;
         if (prop != null){
             Color swp = new Color(prop.getRgbColor());
             color = new Color(swp.getBlue(), swp.getGreen(), swp.getRed());
@@ -136,6 +142,11 @@
         return prop == null ? Line.LineSolid : prop.getPropertyValue();
     }
 
+    /**
+     * The color used to fill this shape.
+     *
+     * @param color the background color
+     */
     public void setFillColor(Color color){
         EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
         int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB();

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java?rev=393576&view=auto
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java Wed Apr 12 11:48:53 2006
@@ -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);
+    }
+    
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java Wed Apr 12 11:48:53 2006
@@ -47,7 +47,7 @@
 	/** 
 	 * 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();
 
@@ -55,7 +55,18 @@
 		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)

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java Wed Apr 12 11:48:53 2006
@@ -262,4 +262,15 @@
 			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;
+	}
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextBytesAtom.java Wed Apr 12 11:48:53 2006
@@ -71,6 +71,18 @@
 		_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

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextHeaderAtom.java Wed Apr 12 11:48:53 2006
@@ -75,6 +75,18 @@
 		// 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

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java Wed Apr 12 11:48:53 2006
@@ -25,6 +25,7 @@
 
 /**
  * A class that represents the image data contained in the Presentation.
+ * 
  *
  *  @author Yegor Kozlov
  */
@@ -35,6 +36,9 @@
 	*/
 	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
 	*/
@@ -118,10 +122,26 @@
 	*/
 	public void setType(int format){
         switch (format){
-            case Picture.JPEG: LittleEndian.putInt(header, 0, -266516832); break;
-            case Picture.PNG: LittleEndian.putInt(header, 0, -266441216); break;
+            case Picture.JPEG: LittleEndian.putInt(header, 0, PictureData.JPEG_HEADER); 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

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java Wed Apr 12 11:48:53 2006
@@ -401,6 +401,7 @@
 	_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
@@ -418,6 +419,7 @@
 	_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
@@ -472,9 +474,9 @@
 	//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();
 	}
 	
@@ -483,7 +485,20 @@
 	 */
 	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);
 	}
 	
 	/**
@@ -491,9 +506,9 @@
 	 */
 	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 @@
   		usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
   		
   		// All done and added
+  		slide.setSlideShow(this);
   		return slide;
 	}
 

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java Wed Apr 12 11:48:53 2006
@@ -17,12 +17,14 @@
 
 import junit.framework.TestCase;
 import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.hslf.usermodel.RichTextRun;
 import org.apache.poi.hslf.HSLFSlideShow;
 
 import java.awt.*;
 import java.awt.Rectangle;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
 
 /**
  * Test drawing shapes via Graphics2D
@@ -36,21 +38,23 @@
 		String dirname = System.getProperty("HSLF.testdata.path");
 		String filename = dirname + "/empty.ppt";
 		ppt = new SlideShow(new HSLFSlideShow(filename));
-        getClass().getResourceAsStream("");
     }
 
     public void testGraphics() throws Exception {
         Slide slide = ppt.createSlide();
 
         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.setLineStyle(Line.LineDashSys);
         line.setLineColor(Color.red);
         slide.addShape(line);
 
-        Ellipse ellipse = new Ellipse();
-        ellipse.setAnchor(new Rectangle(4000, 1000, 1000, 1000));
+        AutoShape ellipse = new AutoShape(ShapeTypes.Ellipse);
+        java.awt.Rectangle ellipseAnchor = new Rectangle(320, 154, 55, 111);
+        ellipse.setAnchor(ellipseAnchor);
         ellipse.setLineWidth(2);
         ellipse.setLineStyle(Line.LineSolid);
         ellipse.setLineColor(Color.green);
@@ -64,17 +68,103 @@
         //read ppt from byte array
 
         ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
-        assertEquals(ppt.getSlides().length, 1);
+        assertEquals(1, ppt.getSlides().length);
 
         slide = ppt.getSlides()[0];
         Shape[] shape = slide.getShapes();
-        assertEquals(shape.length, 2);
+        assertEquals(2, shape.length);
 
         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
-        assertEquals(shape[1].getAnchor(), new Rectangle(4000, 1000, 1000, 1000)); //group shape
+        assertTrue(shape[1] instanceof AutoShape); //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());
+            }
+        }
     }
 
 }

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java
URL: http://svn.apache.org/viewcvs/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java?rev=393576&r1=393575&r2=393576&view=diff
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPictures.java Wed Apr 12 11:48:53 2006
@@ -50,10 +50,37 @@
 
             BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
             assertNotNull(img);
+            assertEquals(Picture.PNG, pict[i].getType());
         }
         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 {
         HSLFSlideShow ppt = new HSLFSlideShow(filename);
         PictureData[] pict = ppt.getPictures();
@@ -78,12 +105,10 @@
         idx = ppt.addPicture(new File(dirname + "/clock.jpg"), Picture.JPEG);
         slide = ppt.createSlide();
         pict = new Picture(idx);
-        pict.setDefaultSize(ppt);
         slide.addShape(pict);
 
         idx = ppt.addPicture(new File(dirname + "/painting.png"), Picture.PNG);
         pict = new Picture(idx);
-        pict.setDefaultSize(ppt);
         slide.addShape(pict);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -91,7 +116,7 @@
         out.close();
 
         ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
-        assertTrue(ppt.getPictures().length == 2 );
+        assertTrue(ppt.getPictureData().length == 2 );
     }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
Mailing List:    http://jakarta.apache.org/site/mail2.html#poi
The Apache Jakarta POI Project: http://jakarta.apache.org/poi/