test integration of XDDF text entities

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1839259 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alain Béarez 2018-08-26 21:33:16 +00:00
parent 0f9247a088
commit 85e2e8616d
12 changed files with 1205 additions and 720 deletions

View File

@ -1152,10 +1152,8 @@ under the License.
<target name="retest-ooxml" depends="jar">
<delete dir="${ooxml.reports.test}"/>
<delete dir="${ooxml.output.test}"/>
<delete dir="${ooxml.output.test.dir}"/>
<mkdir dir="${ooxml.reports.test}"/>
<mkdir dir="${ooxml.output.test}"/>
<mkdir dir="${ooxml.output.test.dir}"/>
<!-- compile the sources -->
<javac target="${jdk.version.class}"

View File

@ -21,34 +21,28 @@ package org.apache.poi.xslf.usermodel;
import org.apache.poi.sl.usermodel.AutoShape;
import org.apache.poi.util.Beta;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
/**
* Represents a shape with a preset geometry.
*
* @author Yegor Kozlov
*/
@Beta
public class XSLFAutoShape extends XSLFTextShape
implements AutoShape<XSLFShape,XSLFTextParagraph> {
public class XSLFAutoShape extends XSLFTextShape implements AutoShape<XSLFShape, XSLFTextParagraph> {
/*package*/ XSLFAutoShape(CTShape shape, XSLFSheet sheet) {
/* package */ XSLFAutoShape(CTShape shape, XSLFSheet sheet) {
super(shape, sheet);
}
/*package*/
/* package */
static XSLFAutoShape create(CTShape shape, XSLFSheet sheet) {
if (shape.getSpPr().isSetCustGeom()) {
return new XSLFFreeformShape(shape, sheet);
@ -60,7 +54,8 @@ public class XSLFAutoShape extends XSLFTextShape
}
/**
* @param shapeId 1-based shapeId
* @param shapeId
* 1-based shapeId
*/
static CTShape prototype(int shapeId) {
CTShape ct = CTShape.Factory.newInstance();
@ -77,21 +72,9 @@ public class XSLFAutoShape extends XSLFTextShape
return ct;
}
protected static void initTextBody(CTTextBody txBody) {
CTTextBodyProperties bodypr = txBody.addNewBodyPr();
bodypr.setAnchor(STTextAnchoringType.T);
bodypr.setRtlCol(false);
CTTextParagraph p = txBody.addNewP();
p.addNewPPr().setAlgn(STTextAlignType.L);
CTTextCharacterProperties endPr = p.addNewEndParaRPr();
endPr.setLang("en-US");
endPr.setSz(1100);
p.addNewR().setT("");
txBody.addNewLstStyle();
}
protected CTTextBody getTextBody(boolean create){
CTShape shape = (CTShape)getXmlObject();
@Override
protected CTTextBody getTextBody(boolean create) {
CTShape shape = (CTShape) getXmlObject();
CTTextBody txBody = shape.getTxBody();
if (txBody == null && create) {
txBody = shape.addNewTxBody();
@ -101,7 +84,7 @@ public class XSLFAutoShape extends XSLFTextShape
}
@Override
public String toString(){
public String toString() {
return "[" + getClass().getSimpleName() + "] " + getShapeName();
}

View File

@ -33,6 +33,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.sl.usermodel.TableCell;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle;
import org.apache.xmlbeans.XmlObject;
@ -67,7 +68,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
/**
* Represents a cell of a table in a .pptx presentation
*/
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> {
public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape, XSLFTextParagraph> {
private CTTableCellProperties _tcPr;
private final XSLFTable table;
private int row, col;
@ -77,18 +78,20 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
*/
private Rectangle2D anchor;
/*package*/ XSLFTableCell(CTTableCell cell, XSLFTable table){
/* package */ XSLFTableCell(CTTableCell cell, XSLFTable table) {
super(cell, table.getSheet());
this.table = table;
}
@Override
protected CTTextBody getTextBody(boolean create){
protected CTTextBody getTextBody(boolean create) {
CTTableCell cell = getCell();
CTTextBody txBody = cell.getTxBody();
if (txBody == null && create) {
txBody = cell.addNewTxBody();
XSLFAutoShape.initTextBody(txBody);
XDDFTextBody body = new XDDFTextBody(this);
initTextBody(body);
cell.setTxBody(body.getXmlObject());
txBody = cell.getTxBody();
}
return txBody;
}
@ -116,25 +119,25 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
@Override
public void setLeftInset(double margin){
public void setLeftInset(double margin) {
CTTableCellProperties pr = getCellProperties(true);
pr.setMarL(Units.toEMU(margin));
}
@Override
public void setRightInset(double margin){
public void setRightInset(double margin) {
CTTableCellProperties pr = getCellProperties(true);
pr.setMarR(Units.toEMU(margin));
}
@Override
public void setTopInset(double margin){
public void setTopInset(double margin) {
CTTableCellProperties pr = getCellProperties(true);
pr.setMarT(Units.toEMU(margin));
}
@Override
public void setBottomInset(double margin){
public void setBottomInset(double margin) {
CTTableCellProperties pr = getCellProperties(true);
pr.setMarB(Units.toEMU(margin));
}
@ -276,7 +279,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
ln.unsetNoFill();
}
if(!ln.isSetPrstDash()) {
if (!ln.isSetPrstDash()) {
ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
}
if (!ln.isSetCmpd()) {
@ -396,19 +399,19 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
}
/**
* Specifies a solid color fill. The shape is filled entirely with the specified color.
* Specifies a solid color fill. The shape is filled entirely with the
* specified color.
*
* @param color the solid color fill.
* The value of <code>null</code> unsets the solidFIll attribute from the underlying xml
* @param color
* the solid color fill. The value of <code>null</code> unsets
* the solidFIll attribute from the underlying xml
*/
@Override
public void setFillColor(Color color) {
CTTableCellProperties spPr = getCellProperties(true);
if (color == null) {
if(spPr.isSetSolidFill()) {
if (spPr.isSetSolidFill()) {
spPr.unsetSolidFill();
}
} else {
@ -423,10 +426,10 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
* @return solid fill color of null if not set
*/
@Override
public Color getFillColor(){
public Color getFillColor() {
PaintStyle ps = getFillPaint();
if (ps instanceof SolidPaint) {
ColorStyle cs = ((SolidPaint)ps).getSolidColor();
ColorStyle cs = ((SolidPaint) ps).getSolidColor();
return DrawPaint.applyColorTransform(cs);
}
@ -480,8 +483,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
/**
* Retrieves the part style depending on the location of this cell
*
* @param tablePartStyle the part to be returned, usually this is null
* and only set when used as a helper method
* @param tablePartStyle
* the part to be returned, usually this is null and only set
* when used as a helper method
* @return the table part style
*/
private CTTablePartStyle getTablePartStyle(TablePartStyle tablePartStyle) {
@ -503,11 +507,11 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
tps = tablePartStyle;
} else if (row == 0 && firstRow) {
tps = TablePartStyle.firstRow;
} else if (row == table.getNumberOfRows()-1 && lastRow) {
} else if (row == table.getNumberOfRows() - 1 && lastRow) {
tps = TablePartStyle.lastRow;
} else if (col == 0 && firstCol) {
tps = TablePartStyle.firstCol;
} else if (col == table.getNumberOfColumns()-1 && lastCol) {
} else if (col == table.getNumberOfColumns() - 1 && lastCol) {
tps = TablePartStyle.lastCol;
} else {
tps = TablePartStyle.wholeTbl;
@ -559,10 +563,10 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
@Override
public void setVerticalAlignment(VerticalAlignment anchor){
public void setVerticalAlignment(VerticalAlignment anchor) {
CTTableCellProperties cellProps = getCellProperties(true);
if(anchor == null) {
if(cellProps.isSetAnchor()) {
if (anchor == null) {
if (cellProps.isSetAnchor()) {
cellProps.unsetAnchor();
}
} else {
@ -571,11 +575,11 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
@Override
public VerticalAlignment getVerticalAlignment(){
public VerticalAlignment getVerticalAlignment() {
CTTableCellProperties cellProps = getCellProperties(false);
VerticalAlignment align = VerticalAlignment.TOP;
if(cellProps != null && cellProps.isSetAnchor()) {
if (cellProps != null && cellProps.isSetAnchor()) {
int ival = cellProps.getAnchor().intValue();
align = VerticalAlignment.values()[ival - 1];
}
@ -588,7 +592,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
@Override
public void setTextDirection(TextDirection orientation) {
CTTableCellProperties cellProps = getCellProperties(true);
if(orientation == null) {
if (orientation == null) {
if (cellProps.isSetVert()) {
cellProps.unsetVert();
}
@ -645,7 +649,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
private CTTableCell getCell() {
return (CTTableCell)getXmlObject();
return (CTTableCell) getXmlObject();
}
/* package */ void setRowColIndex(int row, int col) {
@ -669,15 +673,16 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
/**
* There's no real anchor for table cells - this method is used to temporarily store the location
* of the cell for a later retrieval, e.g. for rendering
* There's no real anchor for table cells - this method is used to
* temporarily store the location of the cell for a later retrieval, e.g.
* for rendering
*
* @since POI 3.15-beta2
*/
@Override
public void setAnchor(Rectangle2D anchor) {
if (this.anchor == null) {
this.anchor = (Rectangle2D)anchor.clone();
this.anchor = (Rectangle2D) anchor.clone();
} else {
this.anchor.setRect(anchor);
}
@ -692,7 +697,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
table.updateCellAnchor();
}
// anchor should be set, after updateCellAnchor is through
assert(anchor != null);
assert (anchor != null);
return anchor;
}
@ -741,7 +746,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
@Override
public PaintStyle getFontColor(){
public PaintStyle getFontColor() {
CTTableStyleTextStyle txStyle = getTextStyle();
if (txStyle == null) {
return super.getFontColor();

View File

@ -21,27 +21,30 @@ package org.apache.poi.xslf.usermodel;
import org.apache.poi.sl.usermodel.TextBox;
import org.apache.poi.util.Beta;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
/**
* @author Yegor Kozlov
*/
@Beta
public class XSLFTextBox extends XSLFAutoShape
implements TextBox<XSLFShape,XSLFTextParagraph> {
public class XSLFTextBox extends XSLFAutoShape implements TextBox<XSLFShape, XSLFTextParagraph> {
/*package*/ XSLFTextBox(CTShape shape, XSLFSheet sheet){
/* package */ XSLFTextBox(CTShape shape, XSLFSheet sheet) {
super(shape, sheet);
}
/**
*
* @param shapeId 1-based shapeId
* @param shapeId
* 1-based shapeId
*/
static CTShape prototype(int shapeId){
static CTShape prototype(int shapeId) {
CTShape ct = CTShape.Factory.newInstance();
CTShapeNonVisual nvSpPr = ct.addNewNvSpPr();
CTNonVisualDrawingProps cnv = nvSpPr.addNewCNvPr();
@ -53,8 +56,9 @@ public class XSLFTextBox extends XSLFAutoShape
CTPresetGeometry2D prst = spPr.addNewPrstGeom();
prst.setPrst(STShapeType.RECT);
prst.addNewAvLst();
CTTextBody txBody = ct.addNewTxBody();
XSLFAutoShape.initTextBody(txBody);
XDDFTextBody body = new XDDFTextBody(null);
initTextBody(body);
ct.setTxBody(body.getXmlObject());
return ct;
}

View File

@ -24,6 +24,8 @@ import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.sl.draw.DrawFactory;
@ -34,6 +36,9 @@ import org.apache.poi.sl.usermodel.TextShape;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.text.TextContainer;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.poi.xslf.model.TextBodyPropertyFetcher;
import org.apache.xmlbeans.XmlObject;
@ -52,10 +57,10 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STTextWrappingType;
*/
@Beta
public abstract class XSLFTextShape extends XSLFSimpleShape
implements TextShape<XSLFShape,XSLFTextParagraph> {
implements TextContainer, TextShape<XSLFShape, XSLFTextParagraph> {
private final List<XSLFTextParagraph> _paragraphs;
/*package*/ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
/* package */ XSLFTextShape(XmlObject shape, XSLFSheet sheet) {
super(shape, sheet);
_paragraphs = new ArrayList<>();
@ -67,8 +72,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
}
protected static void initTextBody(XDDFTextBody body) {
XDDFTextParagraph p = body.getParagraph(0);
p.appendRegularRun("");
}
@Beta
public XDDFTextBody getTextBody() {
CTTextBody txBody = getTextBody(false);
if (txBody == null) {
return null;
}
return new XDDFTextBody(this, txBody);
}
@Override
public Iterator<XSLFTextParagraph> iterator(){
public Iterator<XSLFTextParagraph> iterator() {
return getTextParagraphs().iterator();
}
@ -87,7 +106,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
* unset text from this shape
*/
public void clearText(){
public void clearText() {
_paragraphs.clear();
CTTextBody txBody = getTextBody(true);
txBody.setPArray(null); // remove any existing paragraphs
@ -95,13 +114,14 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
@Override
public XSLFTextRun setText(String text) {
// calling clearText or setting to a new Array leads to a XmlValueDisconnectedException
// calling clearText or setting to a new Array leads to a
// XmlValueDisconnectedException
if (!_paragraphs.isEmpty()) {
CTTextBody txBody = getTextBody(false);
int cntPs = txBody.sizeOfPArray();
for (int i = cntPs; i > 1; i--) {
txBody.removeP(i-1);
_paragraphs.remove(i-1);
txBody.removeP(i - 1);
_paragraphs.remove(i - 1);
}
_paragraphs.get(0).clearButKeepProperties();
@ -127,18 +147,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
para = null;
} else {
firstPara = !newParagraph;
para = _paragraphs.get(_paragraphs.size()-1);
para = _paragraphs.get(_paragraphs.size() - 1);
CTTextParagraph ctp = para.getXmlObject();
otherPPr = ctp.getPPr();
List<XSLFTextRun> runs = para.getTextRuns();
if (!runs.isEmpty()) {
XSLFTextRun r0 = runs.get(runs.size()-1);
XSLFTextRun r0 = runs.get(runs.size() - 1);
otherRPr = r0.getRPr(false);
if (otherRPr == null) {
otherRPr = ctp.getEndParaRPr();
}
}
// don't copy endParaRPr to the run in case there aren't any other runs
// don't copy endParaRPr to the run in case there aren't any other
// runs
// this is the case when setText() was called initially
// otherwise the master style will be overridden/ignored
}
@ -173,7 +194,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
firstPara = false;
}
assert(run != null);
assert (run != null);
return run;
}
@ -203,11 +224,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public void setVerticalAlignment(VerticalAlignment anchor){
public void setVerticalAlignment(VerticalAlignment anchor) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(anchor == null) {
if(bodyPr.isSetAnchor()) {
if (anchor == null) {
if (bodyPr.isSetAnchor()) {
bodyPr.unsetAnchor();
}
} else {
@ -217,11 +238,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public VerticalAlignment getVerticalAlignment(){
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
public VerticalAlignment getVerticalAlignment() {
PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetAnchor()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetAnchor()) {
int val = props.getAnchor().intValue();
setValue(VerticalAlignment.values()[val - 1]);
return true;
@ -234,7 +255,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public void setHorizontalCentered(Boolean isCentered){
public void setHorizontalCentered(Boolean isCentered) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if (isCentered == null) {
@ -248,11 +269,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public boolean isHorizontalCentered(){
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
public boolean isHorizontalCentered() {
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetAnchorCtr()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetAnchorCtr()) {
setValue(props.getAnchorCtr());
return true;
}
@ -264,11 +285,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public void setTextDirection(TextDirection orientation){
public void setTextDirection(TextDirection orientation) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(orientation == null) {
if(bodyPr.isSetVert()) {
if (orientation == null) {
if (bodyPr.isSetVert()) {
bodyPr.unsetVert();
}
} else {
@ -278,11 +299,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public TextDirection getTextDirection(){
public TextDirection getTextDirection() {
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
STTextVerticalType.Enum val = bodyPr.getVert();
if(val != null) {
if (val != null) {
switch (val.intValue()) {
default:
case STTextVerticalType.INT_HORZ:
@ -315,22 +336,22 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
public void setTextRotation(Double rotation) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
bodyPr.setRot((int)(rotation * 60000.));
bodyPr.setRot((int) (rotation * 60000.));
}
}
/**
* Returns the distance (in points) between the bottom of the text frame
* and the bottom of the inscribed rectangle of the shape that contains the text.
* Returns the distance (in points) between the bottom of the text frame and
* the bottom of the inscribed rectangle of the shape that contains the
* text.
*
* @return the bottom inset in points
*/
public double getBottomInset(){
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
public double getBottomInset() {
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetBIns()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetBIns()) {
double val = Units.toPoints(props.getBIns());
setValue(val);
return true;
@ -350,11 +371,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
*
* @return the left inset in points
*/
public double getLeftInset(){
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
public double getLeftInset() {
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetLIns()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetLIns()) {
double val = Units.toPoints(props.getLIns());
setValue(val);
return true;
@ -368,17 +389,17 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
/**
* Returns the distance (in points) between the right edge of the
* text frame and the right edge of the inscribed rectangle of the shape
* that contains the text.
* Returns the distance (in points) between the right edge of the text frame
* and the right edge of the inscribed rectangle of the shape that contains
* the text.
*
* @return the right inset in points
*/
public double getRightInset(){
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
public double getRightInset() {
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetRIns()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetRIns()) {
double val = Units.toPoints(props.getRIns());
setValue(val);
return true;
@ -392,16 +413,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
/**
* Returns the distance (in points) between the top of the text frame
* and the top of the inscribed rectangle of the shape that contains the text.
* Returns the distance (in points) between the top of the text frame and
* the top of the inscribed rectangle of the shape that contains the text.
*
* @return the top inset in points
*/
public double getTopInset(){
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
public double getTopInset() {
PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetTIns()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetTIns()) {
double val = Units.toPoints(props.getTIns());
setValue(val);
return true;
@ -416,14 +437,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
* Sets the bottom margin.
*
* @see #getBottomInset()
*
* @param margin the bottom margin
* @param margin
* the bottom margin
*/
public void setBottomInset(double margin){
public void setBottomInset(double margin) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(margin == -1) {
if (margin == -1) {
bodyPr.unsetBIns();
} else {
bodyPr.setBIns(Units.toEMU(margin));
@ -433,14 +456,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
* Sets the left margin.
*
* @see #getLeftInset()
*
* @param margin the left margin
* @param margin
* the left margin
*/
public void setLeftInset(double margin){
public void setLeftInset(double margin) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(margin == -1) {
if (margin == -1) {
bodyPr.unsetLIns();
} else {
bodyPr.setLIns(Units.toEMU(margin));
@ -450,14 +475,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
* Sets the right margin.
*
* @see #getRightInset()
*
* @param margin the right margin
* @param margin
* the right margin
*/
public void setRightInset(double margin){
public void setRightInset(double margin) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(margin == -1) {
if (margin == -1) {
bodyPr.unsetRIns();
} else {
bodyPr.setRIns(Units.toEMU(margin));
@ -467,14 +494,16 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
* Sets the top margin.
*
* @see #getTopInset()
*
* @param margin the top margin
* @param margin
* the top margin
*/
public void setTopInset(double margin){
public void setTopInset(double margin) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(margin == -1) {
if (margin == -1) {
bodyPr.unsetTIns();
} else {
bodyPr.setTIns(Units.toEMU(margin));
@ -496,11 +525,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public boolean getWordWrap(){
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
public boolean getWordWrap() {
PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>() {
@Override
public boolean fetch(CTTextBodyProperties props){
if(props.isSetWrap()){
public boolean fetch(CTTextBodyProperties props) {
if (props.isSetWrap()) {
setValue(props.getWrap() == STTextWrappingType.SQUARE);
return true;
}
@ -512,7 +541,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
}
@Override
public void setWordWrap(boolean wrap){
public void setWordWrap(boolean wrap) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
bodyPr.setWrap(wrap ? STTextWrappingType.SQUARE : STTextWrappingType.NONE);
@ -521,28 +550,36 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
/**
*
* Specifies that a shape should be auto-fit to fully contain the text described within it.
* Auto-fitting is when text within a shape is scaled in order to contain all the text inside
* Specifies that a shape should be auto-fit to fully contain the text
* described within it. Auto-fitting is when text within a shape is scaled
* in order to contain all the text inside
*
* @param value type of autofit
* @param value
* type of autofit
*/
public void setTextAutofit(TextAutofit value){
public void setTextAutofit(TextAutofit value) {
CTTextBodyProperties bodyPr = getTextBodyPr(true);
if (bodyPr != null) {
if(bodyPr.isSetSpAutoFit()) {
if (bodyPr.isSetSpAutoFit()) {
bodyPr.unsetSpAutoFit();
}
if(bodyPr.isSetNoAutofit()) {
if (bodyPr.isSetNoAutofit()) {
bodyPr.unsetNoAutofit();
}
if(bodyPr.isSetNormAutofit()) {
if (bodyPr.isSetNormAutofit()) {
bodyPr.unsetNormAutofit();
}
switch(value){
case NONE: bodyPr.addNewNoAutofit(); break;
case NORMAL: bodyPr.addNewNormAutofit(); break;
case SHAPE: bodyPr.addNewSpAutoFit(); break;
switch (value) {
case NONE:
bodyPr.addNewNoAutofit();
break;
case NORMAL:
bodyPr.addNewNormAutofit();
break;
case SHAPE:
bodyPr.addNewSpAutoFit();
break;
}
}
}
@ -551,10 +588,10 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
*
* @return type of autofit
*/
public TextAutofit getTextAutofit(){
public TextAutofit getTextAutofit() {
CTTextBodyProperties bodyPr = getTextBodyPr();
if (bodyPr != null) {
if(bodyPr.isSetNoAutofit()) {
if (bodyPr.isSetNoAutofit()) {
return TextAutofit.NONE;
} else if (bodyPr.isSetNormAutofit()) {
return TextAutofit.NORMAL;
@ -565,7 +602,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return TextAutofit.NORMAL;
}
protected CTTextBodyProperties getTextBodyPr(){
protected CTTextBodyProperties getTextBodyPr() {
return getTextBodyPr(false);
}
@ -588,24 +625,24 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
super.setPlaceholder(placeholder);
}
public Placeholder getTextType(){
public Placeholder getTextType() {
return getPlaceholder();
}
@Override
public double getTextHeight(){
public double getTextHeight() {
return getTextHeight(null);
}
@Override
public double getTextHeight(Graphics2D graphics){
public double getTextHeight(Graphics2D graphics) {
DrawFactory drawFact = DrawFactory.getInstance(graphics);
DrawTextShape dts = drawFact.getDrawable(this);
return dts.getTextHeight(graphics);
}
@Override
public Rectangle2D resizeToFitText(){
public Rectangle2D resizeToFitText() {
return resizeToFitText(null);
}
@ -613,64 +650,63 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
public Rectangle2D resizeToFitText(Graphics2D graphics) {
Rectangle2D anchor = getAnchor();
if(anchor.getWidth() == 0.) {
if (anchor.getWidth() == 0.) {
throw new POIXMLException("Anchor of the shape was not set.");
}
double height = getTextHeight(graphics);
height += 1; // add a pixel to compensate rounding errors
Insets2D insets = getInsets();
anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height+insets.top+insets.bottom);
anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height + insets.top + insets.bottom);
setAnchor(anchor);
return anchor;
}
@Override
void copy(XSLFShape other){
void copy(XSLFShape other) {
super.copy(other);
XSLFTextShape otherTS = (XSLFTextShape)other;
XSLFTextShape otherTS = (XSLFTextShape) other;
CTTextBody otherTB = otherTS.getTextBody(false);
CTTextBody thisTB = getTextBody(true);
if (otherTB == null) {
return;
}
thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy());
thisTB.setBodyPr((CTTextBodyProperties) otherTB.getBodyPr().copy());
if (thisTB.isSetLstStyle()) {
thisTB.unsetLstStyle();
}
if (otherTB.isSetLstStyle()) {
thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy());
thisTB.setLstStyle((CTTextListStyle) otherTB.getLstStyle().copy());
}
boolean srcWordWrap = otherTS.getWordWrap();
if(srcWordWrap != getWordWrap()){
if (srcWordWrap != getWordWrap()) {
setWordWrap(srcWordWrap);
}
double leftInset = otherTS.getLeftInset();
if(leftInset != getLeftInset()) {
if (leftInset != getLeftInset()) {
setLeftInset(leftInset);
}
double rightInset = otherTS.getRightInset();
if(rightInset != getRightInset()) {
if (rightInset != getRightInset()) {
setRightInset(rightInset);
}
double topInset = otherTS.getTopInset();
if(topInset != getTopInset()) {
if (topInset != getTopInset()) {
setTopInset(topInset);
}
double bottomInset = otherTS.getBottomInset();
if(bottomInset != getBottomInset()) {
if (bottomInset != getBottomInset()) {
setBottomInset(bottomInset);
}
VerticalAlignment vAlign = otherTS.getVerticalAlignment();
if(vAlign != getVerticalAlignment()) {
if (vAlign != getVerticalAlignment()) {
setVerticalAlignment(vAlign);
}
@ -715,18 +751,23 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
return TextPlaceholder.BODY;
}
switch (ph) {
case BODY: return TextPlaceholder.BODY;
case TITLE: return TextPlaceholder.TITLE;
case CENTERED_TITLE: return TextPlaceholder.CENTER_TITLE;
case BODY:
return TextPlaceholder.BODY;
case TITLE:
return TextPlaceholder.TITLE;
case CENTERED_TITLE:
return TextPlaceholder.CENTER_TITLE;
default:
case CONTENT: return TextPlaceholder.OTHER;
case CONTENT:
return TextPlaceholder.OTHER;
}
}
/**
* Helper method to allow subclasses to provide their own text paragraph
*
* @param p the xml reference
* @param p
* the xml reference
*
* @return a new text paragraph
*
@ -735,4 +776,19 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) {
return new XSLFTextParagraph(p, this);
}
@Override
public <R> Optional<R> findDefinedParagraphProperty(Function<CTTextParagraphProperties, Boolean> isSet,
Function<CTTextParagraphProperties, R> getter) {
// TODO Auto-generated method stub
return Optional.empty();
}
@Override
public <R> Optional<R> findDefinedRunProperty(Function<CTTextCharacterProperties, Boolean> isSet,
Function<CTTextCharacterProperties, R> getter) {
// TODO Auto-generated method stub
return Optional.empty();
}
}

View File

@ -74,7 +74,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
private XSSFGraphicFrame frame;
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
List<XSSFChartAxis> axis = new ArrayList<>();
/**
@ -89,7 +89,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
* Construct a SpreadsheetML chart from a package part.
*
* @param part
* the package part holding the chart data, the content type must be
* the package part holding the chart data, the content type must
* be
* <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
*
* @since POI 3.14-Beta1
@ -114,7 +115,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
}
/**
* Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects.
* Construct a new CTChartSpace bean. By default, it's just an empty
* placeholder for chart objects.
*/
private void createChart() {
CTPlotArea plotArea = getCTPlotArea();
@ -140,12 +142,15 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
/*
* Saved chart space must have the following namespaces set: <c:chartSpace
* Saved chart space must have the following namespaces set:
* <c:chartSpace
* xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
* xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r=
* xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
* xmlns:r=
* "http://schemas.openxmlformats.org/officeDocument/2006/relationships">
*/
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
xmlOptions.setSaveSyntheticDocumentElement(
new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
PackagePart part = getPackagePart();
try (OutputStream out = part.getOutputStream()) {
@ -171,28 +176,28 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFChartDataFactory getChartDataFactory() {
return XSSFChartDataFactory.getInstance();
}
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFChart getChartAxisFactory() {
return this;
}
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public void plot(ChartData data, ChartAxis... chartAxis) {
data.fillChart(this, chartAxis);
}
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos);
@ -207,7 +212,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos);
@ -222,7 +227,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos);
@ -240,7 +245,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
*/
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public List<? extends XSSFChartAxis> getAxis() {
if (axis.isEmpty() && hasAxis()) {
parseAxis();
@ -250,34 +255,36 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFManualLayout getManualLayout() {
return new XSSFManualLayout(this);
}
/**
* Returns the title static text, or null if none is set.
* Note that a title formula may be set instead.
* Returns the title static text, or null if none is set. Note that a title
* formula may be set instead.
*
* @return static title text, if set
* @deprecated POI 3.16, use {@link #getTitleText()} instead.
*/
@Deprecated
@Removal(version="4.0")
@Removal(version = "4.0")
public XSSFRichTextString getTitle() {
return getTitleText();
}
/**
* Returns the title static text, or null if none is set.
* Note that a title formula may be set instead.
* Empty text result is for backward compatibility, and could mean the title text is empty or there is a formula instead.
* Check for a formula first, falling back on text for cleaner logic.
* @return static title text if set,
* null if there is no title,
* empty string if the title text is empty or the title uses a formula instead
* Returns the title static text, or null if none is set. Note that a title
* formula may be set instead. Empty text result is for backward
* compatibility, and could mean the title text is empty or there is a
* formula instead. Check for a formula first, falling back on text for
* cleaner logic.
*
* @return static title text if set, null if there is no title, empty string
* if the title text is empty or the title uses a formula instead
*/
public XSSFRichTextString getTitleText() {
if(! chart.isSetTitle()) {
if (!chart.isSetTitle()) {
return null;
}
@ -285,8 +292,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
CTTitle title = chart.getTitle();
StringBuilder text = new StringBuilder(64);
XmlObject[] t = title
.selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t");
XmlObject[] t = title.selectPath("declare namespace a='" + XSSFDrawing.NAMESPACE_A + "' .//a:t");
for (XmlObject element : t) {
NodeList kids = element.getDomNode().getChildNodes();
final int count = kids.getLength();
@ -331,7 +337,8 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
rich = tx.getRich();
} else {
rich = tx.addNewRich();
rich.addNewBodyPr(); // body properties must exist (but can be empty)
rich.addNewBodyPr(); // body properties must exist (but can be
// empty)
}
CTTextParagraph para;
@ -414,21 +421,22 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Override
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
public XSSFChartLegend getOrCreateLegend() {
return new XSSFChartLegend(this);
}
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
private boolean hasAxis() {
CTPlotArea ctPlotArea = chart.getPlotArea();
int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray();
int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea
.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray();
return totalAxisCount > 0;
}
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
private void parseAxis() {
// TODO: add other axis types
parseCategoryAxis();
@ -437,7 +445,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
}
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
private void parseCategoryAxis() {
for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) {
axis.add(new XSSFCategoryAxis(this, catAx));
@ -445,7 +453,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
}
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
private void parseDateAxis() {
for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) {
axis.add(new XSSFDateAxis(this, dateAx));
@ -453,7 +461,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
}
@Deprecated
@Removal(version="4.2")
@Removal(version = "4.2")
private void parseValueAxis() {
for (CTValAx valAx : chart.getPlotArea().getValAxArray()) {
axis.add(new XSSFValueAxis(this, valAx));

View File

@ -103,7 +103,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS
XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
shape.setXfrm(anchor.getCTTransform2D());
return shape;
}
@ -122,7 +122,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS
XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());
shape.setXfrm(anchor.getCTTransform2D());
return shape;
}
@ -220,6 +220,7 @@ public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XS
chExt.setCy(y2);
}
@Override
protected CTShapeProperties getShapeProperties() {
throw new IllegalStateException("Not supported for shape group");
}

View File

@ -0,0 +1,81 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xddf.usermodel.text;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.poi.util.Units;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;
public class TestXDDFTextBodyProperties {
@Test
public void testProperties() throws IOException {
XDDFBodyProperties body = new XDDFTextBody(null).getBodyProperties();
CTTextBodyProperties props = body.getXmlObject();
body.setBottomInset(null);
assertFalse(props.isSetBIns());
body.setBottomInset(3.6);
assertTrue(props.isSetBIns());
assertEquals(Units.toEMU(3.6), props.getBIns());
body.setLeftInset(null);
assertFalse(props.isSetLIns());
body.setLeftInset(3.6);
assertTrue(props.isSetLIns());
assertEquals(Units.toEMU(3.6), props.getLIns());
body.setRightInset(null);
assertFalse(props.isSetRIns());
body.setRightInset(3.6);
assertTrue(props.isSetRIns());
assertEquals(Units.toEMU(3.6), props.getRIns());
body.setTopInset(null);
assertFalse(props.isSetTIns());
body.setTopInset(3.6);
assertTrue(props.isSetTIns());
assertEquals(Units.toEMU(3.6), props.getTIns());
body.setAutoFit(null);
assertFalse(props.isSetNoAutofit());
assertFalse(props.isSetNormAutofit());
assertFalse(props.isSetSpAutoFit());
body.setAutoFit(new XDDFNoAutoFit());
assertTrue(props.isSetNoAutofit());
assertFalse(props.isSetNormAutofit());
assertFalse(props.isSetSpAutoFit());
body.setAutoFit(new XDDFNormalAutoFit());
assertFalse(props.isSetNoAutofit());
assertTrue(props.isSetNormAutofit());
assertFalse(props.isSetSpAutoFit());
body.setAutoFit(new XDDFShapeAutoFit());
assertFalse(props.isSetNoAutofit());
assertFalse(props.isSetNormAutofit());
assertTrue(props.isSetSpAutoFit());
}
}

View File

@ -0,0 +1,135 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xddf.usermodel.text;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTextShape;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTextBox;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Test;
public class TestXDDFTextRun {
@Test
public void testTextRunPropertiesInSlide() throws IOException {
try (XMLSlideShow ppt = new XMLSlideShow()) {
XSLFSlide slide = ppt.createSlide();
XSLFTextShape sh = slide.createAutoShape();
sh.addNewTextParagraph();
XDDFTextBody body = sh.getTextBody();
XDDFTextParagraph para = body.getParagraph(0);
XDDFTextRun r = para.appendRegularRun("text");
assertEquals(LocaleUtil.getUserLocale().toLanguageTag(), r.getLanguage().toLanguageTag());
assertNull(r.getCharacterSpacing());
r.setCharacterSpacing(3.0);
assertEquals(3., r.getCharacterSpacing(), 0);
r.setCharacterSpacing(-3.0);
assertEquals(-3., r.getCharacterSpacing(), 0);
r.setCharacterSpacing(0.0);
assertEquals(0., r.getCharacterSpacing(), 0);
assertEquals(11.0, r.getFontSize(), 0);
r.setFontSize(13.0);
assertEquals(13.0, r.getFontSize(), 0);
assertFalse(r.isSuperscript());
r.setSuperscript(0.8);
assertTrue(r.isSuperscript());
r.setSuperscript(null);
assertFalse(r.isSuperscript());
assertFalse(r.isSubscript());
r.setSubscript(0.7);
assertTrue(r.isSubscript());
r.setSubscript(null);
assertFalse(r.isSubscript());
r.setBaseline(0.9);
assertTrue(r.isSuperscript());
r.setBaseline(-0.6);
assertTrue(r.isSubscript());
}
}
@Test
public void testTextRunPropertiesInSheet() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFTextBox shape = drawing.createTextbox(new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4));
shape.addNewTextParagraph().addNewTextRun().setText("Line 1");
XDDFTextBody body = shape.getTextBody();
XDDFTextParagraph para = body.getParagraph(1);
List<XDDFTextRun> runs = para.getTextRuns();
assertEquals(1, runs.size());
XDDFTextRun run = runs.get(0);
assertEquals("Line 1", run.getText());
assertFalse(run.isStrikeThrough());
run.setStrikeThrough(StrikeType.SINGLE_STRIKE);
assertTrue(run.isStrikeThrough());
run.setStrikeThrough(StrikeType.NO_STRIKE);
assertFalse(run.isStrikeThrough());
assertFalse(run.isCapitals());
run.setCapitals(CapsType.SMALL);
assertTrue(run.isCapitals());
run.setCapitals(CapsType.NONE);
assertFalse(run.isCapitals());
assertFalse(run.isBold());
run.setBold(true);
assertTrue(run.isBold());
run.setBold(false);
assertFalse(run.isBold());
assertFalse(run.isItalic());
run.setItalic(true);
assertTrue(run.isItalic());
run.setItalic(false);
assertFalse(run.isItalic());
assertFalse(run.isUnderline());
run.setUnderline(UnderlineType.WAVY_DOUBLE);
assertTrue(run.isUnderline());
run.setUnderline(UnderlineType.NONE);
assertFalse(run.isUnderline());
assertNotNull(run.getText());
}
}
}

View File

@ -30,6 +30,7 @@ import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hslf.usermodel.HSLFTextShape;
@ -38,6 +39,8 @@ import org.apache.poi.sl.usermodel.SlideShow;
import org.apache.poi.sl.usermodel.SlideShowFactory;
import org.apache.poi.sl.usermodel.TextParagraph.TextAlign;
import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.junit.BeforeClass;
import org.junit.Test;
@ -83,6 +86,8 @@ public class TestXSLFTextShape {
assertEquals("Title Slide",layout.getName());
XSLFTextShape shape1 = (XSLFTextShape)shapes.get(0);
XDDFTextBody tb1 = shape1.getTextBody();
XDDFBodyProperties tbp1 = tb1.getBodyProperties();
CTPlaceholder ph1 = shape1.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType());
// anchor is not defined in the shape
@ -104,15 +109,24 @@ public class TestXSLFTextShape {
assertEquals(3.6, shape1.getTopInset(), 0); // 0.05"
assertEquals(3.6, shape1.getBottomInset(), 0); // 0.05"
assertEquals(VerticalAlignment.MIDDLE, shape1.getVerticalAlignment());
assertNull(tbp1.getLeftInset());
assertNull(tbp1.getRightInset());
assertNull(tbp1.getBottomInset());
assertNull(tbp1.getTopInset());
assertNull(tbp1.getAnchoring());
// now check text properties
assertEquals("Centered Title", shape1.getText());
assertEquals("Centered Title",
tb1.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n")));
XSLFTextRun r1 = shape1.getTextParagraphs().get(0).getTextRuns().get(0);
assertEquals("Calibri", r1.getFontFamily());
assertEquals(44.0, r1.getFontSize(), 0);
assertTrue(sameColor(Color.black, r1.getFontColor()));
XSLFTextShape shape2 = (XSLFTextShape)shapes.get(1);
XDDFTextBody tb2 = shape2.getTextBody();
XDDFBodyProperties tbp2 = tb2.getBodyProperties();
CTPlaceholder ph2 = shape2.getPlaceholderDetails().getCTPlaceholder(false);
assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType());
// anchor is not defined in the shape
@ -134,8 +148,14 @@ public class TestXSLFTextShape {
assertEquals(3.6, shape2.getTopInset(), 0); // 0.05"
assertEquals(3.6, shape2.getBottomInset(), 0); // 0.05"
assertEquals(VerticalAlignment.TOP, shape2.getVerticalAlignment());
assertNull(tbp2.getLeftInset());
assertNull(tbp2.getRightInset());
assertNull(tbp2.getBottomInset());
assertNull(tbp2.getTopInset());
assertNull(tbp2.getAnchoring());
assertEquals("subtitle", shape2.getText());
assertEquals("subtitle", tb2.getParagraphs().stream().map(p -> p.getText()).collect(Collectors.joining("\n")));
XSLFTextRun r2 = shape2.getTextParagraphs().get(0).getTextRuns().get(0);
assertEquals("Calibri", r2.getFontFamily());
assertEquals(32.0, r2.getFontSize(), 0);

View File

@ -16,12 +16,23 @@
==================================================================== */
package org.apache.poi.xssf.usermodel;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.io.IOException;
import java.util.List;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xddf.usermodel.text.XDDFBodyProperties;
import org.apache.poi.xddf.usermodel.text.XDDFNoAutoFit;
import org.apache.poi.xddf.usermodel.text.XDDFNormalAutoFit;
import org.apache.poi.xddf.usermodel.text.XDDFShapeAutoFit;
import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xddf.usermodel.text.XDDFTextParagraph;
import org.junit.Test;
public class TestXSSFSimpleShape {
@ -48,7 +59,7 @@ public class TestXSSFSimpleShape {
assertNotNull(shape.iterator());
assertNotNull(XSSFSimpleShape.prototype());
for(ListAutoNumber nr : ListAutoNumber.values()) {
for (ListAutoNumber nr : ListAutoNumber.values()) {
shape.getTextParagraphs().get(0).setBullet(nr);
assertNotNull(shape.getText());
}
@ -68,6 +79,16 @@ public class TestXSSFSimpleShape {
shape.addNewTextParagraph(new XSSFRichTextString());
assertEquals("null\n\ntest-other-text\nrtstring\nnull", shape.getText());
XDDFTextBody body = shape.getTextBody();
assertNotNull(body);
List<XDDFTextParagraph> paragraphs = body.getParagraphs();
assertEquals(5, paragraphs.size());
assertEquals("null", body.getParagraph(0).getText());
assertEquals("", body.getParagraph(1).getText());
assertEquals("test-other-text", body.getParagraph(2).getText());
assertEquals("rtstring", body.getParagraph(3).getText());
assertEquals("null", body.getParagraph(4).getText());
assertEquals(TextHorizontalOverflow.OVERFLOW, shape.getTextHorizontalOverflow());
shape.setTextHorizontalOverflow(TextHorizontalOverflow.CLIP);
assertEquals(TextHorizontalOverflow.CLIP, shape.getTextHorizontalOverflow());
@ -108,37 +129,56 @@ public class TestXSSFSimpleShape {
shape.setTextDirection(null);
assertEquals(TextDirection.HORIZONTAL, shape.getTextDirection());
XDDFBodyProperties props = body.getBodyProperties();
assertNotNull(props);
assertEquals(3.6, shape.getBottomInset(), 0.01);
assertNull(props.getBottomInset());
shape.setBottomInset(12.32);
assertEquals(12.32, shape.getBottomInset(), 0.01);
assertEquals(12.32, props.getBottomInset(), 0.01);
shape.setBottomInset(-1);
assertEquals(3.6, shape.getBottomInset(), 0.01);
assertNull(props.getBottomInset());
shape.setBottomInset(-1);
assertEquals(3.6, shape.getBottomInset(), 0.01);
assertNull(props.getBottomInset());
assertEquals(3.6, shape.getLeftInset(), 0.01);
assertNull(props.getLeftInset());
shape.setLeftInset(12.31);
assertEquals(12.31, shape.getLeftInset(), 0.01);
assertEquals(12.31, props.getLeftInset(), 0.01);
shape.setLeftInset(-1);
assertEquals(3.6, shape.getLeftInset(), 0.01);
assertNull(props.getLeftInset());
shape.setLeftInset(-1);
assertEquals(3.6, shape.getLeftInset(), 0.01);
assertNull(props.getLeftInset());
assertEquals(3.6, shape.getRightInset(), 0.01);
assertNull(props.getRightInset());
shape.setRightInset(13.31);
assertEquals(13.31, shape.getRightInset(), 0.01);
assertEquals(13.31, props.getRightInset(), 0.01);
shape.setRightInset(-1);
assertEquals(3.6, shape.getRightInset(), 0.01);
assertNull(props.getRightInset());
shape.setRightInset(-1);
assertEquals(3.6, shape.getRightInset(), 0.01);
assertNull(props.getRightInset());
assertEquals(3.6, shape.getTopInset(), 0.01);
assertNull(props.getTopInset());
shape.setTopInset(23.31);
assertEquals(23.31, shape.getTopInset(), 0.01);
assertEquals(23.31, props.getTopInset(), 0.01);
shape.setTopInset(-1);
assertEquals(3.6, shape.getTopInset(), 0.01);
assertNull(props.getTopInset());
shape.setTopInset(-1);
assertEquals(3.6, shape.getTopInset(), 0.01);
assertNull(props.getTopInset());
assertTrue(shape.getWordWrap());
shape.setWordWrap(false);
@ -147,22 +187,26 @@ public class TestXSSFSimpleShape {
assertTrue(shape.getWordWrap());
assertEquals(TextAutofit.NORMAL, shape.getTextAutofit());
assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit);
shape.setTextAutofit(TextAutofit.NORMAL);
assertEquals(TextAutofit.NORMAL, shape.getTextAutofit());
assertTrue(props.getAutoFit() instanceof XDDFNormalAutoFit);
shape.setTextAutofit(TextAutofit.SHAPE);
assertEquals(TextAutofit.SHAPE, shape.getTextAutofit());
assertTrue(props.getAutoFit() instanceof XDDFShapeAutoFit);
shape.setTextAutofit(TextAutofit.NONE);
assertEquals(TextAutofit.NONE, shape.getTextAutofit());
assertTrue(props.getAutoFit() instanceof XDDFNoAutoFit);
assertEquals(5, shape.getShapeType());
shape.setShapeType(23);
assertEquals(23, shape.getShapeType());
// TODO: should this be supported?
// shape.setShapeType(-1);
// assertEquals(-1, shape.getShapeType());
// shape.setShapeType(-1);
// assertEquals(-1, shape.getShapeType());
// shape.setShapeType(-1);
// assertEquals(-1, shape.getShapeType());
// shape.setShapeType(-1);
// assertEquals(-1, shape.getShapeType());
assertNotNull(shape.getShapeProperties());
} finally {