You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2008/04/30 08:29:12 UTC

svn commit: r652298 - in /poi/trunk/src/scratchpad: src/org/apache/poi/hslf/model/ src/org/apache/poi/hslf/record/ src/org/apache/poi/hslf/usermodel/ testcases/org/apache/poi/hslf/model/ testcases/org/apache/poi/hslf/record/ testcases/org/apache/poi/hs...

Author: yegor
Date: Tue Apr 29 23:29:11 2008
New Revision: 652298

URL: http://svn.apache.org/viewvc?rev=652298&view=rev
Log:
more work on rendering ppt slides

Added:
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java   (with props)
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java   (with props)
Modified:
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextPainter.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/AutoShapes.java Tue Apr 29 23:29:11 2008
@@ -369,5 +369,12 @@
             }
         };
 
+        shapes[ShapeTypes.StraightConnector1] = new ShapeOutline(){
+            public java.awt.Shape getOutline(Shape shape){
+                return new Line2D.Float(0, 0, 21600, 21600);
+            }
+        };
+
+
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Freeform.java Tue Apr 29 23:29:11 2008
@@ -19,6 +19,7 @@
 import org.apache.poi.ddf.*;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.HexDump;
 
 import java.awt.geom.*;
 import java.util.ArrayList;
@@ -185,10 +186,6 @@
             return null;
         }
 
-        Rectangle2D bounds = getAnchor2D();
-        float right = (float)bounds.getX();
-        float bottom = (float)bounds.getY();
-
         GeneralPath path = new GeneralPath();
         int numPoints = verticesProp.getNumberOfElementsInArray();
         int numSegments = segmentsProp.getNumberOfElementsInArray();
@@ -199,8 +196,8 @@
                 short x = LittleEndian.getShort(p, 0);
                 short y = LittleEndian.getShort(p, 2);
                 path.moveTo(
-                        ((float)x*POINT_DPI/MASTER_DPI + right),
-                        ((float)y*POINT_DPI/MASTER_DPI + bottom));
+                        ((float)x*POINT_DPI/MASTER_DPI),
+                        ((float)y*POINT_DPI/MASTER_DPI));
             } else if (Arrays.equals(elem, SEGMENTINFO_CUBICTO) || Arrays.equals(elem, SEGMENTINFO_CUBICTO2)){
                 i++;
                 byte[] p1 = verticesProp.getElement(j++);
@@ -213,9 +210,9 @@
                 short x3 = LittleEndian.getShort(p3, 0);
                 short y3 = LittleEndian.getShort(p3, 2);
                 path.curveTo(
-                        ((float)x1*POINT_DPI/MASTER_DPI + right), ((float)y1*POINT_DPI/MASTER_DPI + bottom),
-                        ((float)x2*POINT_DPI/MASTER_DPI + right), ((float)y2*POINT_DPI/MASTER_DPI + bottom),
-                        ((float)x3*POINT_DPI/MASTER_DPI + right), ((float)y3*POINT_DPI/MASTER_DPI + bottom));
+                        ((float)x1*POINT_DPI/MASTER_DPI), ((float)y1*POINT_DPI/MASTER_DPI),
+                        ((float)x2*POINT_DPI/MASTER_DPI), ((float)y2*POINT_DPI/MASTER_DPI),
+                        ((float)x3*POINT_DPI/MASTER_DPI), ((float)y3*POINT_DPI/MASTER_DPI));
 
             } else if (Arrays.equals(elem, SEGMENTINFO_LINETO)){
                 i++;
@@ -226,18 +223,26 @@
                         short x = LittleEndian.getShort(p, 0);
                         short y = LittleEndian.getShort(p, 2);
                         path.lineTo(
-                                ((float)x*POINT_DPI/MASTER_DPI + right), ((float)y*POINT_DPI/MASTER_DPI + bottom));
+                                ((float)x*POINT_DPI/MASTER_DPI), ((float)y*POINT_DPI/MASTER_DPI));
                     }
                 } else if (Arrays.equals(pnext, SEGMENTINFO_CLOSE)){
                     path.closePath();
                 }
             }
         }
-
         return path;
     }
 
     public java.awt.Shape getOutline(){
-        return getPath();
+        GeneralPath path =  getPath();
+        Rectangle2D anchor = getAnchor2D();
+        Rectangle2D bounds = path.getBounds2D();
+        AffineTransform at = new AffineTransform();
+        at.translate(anchor.getX(), anchor.getY());
+        at.scale(
+                anchor.getWidth()/bounds.getWidth(),
+                anchor.getHeight()/bounds.getHeight()
+        );
+        return at.createTransformedShape(path);
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MasterSheet.java Tue Apr 29 23:29:11 2008
@@ -67,4 +67,21 @@
         }
         return false;
     }
+
+    /**
+     * Return placeholder by text type
+     */
+    public TextShape getPlaceholder(int type){
+        Shape[] shape = getShapes();
+        for (int i = 0; i < shape.length; i++) {
+            if(shape[i] instanceof TextShape){
+                TextShape tx = (TextShape)shape[i];
+                TextRun run = tx.getTextRun();
+                if(run != null && run.getRunType() == type){
+                    return tx;
+                }
+            }
+        }
+        return null;
+    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Picture.java Tue Apr 29 23:29:11 2008
@@ -28,6 +28,7 @@
 import java.awt.image.BufferedImage;
 import java.awt.*;
 import java.awt.geom.Rectangle2D;
+import java.awt.geom.AffineTransform;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -244,6 +245,9 @@
     }
 
     public void draw(Graphics2D graphics){
+        AffineTransform at = graphics.getTransform();
+        ShapePainter.paint(this, graphics);
+
         PictureData data = getPictureData();
         if (data  instanceof Bitmap){
             BufferedImage img = null;
@@ -260,5 +264,6 @@
         } else {
             logger.log(POILogger.WARN, "Rendering of metafiles is not yet supported. image.type: " + (data == null ? "NA" : data.getClass().getName()));
         }
+        graphics.setTransform(at);
     }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java Tue Apr 29 23:29:11 2008
@@ -341,58 +341,7 @@
      * @param sh - owning shape
      */
     protected void afterInsert(Sheet sh){
-        PPDrawing ppdrawing = sh.getPPDrawing();
 
-        EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
-
-        EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
-
-        int id = allocateShapeId(dg);
-        setShapeId(id);
-    }
-
-    /**
-     * Allocates new shape id for the new drawing group id.
-     *
-     * @param dg  EscherDgRecord of the sheet that owns the shape being created
-     *
-     * @return a new shape id.
-     */
-    protected int allocateShapeId(EscherDgRecord dg)
-    {
-        EscherDggRecord dgg = _sheet.getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
-        if(dgg == null){
-            logger.log(POILogger.ERROR, "EscherDggRecord not found");
-            return 0;
-        }
-
-        dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
-
-        // Add to existing cluster if space available
-        for (int i = 0; i < dgg.getFileIdClusters().length; i++)
-        {
-            EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
-            if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
-            {
-                int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
-                c.incrementShapeId();
-                dg.setNumShapes( dg.getNumShapes() + 1 );
-                dg.setLastMSOSPID( result );
-                if (result >= dgg.getShapeIdMax())
-                    dgg.setShapeIdMax( result + 1 );
-                return result;
-            }
-        }
-
-        // Create new cluster
-        dgg.addCluster( dg.getDrawingGroupId(), 0 );
-        dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
-        dg.setNumShapes( dg.getNumShapes() + 1 );
-        int result = (1024 * dgg.getFileIdClusters().length);
-        dg.setLastMSOSPID( result );
-        if (result >= dgg.getShapeIdMax())
-            dgg.setShapeIdMax( result + 1 );
-        return result;
     }
 
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java Tue Apr 29 23:29:11 2008
@@ -196,13 +196,8 @@
 
         Sheet sheet = getSheet();
         shape.setSheet(sheet);
+        shape.setShapeId(sheet.allocateShapeId());
         shape.afterInsert(sheet);
-
-        if (shape instanceof TextShape) {
-            TextShape tbox = (TextShape) shape;
-            EscherTextboxWrapper txWrapper = tbox.getEscherTextboxWrapper();
-            if(txWrapper != null) getSheet().getPPDrawing().addTextboxWrapper(txWrapper);
-        }
     }
 
     /**
@@ -277,20 +272,9 @@
     }
 
     public void draw(Graphics2D graphics){
-        Rectangle2D anchor = getAnchor2D();
-        Rectangle2D coords = getCoordinates();
 
-        //transform coordinates
         AffineTransform at = graphics.getTransform();
-        /*
-        if(!anchor.equals(coords)){
-            graphics.scale(anchor.getWidth()/coords.getWidth(), anchor.getHeight()/coords.getHeight());
-
-            graphics.translate(
-                    anchor.getX()*coords.getWidth()/anchor.getWidth() - coords.getX(),
-                    anchor.getY()*coords.getHeight()/anchor.getHeight() - coords.getY());
-        }
-        */
+
         Shape[] sh = getShapes();
         for (int i = 0; i < sh.length; i++) {
             sh[i].draw(graphics);

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java Tue Apr 29 23:29:11 2008
@@ -18,12 +18,10 @@
 
 package org.apache.poi.hslf.model;
 
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherDgRecord;
-import org.apache.poi.ddf.EscherRecord;
-import org.apache.poi.ddf.EscherSpRecord;
+import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.record.*;
 import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.util.POILogger;
 
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -248,15 +246,47 @@
         spgr.addChildRecord(shape.getSpContainer());
 
         shape.setSheet(this);
+        shape.setShapeId(allocateShapeId());
         shape.afterInsert(this);
+    }
 
-        // If it's a TextShape, we need to tell the PPDrawing, as it has to
-        //  track TextboxWrappers specially
-        if (shape instanceof TextShape) {
-            TextShape tbox = (TextShape) shape;
-            EscherTextboxWrapper txWrapper = tbox.getEscherTextboxWrapper();
-            if(txWrapper != null) ppdrawing.addTextboxWrapper(txWrapper);
+    /**
+     * Allocates new shape id for the new drawing group id.
+     *
+     * @return a new shape id.
+     */
+    public int allocateShapeId()
+    {
+        EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
+
+        dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
+
+        // Add to existing cluster if space available
+        for (int i = 0; i < dgg.getFileIdClusters().length; i++)
+        {
+            EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
+            if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
+            {
+                int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
+                c.incrementShapeId();
+                dg.setNumShapes( dg.getNumShapes() + 1 );
+                dg.setLastMSOSPID( result );
+                if (result >= dgg.getShapeIdMax())
+                    dgg.setShapeIdMax( result + 1 );
+                return result;
+            }
         }
+
+        // Create new cluster
+        dgg.addCluster( dg.getDrawingGroupId(), 0, false );
+        dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
+        dg.setNumShapes( dg.getNumShapes() + 1 );
+        int result = (1024 * dgg.getFileIdClusters().length);
+        dg.setLastMSOSPID( result );
+        if (result >= dgg.getShapeIdMax())
+            dgg.setShapeIdMax( result + 1 );
+        return result;
     }
 
     /**
@@ -285,6 +315,13 @@
     }
 
     /**
+     * Called by SlideShow ater a new sheet is created
+     */
+    public void onCreate(){
+
+    }
+
+    /**
      * Return the master sheet .
      */
     public abstract MasterSheet getMasterSheet();

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SimpleShape.java Tue Apr 29 23:29:11 2008
@@ -126,8 +126,8 @@
         EscherSimpleProperty p2 = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.LINESTYLE__NOLINEDRAWDASH);
         int p2val = p2 == null ? 0 : p2.getPropertyValue();
         Color clr = null;
-        if (p1 != null && (p2val  & 0x8) != 0){
-            int rgb = p1.getPropertyValue();
+        if ((p2val  & 0x8) != 0 || (p2val  & 0x10) != 0){
+            int rgb = p1 == null ? 0 : p1.getPropertyValue();
             if (rgb >= 0x8000000) {
                 int idx = rgb % 0x8000000;
                 if(getSheet() != null) {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Slide.java Tue Apr 29 23:29:11 2008
@@ -21,12 +21,17 @@
 package org.apache.poi.hslf.model;
 
 import java.util.Vector;
+import java.util.Iterator;
 import java.awt.*;
 
 import org.apache.poi.hslf.record.SlideAtom;
 import org.apache.poi.hslf.record.TextHeaderAtom;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
 import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
+import org.apache.poi.ddf.EscherDggRecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherDgRecord;
+import org.apache.poi.ddf.EscherSpRecord;
 
 /**
  * This class represents a slide in a PowerPoint Document. It allows 
@@ -126,6 +131,42 @@
 		_slideNo = newSlideNumber;
 	}
   
+    /**
+     * Called by SlideShow ater a new slide is created.
+     * <p>
+     * For Slide we need to do the following:
+     *  <li> set id of the drawing group.
+     *  <li> set shapeId for the container descriptor and background
+     * </p>
+     */
+    public void onCreate(){
+        //initialize drawing group id
+        EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherContainerRecord dgContainer = (EscherContainerRecord)getSheetContainer().getPPDrawing().getEscherRecords()[0];
+        EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
+        int dgId = dgg.getMaxDrawingGroupId() + 1;
+        dg.setOptions((short)(dgId << 4));
+        dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
+
+        for (Iterator it = dgContainer.getChildContainers().iterator(); it.hasNext(); ) {
+            EscherContainerRecord c = (EscherContainerRecord)it.next();
+            EscherSpRecord spr = null;
+            switch(c.getRecordId()){
+                case EscherContainerRecord.SPGR_CONTAINER:
+                    EscherContainerRecord dc = (EscherContainerRecord)c.getChildRecords().get(0);
+                    spr = dc.getChildById(EscherSpRecord.RECORD_ID);
+                    break;
+                case EscherContainerRecord.SP_CONTAINER:
+                    spr = c.getChildById(EscherSpRecord.RECORD_ID);
+                    break;
+            }
+            if(spr != null) spr.setShapeId(allocateShapeId());
+        }
+
+        //PPT doen't increment the number of saved shapes for group descriptor and background 
+        dg.setNumShapes(1);
+    }
+
 	/**
 	 * Create a <code>TextBox</code> object that represents the slide's title.
 	 *

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/SlideMaster.java Tue Apr 29 23:29:11 2008
@@ -92,6 +92,7 @@
             } else {
                 switch (txtype) {
                     case TextHeaderAtom.CENTRE_BODY_TYPE:
+                    case TextHeaderAtom.HALF_BODY_TYPE:
                     case TextHeaderAtom.QUARTER_BODY_TYPE:
                         txtype = TextHeaderAtom.BODY_TYPE;
                         break;

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=652298&r1=652297&r2=652298&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 Tue Apr 29 23:29:11 2008
@@ -17,6 +17,7 @@
 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;
 
@@ -38,6 +39,13 @@
 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){
@@ -49,6 +57,10 @@
      */
     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++) {
@@ -109,7 +121,24 @@
             }
 
             float wrappingWidth = (float)anchor.getWidth() - _shape.getMarginLeft() - _shape.getMarginRight();
-            wrappingWidth -= rt.getTextOffset();
+            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;
+            }
+
+            wrappingWidth -= textOffset;
 
             if (_shape.getWordWrap() == TextShape.WrapNone) {
                 wrappingWidth = _shape.getSheet().getSlideShow().getPageSize().width;
@@ -141,8 +170,9 @@
             }
 
             el._align = rt.getAlignment();
-            el._text = textLayout;
-            el._textOffset = rt.getTextOffset();
+            el.advance = textLayout.getAdvance();
+            el._textOffset = textOffset;
+            el._text = new AttributedString(it, startIndex, endIndex);
 
             if (prStart){
                 int sp = rt.getSpaceBefore();
@@ -182,13 +212,25 @@
                 Color clr = rt.getBulletColor();
                 if (clr != null) bat.addAttribute(TextAttribute.FOREGROUND, clr);
                 else bat.addAttribute(TextAttribute.FOREGROUND, it.getAttribute(TextAttribute.FOREGROUND));
-                bat.addAttribute(TextAttribute.FAMILY, it.getAttribute(TextAttribute.FAMILY));
-                bat.addAttribute(TextAttribute.SIZE, it.getAttribute(TextAttribute.SIZE));
 
-                TextLayout bulletLayout = new TextLayout(bat.getIterator(), graphics.getFontRenderContext());
+                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 = bulletLayout;
-                    el._bulletOffset = rt.getBulletOffset();
+                    el._bullet = bat;
+                    el._bulletOffset = bulletOffset;
                 }
             }
             lines.add(el);
@@ -225,29 +267,32 @@
                     break;
                 case TextShape.AlignCenter:
                     pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem._text.getAdvance() - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
+                            (anchor.getWidth() - elem.advance - _shape.getMarginLeft() - _shape.getMarginRight()) / 2;
                     break;
                 case TextShape.AlignRight:
                     pen.x = anchor.getX() + _shape.getMarginLeft() +
-                            (anchor.getWidth() - elem._text.getAdvance() - _shape.getMarginLeft() - _shape.getMarginRight());
+                            (anchor.getWidth() - elem.advance - _shape.getMarginLeft() - _shape.getMarginRight());
                     break;
             }
             if(elem._bullet != null){
-                elem._bullet.draw(graphics, (float)(pen.x + elem._bulletOffset), (float)pen.y);
+                graphics.drawString(elem._bullet.getIterator(), (float)(pen.x + elem._bulletOffset), (float)pen.y);
+            }
+            AttributedCharacterIterator chIt = elem._text.getIterator();
+            if(chIt.getEndIndex() > chIt.getBeginIndex()) {
+                graphics.drawString(chIt, (float)(pen.x + elem._textOffset), (float)pen.y);
             }
-            elem._text.draw(graphics, (float)(pen.x + elem._textOffset), (float)pen.y);
-
             y0 += elem.descent;
         }
     }
 
 
-    static class TextElement {
-        public TextLayout _text;
+    public static class TextElement {
+        public AttributedString _text;
         public int _textOffset;
-        public TextLayout _bullet;
+        public AttributedString _bullet;
         public int _bulletOffset;
         public int _align;
         public float ascent, descent;
+        public float advance;
     }
 }

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=652298&r1=652297&r2=652298&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 Tue Apr 29 23:29:11 2008
@@ -535,9 +535,13 @@
 		//  them to \n
 		String text = rawText.replace('\r','\n');
 
-        //0xB acts like cariage return in page titles
-        text = text.replace((char) 0x0B, '\n');
-
+        int type = _headerAtom == null ? 0 : _headerAtom.getTextType();
+        if(type == TextHeaderAtom.TITLE_TYPE || type == TextHeaderAtom.CENTER_TITLE_TYPE){
+            //0xB acts like cariage return in page titles and like blank in the others
+            text = text.replace((char) 0x0B, '\n');
+        } else {
+            text = text.replace((char) 0x0B, ' ');
+        }
 		return text;
 	}
 
@@ -655,4 +659,11 @@
         return null;
     }
 
+    public TextRulerAtom getTextRuler(){
+        for (int i = 0; i < _records.length; i++) {
+            if(_records[i] instanceof TextRulerAtom) return (TextRulerAtom)_records[i];
+        }
+        return null;
+
+    }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextShape.java Tue Apr 29 23:29:11 2008
@@ -261,17 +261,28 @@
     public int getVerticalAlignment(){
         EscherOptRecord opt = (EscherOptRecord)getEscherChild(_escherContainer, EscherOptRecord.RECORD_ID);
         EscherSimpleProperty prop = (EscherSimpleProperty)getEscherProperty(opt, EscherProperties.TEXT__ANCHORTEXT);
-        int valign;
+        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();
-            switch (type){
-                case TextHeaderAtom.TITLE_TYPE:
-                case TextHeaderAtom.CENTER_TITLE_TYPE:
-                    valign = TextShape.AnchorMiddle;
-                    break;
-                default:
-                    valign = TextShape.AnchorTop;
-                    break;
+            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();

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java Tue Apr 29 23:29:11 2008
@@ -24,11 +24,13 @@
 
 import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.model.ShapeTypes;
+import org.apache.poi.hslf.model.Shape;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Vector;
+import java.util.Iterator;
 
 /**
  * These are actually wrappers onto Escher drawings. Make use of
@@ -52,6 +54,8 @@
 	private EscherRecord[] childRecords;
 	private EscherTextboxWrapper[] textboxWrappers;
 
+    //cached EscherDgRecord
+    private EscherDgRecord dg;
 
 	/**
 	 * Get access to the underlying Escher Records
@@ -296,4 +300,24 @@
 		tw[textboxWrappers.length] = txtbox;
 		textboxWrappers = tw;
 	}
+
+    /**
+     * Return EscherDgRecord which keeps track of the number of shapes and shapeId in this drawing group
+     *
+     * @return EscherDgRecord
+     */
+    public EscherDgRecord getEscherDgRecord(){
+        if(dg == null){
+            EscherContainerRecord dgContainer = (EscherContainerRecord)childRecords[0];
+            for(Iterator it = dgContainer.getChildRecords().iterator(); it.hasNext();){
+                EscherRecord r = (EscherRecord) it.next();
+                if(r instanceof EscherDgRecord){
+                    dg = (EscherDgRecord)r;
+                    break;
+                }
+            }
+        }
+        return dg;
+    }
+
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java Tue Apr 29 23:29:11 2008
@@ -89,7 +89,7 @@
     public static final Type TxMasterStyleAtom = new Type(4003,TxMasterStyleAtom.class);
     public static final Type TxCFStyleAtom = new Type(4004,null);
     public static final Type TxPFStyleAtom = new Type(4005,null);
-    public static final Type TextRulerAtom = new Type(4006,null);
+    public static final Type TextRulerAtom = new Type(4006,TextRulerAtom.class);
     public static final Type TextBookmarkAtom = new Type(4007,null);
     public static final Type TextBytesAtom = new Type(4008,TextBytesAtom.class);
     public static final Type TxSIStyleAtom = new Type(4009,null);

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java Tue Apr 29 23:29:11 2008
@@ -127,8 +127,8 @@
 				new ParagraphFlagsTextProp(),
                 new TextProp(2, 0x80, "bullet.char"),
 				new TextProp(2, 0x10, "bullet.font"),
+                new TextProp(2, 0x40, "bullet.size"),
 				new TextProp(4, 0x20, "bullet.color"),
-				new TextProp(2, 0x40, "bullet.size"),
                 new AlignmentTextProp(),
                 new TextProp(2, 0x100, "text.offset"),
 				new TextProp(2, 0x200, "para_unknown_2"),

Added: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java?rev=652298&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java Tue Apr 29 23:29:11 2008
@@ -0,0 +1,194 @@
+/* ====================================================================
+   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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogger;
+
+/**
+ * Ruler of a text as it differs from the style's ruler settings.
+ *
+ * @author Yegor Kozlov
+ */
+public class TextRulerAtom extends RecordAtom {
+
+    /**
+     * Record header.
+     */
+    private byte[] _header;
+
+    /**
+     * Record data.
+     */
+    private byte[] _data;
+
+    //ruler internals
+    private int defaultTabSize;
+    private int numLevels;
+    private int[] tabStops;
+    private int[] bulletOffsets = new int[5];
+    private int[] textOffsets = new int[5];
+
+    /**
+     * Constructs a new empty ruler atom.
+     */
+    protected TextRulerAtom() {
+        _header = new byte[8];
+        _data = new byte[0];
+
+        LittleEndian.putShort(_header, 2, (short)getRecordType());
+        LittleEndian.putInt(_header, 4, _data.length);
+    }
+
+    /**
+     * Constructs the ruler 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 TextRulerAtom(byte[] source, int start, int len) {
+        // Get the header.
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Get the record data.
+        _data = new byte[len-8];
+        System.arraycopy(source,start+8,_data,0,len-8);
+
+        try {
+            read();
+        } catch (Exception e){
+            logger.log(POILogger.ERROR, "Failed to parse TextRulerAtom: " + e.getMessage()); 
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Gets the record type.
+     *
+     * @return the record type.
+     */
+    public long getRecordType() {
+        return RecordTypes.TextRulerAtom.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(_data);
+    }
+
+    /**
+     * Read the record bytes and initialize the internal variables
+     */
+    private void read(){
+        int pos = 0;
+        short mask = LittleEndian.getShort(_data);  pos += 4;
+        short val;
+        int[] bits = {1, 0, 2, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12};
+        for (int i = 0; i < bits.length; i++) {
+            if((mask & 1 << bits[i]) != 0){
+                switch (bits[i]){
+                    case 0:
+                        //defaultTabSize
+                        defaultTabSize = LittleEndian.getShort(_data, pos); pos += 2;
+                        break;
+                    case 1:
+                        //numLevels
+                        numLevels = LittleEndian.getShort(_data, pos); pos += 2;
+                        break;
+                    case 2:
+                        //tabStops
+                        val = LittleEndian.getShort(_data, pos); pos += 2;
+                        tabStops = new int[val*2];
+                        for (int j = 0; j < tabStops.length; j++) {
+                            tabStops[j] = LittleEndian.getUShort(_data, pos); pos += 2;
+                        }
+                        break;
+                    case 3:
+                    case 4:
+                    case 5:
+                    case 6:
+                    case 7:
+                        //bullet.offset
+                        val = LittleEndian.getShort(_data, pos); pos += 2;
+                        bulletOffsets[bits[i]-3] = val;
+                        break;
+                    case 8:
+                    case 9:
+                    case 10:
+                    case 11:
+                    case 12:
+                        //text.offset
+                        val = LittleEndian.getShort(_data, pos); pos += 2;
+                        textOffsets[bits[i]-8] = val;
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Default distance between tab stops, in master coordinates (576 dpi).
+     */
+    public int getDefaultTabSize(){
+        return defaultTabSize;
+    }
+
+    /**
+     * Number of indent levels (maximum 5).
+     */
+    public int getNumberOfLevels(){
+        return numLevels;
+    }
+
+    /**
+     * Default distance between tab stops, in master coordinates (576 dpi).
+     */
+    public int[] getTabStops(){
+        return tabStops;
+    }
+
+    /**
+     * Paragraph's distance from shape's left margin, in master coordinates (576 dpi).
+     */
+    public int[] getTextOffsets(){
+        return textOffsets;
+    }
+
+    /**
+     * First line of paragraph's distance from shape's left margin, in master coordinates (576 dpi).
+     */
+    public int[] getBulletOffsets(){
+        return bulletOffsets;
+    }
+}

Propchange: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TextRulerAtom.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/RichTextRun.java Tue Apr 29 23:29:11 2008
@@ -32,6 +32,8 @@
 import org.apache.poi.hslf.model.textproperties.TextProp;
 import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.ColorSchemeAtom;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
 
 
 /**
@@ -39,6 +41,8 @@
  * 
  */
 public class RichTextRun {
+    protected POILogger logger = POILogFactory.getLogger(this.getClass());
+
 	/** The TextRun we belong to */
 	private TextRun parentRun;
 	/** The SlideShow we belong to */
@@ -199,10 +203,15 @@
         }
         if (prop == null){
             Sheet sheet = parentRun.getSheet();
-            int txtype = parentRun.getRunType();
-            MasterSheet master = sheet.getMasterSheet();
-            if (master != null)
-                prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
+            if(sheet != null){
+                int txtype = parentRun.getRunType();
+                MasterSheet master = sheet.getMasterSheet();
+                if (master != null){
+                    prop = (BitMaskTextProp)master.getStyleAttribute(txtype, getIndentLevel(), propname, isCharacter);
+                }
+            } else {
+                logger.log(POILogger.WARN, "MasterSheet is not available");
+            }
         }
 
         return prop == null ? false : prop.getSubValue(index);
@@ -213,7 +222,7 @@
 	 *  it if required. 
 	 */
 	private void setCharFlagsTextPropVal(int index, boolean value) {
-        setFlag(true, index, value);
+        if(getFlag(true, index) != value) setFlag(true, index, value);
 	}
 
     public void setFlag(boolean isCharacter, int index, boolean value) {
@@ -281,10 +290,14 @@
 	 */
 	private int getParaTextPropVal(String propName) {
         TextProp prop = null;
+        boolean hardAttribute = false;
         if (paragraphStyle != null){
             prop = paragraphStyle.findByName(propName);
+
+            BitMaskTextProp maskProp = (BitMaskTextProp)paragraphStyle.findByName(ParagraphFlagsTextProp.NAME);
+            hardAttribute = maskProp != null && maskProp.getValue() == 0;
         }
-        if (prop == null){
+        if (prop == null && !hardAttribute){
             Sheet sheet = parentRun.getSheet();
             int txtype = parentRun.getRunType();
             MasterSheet master = sheet.getMasterSheet();
@@ -575,6 +588,13 @@
     }
 
     /**
+     * Returns whether this rich text run has bullets
+     */
+    public boolean isBulletHard() {
+        return getFlag(false, ParagraphFlagsTextProp.BULLET_IDX);
+    }
+
+    /**
      * Sets the bullet character
      */
     public void setBulletChar(char c) {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java Tue Apr 29 23:29:11 2008
@@ -24,10 +24,7 @@
 import java.awt.Dimension;
 import java.io.*;
 
-import org.apache.poi.ddf.EscherBSERecord;
-import org.apache.poi.ddf.EscherContainerRecord;
-import org.apache.poi.ddf.EscherOptRecord;
-import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.*;
 import org.apache.poi.hslf.model.*;
 import org.apache.poi.hslf.model.Notes;
@@ -66,9 +63,7 @@
   // Lookup between the PersitPtr "sheet" IDs, and the position
   //  in the mostRecentCoreRecords array
   private Hashtable _sheetIdToCoreRecordsLookup;
-  // Used when adding new core records
-  private int _highestSheetId;
-  
+
   // Records that are interesting
   private Document _documentRecord;
 
@@ -203,8 +198,6 @@
 	for(int i=0; i<allIDs.length; i++) {
 		_sheetIdToCoreRecordsLookup.put(new Integer(allIDs[i]), new Integer(i));
 	}
-	// Capture the ID of the highest sheet
-	_highestSheetId = allIDs[(allIDs.length-1)];
 
 	// Now convert the byte offsets back into record offsets
 	for(int i=0; i<_records.length; i++) {
@@ -612,38 +605,35 @@
   				}
   			}
   		}
-  		
-  		// Set up a new  SlidePersistAtom for this slide 
+
+  		// Set up a new  SlidePersistAtom for this slide
   		SlidePersistAtom sp = new SlidePersistAtom();
 
-  		// Reference is the 1-based index of the slide container in 
-  		//  the PersistPtr root.
-  		// It always starts with 3 (1 is Document, 2 is MainMaster, 3 is 
-  		//  the first slide), but quicksaves etc can leave gaps
-  		_highestSheetId++;
-  		sp.setRefID(_highestSheetId);
   		// First slideId is always 256
   		sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1));
-  		
+
   		// Add this new SlidePersistAtom to the SlideListWithText
   		slist.addSlidePersistAtom(sp);
-  		
-  		
+
+
   		// Create a new Slide
   		Slide slide = new Slide(sp.getSlideIdentifier(), sp.getRefID(), _slides.length+1);
+        slide.setSlideShow(this);
+        slide.onCreate();
+
   		// Add in to the list of Slides
   		Slide[] s = new Slide[_slides.length+1];
   		System.arraycopy(_slides, 0, s, 0, _slides.length);
   		s[_slides.length] = slide;
   		_slides = s;
   		logger.log(POILogger.INFO, "Added slide " + _slides.length + " with ref " + sp.getRefID() + " and identifier " + sp.getSlideIdentifier());
-  		
+
   		// Add the core records for this new Slide to the record tree
   		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
-  		slideRecord.setSheetId(sp.getRefID());
   		int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
   		_records = _hslfSlideShow.getRecords();
 
+
   		// Add the new Slide into the PersistPtr stuff
   		int offset = 0;
   		int slideOffset = 0;
@@ -653,7 +643,7 @@
   			Record record = _records[i];
   			ByteArrayOutputStream out = new ByteArrayOutputStream();
   			record.writeOut(out);
-  			
+
   			// Grab interesting records as they come past
   			if(_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID){
   				ptr = (PersistPtrHolder)_records[i];
@@ -661,25 +651,29 @@
   			if(_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) {
   				usr = (UserEditAtom)_records[i];
   			}
-  			
+
   			if(i == slideRecordPos) {
   				slideOffset = offset;
   			}
   			offset += out.size();
   		}
-  		
+
+        // persist ID is UserEditAtom.maxPersistWritten + 1
+        int psrId = usr.getMaxPersistWritten() + 1;
+        sp.setRefID(psrId);
+        slideRecord.setSheetId(psrId);
+
+        // Last view is now of the slide
+        usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
+        usr.setMaxPersistWritten(psrId);    //increment the number of persit objects
+
 		// Add the new slide into the last PersistPtr
   		// (Also need to tell it where it is)
 		slideRecord.setLastOnDiskOffset(slideOffset);
 		ptr.addSlideLookup(sp.getRefID(), slideOffset);
 		logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
 
-		// Last view is now of the slide
-  		usr.setLastViewType((short)UserEditAtom.LAST_VIEW_SLIDE_VIEW);
-  		usr.setMaxPersistWritten(_highestSheetId);
-
   		// All done and added
-  		slide.setSlideShow(this);
   		return slide;
 	}
 

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java Tue Apr 29 23:29:11 2008
@@ -52,7 +52,7 @@
         Freeform p = new Freeform();
         p.setPath(path1);
 
-        GeneralPath path2 = p.getPath();
+        java.awt.Shape path2 = p.getOutline();
         assertTrue(new Area(path1).equals(new Area(path2)));
     }
 
@@ -63,7 +63,7 @@
         Freeform p = new Freeform();
         p.setPath(path1);
 
-        GeneralPath path2 = p.getPath();
+        java.awt.Shape path2 = p.getOutline();
         assertTrue(new Area(path1).equals(new Area(path2)));
     }
 
@@ -74,7 +74,7 @@
         Freeform p = new Freeform();
         p.setPath(path1);
 
-        GeneralPath path2 = p.getPath();
+        java.awt.Shape path2 = p.getOutline();
         assertTrue(new Area(path1).equals(new Area(path2)));
-    }
+   }
 }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java Tue Apr 29 23:29:11 2008
@@ -20,6 +20,8 @@
 import org.apache.poi.hslf.usermodel.SlideShow;
 import org.apache.poi.hslf.usermodel.RichTextRun;
 import org.apache.poi.hslf.HSLFSlideShow;
+import org.apache.poi.ddf.EscherDggRecord;
+import org.apache.poi.ddf.EscherDgRecord;
 
 import java.awt.*;
 import java.awt.Rectangle;
@@ -311,18 +313,49 @@
     public void testShapeId() throws IOException {
         SlideShow ppt = new SlideShow();
         Slide slide = ppt.createSlide();
-        Shape shape;
+        Shape shape = null;
 
-        shape = new Line();
-        assertEquals(0, shape.getShapeId());
-        slide.addShape(shape);
-        assertTrue(shape.getShapeId() > 0);
-
-        int shapeId = shape.getShapeId();
-
-        shape = new Line();
-        assertEquals(0, shape.getShapeId());
-        slide.addShape(shape);
-        assertEquals(shapeId + 1, shape.getShapeId());
+        //EscherDgg is a document-level record which keeps track of the drawing groups
+        EscherDggRecord dgg = ppt.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
+        EscherDgRecord dg = slide.getSheetContainer().getPPDrawing().getEscherDgRecord();
+
+        int dggShapesUsed = dgg.getNumShapesSaved();   //total number of shapes in the ppt
+        int dggMaxId = dgg.getShapeIdMax();            //max number of shapeId
+
+        int dgMaxId = dg.getLastMSOSPID();   //max shapeId in the slide
+        int dgShapesUsed = dg.getNumShapes();          // number of shapes in the slide
+        //insert 3 shapes and make sure the Ids are properly incremented
+        for (int i = 0; i < 3; i++) {
+            shape = new Line();
+            assertEquals(0, shape.getShapeId());
+            slide.addShape(shape);
+            assertTrue(shape.getShapeId() > 0);
+
+            //check that EscherDgRecord is updated
+            assertEquals(shape.getShapeId(), dg.getLastMSOSPID());
+            assertEquals(dgMaxId + 1, dg.getLastMSOSPID());
+            assertEquals(dgShapesUsed + 1, dg.getNumShapes());
+
+            //check that EscherDggRecord is updated
+            assertEquals(shape.getShapeId() + 1, dgg.getShapeIdMax());
+            assertEquals(dggMaxId + 1, dgg.getShapeIdMax());
+            assertEquals(dggShapesUsed + 1, dgg.getNumShapesSaved());
+
+            dggShapesUsed = dgg.getNumShapesSaved();
+            dggMaxId = dgg.getShapeIdMax();
+            dgMaxId = dg.getLastMSOSPID();
+            dgShapesUsed = dg.getNumShapes();
+        }
+
+
+        //For each drawing group PPT allocates clusters with size=1024
+        //if the number of shapes is greater that 1024 a new cluster is allocated
+        //make sure it is so
+        int numClusters = dgg.getNumIdClusters();
+        for (int i = 0; i < 1025; i++) {
+            shape = new Line();
+            slide.addShape(shape);
+        }
+        assertEquals(numClusters + 1, dgg.getNumIdClusters());
     }
 }

Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java?rev=652298&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java (added)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java Tue Apr 29 23:29:11 2008
@@ -0,0 +1,76 @@
+
+/* ====================================================================
+   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 org.apache.poi.hslf.HSLFSlideShow;
+import org.apache.poi.hslf.model.textproperties.CharFlagsTextProp;
+import org.apache.poi.hslf.model.textproperties.TextProp;
+import org.apache.poi.hslf.model.textproperties.TextPropCollection;
+import org.apache.poi.hslf.record.StyleTextPropAtom.*;
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.util.HexDump;
+
+import junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.util.LinkedList;
+import java.util.Arrays;
+
+/**
+ * Tests TextRulerAtom
+ *
+ * @author Yegor Kozlov
+ */
+public class TestTextRulerAtom extends TestCase {
+
+    //from a real file
+	private byte[] data_1 = new byte[] {
+		0x00, 0x00, (byte)0xA6, 0x0F, 0x18, 0x00, 0x00, 0x00,
+        (byte)0xF8, 0x1F, 0x00, 0x00, 0x75, 0x00, (byte)0xE2, 0x00, 0x59,
+        0x01, (byte)0xC3, 0x01, 0x1A, 0x03, (byte)0x87, 0x03, (byte)0xF8,
+        0x03, 0x69, 0x04, (byte)0xF6, 0x05, (byte)0xF6, 0x05
+	};
+
+
+    public void testReadRuler() throws Exception {
+		TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
+        assertEquals(ruler.getNumberOfLevels(), 0);
+        assertEquals(ruler.getDefaultTabSize(), 0);
+
+        int[] tabStops = ruler.getTabStops();
+        assertNull(tabStops);
+
+        int[] textOffsets = ruler.getTextOffsets();
+        assertTrue(Arrays.equals(new int[]{226, 451, 903, 1129, 1526}, textOffsets));
+
+        int[] bulletOffsets = ruler.getBulletOffsets();
+        assertTrue(Arrays.equals(new int[]{117, 345, 794, 1016, 1526}, bulletOffsets));
+
+	}
+
+    public void testWriteRuler() throws Exception {
+		TextRulerAtom ruler = new TextRulerAtom(data_1, 0, data_1.length);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ruler.writeOut(out);
+
+        byte[] result = out.toByteArray();
+        assertTrue(Arrays.equals(result, data_1));
+	}
+}

Propchange: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTextRulerAtom.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java?rev=652298&r1=652297&r2=652298&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestRichTextRun.java Tue Apr 29 23:29:11 2008
@@ -90,9 +90,11 @@
 		
 		// Now set it to not bold
 		rtr.setBold(false);
-		assertNotNull(rtr._getRawCharacterStyle());
-		assertNotNull(rtr._getRawParagraphStyle());
-		assertFalse(rtr.isBold());
+		//setting bold=false doesn't change the internal state
+        assertNull(rtr._getRawCharacterStyle());
+		assertNull(rtr._getRawParagraphStyle());
+
+        assertFalse(rtr.isBold());
 		
 		// And now make it bold
 		rtr.setBold(true);



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