poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1677496 - in /poi/branches/common_sl/src: ooxml/java/org/apache/poi/xslf/usermodel/ scratchpad/src/org/apache/poi/hslf/model/textproperties/ scratchpad/src/org/apache/poi/hslf/record/ scratchpad/src/org/apache/poi/hslf/usermodel/ scratchpa...
Date Sun, 03 May 2015 23:42:42 GMT
Author: kiwiwings
Date: Sun May  3 23:42:42 2015
New Revision: 1677496

URL: http://svn.apache.org/r1677496
Log:
fixed HSLF text handling

Modified:
    poi/branches/common_sl/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java
    poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
    poi/branches/common_sl/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java

Modified: poi/branches/common_sl/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
(original)
+++ poi/branches/common_sl/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
Sun May  3 23:42:42 2015
@@ -490,27 +490,7 @@ public class XSLFTextParagraph implement
         tabStops.addNewTab().setPos(Units.toEMU(value));
     }
 
-    /**
-     * This element specifies the vertical line spacing that is to be used within a paragraph.
-     * This may be specified in two different ways, percentage spacing and font point spacing:
-     * <p>
-     * If linespacing >= 0, then linespacing is a percentage of normal line height
-     * If linespacing < 0, the absolute value of linespacing is the spacing in points
-     * </p>
-     * Examples:
-     * <pre><code>
-     *      // spacing will be 120% of the size of the largest text on each line
-     *      paragraph.setLineSpacing(120);
-     *
-     *      // spacing will be 200% of the size of the largest text on each line
-     *      paragraph.setLineSpacing(200);
-     *
-     *      // spacing will be 48 points
-     *      paragraph.setLineSpacing(-48.0);
-     * </code></pre>
-     * 
-     * @param linespacing the vertical line spacing
-     */
+    @Override
     public void setLineSpacing(double linespacing){
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
         CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
@@ -519,16 +499,7 @@ public class XSLFTextParagraph implement
         pr.setLnSpc(spc);
     }
 
-    /**
-     * Returns the vertical line spacing that is to be used within a paragraph.
-     * This may be specified in two different ways, percentage spacing and font point spacing:
-     * <p>
-     * If linespacing >= 0, then linespacing is a percentage of normal line height.
-     * If linespacing < 0, the absolute value of linespacing is the spacing in points
-     * </p>
-     *
-     * @return the vertical line spacing.
-     */
+    @Override
     public double getLineSpacing(){
         ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
             public boolean fetch(CTTextParagraphProperties props){

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/BitMaskTextProp.java
Sun May  3 23:42:42 2015
@@ -82,13 +82,9 @@ public abstract class BitMaskTextProp ex
 	 * Set the true/false status of the subproperty with the given index
 	 */
 	public void setSubValue(boolean value, int idx) {
-		if(subPropMatches[idx] == value) { return; }
-		if(value) {
-			dataValue += subPropMasks[idx];
-		} else {
-			dataValue -= subPropMasks[idx];
-		}
-		subPropMatches[idx] = value;
+		if (subPropMatches[idx] == value) return; 
+        subPropMatches[idx] = value;
+		dataValue ^= subPropMasks[idx];
 	}
 	
 	@Override
@@ -101,4 +97,8 @@ public abstract class BitMaskTextProp ex
 		
 		return newObj;
 	}
+	
+    public BitMaskTextProp cloneAll(){
+        return (BitMaskTextProp)super.clone();
+    }	
 }
\ No newline at end of file

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/model/textproperties/TextPropCollection.java
Sun May  3 23:42:42 2015
@@ -160,14 +160,9 @@ public class TextPropCollection {
         this.reservedField = other.reservedField;
         this.textPropList.clear();
         for (TextProp tp : other.textPropList) {
-            TextProp tpCopy = tp.clone();
-            if (tpCopy instanceof BitMaskTextProp) {
-                BitMaskTextProp bmt = (BitMaskTextProp)tpCopy;
-                boolean matches[] = ((BitMaskTextProp)tp).getSubPropMatches();
-                for (int i=0; i<matches.length; i++) {
-                    bmt.setSubValue(matches[i], i);
-                }
-            }
+            TextProp tpCopy = (tp instanceof BitMaskTextProp)
+                ? ((BitMaskTextProp)tp).cloneAll()
+                : tp.clone();
             this.textPropList.add(tpCopy);
         }
 	}
@@ -183,7 +178,7 @@ public class TextPropCollection {
 	/**
 	 * Writes out to disk the header, and then all the properties
 	 */
-	public void writeOut(OutputStream o) throws IOException {
+	public void writeOut(OutputStream o, TextProp[] potentialProperties) throws IOException
{
 		// First goes the number of characters we affect
 		StyleTextPropAtom.writeLittleEndian(charactersCovered,o);
 
@@ -194,10 +189,8 @@ public class TextPropCollection {
 
 		// Then the mask field
 		int mask = maskSpecial;
-		for(int i=0; i<textPropList.size(); i++) {
-			TextProp textProp = textPropList.get(i);
+		for(TextProp textProp : textPropList) {
             //sometimes header indicates that the bitmask is present but its value is 0
-
             if (textProp instanceof BitMaskTextProp) {
                 if(mask == 0) mask |=  textProp.getWriteMask();
             }
@@ -208,14 +201,19 @@ public class TextPropCollection {
 		StyleTextPropAtom.writeLittleEndian(mask,o);
 
 		// Then the contents of all the properties
-		for(int i=0; i<textPropList.size(); i++) {
-			TextProp textProp = textPropList.get(i);
-			int val = textProp.getValue();
-			if(textProp.getSize() == 2) {
-				StyleTextPropAtom.writeLittleEndian((short)val,o);
-			} else if(textProp.getSize() == 4){
-				StyleTextPropAtom.writeLittleEndian(val,o);
-			}
+		for (TextProp potProp : potentialProperties) {
+    		for(TextProp textProp : textPropList) {
+    		    if (!textProp.getName().equals(potProp.getName())) continue;
+                int val = textProp.getValue();
+                if (textProp instanceof BitMaskTextProp && val == 0) {
+                    // don't add empty properties, as they can't be recognized while reading
+                    continue;
+                } else if (textProp.getSize() == 2) {
+    				StyleTextPropAtom.writeLittleEndian((short)val,o);
+    			} else if (textProp.getSize() == 4) {
+    				StyleTextPropAtom.writeLittleEndian(val,o);
+    			}
+    		}
 		}
 	}
 

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/record/StyleTextPropAtom.java
Sun May  3 23:42:42 2015
@@ -17,15 +17,12 @@
 
 package org.apache.poi.hslf.record;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.LinkedList;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.poi.hslf.model.textproperties.*;
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogger;
+import org.apache.poi.util.*;
 
 /**
  * A StyleTextPropAtom (type 4001). Holds basic character properties
@@ -64,26 +61,26 @@ public final class StyleTextPropAtom ext
      *  Characters the paragraph covers, and also contains the TextProps
      *  that actually define the styling of the paragraph.
      */
-    private LinkedList<TextPropCollection> paragraphStyles;
-    public LinkedList<TextPropCollection> getParagraphStyles() { return paragraphStyles;
}
+    private List<TextPropCollection> paragraphStyles;
+    public List<TextPropCollection> getParagraphStyles() { return paragraphStyles;
}
     /**
      * Updates the link list of TextPropCollections which make up the
      *  paragraph stylings
      */
-    public void setParagraphStyles(LinkedList<TextPropCollection> ps) { paragraphStyles
= ps; }
+    public void setParagraphStyles(List<TextPropCollection> ps) { paragraphStyles =
ps; }
     /**
      * The list of all the different character stylings we code for.
      * Each entry is a TextPropCollection, which tells you how many
      *  Characters the character styling covers, and also contains the
      *  TextProps that actually define the styling of the characters.
      */
-    private LinkedList<TextPropCollection> charStyles;
-    public LinkedList<TextPropCollection> getCharacterStyles() { return charStyles;
}
+    private List<TextPropCollection> charStyles;
+    public List<TextPropCollection> getCharacterStyles() { return charStyles; }
     /**
      * Updates the link list of TextPropCollections which make up the
      *  character stylings
      */
-    public void setCharacterStyles(LinkedList<TextPropCollection> cs) { charStyles
= cs; }
+    public void setCharacterStyles(List<TextPropCollection> cs) { charStyles = cs;
}
 
     /**
      * Returns how many characters the paragraph's
@@ -105,7 +102,7 @@ public final class StyleTextPropAtom ext
     public int getCharacterTextLengthCovered() {
         return getCharactersCovered(charStyles);
     }
-    private int getCharactersCovered(LinkedList<TextPropCollection> styles) {
+    private int getCharactersCovered(List<TextPropCollection> styles) {
         int length = 0;
         for(TextPropCollection tpc : styles) {
             length += tpc.getCharactersCovered();
@@ -197,9 +194,9 @@ public final class StyleTextPropAtom ext
         System.arraycopy(source,start+8,rawContents,0,rawContents.length);
         reserved = new byte[0];
 
-        // Set empty linked lists, ready for when they call setParentTextSize
-        paragraphStyles = new LinkedList<TextPropCollection>();
-        charStyles = new LinkedList<TextPropCollection>();
+        // Set empty lists, ready for when they call setParentTextSize
+        paragraphStyles = new ArrayList<TextPropCollection>();
+        charStyles = new ArrayList<TextPropCollection>();
     }
 
 
@@ -217,8 +214,8 @@ public final class StyleTextPropAtom ext
         LittleEndian.putInt(_header,4,10);
 
         // Set empty paragraph and character styles
-        paragraphStyles = new LinkedList<TextPropCollection>();
-        charStyles = new LinkedList<TextPropCollection>();
+        paragraphStyles = new ArrayList<TextPropCollection>();
+        charStyles = new ArrayList<TextPropCollection>();
 
         TextPropCollection defaultParagraphTextProps =
                 new TextPropCollection(parentTextSize, (short)0);
@@ -377,13 +374,13 @@ public final class StyleTextPropAtom ext
         // First up, we need to serialise the paragraph properties
         for(int i=0; i<paragraphStyles.size(); i++) {
             TextPropCollection tpc = paragraphStyles.get(i);
-            tpc.writeOut(baos);
+            tpc.writeOut(baos, paragraphTextPropTypes);
         }
 
         // Now, we do the character ones
         for(int i=0; i<charStyles.size(); i++) {
             TextPropCollection tpc = charStyles.get(i);
-            tpc.writeOut(baos);
+            tpc.writeOut(baos, characterTextPropTypes);
         }
 
         rawContents = baos.toByteArray();
@@ -454,7 +451,7 @@ public final class StyleTextPropAtom ext
 
                 try {
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    pr.writeOut(baos);
+                    pr.writeOut(baos, paragraphTextPropTypes);
                     byte[] b = baos.toByteArray();
                     out.append(HexDump.dump(b, 0, 0));
                 } catch (Exception e ) {
@@ -475,7 +472,7 @@ public final class StyleTextPropAtom ext
 
                 try {
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    pr.writeOut(baos);
+                    pr.writeOut(baos, characterTextPropTypes);
                     byte[] b = baos.toByteArray();
                     out.append(HexDump.dump(b, 0, 0));
                 } catch (Exception e ) {

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSheet.java
Sun May  3 23:42:42 2015
@@ -270,7 +270,6 @@ public abstract class HSLFSheet implemen
      * @param shape
      */
     protected void onAddTextShape(HSLFTextShape shape) {
-
     }
 
     /**

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
Sun May  3 23:42:42 2015
@@ -553,30 +553,22 @@ public final class HSLFTextParagraph imp
        return getParaTextPropVal("bullet.font");
    }
 
-   /**
-    * Sets the line spacing.
-    * <p>
-    * If linespacing >= 0, then linespacing is a percentage of normal line height.
-    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-    * </p>
-    */
-   public void setLineSpacing(int val) {
-       setParaTextPropVal("linespacing", val);
+   @Override
+   public void setLineSpacing(double lineSpacing) {
+       // if lineSpacing < 0, we need to convert points (common interface) to master units
(hslf)
+       if (lineSpacing < 0) {
+           lineSpacing = (lineSpacing*HSLFShape.MASTER_DPI/HSLFShape.POINT_DPI);
+       }
+       setParaTextPropVal("linespacing", (int)lineSpacing);
    }
 
-   /**
-    * Returns the line spacing
-    * <p>
-    * If linespacing >= 0, then linespacing is a percentage of normal line height.
-    * If linespacing < 0, the absolute value of linespacing is the spacing in master coordinates.
-    * </p>
-    *
-    * @return the spacing between lines
-    */
    @Override
    public double getLineSpacing() {
-       int val = getParaTextPropVal("linespacing");
-       return val == -1 ? 0 : val;
+       double val = getParaTextPropVal("linespacing");
+       // if lineSpacing < 0, we need to convert master units (hslf) to points (common
interface)
+       if (val == -1) return 0;
+       if (val < -1) val *= HSLFShape.POINT_DPI/((double)HSLFShape.MASTER_DPI);
+       return val;
    }
 
    /**
@@ -722,6 +714,12 @@ public final class HSLFTextParagraph imp
                throw new RuntimeException("child record not found - malformed container record");
            }
            cr[idx] = newRecord;
+           
+           if (newRecord == byteAtom) {
+               charAtom = null;
+           } else {
+               byteAtom = null;
+           }
        }
 
        // Ensure a StyleTextPropAtom is present, adding if required
@@ -750,6 +748,7 @@ public final class HSLFTextParagraph imp
            }
            for (HSLFTextRun tr : para.getTextRuns()) {
                TextPropCollection rtpc = tr.getCharacterStyle();
+               rtpc.updateTextSize(0);
                if (!rtpc.equals(lastRTPC)) {
                    lastRTPC = styleAtom.addCharacterTextPropCollection(0);
                    lastRTPC.copy(rtpc);
@@ -783,19 +782,43 @@ public final class HSLFTextParagraph imp
     * 
     * @param text the text string used by this object.
     */
-   protected static void appendText(List<HSLFTextParagraph> paragraphs, String text,
boolean newParagraph) {
+   protected static HSLFTextRun appendText(List<HSLFTextParagraph> paragraphs, String
text, boolean newParagraph) {
        text = toInternalString(text);
+
+       // check paragraphs
+       assert(!paragraphs.isEmpty() && !paragraphs.get(0).getTextRuns().isEmpty());
+       
+       HSLFTextParagraph htp = paragraphs.get(paragraphs.size()-1);
+       HSLFTextRun htr = htp.getTextRuns().get(htp.getTextRuns().size()-1);
+
+       if (newParagraph) {
+           htr.setText(htr.getRawText()+"\n");
+       }
        
-       // init paragraphs
-       assert(!paragraphs.isEmpty());
+       boolean isFirst = !newParagraph;
+       for (String rawText : text.split("(?<=\r)")) {
+           if (!isFirst) {
+               TextPropCollection tpc = htp.getParagraphStyle();
+               HSLFTextParagraph prevHtp = htp;
+               htp = new HSLFTextParagraph(htp._headerAtom, htp._byteAtom, htp._charAtom,
htp._styleAtom);
+               htp.getParagraphStyle().copy(tpc);
+               htp.setParentShape(prevHtp.getParentShape());
+               htp.setShapeId(prevHtp.getShapeId());
+               htp.supplySheet(prevHtp.getSheet());
+               paragraphs.add(htp);
+               isFirst = false;
+           }
+           TextPropCollection tpc = htr.getCharacterStyle();
+           // special case, last text run is empty, we will reuse it
+           if (htr.getLength() > 0) {
+               htr = new HSLFTextRun(htp);
+               htr.getCharacterStyle().copy(tpc);
+               htp.addTextRun(htr);
+           }
+           htr.setText(rawText);
+       }
        
-       HSLFTextParagraph lastHTP = paragraphs.get(paragraphs.size()-1);
-       HSLFTextRun lastHTR = lastHTP.getTextRuns().get(lastHTP.getTextRuns().size()-1);
-       HSLFTextParagraph htp = (newParagraph) ? new HSLFTextParagraph(lastHTP) : lastHTP;
-       HSLFTextRun htr = new HSLFTextRun(htp);
-       htr.setText(text);
-       htr.getCharacterStyle().copy(lastHTR.getCharacterStyle());
-       htp.addTextRun(htr);
+       return htr;
    }
    
    /**
@@ -804,29 +827,30 @@ public final class HSLFTextParagraph imp
     * 
     * @param text the text string used by this object.
     */
-   public static void setText(List<HSLFTextParagraph> paragraphs, String text) {
+   public static HSLFTextRun setText(List<HSLFTextParagraph> paragraphs, String text)
{
        text = HSLFTextParagraph.toInternalString(text);
        
-       // init paragraphs
-       assert(!paragraphs.isEmpty());
+       // check paragraphs
+       assert(!paragraphs.isEmpty() && !paragraphs.get(0).getTextRuns().isEmpty());
 
        Iterator<HSLFTextParagraph> paraIter = paragraphs.iterator();
-       HSLFTextParagraph firstHTP = paraIter.next(); // keep first
-       assert(firstHTP != null);
+       HSLFTextParagraph htp = paraIter.next(); // keep first
+       assert(htp != null);
        while (paraIter.hasNext()) {
            paraIter.next();
            paraIter.remove();
        }
        
-       Iterator<HSLFTextRun> runIter = firstHTP.getTextRuns().iterator();
-       HSLFTextRun firstHTR = runIter.next();
-       assert(firstHTR != null);
+       Iterator<HSLFTextRun> runIter = htp.getTextRuns().iterator();
+       HSLFTextRun htr = runIter.next();
+       htr.setText("");
+       assert(htr != null);
        while (runIter.hasNext()) {
            runIter.next();
            runIter.remove();
        }
        
-       firstHTR.setText(text);
+       return appendText(paragraphs, text, false);
    }
    
    public static String getRawText(List<HSLFTextParagraph> paragraphs) {
@@ -835,9 +859,7 @@ public final class HSLFTextParagraph imp
            for (HSLFTextRun r : p.getTextRuns()) {
                sb.append(r.getRawText());
            }
-           sb.append("\r");
        }
-       sb.deleteCharAt(sb.length()-1); // remove last line break
        return sb.toString();        
    }
    
@@ -947,7 +969,7 @@ public final class HSLFTextParagraph imp
             return paragraphCollection;
         }
         
-        for (int slwtIndex = 0; recordIdx < records.length-2; slwtIndex++) {
+        for (int slwtIndex = 0; recordIdx < records.length; slwtIndex++) {
             List<HSLFTextParagraph> paragraphs = new ArrayList<HSLFTextParagraph>();
             paragraphCollection.add(paragraphs);
             
@@ -985,12 +1007,14 @@ public final class HSLFTextParagraph imp
             
             if (tbytes == null && tchars == null) {
                 tbytes = new TextBytesAtom();
+                header.getParentRecord().addChildAfter(tbytes, header);
                 logger.log(POILogger.INFO, "bytes nor chars atom doesn't exist. Creating
dummy record for later saving.");
             }
         
             String rawText = (tchars != null) ? tchars.getText() : tbytes.getText();
         
-            for (String para : rawText.split("\r")) {
+            // split, but keep delimiter
+            for (String para : rawText.split("(?<=\r)")) {
                 HSLFTextParagraph tpara = new HSLFTextParagraph(header, tbytes, tchars, styles);
                 paragraphs.add(tpara);
                 tpara.setStyleTextProp9Atom(styleTextProp9Atom);
@@ -1021,29 +1045,21 @@ public final class HSLFTextParagraph imp
 
     protected static void applyCharacterStyles(List<HSLFTextParagraph> paragraphs,
List<TextPropCollection> charStyles) {
         int paraIdx = 0, runIdx = 0;
-        for (TextPropCollection p : charStyles) {
+        HSLFTextRun trun;
+        
+        for (int csIdx=0; csIdx<charStyles.size(); csIdx++) {
+            TextPropCollection p = charStyles.get(csIdx);
             for (int ccRun = 0, ccStyle = p.getCharactersCovered(); ccRun < ccStyle; )
{
                 HSLFTextParagraph para = paragraphs.get(paraIdx);
                 List<HSLFTextRun> runs = para.getTextRuns();
-                HSLFTextRun trun = runs.get(runIdx);
+                trun = runs.get(runIdx);
                 int len = trun.getLength();
                 
-                if (runIdx+1 >= runs.size()) {
-                    // need to add +1 to the last run of the paragraph
-                    len++;
-                }
-                
-                TextPropCollection pCopy = new TextPropCollection(1);
-                pCopy.copy(p);
                 if (ccRun+len <= ccStyle) {
-                    trun.setCharacterStyle(pCopy);
-                    pCopy.updateTextSize(len);
                     ccRun += len;
                 } else {
                     String text = trun.getRawText();
                     trun.setText(text.substring(0,ccStyle-ccRun));
-                    pCopy.updateTextSize(ccStyle-ccRun);
-                    trun.setCharacterStyle(pCopy);
                     
                     HSLFTextRun nextRun = new HSLFTextRun(para);
                     nextRun.setText(text.substring(ccStyle-ccRun));
@@ -1052,8 +1068,27 @@ public final class HSLFTextParagraph imp
                     ccRun += ccStyle-ccRun;
                 }
 
-                // need to compare it again, in case a run has been added afer
-                if (++runIdx >= runs.size()) {
+                TextPropCollection pCopy = new TextPropCollection(0);
+                pCopy.copy(p);
+                trun.setCharacterStyle(pCopy);
+
+                len = trun.getLength();
+                if (paraIdx == paragraphs.size()-1 && runIdx == runs.size()-1) {
+                    if (csIdx < charStyles.size()-1) {
+                        // special case, empty trailing text run
+                        HSLFTextRun nextRun = new HSLFTextRun(para);
+                        nextRun.setText("");
+                        runs.add(nextRun);
+                    } else {
+                        // need to add +1 to the last run of the last paragraph
+                        len++;
+                        ccRun++;
+                    }
+                }
+                pCopy.updateTextSize(len);
+                
+                // need to compare it again, in case a run has been added after
+                if (++runIdx == runs.size()) {
                     paraIdx++;
                     runIdx = 0;
                 }
@@ -1065,16 +1100,18 @@ public final class HSLFTextParagraph imp
         int paraIdx = 0;
         for (TextPropCollection p : paraStyles) {
             for (int ccPara = 0, ccStyle = p.getCharactersCovered(); ccPara < ccStyle;
paraIdx++) {
-                HSLFTextParagraph para = paragraphs.get(paraIdx);
-                TextPropCollection pCopy = new TextPropCollection(1);
+                if (paraIdx >= paragraphs.size() || ccPara >= ccStyle-1) return;
+                HSLFTextParagraph htp = paragraphs.get(paraIdx);
+                TextPropCollection pCopy = new TextPropCollection(0);
                 pCopy.copy(p);
+                htp.setParagraphStyle(pCopy);
                 int len = 0;
-                for (HSLFTextRun trun : para.getTextRuns()) {
+                for (HSLFTextRun trun : htp.getTextRuns()) {
                     len += trun.getLength();
                 }
-                pCopy.updateTextSize(len+1);
-                para.setParagraphStyle(pCopy);
-                ccPara += len+1;
+                if (paraIdx == paragraphs.size()-1) len++;
+                pCopy.updateTextSize(len);
+                ccPara += len;
             }
         }
     }
@@ -1101,15 +1138,28 @@ public final class HSLFTextParagraph imp
         tha.setParentRecord(wrapper);
         wrapper.appendChildRecord(tha);
     
-        TextCharsAtom tca = new TextCharsAtom();
-        wrapper.appendChildRecord(tca);
+        TextBytesAtom tba = new TextBytesAtom();
+        tba.setText("\r".getBytes());
+        wrapper.appendChildRecord(tba);
     
-        StyleTextPropAtom sta = new StyleTextPropAtom(0);
+        StyleTextPropAtom sta = new StyleTextPropAtom(1);
+        TextPropCollection paraStyle = sta.addParagraphTextPropCollection(1);
+        TextPropCollection charStyle = sta.addCharacterTextPropCollection(1);
         wrapper.appendChildRecord(sta);
     
-        HSLFTextParagraph htp = new HSLFTextParagraph(tha, null, tca, sta);
+        HSLFTextParagraph htp = new HSLFTextParagraph(tha, tba, null, sta);
+        htp.setParagraphStyle(paraStyle);
         htp._records = new Record[0];
+        htp.setBullet(false);
+        htp.setLineSpacing(100);
+        htp.setLeftMargin(0);
+        htp.setIndent(0);
+        // set wrap flags
+        
         HSLFTextRun htr = new HSLFTextRun(htp);
+        htr.setCharacterStyle(charStyle);
+        htr.setText("\r");
+        htr.setFontColor(Color.black);
         htp.addTextRun(htr);
         
         return Arrays.asList(htp);

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
Sun May  3 23:42:42 2015
@@ -37,14 +37,14 @@ public final class HSLFTextRun implement
 
 	/** The TextRun we belong to */
 	private HSLFTextParagraph parentParagraph;
-	private String _runText = "\r";
+	private String _runText = "";
 	private String _fontname;
 	
 	/**
 	 * Our paragraph and character style.
 	 * Note - we may share these styles with other RichTextRuns
 	 */
-	private TextPropCollection characterStyle = new TextPropCollection(1);
+	private TextPropCollection characterStyle = new TextPropCollection(0);
 
 	/**
 	 * Create a new wrapper around a rich text string

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
Sun May  3 23:42:42 2015
@@ -22,14 +22,11 @@ import static org.apache.poi.hslf.record
 import java.awt.Rectangle;
 import java.awt.font.FontRenderContext;
 import java.awt.geom.Rectangle2D;
-import java.awt.geom.Rectangle2D.Double;
 import java.io.IOException;
 import java.util.*;
 
-import org.apache.poi.POIXMLException;
 import org.apache.poi.ddf.*;
 import org.apache.poi.hslf.exceptions.HSLFException;
-import org.apache.poi.hslf.model.textproperties.TextPropCollection;
 import org.apache.poi.hslf.record.*;
 import org.apache.poi.sl.draw.DrawFactory;
 import org.apache.poi.sl.draw.DrawTextShape;
@@ -139,8 +136,12 @@ public abstract class HSLFTextShape exte
     protected void afterInsert(HSLFSheet sh){
         super.afterInsert(sh);
 
+        storeText();
+        
         EscherTextboxWrapper _txtbox = getEscherTextboxWrapper();
         if(_txtbox != null){
+            _escherContainer.addChildRecord(_txtbox.getEscherRecord());
+            
             PPDrawing ppdrawing = sh.getPPDrawing();
             ppdrawing.addTextboxWrapper(_txtbox);
             // Ensure the escher layer knows about the added records
@@ -712,10 +713,10 @@ public abstract class HSLFTextShape exte
        * 
        * @param text the text string used by this object.
        */
-      public void appendText(String text, boolean newParagraph) {
+      public HSLFTextRun appendText(String text, boolean newParagraph) {
           // init paragraphs
           List<HSLFTextParagraph> paras = getTextParagraphs();
-          HSLFTextParagraph.appendText(paras, text, newParagraph);
+          return HSLFTextParagraph.appendText(paras, text, newParagraph);
       }
 
       /**
@@ -723,12 +724,15 @@ public abstract class HSLFTextShape exte
        * Uses the properties of the first paragraph / textrun
        * 
        * @param text the text string used by this object.
+       * 
+       * @return the last text run of the splitted text
        */
-      public void setText(String text) {
+      public HSLFTextRun setText(String text) {
           // init paragraphs
           List<HSLFTextParagraph> paras = getTextParagraphs();
-          HSLFTextParagraph.setText(paras, text);
+          HSLFTextRun htr = HSLFTextParagraph.setText(paras, text);
           setTextId(text.hashCode());
+          return htr;
       }
       
       /**

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java (original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/draw/DrawTextShape.java Sun
May  3 23:42:42 2015
@@ -104,8 +104,8 @@ public class DrawTextShape<T extends Tex
                     // negative value means the absolute spacing in points
                     y += -spaceBefore;
                 }
-                isFirstLine = false;
             }
+            isFirstLine = false;
             
             dp.setPosition(x, y);
             dp.draw(graphics);

Modified: poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
(original)
+++ poi/branches/common_sl/src/scratchpad/src/org/apache/poi/sl/usermodel/TextParagraph.java
Sun May  3 23:42:42 2015
@@ -113,7 +113,7 @@ public interface TextParagraph<T extends
      * This may be specified in two different ways, percentage spacing and font point spacing:
      * <p>
      * If spaceBefore >= 0, then space is a percentage of normal line height.
-     * If spaceBefore < 0, the absolute value of linespacing is the spacing in points
+     * If spaceBefore < 0, the absolute value in points
      * </p>
      *
      * @return the vertical white space before the paragraph
@@ -174,6 +174,29 @@ public interface TextParagraph<T extends
      * @return the vertical line spacing.
      */
     double getLineSpacing();
+    
+    /**
+     * This element specifies the vertical line spacing that is to be used within a paragraph.
+     * This may be specified in two different ways, percentage spacing and font point spacing:
+     * <p>
+     * If linespacing >= 0, then linespacing is a percentage of normal line height
+     * If linespacing < 0, the absolute value of linespacing is the spacing in points
+     * </p>
+     * Examples:
+     * <pre><code>
+     *      // spacing will be 120% of the size of the largest text on each line
+     *      paragraph.setLineSpacing(120);
+     *
+     *      // spacing will be 200% of the size of the largest text on each line
+     *      paragraph.setLineSpacing(200);
+     *
+     *      // spacing will be 48 points
+     *      paragraph.setLineSpacing(-48.0);
+     * </code></pre>
+     * 
+     * @param linespacing the vertical line spacing
+     */
+    void setLineSpacing(double lineSpacing);
 
     String getDefaultFontFamily();
     

Modified: poi/branches/common_sl/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
URL: http://svn.apache.org/viewvc/poi/branches/common_sl/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java?rev=1677496&r1=1677495&r2=1677496&view=diff
==============================================================================
--- poi/branches/common_sl/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
(original)
+++ poi/branches/common_sl/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
Sun May  3 23:42:42 2015
@@ -20,6 +20,8 @@ package org.apache.poi.hslf.model;
 import static org.junit.Assert.*;
 
 import java.awt.*;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Rectangle2D.Double;
 import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
@@ -136,6 +138,48 @@ public final class TestShapes {
         }
     }
 
+    @Test
+    public void testParagraphs() throws Exception {
+        HSLFSlideShow ppt = new HSLFSlideShow();
+        HSLFSlide slide = ppt.createSlide();
+        HSLFTextBox shape = new HSLFTextBox();
+        HSLFTextRun p1r1 = shape.setText("para 1 run 1. ");
+        HSLFTextRun p1r2 = shape.appendText("para 1 run 2.", false);
+        HSLFTextRun p2r1 = shape.appendText("para 2 run 1. ", true);
+        HSLFTextRun p2r2 = shape.appendText("para 2 run 2. ", false);
+        p1r1.setFontColor(Color.black);
+        p1r2.setFontColor(Color.red);
+        p2r1.setFontColor(Color.yellow);
+        p2r2.setStrikethrough(true);
+        // run 3 has same text properties as run 2 and will be merged when saving
+        HSLFTextRun p2r3 = shape.appendText("para 2 run 3.", false);
+        shape.setAnchor(new Rectangle2D.Double(100,100,100,10));
+        slide.addShape(shape);
+        shape.resizeToFitText();
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ppt.write(bos);
+        
+        ppt = new HSLFSlideShow(new ByteArrayInputStream(bos.toByteArray()));
+        slide = ppt.getSlides().get(0);
+        HSLFTextBox tb = (HSLFTextBox)slide.getShapes().get(0);
+        List<HSLFTextParagraph> para = tb.getTextParagraphs();
+        HSLFTextRun tr = para.get(0).getTextRuns().get(0);
+        assertEquals("para 1 run 1. ", tr.getRawText());
+        assertEquals(Color.black, tr.getFontColor());
+        tr = para.get(0).getTextRuns().get(1);
+        assertEquals("para 1 run 2.\r",  tr.getRawText());
+        assertEquals(Color.red, tr.getFontColor());
+        tr = para.get(1).getTextRuns().get(0);
+        assertEquals("para 2 run 1. ", tr.getRawText());
+        assertEquals(Color.yellow, tr.getFontColor());
+        tr = para.get(1).getTextRuns().get(1);
+        assertEquals("para 2 run 2. para 2 run 3.", tr.getRawText());
+        assertEquals(Color.black, tr.getFontColor());
+        assertTrue(tr.isStrikethrough());
+    }
+        
+    
     /**
      * Verify that we can add TextBox shapes to a slide
      * and set some of the style attributes
@@ -235,7 +279,11 @@ public final class TestShapes {
             for (HSLFShape sh : sld.getShapes()) {
                 if (sh instanceof HSLFTextShape){
                     HSLFTextShape tbox = (HSLFTextShape)sh;
-                    lst2.add(tbox.getText());
+                    for (HSLFTextParagraph p : tbox.getTextParagraphs()) {
+                        for (HSLFTextRun r : p) {
+                            lst2.add(r.getRawText());
+                        }
+                    }
                 }
             }
             assertTrue(lst1.containsAll(lst2));



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


Mime
View raw message