60465: Cannot specify interline spacing for a Paragraph in XWPF

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
This commit is contained in:
Mark Murphy 2016-12-16 03:21:02 +00:00
parent 4cc6e093f4
commit f4d208f452
3 changed files with 78 additions and 3 deletions

View 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);

View 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

View 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();
}