]> source.dussan.org Git - poi.git/commitdiff
60465: Cannot specify interline spacing for a Paragraph in XWPF
authorMark Murphy <jmarkmurphy@apache.org>
Fri, 16 Dec 2016 03:21:02 +0000 (03:21 +0000)
committerMark Murphy <jmarkmurphy@apache.org>
Fri, 16 Dec 2016 03:21:02 +0000 (03:21 +0000)
Task-Url: https://bz.apache.org/bugzilla/show_bug.cgi?id=60465

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1774551 13f79535-47bb-0310-9956-ffa450edef68

src/examples/src/org/apache/poi/xwpf/usermodel/examples/SimpleDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java

index 4f5487b1fc80cdeae53a1a6c687d66c52549ddc1..28433c4ed06968bcd8ceaa6f7499a47818106b00 100644 (file)
@@ -85,7 +85,7 @@ public class SimpleDocument {
                 
         //p3.setAlignment(ParagraphAlignment.DISTRIBUTE);
         p3.setAlignment(ParagraphAlignment.BOTH);
-        p3.setSpacingLineRule(LineSpacingRule.EXACT);
+        p3.setSpacingBetween(15, LineSpacingRule.EXACT);
 
         p3.setIndentationFirstLine(600);
         
index 4e2d3654d1bcc17843dee0d9f3d97aaa044102ac..a58d0b97e09173fdbd9b10f3b19e5c22a12a34bb 100644 (file)
@@ -899,7 +899,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents, Para
      * Specifies the spacing that should be added after the last line in this
      * paragraph in the document in absolute units.
      *
-     * @return bigInteger - value representing the spacing after the paragraph
+     * @return int - value representing the spacing after the paragraph
      * @see #setSpacingAfterLines(int)
      */
     public int getSpacingAfterLines() {
@@ -922,7 +922,7 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents, Para
      *
      * @param spaces -
      *               a positive whole number, whose contents consist of a
-     *               measurement in twentieths of a
+     *               measurement in hundredths of a line
      */
     public void setSpacingAfterLines(int spaces) {
         CTSpacing spacing = getCTSpacing(true);
@@ -1012,11 +1012,66 @@ public class XWPFParagraph implements IBodyElement, IRunBody, ISDTContents, Para
      * @param rule
      * @see LineSpacingRule
      */
+     // TODO Fix this to convert line to equivalent value, or deprecate this in
+     //      favor of setSpacingLine(double, LineSpacingRule)
     public void setSpacingLineRule(LineSpacingRule rule) {
         CTSpacing spacing = getCTSpacing(true);
         spacing.setLineRule(STLineSpacingRule.Enum.forInt(rule.getValue()));
     }
 
+    /**
+     * Return the spacing between lines of a paragraph. The units of the return value depends on the
+     * {@link LineSpacingRule}. If AUTO, the return value is in lines, otherwise the return
+     * value is in points
+     *
+     * @return a double specifying points or lines.
+     */
+    public double getSpacingBetween() {
+        CTSpacing spacing = getCTSpacing(false);
+        if (spacing == null || !spacing.isSetLine()) {
+            return -1;
+        } else if (spacing.getLineRule() == null || spacing.getLineRule() == STLineSpacingRule.AUTO) {
+            BigInteger[] val = spacing.getLine().divideAndRemainder(BigInteger.valueOf(240L));
+            return val[0].doubleValue() + (val[1].doubleValue() / 240L);
+        }
+        BigInteger[] val = spacing.getLine().divideAndRemainder(BigInteger.valueOf(20L));
+        return val[0].doubleValue() + (val[1].doubleValue() / 20L);        
+    }
+
+    /**
+     * Sets the spacing between lines in a paragraph
+     *
+     * @param spacing - A double specifying spacing in inches or lines. If rule is
+     *                  AUTO, then spacing is in lines. Otherwise spacing is in points.
+     * @param rule - {@link LineSpacingRule} indicating how spacing is interpreted. If
+     *               AUTO, then spacing value is in lines, and the height depends on the
+     *               font size. If AT_LEAST, then spacing value is in inches, and is the
+     *               minimum size of the line. If the line height is taller, then the
+     *               line expands to match. If EXACT, then spacing is the exact line
+     *               height. If the text is taller than the line height, then it is 
+     *               clipped at the top. 
+     */
+    public void setSpacingBetween(double spacing, LineSpacingRule rule) {
+        CTSpacing ctSp = getCTSpacing(true);
+        switch (rule) {
+        case AUTO:
+            ctSp.setLine(new BigInteger(String.valueOf(Math.round(spacing * 240.0))));
+            break;
+        default:
+            ctSp.setLine(new BigInteger(String.valueOf(Math.round(spacing * 20.0))));
+        }
+        ctSp.setLineRule(STLineSpacingRule.Enum.forInt(rule.getValue()));
+    }
+    
+    /**
+     * Sets the spacing between lines in a paragraph
+     *
+     * @param spacing - A double specifying spacing in lines.
+     */
+    public void setSpacingBetween(double spacing) {
+        setSpacingBetween(spacing, LineSpacingRule.AUTO);
+    }
+    
     /**
      * Specifies the indentation which shall be placed between the left text
      * margin for this paragraph and the left edge of that paragraph's content
index 756aeef5548eeeb108c1812d0f20f262791a7994..d718a621b5408c455bf4eca8db502cb381b58eb4 100644 (file)
@@ -160,14 +160,34 @@ public final class TestXWPFParagraph {
         CTP ctp = p.getCTP();
         CTPPr ppr = ctp.getPPr() == null ? ctp.addNewPPr() : ctp.getPPr();
 
+        assertEquals(-1, p.getSpacingBefore());
         assertEquals(-1, p.getSpacingAfter());
+        assertEquals(-1, p.getSpacingBetween(), 0.1);
+        assertEquals(LineSpacingRule.AUTO, p.getSpacingLineRule());
 
         CTSpacing spacing = ppr.addNewSpacing();
         spacing.setAfter(new BigInteger("10"));
         assertEquals(10, p.getSpacingAfter());
+        spacing.setBefore(new BigInteger("10"));
+        assertEquals(10, p.getSpacingBefore());
 
         p.setSpacingAfter(100);
         assertEquals(100, spacing.getAfter().intValue());
+        p.setSpacingBefore(100);
+        assertEquals(100, spacing.getBefore().intValue());
+        
+        p.setSpacingBetween(.25, LineSpacingRule.EXACT);
+        assertEquals(.25, p.getSpacingBetween(), 0.01);
+        assertEquals(LineSpacingRule.EXACT, p.getSpacingLineRule());
+        p.setSpacingBetween(1.25, LineSpacingRule.AUTO);
+        assertEquals(1.25, p.getSpacingBetween(), 0.01);
+        assertEquals(LineSpacingRule.AUTO, p.getSpacingLineRule());
+        p.setSpacingBetween(.5, LineSpacingRule.AT_LEAST);
+        assertEquals(.5, p.getSpacingBetween(), 0.01);
+        assertEquals(LineSpacingRule.AT_LEAST, p.getSpacingLineRule());
+        p.setSpacingBetween(1.15);
+        assertEquals(1.15, p.getSpacingBetween(), 0.01);
+        assertEquals(LineSpacingRule.AUTO, p.getSpacingLineRule());
         
         doc.close();
     }