You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/05/21 20:15:01 UTC

svn commit: r777204 [8/21] - in /poi/trunk/src/scratchpad: examples/src/org/apache/poi/hslf/examples/ examples/src/org/apache/poi/hwpf/ src/org/apache/poi/hdf/event/ src/org/apache/poi/hdf/extractor/ src/org/apache/poi/hdf/extractor/data/ src/org/apach...

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TableCell.java Thu May 21 18:12:22 2009
@@ -1,153 +1,153 @@
-
-/* ====================================================================
-   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.TextHeaderAtom;
-
-import java.awt.*;
-
-/**
- * Represents a cell in a ppt table
- * 
- * @author Yegor Kozlov
- */
-public class TableCell extends TextBox {
-    protected static final int DEFAULT_WIDTH = 100;
-    protected static final int DEFAULT_HEIGHT = 40;
-
-    private Line borderLeft;
-    private Line borderRight;
-    private Line borderTop;
-    private Line borderBottom;
-
-    /**
-     * Create a TableCell 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 TableCell(EscherContainerRecord escherRecord, Shape parent){
-        super(escherRecord, parent);
-    }
-
-    /**
-     * Create a new TableCell. 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 TableCell(Shape parent){
-        super(parent);
-
-        setShapeType(ShapeTypes.Rectangle);
-        //_txtrun.setRunType(TextHeaderAtom.HALF_BODY_TYPE);
-        //_txtrun.getRichTextRuns()[0].setFlag(false, 0, false);
-    }
-
-    protected EscherContainerRecord createSpContainer(boolean isChild){
-        _escherContainer = super.createSpContainer(isChild);
-        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
-        setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0);
-        setEscherProperty(opt, EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20000);
-        setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150001);
-        setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
-        setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);
-
-        return _escherContainer;
-    }
-
-    protected void anchorBorder(int type, Line line){
-        Rectangle cellAnchor = getAnchor();
-        Rectangle lineAnchor = new Rectangle();
-        switch(type){
-            case Table.BORDER_TOP:
-                lineAnchor.x = cellAnchor.x;
-                lineAnchor.y = cellAnchor.y;
-                lineAnchor.width = cellAnchor.width;
-                lineAnchor.height = 0;
-                break;
-            case Table.BORDER_RIGHT:
-                lineAnchor.x = cellAnchor.x + cellAnchor.width;
-                lineAnchor.y = cellAnchor.y;
-                lineAnchor.width = 0;
-                lineAnchor.height = cellAnchor.height;
-                break;
-            case Table.BORDER_BOTTOM:
-                lineAnchor.x = cellAnchor.x;
-                lineAnchor.y = cellAnchor.y + cellAnchor.height;
-                lineAnchor.width = cellAnchor.width;
-                lineAnchor.height = 0;
-                break;
-            case Table.BORDER_LEFT:
-                lineAnchor.x = cellAnchor.x;
-                lineAnchor.y = cellAnchor.y;
-                lineAnchor.width = 0;
-                lineAnchor.height = cellAnchor.height;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown border type: " + type);
-        }
-        line.setAnchor(lineAnchor);
-    }
-
-    public Line getBorderLeft() {
-        return borderLeft;
-    }
-
-    public void setBorderLeft(Line line) {
-        if(line != null) anchorBorder(Table.BORDER_LEFT, line);
-        this.borderLeft = line;
-    }
-
-    public Line getBorderRight() {
-        return borderRight;
-    }
-
-    public void setBorderRight(Line line) {
-        if(line != null) anchorBorder(Table.BORDER_RIGHT, line);
-        this.borderRight = line;
-    }
-
-    public Line getBorderTop() {
-        return borderTop;
-    }
-
-    public void setBorderTop(Line line) {
-        if(line != null) anchorBorder(Table.BORDER_TOP, line);
-        this.borderTop = line;
-    }
-
-    public Line getBorderBottom() {
-        return borderBottom;
-    }
-
-    public void setBorderBottom(Line line) {
-        if(line != null) anchorBorder(Table.BORDER_BOTTOM, line);
-        this.borderBottom = line;
-    }
-
-    public void setAnchor(Rectangle anchor){
-        super.setAnchor(anchor);
-
-        if(borderTop != null) anchorBorder(Table.BORDER_TOP, borderTop);
-        if(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight);
-        if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom);
-        if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft);
-    }
-}
+/* ====================================================================
+   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.TextHeaderAtom;
+
+import java.awt.*;
+
+/**
+ * Represents a cell in a ppt table
+ *
+ * @author Yegor Kozlov
+ */
+public final class TableCell extends TextBox {
+    protected static final int DEFAULT_WIDTH = 100;
+    protected static final int DEFAULT_HEIGHT = 40;
+
+    private Line borderLeft;
+    private Line borderRight;
+    private Line borderTop;
+    private Line borderBottom;
+
+    /**
+     * Create a TableCell 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 TableCell(EscherContainerRecord escherRecord, Shape parent){
+        super(escherRecord, parent);
+    }
+
+    /**
+     * Create a new TableCell. 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 TableCell(Shape parent){
+        super(parent);
+
+        setShapeType(ShapeTypes.Rectangle);
+        //_txtrun.setRunType(TextHeaderAtom.HALF_BODY_TYPE);
+        //_txtrun.getRichTextRuns()[0].setFlag(false, 0, false);
+    }
+
+    protected EscherContainerRecord createSpContainer(boolean isChild){
+        _escherContainer = super.createSpContainer(isChild);
+        EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
+        setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0);
+        setEscherProperty(opt, EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20000);
+        setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150001);
+        setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
+        setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);
+
+        return _escherContainer;
+    }
+
+    protected void anchorBorder(int type, Line line){
+        Rectangle cellAnchor = getAnchor();
+        Rectangle lineAnchor = new Rectangle();
+        switch(type){
+            case Table.BORDER_TOP:
+                lineAnchor.x = cellAnchor.x;
+                lineAnchor.y = cellAnchor.y;
+                lineAnchor.width = cellAnchor.width;
+                lineAnchor.height = 0;
+                break;
+            case Table.BORDER_RIGHT:
+                lineAnchor.x = cellAnchor.x + cellAnchor.width;
+                lineAnchor.y = cellAnchor.y;
+                lineAnchor.width = 0;
+                lineAnchor.height = cellAnchor.height;
+                break;
+            case Table.BORDER_BOTTOM:
+                lineAnchor.x = cellAnchor.x;
+                lineAnchor.y = cellAnchor.y + cellAnchor.height;
+                lineAnchor.width = cellAnchor.width;
+                lineAnchor.height = 0;
+                break;
+            case Table.BORDER_LEFT:
+                lineAnchor.x = cellAnchor.x;
+                lineAnchor.y = cellAnchor.y;
+                lineAnchor.width = 0;
+                lineAnchor.height = cellAnchor.height;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown border type: " + type);
+        }
+        line.setAnchor(lineAnchor);
+    }
+
+    public Line getBorderLeft() {
+        return borderLeft;
+    }
+
+    public void setBorderLeft(Line line) {
+        if(line != null) anchorBorder(Table.BORDER_LEFT, line);
+        this.borderLeft = line;
+    }
+
+    public Line getBorderRight() {
+        return borderRight;
+    }
+
+    public void setBorderRight(Line line) {
+        if(line != null) anchorBorder(Table.BORDER_RIGHT, line);
+        this.borderRight = line;
+    }
+
+    public Line getBorderTop() {
+        return borderTop;
+    }
+
+    public void setBorderTop(Line line) {
+        if(line != null) anchorBorder(Table.BORDER_TOP, line);
+        this.borderTop = line;
+    }
+
+    public Line getBorderBottom() {
+        return borderBottom;
+    }
+
+    public void setBorderBottom(Line line) {
+        if(line != null) anchorBorder(Table.BORDER_BOTTOM, line);
+        this.borderBottom = line;
+    }
+
+    public void setAnchor(Rectangle anchor){
+        super.setAnchor(anchor);
+
+        if(borderTop != null) anchorBorder(Table.BORDER_TOP, borderTop);
+        if(borderRight != null) anchorBorder(Table.BORDER_RIGHT, borderRight);
+        if(borderBottom != null) anchorBorder(Table.BORDER_BOTTOM, borderBottom);
+        if(borderLeft != null) anchorBorder(Table.BORDER_LEFT, borderLeft);
+    }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java Thu May 21 18:12:22 2009
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -33,7 +32,7 @@
 
     /**
      * 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
      */

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java Thu May 21 18:12:22 2009
@@ -1,311 +1,312 @@
-/* ====================================================================
-   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.hslf.usermodel.RichTextRun;
-import org.apache.poi.hslf.record.TextRulerAtom;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
-
-import java.text.AttributedString;
-import java.text.AttributedCharacterIterator;
-import java.text.BreakIterator;
-import java.awt.font.TextAttribute;
-import java.awt.font.LineBreakMeasurer;
-import java.awt.font.TextLayout;
-import java.awt.font.FontRenderContext;
-import java.awt.*;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Point2D;
-import java.util.ArrayList;
-
-/**
- * Paint text into java.awt.Graphics2D
- * 
- * @author Yegor Kozlov
- */
-public class TextPainter {
-    protected POILogger logger = POILogFactory.getLogger(this.getClass());
-
-    /**
-     * Display unicode square if a bullet char can't be displayed,
-     * for example, if Wingdings font is used.
-     * TODO: map Wingdngs and Symbol to unicode Arial
-     */
-    protected static final char DEFAULT_BULLET_CHAR = '\u25a0';
-
-    protected TextShape _shape;
-
-    public TextPainter(TextShape shape){
-        _shape = shape;
-    }
-
-    /**
-     * Convert the underlying set of rich text runs into java.text.AttributedString
-     */
-    public AttributedString getAttributedString(TextRun txrun){
-        String text = txrun.getText();
-        //TODO: properly process tabs
-        text = text.replace('\t', ' ');
-        text = text.replace((char)160, ' ');
-
-        AttributedString at = new AttributedString(text);
-        RichTextRun[] rt = txrun.getRichTextRuns();
-        for (int i = 0; i < rt.length; i++) {
-            int start = rt[i].getStartIndex();
-            int end = rt[i].getEndIndex();
-            if(start == end) {
-                logger.log(POILogger.INFO,  "Skipping RichTextRun with zero length");
-                continue;
-            }
-
-            at.addAttribute(TextAttribute.FAMILY, rt[i].getFontName(), start, end);
-            at.addAttribute(TextAttribute.SIZE, new Float(rt[i].getFontSize()), start, end);
-            at.addAttribute(TextAttribute.FOREGROUND, rt[i].getFontColor(), start, end);
-            if(rt[i].isBold()) at.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, start, end);
-            if(rt[i].isItalic()) at.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, start, end);
-            if(rt[i].isUnderlined()) {
-                at.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, start, end);
-                at.addAttribute(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, start, end);
-            }
-            if(rt[i].isStrikethrough()) at.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, start, end);
-            int superScript = rt[i].getSuperscript();
-            if(superScript != 0) at.addAttribute(TextAttribute.SUPERSCRIPT, superScript > 0 ? TextAttribute.SUPERSCRIPT_SUPER : TextAttribute.SUPERSCRIPT_SUB, start, end);
-
-        }
-        return at;
-    }
-
-    public void paint(Graphics2D graphics){
-        Rectangle2D anchor = _shape.getLogicalAnchor2D();
-        TextElement[] elem = getTextElements((float)anchor.getWidth(), graphics.getFontRenderContext());
-        if(elem == null) return;
-
-        float textHeight = 0;
-        for (int i = 0; i < elem.length; i++) {
-            textHeight += elem[i].ascent + elem[i].descent;
-        }
-
-        int valign = _shape.getVerticalAlignment();
-        double y0 = anchor.getY();
-        switch (valign){
-            case TextShape.AnchorTopBaseline:
-            case TextShape.AnchorTop:
-                y0 += _shape.getMarginTop();
-                break;
-            case TextShape.AnchorBottom:
-                y0 += anchor.getHeight() - textHeight - _shape.getMarginBottom();
-                break;
-            default:
-            case TextShape.AnchorMiddle:
-                float delta =  (float)anchor.getHeight() - textHeight - _shape.getMarginTop() - _shape.getMarginBottom();
-                y0 += _shape.getMarginTop()  + delta/2;
-                break;
-        }
-
-        //finally draw the text fragments
-        for (int i = 0; i < elem.length; i++) {
-            y0 += elem[i].ascent;
-
-            Point2D.Double pen = new Point2D.Double();
-            pen.y = y0;
-            switch (elem[i]._align) {
-                default:
-                case TextShape.AlignLeft:
-                    pen.x = anchor.getX() + _shape.getMarginLeft();
-                    break;
-                case TextShape.AlignCenter:
-                    pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
-                    break;
-                case TextShape.AlignRight:
-                    pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight());
-                    break;
-            }
-            if(elem[i]._bullet != null){
-                graphics.drawString(elem[i]._bullet.getIterator(), (float)(pen.x + elem[i]._bulletOffset), (float)pen.y);
-            }
-            AttributedCharacterIterator chIt = elem[i]._text.getIterator();
-            if(chIt.getEndIndex() > chIt.getBeginIndex()) {
-                graphics.drawString(chIt, (float)(pen.x + elem[i]._textOffset), (float)pen.y);
-            }
-            y0 += elem[i].descent;
-        }
-    }
-
-    public TextElement[] getTextElements(float textWidth, FontRenderContext frc){
-        TextRun run = _shape.getTextRun();
-        if (run == null) return null;
-
-        String text = run.getText();
-        if (text == null || text.equals("")) return null;
-
-        AttributedString at = getAttributedString(run);
-
-        AttributedCharacterIterator it = at.getIterator();
-        int paragraphStart = it.getBeginIndex();
-        int paragraphEnd = it.getEndIndex();
-
-        ArrayList lines = new ArrayList();
-        LineBreakMeasurer measurer = new LineBreakMeasurer(it, frc);
-        measurer.setPosition(paragraphStart);
-        while (measurer.getPosition() < paragraphEnd) {
-            int startIndex = measurer.getPosition();
-            int nextBreak = text.indexOf('\n', measurer.getPosition() + 1);
-
-            boolean prStart = text.charAt(startIndex) == '\n';
-            if(prStart) measurer.setPosition(startIndex++);
-
-            RichTextRun rt = run.getRichTextRunAt(startIndex == text.length() ? (startIndex-1) : startIndex);
-            if(rt == null) {
-                logger.log(POILogger.WARN,  "RichTextRun not found at pos" + startIndex + "; text.length: " + text.length());
-                break;
-            }
-
-            float wrappingWidth = textWidth - _shape.getMarginLeft() - _shape.getMarginRight();
-            int bulletOffset = rt.getBulletOffset();
-            int textOffset = rt.getTextOffset();
-            int indent = rt.getIndentLevel();
-
-            TextRulerAtom ruler = run.getTextRuler();
-            if(ruler != null) {
-                int bullet_val = ruler.getBulletOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
-                int text_val = ruler.getTextOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
-                if(bullet_val > text_val){
-                    int a = bullet_val;
-                    bullet_val = text_val;
-                    text_val = a;
-                }
-                if(bullet_val != 0 ) bulletOffset = bullet_val;
-                if(text_val != 0) textOffset = text_val;
-            }
-
-            if(bulletOffset > 0 || prStart || startIndex == 0) wrappingWidth -= textOffset;
-
-            if (_shape.getWordWrap() == TextShape.WrapNone) {
-                wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
-            }
-
-            TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
-                    nextBreak == -1 ? paragraphEnd : nextBreak, true);
-            if (textLayout == null) {
-                textLayout = measurer.nextLayout(textWidth,
-                    nextBreak == -1 ? paragraphEnd : nextBreak, false);
-            }
-            if(textLayout == null){
-                logger.log(POILogger.WARN, "Failed to break text into lines: wrappingWidth: "+wrappingWidth+
-                        "; text: " + rt.getText());
-                measurer.setPosition(rt.getEndIndex());
-                continue;
-            }
-            int endIndex = measurer.getPosition();
-
-            float lineHeight = (float)textLayout.getBounds().getHeight();
-            int linespacing = rt.getLineSpacing();
-            if(linespacing == 0) linespacing = 100;
-
-            TextElement el = new TextElement();
-            if(linespacing >= 0){
-                el.ascent = textLayout.getAscent()*linespacing/100;
-            } else {
-                el.ascent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
-            }
-
-            el._align = rt.getAlignment();
-            el.advance = textLayout.getAdvance();
-            el._textOffset = textOffset;
-            el._text = new AttributedString(it, startIndex, endIndex);
-            el.textStartIndex = startIndex;
-            el.textEndIndex = endIndex;
-
-            if (prStart){
-                int sp = rt.getSpaceBefore();
-                float spaceBefore;
-                if(sp >= 0){
-                    spaceBefore = lineHeight * sp/100;
-                } else {
-                    spaceBefore = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
-                }
-                el.ascent += spaceBefore;
-            }
-
-            float descent;
-            if(linespacing >= 0){
-                descent = (textLayout.getDescent() + textLayout.getLeading())*linespacing/100;
-            } else {
-                descent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
-            }
-            if (prStart){
-                int sp = rt.getSpaceAfter();
-                float spaceAfter;
-                if(sp >= 0){
-                    spaceAfter = lineHeight * sp/100;
-                } else {
-                    spaceAfter = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
-                }
-                el.ascent += spaceAfter;
-            }
-            el.descent = descent;
-
-            if(rt.isBullet() && (prStart || startIndex == 0)){
-                it.setIndex(startIndex);
-
-                AttributedString bat = new AttributedString(Character.toString(rt.getBulletChar()));
-                Color clr = rt.getBulletColor();
-                if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
-                else bat.addAttribute(TextAttribute.FOREGROUND, it.getAttribute(TextAttribute.FOREGROUND));
-
-                int fontIdx = rt.getBulletFont();
-                if(fontIdx == -1) fontIdx = rt.getFontIndex();
-                PPFont bulletFont = _shape.getSheet().getSlideShow().getFont(fontIdx);
-                bat.addAttribute(TextAttribute.FAMILY, bulletFont.getFontName());
-
-                int bulletSize = rt.getBulletSize();
-                int fontSize = rt.getFontSize();
-                if(bulletSize != -1) fontSize = Math.round(fontSize*bulletSize*0.01f);
-                bat.addAttribute(TextAttribute.SIZE, new Float(fontSize));
-
-                if(!new Font(bulletFont.getFontName(), Font.PLAIN, 1).canDisplay(rt.getBulletChar())){
-                    bat.addAttribute(TextAttribute.FAMILY, "Arial");
-                    bat = new AttributedString("" + DEFAULT_BULLET_CHAR, bat.getIterator().getAttributes());
-                }
-
-                if(text.substring(startIndex, endIndex).length() > 1){
-                    el._bullet = bat;
-                    el._bulletOffset = bulletOffset;
-                }
-            }
-            lines.add(el);
-        }
-
-        //finally draw the text fragments
-        TextElement[] elems = new TextElement[lines.size()];
-        return (TextElement[])lines.toArray(elems);
-    }
-
-    public static class TextElement {
-        public AttributedString _text;
-        public int _textOffset;
-        public AttributedString _bullet;
-        public int _bulletOffset;
-        public int _align;
-        public float ascent, descent;
-        public float advance;
-        public int textStartIndex, textEndIndex;
-    }
-}
+/* ====================================================================
+   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.hslf.usermodel.RichTextRun;
+import org.apache.poi.hslf.record.TextRulerAtom;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
+
+import java.text.AttributedString;
+import java.text.AttributedCharacterIterator;
+import java.text.BreakIterator;
+import java.awt.font.TextAttribute;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextLayout;
+import java.awt.font.FontRenderContext;
+import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+
+/**
+ * Paint text into java.awt.Graphics2D
+ *
+ * @author Yegor Kozlov
+ */
+public final class TextPainter {
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
+    /**
+     * Display unicode square if a bullet char can't be displayed,
+     * for example, if Wingdings font is used.
+     * TODO: map Wingdngs and Symbol to unicode Arial
+     */
+    protected static final char DEFAULT_BULLET_CHAR = '\u25a0';
+
+    protected TextShape _shape;
+
+    public TextPainter(TextShape shape){
+        _shape = shape;
+    }
+
+    /**
+     * Convert the underlying set of rich text runs into java.text.AttributedString
+     */
+    public AttributedString getAttributedString(TextRun txrun){
+        String text = txrun.getText();
+        //TODO: properly process tabs
+        text = text.replace('\t', ' ');
+        text = text.replace((char)160, ' ');
+
+        AttributedString at = new AttributedString(text);
+        RichTextRun[] rt = txrun.getRichTextRuns();
+        for (int i = 0; i < rt.length; i++) {
+            int start = rt[i].getStartIndex();
+            int end = rt[i].getEndIndex();
+            if(start == end) {
+                logger.log(POILogger.INFO,  "Skipping RichTextRun with zero length");
+                continue;
+            }
+
+            at.addAttribute(TextAttribute.FAMILY, rt[i].getFontName(), start, end);
+            at.addAttribute(TextAttribute.SIZE, new Float(rt[i].getFontSize()), start, end);
+            at.addAttribute(TextAttribute.FOREGROUND, rt[i].getFontColor(), start, end);
+            if(rt[i].isBold()) at.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, start, end);
+            if(rt[i].isItalic()) at.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, start, end);
+            if(rt[i].isUnderlined()) {
+                at.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, start, end);
+                at.addAttribute(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, start, end);
+            }
+            if(rt[i].isStrikethrough()) at.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, start, end);
+            int superScript = rt[i].getSuperscript();
+            if(superScript != 0) at.addAttribute(TextAttribute.SUPERSCRIPT, superScript > 0 ? TextAttribute.SUPERSCRIPT_SUPER : TextAttribute.SUPERSCRIPT_SUB, start, end);
+
+        }
+        return at;
+    }
+
+    public void paint(Graphics2D graphics){
+        Rectangle2D anchor = _shape.getLogicalAnchor2D();
+        TextElement[] elem = getTextElements((float)anchor.getWidth(), graphics.getFontRenderContext());
+        if(elem == null) return;
+
+        float textHeight = 0;
+        for (int i = 0; i < elem.length; i++) {
+            textHeight += elem[i].ascent + elem[i].descent;
+        }
+
+        int valign = _shape.getVerticalAlignment();
+        double y0 = anchor.getY();
+        switch (valign){
+            case TextShape.AnchorTopBaseline:
+            case TextShape.AnchorTop:
+                y0 += _shape.getMarginTop();
+                break;
+            case TextShape.AnchorBottom:
+                y0 += anchor.getHeight() - textHeight - _shape.getMarginBottom();
+                break;
+            default:
+            case TextShape.AnchorMiddle:
+                float delta =  (float)anchor.getHeight() - textHeight - _shape.getMarginTop() - _shape.getMarginBottom();
+                y0 += _shape.getMarginTop()  + delta/2;
+                break;
+        }
+
+        //finally draw the text fragments
+        for (int i = 0; i < elem.length; i++) {
+            y0 += elem[i].ascent;
+
+            Point2D.Double pen = new Point2D.Double();
+            pen.y = y0;
+            switch (elem[i]._align) {
+                default:
+                case TextShape.AlignLeft:
+                    pen.x = anchor.getX() + _shape.getMarginLeft();
+                    break;
+                case TextShape.AlignCenter:
+                    pen.x = anchor.getX() + _shape.getMarginLeft() +
+                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
+                    break;
+                case TextShape.AlignRight:
+                    pen.x = anchor.getX() + _shape.getMarginLeft() +
+                            (anchor.getWidth() - elem[i].advance - _shape.getMarginLeft() - _shape.getMarginRight());
+                    break;
+            }
+            if(elem[i]._bullet != null){
+                graphics.drawString(elem[i]._bullet.getIterator(), (float)(pen.x + elem[i]._bulletOffset), (float)pen.y);
+            }
+            AttributedCharacterIterator chIt = elem[i]._text.getIterator();
+            if(chIt.getEndIndex() > chIt.getBeginIndex()) {
+                graphics.drawString(chIt, (float)(pen.x + elem[i]._textOffset), (float)pen.y);
+            }
+            y0 += elem[i].descent;
+        }
+    }
+
+    public TextElement[] getTextElements(float textWidth, FontRenderContext frc){
+        TextRun run = _shape.getTextRun();
+        if (run == null) return null;
+
+        String text = run.getText();
+        if (text == null || text.equals("")) return null;
+
+        AttributedString at = getAttributedString(run);
+
+        AttributedCharacterIterator it = at.getIterator();
+        int paragraphStart = it.getBeginIndex();
+        int paragraphEnd = it.getEndIndex();
+
+        ArrayList lines = new ArrayList();
+        LineBreakMeasurer measurer = new LineBreakMeasurer(it, frc);
+        measurer.setPosition(paragraphStart);
+        while (measurer.getPosition() < paragraphEnd) {
+            int startIndex = measurer.getPosition();
+            int nextBreak = text.indexOf('\n', measurer.getPosition() + 1);
+
+            boolean prStart = text.charAt(startIndex) == '\n';
+            if(prStart) measurer.setPosition(startIndex++);
+
+            RichTextRun rt = run.getRichTextRunAt(startIndex == text.length() ? (startIndex-1) : startIndex);
+            if(rt == null) {
+                logger.log(POILogger.WARN,  "RichTextRun not found at pos" + startIndex + "; text.length: " + text.length());
+                break;
+            }
+
+            float wrappingWidth = textWidth - _shape.getMarginLeft() - _shape.getMarginRight();
+            int bulletOffset = rt.getBulletOffset();
+            int textOffset = rt.getTextOffset();
+            int indent = rt.getIndentLevel();
+
+            TextRulerAtom ruler = run.getTextRuler();
+            if(ruler != null) {
+                int bullet_val = ruler.getBulletOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
+                int text_val = ruler.getTextOffsets()[indent]*Shape.POINT_DPI/Shape.MASTER_DPI;
+                if(bullet_val > text_val){
+                    int a = bullet_val;
+                    bullet_val = text_val;
+                    text_val = a;
+                }
+                if(bullet_val != 0 ) bulletOffset = bullet_val;
+                if(text_val != 0) textOffset = text_val;
+            }
+
+            if(bulletOffset > 0 || prStart || startIndex == 0) wrappingWidth -= textOffset;
+
+            if (_shape.getWordWrap() == TextShape.WrapNone) {
+                wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
+            }
+
+            TextLayout textLayout = measurer.nextLayout(wrappingWidth + 1,
+                    nextBreak == -1 ? paragraphEnd : nextBreak, true);
+            if (textLayout == null) {
+                textLayout = measurer.nextLayout(textWidth,
+                    nextBreak == -1 ? paragraphEnd : nextBreak, false);
+            }
+            if(textLayout == null){
+                logger.log(POILogger.WARN, "Failed to break text into lines: wrappingWidth: "+wrappingWidth+
+                        "; text: " + rt.getText());
+                measurer.setPosition(rt.getEndIndex());
+                continue;
+            }
+            int endIndex = measurer.getPosition();
+
+            float lineHeight = (float)textLayout.getBounds().getHeight();
+            int linespacing = rt.getLineSpacing();
+            if(linespacing == 0) linespacing = 100;
+
+            TextElement el = new TextElement();
+            if(linespacing >= 0){
+                el.ascent = textLayout.getAscent()*linespacing/100;
+            } else {
+                el.ascent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
+            }
+
+            el._align = rt.getAlignment();
+            el.advance = textLayout.getAdvance();
+            el._textOffset = textOffset;
+            el._text = new AttributedString(it, startIndex, endIndex);
+            el.textStartIndex = startIndex;
+            el.textEndIndex = endIndex;
+
+            if (prStart){
+                int sp = rt.getSpaceBefore();
+                float spaceBefore;
+                if(sp >= 0){
+                    spaceBefore = lineHeight * sp/100;
+                } else {
+                    spaceBefore = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
+                }
+                el.ascent += spaceBefore;
+            }
+
+            float descent;
+            if(linespacing >= 0){
+                descent = (textLayout.getDescent() + textLayout.getLeading())*linespacing/100;
+            } else {
+                descent = -linespacing*Shape.POINT_DPI/Shape.MASTER_DPI;
+            }
+            if (prStart){
+                int sp = rt.getSpaceAfter();
+                float spaceAfter;
+                if(sp >= 0){
+                    spaceAfter = lineHeight * sp/100;
+                } else {
+                    spaceAfter = -sp*Shape.POINT_DPI/Shape.MASTER_DPI;
+                }
+                el.ascent += spaceAfter;
+            }
+            el.descent = descent;
+
+            if(rt.isBullet() && (prStart || startIndex == 0)){
+                it.setIndex(startIndex);
+
+                AttributedString bat = new AttributedString(Character.toString(rt.getBulletChar()));
+                Color clr = rt.getBulletColor();
+                if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
+                else bat.addAttribute(TextAttribute.FOREGROUND, it.getAttribute(TextAttribute.FOREGROUND));
+
+                int fontIdx = rt.getBulletFont();
+                if(fontIdx == -1) fontIdx = rt.getFontIndex();
+                PPFont bulletFont = _shape.getSheet().getSlideShow().getFont(fontIdx);
+                bat.addAttribute(TextAttribute.FAMILY, bulletFont.getFontName());
+
+                int bulletSize = rt.getBulletSize();
+                int fontSize = rt.getFontSize();
+                if(bulletSize != -1) fontSize = Math.round(fontSize*bulletSize*0.01f);
+                bat.addAttribute(TextAttribute.SIZE, new Float(fontSize));
+
+                if(!new Font(bulletFont.getFontName(), Font.PLAIN, 1).canDisplay(rt.getBulletChar())){
+                    bat.addAttribute(TextAttribute.FAMILY, "Arial");
+                    bat = new AttributedString("" + DEFAULT_BULLET_CHAR, bat.getIterator().getAttributes());
+                }
+
+                if(text.substring(startIndex, endIndex).length() > 1){
+                    el._bullet = bat;
+                    el._bulletOffset = bulletOffset;
+                }
+            }
+            lines.add(el);
+        }
+
+        //finally draw the text fragments
+        TextElement[] elems = new TextElement[lines.size()];
+        return (TextElement[])lines.toArray(elems);
+    }
+
+    public static class TextElement {
+        public AttributedString _text;
+        public int _textOffset;
+        public AttributedString _bullet;
+        public int _bulletOffset;
+        public int _align;
+        public float ascent, descent;
+        public float advance;
+        public int textStartIndex, textEndIndex;
+    }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java Thu May 21 18:12:22 2009
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,8 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
-
 
 package org.apache.poi.hslf.model;
 
@@ -38,7 +35,7 @@
  * @author Nick Burch
  */
 
-public class TextRun
+public final class TextRun
 {
 	// Note: These fields are protected to help with unit testing
 	//   Other classes shouldn't really go playing with them!
@@ -80,7 +77,7 @@
 	public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) {
 		this(tha,tba,null,sta);
 	}
-	
+
 	/**
 	 * Internal constructor and initializer
 	 */
@@ -95,7 +92,7 @@
 			_isUnicode = true;
 		}
 		String runRawText = getText();
-		
+
 		// Figure out the rich text runs
 		LinkedList pStyles = new LinkedList();
 		LinkedList cStyles = new LinkedList();
@@ -107,7 +104,7 @@
 		}
         buildRichTextRuns(pStyles, cStyles, runRawText);
 	}
-	
+
 	public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText){
 
         // Handle case of no current style, with a default
@@ -258,25 +255,25 @@
     }
 
     // Update methods follow
-	
+
 	/**
-	 * Adds the supplied text onto the end of the TextRun, 
+	 * Adds the supplied text onto the end of the TextRun,
 	 *  creating a new RichTextRun (returned) for it to
-	 *  sit in. 
+	 *  sit in.
 	 * In many cases, before calling this, you'll want to add
 	 *  a newline onto the end of your last RichTextRun
 	 */
 	public RichTextRun appendText(String s) {
 		// We will need a StyleTextProp atom
 		ensureStyleAtomPresent();
-		
-		// First up, append the text to the 
+
+		// First up, append the text to the
 		//  underlying text atom
 		int oldSize = getRawText().length();
 		storeText(
 				getRawText() + s
 		);
-		
+
 		// If either of the previous styles overran
 		//  the text by one, we need to shuffle that
 		//  extra character onto the new ones
@@ -296,32 +293,32 @@
 					tpc.getCharactersCovered() - cOverRun
 			);
 		}
-		
+
 		// Next, add the styles for its paragraph and characters
 		TextPropCollection newPTP =
 			_styleAtom.addParagraphTextPropCollection(s.length()+pOverRun);
 		TextPropCollection newCTP =
 			_styleAtom.addCharacterTextPropCollection(s.length()+cOverRun);
-		
+
 		// Now, create the new RichTextRun
 		RichTextRun nr = new RichTextRun(
-				this, oldSize, s.length(), 
+				this, oldSize, s.length(),
 				newPTP, newCTP, false, false
 		);
-		
+
 		// Add the new RichTextRun onto our list
 		RichTextRun[] newRuns = new RichTextRun[_rtRuns.length+1];
 		System.arraycopy(_rtRuns, 0, newRuns, 0, _rtRuns.length);
 		newRuns[newRuns.length-1] = nr;
 		_rtRuns = newRuns;
-		
+
 		// And return the new run to the caller
 		return nr;
 	}
 
 	/**
-	 * Saves the given string to the records. Doesn't 
-	 *  touch the stylings. 
+	 * Saves the given string to the records. Doesn't
+	 *  touch the stylings.
 	 */
 	private void storeText(String s) {
 		// Remove a single trailing \r, as there is an implicit one at the
@@ -329,7 +326,7 @@
 		if(s.endsWith("\r")) {
 			s = s.substring(0, s.length()-1);
 		}
-		
+
 		// Store in the appropriate record
 		if(_isUnicode) {
 			// The atom can safely convert to unicode
@@ -344,11 +341,11 @@
 				_byteAtom.setText(text);
 			} else {
 				// Need to swap a TextBytesAtom for a TextCharsAtom
-				
+
 				// Build the new TextCharsAtom
 				_charAtom = new TextCharsAtom();
 				_charAtom.setText(s);
-				
+
 				// Use the TextHeaderAtom to do the swap on the parent
 				RecordContainer parent = _headerAtom.getParentRecord();
 				Record[] cr = parent.getChildRecords();
@@ -360,7 +357,7 @@
 						break;
 					}
 				}
-				
+
 				// Flag the change
 				_byteAtom = null;
 				_isUnicode = true;
@@ -379,7 +376,7 @@
             }
         }
 	}
-	
+
 	/**
 	 * Handles an update to the text stored in one of the Rich Text Runs
 	 * @param run
@@ -396,10 +393,10 @@
 		if(runID == -1) {
 			throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun");
 		}
-		
+
 		// Ensure a StyleTextPropAtom is present, adding if required
 		ensureStyleAtomPresent();
-		
+
 		// Update the text length for its Paragraph and Character stylings
 		// If it's shared:
 		//   * calculate the new length based on the run's old text
@@ -416,7 +413,7 @@
 		if(runID == _rtRuns.length-1) {
 			newSize++;
 		}
-		
+
 		if(run._isParagraphStyleShared()) {
 			pCol.updateTextSize( pCol.getCharactersCovered() - run.getLength() + s.length() );
 		} else {
@@ -427,14 +424,14 @@
 		} else {
 			cCol.updateTextSize(newSize);
 		}
-		
+
 		// Build up the new text
 		// As we go through, update the start position for all subsequent runs
 		// The building relies on the old text still being present
 		StringBuffer newText = new StringBuffer();
 		for(int i=0; i<_rtRuns.length; i++) {
 			int newStartPos = newText.length();
-			
+
 			// Build up the new text
 			if(i != runID) {
 				// Not the affected run, so keep old text
@@ -443,7 +440,7 @@
 				// Affected run, so use new text
 				newText.append(s);
 			}
-			
+
 			// Do we need to update the start position of this run?
 			// (Need to get the text before we update the start pos)
 			if(i <= runID) {
@@ -453,15 +450,15 @@
 				_rtRuns[i].updateStartPosition(newStartPos);
 			}
 		}
-		
+
 		// Now we can save the new text
 		storeText(newText.toString());
 	}
 
 	/**
 	 * Changes the text, and sets it all to have the same styling
-	 *  as the the first character has. 
-	 * If you care about styling, do setText on a RichTextRun instead 
+	 *  as the the first character has.
+	 * If you care about styling, do setText on a RichTextRun instead
 	 */
 	public void setRawText(String s) {
 		// Save the new text to the atoms
@@ -481,10 +478,10 @@
 		if(_styleAtom != null) {
 			LinkedList pStyles = _styleAtom.getParagraphStyles();
 			while(pStyles.size() > 1) { pStyles.removeLast(); }
-			
+
 			LinkedList cStyles = _styleAtom.getCharacterStyles();
 			while(cStyles.size() > 1) { cStyles.removeLast(); }
-			
+
 			_rtRuns[0].setText(s);
 		} else {
 			// Recreate rich text run with no styling
@@ -503,7 +500,7 @@
     }
 
     /**
-	 * Ensure a StyleTextPropAtom is present for this run, 
+	 * Ensure a StyleTextPropAtom is present for this run,
 	 *  by adding if required. Normally for internal TextRun use.
 	 */
 	public void ensureStyleAtomPresent() {
@@ -511,23 +508,23 @@
 			// All there
 			return;
 		}
-		
+
 		// Create a new one at the right size
 		_styleAtom = new StyleTextPropAtom(getRawText().length() + 1);
-		
+
 		// Use the TextHeader atom to get at the parent
 		RecordContainer runAtomsParent = _headerAtom.getParentRecord();
-		
+
 		// Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
 		Record addAfter = _byteAtom;
 		if(_byteAtom == null) { addAfter = _charAtom; }
 		runAtomsParent.addChildAfter(_styleAtom, addAfter);
-		
+
 		// Feed this to our sole rich text run
 		if(_rtRuns.length != 1) {
 			throw new IllegalStateException("Needed to add StyleTextPropAtom when had many rich text runs");
 		}
-		// These are the only styles for now 
+		// These are the only styles for now
 		_rtRuns[0].supplyTextProps(
 				(TextPropCollection)_styleAtom.getParagraphStyles().get(0),
 				(TextPropCollection)_styleAtom.getCharacterStyles().get(0),
@@ -572,7 +569,7 @@
 			return _byteAtom.getText();
 		}
 	}
-	
+
 	/**
 	 * Fetch the rich text runs (runs of text with the same styling) that
 	 *  are contained within this block of text
@@ -580,13 +577,13 @@
 	public RichTextRun[] getRichTextRuns() {
 		return 	_rtRuns;
 	}
-	
+
 	/**
 	* Returns the type of the text, from the TextHeaderAtom.
 	* Possible values can be seen from TextHeaderAtom
 	* @see org.apache.poi.hslf.record.TextHeaderAtom
 	*/
-	public int getRunType() { 
+	public int getRunType() {
 		return _headerAtom.getTextType();
 	}
 
@@ -599,7 +596,7 @@
 	public void setRunType(int type) {
 		_headerAtom.setTextType(type);
 	}
-	
+
 	/**
 	 * Supply the SlideShow we belong to.
 	 * Also passes it on to our child RichTextRuns
@@ -618,7 +615,7 @@
     }
 
     public Sheet getSheet(){
-        return this.sheet;        
+        return this.sheet;
     }
 
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TitleMaster.java Thu May 21 18:12:22 2009
@@ -1,69 +1,69 @@
-/* ====================================================================
-   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.hslf.model.textproperties.TextProp;
-import org.apache.poi.hslf.record.*;
-
-/**
- * Title masters define the design template for slides with a Title Slide layout.
- *
- * @author Yegor Kozlov
- */
-public class TitleMaster extends MasterSheet {
-    private TextRun[] _runs;
-
-    /**
-     * Constructs a TitleMaster
-     *
-     */
-    public TitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
-        super(record, sheetNo);
-
-        _runs = findTextRuns(getPPDrawing());
-        for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
-    }
-
-    /**
-     * Returns an array of all the TextRuns found
-     */
-    public TextRun[] getTextRuns() {
-        return _runs;
-    }
-
-    /**
-     * Delegate the call to the underlying slide master.
-     */
-    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
-        MasterSheet master = getMasterSheet();
-        return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
-    }
-
-    /**
-     * Returns the slide master for this title master.
-     */
-    public MasterSheet getMasterSheet(){
-        SlideMaster[] master = getSlideShow().getSlidesMasters();
-        SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
-        int masterId = sa.getMasterID();
-        for (int i = 0; i < master.length; i++) {
-            if (masterId == master[i]._getSheetNumber()) return master[i];
-        }
-        return null;
-    }
-}
+/* ====================================================================
+   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.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.record.*;
+
+/**
+ * Title masters define the design template for slides with a Title Slide layout.
+ *
+ * @author Yegor Kozlov
+ */
+public final class TitleMaster extends MasterSheet {
+    private TextRun[] _runs;
+
+    /**
+     * Constructs a TitleMaster
+     *
+     */
+    public TitleMaster(org.apache.poi.hslf.record.Slide record, int sheetNo) {
+        super(record, sheetNo);
+
+        _runs = findTextRuns(getPPDrawing());
+        for (int i = 0; i < _runs.length; i++) _runs[i].setSheet(this);
+    }
+
+    /**
+     * Returns an array of all the TextRuns found
+     */
+    public TextRun[] getTextRuns() {
+        return _runs;
+    }
+
+    /**
+     * Delegate the call to the underlying slide master.
+     */
+    public TextProp getStyleAttribute(int txtype, int level, String name, boolean isCharacter) {
+        MasterSheet master = getMasterSheet();
+        return master == null ? null : master.getStyleAttribute(txtype, level, name, isCharacter);
+    }
+
+    /**
+     * Returns the slide master for this title master.
+     */
+    public MasterSheet getMasterSheet(){
+        SlideMaster[] master = getSlideShow().getSlidesMasters();
+        SlideAtom sa = ((org.apache.poi.hslf.record.Slide)getSheetContainer()).getSlideAtom();
+        int masterId = sa.getMasterID();
+        for (int i = 0; i < master.length; i++) {
+            if (masterId == master[i]._getSheetNumber()) return master[i];
+        }
+        return null;
+    }
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/ParagraphFlagsTextProp.java Thu May 21 18:12:22 2009
@@ -1,41 +1,41 @@
-/* ====================================================================
-   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.textproperties;
-
-/** 
- * Definition for the common paragraph text property bitset.
- *
- * @author Yegor Kozlov
- */
-public class ParagraphFlagsTextProp extends BitMaskTextProp {
-	public static final int BULLET_IDX = 0;
-	public static final int BULLET_HARDFONT_IDX = 1;
-	public static final int BULLET_HARDCOLOR_IDX = 2;
-	public static final int BULLET_HARDSIZE_IDX = 4;
-
-    public static String NAME = "paragraph_flags";
-
-	public ParagraphFlagsTextProp() {
-		super(2,  0xF, NAME, new String[] {
-					"bullet",
-                    "bullet.hardfont",
-					"bullet.hardcolor",
-                    "bullet.hardsize"}
-		);
-	}
-}
\ No newline at end of file
+/* ====================================================================
+   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.textproperties;
+
+/**
+ * Definition for the common paragraph text property bitset.
+ *
+ * @author Yegor Kozlov
+ */
+public final class ParagraphFlagsTextProp extends BitMaskTextProp {
+	public static final int BULLET_IDX = 0;
+	public static final int BULLET_HARDFONT_IDX = 1;
+	public static final int BULLET_HARDCOLOR_IDX = 2;
+	public static final int BULLET_HARDSIZE_IDX = 4;
+
+    public static String NAME = "paragraph_flags";
+
+	public ParagraphFlagsTextProp() {
+		super(2,  0xF, NAME, new String[] {
+					"bullet",
+                    "bullet.hardfont",
+					"bullet.hardcolor",
+                    "bullet.hardsize"}
+		);
+	}
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfo.java Thu May 21 18:12:22 2009
@@ -1,97 +1,98 @@
-/*
-* 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.record;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
-
-/**
- * A container record that specifies information about animation information for a shape.
- *
- * @author Yegor Kozlov
- */
-public class AnimationInfo extends RecordContainer {
-	private byte[] _header;
-
-	// Links to our more interesting children
-	private AnimationInfoAtom animationAtom;
-
-	/**
-	 * Set things up, and find our more interesting children
-	 */
-	protected AnimationInfo(byte[] source, int start, int len) {
-		// Grab the header
-		_header = new byte[8];
-		System.arraycopy(source,start,_header,0,8);
-
-		// Find our children
-		_children = Record.findChildRecords(source,start+8,len-8);
-		findInterestingChildren();
-	}
-
-	/**
-	 * Go through our child records, picking out the ones that are
-	 *  interesting, and saving those for use by the easy helper
-	 *  methods.
-	 */	
-	private void findInterestingChildren() {
-
-		// First child should be the ExMediaAtom
-		if(_children[0] instanceof AnimationInfoAtom) {
-			animationAtom = (AnimationInfoAtom)_children[0];
-		} else {
-			logger.log(POILogger.ERROR, "First child record wasn't a AnimationInfoAtom, was of type " + _children[0].getRecordType());
-		}
-	}
-
-	/**
-	 * Create a new AnimationInfo, with blank fields
-	 */
-	public AnimationInfo() {
-        // Setup our header block
-		_header = new byte[8];
-		_header[0] = 0x0f; // We are a container record
-		LittleEndian.putShort(_header, 2, (short)getRecordType());
-		
-        _children = new Record[1];
-		_children[0] = animationAtom = new AnimationInfoAtom();
-	}
-
-	/**
-	 * We are of type 4103
-	 */
-	public long getRecordType() { return RecordTypes.AnimationInfo.typeID; }
-
-	/**
-	 * Write the contents of the record back, so it can be written
-	 *  to disk
-	 */
-	public void writeOut(OutputStream out) throws IOException {
-		writeOut(_header[0],_header[1],getRecordType(),_children,out);
-	}
-
-    /**
-     * Returns the AnimationInfo
-     */
-    public AnimationInfoAtom getAnimationInfoAtom() {
-        return animationAtom;
-    }
-
-}
+/* ====================================================================
+   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.record;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+
+/**
+ * A container record that specifies information about animation information for a shape.
+ *
+ * @author Yegor Kozlov
+ */
+public final class AnimationInfo extends RecordContainer {
+	private byte[] _header;
+
+	// Links to our more interesting children
+	private AnimationInfoAtom animationAtom;
+
+	/**
+	 * Set things up, and find our more interesting children
+	 */
+	protected AnimationInfo(byte[] source, int start, int len) {
+		// Grab the header
+		_header = new byte[8];
+		System.arraycopy(source,start,_header,0,8);
+
+		// Find our children
+		_children = Record.findChildRecords(source,start+8,len-8);
+		findInterestingChildren();
+	}
+
+	/**
+	 * Go through our child records, picking out the ones that are
+	 *  interesting, and saving those for use by the easy helper
+	 *  methods.
+	 */
+	private void findInterestingChildren() {
+
+		// First child should be the ExMediaAtom
+		if(_children[0] instanceof AnimationInfoAtom) {
+			animationAtom = (AnimationInfoAtom)_children[0];
+		} else {
+			logger.log(POILogger.ERROR, "First child record wasn't a AnimationInfoAtom, was of type " + _children[0].getRecordType());
+		}
+	}
+
+	/**
+	 * Create a new AnimationInfo, with blank fields
+	 */
+	public AnimationInfo() {
+        // Setup our header block
+		_header = new byte[8];
+		_header[0] = 0x0f; // We are a container record
+		LittleEndian.putShort(_header, 2, (short)getRecordType());
+
+        _children = new Record[1];
+		_children[0] = animationAtom = new AnimationInfoAtom();
+	}
+
+	/**
+	 * We are of type 4103
+	 */
+	public long getRecordType() { return RecordTypes.AnimationInfo.typeID; }
+
+	/**
+	 * Write the contents of the record back, so it can be written
+	 *  to disk
+	 */
+	public void writeOut(OutputStream out) throws IOException {
+		writeOut(_header[0],_header[1],getRecordType(),_children,out);
+	}
+
+    /**
+     * Returns the AnimationInfo
+     */
+    public AnimationInfoAtom getAnimationInfoAtom() {
+        return animationAtom;
+    }
+
+}

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java?rev=777204&r1=777203&r2=777204&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/AnimationInfoAtom.java Thu May 21 18:12:22 2009
@@ -1,278 +1,277 @@
-/* ====================================================================
-   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.record;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Date;
-
-import org.apache.poi.hslf.util.SystemTimeUtils;
-import org.apache.poi.util.LittleEndian;
-
-/**
- * An atom record that specifies the animation information for a shape.
- *
- * @author Yegor Kozlov
- */
-public class AnimationInfoAtom extends RecordAtom
-{
-
-    /**
-     * whether the animation plays in the reverse direction
-     */
-    public static final int Reverse = 1;
-    /**
-     * whether the animation starts automatically
-     */
-    public static final int Automatic = 4;
-    /**
-     * whether the animation has an associated sound
-     */
-    public static final int Sound = 16;
-    /**
-     * whether all playing sounds are stopped when this animation begins
-     */
-    public static final int StopSound = 64;
-    /**
-     * whether an associated sound, media or action verb is activated when the shape is clicked.
-     */
-    public static final int Play = 256;
-    /**
-     * specifies that the animation, while playing, stops other slide show actions.
-     */
-    public static final int Synchronous = 1024;
-    /**
-     * whether the shape is hidden while the animation is not playing
-     */
-    public static final int Hide = 4096;
-    /**
-     * whether the background of the shape is animated
-     */
-    public static final int AnimateBg = 16384;
-
-    /**
-     * Record header.
-     */
-    private byte[] _header;
-
-    /**
-     * record data
-     */
-    private byte[] _recdata;
-
-    /**
-     * Constructs a brand new link related atom record.
-     */
-    protected AnimationInfoAtom() {
-        _recdata = new byte[28];
-
-        _header = new byte[8];
-        LittleEndian.putShort(_header, 0, (short)0x01);
-        LittleEndian.putShort(_header, 2, (short)getRecordType());
-        LittleEndian.putInt(_header, 4, _recdata.length);
-    }
-
-    /**
-     * Constructs the link related atom record from its
-     *  source data.
-     *
-     * @param source the source data as a byte array.
-     * @param start the start offset into the byte array.
-     * @param len the length of the slice in the byte array.
-     */
-    protected AnimationInfoAtom(byte[] source, int start, int len) {
-        // Get the header
-        _header = new byte[8];
-        System.arraycopy(source,start,_header,0,8);
-
-        // Grab the record data
-        _recdata = new byte[len-8];
-        System.arraycopy(source,start+8,_recdata,0,len-8);
-    }
-
-    /**
-     * Gets the record type.
-     * @return the record type.
-     */
-    public long getRecordType() {
-        return RecordTypes.AnimationInfoAtom.typeID;
-    }
-
-    /**
-     * Write the contents of the record back, so it can be written
-     * to disk
-     *
-     * @param out the output stream to write to.
-     * @throws java.io.IOException if an error occurs.
-     */
-    public void writeOut(OutputStream out) throws IOException {
-        out.write(_header);
-        out.write(_recdata);
-    }
-
-    /**
-     * A rgb structure that specifies a color for the dim effect after the animation is complete.
-     *
-     * @return  color for the dim effect after the animation is complete
-     */
-    public int getDimColor(){
-        return LittleEndian.getInt(_recdata, 0);
-    }
-
-    /**
-     * A rgb structure that specifies a color for the dim effect after the animation is complete.
-     *
-     * @param rgb  color for the dim effect after the animation is complete
-     */
-    public void setDimColor(int rgb){
-         LittleEndian.putInt(_recdata, 0, rgb);
-    }
-
-    /**
-     *  A bit mask specifying options for displaying headers and footers
-     *
-     * @return A bit mask specifying options for displaying headers and footers
-     */
-    public int getMask(){
-        return LittleEndian.getInt(_recdata, 4);
-    }
-
-    /**
-     *  A bit mask specifying options for displaying video
-     *
-     * @param mask A bit mask specifying options for displaying video
-     */
-    public void setMask(int mask){
-        LittleEndian.putInt(_recdata, 4, mask);
-    }
-
-    /**
-     * @param bit the bit to check
-     * @return whether the specified flag is set
-     */
-    public boolean getFlag(int bit){
-        return (getMask() & bit) != 0;
-    }
-
-    /**
-     * @param  bit the bit to set
-     * @param  value whether the specified bit is set
-     */
-    public void setFlag(int bit, boolean value){
-        int mask = getMask();
-        if(value) mask |= bit;
-        else mask &= ~bit;
-        setMask(mask);
-    }
-
-    /**
-     * A 4-byte unsigned integer that specifies a reference to a sound
-     * in the SoundCollectionContainer record to locate the embedded audio
-     *
-     * @return  reference to a sound
-     */
-    public int getSoundIdRef(){
-        return LittleEndian.getInt(_recdata, 8);
-    }
-
-    /**
-     * A 4-byte unsigned integer that specifies a reference to a sound
-     * in the SoundCollectionContainer record to locate the embedded audio
-     *
-     * @param id reference to a sound
-     */
-    public void setSoundIdRef(int id){
-         LittleEndian.putInt(_recdata, 8, id);
-    }
-
-    /**
-     * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
-     * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
-     */
-    public int getDelayTime(){
-        return LittleEndian.getInt(_recdata, 12);
-    }
-    /**
-     * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
-     * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
-     */
-    public void setDelayTime(int id){
-         LittleEndian.putInt(_recdata, 12, id);
-    }
-
-    /**
-     * A signed integer that specifies the order of the animation in the slide.
-     * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
-     * the corresponding placeholder shape on the main master slide or title master slide.
-     * The value -1 SHOULD NOT <105> be used.
-     */
-    public int getOrderID(){
-        return LittleEndian.getInt(_recdata, 16);
-    }
-
-    /**
-     * A signed integer that specifies the order of the animation in the slide.
-     * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
-     * the corresponding placeholder shape on the main master slide or title master slide.
-     * The value -1 SHOULD NOT <105> be used.
-     */
-    public void setOrderID(int id){
-         LittleEndian.putInt(_recdata, 16, id);
-    }
-
-    /**
-     * An unsigned integer that specifies the number of slides that this animation continues playing.
-     * This field is utilized only in conjunction with media.
-     * The value 0xFFFFFFFF specifies that the animation plays for one slide.
-     */
-    public int getSlideCount(){
-        return LittleEndian.getInt(_recdata, 18);
-    }
-
-    /**
-     * An unsigned integer that specifies the number of slides that this animation continues playing.
-     * This field is utilized only in conjunction with media.
-     * The value 0xFFFFFFFF specifies that the animation plays for one slide.
-     */
-    public void setSlideCount(int id){
-         LittleEndian.putInt(_recdata, 18, id);
-    }
-
-    public String toString(){
-        StringBuffer buf = new StringBuffer();
-        buf.append("AnimationInfoAtom\n");
-        buf.append("\tDimColor: " + getDimColor() + "\n");
-        int mask = getMask();
-        buf.append("\tMask: " + mask + ", 0x"+Integer.toHexString(mask)+"\n");
-        buf.append("\t  Reverse: " + getFlag(Reverse)+"\n");
-        buf.append("\t  Automatic: " + getFlag(Automatic)+"\n");
-        buf.append("\t  Sound: " + getFlag(Sound)+"\n");
-        buf.append("\t  StopSound: " + getFlag(StopSound)+"\n");
-        buf.append("\t  Play: " + getFlag(Play)+"\n");
-        buf.append("\t  Synchronous: " + getFlag(Synchronous)+"\n");
-        buf.append("\t  Hide: " + getFlag(Hide)+"\n");
-        buf.append("\t  AnimateBg: " + getFlag(AnimateBg)+"\n");
-        buf.append("\tSoundIdRef: " + getSoundIdRef() + "\n");
-        buf.append("\tDelayTime: " + getDelayTime() + "\n");
-        buf.append("\tOrderID: " + getOrderID() + "\n");
-        buf.append("\tSlideCount: " + getSlideCount() + "\n");
-        return buf.toString();
-    }
-
-}
+/* ====================================================================
+   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.record;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Date;
+
+import org.apache.poi.hslf.util.SystemTimeUtils;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * An atom record that specifies the animation information for a shape.
+ *
+ * @author Yegor Kozlov
+ */
+public final class AnimationInfoAtom extends RecordAtom
+{
+
+    /**
+     * whether the animation plays in the reverse direction
+     */
+    public static final int Reverse = 1;
+    /**
+     * whether the animation starts automatically
+     */
+    public static final int Automatic = 4;
+    /**
+     * whether the animation has an associated sound
+     */
+    public static final int Sound = 16;
+    /**
+     * whether all playing sounds are stopped when this animation begins
+     */
+    public static final int StopSound = 64;
+    /**
+     * whether an associated sound, media or action verb is activated when the shape is clicked.
+     */
+    public static final int Play = 256;
+    /**
+     * specifies that the animation, while playing, stops other slide show actions.
+     */
+    public static final int Synchronous = 1024;
+    /**
+     * whether the shape is hidden while the animation is not playing
+     */
+    public static final int Hide = 4096;
+    /**
+     * whether the background of the shape is animated
+     */
+    public static final int AnimateBg = 16384;
+
+    /**
+     * Record header.
+     */
+    private byte[] _header;
+
+    /**
+     * record data
+     */
+    private byte[] _recdata;
+
+    /**
+     * Constructs a brand new link related atom record.
+     */
+    protected AnimationInfoAtom() {
+        _recdata = new byte[28];
+
+        _header = new byte[8];
+        LittleEndian.putShort(_header, 0, (short)0x01);
+        LittleEndian.putShort(_header, 2, (short)getRecordType());
+        LittleEndian.putInt(_header, 4, _recdata.length);
+    }
+
+    /**
+     * Constructs the link related atom record from its
+     *  source data.
+     *
+     * @param source the source data as a byte array.
+     * @param start the start offset into the byte array.
+     * @param len the length of the slice in the byte array.
+     */
+    protected AnimationInfoAtom(byte[] source, int start, int len) {
+        // Get the header
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Grab the record data
+        _recdata = new byte[len-8];
+        System.arraycopy(source,start+8,_recdata,0,len-8);
+    }
+
+    /**
+     * Gets the record type.
+     * @return the record type.
+     */
+    public long getRecordType() {
+        return RecordTypes.AnimationInfoAtom.typeID;
+    }
+
+    /**
+     * Write the contents of the record back, so it can be written
+     * to disk
+     *
+     * @param out the output stream to write to.
+     * @throws java.io.IOException if an error occurs.
+     */
+    public void writeOut(OutputStream out) throws IOException {
+        out.write(_header);
+        out.write(_recdata);
+    }
+
+    /**
+     * A rgb structure that specifies a color for the dim effect after the animation is complete.
+     *
+     * @return  color for the dim effect after the animation is complete
+     */
+    public int getDimColor(){
+        return LittleEndian.getInt(_recdata, 0);
+    }
+
+    /**
+     * A rgb structure that specifies a color for the dim effect after the animation is complete.
+     *
+     * @param rgb  color for the dim effect after the animation is complete
+     */
+    public void setDimColor(int rgb){
+         LittleEndian.putInt(_recdata, 0, rgb);
+    }
+
+    /**
+     *  A bit mask specifying options for displaying headers and footers
+     *
+     * @return A bit mask specifying options for displaying headers and footers
+     */
+    public int getMask(){
+        return LittleEndian.getInt(_recdata, 4);
+    }
+
+    /**
+     *  A bit mask specifying options for displaying video
+     *
+     * @param mask A bit mask specifying options for displaying video
+     */
+    public void setMask(int mask){
+        LittleEndian.putInt(_recdata, 4, mask);
+    }
+
+    /**
+     * @param bit the bit to check
+     * @return whether the specified flag is set
+     */
+    public boolean getFlag(int bit){
+        return (getMask() & bit) != 0;
+    }
+
+    /**
+     * @param  bit the bit to set
+     * @param  value whether the specified bit is set
+     */
+    public void setFlag(int bit, boolean value){
+        int mask = getMask();
+        if(value) mask |= bit;
+        else mask &= ~bit;
+        setMask(mask);
+    }
+
+    /**
+     * A 4-byte unsigned integer that specifies a reference to a sound
+     * in the SoundCollectionContainer record to locate the embedded audio
+     *
+     * @return  reference to a sound
+     */
+    public int getSoundIdRef(){
+        return LittleEndian.getInt(_recdata, 8);
+    }
+
+    /**
+     * A 4-byte unsigned integer that specifies a reference to a sound
+     * in the SoundCollectionContainer record to locate the embedded audio
+     *
+     * @param id reference to a sound
+     */
+    public void setSoundIdRef(int id){
+         LittleEndian.putInt(_recdata, 8, id);
+    }
+
+    /**
+     * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
+     * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
+     */
+    public int getDelayTime(){
+        return LittleEndian.getInt(_recdata, 12);
+    }
+    /**
+     * A signed integer that specifies the delay time, in milliseconds, before the animation starts to play.
+     * If {@link #Automatic} is 0x1, this value MUST be greater than or equal to 0; otherwise, this field MUST be ignored.
+     */
+    public void setDelayTime(int id){
+         LittleEndian.putInt(_recdata, 12, id);
+    }
+
+    /**
+     * A signed integer that specifies the order of the animation in the slide.
+     * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
+     * the corresponding placeholder shape on the main master slide or title master slide.
+     * The value -1 SHOULD NOT <105> be used.
+     */
+    public int getOrderID(){
+        return LittleEndian.getInt(_recdata, 16);
+    }
+
+    /**
+     * A signed integer that specifies the order of the animation in the slide.
+     * It MUST be greater than or equal to -2. The value -2 specifies that this animation follows the order of
+     * the corresponding placeholder shape on the main master slide or title master slide.
+     * The value -1 SHOULD NOT <105> be used.
+     */
+    public void setOrderID(int id){
+         LittleEndian.putInt(_recdata, 16, id);
+    }
+
+    /**
+     * An unsigned integer that specifies the number of slides that this animation continues playing.
+     * This field is utilized only in conjunction with media.
+     * The value 0xFFFFFFFF specifies that the animation plays for one slide.
+     */
+    public int getSlideCount(){
+        return LittleEndian.getInt(_recdata, 18);
+    }
+
+    /**
+     * An unsigned integer that specifies the number of slides that this animation continues playing.
+     * This field is utilized only in conjunction with media.
+     * The value 0xFFFFFFFF specifies that the animation plays for one slide.
+     */
+    public void setSlideCount(int id){
+         LittleEndian.putInt(_recdata, 18, id);
+    }
+
+    public String toString(){
+        StringBuffer buf = new StringBuffer();
+        buf.append("AnimationInfoAtom\n");
+        buf.append("\tDimColor: " + getDimColor() + "\n");
+        int mask = getMask();
+        buf.append("\tMask: " + mask + ", 0x"+Integer.toHexString(mask)+"\n");
+        buf.append("\t  Reverse: " + getFlag(Reverse)+"\n");
+        buf.append("\t  Automatic: " + getFlag(Automatic)+"\n");
+        buf.append("\t  Sound: " + getFlag(Sound)+"\n");
+        buf.append("\t  StopSound: " + getFlag(StopSound)+"\n");
+        buf.append("\t  Play: " + getFlag(Play)+"\n");
+        buf.append("\t  Synchronous: " + getFlag(Synchronous)+"\n");
+        buf.append("\t  Hide: " + getFlag(Hide)+"\n");
+        buf.append("\t  AnimateBg: " + getFlag(AnimateBg)+"\n");
+        buf.append("\tSoundIdRef: " + getSoundIdRef() + "\n");
+        buf.append("\tDelayTime: " + getDelayTime() + "\n");
+        buf.append("\tOrderID: " + getOrderID() + "\n");
+        buf.append("\tSlideCount: " + getSlideCount() + "\n");
+        return buf.toString();
+    }
+
+}



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