You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ba...@apache.org on 2006/12/22 21:56:06 UTC

svn commit: r489760 [5/8] - in /jakarta/poi/trunk/src: java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/formula/ java/org/apache/poi/hssf/util/ scratchpad/src/org/apache/poi/hslf/blip/ scratchpad/src/org/apache/poi/hslf/extractor/ scrat...

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java Fri Dec 22 12:56:04 2006
@@ -1,504 +1,504 @@
-
-/* ====================================================================
-   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;
-import java.util.Vector;
-
-/**
- * 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;
-
-    /**
-     * 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;
-    
-    /**
-     * Is the TextBox missing the text records which actually
-     *  store the text?
-     */
-    private boolean _missingTextRecords = false;
-
-    /**
-     * 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);
-    }
-
-    /**
-     * 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, 0x8000004);
-        setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
-        setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000);
-        setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001);
-        setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
-        setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
-
-        //create EscherTextboxWrapper
-        _txtbox = new EscherTextboxWrapper();
-
-        TextHeaderAtom tha = new TextHeaderAtom();
-        tha.setParentRecord(_txtbox); // TextHeaderAtom is parent aware
-        _txtbox.appendChildRecord(tha);
-
-        TextCharsAtom tca = new TextCharsAtom();
-        _txtbox.appendChildRecord(tca);
-
-        StyleTextPropAtom sta = new StyleTextPropAtom(0);
-        _txtbox.appendChildRecord(sta);
-
-        _txtrun = new TextRun(tha,tca,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);
-        }
-        if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText();
-    }
-
-    /**
-     * Adjust the size of the TextBox so it encompasses the text inside it.
-     */
-    public void resizeToFitText(){
-        try{
-        FontRenderContext frc = new FontRenderContext(null, true, true);
-        RichTextRun rt = _txtrun.getRichTextRuns()[0];
-        int size = rt.getFontSize();
-        int style = 0;
-        if (rt.isBold()) style |= Font.BOLD;
-        if (rt.isItalic()) style |= Font.ITALIC;
-        String fntname = rt.getFontName();
-        Font font = new Font(fntname, style, size);
-
-        TextLayout layout = new TextLayout(getText(), font, frc);
-        int width = Math.round(layout.getAdvance());
-        int height = Math.round(layout.getAscent());
-
-        Dimension txsize = new Dimension(width, height);
-        java.awt.Rectangle anchor = getAnchor();
-        anchor.setSize(txsize);
-        setAnchor(anchor);
-        } catch (Exception e){
-            e.printStackTrace();
-
-        }
-    }
-
-    /**
-     * 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);
-        int valign;
-        if (prop == null){
-            int type = getTextRun().getRunType();
-            switch (type){
-                case TextHeaderAtom.TITLE_TYPE:
-                case TextHeaderAtom.CENTER_TITLE_TYPE:
-                    valign = TextBox.AnchorMiddle;
-                    break;
-                default:
-                    valign = TextBox.AnchorTop;
-                    break;
-            }
-        } else {
-            valign = prop.getPropertyValue();
-        }
-        return valign;
-    }
-
-    /**
-     * 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 the TextRun object for this text box
-      */
-     public TextRun getTextRun(){
-         return _txtrun;
-     }
-
-     public void setSheet(Sheet sheet){
-        _sheet = sheet;
-
-        // Initialize _txtrun object.
-        // (We can't do it in the constructor because the sheet
-        //  is not assigned then, it's only built once we have
-        //  all the records)
-        if(_txtrun == null) initTextRun();
-        if(_txtrun == null) {
-        	// No text records found, skip
-        	_missingTextRecords = true;
-        	return;
-        } else {
-        	_missingTextRecords = false;
-        }
-        
-        // Supply the sheet to our child RichTextRuns
-        _txtrun.setSheet(sheet);
-        RichTextRun[] rt = _txtrun.getRichTextRuns();
-        for (int i = 0; i < rt.length; i++) {
-            rt[i].supplySlideShow(_sheet.getSlideShow());
-        }
-    }
-
-    private void initTextRun(){
-        TextHeaderAtom tha = null;
-        TextCharsAtom tca = null;
-        TextBytesAtom tba = null;
-        StyleTextPropAtom sta = null;
-        OutlineTextRefAtom ota = null;
-        
-        // Find the interesting child records 
-        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];
-            else if (child[i] instanceof OutlineTextRefAtom) ota = (OutlineTextRefAtom)child[i];
-            else if (child[i] instanceof TextCharsAtom) tca = (TextCharsAtom)child[i];
-        }
-
-        // Special handling for cases where there's an OutlineTextRefAtom
-        if (ota != null) {
-            // TextHeaderAtom, TextBytesAtom and StyleTextPropAtom are
-        	//  stored outside of  EscherContainerRecord
-            int idx = ota.getTextIndex();
-            Slide sl = (Slide)getSheet();
-            Record[] rec = sl.getSlideAtomsSet().getSlideRecords();
-            for (int i = 0, j = 0; i < rec.length; i++) {
-                if(rec[i].getRecordType() == RecordTypes.TextHeaderAtom.typeID){
-                    if(j++ == idx) { //we found j-th  TextHeaderAtom, read the text data
-                        for (int k = i; k < rec.length; k++) {
-                            if (rec[k] instanceof TextHeaderAtom) {
-                                if (tha != null) break;
-                                else tha = (TextHeaderAtom)rec[k];
-                            }
-                            else if (rec[k] instanceof TextBytesAtom) tba = (TextBytesAtom)rec[k];
-                            else if (rec[k] instanceof TextCharsAtom) tca = (TextCharsAtom)rec[k];
-                            else if (rec[k] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)rec[k];
-                        }
-                    }
-                }
-            }
-        }
-        
-        // If we found the records we needed, create a TextRun
-        if(tba != null) {
-        	// Bytes based Text Run
-        	_txtrun = new TextRun(tha,tba,sta);
-        } else if (tca != null) {
-        	// Characters (unicode) based Text Run
-        	_txtrun = new TextRun(tha,tca,sta);
-        } else {
-        	// Empty text box
-        	System.err.println("Warning - no text records found for TextBox");
-        }
-    }
-}
+
+/* ====================================================================
+   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;
+import java.util.Vector;
+
+/**
+ * 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;
+
+    /**
+     * 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;
+    
+    /**
+     * Is the TextBox missing the text records which actually
+     *  store the text?
+     */
+    private boolean _missingTextRecords = false;
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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, 0x8000004);
+        setEscherProperty(opt, EscherProperties.FILL__FILLBACKCOLOR, 0x8000000);
+        setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x100000);
+        setEscherProperty(opt, EscherProperties.LINESTYLE__COLOR, 0x8000001);
+        setEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x80000);
+        setEscherProperty(opt, EscherProperties.SHADOWSTYLE__COLOR, 0x8000002);
+
+        //create EscherTextboxWrapper
+        _txtbox = new EscherTextboxWrapper();
+
+        TextHeaderAtom tha = new TextHeaderAtom();
+        tha.setParentRecord(_txtbox); // TextHeaderAtom is parent aware
+        _txtbox.appendChildRecord(tha);
+
+        TextCharsAtom tca = new TextCharsAtom();
+        _txtbox.appendChildRecord(tca);
+
+        StyleTextPropAtom sta = new StyleTextPropAtom(0);
+        _txtbox.appendChildRecord(sta);
+
+        _txtrun = new TextRun(tha,tca,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);
+        }
+        if(getAnchor().equals(new java.awt.Rectangle())) resizeToFitText();
+    }
+
+    /**
+     * Adjust the size of the TextBox so it encompasses the text inside it.
+     */
+    public void resizeToFitText(){
+        try{
+        FontRenderContext frc = new FontRenderContext(null, true, true);
+        RichTextRun rt = _txtrun.getRichTextRuns()[0];
+        int size = rt.getFontSize();
+        int style = 0;
+        if (rt.isBold()) style |= Font.BOLD;
+        if (rt.isItalic()) style |= Font.ITALIC;
+        String fntname = rt.getFontName();
+        Font font = new Font(fntname, style, size);
+
+        TextLayout layout = new TextLayout(getText(), font, frc);
+        int width = Math.round(layout.getAdvance());
+        int height = Math.round(layout.getAscent());
+
+        Dimension txsize = new Dimension(width, height);
+        java.awt.Rectangle anchor = getAnchor();
+        anchor.setSize(txsize);
+        setAnchor(anchor);
+        } catch (Exception e){
+            e.printStackTrace();
+
+        }
+    }
+
+    /**
+     * 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);
+        int valign;
+        if (prop == null){
+            int type = getTextRun().getRunType();
+            switch (type){
+                case TextHeaderAtom.TITLE_TYPE:
+                case TextHeaderAtom.CENTER_TITLE_TYPE:
+                    valign = TextBox.AnchorMiddle;
+                    break;
+                default:
+                    valign = TextBox.AnchorTop;
+                    break;
+            }
+        } else {
+            valign = prop.getPropertyValue();
+        }
+        return valign;
+    }
+
+    /**
+     * 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 the TextRun object for this text box
+      */
+     public TextRun getTextRun(){
+         return _txtrun;
+     }
+
+     public void setSheet(Sheet sheet){
+        _sheet = sheet;
+
+        // Initialize _txtrun object.
+        // (We can't do it in the constructor because the sheet
+        //  is not assigned then, it's only built once we have
+        //  all the records)
+        if(_txtrun == null) initTextRun();
+        if(_txtrun == null) {
+        	// No text records found, skip
+        	_missingTextRecords = true;
+        	return;
+        } else {
+        	_missingTextRecords = false;
+        }
+        
+        // Supply the sheet to our child RichTextRuns
+        _txtrun.setSheet(sheet);
+        RichTextRun[] rt = _txtrun.getRichTextRuns();
+        for (int i = 0; i < rt.length; i++) {
+            rt[i].supplySlideShow(_sheet.getSlideShow());
+        }
+    }
+
+    private void initTextRun(){
+        TextHeaderAtom tha = null;
+        TextCharsAtom tca = null;
+        TextBytesAtom tba = null;
+        StyleTextPropAtom sta = null;
+        OutlineTextRefAtom ota = null;
+        
+        // Find the interesting child records 
+        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];
+            else if (child[i] instanceof OutlineTextRefAtom) ota = (OutlineTextRefAtom)child[i];
+            else if (child[i] instanceof TextCharsAtom) tca = (TextCharsAtom)child[i];
+        }
+
+        // Special handling for cases where there's an OutlineTextRefAtom
+        if (ota != null) {
+            // TextHeaderAtom, TextBytesAtom and StyleTextPropAtom are
+        	//  stored outside of  EscherContainerRecord
+            int idx = ota.getTextIndex();
+            Slide sl = (Slide)getSheet();
+            Record[] rec = sl.getSlideAtomsSet().getSlideRecords();
+            for (int i = 0, j = 0; i < rec.length; i++) {
+                if(rec[i].getRecordType() == RecordTypes.TextHeaderAtom.typeID){
+                    if(j++ == idx) { //we found j-th  TextHeaderAtom, read the text data
+                        for (int k = i; k < rec.length; k++) {
+                            if (rec[k] instanceof TextHeaderAtom) {
+                                if (tha != null) break;
+                                else tha = (TextHeaderAtom)rec[k];
+                            }
+                            else if (rec[k] instanceof TextBytesAtom) tba = (TextBytesAtom)rec[k];
+                            else if (rec[k] instanceof TextCharsAtom) tca = (TextCharsAtom)rec[k];
+                            else if (rec[k] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)rec[k];
+                        }
+                    }
+                }
+            }
+        }
+        
+        // If we found the records we needed, create a TextRun
+        if(tba != null) {
+        	// Bytes based Text Run
+        	_txtrun = new TextRun(tha,tba,sta);
+        } else if (tca != null) {
+        	// Characters (unicode) based Text Run
+        	_txtrun = new TextRun(tha,tca,sta);
+        } else {
+        	// Empty text box
+        	System.err.println("Warning - no text records found for TextBox");
+        }
+    }
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OEPlaceholderAtom.java Fri Dec 22 12:56:04 2006
@@ -1,200 +1,200 @@
-
-/* ====================================================================
-   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.record;
-
-import org.apache.poi.util.LittleEndian;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * OEPlaceholderAtom (3011).
- * <p>
- *  Atom that describes the placeholder.
- * </p>
- *
- * @author Yegor Kozlov
- */
-
-public class OEPlaceholderAtom extends RecordAtom{
-
-    public static final int PLACEHOLDER_FULLSIZE = 0;
-    public static final int PLACEHOLDER_HALFSIZE = 1;
-    public static final int PLACEHOLDER_QUARTSIZE = 2;
-
-    public static final byte None = 0;
-
-    public static final byte MasterTitle = 1;
-
-    public static final byte MasterBody = 2;
-
-    public static final byte MasterCenteredTitle = 3;
-
-    public static final byte MasterNotesSlideImage = 4;
-
-    public static final byte MasterNotesBodyImage = 5;
-
-    public static final byte MasterDate = 6;
-
-    public static final byte MasterSlideNumber = 7;
-
-    public static final byte MasterFooter = 8;
-
-    public static final byte MasterHeader = 9;
-
-    public static final byte MasterSubtitle = 10;
-
-    public static final byte GenericTextObject = 11;
-
-    public static final byte Title = 12;
-
-    public static final byte Body = 13;
-
-    public static final byte NotesBody = 14;
-
-    public static final byte CenteredTitle = 15;
-
-    public static final byte Subtitle = 16;
-
-    public static final byte VerticalTextTitle = 17;
-
-    public static final byte VerticalTextBody = 18;
-
-    public static final byte NotesSlideImage = 19;
-
-    public static final byte Object = 20;
-
-    public static final byte Graph = 21;
-
-    public static final byte Table = 22;
-
-    public static final byte ClipArt = 23;
-
-    public static final byte OrganizationChart = 24;
-
-    public static final byte MediaClip = 25;
-
-	private byte[] _header;
-
-    private int placementId;
-    private int placeholderId;
-    private int placeholderSize;
-
-
-    /**
-     * Create a new instance of <code>OEPlaceholderAtom</code>
-     */
-    public OEPlaceholderAtom(){
-        _header = new byte[8];
-        LittleEndian.putUShort(_header, 0, 0);
-        LittleEndian.putUShort(_header, 2, (int)getRecordType());
-        LittleEndian.putInt(_header, 4, 8);
-
-        placementId = 0;
-        placeholderId = 0;
-        placeholderSize = 0;
-    }
-
-    /**
-     * Build an instance of <code>OEPlaceholderAtom</code> from on-disk data
-     */
-	protected OEPlaceholderAtom(byte[] source, int start, int len) {
-		_header = new byte[8];
-		System.arraycopy(source,start,_header,0,8);
-
-        placementId = LittleEndian.getInt(source, start);
-        placeholderId = LittleEndian.getUnsignedByte(source, start+4);
-        placeholderSize = LittleEndian.getUnsignedByte(source, start+5);
-	}
-
-    /**
-     * @return type of this record {@link RecordTypes#OEPlaceholderAtom}.
-     */
-	public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; }
-
-    /**
-     * Returns the placement Id.
-     *
-     * @return the placement Id.
-     */
-    public int getPlacementId(){
-        return placementId;
-    }
-
-    /**
-     * Sets the placement Id.
-     *
-     * @param id the placement Id.
-     */
-   public void setPlacementId(int id){
-        placementId = id;
-    }
-
-    /**
-     * Returns the placeholder Id.
-     *
-     * @return the placeholder Id.
-     */
-    public int getPlaceholderId(){
-        return placeholderId;
-    }
-
-    /**
-     * Sets the placeholder Id.
-     *
-     * @param id the placeholder Id.
-     */
-    public void setPlaceholderId(byte id){
-        placeholderId = id;
-    }
-
-    /**
-     * Returns the placeholder size.
-     * Must be one of the PLACEHOLDER_* static constants defined in this class.
-     *
-     * @return the placeholder size.
-     */
-    public int getPlaceholderSize(){
-        return placeholderSize;
-    }
-
-    /**
-     * Sets the placeholder size.
-     * Must be one of the PLACEHOLDER_* static constants defined in this class.
-     *
-     * @param size the placeholder size.
-     */
-     public void setPlaceholderSize(byte size){
-        placeholderSize = size;
-    }
-
-	/**
-	 * Write the contents of the record back, so it can be written
-	 *  to disk
-	 */
-	public void writeOut(OutputStream out) throws IOException {
-		out.write(_header);
-
-        byte[] recdata = new byte[8];
-        LittleEndian.putInt(recdata, 0, placementId);
-        recdata[4] = (byte)placeholderId;
-        recdata[5] = (byte)placeholderSize;
-
-        out.write(recdata);
-	}
-}
+
+/* ====================================================================
+   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.record;
+
+import org.apache.poi.util.LittleEndian;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * OEPlaceholderAtom (3011).
+ * <p>
+ *  Atom that describes the placeholder.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+
+public class OEPlaceholderAtom extends RecordAtom{
+
+    public static final int PLACEHOLDER_FULLSIZE = 0;
+    public static final int PLACEHOLDER_HALFSIZE = 1;
+    public static final int PLACEHOLDER_QUARTSIZE = 2;
+
+    public static final byte None = 0;
+
+    public static final byte MasterTitle = 1;
+
+    public static final byte MasterBody = 2;
+
+    public static final byte MasterCenteredTitle = 3;
+
+    public static final byte MasterNotesSlideImage = 4;
+
+    public static final byte MasterNotesBodyImage = 5;
+
+    public static final byte MasterDate = 6;
+
+    public static final byte MasterSlideNumber = 7;
+
+    public static final byte MasterFooter = 8;
+
+    public static final byte MasterHeader = 9;
+
+    public static final byte MasterSubtitle = 10;
+
+    public static final byte GenericTextObject = 11;
+
+    public static final byte Title = 12;
+
+    public static final byte Body = 13;
+
+    public static final byte NotesBody = 14;
+
+    public static final byte CenteredTitle = 15;
+
+    public static final byte Subtitle = 16;
+
+    public static final byte VerticalTextTitle = 17;
+
+    public static final byte VerticalTextBody = 18;
+
+    public static final byte NotesSlideImage = 19;
+
+    public static final byte Object = 20;
+
+    public static final byte Graph = 21;
+
+    public static final byte Table = 22;
+
+    public static final byte ClipArt = 23;
+
+    public static final byte OrganizationChart = 24;
+
+    public static final byte MediaClip = 25;
+
+	private byte[] _header;
+
+    private int placementId;
+    private int placeholderId;
+    private int placeholderSize;
+
+
+    /**
+     * Create a new instance of <code>OEPlaceholderAtom</code>
+     */
+    public OEPlaceholderAtom(){
+        _header = new byte[8];
+        LittleEndian.putUShort(_header, 0, 0);
+        LittleEndian.putUShort(_header, 2, (int)getRecordType());
+        LittleEndian.putInt(_header, 4, 8);
+
+        placementId = 0;
+        placeholderId = 0;
+        placeholderSize = 0;
+    }
+
+    /**
+     * Build an instance of <code>OEPlaceholderAtom</code> from on-disk data
+     */
+	protected OEPlaceholderAtom(byte[] source, int start, int len) {
+		_header = new byte[8];
+		System.arraycopy(source,start,_header,0,8);
+
+        placementId = LittleEndian.getInt(source, start);
+        placeholderId = LittleEndian.getUnsignedByte(source, start+4);
+        placeholderSize = LittleEndian.getUnsignedByte(source, start+5);
+	}
+
+    /**
+     * @return type of this record {@link RecordTypes#OEPlaceholderAtom}.
+     */
+	public long getRecordType() { return RecordTypes.OEPlaceholderAtom.typeID; }
+
+    /**
+     * Returns the placement Id.
+     *
+     * @return the placement Id.
+     */
+    public int getPlacementId(){
+        return placementId;
+    }
+
+    /**
+     * Sets the placement Id.
+     *
+     * @param id the placement Id.
+     */
+   public void setPlacementId(int id){
+        placementId = id;
+    }
+
+    /**
+     * Returns the placeholder Id.
+     *
+     * @return the placeholder Id.
+     */
+    public int getPlaceholderId(){
+        return placeholderId;
+    }
+
+    /**
+     * Sets the placeholder Id.
+     *
+     * @param id the placeholder Id.
+     */
+    public void setPlaceholderId(byte id){
+        placeholderId = id;
+    }
+
+    /**
+     * Returns the placeholder size.
+     * Must be one of the PLACEHOLDER_* static constants defined in this class.
+     *
+     * @return the placeholder size.
+     */
+    public int getPlaceholderSize(){
+        return placeholderSize;
+    }
+
+    /**
+     * Sets the placeholder size.
+     * Must be one of the PLACEHOLDER_* static constants defined in this class.
+     *
+     * @param size the placeholder size.
+     */
+     public void setPlaceholderSize(byte size){
+        placeholderSize = size;
+    }
+
+	/**
+	 * Write the contents of the record back, so it can be written
+	 *  to disk
+	 */
+	public void writeOut(OutputStream out) throws IOException {
+		out.write(_header);
+
+        byte[] recdata = new byte[8];
+        LittleEndian.putInt(recdata, 0, placementId);
+        recdata[4] = (byte)placeholderId;
+        recdata[5] = (byte)placeholderSize;
+
+        out.write(recdata);
+	}
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/OutlineTextRefAtom.java Fri Dec 22 12:56:04 2006
@@ -1,107 +1,107 @@
-/* ====================================================================
-   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.record;
-
-import org.apache.poi.util.LittleEndian;
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * OEPlaceholderAtom (3998).
- * <br>
- * What MSDN says about  <code>OutlineTextRefAtom</code>:
- * <p>
- * Appears in a slide to indicate a text that is already contained in the document,
- * in a SlideListWithText containter. Sometimes slide texts are not contained
- * within the slide container to be able to delay loading a slide and still display
- * the title and body text in outline view.
- * </p>
- *
- * @author Yegor Kozlov
- */
-
-public class OutlineTextRefAtom extends RecordAtom {
-    /**
-     * record header
-     */
-    private byte[] _header;
-
-    /**
-     * the text's index within the SlideListWithText (0 for title, 1..n for the nth body)
-     */
-    private int _index;
-
-    /**
-     * Build an instance of <code>OutlineTextRefAtom</code> from on-disk data
-     */
-    protected OutlineTextRefAtom(byte[] source, int start, int len) {
-        // Get the header
-        _header = new byte[8];
-        System.arraycopy(source,start,_header,0,8);
-
-        // Grab the record data
-        _index = LittleEndian.getInt(source, start+8);
-    }
-
-    /**
-     * Create a new instance of <code>FontEntityAtom</code>
-     */
-    protected OutlineTextRefAtom() {
-        _index = 0;
-
-        _header = new byte[8];
-        LittleEndian.putUShort(_header, 0, 0);
-        LittleEndian.putUShort(_header, 2, (int)getRecordType());
-        LittleEndian.putInt(_header, 4, 4);
-    }
-
-    public long getRecordType() {
-        return RecordTypes.OutlineTextRefAtom.typeID;
-    }
-
-    /**
-     * Write the contents of the record back, so it can be written to disk
-     */
-    public void writeOut(OutputStream out) throws IOException {
-        out.write(_header);
-
-        byte[] recdata = new byte[4];
-        LittleEndian.putInt(recdata, 0, _index);
-        out.write(recdata);
-    }
-
-    /**
-     * Sets text's index within the SlideListWithText container
-     * (0 for title, 1..n for the nth body).
-     *
-     * @param idx 0-based text's index
-     */
-    public void setTextIndex(int idx){
-        _index = idx;
-    }
-
-    /**
-     * Return text's index within the SlideListWithText container
-     * (0 for title, 1..n for the nth body).
-     *
-     * @return idx text's index
-     */
-    public int getTextIndex(){
-        return _index;
-    }
-
-}
+/* ====================================================================
+   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.record;
+
+import org.apache.poi.util.LittleEndian;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * OEPlaceholderAtom (3998).
+ * <br>
+ * What MSDN says about  <code>OutlineTextRefAtom</code>:
+ * <p>
+ * Appears in a slide to indicate a text that is already contained in the document,
+ * in a SlideListWithText containter. Sometimes slide texts are not contained
+ * within the slide container to be able to delay loading a slide and still display
+ * the title and body text in outline view.
+ * </p>
+ *
+ * @author Yegor Kozlov
+ */
+
+public class OutlineTextRefAtom extends RecordAtom {
+    /**
+     * record header
+     */
+    private byte[] _header;
+
+    /**
+     * the text's index within the SlideListWithText (0 for title, 1..n for the nth body)
+     */
+    private int _index;
+
+    /**
+     * Build an instance of <code>OutlineTextRefAtom</code> from on-disk data
+     */
+    protected OutlineTextRefAtom(byte[] source, int start, int len) {
+        // Get the header
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Grab the record data
+        _index = LittleEndian.getInt(source, start+8);
+    }
+
+    /**
+     * Create a new instance of <code>FontEntityAtom</code>
+     */
+    protected OutlineTextRefAtom() {
+        _index = 0;
+
+        _header = new byte[8];
+        LittleEndian.putUShort(_header, 0, 0);
+        LittleEndian.putUShort(_header, 2, (int)getRecordType());
+        LittleEndian.putInt(_header, 4, 4);
+    }
+
+    public long getRecordType() {
+        return RecordTypes.OutlineTextRefAtom.typeID;
+    }
+
+    /**
+     * Write the contents of the record back, so it can be written to disk
+     */
+    public void writeOut(OutputStream out) throws IOException {
+        out.write(_header);
+
+        byte[] recdata = new byte[4];
+        LittleEndian.putInt(recdata, 0, _index);
+        out.write(recdata);
+    }
+
+    /**
+     * Sets text's index within the SlideListWithText container
+     * (0 for title, 1..n for the nth body).
+     *
+     * @param idx 0-based text's index
+     */
+    public void setTextIndex(int idx){
+        _index = idx;
+    }
+
+    /**
+     * Return text's index within the SlideListWithText container
+     * (0 for title, 1..n for the nth body).
+     *
+     * @return idx text's index
+     */
+    public int getTextIndex(){
+        return _index;
+    }
+
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawingGroup.java Fri Dec 22 12:56:04 2006
@@ -1,103 +1,103 @@
-package org.apache.poi.hslf.record;
-
-import org.apache.poi.ddf.*;
-import org.apache.poi.util.LittleEndian;
-
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Iterator;
-
-/**
- * Container records which always exists inside Document.
- * It always acts as a holder for escher DGG container
- *  which may contain which Escher BStore container information 
- *  about pictures containes in the presentation (if any).
- * 
- * @author Yegor Kozlov
- */
-public class PPDrawingGroup extends RecordAtom {
-
-    private byte[] _header;
-    private EscherContainerRecord dggContainer;
-
-    protected PPDrawingGroup(byte[] source, int start, int len) {
-        // Get the header
-        _header = new byte[8];
-        System.arraycopy(source,start,_header,0,8);
-
-        // Get the contents for now
-        byte[] contents = new byte[len];
-        System.arraycopy(source,start,contents,0,len);
-
-        DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory();
-        EscherRecord child = erf.createRecord(contents, 0);
-        child.fillFields( contents, 0, erf );
-        dggContainer = (EscherContainerRecord)child.getChild(0);
-    }
-
-    /**
-     * We are type 1035
-     */
-    public long getRecordType() {
-        return RecordTypes.PPDrawingGroup.typeID;
-    }
-
-    /**
-     * We're pretending to be an atom, so return null
-     */
-    public Record[] getChildRecords() {
-        return null;
-    }
-
-    public void writeOut(OutputStream out) throws IOException {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        List child = dggContainer.getChildRecords();
-        for (int i = 0; i < child.size(); i++) {
-            EscherRecord r = (EscherRecord)child.get(i);
-            if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){
-                EscherContainerRecord bstore = (EscherContainerRecord)r;
-
-                ByteArrayOutputStream b2 = new ByteArrayOutputStream();
-                List blip = bstore.getChildRecords();
-                for (Iterator it=blip.iterator(); it.hasNext();) {
-                    EscherBSERecord bse = (EscherBSERecord)it.next();
-                    byte[] b = new byte[36+8];
-                    bse.serialize(0, b);
-                    b2.write(b);
-                }
-                byte[] bstorehead = new byte[8];
-                LittleEndian.putShort(bstorehead, 0, bstore.getOptions());
-                LittleEndian.putShort(bstorehead, 2, bstore.getRecordId());
-                LittleEndian.putInt(bstorehead, 4, b2.size());
-                bout.write(bstorehead);
-                bout.write(b2.toByteArray());
-
-            } else {
-                bout.write(r.serialize());
-            }
-        }
-        int size = bout.size();
-
-        // Update the size (header bytes 5-8)
-        LittleEndian.putInt(_header,4,size+8);
-
-        // Write out our header
-        out.write(_header);
-
-        byte[] dgghead = new byte[8];
-        LittleEndian.putShort(dgghead, 0, dggContainer.getOptions());
-        LittleEndian.putShort(dgghead, 2, dggContainer.getRecordId());
-        LittleEndian.putInt(dgghead, 4, size);
-        out.write(dgghead);
-
-        // Finally, write out the children
-        out.write(bout.toByteArray());
-
-    }
-
-    public EscherContainerRecord getDggContainer(){
-        return dggContainer;
-    }
-}
+package org.apache.poi.hslf.record;
+
+import org.apache.poi.ddf.*;
+import org.apache.poi.util.LittleEndian;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * Container records which always exists inside Document.
+ * It always acts as a holder for escher DGG container
+ *  which may contain which Escher BStore container information 
+ *  about pictures containes in the presentation (if any).
+ * 
+ * @author Yegor Kozlov
+ */
+public class PPDrawingGroup extends RecordAtom {
+
+    private byte[] _header;
+    private EscherContainerRecord dggContainer;
+
+    protected PPDrawingGroup(byte[] source, int start, int len) {
+        // Get the header
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Get the contents for now
+        byte[] contents = new byte[len];
+        System.arraycopy(source,start,contents,0,len);
+
+        DefaultEscherRecordFactory erf = new DefaultEscherRecordFactory();
+        EscherRecord child = erf.createRecord(contents, 0);
+        child.fillFields( contents, 0, erf );
+        dggContainer = (EscherContainerRecord)child.getChild(0);
+    }
+
+    /**
+     * We are type 1035
+     */
+    public long getRecordType() {
+        return RecordTypes.PPDrawingGroup.typeID;
+    }
+
+    /**
+     * We're pretending to be an atom, so return null
+     */
+    public Record[] getChildRecords() {
+        return null;
+    }
+
+    public void writeOut(OutputStream out) throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        List child = dggContainer.getChildRecords();
+        for (int i = 0; i < child.size(); i++) {
+            EscherRecord r = (EscherRecord)child.get(i);
+            if (r.getRecordId() == EscherContainerRecord.BSTORE_CONTAINER){
+                EscherContainerRecord bstore = (EscherContainerRecord)r;
+
+                ByteArrayOutputStream b2 = new ByteArrayOutputStream();
+                List blip = bstore.getChildRecords();
+                for (Iterator it=blip.iterator(); it.hasNext();) {
+                    EscherBSERecord bse = (EscherBSERecord)it.next();
+                    byte[] b = new byte[36+8];
+                    bse.serialize(0, b);
+                    b2.write(b);
+                }
+                byte[] bstorehead = new byte[8];
+                LittleEndian.putShort(bstorehead, 0, bstore.getOptions());
+                LittleEndian.putShort(bstorehead, 2, bstore.getRecordId());
+                LittleEndian.putInt(bstorehead, 4, b2.size());
+                bout.write(bstorehead);
+                bout.write(b2.toByteArray());
+
+            } else {
+                bout.write(r.serialize());
+            }
+        }
+        int size = bout.size();
+
+        // Update the size (header bytes 5-8)
+        LittleEndian.putInt(_header,4,size+8);
+
+        // Write out our header
+        out.write(_header);
+
+        byte[] dgghead = new byte[8];
+        LittleEndian.putShort(dgghead, 0, dggContainer.getOptions());
+        LittleEndian.putShort(dgghead, 2, dggContainer.getRecordId());
+        LittleEndian.putInt(dgghead, 4, size);
+        out.write(dgghead);
+
+        // Finally, write out the children
+        out.write(bout.toByteArray());
+
+    }
+
+    public EscherContainerRecord getDggContainer(){
+        return dggContainer;
+    }
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- 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 Fri Dec 22 12:56:04 2006
@@ -1,213 +1,213 @@
-/* ====================================================================
-   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.usermodel;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.hslf.model.Picture;
-import org.apache.poi.hslf.blip.*;
-
-import java.io.OutputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * A class that represents image data contained in a slide show.
- *
- *  @author Yegor Kozlov
- */
-public abstract class PictureData {
-
-    /**
-     * Size of the image checksum calculated using MD5 algorithm.
-     */
-    protected static final int CHECKSUM_SIZE = 16;
-
-	/**
-	* Binary data of the picture
-	*/
-    private byte[] rawdata;
-	/**
-	 * The offset to the picture in the stream
-	 */
-	protected int offset;
-
-    /**
-     * Returns type of this picture.
-     * Must be one of the static constants defined in the <code>Picture<code> class.
-     *
-     * @return type of this picture.
-     */
-    public abstract int getType();
-
-    /**
-     * Returns the binary data of this Picture
-     * @return picture data
-     */
-    public abstract byte[] getData();
-
-    /**
-     *  Set picture data
-     */
-    public abstract void setData(byte[] data) throws IOException;
-
-    /**
-     * Blip signature.
-     */
-    protected abstract int getSignature();
-
-    /**
-     * Returns the raw binary data of this Picture excluding the first 8 bytes
-     * which hold image signature and size of the image data.
-     *
-     * @return picture data
-     */
-    public byte[] getRawData(){
-        return rawdata;
-    }
-
-    public void setRawData(byte[] data){
-        rawdata = data;
-    }
-
-    /**
-     * File offset in the 'Pictures' stream
-     *
-     * @return offset in the 'Pictures' stream
-     */
-    public int getOffset(){
-        return offset;
-    }
-
-    /**
-     * Set offset of this picture in the 'Pictures' stream.
-     * We need to set it when a new picture is created.
-     *
-     * @param offset in the 'Pictures' stream
-     */
-    public void setOffset(int offset){
-        this.offset = offset;
-    }
-
-    /**
-     * Returns 16-byte checksum of this picture
-     */
-    public byte[] getUID(){
-        byte[] uid = new byte[16];
-        System.arraycopy(rawdata, 0, uid, 0, uid.length);
-        return uid;
-    }
-
-
-    /**
-     * Compute 16-byte checksum of this picture using MD5 algorithm.
-     */
-    public static byte[] getChecksum(byte[] data) {
-        MessageDigest sha;
-        try {
-            sha = MessageDigest.getInstance("MD5");
-        } catch (NoSuchAlgorithmException e){
-            throw new RuntimeException(e.getMessage());
-        }
-        sha.update(data);
-        return sha.digest();
-    }
-
-    /**
-     * Write this picture into <code>OutputStream</code>
-     */
-    public void write(OutputStream out) throws IOException {
-        byte[] data;
-
-        data = new byte[LittleEndian.SHORT_SIZE];
-        LittleEndian.putUShort(data, 0, getSignature());
-        out.write(data);
-
-        data = new byte[LittleEndian.SHORT_SIZE];
-        LittleEndian.putUShort(data, 0, getType() + 0xF018);
-        out.write(data);
-
-        byte[] rawdata = getRawData();
-
-        data = new byte[LittleEndian.INT_SIZE];
-        LittleEndian.putInt(data, 0, rawdata.length);
-        out.write(data);
-
-        out.write(rawdata);
-    }
-
-    /**
-     * Create an instance of <code>PictureData</code> by type.
-     *
-     * @param type type of the picture data.
-     * Must be one of the static constants defined in the <code>Picture<code> class.
-     * @return concrete instance of <code>PictureData</code>
-     */
-     public static PictureData create(int type){
-        PictureData pict;
-        switch (type){
-            case Picture.EMF:
-                pict = new EMF();
-                break;
-            case Picture.WMF:
-                pict = new WMF();
-                break;
-            case Picture.PICT:
-                pict = new PICT();
-                break;
-            case Picture.JPEG:
-                pict = new JPEG();
-                break;
-            case Picture.PNG:
-                pict = new PNG();
-                break;
-            case Picture.DIB:
-                pict = new DIB();
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported picture type: " + type);
-        }
-        return pict;
-    }
-
-    /**
-     * Return 24 byte header which preceeds the actual picture data.
-     * <p>
-     * The header consists of 2-byte signature, 2-byte type,
-     * 4-byte image size and 16-byte checksum of the image data.
-     * </p>
-     *
-     * @return the 24 byte header which preceeds the actual picture data.
-     */
-    public byte[] getHeader() {
-        byte[] header = new byte[16 + 8];
-        LittleEndian.putInt(header, 0, getSignature());
-        LittleEndian.putInt(header, 4, getRawData().length);
-        System.arraycopy(rawdata, 0, header, 8, 16);
-        return header;
-    }
-
-    /**
-    * Return image size in bytes
-    *
-    *  @return the size of the picture in bytes
-     * @deprecated Use <code>getData().length</code> instead.
-    */
-    public int getSize(){
-        return getData().length;
-    }
-
-}
+/* ====================================================================
+   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.usermodel;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.hslf.blip.*;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * A class that represents image data contained in a slide show.
+ *
+ *  @author Yegor Kozlov
+ */
+public abstract class PictureData {
+
+    /**
+     * Size of the image checksum calculated using MD5 algorithm.
+     */
+    protected static final int CHECKSUM_SIZE = 16;
+
+	/**
+	* Binary data of the picture
+	*/
+    private byte[] rawdata;
+	/**
+	 * The offset to the picture in the stream
+	 */
+	protected int offset;
+
+    /**
+     * Returns type of this picture.
+     * Must be one of the static constants defined in the <code>Picture<code> class.
+     *
+     * @return type of this picture.
+     */
+    public abstract int getType();
+
+    /**
+     * Returns the binary data of this Picture
+     * @return picture data
+     */
+    public abstract byte[] getData();
+
+    /**
+     *  Set picture data
+     */
+    public abstract void setData(byte[] data) throws IOException;
+
+    /**
+     * Blip signature.
+     */
+    protected abstract int getSignature();
+
+    /**
+     * Returns the raw binary data of this Picture excluding the first 8 bytes
+     * which hold image signature and size of the image data.
+     *
+     * @return picture data
+     */
+    public byte[] getRawData(){
+        return rawdata;
+    }
+
+    public void setRawData(byte[] data){
+        rawdata = data;
+    }
+
+    /**
+     * File offset in the 'Pictures' stream
+     *
+     * @return offset in the 'Pictures' stream
+     */
+    public int getOffset(){
+        return offset;
+    }
+
+    /**
+     * Set offset of this picture in the 'Pictures' stream.
+     * We need to set it when a new picture is created.
+     *
+     * @param offset in the 'Pictures' stream
+     */
+    public void setOffset(int offset){
+        this.offset = offset;
+    }
+
+    /**
+     * Returns 16-byte checksum of this picture
+     */
+    public byte[] getUID(){
+        byte[] uid = new byte[16];
+        System.arraycopy(rawdata, 0, uid, 0, uid.length);
+        return uid;
+    }
+
+
+    /**
+     * Compute 16-byte checksum of this picture using MD5 algorithm.
+     */
+    public static byte[] getChecksum(byte[] data) {
+        MessageDigest sha;
+        try {
+            sha = MessageDigest.getInstance("MD5");
+        } catch (NoSuchAlgorithmException e){
+            throw new RuntimeException(e.getMessage());
+        }
+        sha.update(data);
+        return sha.digest();
+    }
+
+    /**
+     * Write this picture into <code>OutputStream</code>
+     */
+    public void write(OutputStream out) throws IOException {
+        byte[] data;
+
+        data = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putUShort(data, 0, getSignature());
+        out.write(data);
+
+        data = new byte[LittleEndian.SHORT_SIZE];
+        LittleEndian.putUShort(data, 0, getType() + 0xF018);
+        out.write(data);
+
+        byte[] rawdata = getRawData();
+
+        data = new byte[LittleEndian.INT_SIZE];
+        LittleEndian.putInt(data, 0, rawdata.length);
+        out.write(data);
+
+        out.write(rawdata);
+    }
+
+    /**
+     * Create an instance of <code>PictureData</code> by type.
+     *
+     * @param type type of the picture data.
+     * Must be one of the static constants defined in the <code>Picture<code> class.
+     * @return concrete instance of <code>PictureData</code>
+     */
+     public static PictureData create(int type){
+        PictureData pict;
+        switch (type){
+            case Picture.EMF:
+                pict = new EMF();
+                break;
+            case Picture.WMF:
+                pict = new WMF();
+                break;
+            case Picture.PICT:
+                pict = new PICT();
+                break;
+            case Picture.JPEG:
+                pict = new JPEG();
+                break;
+            case Picture.PNG:
+                pict = new PNG();
+                break;
+            case Picture.DIB:
+                pict = new DIB();
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported picture type: " + type);
+        }
+        return pict;
+    }
+
+    /**
+     * Return 24 byte header which preceeds the actual picture data.
+     * <p>
+     * The header consists of 2-byte signature, 2-byte type,
+     * 4-byte image size and 16-byte checksum of the image data.
+     * </p>
+     *
+     * @return the 24 byte header which preceeds the actual picture data.
+     */
+    public byte[] getHeader() {
+        byte[] header = new byte[16 + 8];
+        LittleEndian.putInt(header, 0, getSignature());
+        LittleEndian.putInt(header, 4, getRawData().length);
+        System.arraycopy(rawdata, 0, header, 8, 16);
+        return header;
+    }
+
+    /**
+    * Return image size in bytes
+    *
+    *  @return the size of the picture in bytes
+     * @deprecated Use <code>getData().length</code> instead.
+    */
+    public int getSize(){
+        return getData().length;
+    }
+
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java Fri Dec 22 12:56:04 2006
@@ -1,39 +1,39 @@
-/*
- * Created on Nov 25, 2006
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- * 
- */
-public class If implements Function {
-
-    public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
-        Eval retval = null;
-        Eval evalWhenFalse = BoolEval.FALSE;
-        switch (evals.length) {
-        case 3:
-            evalWhenFalse = evals[2];
-        case 2:
-            BoolEval beval = (BoolEval) evals[0];
-            if (beval.getBooleanValue()) {
-                retval = evals[1];
-            }
-            else {
-                retval = evalWhenFalse;
-            }
-            break;
-        default:
-            retval = ErrorEval.UNKNOWN_ERROR;
-        }
-        return retval;
-    }
-
-
-}
+/*
+ * Created on Nov 25, 2006
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BoolEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+
+/**
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ * 
+ */
+public class If implements Function {
+
+    public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) {
+        Eval retval = null;
+        Eval evalWhenFalse = BoolEval.FALSE;
+        switch (evals.length) {
+        case 3:
+            evalWhenFalse = evals[2];
+        case 2:
+            BoolEval beval = (BoolEval) evals[0];
+            if (beval.getBooleanValue()) {
+                retval = evals[1];
+            }
+            else {
+                retval = evalWhenFalse;
+            }
+            break;
+        default:
+            retval = ErrorEval.UNKNOWN_ERROR;
+        }
+        return retval;
+    }
+
+
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java Fri Dec 22 12:56:04 2006
@@ -1,31 +1,31 @@
-/*
- * Created on Nov 25, 2006
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public abstract class LogicalFunction implements Function {
-
-    /**
-     * recursively evaluate any RefEvals
-     * @param reval
-     * @return
-     */
-    protected ValueEval xlateRefEval(RefEval reval) {
-        ValueEval retval = (ValueEval) reval.getInnerValueEval();
-        
-        if (retval instanceof RefEval) {
-            RefEval re = (RefEval) retval;
-            retval = xlateRefEval(re);
-        }
-
-        return retval;
-    }
-}
+/*
+ * Created on Nov 25, 2006
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.RefEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ *
+ */
+public abstract class LogicalFunction implements Function {
+
+    /**
+     * recursively evaluate any RefEvals
+     * @param reval
+     * @return
+     */
+    protected ValueEval xlateRefEval(RefEval reval) {
+        ValueEval retval = (ValueEval) reval.getInnerValueEval();
+        
+        if (retval instanceof RefEval) {
+            RefEval re = (RefEval) retval;
+            retval = xlateRefEval(re);
+        }
+
+        return retval;
+    }
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java?view=diff&rev=489760&r1=489759&r2=489760
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/model/SavedByEntry.java Fri Dec 22 12:56:04 2006
@@ -1,85 +1,85 @@
-/* ====================================================================
-   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.hwpf.model;
-
-
-/**
- * A single entry in the {@link SavedByTable}.
- * 
- * @author Daniel Noll
- */
-public class SavedByEntry
-{
-  private String userName;
-  private String saveLocation;
-
-  public SavedByEntry(String userName, String saveLocation)
-  {
-    this.userName = userName;
-    this.saveLocation = saveLocation;
-  }
-
-  public String getUserName()
-  {
-    return userName;
-  }
-
-  public String getSaveLocation()
-  {
-    return saveLocation;
-  }
-
-  /**
-   * Compares this object with another, for equality.
-   *
-   * @param other the object to compare to this one.
-   * @return <code>true</code> iff the other object is equal to this one.
-   */
-  public boolean equals(Object other)
-  {
-    if (other == this) return true;
-    if (!(other instanceof SavedByEntry)) return false;
-    SavedByEntry that = (SavedByEntry) other;
-    return that.userName.equals(userName) &&
-           that.saveLocation.equals(saveLocation);
-  }
-
-  /**
-   * Generates a hash code for consistency with {@link #equals(Object)}.
-   *
-   * @return the hash code.
-   */
-  public int hashCode()
-  {
-    int hash = 29;
-    hash = hash * 13 + userName.hashCode();
-    hash = hash * 13 + saveLocation.hashCode();
-    return hash;
-  }
-
-  /**
-   * Returns a string for display.
-   *
-   * @return the string.
-   */
-  public String toString()
-  {
-    return "SavedByEntry[userName=" + getUserName() +
-                       ",saveLocation=" + getSaveLocation() + "]";
-  }
-}
+/* ====================================================================
+   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.hwpf.model;
+
+
+/**
+ * A single entry in the {@link SavedByTable}.
+ * 
+ * @author Daniel Noll
+ */
+public class SavedByEntry
+{
+  private String userName;
+  private String saveLocation;
+
+  public SavedByEntry(String userName, String saveLocation)
+  {
+    this.userName = userName;
+    this.saveLocation = saveLocation;
+  }
+
+  public String getUserName()
+  {
+    return userName;
+  }
+
+  public String getSaveLocation()
+  {
+    return saveLocation;
+  }
+
+  /**
+   * Compares this object with another, for equality.
+   *
+   * @param other the object to compare to this one.
+   * @return <code>true</code> iff the other object is equal to this one.
+   */
+  public boolean equals(Object other)
+  {
+    if (other == this) return true;
+    if (!(other instanceof SavedByEntry)) return false;
+    SavedByEntry that = (SavedByEntry) other;
+    return that.userName.equals(userName) &&
+           that.saveLocation.equals(saveLocation);
+  }
+
+  /**
+   * Generates a hash code for consistency with {@link #equals(Object)}.
+   *
+   * @return the hash code.
+   */
+  public int hashCode()
+  {
+    int hash = 29;
+    hash = hash * 13 + userName.hashCode();
+    hash = hash * 13 + saveLocation.hashCode();
+    return hash;
+  }
+
+  /**
+   * Returns a string for display.
+   *
+   * @return the string.
+   */
+  public String toString()
+  {
+    return "SavedByEntry[userName=" + getUserName() +
+                       ",saveLocation=" + getSaveLocation() + "]";
+  }
+}



---------------------------------------------------------------------
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/