You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/06/09 15:30:19 UTC

svn commit: r664700 [3/3] - in /poi/branches/ooxml: ./ src/documentation/content/xdocs/ src/java/org/apache/poi/ddf/ src/java/org/apache/poi/hssf/model/ src/java/org/apache/poi/hssf/record/ src/java/org/apache/poi/hssf/record/formula/ src/java/org/apac...

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java Mon Jun  9 06:30:17 2008
@@ -1,537 +1,545 @@
-
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You 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 org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.util.POILogger;
-
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.AffineTransform;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextLayout;
-import java.io.IOException;
-
-/**
- * A common superclass of all shapes that can hold text.
- *
- * @author Yegor Kozlov
- */
-public abstract class TextShape 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;
-
-    /**
-     * TextRun 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;
-
-    /**
-     * Used to calculate text bounds
-     */
-    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
-
-    /**
-     * 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 TextShape(EscherContainerRecord escherRecord, Shape parent){
-        super(escherRecord, parent);
-
-    }
-
-    /**
-     * 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 TextShape(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 TextShape(){
-        this(null);
-    }
-
-    public TextRun createTextRun(){
-        _txtbox = getEscherTextboxWrapper();
-        if(_txtbox == null) _txtbox = new EscherTextboxWrapper();
-
-        _txtrun = getTextRun();
-        if(_txtrun == null){
-            TextHeaderAtom tha = new TextHeaderAtom();
-            tha.setParentRecord(_txtbox);
-            _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("");
-
-            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
-
-            setDefaultTextProperties(_txtrun);
-        }
-
-        return _txtrun;
-    }
-
-    /**
-     * Set default properties for the  TextRun.
-     * Depending on the text and shape type the defaults are different:
-     *   TextBox: align=left, valign=top
-     *   AutoShape: align=center, valign=middle
-     *
-     */
-    protected void setDefaultTextProperties(TextRun _txtrun){
-
-    }
-
-    /**
-     * Returns the text contained in this text frame.
-     *
-     * @return the text string for this textbox.
-     */
-     public String getText(){
-        TextRun tx = getTextRun();
-        return tx == null ? null : tx.getText();
-    }
-
-    /**
-     * Sets the text contained in this text frame.
-     *
-     * @param text the text string used by this object.
-     */
-    public void setText(String text){
-        TextRun tx = getTextRun();
-        if(tx == null){
-            tx = createTextRun();
-        }
-        tx.setText(text);
-        setTextId(text.hashCode());
-    }
-
-    /**
-     * 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){
-        super.afterInsert(sh);
-
-        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
-        if(_txtbox != null){
-            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 HSLFException(e);
-            }
-            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
-        }
-    }
-
-    protected EscherTextboxWrapper getEscherTextboxWrapper(){
-        if(_txtbox == null){
-            EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
-            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
-        }
-        return _txtbox;
-    }
-    /**
-     * Adjust the size of the TextShape so it encompasses the text inside it.
-     *
-     * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.
-     */
-    public Rectangle2D resizeToFitText(){
-        String txt = getText();
-        if(txt == null || txt.length() == 0) return new Rectangle2D.Float();
-
-        RichTextRun rt = getTextRun().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);
-
-        float width = 0, height = 0;
-        String[] lines = txt.split("\r");
-        for (int i = 0; i < lines.length; i++) {
-            if(lines[i].length() == 0) continue;
-
-            TextLayout layout = new TextLayout(lines[i], font, _frc);
-
-            width = Math.max(width, layout.getAdvance());
-
-            /**
-             * Even if top and bottom margins are set to 0 PowerPoint
-             * always sets extra space between the text and its bounding box.
-             *
-             * The approximation height = ascent*2 works good enough in most cases
-             */
-            height = Math.max(height, 2*layout.getAscent());
-        }
-
-        width += getMarginLeft() + getMarginRight();
-        height += getMarginTop() + getMarginBottom();
-
-        Rectangle2D anchor = getAnchor2D();
-        anchor.setRect(anchor.getX(), anchor.getY(), width, height);
-        setAnchor(anchor);
-
-        return 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);
-        int valign = TextShape.AnchorTop;
-        if (prop == null){
-            /**
-             * If vertical alignment was not found in the shape properties then try to
-             * fetch the master shape and search for the align property there.
-             */
-            int type = getTextRun().getRunType();
-            MasterSheet master = getSheet().getMasterSheet();
-            if(master != null){
-                TextShape masterShape = master.getPlaceholder(type);
-                if(masterShape != null) valign = masterShape.getVerticalAlignment();
-            } else {
-                //not found in the master sheet. Use the hardcoded defaults.
-                switch (type){
-                     case TextHeaderAtom.TITLE_TYPE:
-                     case TextHeaderAtom.CENTER_TITLE_TYPE:
-                         valign = TextShape.AnchorMiddle;
-                         break;
-                     default:
-                         valign = TextShape.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){
-        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);
-    }
-
-    /**
-     * Sets the type of horizontal alignment for the text.
-     * One of the <code>Align*</code> constants defined in this class.
-     *
-     * @param align - the type of horizontal alignment
-     */
-    public void setHorizontalAlignment(int align){
-        TextRun tx = getTextRun();
-        if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);
-    }
-
-    /**
-     * Gets the type of horizontal alignment for the text.
-     * One of the <code>Align*</code> constants defined in this class.
-     *
-     * @return align - the type of horizontal alignment
-     */
-    public int getHorizontalAlignment(){
-        TextRun tx = getTextRun();
-        return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();
-    }
-
-    /**
-     * 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 float 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 (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the botom margin.
-     * @see #getMarginBottom()
-     *
-     * @param margin    the bottom margin
-     */
-    public void setMarginBottom(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
-    }
-
-    /**
-     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the left margin.
-     * @see #getMarginLeft()
-     *
-     * @param margin    the left margin
-     */
-    public void setMarginLeft(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
-    }
-
-    /**
-     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
-    }
-
-    /**
-     * Sets the right margin.
-     * @see #getMarginRight()
-     *
-     * @param margin    the right margin
-     */
-    public void setMarginRight(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
-    }
-
-     /**
-     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
-    }
-
-   /**
-     * Sets the top margin.
-     * @see #getMarginTop()
-     *
-     * @param margin    the top margin
-     */
-    public void setMarginTop(float margin){
-        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
-    }
-
-
-    /**
-     * Returns the value indicating word wrap.
-     *
-     * @return the value indicating word wrap.
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.
-     */
-    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.
-     *  Must be one of the <code>Wrap*</code> constants defined in this class.
-     */
-    public void setWordWrap(int wrap){
-        setEscherProperty(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){
-        setEscherProperty(EscherProperties.TEXT__TEXTID, id);
-    }
-
-    /**
-      * @return the TextRun object for this text box
-      */
-     public TextRun getTextRun(){
-         if(_txtrun == null) initTextRun();
-         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)
-        TextRun tx = getTextRun();
-        if (tx != null) {
-            // Supply the sheet to our child RichTextRuns
-            tx.setSheet(_sheet);
-            RichTextRun[] rt = tx.getRichTextRuns();
-            for (int i = 0; i < rt.length; i++) {
-                rt[i].supplySlideShow(_sheet.getSlideShow());
-            }
-        }
-
-    }
-
-    protected void initTextRun(){
-        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
-        Sheet sheet = getSheet();
-
-        if(sheet == null || txtbox == null) return;
-
-        OutlineTextRefAtom ota = null;
-
-        Record[] child = txtbox.getChildRecords();
-        for (int i = 0; i < child.length; i++) {
-            if (child[i] instanceof OutlineTextRefAtom) {
-                ota = (OutlineTextRefAtom)child[i];
-                break;
-            }
-        }
-
-        TextRun[] runs = _sheet.getTextRuns();
-        if (ota != null) {
-            int idx = ota.getTextIndex();
-            for (int i = 0; i < runs.length; i++) {
-                if(runs[i].getIndex() == idx){
-                    _txtrun = runs[i];
-                    break;
-                }
-            }
-            if(_txtrun == null) {
-                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
-            }
-        } else {
-            int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
-            if(runs != null) for (int i = 0; i < runs.length; i++) {
-                if(runs[i].getShapeId() == shapeId){
-                    _txtrun = runs[i];
-                    break;
-                }
-            }
-        }
-    }
-
-    public void draw(Graphics2D graphics){
-        AffineTransform at = graphics.getTransform();
-        ShapePainter.paint(this, graphics);
-        new TextPainter(this).paint(graphics);
-        graphics.setTransform(at);
-    }
-
-}
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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 org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.util.POILogger;
+
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.AffineTransform;
+import java.awt.font.FontRenderContext;
+import java.awt.font.TextLayout;
+import java.io.IOException;
+import java.util.Iterator;
+
+/**
+ * A common superclass of all shapes that can hold text.
+ *
+ * @author Yegor Kozlov
+ */
+public abstract class TextShape 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;
+
+    /**
+     * TextRun 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;
+
+    /**
+     * Used to calculate text bounds
+     */
+    protected static final FontRenderContext _frc = new FontRenderContext(null, true, true);
+
+    /**
+     * 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 TextShape(EscherContainerRecord escherRecord, Shape parent){
+        super(escherRecord, parent);
+
+    }
+
+    /**
+     * 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 TextShape(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 TextShape(){
+        this(null);
+    }
+
+    public TextRun createTextRun(){
+        _txtbox = getEscherTextboxWrapper();
+        if(_txtbox == null) _txtbox = new EscherTextboxWrapper();
+
+        _txtrun = getTextRun();
+        if(_txtrun == null){
+            TextHeaderAtom tha = new TextHeaderAtom();
+            tha.setParentRecord(_txtbox);
+            _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("");
+
+            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
+
+            setDefaultTextProperties(_txtrun);
+        }
+
+        return _txtrun;
+    }
+
+    /**
+     * Set default properties for the  TextRun.
+     * Depending on the text and shape type the defaults are different:
+     *   TextBox: align=left, valign=top
+     *   AutoShape: align=center, valign=middle
+     *
+     */
+    protected void setDefaultTextProperties(TextRun _txtrun){
+
+    }
+
+    /**
+     * Returns the text contained in this text frame.
+     *
+     * @return the text string for this textbox.
+     */
+     public String getText(){
+        TextRun tx = getTextRun();
+        return tx == null ? null : tx.getText();
+    }
+
+    /**
+     * Sets the text contained in this text frame.
+     *
+     * @param text the text string used by this object.
+     */
+    public void setText(String text){
+        TextRun tx = getTextRun();
+        if(tx == null){
+            tx = createTextRun();
+        }
+        tx.setText(text);
+        setTextId(text.hashCode());
+    }
+
+    /**
+     * 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){
+        super.afterInsert(sh);
+
+        EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
+        if(_txtbox != null){
+            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 HSLFException(e);
+            }
+            if(getAnchor().equals(new Rectangle()) && !"".equals(getText())) resizeToFitText();
+        }
+    }
+
+    protected EscherTextboxWrapper getEscherTextboxWrapper(){
+        if(_txtbox == null){
+            EscherTextboxRecord textRecord = (EscherTextboxRecord)Shape.getEscherChild(_escherContainer, EscherTextboxRecord.RECORD_ID);
+            if(textRecord != null) _txtbox = new EscherTextboxWrapper(textRecord);
+        }
+        return _txtbox;
+    }
+    /**
+     * Adjust the size of the TextShape so it encompasses the text inside it.
+     *
+     * @return a <code>Rectangle2D</code> that is the bounds of this <code>TextShape</code>.
+     */
+    public Rectangle2D resizeToFitText(){
+        String txt = getText();
+        if(txt == null || txt.length() == 0) return new Rectangle2D.Float();
+
+        RichTextRun rt = getTextRun().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);
+
+        float width = 0, height = 0, leading = 0;        
+        String[] lines = txt.split("\n");        
+        for (int i = 0; i < lines.length; i++) {
+            if(lines[i].length() == 0) continue;
+            
+            TextLayout layout = new TextLayout(lines[i], font, _frc);
+            
+            leading = Math.max(leading, layout.getLeading());           
+            width = Math.max(width, layout.getAdvance());
+            height = Math.max(height, (height + (layout.getDescent() + layout.getAscent())));
+        } 	
+    	
+        // add one character to width
+        Rectangle2D charBounds = font.getMaxCharBounds(_frc);                
+        width += getMarginLeft() + getMarginRight() + charBounds.getWidth();
+        
+        // add leading to height        
+        height += getMarginTop() + getMarginBottom() + leading;
+
+        Rectangle2D anchor = getAnchor2D();
+        anchor.setRect(anchor.getX(), anchor.getY(), width, height);
+        setAnchor(anchor);
+
+        return 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);
+        int valign = TextShape.AnchorTop;
+        if (prop == null){
+            /**
+             * If vertical alignment was not found in the shape properties then try to
+             * fetch the master shape and search for the align property there.
+             */
+            int type = getTextRun().getRunType();
+            MasterSheet master = getSheet().getMasterSheet();
+            if(master != null){
+                TextShape masterShape = master.getPlaceholder(type);
+                if(masterShape != null) valign = masterShape.getVerticalAlignment();
+            } else {
+                //not found in the master sheet. Use the hardcoded defaults.
+                switch (type){
+                     case TextHeaderAtom.TITLE_TYPE:
+                     case TextHeaderAtom.CENTER_TITLE_TYPE:
+                         valign = TextShape.AnchorMiddle;
+                         break;
+                     default:
+                         valign = TextShape.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){
+        setEscherProperty(EscherProperties.TEXT__ANCHORTEXT, align);
+    }
+
+    /**
+     * Sets the type of horizontal alignment for the text.
+     * One of the <code>Align*</code> constants defined in this class.
+     *
+     * @param align - the type of horizontal alignment
+     */
+    public void setHorizontalAlignment(int align){
+        TextRun tx = getTextRun();
+        if(tx != null) tx.getRichTextRuns()[0].setAlignment(align);
+    }
+
+    /**
+     * Gets the type of horizontal alignment for the text.
+     * One of the <code>Align*</code> constants defined in this class.
+     *
+     * @return align - the type of horizontal alignment
+     */
+    public int getHorizontalAlignment(){
+        TextRun tx = getTextRun();
+        return tx == null ? -1 : tx.getRichTextRuns()[0].getAlignment();
+    }
+
+    /**
+     * 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 float 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 (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the botom margin.
+     * @see #getMarginBottom()
+     *
+     * @param margin    the bottom margin
+     */
+    public void setMarginBottom(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTBOTTOM, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the left margin.
+     * @see #getMarginLeft()
+     *
+     * @param margin    the left margin
+     */
+    public void setMarginLeft(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTLEFT, (int)(margin*EMU_PER_POINT));
+    }
+
+    /**
+     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
+    }
+
+    /**
+     * Sets the right margin.
+     * @see #getMarginRight()
+     *
+     * @param margin    the right margin
+     */
+    public void setMarginRight(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTRIGHT, (int)(margin*EMU_PER_POINT));
+    }
+
+     /**
+     *  Returns the distance (in points) 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 float 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 (float)val/EMU_PER_POINT;
+    }
+
+   /**
+     * Sets the top margin.
+     * @see #getMarginTop()
+     *
+     * @param margin    the top margin
+     */
+    public void setMarginTop(float margin){
+        setEscherProperty(EscherProperties.TEXT__TEXTTOP, (int)(margin*EMU_PER_POINT));
+    }
+
+
+    /**
+     * Returns the value indicating word wrap.
+     *
+     * @return the value indicating word wrap.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     */
+    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.
+     *  Must be one of the <code>Wrap*</code> constants defined in this class.
+     */
+    public void setWordWrap(int wrap){
+        setEscherProperty(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){
+        setEscherProperty(EscherProperties.TEXT__TEXTID, id);
+    }
+
+    /**
+      * @return the TextRun object for this text box
+      */
+     public TextRun getTextRun(){
+         if(_txtrun == null) initTextRun();
+         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)
+        TextRun tx = getTextRun();
+        if (tx != null) {
+            // Supply the sheet to our child RichTextRuns
+            tx.setSheet(_sheet);
+            RichTextRun[] rt = tx.getRichTextRuns();
+            for (int i = 0; i < rt.length; i++) {
+                rt[i].supplySlideShow(_sheet.getSlideShow());
+            }
+        }
+
+    }
+
+    protected void initTextRun(){
+        EscherTextboxWrapper txtbox = getEscherTextboxWrapper();
+        Sheet sheet = getSheet();
+
+        if(sheet == null || txtbox == null) return;
+
+        OutlineTextRefAtom ota = null;
+
+        Record[] child = txtbox.getChildRecords();
+        for (int i = 0; i < child.length; i++) {
+            if (child[i] instanceof OutlineTextRefAtom) {
+                ota = (OutlineTextRefAtom)child[i];
+                break;
+            }
+        }
+
+        TextRun[] runs = _sheet.getTextRuns();
+        if (ota != null) {
+            int idx = ota.getTextIndex();
+            for (int i = 0; i < runs.length; i++) {
+                if(runs[i].getIndex() == idx){
+                    _txtrun = runs[i];
+                    break;
+                }
+            }
+            if(_txtrun == null) {
+                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
+            }
+        } else {
+            int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
+            if(runs != null) for (int i = 0; i < runs.length; i++) {
+                if(runs[i].getShapeId() == shapeId){
+                    _txtrun = runs[i];
+                    break;
+                }
+            }
+        }
+    }
+
+    public void draw(Graphics2D graphics){
+        AffineTransform at = graphics.getTransform();
+        ShapePainter.paint(this, graphics);
+        new TextPainter(this).paint(graphics);
+        graphics.setTransform(at);
+    }
+
+    /**
+     * Return <code>OEPlaceholderAtom</code>, the atom that describes a placeholder.
+     *
+     * @return <code>OEPlaceholderAtom</code> or <code>null</code> if not found
+     */
+    public OEPlaceholderAtom getPlaceholderAtom(){
+        return (OEPlaceholderAtom)getClientDataRecord(RecordTypes.OEPlaceholderAtom.typeID);
+    }
+
+}

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java Mon Jun  9 06:30:17 2008
@@ -138,7 +138,7 @@
 				new TextProp(2, 0x4000, "spaceafter"),
 				new TextProp(2, 0x8000, "para_unknown_4"),
 				new TextProp(2, 0x10000, "para_unknown_5"),
-				new TextProp(2, 0xE0000, "para_unknown_6"),
+				new TextProp(2, 0xA0000, "para_unknown_6"),
 				new TextProp(2, 0x200000, "para_unknown_7")
 	};
 	/** All the different kinds of character properties we might handle */
@@ -167,7 +167,7 @@
 	/** 
 	 * For the Text Style Properties (StyleTextProp) Atom
 	 */
-	protected StyleTextPropAtom(byte[] source, int start, int len) {
+	public StyleTextPropAtom(byte[] source, int start, int len) {
 		// Sanity Checking - we're always at least 8+10 bytes long
 		if(len < 18) {
 			len = 18;

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java Mon Jun  9 06:30:17 2008
@@ -17,6 +17,8 @@
 package org.apache.poi.hslf.usermodel;
 
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
 import org.apache.poi.hslf.model.Picture;
 import org.apache.poi.hslf.blip.*;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -25,6 +27,7 @@
 import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.awt.*;
 
 /**
  * A class that represents image data contained in a slide show.
@@ -33,19 +36,21 @@
  */
 public abstract class PictureData {
 
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
     /**
      * Size of the image checksum calculated using MD5 algorithm.
      */
     protected static final int CHECKSUM_SIZE = 16;
 
-	/**
-	* Binary data of the picture
-	*/
+    /**
+    * Binary data of the picture
+    */
     private byte[] rawdata;
-	/**
-	 * The offset to the picture in the stream
-	 */
-	protected int offset;
+    /**
+     * The offset to the picture in the stream
+     */
+    protected int offset;
 
     /**
      * Returns type of this picture.
@@ -71,6 +76,13 @@
      */
     protected abstract int getSignature();
 
+    protected static ImagePainter[] painters = new ImagePainter[8];
+    static {
+        PictureData.setImagePainter(Picture.PNG, new BitmapPainter());
+        PictureData.setImagePainter(Picture.JPEG, new BitmapPainter());
+        PictureData.setImagePainter(Picture.DIB, new BitmapPainter());
+    }
+
     /**
      * Returns the raw binary data of this Picture excluding the first 8 bytes
      * which hold image signature and size of the image data.
@@ -212,4 +224,30 @@
         return getData().length;
     }
 
+    public void draw(Graphics2D graphics, Picture parent){
+        ImagePainter painter = painters[getType()];
+        if(painter != null) painter.paint(graphics, this, parent);
+        else logger.log(POILogger.WARN, "Rendering is not supported: " + getClass().getName());
+    }
+
+    /**
+     * Register ImagePainter for the specified image type
+     *
+     * @param type  image type, must be one of the static constants defined in the <code>Picture<code> class.
+     * @param painter   
+     */
+    public static void setImagePainter(int type, ImagePainter painter){
+        painters[type] = painter;
+    }
+
+    /**
+     * Return ImagePainter for the specified image type
+     *
+     * @param type blip type, must be one of the static constants defined in the <code>Picture<code> class.
+     * @return ImagePainter for the specified image type
+     */
+    public static ImagePainter getImagePainter(int type){
+        return painters[type];
+    }
+
 }

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java Mon Jun  9 06:30:17 2008
@@ -734,7 +734,7 @@
         else if (format == Picture.WMF) bse.setBlipTypeMacOS((byte)Picture.PICT);
         else if (format == Picture.PICT) bse.setBlipTypeWin32((byte)Picture.WMF);
 
-        bse.setRef(1);
+        bse.setRef(0);
         bse.setOffset(offset);
 
         bstore.addChildRecord(bse);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java Mon Jun  9 06:30:17 2008
@@ -40,7 +40,7 @@
 import org.apache.poi.hssf.record.formula.PercentPtg;
 import org.apache.poi.hssf.record.formula.PowerPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.record.formula.SubtractPtg;
 import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
@@ -165,14 +165,14 @@
 	public void testUnaryMinus() {
 		Ptg[] ptgs = parseFormula("-A1");
 		assertEquals(2, ptgs.length);
-		assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+		assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
 		assertTrue("second ptg is Minus",ptgs[1] instanceof UnaryMinusPtg);
 	}
 
 	public void testUnaryPlus() {
 		Ptg[] ptgs = parseFormula("+A1");
 		assertEquals(2, ptgs.length);
-		assertTrue("first ptg is reference",ptgs[0] instanceof ReferencePtg);
+		assertTrue("first ptg is reference",ptgs[0] instanceof RefPtg);
 		assertTrue("second ptg is Plus",ptgs[1] instanceof UnaryPlusPtg);
 	}
 
@@ -540,11 +540,11 @@
 		Class[] expClss;
 
 		expClss = new Class[] { 
-				ReferencePtg.class, 
+				RefPtg.class, 
 				AttrPtg.class, // tAttrIf
 				MissingArgPtg.class, 
 				AttrPtg.class, // tAttrSkip
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class, // tAttrSkip
 				FuncVarPtg.class, 
 		};
@@ -696,7 +696,7 @@
 		// FormulaParser strips spaces anyway
 		assertEquals("4", formulaString);
 
-		ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, new AddPtg()};
+		ptgs = new Ptg[] { new IntPtg(3), spacePtg, new IntPtg(4), spacePtg, AddPtg.instance, };
 		formulaString = FormulaParser.toFormulaString(null, ptgs);
 		assertEquals("3+4", formulaString);
 	}
@@ -710,7 +710,7 @@
 		Ptg[] ptgs = {
 				// Excel would probably have put tMissArg here
 				new IntPtg(1),
-				new DividePtg(),
+				DividePtg.instance,
 		};
 		try {
 			FormulaParser.toFormulaString(null, ptgs);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParserIf.java Mon Jun  9 06:30:17 2008
@@ -31,7 +31,7 @@
 import org.apache.poi.hssf.record.formula.MultiplyPtg;
 import org.apache.poi.hssf.record.formula.NotEqualPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.StringPtg;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
@@ -61,7 +61,7 @@
 		Class[] expClss;
 
 		expClss = new Class[] {
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class, // tAttrIf
 				IntPtg.class,
 				AttrPtg.class, // tAttrSkip
@@ -82,9 +82,9 @@
 		Class[] expClss;
 
 		expClss = new Class[] {
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class, // tAttrIf
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class, // tAttrSkip
 				FuncVarPtg.class,
 		};
@@ -100,20 +100,20 @@
 		Class[] expClss;
 
 		expClss = new Class[] {
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class, // tAttrIf
 
-				ReferencePtg.class,
+				RefPtg.class,
 				IntPtg.class,
 				MultiplyPtg.class,
-				ReferencePtg.class,
+				RefPtg.class,
 				IntPtg.class,
 				AddPtg.class,
 				FuncPtg.class,
 				AttrPtg.class, // tAttrSkip
 				
-				ReferencePtg.class,
-				ReferencePtg.class,
+				RefPtg.class,
+				RefPtg.class,
 				FuncPtg.class,
 				
 				AttrPtg.class, // tAttrSkip
@@ -133,9 +133,9 @@
 
 		expClss = new Class[] {
 
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class,	  // A tAttrIf
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class,    //   B tAttrIf
 				IntPtg.class,
 				AttrPtg.class,    //   B tAttrSkip
@@ -143,7 +143,7 @@
 				AttrPtg.class,    //   B tAttrSkip
 				FuncVarPtg.class,
 				AttrPtg.class,    // A tAttrSkip
-				ReferencePtg.class,
+				RefPtg.class,
 				AttrPtg.class,    //   C tAttrIf
 				IntPtg.class,
 				AttrPtg.class,    //   C tAttrSkip

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestRVA.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestRVA.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestRVA.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestRVA.java Mon Jun  9 06:30:17 2008
@@ -23,7 +23,7 @@
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtgBase;
 import org.apache.poi.hssf.usermodel.FormulaExtractor;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 import org.apache.poi.hssf.usermodel.HSSFRow;
@@ -102,7 +102,7 @@
 		for (int i = 0; i < nExcelTokens; i++) {
 			Ptg poiPtg = poiPtgs[i];
 			Ptg excelPtg = excelPtgs[i];
-			if (!areTokenClassesSame(poiPtg, excelPtg)) {
+			if (excelPtg.getClass() != poiPtg.getClass()) {
 				hasMismatch = true;
 				sb.append("  mismatch token type[" + i + "] " + getShortClassName(excelPtg) + " "
 						+ getOperandClassName(excelPtg) + " - " + getShortClassName(poiPtg) + " "
@@ -127,17 +127,6 @@
 		}
 	}
 
-	private boolean areTokenClassesSame(Ptg poiPtg, Ptg excelPtg) {
-		if (excelPtg.getClass() == poiPtg.getClass()) {
-			return true;
-		}
-		if (poiPtg.getClass() == ReferencePtg.class) {
-			// TODO - remove funny subclasses of ReferencePtg
-			return excelPtg instanceof ReferencePtg;
-		}
-		return false;
-	}
-
 	private String getShortClassName(Object o) {
 		String cn = o.getClass().getName();
 		int pos = cn.lastIndexOf('.');

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestFormulaRecord.java Mon Jun  9 06:30:17 2008
@@ -26,7 +26,7 @@
 import org.apache.poi.hssf.record.formula.AttrPtg;
 import org.apache.poi.hssf.record.formula.FuncVarPtg;
 import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 
 /**
  * Tests the serialization and deserialization of the FormulaRecord
@@ -130,11 +130,11 @@
 		assertEquals(9, ptgs.size());
 		assertEquals(IntPtg.class,	   ptgs.get(0).getClass());
 		assertEquals(AttrPtg.class,	  ptgs.get(1).getClass());
-		assertEquals(ReferencePtg.class, ptgs.get(2).getClass());
+		assertEquals(RefPtg.class, ptgs.get(2).getClass());
 		assertEquals(AttrPtg.class,	  ptgs.get(3).getClass());
-		assertEquals(ReferencePtg.class, ptgs.get(4).getClass());
+		assertEquals(RefPtg.class, ptgs.get(4).getClass());
 		assertEquals(AttrPtg.class,	  ptgs.get(5).getClass());
-		assertEquals(ReferencePtg.class, ptgs.get(6).getClass());
+		assertEquals(RefPtg.class, ptgs.get(6).getClass());
 		assertEquals(AttrPtg.class,	  ptgs.get(7).getClass());
 		assertEquals(FuncVarPtg.class,   ptgs.get(8).getClass());
 		

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/TestSharedFormulaRecord.java Mon Jun  9 06:30:17 2008
@@ -25,7 +25,7 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.RefAPtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 
 /**
  * @author Josh Micich
@@ -68,7 +68,7 @@
 		
 		Stack convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
 		
-		RefAPtg refPtg = (RefAPtg) convertedFormula.get(1);
+		RefPtg refPtg = (RefPtg) convertedFormula.get(1);
 		assertEquals("$C101", refPtg.toFormulaString(null));
 		if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
 			throw new AssertionFailedError("Identified bug 45123");

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestArrayPtg.java Mon Jun  9 06:30:17 2008
@@ -54,12 +54,12 @@
 	 */
 	public void testReadWriteTokenValueBytes() {
 		
-		ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+		ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
 		
 		ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
 		assertEquals(3, ptg.getColumnCount());
 		assertEquals(2, ptg.getRowCount());
-		Object[] values = ptg.token_3_arrayValues;
+		Object[] values = ptg.getTokenArrayValues();
 		assertEquals(6, values.length);
 		
 		
@@ -82,7 +82,7 @@
 	 * Excel stores array elements column by column.  This test makes sure POI does the same.
 	 */
 	public void testElementOrdering() {
-		ArrayPtg ptg = new ArrayPtgV(new TestcaseRecordInputStream(ArrayPtgV.sid, ENCODED_PTG_DATA));
+		ArrayPtg ptg = new ArrayPtg(new TestcaseRecordInputStream(ArrayPtg.sid, ENCODED_PTG_DATA));
 		ptg.readTokenValues(new TestcaseRecordInputStream(0, ENCODED_CONSTANT_DATA));
 		assertEquals(3, ptg.getColumnCount());
 		assertEquals(2, ptg.getRowCount());

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java Mon Jun  9 06:30:17 2008
@@ -17,15 +17,19 @@
 
 package org.apache.poi.hssf.record.formula;
 
+import java.util.Arrays;
+import java.util.Stack;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.record.TestcaseRecordInputStream;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 
 /**
- * Tests for {@link ReferencePtg}.
+ * Tests for {@link RefPtg}.
  */
 public final class TestReferencePtg extends TestCase {
     /**
@@ -86,5 +90,18 @@
             throw e;
         }
     }
+    private static final byte[] tRefN_data = {
+    	0x2C, 33, 44, 55, 66,
+    };
+    public void testReadWrite_tRefN_bug45091() {
+        TestcaseRecordInputStream in = new TestcaseRecordInputStream(-1, tRefN_data);
+        Stack ptgs = Ptg.createParsedExpressionTokens((short)tRefN_data.length, in);
+        byte[] outData = new byte[5];
+        Ptg.serializePtgStack(ptgs, outData, 0);
+        if (outData[0] == 0x24) {
+            throw new AssertionFailedError("Identified bug 45091");
+        }
+        assertTrue(Arrays.equals(tRefN_data, outData));
+    }
 }
 

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java Mon Jun  9 06:30:17 2008
@@ -41,7 +41,7 @@
 			arg,	
 		};
 		
-		PercentEval opEval = new PercentEval(new PercentPtg());
+		PercentEval opEval = new PercentEval(PercentPtg.instance);
 		double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1);
 		
 		assertEquals(expectedResult, result, 0);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java Mon Jun  9 06:30:17 2008
@@ -36,7 +36,7 @@
 	 * The code for handling column operands had been copy-pasted from the row handling code. 
 	 */
 	public void testColumnOperand() {
-		
+
 		short firstRow = (short)8;
 		short lastRow = (short)12;
 		short colNum = (short)5;
@@ -52,10 +52,9 @@
 		Eval[] args = { 
 			areaEval,	
 		};
-		
-		double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(new UnaryPlusPtg()), args, 10, (short)20);
-		
+
+		double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(UnaryPlusPtg.instance), args, 10, (short)20);
+
 		assertEquals(35, result, 0);
 	}
-
 }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java Mon Jun  9 06:30:17 2008
@@ -19,7 +19,7 @@
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
@@ -58,6 +58,6 @@
 	 * Creates a single RefEval (with value zero)
 	 */
 	public static RefEval createRefEval(String refStr) {
-		return new Ref2DEval(new ReferencePtg(refStr), ZERO);
+		return new Ref2DEval(new RefPtg(refStr), ZERO);
 	}
 }

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java Mon Jun  9 06:30:17 2008
@@ -21,7 +21,7 @@
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
@@ -124,7 +124,7 @@
 		};
 		Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values);
 		
-		Ref2DEval criteriaArg = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(25));
+		Ref2DEval criteriaArg = new Ref2DEval(new RefPtg("A1"), new NumberEval(25));
 		Eval[] args=  { arg0, criteriaArg, };
 		
 		double actual = NumericFunctionInvoker.invoke(new Countif(), args);

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java Mon Jun  9 06:30:17 2008
@@ -18,7 +18,7 @@
 package org.apache.poi.hssf.record.formula.functions;
 
 import org.apache.poi.hssf.record.formula.AreaPtg;
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.Area2DEval;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
@@ -77,7 +77,7 @@
 		
 		// startPos is 1x1 area ref, numChars is cell ref
 		AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } );
-		RefEval reNumChars = new Ref2DEval(new ReferencePtg("B1"), new NumberEval(3));
+		RefEval reNumChars = new Ref2DEval(new RefPtg("B1"), new NumberEval(3));
 		confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala");
 
 		confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, "");

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java Mon Jun  9 06:30:17 2008
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.AreaEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
@@ -50,7 +50,7 @@
 
 	public void testScalarSimple() {
 		
-		RefEval refEval = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(3));
+		RefEval refEval = new Ref2DEval(new RefPtg("A1"), new NumberEval(3));
 		Eval[] args = {
 			refEval, 
 			new NumberEval(2),

Modified: poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java?rev=664700&r1=664699&r2=664700&view=diff
==============================================================================
--- poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java (original)
+++ poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java Mon Jun  9 06:30:17 2008
@@ -17,7 +17,7 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.RefPtg;
 import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.BoolEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
@@ -50,7 +50,7 @@
 	 * where cell A1 has the specified innerValue
 	 */
 	private Eval invokeTWithReference(ValueEval innerValue) {
-		Eval arg = new Ref2DEval(new ReferencePtg((short)1, (short)1, false, false), innerValue);
+		Eval arg = new Ref2DEval(new RefPtg((short)1, (short)1, false, false), innerValue);
 		return invokeT(arg);
 	}
 	



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org