]> source.dussan.org Git - poi.git/commitdiff
[github-119] extra xpwf formatting support. This closes #119
authorPJ Fanning <fanningpj@apache.org>
Thu, 2 Aug 2018 21:28:47 +0000 (21:28 +0000)
committerPJ Fanning <fanningpj@apache.org>
Thu, 2 Aug 2018 21:28:47 +0000 (21:28 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1837336 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFRun.java

index 10261c5cd439b8ae1b7bc97c5ccebb09ebd76250..e4920d718d75a50af7ea3e529a7c3c191ccf9dda 100644 (file)
@@ -31,8 +31,11 @@ import javax.xml.namespace.QName;
 import org.apache.poi.ooxml.POIXMLException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ooxml.util.DocumentHelper;
+import org.apache.poi.util.HexDump;
 import org.apache.poi.util.Internal;
+import org.apache.poi.util.Removal;
 import org.apache.poi.wp.usermodel.CharacterRun;
+import org.apache.xmlbeans.SimpleValue;
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
@@ -234,7 +237,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @return the language tag associated with this run, if any
      */
     public String getLang() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         Object lang = pr == null || !pr.isSetLang() ? null : pr.getLang().getVal();
         return (String) lang;
     }
@@ -247,7 +250,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public boolean isBold() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetB() && isCTOnOff(pr.getB());
     }
 
@@ -277,7 +280,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public void setBold(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff bold = pr.isSetB() ? pr.getB() : pr.addNewB();
         bold.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
@@ -288,7 +291,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     public String getColor() {
         String color = null;
         if (run.isSetRPr()) {
-            CTRPr pr = run.getRPr();
+            CTRPr pr = getRunProperties(false);
             if (pr.isSetColor()) {
                 CTColor clr = pr.getColor();
                 color = clr.xgetVal().getStringValue();
@@ -303,7 +306,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @param rgbStr - the desired color, in the hex form "RRGGBB".
      */
     public void setColor(String rgbStr) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTColor color = pr.isSetColor() ? pr.getColor() : pr.addNewColor();
         color.setVal(rgbStr);
     }
@@ -357,7 +360,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public boolean isItalic() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetI() && isCTOnOff(pr.getI());
     }
 
@@ -388,29 +391,32 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public void setItalic(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff italic = pr.isSetI() ? pr.getI() : pr.addNewI();
         italic.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     /**
-     * Specifies that the contents of this run should be displayed along with an
-     * underline appearing directly below the character heigh
+     * Get the underline setting for the run.
      *
-     * @return the Underline pattern applyed to this run
-     * @see UnderlinePatterns
+     * @return the Underline pattern applied to this run
+     * @see (@link UnderlinePatterns}
      */
     public UnderlinePatterns getUnderline() {
-        CTRPr pr = run.getRPr();
-        return (pr != null && pr.isSetU() && pr.getU().getVal() != null)
-                ? UnderlinePatterns.valueOf(pr.getU().getVal().intValue())
-                : UnderlinePatterns.NONE;
+        UnderlinePatterns value = UnderlinePatterns.NONE;
+        CTUnderline underline = getCTUnderline(false);
+        if (underline != null) {
+            STUnderline.Enum baseValue = underline.getVal();
+            if (baseValue != null) {
+                value = UnderlinePatterns.valueOf(baseValue.intValue());
+            }
+        }
+        return value;
     }
 
     /**
      * Specifies that the contents of this run should be displayed along with an
-     * underline appearing directly below the character heigh
-     * <p>
+     * underline appearing directly below the character height.
      * <p>
      * If this element is not present, the default value is to leave the
      * formatting applied at previous level in the style hierarchy. If this
@@ -420,14 +426,98 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      *
      * @param value -
      *              underline type
-     * @see UnderlinePatterns : all possible patterns that could be applied
+     * @see {@link UnderlinePatterns} : all possible patterns that could be applied
      */
     public void setUnderline(UnderlinePatterns value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
-        CTUnderline underline = (pr.getU() == null) ? pr.addNewU() : pr.getU();
+        CTUnderline underline = getCTUnderline(true);
         underline.setVal(STUnderline.Enum.forInt(value.getValue()));
     }
 
+    /**
+     * Get the CTUnderline for the run.
+     * @param create Create a new underline if necessary
+     * @return The underline, or null create is false and there is no underline.
+     */
+    private CTUnderline getCTUnderline(boolean create) {
+        CTRPr pr = getRunProperties(true);
+        CTUnderline underline = pr.getU();
+        if (create && underline == null) {
+            underline = pr.addNewU();
+        }
+        return underline;
+    }
+
+    /**
+     * Set the underline color for the run's underline, if any.
+     *
+     * @param color An RGB color value (e.g, "a0C6F3") or "auto". 
+     * @since 4.0.0
+     */
+    public void setUnderlineColor(String color) {
+        CTUnderline underline = getCTUnderline(true);
+        SimpleValue svColor = null;
+        if (color.equals("auto")) {
+            STHexColorAuto hexColor = STHexColorAuto.Factory.newInstance();
+            hexColor.set(STHexColorAuto.Enum.forString(color));
+            svColor = (SimpleValue) hexColor;
+        } else {
+            STHexColorRGB rgbColor = STHexColorRGB.Factory.newInstance();
+            rgbColor.setStringValue(color);
+            svColor = (SimpleValue) rgbColor;
+        }
+        underline.setColor(svColor);
+    }
+    
+    /**
+     * Set the underline theme color for the run's underline, if any.
+     *
+     * @param themeColor A theme color name (see {@link STThemeColor.Enum}). 
+     * @since 4.0.0
+     */
+    public void setUnderlineThemeColor(String themeColor) {
+        CTUnderline underline = getCTUnderline(true);
+        STThemeColor.Enum val = STThemeColor.Enum.forString(themeColor);
+        if (val != null) {
+            underline.setThemeColor(val);
+        }
+    }
+    
+    /**
+     * Get the underline theme color for the run's underline, if any.
+     *
+     * @return The {@link STThemeColor.Enum}.
+     * @since 4.0.0
+     */
+    public STThemeColor.Enum getUnderlineThemeColor() {
+        CTUnderline underline = getCTUnderline(false);
+        STThemeColor.Enum color = STThemeColor.NONE;
+        if (underline != null) {
+            color = underline.getThemeColor();
+        }
+        return color;
+    }
+    
+    /**
+     * Get the underline color for the run's underline, if any.
+     *
+     * @return The RGB color value as as a string of hexadecimal digits (e.g., "A0B2F1") or "auto".
+     * @since 4.0.0
+     */
+    public String getUnderlineColor() {
+        CTUnderline underline = getCTUnderline(true);
+        String colorName = "auto";
+        Object rawValue = underline.getColor();
+        if (rawValue != null) {
+            if (rawValue instanceof String) {
+                colorName = (String)rawValue;
+            } else {
+                byte[] rgbColor = (byte[])rawValue;
+                colorName = HexDump.toHex(rgbColor[0]) + HexDump.toHex(rgbColor[1]) + HexDump.toHex(rgbColor[2]);
+            }
+        }
+        return colorName;
+    }
+    
     /**
      * Specifies that the contents of this run shall be displayed with a single
      * horizontal line through the center of the line.
@@ -436,7 +526,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public boolean isStrikeThrough() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetStrike() && isCTOnOff(pr.getStrike());
     }
 
@@ -466,7 +556,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public void setStrikeThrough(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff strike = pr.isSetStrike() ? pr.getStrike() : pr.addNewStrike();
         strike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
@@ -489,7 +579,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public boolean isDoubleStrikeThrough() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetDstrike() && isCTOnOff(pr.getDstrike());
     }
 
@@ -501,72 +591,72 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public void setDoubleStrikethrough(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff dstrike = pr.isSetDstrike() ? pr.getDstrike() : pr.addNewDstrike();
         dstrike.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     @Override
     public boolean isSmallCaps() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetSmallCaps() && isCTOnOff(pr.getSmallCaps());
     }
 
     @Override
     public void setSmallCaps(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff caps = pr.isSetSmallCaps() ? pr.getSmallCaps() : pr.addNewSmallCaps();
         caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     @Override
     public boolean isCapitalized() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetCaps() && isCTOnOff(pr.getCaps());
     }
 
     @Override
     public void setCapitalized(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff caps = pr.isSetCaps() ? pr.getCaps() : pr.addNewCaps();
         caps.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     @Override
     public boolean isShadowed() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetShadow() && isCTOnOff(pr.getShadow());
     }
 
     @Override
     public void setShadow(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff shadow = pr.isSetShadow() ? pr.getShadow() : pr.addNewShadow();
         shadow.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     @Override
     public boolean isImprinted() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetImprint() && isCTOnOff(pr.getImprint());
     }
 
     @Override
     public void setImprinted(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff imprinted = pr.isSetImprint() ? pr.getImprint() : pr.addNewImprint();
         imprinted.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
 
     @Override
     public boolean isEmbossed() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return pr != null && pr.isSetEmboss() && isCTOnOff(pr.getEmboss());
     }
 
     @Override
     public void setEmbossed(boolean value) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTOnOff emboss = pr.isSetEmboss() ? pr.getEmboss() : pr.addNewEmboss();
         emboss.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
     }
@@ -578,10 +668,12 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * altering the font size of the run properties.
      *
      * @return VerticalAlign
-     * @see VerticalAlign all possible value that could be applyed to this run
+     * @see {@link VerticalAlign} all possible value that could be applyed to this run
+     * @deprecated use {@link XWPFRun.getVerticalAlignment}
      */
+    @Removal(version = "4.2")
     public VerticalAlign getSubscript() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr.getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE;
     }
 
@@ -602,14 +694,14 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @see VerticalAlign
      */
     public void setSubscript(VerticalAlign valign) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTVerticalAlignRun ctValign = pr.isSetVertAlign() ? pr.getVertAlign() : pr.addNewVertAlign();
         ctValign.setVal(STVerticalAlignRun.Enum.forInt(valign.getValue()));
     }
 
     @Override
     public int getKerning() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         if (pr == null || !pr.isSetKern()) {
             return 0;
         }
@@ -618,18 +710,19 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
 
     @Override
     public void setKerning(int kern) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTHpsMeasure kernmes = pr.isSetKern() ? pr.getKern() : pr.addNewKern();
         kernmes.setVal(BigInteger.valueOf(kern));
     }
 
     @Override
     public boolean isHighlighted() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         if (pr == null || !pr.isSetHighlight()) {
             return false;
         }
-        if (pr.getHighlight().getVal() == STHighlightColor.NONE) {
+        STHighlightColor.Enum val = pr.getHighlight().getVal();
+        if (val == null || val == STHighlightColor.NONE) {
             return false;
         }
         return true;
@@ -639,7 +732,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
 
     @Override
     public int getCharacterSpacing() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         if (pr == null || !pr.isSetSpacing()) {
             return 0;
         }
@@ -648,7 +741,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
 
     @Override
     public void setCharacterSpacing(int twips) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTSignedTwipsMeasure spc = pr.isSetSpacing() ? pr.getSpacing() : pr.addNewSpacing();
         spc.setVal(BigInteger.valueOf(twips));
     }
@@ -694,7 +787,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @return a string representing the font famil
      */
     public String getFontFamily(FontCharRange fcr) {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         if (pr == null || !pr.isSetRFonts()) {
             return null;
         }
@@ -723,7 +816,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @param fcr        FontCharRange or null for default handling
      */
     public void setFontFamily(String fontFamily, FontCharRange fcr) {
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTFonts fonts = pr.isSetRFonts() ? pr.getRFonts() : pr.addNewRFonts();
 
         if (fcr == null) {
@@ -763,7 +856,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     @Override
     public int getFontSize() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return (pr != null && pr.isSetSz()) ? pr.getSz().getVal().divide(new BigInteger("2")).intValue() : -1;
     }
 
@@ -782,7 +875,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
     @Override
     public void setFontSize(int size) {
         BigInteger bint = new BigInteger(Integer.toString(size));
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTHpsMeasure ctSize = pr.isSetSz() ? pr.getSz() : pr.addNewSz();
         ctSize.setVal(bint.multiply(new BigInteger("2")));
     }
@@ -796,7 +889,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      * @return a big integer representing the amount of text shall be "moved"
      */
     public int getTextPosition() {
-        CTRPr pr = run.getRPr();
+        CTRPr pr = getRunProperties(false);
         return (pr != null && pr.isSetPosition()) ? pr.getPosition().getVal().intValue()
                 : -1;
     }
@@ -826,7 +919,7 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
      */
     public void setTextPosition(int val) {
         BigInteger bint = new BigInteger(Integer.toString(val));
-        CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
+        CTRPr pr = getRunProperties(true);
         CTSignedHpsMeasure position = pr.isSetPosition() ? pr.getPosition() : pr.addNewPosition();
         position.setVal(bint);
     }
@@ -1278,4 +1371,186 @@ public class XWPFRun implements ISDTContents, IRunElement, CharacterRun {
         eastAsia /* east asia */,
         hAnsi /* high ansi */
     }
+
+    /**
+     * Set the text expand/collapse scale value.
+     *
+     * @param percentage The percentage to expand or compress the text
+     * @since 4.0.0
+     */
+    public void setTextScale(int percentage) {
+        CTRPr pr = getRunProperties(true);
+        CTTextScale scale = pr.isSetW() ? pr.getW() : pr.addNewW();
+        scale.setVal(percentage);        
+    }
+
+    /**
+     * Gets the current text scale value.
+     *
+     * @return Value is an integer percentage
+     * @since 4.0.0
+     */
+    public int getTextScale() {
+        CTRPr pr = getRunProperties(true);
+        CTTextScale scale = pr.isSetW() ? pr.getW() : pr.addNewW();
+        int value = scale.getVal();
+        if (value == 0) {
+            value = 100; // 100% scaling, that is, no change. See 17.3.2.43 w (Expanded/Compressed Text)
+        }
+        return value;
+    }
+
+    /**
+     * Set the highlight color for the run. Silently does nothing of colorName is not a recognized value.
+     *
+     * @param colorName The name of the color as defined in the ST_HighlightColor simple type ({@link STHightlightColor})
+     * @since 4.0.0
+     */
+    public void setTextHighlightColor(String colorName) {
+        CTRPr pr = getRunProperties(true);
+        CTHighlight highlight = pr.isSetHighlight() ? pr.getHighlight() : pr.addNewHighlight();
+        STHighlightColor color = highlight.xgetVal();
+        if (color == null) {
+            color = STHighlightColor.Factory.newInstance();            
+        }
+        STHighlightColor.Enum val = STHighlightColor.Enum.forString(colorName);
+        if (val != null) {
+            color.setStringValue(val.toString());
+            highlight.xsetVal(color);
+        }
+         
+    }
+
+    /**
+     * Gets the highlight color for the run
+     *
+     * @return {@link STHighlightColor} for the run.
+     * @since 4.0.0
+     */
+    public STHighlightColor.Enum getTextHightlightColor() {
+        CTRPr pr = getRunProperties(true);
+        CTHighlight highlight = pr.isSetHighlight() ? pr.getHighlight() : pr.addNewHighlight();
+        STHighlightColor color = highlight.xgetVal();
+        if (color == null) {
+            color = STHighlightColor.Factory.newInstance();
+            color.set(STHighlightColor.NONE);
+        }
+        return (STHighlightColor.Enum)(color.enumValue());
+    }
+
+    /**
+     * Get the vanish (hidden text) value
+     *
+     * @return True if the run is hidden text.
+     * @since 4.0.0
+     */
+    public boolean isVanish() {
+        CTRPr pr = getRunProperties(true);
+        return pr != null && pr.isSetVanish() && isCTOnOff(pr.getVanish());
+    }
+
+    /**
+     * The vanish (hidden text) property for the run. 
+     *
+     * @param value Set to true to make the run hidden text.
+     * @since 4.0.0
+     */
+    public void setVanish(boolean value) {
+        CTRPr pr = getRunProperties(true);
+        CTOnOff vanish = pr.isSetVanish() ? pr.getVanish() : pr.addNewVanish();
+        vanish.setVal(value ? STOnOff.TRUE : STOnOff.FALSE);
+    }
+
+    /**
+     * Get the vertical alignment value
+     *
+     * @return {@link STVerticalAlignRun.Enum} value (see 22.9.2.17 ST_VerticalAlignRun (Vertical Positioning Location))
+     * @since 4.0.0
+     */
+    public STVerticalAlignRun.Enum getVerticalAlignment() {
+        CTRPr pr = getRunProperties(true);
+        CTVerticalAlignRun vertAlign = pr.isSetVertAlign() ? pr.getVertAlign() : pr.addNewVertAlign();
+        STVerticalAlignRun.Enum val = vertAlign.getVal();
+        if (val == null) {
+            val = STVerticalAlignRun.BASELINE;
+        }
+        return val;
+    }
+
+    /**
+     * Set the vertical alignment of the run.
+     *
+     * @param verticalAlignment Vertical alignment value, one of "baseline", "superscript", or "subscript".
+     * @since 4.0.0
+     */
+    public void setVerticalAlignment(String verticalAlignment) {
+        CTRPr pr = getRunProperties(true);
+        CTVerticalAlignRun vertAlign = pr.getVertAlign();
+        STVerticalAlignRun align = vertAlign.xgetVal();
+        if (align == null) {
+            align = STVerticalAlignRun.Factory.newInstance();            
+        }
+        STVerticalAlignRun.Enum val = STVerticalAlignRun.Enum.forString(verticalAlignment);
+        if (val != null) {
+            align.setStringValue(val.toString());
+            vertAlign.xsetVal(align);
+        }
+        
+        
+    }
+
+    /**
+     * Get the emphasis mark value for the run.
+     *
+     * @return {@link STEm.Enum} emphasis mark type enumeration. See 17.18.24 ST_Em (Emphasis Mark Type).
+     * @since 4.0.0
+     */
+    public STEm.Enum getEmphasisMark() {
+        CTRPr pr = getRunProperties(true);
+        CTEm emphasis = pr.isSetEm() ? pr.getEm() : pr.addNewEm();
+        
+        STEm.Enum val = emphasis.getVal();
+        if (val == null) {
+            val = STEm.NONE;
+        }
+        return val;
+    }
+
+    /**
+     * Set the emphasis mark for the run. The emphasis mark goes above or below the run
+     * text.
+     *
+     * @param markType Emphasis mark type name, e.g., "dot" or "none". See 17.18.24 ST_Em (Emphasis Mark Type)
+     * @since 4.0.0
+     */
+    public void setEmphasisMark(String markType) {
+        CTRPr pr = getRunProperties(true);
+        CTEm emphasisMark = pr.getEm();
+        STEm mark = emphasisMark.xgetVal();
+        if (mark == null) {
+            mark = STEm.Factory.newInstance();            
+        }
+        STEm.Enum val = STEm.Enum.forString(markType);
+        if (val != null) {
+            mark.setStringValue(val.toString());
+            emphasisMark.xsetVal(mark);
+        }
+
+        
+    }
+    
+    /**
+     * Get the run properties for the run.
+     *
+     * @param create If true, create the properties, if false, do not.
+     * @return The run properties or null if there are no properties and create is false.
+     */
+    private CTRPr getRunProperties(boolean create) {
+        CTRPr pr = run.isSetRPr() ? run.getRPr() : null;
+        if (create && pr == null) {
+            pr = run.addNewRPr();
+        }
+        return pr;
+    }
+
 }
index d3ad99a810ec53e4154dfc995e645c323fe7a2ae..41facd92072157fb7a6864b24c163b63436bf8d9 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.util.Units;
 import org.apache.poi.wp.usermodel.HeaderFooterType;
@@ -32,21 +42,13 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrClear;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STEm;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHighlightColor;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STThemeColor;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.util.Iterator;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
 /**
  * Tests for XWPF Run
  */
@@ -161,9 +163,9 @@ public class TestXWPFRun {
     @Test
     public void testSetGetUnderline() {
         CTRPr rpr = ctRun.addNewRPr();
+        XWPFRun run = new XWPFRun(ctRun, irb);
         rpr.addNewU().setVal(STUnderline.DASH);
 
-        XWPFRun run = new XWPFRun(ctRun, irb);
         assertEquals(UnderlinePatterns.DASH.getValue(), run.getUnderline()
                 .getValue());
 
@@ -172,18 +174,6 @@ public class TestXWPFRun {
                 .intValue());
     }
 
-    @Test
-    public void testSetGetVAlign() {
-        CTRPr rpr = ctRun.addNewRPr();
-        rpr.addNewVertAlign().setVal(STVerticalAlignRun.SUBSCRIPT);
-
-        XWPFRun run = new XWPFRun(ctRun, irb);
-        assertEquals(VerticalAlign.SUBSCRIPT, run.getSubscript());
-
-        run.setSubscript(VerticalAlign.BASELINE);
-        assertEquals(STVerticalAlignRun.BASELINE, rpr.getVertAlign().getVal());
-    }
-
     @Test
     public void testSetGetFontFamily() {
         CTRPr rpr = ctRun.addNewRPr();
@@ -467,20 +457,6 @@ public class TestXWPFRun {
         assertNull(run.getLang());
     }
 
-    @Test
-    public void testSetGetHighlight() {
-        XWPFRun run = p.createRun();
-        assertEquals(false, run.isHighlighted());
-        
-        // TODO Do this using XWPFRun methods
-        run.getCTR().addNewRPr().addNewHighlight().setVal(STHighlightColor.NONE);
-        assertEquals(false, run.isHighlighted());
-        run.getCTR().getRPr().getHighlight().setVal(STHighlightColor.CYAN);
-        assertEquals(true, run.isHighlighted());
-        run.getCTR().getRPr().getHighlight().setVal(STHighlightColor.NONE);
-        assertEquals(false, run.isHighlighted());
-    }
-
     @Test
     public void testAddPicture() throws Exception {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("TestDocument.docx");
@@ -670,10 +646,107 @@ public class TestXWPFRun {
         assertEquals(10, run.getFontSize());
         run.setImprinted(true);
         run.setItalic(true);
+    }
+    
+    @Test
+    public void testSetGetTextScale() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(100, run.getTextScale());
+        run.setTextScale(200);
+        assertEquals(200, run.getTextScale());
+        document.close();
+    }
+    
+    @Test
+    public void testSetGetTextHighlightColor() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(STHighlightColor.NONE, run.getTextHightlightColor());
+        assertEquals(false, run.isHighlighted());
+        run.setTextHighlightColor("darkGreen"); // See 17.18.40 ST_HighlightColor (Text Highlight Colors)
+        assertEquals(STHighlightColor.DARK_GREEN, run.getTextHightlightColor());
+        assertEquals(true, run.isHighlighted());
+        run.setTextHighlightColor("none");
+        assertEquals(false, run.isHighlighted());
+        
+        document.close();
+    }
 
+    @Test
+    public void testSetGetVanish() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(false, run.isVanish());
+        run.setVanish(true);
+        assertEquals(true, run.isVanish());
+        run.setVanish(false);
+        assertEquals(false, run.isVanish());
         document.close();
     }
     
+    @Test
+    public void testSetGetVerticalAlignment() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(STVerticalAlignRun.BASELINE, run.getVerticalAlignment());
+        run.setVerticalAlignment("subscript");
+        assertEquals(STVerticalAlignRun.SUBSCRIPT, run.getVerticalAlignment());
+        run.setVerticalAlignment("superscript");
+        assertEquals(STVerticalAlignRun.SUPERSCRIPT, run.getVerticalAlignment());
+        document.close();
+    }
+
+    @Test
+    public void testSetGetVAlign() {
+        CTRPr rpr = ctRun.addNewRPr();
+        rpr.addNewVertAlign().setVal(STVerticalAlignRun.SUBSCRIPT);
+
+        XWPFRun run = new XWPFRun(ctRun, irb);
+        assertEquals(VerticalAlign.SUBSCRIPT, run.getSubscript());
+
+        run.setSubscript(VerticalAlign.BASELINE);
+        assertEquals(STVerticalAlignRun.BASELINE, rpr.getVertAlign().getVal());
+    }
+
+
+    @Test
+    public void testSetGetEmphasisMark() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(STEm.NONE, run.getEmphasisMark());
+        run.setEmphasisMark("dot");
+        assertEquals(STEm.DOT, run.getEmphasisMark());
+        document.close();
+    }
+    
+    @Test
+    public void testSetGetUnderlineColor() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals("auto", run.getUnderlineColor());
+        String colorRgb = "C0F1a2";
+        run.setUnderlineColor(colorRgb);
+        assertEquals(colorRgb.toUpperCase(), run.getUnderlineColor());
+        run.setUnderlineColor("auto");
+        assertEquals("auto", run.getUnderlineColor());
+        document.close();
+    }
+    
+    @Test
+    public void testSetGetUnderlineThemeColor() throws IOException {
+        XWPFDocument document = new XWPFDocument();
+        final XWPFRun run = document.createParagraph().createRun();
+        assertEquals(STThemeColor.NONE, run.getUnderlineThemeColor());
+        String colorName = "accent4";
+        run.setUnderlineThemeColor(colorName);
+        assertEquals(STThemeColor.Enum.forString(colorName), run.getUnderlineThemeColor());
+        run.setUnderlineThemeColor("none");
+        assertEquals(STThemeColor.NONE, run.getUnderlineThemeColor());
+        document.close();
+    }
+    
+
     @Test
     public void testSetStyleId() throws IOException {
         XWPFDocument document = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
@@ -683,8 +756,7 @@ public class TestXWPFRun {
         run.setStyle(styleId);
         String candStyleId = run.getCTR().getRPr().getRStyle().getVal();
         assertNotNull("Expected to find a run style ID", candStyleId);
-        assertEquals(styleId, candStyleId);
-        
+        assertEquals(styleId, candStyleId);        
     }
 
 }