#59702 - Setting background color in slide master

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1749108 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2016-06-18 23:48:00 +00:00
parent d8d821b1f2
commit e1241ed975
12 changed files with 2553 additions and 499 deletions

View File

@ -22,20 +22,16 @@ import java.awt.Dimension;
import java.awt.geom.Rectangle2D;
import org.apache.poi.POIXMLException;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.Background;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.FillStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
/**
* Background shape
*
* @author Yegor Kozlov
*/
public class XSLFBackground extends XSLFSimpleShape
implements Background<XSLFShape,XSLFTextParagraph> {
@ -50,27 +46,16 @@ public class XSLFBackground extends XSLFSimpleShape
return new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());
}
@Override
public Color getFillColor(){
FillStyle fs = getFillStyle();
PaintStyle ps = fs.getPaint();
if (ps instanceof SolidPaint) {
SolidPaint sp = (SolidPaint)ps;
ColorStyle cs = sp.getSolidColor();
return DrawPaint.applyColorTransform(cs);
}
return null;
}
/**
* background does not have a associated transform.
* we return a dummy transform object to prevent exceptions in inherited methods.
* background does not have a associated transform, therefore we return null
*
* @param create ignored
*
* @return dummy CTTransform2D bean
* @return null
*/
@Override
protected CTTransform2D getXfrm() {
return CTTransform2D.Factory.newInstance();
protected CTTransform2D getXfrm(boolean create) {
return null;
}
@Override
@ -78,4 +63,50 @@ public class XSLFBackground extends XSLFSimpleShape
// extending XSLFSimpleShape is a bit unlucky ...
throw new POIXMLException("Can't set a placeholder for a background");
}
protected CTBackgroundProperties getBgPr(boolean create) {
CTBackground bg = (CTBackground)getXmlObject();
if (!bg.isSetBgPr() && create) {
if (bg.isSetBgRef()) {
bg.unsetBgRef();
}
return bg.addNewBgPr();
}
return bg.getBgPr();
}
public void setFillColor(Color color) {
CTBackgroundProperties bgPr = getBgPr(true);
if (color == null) {
if (bgPr.isSetSolidFill()) {
bgPr.unsetSolidFill();
}
if (!bgPr.isSetNoFill()) {
bgPr.addNewNoFill();
}
} else {
if (bgPr.isSetNoFill()) {
bgPr.unsetNoFill();
}
CTSolidColorFillProperties fill = bgPr.isSetSolidFill() ? bgPr.getSolidFill() : bgPr.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
col.setColor(color);
}
}
@Override
protected XmlObject getShapeProperties() {
CTBackground bg = (CTBackground)getXmlObject();
if (bg.isSetBgPr()) {
return bg.getBgPr();
} else if (bg.isSetBgRef()) {
return bg.getBgRef();
} else {
return null;
}
}
}

View File

@ -45,8 +45,6 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual;
/**
* Represents a custom geometric shape.
* This shape will consist of a series of lines and curves described within a creation path.
*
* @author Yegor Kozlov
*/
@Beta
public class XSLFFreeformShape extends XSLFAutoShape
@ -115,7 +113,13 @@ public class XSLFFreeformShape extends XSLFAutoShape
}
it.next();
}
getSpPr().getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath});
XmlObject xo = getShapeProperties();
if (!(xo instanceof CTShapeProperties)) {
return -1;
}
((CTShapeProperties)xo).getCustGeom().getPathLst().setPathArray(new CTPath2D[]{ctPath});
setAnchor(bounds);
return numPoints;
}
@ -125,7 +129,12 @@ public class XSLFFreeformShape extends XSLFAutoShape
Path2D.Double path = new Path2D.Double();
Rectangle2D bounds = getAnchor();
CTCustomGeometry2D geom = getSpPr().getCustGeom();
XmlObject xo = getShapeProperties();
if (!(xo instanceof CTShapeProperties)) {
return null;
}
CTCustomGeometry2D geom = ((CTShapeProperties)xo).getCustGeom();
for(CTPath2D spPath : geom.getPathLst().getPathArray()){
double scaleW = bounds.getWidth() / Units.toPoints(spPath.getW());
double scaleH = bounds.getHeight() / Units.toPoints(spPath.getH());

File diff suppressed because it is too large Load Diff

View File

@ -41,13 +41,14 @@ import org.apache.poi.sl.usermodel.Shape;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
@ -57,7 +58,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
@ -68,11 +68,12 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
*/
@Beta
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
protected static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
private final XmlObject _shape;
private final XSLFSheet _sheet;
private XSLFShapeContainer _parent;
private CTShapeProperties _spPr;
private CTShapeStyle _spStyle;
private CTNonVisualDrawingProps _nvPr;
private CTPlaceholder _ph;
@ -151,75 +152,52 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
final XSLFTheme theme = getSheet().getTheme();
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
public boolean fetch(XSLFShape shape) {
XmlObject pr = null;
try {
pr = shape.getSpPr();
if (((CTShapeProperties)pr).isSetNoFill()) {
setValue(null);
return true;
}
} catch (IllegalStateException e) {}
// trying background properties now
if (pr == null) {
pr = shape.getBgPr();
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
if (fp == null) {
return false;
}
if (pr == null) {
pr = shape.getGrpSpPr();
}
if (pr == null) {
if (shape.getXmlObject() instanceof CTBackground) {
pr = shape.getXmlObject();
}
if (fp.isSetNoFill()) {
setValue(null);
return true;
}
if (pr == null) return false;
PaintStyle paint = null;
PackagePart pp = getSheet().getPackagePart();
for (XmlObject obj : pr.selectPath("*")) {
paint = selectPaint(obj, null, pp, theme);
if (paint != null) {
setValue(paint);
return true;
}
PackagePart pp = shape.getSheet().getPackagePart();
PaintStyle paint = selectPaint(fp, null, pp, theme);
if (paint != null) {
setValue(paint);
return true;
}
CTShapeStyle style = shape.getSpStyle();
if (style != null) {
fp = XSLFPropertiesDelegate.getFillDelegate(style.getFillRef());
paint = selectPaint(fp, null, pp, theme);
}
if (paint != null) {
setValue(paint);
return true;
}
return false;
}
};
fetchShapeProperty(fetcher);
PaintStyle paint = fetcher.getValue();
if (paint != null) return paint;
// fill color was not found, check if it is defined in the theme
// get a reference to a fill style within the style matrix.
CTStyleMatrixReference fillRef = null;
if (fillRef == null) {
CTShapeStyle style = getSpStyle();
if (style != null) fillRef = style.getFillRef();
}
if (fillRef == null) {
fillRef = getBgRef();
}
paint = selectPaint(fillRef, theme);
return paint;
return fetcher.getValue();
}
protected CTBackgroundProperties getBgPr() {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgPr";
return selectProperty(CTBackgroundProperties.class, xquery);
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
}
protected CTStyleMatrixReference getBgRef() {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:bgRef";
return selectProperty(CTStyleMatrixReference.class, xquery);
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
}
protected CTGroupShapeProperties getGrpSpPr() {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:grpSpPr";
return selectProperty(CTGroupShapeProperties.class, xquery);
return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
}
protected CTNonVisualDrawingProps getCNvPr() {
@ -230,28 +208,35 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return _nvPr;
}
protected CTShapeProperties getSpPr() {
if (_spPr == null) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:spPr";
_spPr = selectProperty(CTShapeProperties.class, xquery);
}
if (_spPr == null) {
throw new IllegalStateException("CTShapeProperties was not found.");
}
return _spPr;
}
protected CTShapeStyle getSpStyle() {
if (_spStyle == null) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' p:style";
_spStyle = selectProperty(CTShapeStyle.class, xquery);
_spStyle = getChild(CTShapeStyle.class, PML_NS, "style");
}
return _spStyle;
}
/**
* Return direct child objects of this shape
*
* @param childClass the class to cast the properties to
* @param namespace the namespace - usually it is {@code "http://schemas.openxmlformats.org/presentationml/2006/main"}
* @param nodename the node name, without prefix
* @return the properties object or null if it can't be found
*/
@SuppressWarnings("unchecked")
protected <T extends XmlObject> T getChild(Class<T> childClass, String namespace, String nodename) {
XmlCursor cur = getXmlObject().newCursor();
T child = null;
if (cur.toChild(namespace, nodename)) {
child = (T)cur.getObject();
}
cur.dispose();
return child;
}
protected CTPlaceholder getCTPlaceholder() {
if (_ph == null) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph";
String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr/p:ph";
_ph = selectProperty(CTPlaceholder.class, xquery);
}
return _ph;
@ -275,7 +260,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* @param placeholder
*/
protected void setPlaceholder(Placeholder placeholder) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr";
String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr";
CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery);
if (nv == null) return;
if(placeholder == null) {
@ -362,48 +347,28 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return ok;
}
protected PaintStyle getPaint(XmlObject spPr, CTSchemeColor phClr) {
PaintStyle paint = null;
XSLFSheet sheet = getSheet();
PackagePart pp = sheet.getPackagePart();
XSLFTheme theme = sheet.getTheme();
for (XmlObject obj : spPr.selectPath("*")) {
paint = selectPaint(obj, phClr, pp, theme);
if(paint != null) break;
}
return paint;
}
/**
* Convert shape fill into java.awt.Paint. The result is either Color or
* TexturePaint or GradientPaint or null
*
* @param obj the xml to read. Must contain elements from the EG_ColorChoice group:
* <code>
* a:scrgbClr RGB Color Model - Percentage Variant
* a:srgbClr RGB Color Model - Hex Variant
* a:hslClr Hue, Saturation, Luminance Color Model
* a:sysClr System Color
* a:schemeClr Scheme Color
* a:prstClr Preset Color
* </code>
*
* @param phClr context color
* @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it.
* @param fp a properties handler specific to the underlying shape properties
* @param phClr context color
* @param parentPart the parent package part. Any external references (images, etc.) are resolved relative to it.
* @param theme the theme for the shape/sheet
*
* @return the applied Paint or null if none was applied
*/
protected static PaintStyle selectPaint(XmlObject obj, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {
if (obj instanceof CTNoFillProperties) {
protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {
if (fp == null || fp.isSetNoFill()) {
return null;
} else if (obj instanceof CTSolidColorFillProperties) {
return selectPaint((CTSolidColorFillProperties)obj, phClr, theme);
} else if (obj instanceof CTBlipFillProperties) {
return selectPaint((CTBlipFillProperties)obj, parentPart);
} else if (obj instanceof CTGradientFillProperties) {
return selectPaint((CTGradientFillProperties) obj, phClr, theme);
} else if (obj instanceof CTStyleMatrixReference) {
return selectPaint((CTStyleMatrixReference)obj, theme);
} else if (fp.isSetSolidFill()) {
return selectPaint(fp.getSolidFill(), phClr, theme);
} else if (fp.isSetBlipFill()) {
return selectPaint(fp.getBlipFill(), parentPart);
} else if (fp.isSetGradFill()) {
return selectPaint(fp.getGradFill(), phClr, theme);
} else if (fp.isSetMatrixStyle()) {
return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle());
} else {
return null;
}
@ -518,7 +483,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
};
}
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme) {
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) {
if (fillRef == null) return null;
// The idx attribute refers to the index of a fill style or
@ -528,18 +493,39 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
// values 1001 and above refer to the index of a background fill style within the bgFillStyleLst element.
int idx = (int)fillRef.getIdx();
CTSchemeColor phClr = fillRef.getSchemeClr();
XmlObject fillProps = null;
CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
XmlObject styleLst = null;
int childIdx;
if (idx >= 1 && idx <= 999) {
fillProps = matrix.getFillStyleLst().selectPath("*")[idx - 1];
childIdx = idx-1;
styleLst = (isLineStyle) ? matrix.getLnStyleLst() : matrix.getFillStyleLst();
} else if (idx >= 1001 ){
fillProps = matrix.getBgFillStyleLst().selectPath("*")[idx - 1001];
childIdx = idx - 1001;
styleLst = matrix.getBgFillStyleLst();
} else {
return null;
}
return (fillProps == null) ? null : selectPaint(fillProps, phClr, theme.getPackagePart(), theme);
XmlCursor cur = styleLst.newCursor();
XSLFFillProperties fp = null;
if (cur.toChild(childIdx)) {
fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
}
cur.dispose();
return selectPaint(fp, phClr, theme.getPackagePart(), theme);
}
@Override
public void draw(Graphics2D graphics, Rectangle2D bounds) {
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
}
/**
* Return the shape specific (visual) properties
*
* @return the shape specific properties
*/
protected XmlObject getShapeProperties() {
return getChild(CTShapeProperties.class, PML_NS, "spPr");
}
}

View File

@ -26,6 +26,7 @@ import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.draw.geom.CustomGeometry;
import org.apache.poi.sl.draw.geom.Guide;
import org.apache.poi.sl.draw.geom.PresetGeometries;
@ -43,8 +44,13 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.model.PropertyFetcher;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFEffectProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
@ -82,6 +88,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
public abstract class XSLFSimpleShape extends XSLFShape
implements SimpleShape<XSLFShape,XSLFTextParagraph> {
private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance();
private static final POILogger LOG = POILogFactory.getLogger(XSLFSimpleShape.class);
/* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) {
super(shape,sheet);
@ -89,40 +96,64 @@ public abstract class XSLFSimpleShape extends XSLFShape
@Override
public void setShapeType(ShapeType type) {
STShapeType.Enum geom = STShapeType.Enum.forInt(type.ooxmlId);
getSpPr().getPrstGeom().setPrst(geom);
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
if (gp == null) {
return;
}
if (gp.isSetCustGeom()) {
gp.unsetCustGeom();
}
CTPresetGeometry2D prst = (gp.isSetPrstGeom()) ? gp.getPrstGeom() : gp.addNewPrstGeom();
prst.setPrst(STShapeType.Enum.forInt(type.ooxmlId));
}
@Override
public ShapeType getShapeType(){
STShapeType.Enum geom = getSpPr().getPrstGeom().getPrst();
return ShapeType.forId(geom.intValue(), true);
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
if (gp != null && gp.isSetPrstGeom()) {
STShapeType.Enum geom = gp.getPrstGeom().getPrst();
if (geom != null) {
return ShapeType.forId(geom.intValue(), true);
}
}
return null;
}
protected CTTransform2D getSafeXfrm() {
CTTransform2D xfrm = getXfrm();
return (xfrm == null ? getSpPr().addNewXfrm() : xfrm);
}
protected CTTransform2D getXfrm() {
protected CTTransform2D getXfrm(boolean create) {
PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties pr = shape.getSpPr();
if (pr.isSetXfrm()) {
setValue(pr.getXfrm());
XmlObject xo = shape.getShapeProperties();
if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) {
setValue(((CTShapeProperties)xo).getXfrm());
return true;
}
return false;
}
};
fetchShapeProperty(fetcher);
return fetcher.getValue();
CTTransform2D xfrm = fetcher.getValue();
if (!create || xfrm != null) {
return xfrm;
} else {
XmlObject xo = getShapeProperties();
if (xo instanceof CTShapeProperties) {
return ((CTShapeProperties)xo).addNewXfrm();
} else {
// ... group shapes have their own getXfrm()
LOG.log(POILogger.WARN, getClass().toString()+" doesn't have xfrm element.");
return null;
}
}
}
@Override
public Rectangle2D getAnchor() {
CTTransform2D xfrm = getXfrm();
CTTransform2D xfrm = getXfrm(false);
if (xfrm == null) {
return null;
}
CTPoint2D off = xfrm.getOff();
double x = Units.toPoints(off.getX());
@ -135,7 +166,10 @@ public abstract class XSLFSimpleShape extends XSLFShape
@Override
public void setAnchor(Rectangle2D anchor) {
CTTransform2D xfrm = getSafeXfrm();
CTTransform2D xfrm = getXfrm(true);
if (xfrm == null) {
return;
}
CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
long x = Units.toEMU(anchor.getX());
long y = Units.toEMU(anchor.getY());
@ -151,35 +185,44 @@ public abstract class XSLFSimpleShape extends XSLFShape
@Override
public void setRotation(double theta) {
getSafeXfrm().setRot((int) (theta * 60000));
CTTransform2D xfrm = getXfrm(true);
if (xfrm != null) {
xfrm.setRot((int) (theta * 60000));
}
}
@Override
public double getRotation() {
CTTransform2D xfrm = getXfrm();
CTTransform2D xfrm = getXfrm(false);
return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);
}
@Override
public void setFlipHorizontal(boolean flip) {
getSafeXfrm().setFlipH(flip);
CTTransform2D xfrm = getXfrm(true);
if (xfrm != null) {
xfrm.setFlipH(flip);
}
}
@Override
public void setFlipVertical(boolean flip) {
getSafeXfrm().setFlipV(flip);
CTTransform2D xfrm = getXfrm(true);
if (xfrm != null) {
xfrm.setFlipV(flip);
}
}
@Override
public boolean getFlipHorizontal() {
CTTransform2D xfrm = getXfrm();
return (xfrm == null || !xfrm.isSetFlipH()) ? false : getXfrm().getFlipH();
CTTransform2D xfrm = getXfrm(false);
return (xfrm == null || !xfrm.isSetFlipH()) ? false : xfrm.getFlipH();
}
@Override
public boolean getFlipVertical() {
CTTransform2D xfrm = getXfrm();
return (xfrm == null || !xfrm.isSetFlipV()) ? false : getXfrm().getFlipV();
CTTransform2D xfrm = getXfrm(false);
return (xfrm == null || !xfrm.isSetFlipV()) ? false : xfrm.getFlipV();
}
@ -187,7 +230,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
* Get default line properties defined in the theme (if any).
* Used internally to resolve shape properties.
*
* @return line propeties from the theme of null
* @return line properties from the theme of null
*/
CTLineProperties getDefaultLineProperties() {
CTShapeStyle style = getSpStyle();
@ -214,30 +257,29 @@ public abstract class XSLFSimpleShape extends XSLFShape
* A <code>null</code> value turns off the shape outline.
*/
public void setLineColor(Color color) {
CTShapeProperties spPr = getSpPr();
CTLineProperties ln = spPr.getLn();
if (color == null) {
if (ln == null) {
return;
}
if (ln.isSetSolidFill()) {
ln.unsetSolidFill();
}
if (!ln.isSetNoFill()) {
ln.addNewNoFill();
}
} else {
if (ln == null) {
ln = spPr.addNewLn();
}
if (ln.isSetNoFill()) {
ln.unsetNoFill();
}
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
if (ln.isSetSolidFill()) {
ln.unsetSolidFill();
}
if (ln.isSetGradFill()) {
ln.unsetGradFill();
}
if (ln.isSetPattFill()) {
ln.unsetPattFill();
}
if (ln.isSetNoFill()) {
ln.unsetNoFill();
}
if (color == null) {
ln.addNewNoFill();
} else {
CTSolidColorFillProperties fill = ln.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
col.setColor(color);
}
@ -257,37 +299,29 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
protected PaintStyle getLinePaint() {
final XSLFTheme theme = getSheet().getTheme();
XSLFSheet sheet = getSheet();
final XSLFTheme theme = sheet.getTheme();
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
public boolean fetch(XSLFShape shape) {
CTLineProperties spPr = shape.getSpPr().getLn();
if (spPr != null) {
if (spPr.isSetNoFill()) {
setValue(null); // use it as 'nofill' value
return true;
}
CTLineProperties spPr = getLn(shape, false);
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr);
PackagePart pp = shape.getSheet().getPackagePart();
PaintStyle paint = selectPaint(fp, null, pp, theme);
if (paint != null) {
setValue(paint);
return true;
}
PaintStyle paint = null;
PackagePart pp = getSheet().getPackagePart();
for (XmlObject obj : spPr.selectPath("*")) {
paint = selectPaint(obj, null, pp, theme);
if (paint != null) {
setValue(paint);
return true;
}
}
CTShapeStyle style = shape.getSpStyle();
if (style != null) {
paint = selectPaint(style.getLnRef(), theme);
if (paint != null) {
setValue(paint);
return true;
}
}
CTShapeStyle style = shape.getSpStyle();
if (style != null) {
fp = XSLFPropertiesDelegate.getFillDelegate(style.getLnRef());
paint = selectPaint(fp, null, pp, theme);
}
if (paint != null) {
setValue(paint);
return true;
}
return false;
}
};
fetchShapeProperty(fetcher);
@ -304,9 +338,10 @@ public abstract class XSLFSimpleShape extends XSLFShape
int idx = (int)lnRef.getIdx();
CTSchemeColor phClr = lnRef.getSchemeClr();
if(idx > 0){
XmlObject lnProps = theme.getXmlObject().
getThemeElements().getFmtScheme().getLnStyleLst().selectPath("*")[idx - 1];
paint = getPaint(lnProps, phClr);
CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1);
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
PackagePart pp = sheet.getPackagePart();
paint = selectPaint(fp, phClr, pp, theme);
}
return paint;
@ -317,14 +352,33 @@ public abstract class XSLFSimpleShape extends XSLFShape
* @param width line width in points. <code>0</code> means no line
*/
public void setLineWidth(double width) {
CTShapeProperties spPr = getSpPr();
CTLineProperties lnPr = getLn(this, true);
if (lnPr == null) {
return;
}
if (width == 0.) {
if (spPr.isSetLn() && spPr.getLn().isSetW())
spPr.getLn().unsetW();
if (lnPr.isSetW()) {
lnPr.unsetW();
}
if (!lnPr.isSetNoFill()) {
lnPr.addNewNoFill();
}
if (lnPr.isSetSolidFill()) {
lnPr.unsetSolidFill();
}
if (lnPr.isSetGradFill()) {
lnPr.unsetGradFill();
}
if (lnPr.isSetPattFill()) {
lnPr.unsetPattFill();
}
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
.addNewLn();
ln.setW(Units.toEMU(width));
if (lnPr.isSetNoFill()) {
lnPr.unsetNoFill();
}
lnPr.setW(Units.toEMU(width));
}
}
@ -334,8 +388,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
public double getLineWidth() {
PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties spPr = shape.getSpPr();
CTLineProperties ln = spPr.getLn();
CTLineProperties ln = getLn(shape, false);
if (ln != null) {
if (ln.isSetNoFill()) {
setValue(0.);
@ -370,12 +423,15 @@ public abstract class XSLFSimpleShape extends XSLFShape
* @param compound set the line compound style
*/
public void setLineCompound(LineCompound compound) {
CTShapeProperties spPr = getSpPr();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
if (compound == null) {
if (spPr.isSetLn() && spPr.getLn().isSetCmpd())
spPr.getLn().unsetCmpd();
if (ln.isSetCmpd()) {
ln.unsetCmpd();
}
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
STCompoundLine.Enum xCmpd;
switch (compound) {
default:
@ -405,8 +461,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
public LineCompound getLineCompound() {
PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties spPr = shape.getSpPr();
CTLineProperties ln = spPr.getLn();
CTLineProperties ln = getLn(shape, false);
if (ln != null) {
STCompoundLine.Enum stCmpd = ln.getCmpd();
if (stCmpd != null) {
@ -422,29 +477,24 @@ public abstract class XSLFSimpleShape extends XSLFShape
Integer cmpd = fetcher.getValue();
if (cmpd == null) {
CTLineProperties defaultLn = getDefaultLineProperties();
if (defaultLn != null) {
STCompoundLine.Enum stCmpd = defaultLn.getCmpd();
if (stCmpd != null) {
cmpd = stCmpd.intValue();
if (defaultLn != null && defaultLn.isSetCmpd()) {
switch (defaultLn.getCmpd().intValue()) {
default:
case STCompoundLine.INT_SNG:
return LineCompound.SINGLE;
case STCompoundLine.INT_DBL:
return LineCompound.DOUBLE;
case STCompoundLine.INT_THICK_THIN:
return LineCompound.THICK_THIN;
case STCompoundLine.INT_THIN_THICK:
return LineCompound.THIN_THICK;
case STCompoundLine.INT_TRI:
return LineCompound.TRIPLE;
}
}
}
if (cmpd == null) return null;
switch (cmpd) {
default:
case STCompoundLine.INT_SNG:
return LineCompound.SINGLE;
case STCompoundLine.INT_DBL:
return LineCompound.DOUBLE;
case STCompoundLine.INT_THICK_THIN:
return LineCompound.THICK_THIN;
case STCompoundLine.INT_THIN_THICK:
return LineCompound.THIN_THICK;
case STCompoundLine.INT_TRI:
return LineCompound.TRIPLE;
}
return null;
}
/**
@ -452,34 +502,34 @@ public abstract class XSLFSimpleShape extends XSLFShape
* @param dash a preset line dashing scheme to stroke thr shape outline
*/
public void setLineDash(LineDash dash) {
CTShapeProperties spPr = getSpPr();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
if (dash == null) {
if (spPr.isSetLn() && spPr.getLn().isSetPrstDash())
spPr.getLn().unsetPrstDash();
if (ln.isSetPrstDash()) {
ln.unsetPrstDash();
}
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr.addNewLn();
CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash();
ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
}
}
/**
* @return a preset line dashing scheme to stroke thr shape outline
* @return a preset line dashing scheme to stroke the shape outline
*/
public LineDash getLineDash() {
PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties spPr = shape.getSpPr();
CTLineProperties ln = spPr.getLn();
if (ln != null) {
CTPresetLineDashProperties ctDash = ln.getPrstDash();
if (ctDash != null) {
setValue(LineDash.fromOoxmlId(ctDash.getVal().intValue()));
return true;
}
CTLineProperties ln = getLn(shape, false);
if (ln == null || !ln.isSetPrstDash()) {
return false;
}
return false;
setValue(LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue()));
return true;
}
};
fetchShapeProperty(fetcher);
@ -487,11 +537,8 @@ public abstract class XSLFSimpleShape extends XSLFShape
LineDash dash = fetcher.getValue();
if (dash == null) {
CTLineProperties defaultLn = getDefaultLineProperties();
if (defaultLn != null) {
CTPresetLineDashProperties ctDash = defaultLn.getPrstDash();
if (ctDash != null) {
dash = LineDash.fromOoxmlId(ctDash.getVal().intValue());
}
if (defaultLn != null && defaultLn.isSetPrstDash()) {
dash = LineDash.fromOoxmlId(defaultLn.getPrstDash().getVal().intValue());
}
}
return dash;
@ -502,13 +549,16 @@ public abstract class XSLFSimpleShape extends XSLFShape
* @param cap the line end cap style
*/
public void setLineCap(LineCap cap) {
CTShapeProperties spPr = getSpPr();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
if (cap == null) {
if (spPr.isSetLn() && spPr.getLn().isSetCap())
spPr.getLn().unsetCap();
if (ln.isSetCap()) {
ln.unsetCap();
}
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
.addNewLn();
ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
}
}
@ -520,14 +570,10 @@ public abstract class XSLFSimpleShape extends XSLFShape
public LineCap getLineCap() {
PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties spPr = shape.getSpPr();
CTLineProperties ln = spPr.getLn();
if (ln != null) {
STLineCap.Enum stCap = ln.getCap();
if (stCap != null) {
setValue(LineCap.fromOoxmlId(stCap.intValue()));
return true;
}
CTLineProperties ln = getLn(shape, false);
if (ln != null && ln.isSetCap()) {
setValue(LineCap.fromOoxmlId(ln.getCap().intValue()));
return true;
}
return false;
}
@ -537,11 +583,8 @@ public abstract class XSLFSimpleShape extends XSLFShape
LineCap cap = fetcher.getValue();
if (cap == null) {
CTLineProperties defaultLn = getDefaultLineProperties();
if (defaultLn != null) {
STLineCap.Enum stCap = defaultLn.getCap();
if (stCap != null) {
cap = LineCap.fromOoxmlId(stCap.intValue());
}
if (defaultLn != null && defaultLn.isSetCap()) {
cap = LineCap.fromOoxmlId(defaultLn.getCap().intValue());
}
}
return cap;
@ -549,21 +592,36 @@ public abstract class XSLFSimpleShape extends XSLFShape
@Override
public void setFillColor(Color color) {
CTShapeProperties spPr = getSpPr();
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties());
if (fp == null) {
return;
}
if (color == null) {
if (spPr.isSetSolidFill()) {
spPr.unsetSolidFill();
if (fp.isSetSolidFill()) {
fp.unsetSolidFill();
}
if (fp.isSetGradFill()) {
fp.unsetGradFill();
}
if (!spPr.isSetNoFill()) {
spPr.addNewNoFill();
if (fp.isSetPattFill()) {
fp.unsetGradFill();
}
if (fp.isSetBlipFill()) {
fp.unsetBlipFill();
}
if (!fp.isSetNoFill()) {
fp.addNewNoFill();
}
} else {
if (spPr.isSetNoFill()) {
spPr.unsetNoFill();
if (fp.isSetNoFill()) {
fp.unsetNoFill();
}
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
col.setColor(color);
@ -574,7 +632,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
public Color getFillColor() {
PaintStyle ps = getFillPaint();
if (ps instanceof SolidPaint) {
return ((SolidPaint)ps).getSolidColor().getColor();
return DrawPaint.applyColorTransform(((SolidPaint)ps).getSolidColor());
}
return null;
}
@ -585,9 +643,9 @@ public abstract class XSLFSimpleShape extends XSLFShape
public XSLFShadow getShadow() {
PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
public boolean fetch(XSLFShape shape) {
CTShapeProperties spPr = shape.getSpPr();
if (spPr.isSetEffectLst()) {
CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw();
XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties());
if (ep != null && ep.isSetEffectLst()) {
CTOuterShadowEffect obj = ep.getEffectLst().getOuterShdw();
setValue(obj == null ? NO_SHADOW : obj);
return true;
}
@ -600,7 +658,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
if (obj == null) {
// fill color was not found, check if it is defined in the theme
CTShapeStyle style = getSpStyle();
if (style != null) {
if (style != null && style.getEffectRef() != null) {
// 1-based index of a shadow style within the style matrix
int idx = (int) style.getEffectRef().getIdx();
if(idx != 0) {
@ -618,17 +676,22 @@ public abstract class XSLFSimpleShape extends XSLFShape
* @return definition of the shape geometry
*/
public CustomGeometry getGeometry(){
CTShapeProperties spPr = getSpPr();
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
if (gp == null) {
return null;
}
CustomGeometry geom;
PresetGeometries dict = PresetGeometries.getInstance();
if(spPr.isSetPrstGeom()){
String name = spPr.getPrstGeom().getPrst().toString();
if(gp.isSetPrstGeom()){
String name = gp.getPrstGeom().getPrst().toString();
geom = dict.get(name);
if(geom == null) {
throw new IllegalStateException("Unknown shape geometry: " + name + ", available geometries are: " + dict.keySet());
}
} else if (spPr.isSetCustGeom()){
XMLStreamReader staxReader = spPr.getCustGeom().newXMLStreamReader();
} else if (gp.isSetCustGeom()){
XMLStreamReader staxReader = gp.getCustGeom().newXMLStreamReader();
geom = PresetGeometries.convertCustomGeometry(staxReader);
try { staxReader.close(); }
catch (XMLStreamException e) {}
@ -650,8 +713,9 @@ public abstract class XSLFSimpleShape extends XSLFShape
setFillColor(srsSolidFill);
}
if(getSpPr().isSetBlipFill()){
CTBlip blip = getSpPr().getBlipFill().getBlip();
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties());
if(fp != null && fp.isSetBlipFill()){
CTBlip blip = fp.getBlipFill().getBlip();
String blipId = blip.getEmbed();
String relId = getSheet().importBlip(blipId, s.getSheet().getPackagePart());
@ -686,130 +750,193 @@ public abstract class XSLFSimpleShape extends XSLFShape
/**
* Specifies the line end decoration, such as a triangle or arrowhead.
*
* @param style the line end docoration style
*/
public void setLineHeadDecoration(DecorationShape style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
if (style == null) {
if (lnEnd.isSetType()) lnEnd.unsetType();
if (lnEnd.isSetType()) {
lnEnd.unsetType();
}
} else {
lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration shape
*/
public DecorationShape getLineHeadDecoration() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetHeadEnd()) return DecorationShape.NONE;
STLineEndType.Enum end = ln.getHeadEnd().getType();
return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue());
CTLineProperties ln = getLn(this, false);
DecorationShape ds = DecorationShape.NONE;
if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetType()) {
ds = DecorationShape.fromOoxmlId(ln.getHeadEnd().getType().intValue());
}
return ds;
}
/**
* specifies decorations which can be added to the head of a line.
* specifies decoration width of the head of a line.
*
* @param style the decoration width
*/
public void setLineHeadWidth(DecorationSize style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
if (style == null) {
if (lnEnd.isSetW()) lnEnd.unsetW();
if (lnEnd.isSetW()) {
lnEnd.unsetW();
}
} else {
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration width
*/
public DecorationSize getLineHeadWidth() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;
STLineEndWidth.Enum w = ln.getHeadEnd().getW();
return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue());
CTLineProperties ln = getLn(this, false);
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetW()) {
ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getW().intValue());
}
return ds;
}
/**
* Specifies the line end width in relation to the line width.
*/
public void setLineHeadLength(DecorationSize style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
if (style == null) {
if (lnEnd.isSetLen()) lnEnd.unsetLen();
if (lnEnd.isSetLen()) {
lnEnd.unsetLen();
}
} else {
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration length
*/
public DecorationSize getLineHeadLength() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetHeadEnd()) return DecorationSize.MEDIUM;
STLineEndLength.Enum len = ln.getHeadEnd().getLen();
return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue());
CTLineProperties ln = getLn(this, false);
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetLen()) {
ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getLen().intValue());
}
return ds;
}
/**
* Specifies the line end decoration, such as a triangle or arrowhead.
*/
public void setLineTailDecoration(DecorationShape style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
if (style == null) {
if (lnEnd.isSetType()) lnEnd.unsetType();
if (lnEnd.isSetType()) {
lnEnd.unsetType();
}
} else {
lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration shape
*/
public DecorationShape getLineTailDecoration() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetTailEnd()) return DecorationShape.NONE;
STLineEndType.Enum end = ln.getTailEnd().getType();
return end == null ? DecorationShape.NONE : DecorationShape.fromOoxmlId(end.intValue());
CTLineProperties ln = getLn(this, false);
DecorationShape ds = DecorationShape.NONE;
if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetType()) {
ds = DecorationShape.fromOoxmlId(ln.getTailEnd().getType().intValue());
}
return ds;
}
/**
* specifies decorations which can be added to the tail of a line.
*/
public void setLineTailWidth(DecorationSize style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
if (style == null) {
if (lnEnd.isSetW()) lnEnd.unsetW();
if (lnEnd.isSetW()) {
lnEnd.unsetW();
}
} else {
lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration width
*/
public DecorationSize getLineTailWidth() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;
STLineEndWidth.Enum w = ln.getTailEnd().getW();
return w == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(w.intValue());
CTLineProperties ln = getLn(this, false);
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetW()) {
ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getW().intValue());
}
return ds;
}
/**
* Specifies the line end width in relation to the line width.
*/
public void setLineTailLength(DecorationSize style) {
CTLineProperties ln = getSpPr().getLn();
CTLineProperties ln = getLn(this, true);
if (ln == null) {
return;
}
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
if (style == null) {
if (lnEnd.isSetLen()) lnEnd.unsetLen();
if (lnEnd.isSetLen()) {
lnEnd.unsetLen();
}
} else {
lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
}
}
/**
* @return the line end decoration length
*/
public DecorationSize getLineTailLength() {
CTLineProperties ln = getSpPr().getLn();
if (ln == null || !ln.isSetTailEnd()) return DecorationSize.MEDIUM;
STLineEndLength.Enum len = ln.getTailEnd().getLen();
return len == null ? DecorationSize.MEDIUM : DecorationSize.fromOoxmlId(len.intValue());
CTLineProperties ln = getLn(this, false);
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetLen()) {
ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getLen().intValue());
}
return ds;
}
public boolean isPlaceholder() {
@ -818,9 +945,10 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
public Guide getAdjustValue(String name) {
CTPresetGeometry2D prst = getSpPr().getPrstGeom();
if (prst.isSetAvLst()) {
for (CTGeomGuide g : prst.getAvLst().getGdArray()) {
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) {
for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) {
if (g.getName().equals(name)) {
return new Guide(g.getName(), g.getFmla());
}
@ -943,4 +1071,15 @@ public abstract class XSLFSimpleShape extends XSLFShape
}
return hl;
}
}
private static CTLineProperties getLn(XSLFShape shape, boolean create) {
XmlObject pr = shape.getShapeProperties();
if (!(pr instanceof CTShapeProperties)) {
LOG.log(POILogger.WARN, shape.getClass().toString()+" doesn't have line properties");
return null;
}
CTShapeProperties spr = (CTShapeProperties)pr;
return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn();
}
}

View File

@ -23,7 +23,9 @@ import java.awt.Color;
import java.awt.geom.Rectangle2D;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
@ -31,9 +33,9 @@ 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.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
@ -41,13 +43,13 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTablePartStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleCellStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleTextStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
@ -393,22 +395,27 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
*/
@Override
public Color getFillColor(){
CTTableCellProperties spPr = getCellProperties(false);
if (spPr == null || !spPr.isSetSolidFill()) {
return null;
PaintStyle ps = getFillPaint();
if (ps instanceof SolidPaint) {
ColorStyle cs = ((SolidPaint)ps).getSolidColor();
return DrawPaint.applyColorTransform(cs);
}
CTSolidColorFillProperties fill = spPr.getSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
return c.getColor();
return null;
}
@SuppressWarnings("resource")
@Override
public PaintStyle getFillPaint() {
Color c = getFillColor();
if (c != null) {
return DrawPaint.createSolidPaint(c);
XSLFSheet sheet = getSheet();
XSLFTheme theme = sheet.getTheme();
XmlObject props = getCellProperties(false);
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
if (fp != null) {
PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme);
if (paint != null) {
return paint;
}
}
CTTablePartStyle tps = getTablePartStyle(null);
@ -419,20 +426,25 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
}
}
XMLSlideShow slideShow = table.getSheet().getSlideShow();
assert(slideShow != null);
XSLFTheme theme = slideShow.getSlides().get(0).getTheme();
CTFillProperties pr = tps.getTcStyle().getFill();
for (XmlObject obj : pr.selectPath("*")) {
PaintStyle paint = XSLFShape.selectPaint(obj, null, slideShow.getPackagePart(), theme);
if (paint != null) {
return paint;
}
}
return null;
XMLSlideShow slideShow = sheet.getSlideShow();
CTTableStyleCellStyle tcStyle = tps.getTcStyle();
if (tcStyle.isSetFill()) {
props = tcStyle.getFill();
} else if (tcStyle.isSetFillRef()) {
props = tcStyle.getFillRef();
} else {
return null;
}
fp = XSLFPropertiesDelegate.getFillDelegate(props);
if (fp != null) {
PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme);
if (paint != null) {
return paint;
}
}
return null;
}
/**
@ -671,17 +683,9 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
return new XSLFCellTextParagraph(p, this);
}
/**
* Return fake shape properties as a fallback for not overridden
* methods of XSLFSimpleShape
*
* @return fake shape properties
*
* @since POI 3.15-beta2
*/
@Override
protected CTShapeProperties getSpPr() {
return CTShapeProperties.Factory.newInstance();
protected XmlObject getShapeProperties() {
return getCellProperties(false);
}
/**

View File

@ -18,13 +18,25 @@ package org.apache.poi.xslf.usermodel;
import java.awt.Color;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.TextRun;
import org.apache.poi.util.Beta;
import org.apache.poi.xslf.model.CharacterPropertyFetcher;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
/**
@ -107,19 +119,26 @@ public class XSLFTextRun implements TextRun {
public PaintStyle getFontColor(){
CharacterPropertyFetcher<PaintStyle> fetcher = new CharacterPropertyFetcher<PaintStyle>(_p.getIndentLevel()){
public boolean fetch(CTTextCharacterProperties props){
if (props != null) {
XSLFShape shape = _p.getParentShape();
CTShapeStyle style = shape.getSpStyle();
CTSchemeColor phClr = null;
if (style != null && style.getFontRef() != null) {
phClr = style.getFontRef().getSchemeClr();
}
PaintStyle ps = shape.getPaint(props, phClr);
if (ps != null) {
setValue(ps);
return true;
}
if (props == null) {
return false;
}
XSLFShape shape = _p.getParentShape();
CTShapeStyle style = shape.getSpStyle();
CTSchemeColor phClr = null;
if (style != null && style.getFontRef() != null) {
phClr = style.getFontRef().getSchemeClr();
}
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
XSLFSheet sheet = shape.getSheet();
PackagePart pp = sheet.getPackagePart();
XSLFTheme theme = sheet.getTheme();
PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme);
if (ps != null) {
setValue(ps);
return true;
}
return false;

View File

@ -22,6 +22,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import org.apache.poi.POIDataSamples;
@ -29,7 +31,12 @@ import org.apache.poi.POIXMLProperties.CoreProperties;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFAutoShape;
import org.apache.poi.xslf.usermodel.XSLFBackground;
import org.apache.poi.xslf.usermodel.XSLFRelation;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFSlideShow;
import org.apache.xmlbeans.XmlException;
import org.junit.Before;
@ -126,4 +133,24 @@ public class TestXSLFSlideShow {
xml.close();
}
@Test
public void testMasterBackground() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFBackground b = ppt.getSlideMasters().get(0).getBackground();
b.setFillColor(Color.RED);
XSLFSlide sl = ppt.createSlide();
XSLFAutoShape as = sl.createAutoShape();
as.setAnchor(new Rectangle2D.Double(100,100,100,100));
as.setShapeType(ShapeType.CLOUD);
XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt);
ppt.close();
XSLFBackground b2 = ppt2.getSlideMasters().get(0).getBackground();
assertEquals(Color.RED, b2.getFillColor());
ppt2.close();
}
}

View File

@ -18,9 +18,11 @@ package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
@ -34,21 +36,18 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
/**
* @author Yegor Kozlov
*/
public class TestXSLFConnectorShape {
@Test
public void testLineDecorations() {
public void testLineDecorations() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
XSLFSlide slide = ppt.createSlide();
XSLFConnectorShape shape = slide.createConnector();
assertEquals(1, slide.getShapes().size());
assertFalse(shape.getSpPr().getLn().isSetHeadEnd());
assertFalse(shape.getSpPr().getLn().isSetTailEnd());
assertFalse(getSpPr(shape).getLn().isSetHeadEnd());
assertFalse(getSpPr(shape).getLn().isSetTailEnd());
// line decorations
assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration());
@ -57,22 +56,22 @@ public class TestXSLFConnectorShape {
shape.setLineTailDecoration(null);
assertEquals(DecorationShape.NONE, shape.getLineHeadDecoration());
assertEquals(DecorationShape.NONE, shape.getLineTailDecoration());
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetType());
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetType());
assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetType());
assertFalse(getSpPr(shape).getLn().getTailEnd().isSetType());
shape.setLineHeadDecoration(DecorationShape.ARROW);
shape.setLineTailDecoration(DecorationShape.DIAMOND);
assertEquals(DecorationShape.ARROW, shape.getLineHeadDecoration());
assertEquals(DecorationShape.DIAMOND, shape.getLineTailDecoration());
assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getHeadEnd().getType());
assertEquals(STLineEndType.DIAMOND, shape.getSpPr().getLn().getTailEnd().getType());
assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getHeadEnd().getType());
assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getTailEnd().getType());
shape.setLineHeadDecoration(DecorationShape.DIAMOND);
shape.setLineTailDecoration(DecorationShape.ARROW);
assertEquals(DecorationShape.DIAMOND, shape.getLineHeadDecoration());
assertEquals(DecorationShape.ARROW, shape.getLineTailDecoration());
assertEquals(STLineEndType.DIAMOND, shape.getSpPr().getLn().getHeadEnd().getType());
assertEquals(STLineEndType.ARROW, shape.getSpPr().getLn().getTailEnd().getType());
assertEquals(STLineEndType.DIAMOND, getSpPr(shape).getLn().getHeadEnd().getType());
assertEquals(STLineEndType.ARROW, getSpPr(shape).getLn().getTailEnd().getType());
// line end width
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth());
@ -81,20 +80,20 @@ public class TestXSLFConnectorShape {
shape.setLineHeadWidth(null);
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth());
assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth());
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetW());
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetW());
assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetW());
assertFalse(getSpPr(shape).getLn().getTailEnd().isSetW());
shape.setLineHeadWidth(DecorationSize.LARGE);
shape.setLineTailWidth(DecorationSize.MEDIUM);
assertEquals(DecorationSize.LARGE, shape.getLineHeadWidth());
assertEquals(DecorationSize.MEDIUM, shape.getLineTailWidth());
assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getHeadEnd().getW());
assertEquals(STLineEndWidth.MED, shape.getSpPr().getLn().getTailEnd().getW());
assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getHeadEnd().getW());
assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getTailEnd().getW());
shape.setLineHeadWidth(DecorationSize.MEDIUM);
shape.setLineTailWidth(DecorationSize.LARGE);
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadWidth());
assertEquals(DecorationSize.LARGE, shape.getLineTailWidth());
assertEquals(STLineEndWidth.MED, shape.getSpPr().getLn().getHeadEnd().getW());
assertEquals(STLineEndWidth.LG, shape.getSpPr().getLn().getTailEnd().getW());
assertEquals(STLineEndWidth.MED, getSpPr(shape).getLn().getHeadEnd().getW());
assertEquals(STLineEndWidth.LG, getSpPr(shape).getLn().getTailEnd().getW());
// line end length
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength());
@ -103,25 +102,26 @@ public class TestXSLFConnectorShape {
shape.setLineTailLength(null);
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength());
assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength());
assertFalse(shape.getSpPr().getLn().getHeadEnd().isSetLen());
assertFalse(shape.getSpPr().getLn().getTailEnd().isSetLen());
assertFalse(getSpPr(shape).getLn().getHeadEnd().isSetLen());
assertFalse(getSpPr(shape).getLn().getTailEnd().isSetLen());
shape.setLineHeadLength(DecorationSize.LARGE);
shape.setLineTailLength(DecorationSize.MEDIUM);
assertEquals(DecorationSize.LARGE, shape.getLineHeadLength());
assertEquals(DecorationSize.MEDIUM, shape.getLineTailLength());
assertEquals(STLineEndLength.LG, shape.getSpPr().getLn().getHeadEnd().getLen());
assertEquals(STLineEndLength.MED, shape.getSpPr().getLn().getTailEnd().getLen());
assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getHeadEnd().getLen());
assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getTailEnd().getLen());
shape.setLineHeadLength(DecorationSize.MEDIUM);
shape.setLineTailLength(DecorationSize.LARGE);
assertEquals(DecorationSize.MEDIUM, shape.getLineHeadLength());
assertEquals(DecorationSize.LARGE, shape.getLineTailLength());
assertEquals(STLineEndLength.MED, shape.getSpPr().getLn().getHeadEnd().getLen());
assertEquals(STLineEndLength.LG, shape.getSpPr().getLn().getTailEnd().getLen());
assertEquals(STLineEndLength.MED, getSpPr(shape).getLn().getHeadEnd().getLen());
assertEquals(STLineEndLength.LG, getSpPr(shape).getLn().getTailEnd().getLen());
ppt.close();
}
@Test
public void testAddConnector(){
public void testAddConnector() throws IOException {
XMLSlideShow pptx = new XMLSlideShow();
XSLFSlide slide = pptx.createSlide();
@ -152,6 +152,8 @@ public class TestXSLFConnectorShape {
end.setId(rect2.getShapeId());
// side of the rectangle to attach the connector: left=1, bottom=2,right=3, top=4
end.setIdx(3);
pptx.close();
}
}

View File

@ -16,7 +16,9 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
@ -25,9 +27,6 @@ import java.io.IOException;
import org.junit.Test;
/**
* @author Yegor Kozlov
*/
public class TestXSLFFreeformShape {
@Test
@ -49,7 +48,7 @@ public class TestXSLFFreeformShape {
XSLFFreeformShape shape2 = slide.createFreeform();
shape2.setPath(path2);
assertEquals(shape1.getSpPr().getCustGeom().toString(), shape2.getSpPr().getCustGeom().toString());
assertEquals(getSpPr(shape1).getCustGeom().toString(), getSpPr(shape2).getCustGeom().toString());
ppt.close();
}

View File

@ -23,7 +23,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.awt.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
@ -36,6 +39,7 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.Units;
import org.apache.poi.xslf.XSLFTestDataSamples;
import org.apache.xmlbeans.XmlObject;
import org.junit.Test;
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleList;
@ -48,9 +52,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
/**
* @author Yegor Kozlov
*/
public class TestXSLFSimpleShape {
@Test
@ -61,7 +62,7 @@ public class TestXSLFSimpleShape {
XSLFSimpleShape shape = slide.createAutoShape();
assertEquals(1, slide.getShapes().size());
// line properties are not set by default
assertFalse(shape.getSpPr().isSetLn());
assertFalse(getSpPr(shape).isSetLn());
assertEquals(0., shape.getLineWidth(), 0);
assertEquals(null, shape.getLineColor());
@ -73,60 +74,60 @@ public class TestXSLFSimpleShape {
shape.setLineDash(null);
shape.setLineCap(null);
// still no line properties
assertFalse(shape.getSpPr().isSetLn());
assertTrue(getSpPr(shape).isSetLn());
assertTrue(getSpPr(shape).getLn().isSetNoFill());
// line width
shape.setLineWidth(1.0);
assertEquals(1.0, shape.getLineWidth(), 0);
assertEquals(Units.EMU_PER_POINT, shape.getSpPr().getLn().getW());
assertEquals(Units.EMU_PER_POINT, getSpPr(shape).getLn().getW());
shape.setLineWidth(5.5);
assertEquals(5.5, shape.getLineWidth(), 0);
assertEquals(Units.toEMU(5.5), shape.getSpPr().getLn().getW());
assertEquals(Units.toEMU(5.5), getSpPr(shape).getLn().getW());
shape.setLineWidth(0.0);
// setting line width to zero unsets the W attribute
assertFalse(shape.getSpPr().getLn().isSetW());
assertFalse(getSpPr(shape).getLn().isSetW());
// line cap
shape.setLineCap(LineCap.FLAT);
assertEquals(LineCap.FLAT, shape.getLineCap());
assertEquals(STLineCap.FLAT, shape.getSpPr().getLn().getCap());
assertEquals(STLineCap.FLAT, getSpPr(shape).getLn().getCap());
shape.setLineCap(LineCap.SQUARE);
assertEquals(LineCap.SQUARE, shape.getLineCap());
assertEquals(STLineCap.SQ, shape.getSpPr().getLn().getCap());
assertEquals(STLineCap.SQ, getSpPr(shape).getLn().getCap());
shape.setLineCap(LineCap.ROUND);
assertEquals(LineCap.ROUND, shape.getLineCap());
assertEquals(STLineCap.RND, shape.getSpPr().getLn().getCap());
assertEquals(STLineCap.RND, getSpPr(shape).getLn().getCap());
shape.setLineCap(null);
// setting cap to null unsets the Cap attribute
assertFalse(shape.getSpPr().getLn().isSetCap());
assertFalse(getSpPr(shape).getLn().isSetCap());
// line dash
shape.setLineDash(LineDash.SOLID);
assertEquals(LineDash.SOLID, shape.getLineDash());
assertEquals(STPresetLineDashVal.SOLID, shape.getSpPr().getLn().getPrstDash().getVal());
assertEquals(STPresetLineDashVal.SOLID, getSpPr(shape).getLn().getPrstDash().getVal());
shape.setLineDash(LineDash.DASH_DOT);
assertEquals(LineDash.DASH_DOT, shape.getLineDash());
assertEquals(STPresetLineDashVal.DASH_DOT, shape.getSpPr().getLn().getPrstDash().getVal());
assertEquals(STPresetLineDashVal.DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal());
shape.setLineDash(LineDash.LG_DASH_DOT);
assertEquals(LineDash.LG_DASH_DOT, shape.getLineDash());
assertEquals(STPresetLineDashVal.LG_DASH_DOT, shape.getSpPr().getLn().getPrstDash().getVal());
assertEquals(STPresetLineDashVal.LG_DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal());
shape.setLineDash(null);
// setting dash width to null unsets the Dash element
assertFalse(shape.getSpPr().getLn().isSetPrstDash());
assertFalse(getSpPr(shape).getLn().isSetPrstDash());
// line color
assertFalse(shape.getSpPr().getLn().isSetSolidFill());
assertFalse(getSpPr(shape).getLn().isSetSolidFill());
shape.setLineColor(Color.RED);
assertEquals(Color.RED, shape.getLineColor());
assertTrue(shape.getSpPr().getLn().isSetSolidFill());
assertTrue(getSpPr(shape).getLn().isSetSolidFill());
shape.setLineColor(Color.BLUE);
assertEquals(Color.BLUE, shape.getLineColor());
assertTrue(shape.getSpPr().getLn().isSetSolidFill());
assertTrue(getSpPr(shape).getLn().isSetSolidFill());
shape.setLineColor(null);
assertEquals(null, shape.getLineColor());
// setting dash width to null unsets the SolidFill element
assertFalse(shape.getSpPr().getLn().isSetSolidFill());
assertFalse(getSpPr(shape).getLn().isSetSolidFill());
XSLFSimpleShape ln2 = slide.createAutoShape();
ln2.setLineDash(LineDash.DOT);
@ -152,22 +153,22 @@ public class TestXSLFSimpleShape {
XSLFAutoShape shape = slide.createAutoShape();
// line properties are not set by default
assertFalse(shape.getSpPr().isSetSolidFill());
assertFalse(getSpPr(shape).isSetSolidFill());
assertNull(shape.getFillColor());
shape.setFillColor(null);
assertNull(shape.getFillColor());
assertFalse(shape.getSpPr().isSetSolidFill());
assertFalse(getSpPr(shape).isSetSolidFill());
shape.setFillColor(Color.RED);
assertEquals(Color.RED, shape.getFillColor());
shape.setFillColor(Color.DARK_GRAY);
assertEquals(Color.DARK_GRAY, shape.getFillColor());
assertTrue(shape.getSpPr().isSetSolidFill());
assertTrue(getSpPr(shape).isSetSolidFill());
shape.setFillColor(null);
assertNull(shape.getFillColor());
assertFalse(shape.getSpPr().isSetSolidFill());
assertFalse(getSpPr(shape).isSetSolidFill());
ppt.close();
}
@ -188,56 +189,56 @@ public class TestXSLFSimpleShape {
XSLFSimpleShape s0 = (XSLFSimpleShape) shapes.get(0);
// fill is not set
assertNull(s0.getSpPr().getSolidFill());
assertNull(getSpPr(s0).getSolidFill());
//assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor());
assertEquals(new Color(79, 129, 189), s0.getFillColor());
// lighter 80%
XSLFSimpleShape s1 = (XSLFSimpleShape)shapes.get(1);
CTSchemeColor ref1 = s1.getSpPr().getSolidFill().getSchemeClr();
CTSchemeColor ref1 = getSpPr(s1).getSolidFill().getSchemeClr();
assertEquals(1, ref1.sizeOfLumModArray());
assertEquals(1, ref1.sizeOfLumOffArray());
assertEquals(20000, ref1.getLumModArray(0).getVal());
assertEquals(80000, ref1.getLumOffArray(0).getVal());
assertEquals("accent1", ref1.getVal().toString());
assertEquals(new Color(79, 129, 189), s1.getFillColor());
assertEquals(new Color(220, 230, 242), s1.getFillColor());
// lighter 60%
XSLFSimpleShape s2 = (XSLFSimpleShape)shapes.get(2);
CTSchemeColor ref2 = s2.getSpPr().getSolidFill().getSchemeClr();
CTSchemeColor ref2 = getSpPr(s2).getSolidFill().getSchemeClr();
assertEquals(1, ref2.sizeOfLumModArray());
assertEquals(1, ref2.sizeOfLumOffArray());
assertEquals(40000, ref2.getLumModArray(0).getVal());
assertEquals(60000, ref2.getLumOffArray(0).getVal());
assertEquals("accent1", ref2.getVal().toString());
assertEquals(new Color(79, 129, 189), s2.getFillColor());
assertEquals(new Color(185, 205, 229), s2.getFillColor());
// lighter 40%
XSLFSimpleShape s3 = (XSLFSimpleShape)shapes.get(3);
CTSchemeColor ref3 = s3.getSpPr().getSolidFill().getSchemeClr();
CTSchemeColor ref3 = getSpPr(s3).getSolidFill().getSchemeClr();
assertEquals(1, ref3.sizeOfLumModArray());
assertEquals(1, ref3.sizeOfLumOffArray());
assertEquals(60000, ref3.getLumModArray(0).getVal());
assertEquals(40000, ref3.getLumOffArray(0).getVal());
assertEquals("accent1", ref3.getVal().toString());
assertEquals(new Color(79, 129, 189), s3.getFillColor());
assertEquals(new Color(149, 179, 215), s3.getFillColor());
// darker 25%
XSLFSimpleShape s4 = (XSLFSimpleShape)shapes.get(4);
CTSchemeColor ref4 = s4.getSpPr().getSolidFill().getSchemeClr();
CTSchemeColor ref4 = getSpPr(s4).getSolidFill().getSchemeClr();
assertEquals(1, ref4.sizeOfLumModArray());
assertEquals(0, ref4.sizeOfLumOffArray());
assertEquals(75000, ref4.getLumModArray(0).getVal());
assertEquals("accent1", ref3.getVal().toString());
assertEquals(new Color(79, 129, 189), s4.getFillColor());
assertEquals(new Color(55, 96, 146), s4.getFillColor());
XSLFSimpleShape s5 = (XSLFSimpleShape)shapes.get(5);
CTSchemeColor ref5 = s5.getSpPr().getSolidFill().getSchemeClr();
CTSchemeColor ref5 = getSpPr(s5).getSolidFill().getSchemeClr();
assertEquals(1, ref5.sizeOfLumModArray());
assertEquals(0, ref5.sizeOfLumOffArray());
assertEquals(50000, ref5.getLumModArray(0).getVal());
assertEquals("accent1", ref5.getVal().toString());
assertEquals(new Color(79, 129, 189), s5.getFillColor());
assertEquals(new Color(37, 64, 97), s5.getFillColor());
ppt.close();
}
@ -253,13 +254,13 @@ public class TestXSLFSimpleShape {
XSLFTextShape sh1 = (XSLFTextShape)shapes2.get(0);
assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType());
assertEquals("PPTX Title", sh1.getText());
assertNull(sh1.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout
assertFalse(getSpPr(sh1).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout
assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor());
XSLFTextShape sh2 = (XSLFTextShape)shapes2.get(1);
assertEquals("Subtitle\nAnd second line", sh2.getText());
assertEquals(Placeholder.SUBTITLE, sh2.getTextType());
assertNull(sh2.getSpPr().getXfrm()); // xfrm is not set, the query is delegated to the slide layout
assertFalse(getSpPr(sh2).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout
assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor());
XSLFSlide slide5 = slide.get(4);
@ -267,16 +268,16 @@ public class TestXSLFSimpleShape {
XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE);
assertEquals("Hyperlinks", shTitle.getText());
// xfrm is not set, the query is delegated to the slide layout
assertNull(shTitle.getSpPr().getXfrm());
assertFalse(getSpPr(shTitle).isSetXfrm());
// xfrm is not set, the query is delegated to the slide master
assertNull(layout5.getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm());
assertNotNull(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getSpPr().getXfrm());
assertFalse(getSpPr(layout5.getTextShapeByType(Placeholder.TITLE)).isSetXfrm());
assertTrue(getSpPr(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE)).isSetXfrm());
assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor());
ppt.close();
}
@SuppressWarnings({ "deprecation", "unused" })
@SuppressWarnings("unused")
@Test
public void testShadowEffects() throws IOException{
XMLSlideShow ppt = new XMLSlideShow();
@ -296,7 +297,7 @@ public class TestXSLFSimpleShape {
XSLFSlide slide = ppt.createSlide();
XSLFSimpleShape shape = slide.createAutoShape();
CTShapeProperties spPr = shape.getSpPr();
CTShapeProperties spPr = getSpPr(shape);
CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance();
prstGeom.setPrst(STShapeType.Enum.forInt(1));
@ -320,7 +321,7 @@ public class TestXSLFSimpleShape {
XSLFSlide slide = ppt.createSlide();
XSLFSimpleShape shape = slide.createAutoShape();
CTShapeProperties spPr = shape.getSpPr();
CTShapeProperties spPr = getSpPr(shape);
CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance();
prstGeom.setPrst(STShapeType.Enum.forInt(1));
@ -376,4 +377,10 @@ public class TestXSLFSimpleShape {
}
ppt.close();
}
static CTShapeProperties getSpPr(XSLFShape shape) {
XmlObject xo = shape.getShapeProperties();
assertTrue(xo instanceof CTShapeProperties);
return (CTShapeProperties)xo;
}
}

View File

@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.apache.poi.xslf.usermodel.TestXSLFSimpleShape.getSpPr;
import java.awt.Color;
import java.io.File;
@ -73,10 +74,10 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.CTR_TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
assertNotNull(masterShape1.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape1).getXfrm());
assertEquals(masterShape1.getAnchor(), shape1.getAnchor());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
@ -103,10 +104,10 @@ public class TestXSLFTextShape {
CTPlaceholder ph2 = shape2.getCTPlaceholder();
assertEquals(STPlaceholderType.SUB_TITLE, ph2.getType());
// anchor is not defined in the shape
assertNull(shape2.getSpPr().getXfrm());
assertNull(getSpPr(shape2).getXfrm());
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
assertNotNull(masterShape2.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape2).getXfrm());
assertEquals(masterShape2.getAnchor(), shape2.getAnchor());
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
@ -139,13 +140,13 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
// layout does not have anchor info either, it is in the slide master
assertNull(masterShape1.getSpPr().getXfrm());
assertNull(getSpPr(masterShape1).getXfrm());
masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1);
assertNotNull(masterShape1.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape1).getXfrm());
assertEquals(masterShape1.getAnchor(), shape1.getAnchor());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
@ -174,13 +175,13 @@ public class TestXSLFTextShape {
assertTrue(ph2.isSetIdx());
assertEquals(1, ph2.getIdx());
// anchor is not defined in the shape
assertNull(shape2.getSpPr().getXfrm());
assertNull(getSpPr(shape2).getXfrm());
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
// anchor of the body text is missing in the slide layout, llokup in the slide master
assertNull(masterShape2.getSpPr().getXfrm());
assertNull(getSpPr(masterShape2).getXfrm());
masterShape2 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph2);
assertNotNull(masterShape2.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape2).getXfrm());
assertEquals(masterShape2.getAnchor(), shape2.getAnchor());
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
@ -252,10 +253,10 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
assertNotNull(masterShape1.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape1).getXfrm());
assertEquals(masterShape1.getAnchor(), shape1.getAnchor());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
@ -286,10 +287,10 @@ public class TestXSLFTextShape {
CTPlaceholder ph2 = shape2.getCTPlaceholder();
assertEquals(STPlaceholderType.BODY, ph2.getType());
// anchor is not defined in the shape
assertNull(shape2.getSpPr().getXfrm());
assertNull(getSpPr(shape2).getXfrm());
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
assertNotNull(masterShape2.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape2).getXfrm());
assertEquals(masterShape2.getAnchor(), shape2.getAnchor());
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
@ -323,13 +324,13 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
// layout does not have anchor info either, it is in the slide master
assertNull(masterShape1.getSpPr().getXfrm());
assertNull(getSpPr(masterShape1).getXfrm());
masterShape1 = (XSLFTextShape)layout.getSlideMaster().getPlaceholder(ph1);
assertNotNull(masterShape1.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape1).getXfrm());
assertEquals(masterShape1.getAnchor(), shape1.getAnchor());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
@ -359,10 +360,10 @@ public class TestXSLFTextShape {
assertTrue(ph2.isSetIdx());
assertEquals(1, ph2.getIdx()); //<p:ph sz="half" idx="1"/>
// anchor is not defined in the shape
assertNull(shape2.getSpPr().getXfrm());
assertNull(getSpPr(shape2).getXfrm());
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
assertNotNull(masterShape2.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape2).getXfrm());
assertEquals(masterShape2.getAnchor(), shape2.getAnchor());
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();
@ -438,7 +439,7 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
// none of the following properties are set in the shapes and fetched from the master shape
@ -506,11 +507,11 @@ public class TestXSLFTextShape {
CTPlaceholder ph1 = shape1.getCTPlaceholder();
assertEquals(STPlaceholderType.TITLE, ph1.getType());
// anchor is not defined in the shape
assertNull(shape1.getSpPr().getXfrm());
assertNull(getSpPr(shape1).getXfrm());
XSLFTextShape masterShape1 = (XSLFTextShape)layout.getPlaceholder(ph1);
// layout does not have anchor info either, it is in the slide master
assertNotNull(masterShape1.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape1).getXfrm());
assertEquals(masterShape1.getAnchor(), shape1.getAnchor());
CTTextBodyProperties bodyPr1 = shape1.getTextBodyPr();
@ -541,10 +542,10 @@ public class TestXSLFTextShape {
assertTrue(ph2.isSetIdx());
assertEquals(1, ph2.getIdx());
// anchor is not defined in the shape
assertNull(shape2.getSpPr().getXfrm());
assertNull(getSpPr(shape2).getXfrm());
XSLFTextShape masterShape2 = (XSLFTextShape)layout.getPlaceholder(ph2);
assertNotNull(masterShape2.getSpPr().getXfrm());
assertNotNull(getSpPr(masterShape2).getXfrm());
assertEquals(masterShape2.getAnchor(), shape2.getAnchor());
CTTextBodyProperties bodyPr2 = shape2.getTextBodyPr();