You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2015/07/24 23:47:58 UTC

svn commit: r1692593 [7/17] - in /poi: site/src/documentation/content/xdocs/ trunk/ trunk/src/examples/src/org/apache/poi/hslf/examples/ trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/ trunk/src/examples/src/org/apache/poi/xslf/usermodel...

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTableCell.java Fri Jul 24 21:47:55 2015
@@ -21,43 +21,24 @@ package org.apache.poi.xslf.usermodel;
 
 import java.awt.Color;
 
+import org.apache.poi.sl.usermodel.VerticalAlignment;
 import org.apache.poi.util.Units;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
-import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
-import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment;
-import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
 
 /**
  * Represents a cell of a table in a .pptx presentation
- *
- * @author Yegor Kozlov
  */
 public class XSLFTableCell extends XSLFTextShape {
     static double defaultBorderWidth = 1.0;
+    private CTTableCellProperties _tcPr = null;
 
     /*package*/ XSLFTableCell(CTTableCell cell, XSLFSheet sheet){
         super(cell, sheet);
     }
 
     @Override
-    public CTTableCell getXmlObject(){
-        return (CTTableCell)super.getXmlObject();
-    }
-
-    @Override
     protected CTTextBody getTextBody(boolean create){
-        CTTableCell cell = getXmlObject();
+        CTTableCell cell = (CTTableCell)getXmlObject();
         CTTextBody txBody = cell.getTxBody();
         if (txBody == null && create) {
             txBody = cell.addNewTxBody();
@@ -77,135 +58,72 @@ public class XSLFTableCell extends XSLFT
         return cell;
     }
 
+    protected CTTableCellProperties getCellProperties(boolean create) {
+        if (_tcPr == null) {
+            CTTableCell cell = (CTTableCell)getXmlObject();
+            _tcPr = cell.getTcPr();
+            if (_tcPr == null && create) {
+                _tcPr = cell.addNewTcPr();
+            }
+        }
+        return _tcPr;
+    }
+    
     @Override
     public void setLeftInset(double margin){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        if(pr == null) pr = getXmlObject().addNewTcPr();
-
+        CTTableCellProperties pr = getCellProperties(true);
         pr.setMarL(Units.toEMU(margin));
     }
 
     @Override
     public void setRightInset(double margin){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        if(pr == null) pr = getXmlObject().addNewTcPr();
-
+        CTTableCellProperties pr = getCellProperties(true);
         pr.setMarR(Units.toEMU(margin));
     }
 
     @Override
     public void setTopInset(double margin){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        if(pr == null) pr = getXmlObject().addNewTcPr();
-
+        CTTableCellProperties pr = getCellProperties(true);
         pr.setMarT(Units.toEMU(margin));
     }
 
     @Override
     public void setBottomInset(double margin){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        if(pr == null) pr = getXmlObject().addNewTcPr();
-
+        CTTableCellProperties pr = getCellProperties(true);
         pr.setMarB(Units.toEMU(margin));
     }
 
-    public void setBorderLeft(double width){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL();
-        ln.setW(Units.toEMU(width));
-    }
-
-    public double getBorderLeft(){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.getLnL();
-        return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());
-    }
-
-    public void setBorderLeftColor(Color color){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        CTLineProperties ln = pr.isSetLnL() ? pr.getLnL() : pr.addNewLnL();
-        setLineColor(ln, color);
-    }
-
-    public Color getBorderLeftColor(){
-        return getLineColor(getXmlObject().getTcPr().getLnL());
-    }
-
-    public void setBorderRight(double width){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR();
-        ln.setW(Units.toEMU(width));
-    }
-
-    public double getBorderRight(){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.getLnR();
-        return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());
-    }
-
-    public void setBorderRightColor(Color color){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        CTLineProperties ln = pr.isSetLnR() ? pr.getLnR() : pr.addNewLnR();
-        setLineColor(ln, color);
-    }
-
-    public Color getBorderRightColor(){
-        return getLineColor(getXmlObject().getTcPr().getLnR());
-    }
-
-    public void setBorderTop(double width){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT();
-        ln.setW(Units.toEMU(width));
-    }
-
-    public double getBorderTop(){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.getLnT();
-        return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());
-    }
-
-    public void setBorderTopColor(Color color){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        CTLineProperties ln = pr.isSetLnT() ? pr.getLnT() : pr.addNewLnT();
-        setLineColor(ln, color);
-    }
-
-    public Color getBorderTopColor(){
-        return getLineColor(getXmlObject().getTcPr().getLnT());
+    private CTLineProperties getCTLine(char bltr, boolean create) {
+        CTTableCellProperties pr = getCellProperties(create);
+        if (pr == null) return null;
+        
+        switch (bltr) {
+            case 'b':
+                return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null);
+            case 'l':
+                return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null);
+            case 't':
+                return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null);
+            case 'r':
+                return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null);
+            default:
+                return null;
+        }
     }
-
-    public void setBorderBottom(double width){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();
+    
+    private void setBorderWidth(char bltr, double width) {
+        CTLineProperties ln = getCTLine(bltr, true);
         ln.setW(Units.toEMU(width));
     }
 
-    public double getBorderBottom(){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-
-        CTLineProperties ln = pr.getLnB();
-        return ln == null || !ln.isSetW() ? defaultBorderWidth : Units.toPoints(ln.getW());
+    private double getBorderWidth(char bltr) {
+        CTLineProperties ln = getCTLine(bltr, false);
+        return (ln == null || !ln.isSetW()) ? defaultBorderWidth : Units.toPoints(ln.getW());
     }
 
-    public void setBorderBottomColor(Color color){
-        CTTableCellProperties pr = getXmlObject().getTcPr();
-        CTLineProperties ln = pr.isSetLnB() ? pr.getLnB() : pr.addNewLnB();
-        setLineColor(ln, color);
-    }
+    private void setBorderColor(char bltr, Color color) {
+        CTLineProperties ln = getCTLine(bltr, true);
 
-    public Color getBorderBottomColor(){
-        return getLineColor(getXmlObject().getTcPr().getLnB());
-    }
-
-    private void setLineColor(CTLineProperties ln, Color color){
         if(color == null){
             ln.addNewNoFill();
             if(ln.isSetSolidFill()) ln.unsetSolidFill();
@@ -232,19 +150,85 @@ public class XSLFTableCell extends XSLFT
             rgb.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
             ln.addNewSolidFill().setSrgbClr(rgb);
         }
-    }
-
-    private Color getLineColor(CTLineProperties ln){
-        if(ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
+    }    
+    
+    private Color getBorderColor(char bltr) {
+        CTLineProperties ln = getCTLine(bltr,false);
+        if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
 
         CTSolidColorFillProperties fill = ln.getSolidFill();
-        if(!fill.isSetSrgbClr()) {
+        if (!fill.isSetSrgbClr()) {
             // TODO for now return null for all colors except explicit RGB
             return null;
         }
         byte[] val = fill.getSrgbClr().getVal();
         return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+    }    
+    
+    public void setBorderLeft(double width) {
+        setBorderWidth('l', width);
     }
+
+    public double getBorderLeft() {
+        return getBorderWidth('l');
+    }
+
+    public void setBorderLeftColor(Color color) {
+        setBorderColor('l', color);
+    }
+
+    public Color getBorderLeftColor() {
+        return getBorderColor('l');
+    }
+
+    public void setBorderRight(double width) {
+        setBorderWidth('r', width);
+    }
+
+    public double getBorderRight() {
+        return getBorderWidth('r');
+    }
+
+    public void setBorderRightColor(Color color) {
+        setBorderColor('r', color);
+    }
+
+    public Color getBorderRightColor() {
+        return getBorderColor('r');
+    }
+
+    public void setBorderTop(double width) {
+        setBorderWidth('t', width);
+    }
+
+    public double getBorderTop() {
+        return getBorderWidth('t');
+    }
+
+    public void setBorderTopColor(Color color) {
+        setBorderColor('t', color);
+    }
+
+    public Color getBorderTopColor() {
+        return getBorderColor('t');
+    }
+
+    public void setBorderBottom(double width) {
+        setBorderWidth('b', width);
+    }
+
+    public double getBorderBottom() {
+        return getBorderWidth('b');
+    }
+
+    public void setBorderBottomColor(Color color) {
+        setBorderColor('b', color);
+    }
+
+    public Color getBorderBottomColor(){
+        return getBorderColor('b');
+    }
+
     /**
      * Specifies a solid color fill. The shape is filled entirely with the specified color.
      *
@@ -253,7 +237,7 @@ public class XSLFTableCell extends XSLFT
      */
     @Override
     public void setFillColor(Color color) {
-        CTTableCellProperties spPr = getXmlObject().getTcPr();
+        CTTableCellProperties spPr = getCellProperties(true);
         if (color == null) {
             if(spPr.isSetSolidFill()) spPr.unsetSolidFill();
         }
@@ -273,11 +257,11 @@ public class XSLFTableCell extends XSLFT
      */
     @Override
     public Color getFillColor(){
-        CTTableCellProperties spPr = getXmlObject().getTcPr();
-        if(!spPr.isSetSolidFill() ) return null;
+        CTTableCellProperties spPr = getCellProperties(false);
+        if (spPr == null || !spPr.isSetSolidFill()) return null;
 
         CTSolidColorFillProperties fill = spPr.getSolidFill();
-        if(!fill.isSetSrgbClr()) {
+        if (!fill.isSetSrgbClr()) {
             // TODO for now return null for all colors except explicit RGB
             return null;
         }
@@ -286,38 +270,36 @@ public class XSLFTableCell extends XSLFT
     }
 
     void setGridSpan(int gridSpan_) {
-    	getXmlObject().setGridSpan(gridSpan_);
+        ((CTTableCell)getXmlObject()).setGridSpan(gridSpan_);
     }
 
     void setRowSpan(int rowSpan_) {
-    	getXmlObject().setRowSpan(rowSpan_);
+        ((CTTableCell)getXmlObject()).setRowSpan(rowSpan_);
     }
 
     void setHMerge(boolean merge_) {
-    	getXmlObject().setHMerge(merge_);
+        ((CTTableCell)getXmlObject()).setHMerge(merge_);
     }
 
     void setVMerge(boolean merge_) {
-    	getXmlObject().setVMerge(merge_);
+        ((CTTableCell)getXmlObject()).setVMerge(merge_);
     }
     
     @Override
     public void setVerticalAlignment(VerticalAlignment anchor){
-    	CTTableCellProperties cellProps = getXmlObject().getTcPr();
-    	if(cellProps != null) {
-    		if(anchor == null) {
-    			if(cellProps.isSetAnchor()) {
-    				cellProps.unsetAnchor();
-    			}
-    		} else {
-				cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
+    	CTTableCellProperties cellProps = getCellProperties(true);
+		if(anchor == null) {
+			if(cellProps.isSetAnchor()) {
+				cellProps.unsetAnchor();
 			}
-    	}
+		} else {
+			cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
+		}
     }
 
     @Override
     public VerticalAlignment getVerticalAlignment(){
-        CTTableCellProperties cellProps = getXmlObject().getTcPr();
+        CTTableCellProperties cellProps = getCellProperties(false);
 
         VerticalAlignment align = VerticalAlignment.TOP;
         if(cellProps != null && cellProps.isSetAnchor()) {

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java Fri Jul 24 21:47:55 2015
@@ -17,43 +17,19 @@
 package org.apache.poi.xslf.usermodel;
 
 import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.font.LineBreakMeasurer;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.awt.geom.Rectangle2D;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
-import org.apache.poi.sl.usermodel.TextPainter;
+import org.apache.poi.sl.usermodel.AutoNumberingScheme;
+import org.apache.poi.sl.usermodel.TextParagraph;
 import org.apache.poi.util.Beta;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.Units;
 import org.apache.poi.xslf.model.ParagraphPropertyFetcher;
+import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextAutonumberBullet;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePercent;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextAutonumberScheme;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
 
@@ -65,16 +41,10 @@ import org.openxmlformats.schemas.presen
  * @since POI-3.8
  */
 @Beta
-public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
+public class XSLFTextParagraph implements TextParagraph<XSLFTextRun> {
     private final CTTextParagraph _p;
     private final List<XSLFTextRun> _runs;
     private final XSLFTextShape _shape;
-    private List<TextFragment> _lines;
-    private TextFragment _bullet;
-    /**
-     * the highest line in this paragraph. Used for line spacing.
-     */
-    private double _maxLineHeight;
 
     XSLFTextParagraph(CTTextParagraph p, XSLFTextShape shape){
         _p = p;
@@ -104,7 +74,7 @@ public class XSLFTextParagraph implement
     public String getText(){
         StringBuilder out = new StringBuilder();
         for (XSLFTextRun r : _runs) {
-            out.append(r.getText());
+            out.append(r.getRawText());
         }
         return out.toString();
     }
@@ -122,7 +92,7 @@ public class XSLFTextParagraph implement
         return _p;
     }
 
-    XSLFTextShape getParentShape() {
+    public XSLFTextShape getParentShape() {
         return _shape;
 
     }
@@ -173,11 +143,13 @@ public class XSLFTextParagraph implement
     /**
      * Returns the alignment that is applied to the paragraph.
      *
-     * If this attribute is omitted, then a value of left is implied.
-     * @return ??? alignment that is applied to the paragraph
+     * If this attribute is omitted, then null is returned.
+     * User code can imply the value {@link TextAlign#LEFT} then.
+     *
+     * @return alignment that is applied to the paragraph
      */
     public TextAlign getTextAlign(){
-        ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getLevel()){
+        ParagraphPropertyFetcher<TextAlign> fetcher = new ParagraphPropertyFetcher<TextAlign>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetAlgn()){
                     TextAlign val = TextAlign.values()[props.getAlgn().intValue() - 1];
@@ -188,13 +160,13 @@ public class XSLFTextParagraph implement
             }
         };
         fetchParagraphProperty(fetcher);
-        return fetcher.getValue() == null ? TextAlign.LEFT : fetcher.getValue();
+        return fetcher.getValue();
     }
 
     /**
      * Specifies the alignment that is to be applied to the paragraph.
      * Possible values for this include left, right, centered, justified and distributed,
-     * see {@link org.apache.poi.xslf.usermodel.TextAlign}.
+     * see {@link org.apache.poi.sl.usermodel.TextAlign}.
      *
      * @param align text align
      */
@@ -207,12 +179,45 @@ public class XSLFTextParagraph implement
         }
     }
 
+    @Override
+    public FontAlign getFontAlign(){
+        ParagraphPropertyFetcher<FontAlign> fetcher = new ParagraphPropertyFetcher<FontAlign>(getIndentLevel()){
+            public boolean fetch(CTTextParagraphProperties props){
+                if(props.isSetFontAlgn()){
+                    FontAlign val = FontAlign.values()[props.getFontAlgn().intValue() - 1];
+                    setValue(val);
+                    return true;
+                }
+                return false;
+            }
+        };
+        fetchParagraphProperty(fetcher);
+        return fetcher.getValue();
+    }
+
+    /**
+     * Specifies the font alignment that is to be applied to the paragraph.
+     * Possible values for this include auto, top, center, baseline and bottom.
+     * see {@link org.apache.poi.sl.usermodel.TextParagraph.FontAlign}.
+     *
+     * @param align font align
+     */
+    public void setFontAlign(FontAlign align){
+        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+        if(align == null) {
+            if(pr.isSetFontAlgn()) pr.unsetFontAlgn();
+        } else {
+            pr.setFontAlgn(STTextFontAlignType.Enum.forInt(align.ordinal() + 1));
+        }
+    }
+
+    
 
     /**
      * @return the font to be used on bullet characters within a given paragraph
      */
     public String getBulletFont(){
-        ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){
+        ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuFont()){
                     setValue(props.getBuFont().getTypeface());
@@ -235,7 +240,7 @@ public class XSLFTextParagraph implement
      * @return the character to be used in place of the standard bullet point
      */
     public String getBulletCharacter(){
-        ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getLevel()){
+        ParagraphPropertyFetcher<String> fetcher = new ParagraphPropertyFetcher<String>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuChar()){
                     setValue(props.getBuChar().getChar());
@@ -261,7 +266,7 @@ public class XSLFTextParagraph implement
      */
     public Color getBulletFontColor(){
         final XSLFTheme theme = getParentShape().getSheet().getTheme();
-        ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getLevel()){
+        ParagraphPropertyFetcher<Color> fetcher = new ParagraphPropertyFetcher<Color>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuClr()){
                     XSLFColor c = new XSLFColor(props.getBuClr(), theme, null);
@@ -297,8 +302,8 @@ public class XSLFTextParagraph implement
      *
      * @return the bullet size
      */
-    public double getBulletFontSize(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    public Double getBulletFontSize(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuSzPct()){
                     setValue(props.getBuSzPct().getVal() * 0.001);
@@ -312,7 +317,7 @@ public class XSLFTextParagraph implement
             }
         };
         fetchParagraphProperty(fetcher);
-        return fetcher.getValue() == null ? 100 : fetcher.getValue();
+        return fetcher.getValue();
     }
 
     /**
@@ -338,26 +343,60 @@ public class XSLFTextParagraph implement
    }
 
     /**
-     * Specifies the indent size that will be applied to the first line of text in the paragraph.
-     *
-     * @param value the indent in points. 
+     * @return the auto numbering scheme, or null if not defined
      */
-    public void setIndent(double value){
+    public AutoNumberingScheme getAutoNumberingScheme() {
+        ParagraphPropertyFetcher<AutoNumberingScheme> fetcher = new ParagraphPropertyFetcher<AutoNumberingScheme>(getIndentLevel()) {
+            public boolean fetch(CTTextParagraphProperties props) {
+                if (props.isSetBuAutoNum()) {
+                    AutoNumberingScheme ans = AutoNumberingScheme.forOoxmlID(props.getBuAutoNum().getType().intValue());
+                    if (ans != null) {
+                        setValue(ans);
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+        fetchParagraphProperty(fetcher);
+        return fetcher.getValue();
+    }
+
+    /**
+     * @return the auto numbering starting number, or null if not defined
+     */
+    public Integer getAutoNumberingStartAt() {
+        ParagraphPropertyFetcher<Integer> fetcher = new ParagraphPropertyFetcher<Integer>(getIndentLevel()) {
+            public boolean fetch(CTTextParagraphProperties props) {
+                if (props.isSetBuAutoNum()) {
+                    if (props.getBuAutoNum().isSetStartAt()) {
+                        setValue(props.getBuAutoNum().getStartAt());
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+        fetchParagraphProperty(fetcher);
+        return fetcher.getValue();
+    }
+    
+    
+    @Override
+    public void setIndent(Double indent){
+        if ((indent == null) && !_p.isSetPPr()) return;
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-        if(value == -1) {
+        if(indent == null) {
             if(pr.isSetIndent()) pr.unsetIndent();
         } else {
-            pr.setIndent(Units.toEMU(value));
+            pr.setIndent(Units.toEMU(indent));
         }
     }
 
-    /**
-     *
-     * @return the indent applied to the first line of text in the paragraph.
-     */
-    public double getIndent(){
+    @Override
+    public Double getIndent() {
 
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetIndent()){
                     setValue(Units.toPoints(props.getIndent()));
@@ -368,32 +407,27 @@ public class XSLFTextParagraph implement
         };
         fetchParagraphProperty(fetcher);
 
-        return fetcher.getValue() == null ? 0 : fetcher.getValue();
+        return fetcher.getValue();
     }
 
-    /**
-     * Specifies the left margin of the paragraph. This is specified in addition to the text body
-     * inset and applies only to this text paragraph. That is the text body Inset and the LeftMargin
-     * attributes are additive with respect to the text position.
-     *
-     * @param value the left margin of the paragraph
-     */
-    public void setLeftMargin(double value){
+    @Override
+    public void setLeftMargin(Double leftMargin){
+        if (leftMargin == null && !_p.isSetPPr()) return;
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-        if(value == -1) {
+        if (leftMargin == null) {
             if(pr.isSetMarL()) pr.unsetMarL();
         } else {
-            pr.setMarL(Units.toEMU(value));
+            pr.setMarL(Units.toEMU(leftMargin));
         }
 
     }
 
     /**
-     *
-     * @return the left margin of the paragraph
+     * @return the left margin (in points) of the paragraph, null if unset
      */
-    public double getLeftMargin(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    @Override
+    public Double getLeftMargin(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetMarL()){
                     double val = Units.toPoints(props.getMarL());
@@ -405,15 +439,43 @@ public class XSLFTextParagraph implement
         };
         fetchParagraphProperty(fetcher);
         // if the marL attribute is omitted, then a value of 347663 is implied
-        return fetcher.getValue() == null ? 0 : fetcher.getValue();
+        return fetcher.getValue();
+    }
+
+    @Override
+    public void setRightMargin(Double rightMargin){
+        if (rightMargin == null && !_p.isSetPPr()) return;
+        CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
+        if(rightMargin == null) {
+            if(pr.isSetMarR()) pr.unsetMarR();
+        } else {
+            pr.setMarR(Units.toEMU(rightMargin));
+        }
     }
 
     /**
      *
-     * @return the default size for a tab character within this paragraph in points
+     * @return the right margin of the paragraph, null if unset
      */
-    public double getDefaultTabSize(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    @Override
+    public Double getRightMargin(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
+            public boolean fetch(CTTextParagraphProperties props){
+                if(props.isSetMarR()){
+                    double val = Units.toPoints(props.getMarR());
+                    setValue(val);
+                    return true;
+                }
+                return false;
+            }
+        };
+        fetchParagraphProperty(fetcher);
+        return fetcher.getValue();
+    }
+
+    @Override
+    public Double getDefaultTabSize(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetDefTabSz()){
                     double val = Units.toPoints(props.getDefTabSz());
@@ -424,11 +486,11 @@ public class XSLFTextParagraph implement
             }
         };
         fetchParagraphProperty(fetcher);
-        return fetcher.getValue() == null ? 0 : fetcher.getValue();
+        return fetcher.getValue();
     }
 
     public double getTabStop(final int idx){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetTabLst()){
                     CTTextTabStopList tabStops = props.getTabLst();
@@ -452,47 +514,27 @@ 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
-     */
-    public void setLineSpacing(double linespacing){
+    @Override
+    public void setLineSpacing(Double lineSpacing){
+        if (lineSpacing == null && !_p.isSetPPr()) return;
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-        CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
-        if(linespacing >= 0) spc.addNewSpcPct().setVal((int)(linespacing*1000));
-        else spc.addNewSpcPts().setVal((int)(-linespacing*100));
-        pr.setLnSpc(spc);
+        if(lineSpacing == null) {
+            if (pr.isSetLnSpc()) pr.unsetLnSpc();
+        } else {
+            CTTextSpacing spc = (pr.isSetLnSpc()) ? pr.getLnSpc() : pr.addNewLnSpc();
+            if (lineSpacing >= 0) {
+                (spc.isSetSpcPct() ? spc.getSpcPct() : spc.addNewSpcPct()).setVal((int)(lineSpacing*1000));
+                if (spc.isSetSpcPts()) spc.unsetSpcPts();
+            } else {
+                (spc.isSetSpcPts() ? spc.getSpcPts() : spc.addNewSpcPts()).setVal((int)(-lineSpacing*100));
+                if (spc.isSetSpcPct()) spc.unsetSpcPct();
+            }
+        }
     }
 
-    /**
-     * 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.
-     */
-    public double getLineSpacing(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    @Override
+    public Double getLineSpacing(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetLnSpc()){
                     CTTextSpacing spc = props.getLnSpc();
@@ -506,8 +548,8 @@ public class XSLFTextParagraph implement
         };
         fetchParagraphProperty(fetcher);
 
-        double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue();
-        if(lnSpc > 0) {
+        Double lnSpc = fetcher.getValue();
+        if (lnSpc != null && lnSpc > 0) {
             // check if the percentage value is scaled
             CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit();
             if(normAutofit != null) {
@@ -519,26 +561,9 @@ public class XSLFTextParagraph implement
         return lnSpc;
     }
 
-    /**
-     * Set the amount of vertical white space that will be present before the paragraph.
-     * This space is specified in either percentage or points:
-     * <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
-     * </p>
-     * Examples:
-     * <pre><code>
-     *      // The paragraph will be formatted to have a spacing before the paragraph text.
-     *      // The spacing will be 200% of the size of the largest text on each line
-     *      paragraph.setSpaceBefore(200);
-     *
-     *      // The spacing will be a size of 48 points
-     *      paragraph.setSpaceBefore(-48.0);
-     * </code></pre>
-     *
-     * @param spaceBefore the vertical white space before the paragraph.
-     */
-    public void setSpaceBefore(double spaceBefore){
+    @Override
+    public void setSpaceBefore(Double spaceBefore){
+        if (spaceBefore == null && !_p.isSetPPr()) return;
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
         CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
         if(spaceBefore >= 0) spc.addNewSpcPct().setVal((int)(spaceBefore*1000));
@@ -546,18 +571,9 @@ public class XSLFTextParagraph implement
         pr.setSpcBef(spc);
     }
 
-    /**
-     * The amount of vertical white space before the paragraph
-     * 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
-     * </p>
-     *
-     * @return the vertical white space before the paragraph
-     */
-    public double getSpaceBefore(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    @Override
+    public Double getSpaceBefore(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetSpcBef()){
                     CTTextSpacing spc = props.getSpcBef();
@@ -571,30 +587,11 @@ public class XSLFTextParagraph implement
         };
         fetchParagraphProperty(fetcher);
 
-        double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue();
-        return spcBef;
+        return fetcher.getValue();
     }
 
-    /**
-     * Set the amount of vertical white space that will be present after the paragraph.
-     * This space is specified in either percentage or points:
-     * <p>
-     * If spaceAfter >= 0, then space is a percentage of normal line height.
-     * If spaceAfter < 0, the absolute value of linespacing is the spacing in points
-     * </p>
-     * Examples:
-     * <pre><code>
-     *      // The paragraph will be formatted to have a spacing after the paragraph text.
-     *      // The spacing will be 200% of the size of the largest text on each line
-     *      paragraph.setSpaceAfter(200);
-     *
-     *      // The spacing will be a size of 48 points
-     *      paragraph.setSpaceAfter(-48.0);
-     * </code></pre>
-     *
-     * @param spaceAfter the vertical white space after the paragraph.
-     */
-    public void setSpaceAfter(double spaceAfter){
+    @Override
+    public void setSpaceAfter(Double spaceAfter){
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
         CTTextSpacing spc = CTTextSpacing.Factory.newInstance();
         if(spaceAfter >= 0) spc.addNewSpcPct().setVal((int)(spaceAfter*1000));
@@ -602,18 +599,9 @@ public class XSLFTextParagraph implement
         pr.setSpcAft(spc);
     }
 
-    /**
-     * The amount of vertical white space after the paragraph
-     * 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
-     * </p>
-     *
-     * @return the vertical white space after the paragraph
-     */
-    public double getSpaceAfter(){
-        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){
+    @Override
+    public Double getSpaceAfter(){
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetSpcAft()){
                     CTTextSpacing spc = props.getSpcAft();
@@ -626,39 +614,26 @@ public class XSLFTextParagraph implement
             }
         };
         fetchParagraphProperty(fetcher);
-        return fetcher.getValue() == null ? 0 : fetcher.getValue();
+        return fetcher.getValue();
     }
 
-    /**
-     * Specifies the particular level text properties that this paragraph will follow.
-     * The value for this attribute formats the text according to the corresponding level
-     * paragraph properties defined in the SlideMaster.
-     *
-     * @param level the level (0 ... 4)
-     */
-    public void setLevel(int level){
+    @Override
+    public void setIndentLevel(int level){
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-
         pr.setLvl(level);
     }
 
-    /**
-     *
-     * @return the text level of this paragraph (0-based). Default is 0.
-     */
-    public int getLevel(){
+    @Override
+    public int getIndentLevel() {
         CTTextParagraphProperties pr = _p.getPPr();
-        if(pr == null) return 0;
-
-        return pr.getLvl();
-
+        return (pr == null || !pr.isSetLvl()) ? 0 : pr.getLvl();
     }
 
     /**
      * Returns whether this paragraph has bullets
      */
     public boolean isBullet() {
-        ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getLevel()){
+        ParagraphPropertyFetcher<Boolean> fetcher = new ParagraphPropertyFetcher<Boolean>(getIndentLevel()){
             public boolean fetch(CTTextParagraphProperties props){
                 if(props.isSetBuNone()) {
                     setValue(false);
@@ -683,11 +658,22 @@ public class XSLFTextParagraph implement
         if(isBullet() == flag) return;
 
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
-        if(!flag) {
-            pr.addNewBuNone();
-        } else {
+        if(flag) {
             pr.addNewBuFont().setTypeface("Arial");
             pr.addNewBuChar().setChar("\u2022");
+        } else {
+            if (pr.isSetBuFont()) pr.unsetBuFont();
+            if (pr.isSetBuChar()) pr.unsetBuChar();
+            if (pr.isSetBuAutoNum()) pr.unsetBuAutoNum();
+            if (pr.isSetBuBlip()) pr.unsetBuBlip();
+            if (pr.isSetBuClr()) pr.unsetBuClr();
+            if (pr.isSetBuClrTx()) pr.unsetBuClrTx();
+            if (pr.isSetBuFont()) pr.unsetBuFont();
+            if (pr.isSetBuFontTx()) pr.unsetBuFontTx();
+            if (pr.isSetBuSzPct()) pr.unsetBuSzPct();
+            if (pr.isSetBuSzPts()) pr.unsetBuSzPts();
+            if (pr.isSetBuSzTx()) pr.unsetBuSzTx();
+            pr.addNewBuNone();
         }
     }
 
@@ -698,11 +684,11 @@ public class XSLFTextParagraph implement
      * @param startAt the number that will start number for a given sequence of automatically
     numbered bullets (1-based).
      */
-    public void setBulletAutoNumber(ListAutoNumber scheme, int startAt) {
+    public void setBulletAutoNumber(AutoNumberingScheme scheme, int startAt) {
         if(startAt < 1) throw new IllegalArgumentException("Start Number must be greater or equal that 1") ;
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();
         CTTextAutonumberBullet lst = pr.isSetBuAutoNum() ? pr.getBuAutoNum() : pr.addNewBuAutoNum();
-        lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ordinal() + 1));
+        lst.setType(STTextAutonumberScheme.Enum.forInt(scheme.ooxmlId));
         lst.setStartAt(startAt);
     }
 
@@ -711,334 +697,72 @@ public class XSLFTextParagraph implement
         return "[" + getClass() + "]" + getText();
     }
 
-    List<TextFragment> getTextLines(){
-        return _lines;
-    }
-
-    /**
-     * Returns wrapping width to break lines in this paragraph
-     *
-     * @param firstLine whether the first line is breaking
-     *
-     * @return  wrapping width in points
-     */
-    double getWrappingWidth(boolean firstLine, Graphics2D graphics){
-        // internal margins for the text box
-        double leftInset = _shape.getLeftInset();
-        double rightInset = _shape.getRightInset();
-
-        RenderableShape rShape = new RenderableShape(_shape);
-        Rectangle2D anchor = rShape.getAnchor(graphics);
-
-        double leftMargin = getLeftMargin();
-        double indent = getIndent();
-
-        double width;
-        if(!_shape.getWordWrap()) {
-            // if wordWrap == false then we return the advance to the right border of the sheet
-            width = _shape.getSheet().getSlideShow().getPageSize().getWidth() - anchor.getX();
-        } else {
-            width = anchor.getWidth() -  leftInset - rightInset - leftMargin;
-            if(firstLine) {
-                if(isBullet()){
-                    if(indent > 0) width -= indent;
-                } else {
-                    if(indent > 0) width -= indent; // first line indentation
-                    else if (indent < 0) { // hanging indentation: the first line start at the left margin
-                        width += leftMargin;
-                    }
-                }
-            }
-        }
-
-        return width;
-    }
-
-    public double draw(Graphics2D graphics, double x, double y){
-        double leftInset = _shape.getLeftInset();
-        double rightInset = _shape.getRightInset();
-        RenderableShape rShape = new RenderableShape(_shape);
-        Rectangle2D anchor = rShape.getAnchor(graphics);
-        double penY = y;
-
-        double leftMargin = getLeftMargin();
-        boolean firstLine = true;
-        double indent = getIndent();
-
-        //The vertical line spacing
-        double spacing = getLineSpacing();
-        for(TextFragment line : _lines){
-            double penX = x + leftMargin;
-
-            if(firstLine) {
-                if(_bullet != null){
-                    if(indent < 0) {
-                        // a negative value means "Hanging" indentation and
-                        // indicates the position of the actual bullet character.
-                        // (the bullet is shifted to right relative to the text)
-                        _bullet.draw(graphics, penX + indent,  penY);
-                    } else if(indent > 0){
-                        // a positive value means the "First Line" indentation:
-                        // the first line is indented and other lines start at the bullet ofset
-                        _bullet.draw(graphics, penX,  penY);
-                        penX += indent;
-                    } else {
-                        // a zero indent means that the bullet and text have the same offset
-                        _bullet.draw(graphics, penX,  penY);
-
-                        // don't let text overlay the bullet and advance by the bullet width
-                        penX += _bullet._layout.getAdvance() + 1;
-                    }
-                } else {
-                    penX += indent;
-                }
-            }
-
-
-            switch (getTextAlign()) {
-                case CENTER:
-                    penX += (anchor.getWidth() - leftMargin - line.getWidth() - leftInset - rightInset) / 2;
-                    break;
-                case RIGHT:
-                    penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);
-                    break;
-                default:
-                    break;
-            }
-
-            line.draw(graphics, penX,  penY);
-
-            if(spacing > 0) {
-                // If linespacing >= 0, then linespacing is a percentage of normal line height.
-                penY += spacing*0.01* line.getHeight();
-            } else {
-                // positive value means absolute spacing in points
-                penY += -spacing;
-            }
-
-            firstLine = false;
-        }
-        
-        return penY - y;
-    }
-
-    AttributedString getAttributedString(Graphics2D graphics){
-
-        String text = getRenderableText();
-
-        AttributedString string = new AttributedString(text);
-
-        XSLFFontManager fontHandler = (XSLFFontManager)graphics.getRenderingHint(XSLFRenderingHint.FONT_HANDLER);
-
-        int startIndex = 0;
-        for (XSLFTextRun run : _runs){
-            int length = run.getRenderableText().length();
-            if(length == 0) {
-                // skip empty runs
-                continue;
-            }
-            int endIndex = startIndex + length;
-
-            string.addAttribute(TextAttribute.FOREGROUND, run.getFontColor(), startIndex, endIndex);
-
-            // user can pass an custom object to convert fonts
-            String fontFamily = run.getFontFamily();
-            @SuppressWarnings("unchecked")
-            Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(TextPainter.KEY_FONTMAP);
-            if (fontMap != null && fontMap.containsKey(fontFamily)) {
-                fontFamily = fontMap.get(fontFamily);
-            }
-            if(fontHandler != null) {
-                fontFamily = fontHandler.getRendererableFont(fontFamily, run.getPitchAndFamily());
-            }
-            string.addAttribute(TextAttribute.FAMILY, fontFamily, startIndex, endIndex);
-
-            float fontSz = (float)run.getFontSize();
-            string.addAttribute(TextAttribute.SIZE, fontSz , startIndex, endIndex);
-
-            if(run.isBold()) {
-                string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex);
-            }
-            if(run.isItalic()) {
-                string.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIndex, endIndex);
-            }
-            if(run.isUnderline()) {
-                string.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIndex, endIndex);
-                string.addAttribute(TextAttribute.INPUT_METHOD_UNDERLINE, TextAttribute.UNDERLINE_LOW_TWO_PIXEL, startIndex, endIndex);
-            }
-            if(run.isStrikethrough()) {
-                string.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, startIndex, endIndex);
-            }
-            if(run.isSubscript()) {
-                string.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUB, startIndex, endIndex);
-            }
-            if(run.isSuperscript()) {
-                string.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, startIndex, endIndex);
-            }
-
-
-            startIndex = endIndex;
-        }
-
-        return string;
-    }
-
-    /**
-     *  ensure that the paragraph contains at least one character.
-     *  We need this trick to correctly measure text
-     */
-    private void ensureNotEmpty(){
-        XSLFTextRun r = addNewTextRun();
-        r.setText(" ");
-        CTTextCharacterProperties endPr = _p.getEndParaRPr();
-        if(endPr != null) {
-            if(endPr.isSetSz()) r.setFontSize(endPr.getSz() / 100);
-        }
-    }
-
-    /**
-     * break text into lines
-     *
-     * @param graphics
-     * @return array of text fragments,
-     * each representing a line of text that fits in the wrapping width
-     */
-    List<TextFragment> breakText(Graphics2D graphics){
-        _lines = new ArrayList<TextFragment>();
-
-        // does this paragraph contain text?
-        boolean emptyParagraph = _runs.size() == 0;
-
-        // ensure that the paragraph contains at least one character
-        if(_runs.size() == 0) ensureNotEmpty();
-
-        String text = getRenderableText();
-        if(text.length() == 0) return _lines;
 
-        AttributedString at = getAttributedString(graphics);
-        AttributedCharacterIterator it = at.getIterator();
-        LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext())  ;
-        for (;;) {
-            int startIndex = measurer.getPosition();
-
-            double wrappingWidth = getWrappingWidth(_lines.size() == 0, graphics) + 1; // add a pixel to compensate rounding errors
-            // shape width can be smaller that the sum of insets (this was proved by a test file)
-            if(wrappingWidth < 0) wrappingWidth = 1;
-
-            int nextBreak = text.indexOf('\n', startIndex + 1);
-            if(nextBreak == -1) nextBreak = it.getEndIndex();
-
-            TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);
-            if (layout == null) {
-                 // layout can be null if the entire word at the current position
-                 // does not fit within the wrapping width. Try with requireNextWord=false.
-                 layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false);
-            }
-
-            if(layout == null) {
-                // exit if can't break any more
-                break;
-            }
-
-            int endIndex = measurer.getPosition();
-            // skip over new line breaks (we paint 'clear' text runs not starting or ending with \n)
-            if(endIndex < it.getEndIndex() && text.charAt(endIndex) == '\n'){
-                measurer.setPosition(endIndex + 1);
-            }
-
-            TextAlign hAlign = getTextAlign();
-            if(hAlign == TextAlign.JUSTIFY || hAlign == TextAlign.JUSTIFY_LOW) {
-                layout = layout.getJustifiedLayout((float)wrappingWidth);
-            }
-
-            AttributedString str = new AttributedString(it, startIndex, endIndex);
-            TextFragment line = new TextFragment(
-                    layout, // we will not paint empty paragraphs
-                    emptyParagraph ? null : str);
-            _lines.add(line);
-
-            _maxLineHeight = Math.max(_maxLineHeight, line.getHeight());
-
-            if(endIndex == it.getEndIndex()) break;
-
-        }
-
-        if(isBullet() && !emptyParagraph) {
-            String buCharacter = getBulletCharacter();
-            String buFont = getBulletFont();
-            if(buFont == null) buFont = getTextRuns().get(0).getFontFamily();
-            if(buCharacter != null && buFont != null && _lines.size() > 0) {
-                AttributedString str = new AttributedString(buCharacter);
-
-                TextFragment firstLine = _lines.get(0);
-                AttributedCharacterIterator bit = firstLine._str.getIterator();
-
-                Color buColor = getBulletFontColor();
-                str.addAttribute(TextAttribute.FOREGROUND, buColor == null ?
-                        bit.getAttribute(TextAttribute.FOREGROUND) : buColor);
-                str.addAttribute(TextAttribute.FAMILY, buFont);
-
-                float fontSize = (Float)bit.getAttribute(TextAttribute.SIZE);
-                float buSz = (float)getBulletFontSize();
-                if(buSz > 0) fontSize *= buSz* 0.01;
-                else fontSize = -buSz;
-
-                str.addAttribute(TextAttribute.SIZE, fontSize);
-
-                TextLayout layout = new TextLayout(str.getIterator(), graphics.getFontRenderContext());
-                _bullet = new TextFragment(layout, str);
-            }
-        }
-        return _lines;
-    }
-
-    CTTextParagraphProperties getDefaultMasterStyle(){
+    /* package */ CTTextParagraphProperties getDefaultMasterStyle(){
         CTPlaceholder ph = _shape.getCTPlaceholder();
-        String defaultStyleSelector;
-        if(ph == null) defaultStyleSelector = "otherStyle";   // no placeholder means plain text box
-        else {
-            switch(ph.getType().intValue()){
-                case STPlaceholderType.INT_TITLE:
-                case STPlaceholderType.INT_CTR_TITLE:
-                    defaultStyleSelector = "titleStyle";
-                    break;
-                case STPlaceholderType.INT_FTR:
-                case STPlaceholderType.INT_SLD_NUM:
-                case STPlaceholderType.INT_DT:
-                    defaultStyleSelector = "otherStyle";
-                    break;
-                default:
-                    defaultStyleSelector = "bodyStyle";
-                    break;
-            }
+        String defaultStyleSelector;   
+        switch(ph == null ? -1 : ph.getType().intValue()) {
+            case STPlaceholderType.INT_TITLE:
+            case STPlaceholderType.INT_CTR_TITLE:
+                defaultStyleSelector = "titleStyle";
+                break;
+            case -1: // no placeholder means plain text box
+            case STPlaceholderType.INT_FTR:
+            case STPlaceholderType.INT_SLD_NUM:
+            case STPlaceholderType.INT_DT:
+                defaultStyleSelector = "otherStyle";
+                break;
+            default:
+                defaultStyleSelector = "bodyStyle";
+                break;
         }
-        int level = getLevel();
+        int level = getIndentLevel();
 
         // wind up and find the root master sheet which must be slide master
+        final String nsDecl =
+            "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
+            "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' ";
+        final String xpaths[] = {
+            nsDecl+".//p:txStyles/p:" + defaultStyleSelector +"/a:lvl" +(level+1)+ "pPr",
+            nsDecl+".//p:notesStyle/a:lvl" +(level+1)+ "pPr"
+        };
         XSLFSheet masterSheet = _shape.getSheet();
-        while (masterSheet.getMasterSheet() != null){
-            masterSheet = masterSheet.getMasterSheet();
-        }
+        for (XSLFSheet m = masterSheet; m != null; m = (XSLFSheet)m.getMasterSheet()) {
+            masterSheet = m;
 
-        XmlObject[] o = masterSheet.getXmlObject().selectPath(
-                "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
-                "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
-                ".//p:txStyles/p:" + defaultStyleSelector +"/a:lvl" +(level+1)+ "pPr");
-        if (o.length == 1){
-            return (CTTextParagraphProperties)o[0];
-        } else {
-                o = masterSheet.getXmlObject().selectPath(
-                "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' " +
-                "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
-                ".//p:notesStyle/a:lvl" +(level+1)+ "pPr");
-                
-            if (o.length == 1){
-                return (CTTextParagraphProperties)o[0];
+            XmlObject xo = masterSheet.getXmlObject();
+            for (String xpath : xpaths) {
+                XmlObject[] o = xo.selectPath(xpath);
+                if (o.length == 1) {
+                    return (CTTextParagraphProperties)o[0];
+                }
             }
-            
-            throw new IllegalArgumentException("Failed to fetch default style for " +
-                    defaultStyleSelector + " and level=" + level);
         }
+
+        
+//        for (CTTextBody txBody : (CTTextBody[])xo.selectPath(nsDecl+".//p:txBody")) {
+//            CTTextParagraphProperties defaultPr = null, lastPr = null;
+//            boolean hasLvl = false;
+//            for (CTTextParagraph p : txBody.getPArray()) {
+//                CTTextParagraphProperties pr = p.getPPr();
+//                if (pr.isSetLvl()) {
+//                    hasLvl |= true;
+//                    lastPr = pr;
+//                    if (pr.getLvl() == level) return pr;
+//                } else {
+//                    defaultPr = pr;
+//                }
+//            }
+//            if (!hasLvl) continue;
+//            if (level == 0 && defaultPr != null) return defaultPr;
+//            if (lastPr != null) return lastPr;
+//            break;
+//        }
+//           
+//        String err = "Failed to fetch default style for " + defaultStyleSelector + " and level=" + level;
+//        throw new IllegalArgumentException(err);
+        
+        return null;
     }
 
     private <T> boolean fetchParagraphProperty(ParagraphPropertyFetcher<T> visitor){
@@ -1054,7 +778,7 @@ public class XSLFTextParagraph implement
                 if(ph == null){
                     // if it is a plain text box then take defaults from presentation.xml
                     XMLSlideShow ppt = getParentShape().getSheet().getSlideShow();
-                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getLevel());
+                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(getIndentLevel());
                     if(themeProps != null) ok = visitor.fetch(themeProps);
                 }
 
@@ -1069,65 +793,147 @@ public class XSLFTextParagraph implement
         return ok;
     }
 
-    void copy(XSLFTextParagraph p){
-        TextAlign srcAlign = p.getTextAlign();
+    void copy(XSLFTextParagraph other){
+        if (other == this) return;
+        
+        CTTextParagraph thisP = getXmlObject();
+        CTTextParagraph otherP = other.getXmlObject();
+        
+        if (thisP.isSetPPr()) thisP.unsetPPr();
+        if (thisP.isSetEndParaRPr()) thisP.unsetEndParaRPr();
+        
+        _runs.clear();
+        for (int i=thisP.sizeOfBrArray(); i>0; i--) {
+            thisP.removeBr(i-1);
+        }
+        for (int i=thisP.sizeOfRArray(); i>0; i--) {
+            thisP.removeR(i-1);
+        }
+        for (int i=thisP.sizeOfFldArray(); i>0; i--) {
+            thisP.removeFld(i-1);
+        }
+
+        XmlCursor thisC = thisP.newCursor();
+        thisC.toEndToken();
+        XmlCursor otherC = otherP.newCursor();
+        otherC.copyXmlContents(thisC);
+        otherC.dispose();
+        thisC.dispose();
+        
+        List<XSLFTextRun> otherRs = other.getTextRuns();
+        int i=0;
+        for(CTRegularTextRun rtr : thisP.getRArray()) {
+            XSLFTextRun run = new XSLFTextRun(rtr, this);
+            run.copy(otherRs.get(i++));
+            _runs.add(run);
+        }
+        
+        
+        // set properties again, in case we are based on a different
+        // template
+        TextAlign srcAlign = other.getTextAlign();
         if(srcAlign != getTextAlign()){
             setTextAlign(srcAlign);
         }
 
-        boolean isBullet = p.isBullet();
+        boolean isBullet = other.isBullet();
         if(isBullet != isBullet()){
             setBullet(isBullet);
             if(isBullet) {
-                String buFont = p.getBulletFont();
+                String buFont = other.getBulletFont();
                 if(buFont != null && !buFont.equals(getBulletFont())){
                     setBulletFont(buFont);
                 }
-                String buChar = p.getBulletCharacter();
+                String buChar = other.getBulletCharacter();
                 if(buChar != null && !buChar.equals(getBulletCharacter())){
                     setBulletCharacter(buChar);
                 }
-                Color buColor = p.getBulletFontColor();
+                Color buColor = other.getBulletFontColor();
                 if(buColor != null && !buColor.equals(getBulletFontColor())){
                     setBulletFontColor(buColor);
                 }
-                double buSize = p.getBulletFontSize();
-                if(buSize != getBulletFontSize()){
+                Double buSize = other.getBulletFontSize();
+                if(!doubleEquals(buSize, getBulletFontSize())){
                     setBulletFontSize(buSize);
                 }
             }
         }
 
-        double leftMargin = p.getLeftMargin();
-        if(leftMargin != getLeftMargin()){
+        Double leftMargin = other.getLeftMargin();
+        if (!doubleEquals(leftMargin, getLeftMargin())){
             setLeftMargin(leftMargin);
         }
 
-        double indent = p.getIndent();
-        if(indent != getIndent()){
+        Double indent = other.getIndent();
+        if (!doubleEquals(indent, getIndent())) {
             setIndent(indent);
         }
 
-        double spaceAfter = p.getSpaceAfter();
-        if(spaceAfter != getSpaceAfter()){
+        Double spaceAfter = other.getSpaceAfter();
+        if (!doubleEquals(spaceAfter, getSpaceAfter())) {
             setSpaceAfter(spaceAfter);
         }
-        double spaceBefore = p.getSpaceBefore();
-        if(spaceBefore != getSpaceBefore()){
+        
+        Double spaceBefore = other.getSpaceBefore();
+        if (!doubleEquals(spaceBefore, getSpaceBefore())) {
             setSpaceBefore(spaceBefore);
         }
-        double lineSpacing = p.getLineSpacing();
-        if(lineSpacing != getLineSpacing()){
+        
+        Double lineSpacing = other.getLineSpacing();
+        if (!doubleEquals(lineSpacing, getLineSpacing())) {
             setLineSpacing(lineSpacing);
         }
+    }
 
-        List<XSLFTextRun> srcR = p.getTextRuns();
-        List<XSLFTextRun> tgtR = getTextRuns();
-        for(int i = 0; i < srcR.size(); i++){
-            XSLFTextRun r1 = srcR.get(i);
-            XSLFTextRun r2 = tgtR.get(i);
-            r2.copy(r1);
-        }
+    private static boolean doubleEquals(Double d1, Double d2) {
+        return (d1 == d2 || (d1 != null && d1.equals(d2)));
+    }
+    
+    @Override
+    public Double getDefaultFontSize() {
+        CTTextCharacterProperties endPr = _p.getEndParaRPr();
+        return (endPr == null || !endPr.isSetSz()) ? 12 : (endPr.getSz() / 100.);
     }
 
+    @Override
+    public String getDefaultFontFamily() {
+        return (_runs.isEmpty() ? "Arial" : _runs.get(0).getFontFamily());
+    }
+
+    @Override
+    public BulletStyle getBulletStyle() {
+        if (!isBullet()) return null;
+        return new BulletStyle(){
+            @Override
+            public String getBulletCharacter() {
+                return XSLFTextParagraph.this.getBulletCharacter();
+            }
+
+            @Override
+            public String getBulletFont() {
+                return XSLFTextParagraph.this.getBulletFont();
+            }
+
+            @Override
+            public Double getBulletFontSize() {
+                return XSLFTextParagraph.this.getBulletFontSize();
+            }
+
+            @Override
+            public Color getBulletFontColor() {
+                return XSLFTextParagraph.this.getBulletFontColor();
+            }
+            
+            @Override
+            public AutoNumberingScheme getAutoNumberingScheme() {
+                return XSLFTextParagraph.this.getAutoNumberingScheme();
+            }
+
+            @Override
+            public Integer getAutoNumberingStartAt() {
+                return XSLFTextParagraph.this.getAutoNumberingStartAt();
+            }
+
+        };
+    }
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java?rev=1692593&r1=1692592&r2=1692593&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java Fri Jul 24 21:47:55 2015
@@ -17,25 +17,11 @@
 package org.apache.poi.xslf.usermodel;
 
 import java.awt.Color;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.text.AttributedString;
 
+import org.apache.poi.sl.usermodel.TextRun;
 import org.apache.poi.util.Beta;
 import org.apache.poi.xslf.model.CharacterPropertyFetcher;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
-import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
 
 /**
@@ -45,7 +31,7 @@ import org.openxmlformats.schemas.presen
  * @author Yegor Kozlov
  */
 @Beta
-public class XSLFTextRun {
+public class XSLFTextRun implements TextRun {
     private final CTRegularTextRun _r;
     private final XSLFTextParagraph _p;
 
@@ -58,7 +44,7 @@ public class XSLFTextRun {
         return _p;
     }
 
-    public String getText(){
+    public String getRawText(){
         return _r.getT();
     }
 
@@ -88,28 +74,6 @@ public class XSLFTextRun {
         return buf.toString();
     }
 
-    /**
-     * Replace a tab with the effective number of white spaces.
-     */
-    private String tab2space(){
-        AttributedString string = new AttributedString(" ");
-        // user can pass an object to convert fonts via a rendering hint
-        string.addAttribute(TextAttribute.FAMILY, getFontFamily());
-
-        string.addAttribute(TextAttribute.SIZE, (float)getFontSize());
-        TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true));
-        double wspace = l.getAdvance();
-
-        double tabSz = _p.getDefaultTabSize();
-
-        int numSpaces = (int)Math.ceil(tabSz / wspace);
-        StringBuffer buf = new StringBuffer();
-        for(int i = 0; i < numSpaces; i++) {
-            buf.append(' ');
-        }
-        return buf.toString();
-    }
-    
     public void setText(String text){
         _r.setT(text);
     }
@@ -118,7 +82,8 @@ public class XSLFTextRun {
         return _r;
     }
 
-    public void setFontColor(Color color){
+    @Override
+    public void setFontColor(Color color) {
         CTTextCharacterProperties rPr = getRPr();
         CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
         CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
@@ -132,12 +97,13 @@ public class XSLFTextRun {
 
     }
 
+    @Override
     public Color getFontColor(){
         final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
         CTShapeStyle style = _p.getParentShape().getSpStyle();
         final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();
 
-        CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){
+        CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 CTSolidColorFillProperties solidFill = props.getSolidFill();
                 if(solidFill != null) {
@@ -155,17 +121,13 @@ public class XSLFTextRun {
         return fetcher.getValue();
     }
 
-    /**
-     *
-     * @param fontSize  font size in points.
-     * The value of <code>-1</code> unsets the Sz attribyte from the underlying xml bean
-     */
-    public void setFontSize(double fontSize){
+    @Override
+    public void setFontSize(Double fontSize){
         CTTextCharacterProperties rPr = getRPr();
-        if(fontSize == -1.0) {
-            if(rPr.isSetSz()) rPr.unsetSz();
+        if(fontSize == null) {
+            if (rPr.isSetSz()) rPr.unsetSz();
         } else {
-            if(fontSize < 1.0) {
+            if (fontSize < 1.0) {
                 throw new IllegalArgumentException("Minimum font size is 1pt but was " + fontSize);
             }
 
@@ -173,15 +135,13 @@ public class XSLFTextRun {
         }
     }
 
-    /**
-     * @return font size in points or -1 if font size is not set.
-     */
-    public double getFontSize(){
+    @Override
+    public Double getFontSize(){
         double scale = 1;
         CTTextNormalAutofit afit = getParentParagraph().getParentShape().getTextBodyPr().getNormAutofit();
         if(afit != null) scale = (double)afit.getFontScale() / 100000;
 
-        CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){
+        CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetSz()){
                     setValue(props.getSz()*0.01);
@@ -191,7 +151,7 @@ public class XSLFTextRun {
             }
         };
         fetchCharacterProperty(fetcher);
-        return fetcher.getValue() == null ? -1 : fetcher.getValue()*scale;
+        return fetcher.getValue() == null ? null : fetcher.getValue()*scale;
     }
 
     /**
@@ -201,7 +161,7 @@ public class XSLFTextRun {
      */
     public double getCharacterSpacing(){
 
-        CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getLevel()){
+        CharacterPropertyFetcher<Double> fetcher = new CharacterPropertyFetcher<Double>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetSpc()){
                     setValue(props.getSpc()*0.01);
@@ -268,7 +228,7 @@ public class XSLFTextRun {
     public String getFontFamily(){
         final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
 
-        CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getLevel()){
+        CharacterPropertyFetcher<String> visitor = new CharacterPropertyFetcher<String>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 CTTextFont font = props.getLatin();
                 if(font != null){
@@ -292,7 +252,7 @@ public class XSLFTextRun {
     public byte getPitchAndFamily(){
         final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();
 
-        CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getLevel()){
+        CharacterPropertyFetcher<Byte> visitor = new CharacterPropertyFetcher<Byte>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 CTTextFont font = props.getLatin();
                 if(font != null){
@@ -320,7 +280,7 @@ public class XSLFTextRun {
      * @return whether a run of text will be formatted as strikethrough text. Default is false.
      */
     public boolean isStrikethrough() {
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetStrike()){
                     setValue(props.getStrike() != STTextStrikeType.NO_STRIKE);
@@ -337,7 +297,7 @@ public class XSLFTextRun {
      * @return whether a run of text will be formatted as a superscript text. Default is false.
      */
     public boolean isSuperscript() {
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetBaseline()){
                     setValue(props.getBaseline() > 0);
@@ -387,7 +347,7 @@ public class XSLFTextRun {
      * @return whether a run of text will be formatted as a superscript text. Default is false.
      */
     public boolean isSubscript() {
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetBaseline()){
                     setValue(props.getBaseline() < 0);
@@ -404,7 +364,7 @@ public class XSLFTextRun {
      * @return whether a run of text will be formatted as a superscript text. Default is false.
      */
     public TextCap getTextCap() {
-        CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getLevel()){
+        CharacterPropertyFetcher<TextCap> fetcher = new CharacterPropertyFetcher<TextCap>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetCap()){
                     int idx = props.getCap().intValue() - 1;
@@ -431,7 +391,7 @@ public class XSLFTextRun {
      * @return whether this run of text is formatted as bold text
      */
     public boolean isBold(){
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetB()){
                     setValue(props.getB());
@@ -455,7 +415,7 @@ public class XSLFTextRun {
      * @return whether this run of text is formatted as italic text
      */
     public boolean isItalic(){
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetI()){
                     setValue(props.getI());
@@ -478,8 +438,8 @@ public class XSLFTextRun {
     /**
      * @return whether this run of text is formatted as underlined text
      */
-    public boolean isUnderline(){
-        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getLevel()){
+    public boolean isUnderlined(){
+        CharacterPropertyFetcher<Boolean> fetcher = new CharacterPropertyFetcher<Boolean>(_p.getIndentLevel()){
             public boolean fetch(CTTextCharacterProperties props){
                 if(props.isSetU()){
                     setValue(props.getU() != STTextUnderlineType.NONE);
@@ -498,7 +458,7 @@ public class XSLFTextRun {
 
     @Override
     public String toString(){
-        return "[" + getClass() + "]" + getText();
+        return "[" + getClass() + "]" + getRawText();
     }
 
     public XSLFHyperlink createHyperlink(){
@@ -513,7 +473,7 @@ public class XSLFTextRun {
         return new XSLFHyperlink(_r.getRPr().getHlinkClick(), this);
     }
 
-    private boolean fetchCharacterProperty(CharacterPropertyFetcher fetcher){
+    private boolean fetchCharacterProperty(CharacterPropertyFetcher<?> fetcher){
         boolean ok = false;
 
         if(_r.isSetRPr()) ok = fetcher.fetch(getRPr());
@@ -526,7 +486,7 @@ public class XSLFTextRun {
                 if(ph == null){
                     // if it is a plain text box then take defaults from presentation.xml
                     XMLSlideShow ppt = shape.getSheet().getSlideShow();
-                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getLevel());
+                    CTTextParagraphProperties themeProps = ppt.getDefaultParagraphStyle(_p.getIndentLevel());
                     if(themeProps != null) {
                         fetcher.isFetchingFromMaster = true;
                         ok = fetcher.fetch(themeProps);
@@ -567,8 +527,8 @@ public class XSLFTextRun {
         boolean italic = r.isItalic();
         if(italic != isItalic()) setItalic(italic);
 
-        boolean underline = r.isUnderline();
-        if(underline != isUnderline()) setUnderline(underline);
+        boolean underline = r.isUnderlined();
+        if(underline != isUnderlined()) setUnderline(underline);
 
         boolean strike = r.isStrikethrough();
         if(strike != isStrikethrough()) setStrikethrough(strike);



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