2011-08-11 04:38:19 -04:00
|
|
|
/*
|
|
|
|
* ====================================================================
|
|
|
|
* 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.xslf.usermodel;
|
|
|
|
|
2016-02-29 18:59:49 -05:00
|
|
|
import java.awt.Graphics2D;
|
|
|
|
import java.awt.geom.Rectangle2D;
|
2015-02-21 05:56:03 -05:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Comparator;
|
2011-08-11 04:38:19 -04:00
|
|
|
|
2015-02-21 05:56:03 -05:00
|
|
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
|
|
|
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
2016-02-29 18:59:49 -05:00
|
|
|
import org.apache.poi.sl.draw.DrawFactory;
|
2015-08-09 18:44:13 -04:00
|
|
|
import org.apache.poi.sl.draw.DrawPaint;
|
2015-07-24 17:47:55 -04:00
|
|
|
import org.apache.poi.sl.usermodel.ColorStyle;
|
|
|
|
import org.apache.poi.sl.usermodel.PaintStyle;
|
2015-03-07 18:35:40 -05:00
|
|
|
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
|
|
|
|
import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
|
2015-07-24 17:47:55 -04:00
|
|
|
import org.apache.poi.sl.usermodel.PlaceableShape;
|
2015-12-31 17:10:17 -05:00
|
|
|
import org.apache.poi.sl.usermodel.Placeholder;
|
2015-07-24 17:47:55 -04:00
|
|
|
import org.apache.poi.sl.usermodel.Shape;
|
2013-12-12 00:29:11 -05:00
|
|
|
import org.apache.poi.util.Beta;
|
|
|
|
import org.apache.poi.util.Internal;
|
2015-02-21 05:56:03 -05:00
|
|
|
import org.apache.poi.xslf.model.PropertyFetcher;
|
2016-06-18 19:48:00 -04:00
|
|
|
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
|
|
|
|
import org.apache.xmlbeans.XmlCursor;
|
2013-12-12 00:29:11 -05:00
|
|
|
import org.apache.xmlbeans.XmlObject;
|
2015-08-09 18:44:13 -04:00
|
|
|
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.CTNonVisualDrawingProps;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
|
|
|
|
import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
|
2015-07-24 17:47:55 -04:00
|
|
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTApplicationNonVisualDrawingProps;
|
|
|
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
|
|
|
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
|
|
|
|
import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
|
|
|
|
import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
|
2013-12-12 00:29:11 -05:00
|
|
|
|
2011-08-11 04:38:19 -04:00
|
|
|
/**
|
2011-11-07 04:12:16 -05:00
|
|
|
* Base super-class class for all shapes in PresentationML
|
2011-08-11 04:38:19 -04:00
|
|
|
*/
|
|
|
|
@Beta
|
2015-08-24 19:15:14 -04:00
|
|
|
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
|
2016-06-18 19:48:00 -04:00
|
|
|
protected static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
private final XmlObject _shape;
|
|
|
|
private final XSLFSheet _sheet;
|
|
|
|
private XSLFShapeContainer _parent;
|
2011-08-11 04:38:19 -04:00
|
|
|
|
2015-02-21 05:56:03 -05:00
|
|
|
private CTShapeStyle _spStyle;
|
|
|
|
private CTNonVisualDrawingProps _nvPr;
|
|
|
|
private CTPlaceholder _ph;
|
2011-08-11 04:38:19 -04:00
|
|
|
|
2015-02-21 05:56:03 -05:00
|
|
|
protected XSLFShape(XmlObject shape, XSLFSheet sheet) {
|
|
|
|
_shape = shape;
|
|
|
|
_sheet = sheet;
|
|
|
|
}
|
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
|
|
|
* @return the xml bean holding this shape's data
|
|
|
|
*/
|
2015-03-07 18:35:40 -05:00
|
|
|
public final XmlObject getXmlObject() {
|
|
|
|
// it's final because the xslf inheritance hierarchy is not necessary the same as
|
|
|
|
// the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value
|
2015-02-21 05:56:03 -05:00
|
|
|
return _shape;
|
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public XSLFSheet getSheet() {
|
|
|
|
return _sheet;
|
|
|
|
}
|
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
|
|
|
* @return human-readable name of this shape, e.g. "Rectange 3"
|
|
|
|
*/
|
2015-03-07 18:35:40 -05:00
|
|
|
public String getShapeName(){
|
|
|
|
return getCNvPr().getName();
|
|
|
|
}
|
2011-08-11 04:38:19 -04:00
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
|
|
|
* Returns a unique identifier for this shape within the current document.
|
|
|
|
* This ID may be used to assist in uniquely identifying this object so that it can
|
|
|
|
* be referred to by other parts of the document.
|
|
|
|
* <p>
|
2011-11-10 08:59:16 -05:00
|
|
|
* If multiple objects within the same document share the same id attribute value,
|
|
|
|
* then the document shall be considered non-conformant.
|
2011-11-07 04:12:16 -05:00
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @return unique id of this shape
|
|
|
|
*/
|
2015-03-07 18:35:40 -05:00
|
|
|
public int getShapeId() {
|
|
|
|
return (int)getCNvPr().getId();
|
|
|
|
}
|
2011-10-21 09:17:33 -04:00
|
|
|
|
|
|
|
/**
|
2015-02-21 05:56:03 -05:00
|
|
|
* Set the contents of this shape to be a copy of the source shape.
|
|
|
|
* This method is called recursively for each shape when merging slides
|
2011-10-21 09:17:33 -04:00
|
|
|
*
|
2015-02-21 05:56:03 -05:00
|
|
|
* @param sh the source shape
|
|
|
|
* @see org.apache.poi.xslf.usermodel.XSLFSlide#importContent(XSLFSheet)
|
2011-10-21 09:17:33 -04:00
|
|
|
*/
|
2015-02-21 05:56:03 -05:00
|
|
|
@Internal
|
|
|
|
void copy(XSLFShape sh) {
|
|
|
|
if (!getClass().isInstance(sh)) {
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
"Can't copy " + sh.getClass().getSimpleName() + " into " + getClass().getSimpleName());
|
|
|
|
}
|
2011-11-10 08:59:16 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
if (this instanceof PlaceableShape) {
|
2015-08-24 19:15:14 -04:00
|
|
|
PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this;
|
|
|
|
ps.setAnchor(((PlaceableShape<?,?>)sh).getAnchor());
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setParent(XSLFShapeContainer parent) {
|
|
|
|
this._parent = parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
public XSLFShapeContainer getParent() {
|
|
|
|
return this._parent;
|
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
protected PaintStyle getFillPaint() {
|
2016-06-04 18:53:00 -04:00
|
|
|
final XSLFTheme theme = getSheet().getTheme();
|
2015-03-07 18:35:40 -05:00
|
|
|
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
|
|
|
|
public boolean fetch(XSLFShape shape) {
|
2016-06-18 19:48:00 -04:00
|
|
|
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
|
|
|
|
if (fp == null) {
|
|
|
|
return false;
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
2016-06-18 19:48:00 -04:00
|
|
|
|
|
|
|
if (fp.isSetNoFill()) {
|
|
|
|
setValue(null);
|
|
|
|
return true;
|
2015-07-14 20:30:21 -04:00
|
|
|
}
|
|
|
|
|
2016-06-18 19:48:00 -04:00
|
|
|
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;
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
2016-06-18 19:48:00 -04:00
|
|
|
|
2015-08-09 18:44:13 -04:00
|
|
|
return false;
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
fetchShapeProperty(fetcher);
|
2011-10-21 09:17:33 -04:00
|
|
|
|
2016-06-18 19:48:00 -04:00
|
|
|
return fetcher.getValue();
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
protected CTBackgroundProperties getBgPr() {
|
2016-06-18 19:48:00 -04:00
|
|
|
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
protected CTStyleMatrixReference getBgRef() {
|
2016-06-18 19:48:00 -04:00
|
|
|
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
protected CTGroupShapeProperties getGrpSpPr() {
|
2016-06-18 19:48:00 -04:00
|
|
|
return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
protected CTNonVisualDrawingProps getCNvPr() {
|
|
|
|
if (_nvPr == null) {
|
|
|
|
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";
|
|
|
|
_nvPr = selectProperty(CTNonVisualDrawingProps.class, xquery);
|
|
|
|
}
|
|
|
|
return _nvPr;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
protected CTShapeStyle getSpStyle() {
|
|
|
|
if (_spStyle == null) {
|
2016-06-18 19:48:00 -04:00
|
|
|
_spStyle = getChild(CTShapeStyle.class, PML_NS, "style");
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
return _spStyle;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
|
|
|
|
2016-06-18 19:48:00 -04:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
protected CTPlaceholder getCTPlaceholder() {
|
|
|
|
if (_ph == null) {
|
2016-06-18 19:48:00 -04:00
|
|
|
String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr/p:ph";
|
2015-03-07 18:35:40 -05:00
|
|
|
_ph = selectProperty(CTPlaceholder.class, xquery);
|
|
|
|
}
|
|
|
|
return _ph;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2011-11-10 08:59:16 -05:00
|
|
|
|
2015-12-31 17:10:17 -05:00
|
|
|
public Placeholder getPlaceholder() {
|
|
|
|
CTPlaceholder ph = getCTPlaceholder();
|
2016-01-15 19:11:01 -05:00
|
|
|
if (ph == null || !(ph.isSetType() || ph.isSetIdx())) {
|
2015-12-31 17:10:17 -05:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return Placeholder.lookupOoxml(ph.getType().intValue());
|
|
|
|
}
|
|
|
|
|
2011-10-21 09:17:33 -04:00
|
|
|
/**
|
2015-07-14 20:30:21 -04:00
|
|
|
* Specifies that the corresponding shape should be represented by the generating application
|
|
|
|
* as a placeholder. When a shape is considered a placeholder by the generating application
|
|
|
|
* it can have special properties to alert the user that they may enter content into the shape.
|
|
|
|
* Different types of placeholders are allowed and can be specified by using the placeholder
|
|
|
|
* type attribute for this element
|
2011-10-21 09:17:33 -04:00
|
|
|
*
|
2015-07-14 20:30:21 -04:00
|
|
|
* @param placeholder
|
2011-10-21 09:17:33 -04:00
|
|
|
*/
|
2015-07-14 20:30:21 -04:00
|
|
|
protected void setPlaceholder(Placeholder placeholder) {
|
2016-06-18 19:48:00 -04:00
|
|
|
String xquery = "declare namespace p='"+PML_NS+"' .//*/p:nvPr";
|
2015-07-14 20:30:21 -04:00
|
|
|
CTApplicationNonVisualDrawingProps nv = selectProperty(CTApplicationNonVisualDrawingProps.class, xquery);
|
|
|
|
if (nv == null) return;
|
|
|
|
if(placeholder == null) {
|
|
|
|
if (nv.isSetPh()) nv.unsetPh();
|
|
|
|
_ph = null;
|
|
|
|
} else {
|
2015-12-31 17:10:17 -05:00
|
|
|
nv.addNewPh().setType(STPlaceholderType.Enum.forInt(placeholder.ooxmlId));
|
2015-07-14 20:30:21 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
2015-03-07 18:35:40 -05:00
|
|
|
* As there's no xmlbeans hierarchy, but XSLF works with subclassing, not all
|
|
|
|
* child classes work with a {@link CTShape} object, but often contain the same
|
|
|
|
* properties. This method is the generalized form of selecting and casting those
|
|
|
|
* properties.
|
2011-11-07 04:12:16 -05:00
|
|
|
*
|
2015-07-25 20:25:27 -04:00
|
|
|
* @param resultClass the requested result class
|
|
|
|
* @param xquery the simple (xmlbean) xpath expression to the property
|
|
|
|
* @return the xml object at the xpath location, or null if not found
|
2011-11-07 04:12:16 -05:00
|
|
|
*/
|
2015-03-07 18:35:40 -05:00
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
|
|
|
|
XmlObject[] rs = getXmlObject().selectPath(xquery);
|
|
|
|
if (rs.length == 0) return null;
|
|
|
|
return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2011-10-21 09:17:33 -04:00
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
2015-02-21 05:56:03 -05:00
|
|
|
* Walk up the inheritance tree and fetch shape properties.
|
|
|
|
*
|
|
|
|
* The following order of inheritance is assumed:
|
|
|
|
* <p>
|
|
|
|
* slide <-- slideLayout <-- slideMaster
|
|
|
|
* </p>
|
2011-11-07 04:12:16 -05:00
|
|
|
*
|
2015-02-21 05:56:03 -05:00
|
|
|
* @param visitor the object that collects the desired property
|
|
|
|
* @return true if the property was fetched
|
2011-11-07 04:12:16 -05:00
|
|
|
*/
|
2015-02-21 05:56:03 -05:00
|
|
|
protected boolean fetchShapeProperty(PropertyFetcher<?> visitor) {
|
|
|
|
boolean ok = visitor.fetch(this);
|
|
|
|
|
|
|
|
XSLFSimpleShape masterShape;
|
|
|
|
XSLFSheet masterSheet = (XSLFSheet)getSheet().getMasterSheet();
|
|
|
|
CTPlaceholder ph = getCTPlaceholder();
|
|
|
|
|
|
|
|
if (masterSheet != null && ph != null) {
|
|
|
|
if (!ok) {
|
|
|
|
masterShape = masterSheet.getPlaceholder(ph);
|
|
|
|
if (masterShape != null) {
|
|
|
|
ok = visitor.fetch(masterShape);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// try slide master
|
|
|
|
if (!ok ) {
|
|
|
|
int textType;
|
|
|
|
if ( !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
|
|
|
|
else {
|
|
|
|
switch (ph.getType().intValue()) {
|
|
|
|
case STPlaceholderType.INT_TITLE:
|
|
|
|
case STPlaceholderType.INT_CTR_TITLE:
|
|
|
|
textType = STPlaceholderType.INT_TITLE;
|
|
|
|
break;
|
|
|
|
case STPlaceholderType.INT_FTR:
|
|
|
|
case STPlaceholderType.INT_SLD_NUM:
|
|
|
|
case STPlaceholderType.INT_DT:
|
|
|
|
textType = ph.getType().intValue();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
textType = STPlaceholderType.INT_BODY;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XSLFSheet master = (XSLFSheet)masterSheet.getMasterSheet();
|
|
|
|
if (master != null) {
|
|
|
|
masterShape = master.getPlaceholderByType(textType);
|
|
|
|
if (masterShape != null) {
|
|
|
|
ok = visitor.fetch(masterShape);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
2011-10-21 09:17:33 -04:00
|
|
|
|
2011-11-07 04:12:16 -05:00
|
|
|
/**
|
2015-02-21 05:56:03 -05:00
|
|
|
* Convert shape fill into java.awt.Paint. The result is either Color or
|
|
|
|
* TexturePaint or GradientPaint or null
|
2011-11-10 08:59:16 -05:00
|
|
|
*
|
2016-06-18 19:48:00 -04:00
|
|
|
* @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
|
2015-02-21 05:56:03 -05:00
|
|
|
*
|
|
|
|
* @return the applied Paint or null if none was applied
|
2011-11-07 04:12:16 -05:00
|
|
|
*/
|
2016-06-18 19:48:00 -04:00
|
|
|
protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme) {
|
|
|
|
if (fp == null || fp.isSetNoFill()) {
|
2015-08-09 18:44:13 -04:00
|
|
|
return null;
|
2016-06-18 19:48:00 -04:00
|
|
|
} 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());
|
2015-03-07 18:35:40 -05:00
|
|
|
} else {
|
|
|
|
return null;
|
2011-12-04 06:16:57 -05:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
2011-10-21 09:17:33 -04:00
|
|
|
|
2016-06-04 18:53:00 -04:00
|
|
|
protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
|
2015-08-09 18:44:13 -04:00
|
|
|
if (phClr == null && solidFill.isSetSchemeClr()) {
|
|
|
|
phClr = solidFill.getSchemeClr();
|
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
final XSLFColor c = new XSLFColor(solidFill, theme, phClr);
|
2015-08-09 18:44:13 -04:00
|
|
|
return DrawPaint.createSolidPaint(c.getColorStyle());
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
2016-06-04 18:53:00 -04:00
|
|
|
protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
|
2015-03-07 18:35:40 -05:00
|
|
|
final CTBlip blip = blipFill.getBlip();
|
|
|
|
return new TexturePaint() {
|
|
|
|
private PackagePart getPart() {
|
|
|
|
try {
|
|
|
|
String blipId = blip.getEmbed();
|
|
|
|
PackageRelationship rel = parentPart.getRelationship(blipId);
|
|
|
|
return parentPart.getRelatedPart(rel);
|
|
|
|
} catch (InvalidFormatException e) {
|
|
|
|
throw new RuntimeException(e);
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public InputStream getImageData() {
|
|
|
|
try {
|
|
|
|
return getPart().getInputStream();
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new RuntimeException(e);
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2013-11-09 06:32:55 -05:00
|
|
|
}
|
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public String getContentType() {
|
|
|
|
/* TOOD: map content-type */
|
|
|
|
return getPart().getContentType();
|
|
|
|
}
|
2011-10-21 09:17:33 -04:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public int getAlpha() {
|
|
|
|
return (blip.sizeOfAlphaModFixArray() > 0)
|
|
|
|
? blip.getAlphaModFixArray(0).getAmt()
|
2015-08-09 18:44:13 -04:00
|
|
|
: 100000;
|
2015-03-07 18:35:40 -05:00
|
|
|
}
|
|
|
|
};
|
2011-10-21 09:17:33 -04:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
|
2016-06-04 18:53:00 -04:00
|
|
|
protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
|
2011-11-07 04:12:16 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
Arrays.sort(gs, new Comparator<CTGradientStop>() {
|
|
|
|
public int compare(CTGradientStop o1, CTGradientStop o2) {
|
|
|
|
Integer pos1 = o1.getPos();
|
|
|
|
Integer pos2 = o2.getPos();
|
|
|
|
return pos1.compareTo(pos2);
|
|
|
|
}
|
|
|
|
});
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
final ColorStyle cs[] = new ColorStyle[gs.length];
|
|
|
|
final float fractions[] = new float[gs.length];
|
|
|
|
|
|
|
|
int i=0;
|
|
|
|
for (CTGradientStop cgs : gs) {
|
2015-08-09 18:44:13 -04:00
|
|
|
CTSchemeColor phClrCgs = phClr;
|
|
|
|
if (phClrCgs == null && cgs.isSetSchemeClr()) {
|
|
|
|
phClrCgs = cgs.getSchemeClr();
|
|
|
|
}
|
|
|
|
cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle();
|
2015-03-07 18:35:40 -05:00
|
|
|
fractions[i] = cgs.getPos() / 100000.f;
|
2015-07-11 20:38:39 -04:00
|
|
|
i++;
|
2011-11-10 08:59:16 -05:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
|
|
|
|
return new GradientPaint() {
|
|
|
|
|
|
|
|
public double getGradientAngle() {
|
|
|
|
return (gradFill.isSetLin())
|
|
|
|
? gradFill.getLin().getAng() / 60000.d
|
|
|
|
: 0;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2011-11-10 08:59:16 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public ColorStyle[] getGradientColors() {
|
|
|
|
return cs;
|
|
|
|
}
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public float[] getGradientFractions() {
|
|
|
|
return fractions;
|
|
|
|
}
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public boolean isRotatedWithShape() {
|
|
|
|
// TODO: is this correct???
|
|
|
|
return (gradFill.isSetRotWithShape() || !gradFill.getRotWithShape());
|
|
|
|
}
|
2015-02-21 05:56:03 -05:00
|
|
|
|
2015-03-07 18:35:40 -05:00
|
|
|
public GradientType getGradientType() {
|
|
|
|
if (gradFill.isSetLin()) {
|
|
|
|
return GradientType.linear;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
|
|
|
|
if (gradFill.isSetPath()) {
|
|
|
|
/* TODO: handle rect path */
|
|
|
|
STPathShadeType.Enum ps = gradFill.getPath().getPath();
|
|
|
|
if (ps == STPathShadeType.CIRCLE) {
|
|
|
|
return GradientType.circular;
|
|
|
|
} else if (ps == STPathShadeType.SHAPE) {
|
|
|
|
return GradientType.shape;
|
2015-02-21 05:56:03 -05:00
|
|
|
}
|
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
|
|
|
|
return GradientType.linear;
|
|
|
|
}
|
|
|
|
};
|
2011-11-10 08:59:16 -05:00
|
|
|
}
|
2015-03-07 18:35:40 -05:00
|
|
|
|
2016-06-18 19:48:00 -04:00
|
|
|
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle) {
|
2015-07-14 20:30:21 -04:00
|
|
|
if (fillRef == null) return null;
|
|
|
|
|
|
|
|
// The idx attribute refers to the index of a fill style or
|
|
|
|
// background fill style within the presentation's style matrix, defined by the fmtScheme element.
|
|
|
|
// value of 0 or 1000 indicates no background,
|
|
|
|
// values 1-999 refer to the index of a fill style within the fillStyleLst element
|
|
|
|
// 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();
|
|
|
|
CTStyleMatrix matrix = theme.getXmlObject().getThemeElements().getFmtScheme();
|
2016-06-18 19:48:00 -04:00
|
|
|
XmlObject styleLst = null;
|
|
|
|
int childIdx;
|
2015-07-14 20:30:21 -04:00
|
|
|
if (idx >= 1 && idx <= 999) {
|
2016-06-18 19:48:00 -04:00
|
|
|
childIdx = idx-1;
|
|
|
|
styleLst = (isLineStyle) ? matrix.getLnStyleLst() : matrix.getFillStyleLst();
|
2015-07-14 20:30:21 -04:00
|
|
|
} else if (idx >= 1001 ){
|
2016-06-18 19:48:00 -04:00
|
|
|
childIdx = idx - 1001;
|
|
|
|
styleLst = matrix.getBgFillStyleLst();
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
XmlCursor cur = styleLst.newCursor();
|
|
|
|
XSLFFillProperties fp = null;
|
|
|
|
if (cur.toChild(childIdx)) {
|
|
|
|
fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
|
2015-07-14 20:30:21 -04:00
|
|
|
}
|
2016-06-18 19:48:00 -04:00
|
|
|
cur.dispose();
|
|
|
|
|
|
|
|
return selectPaint(fp, phClr, theme.getPackagePart(), theme);
|
2011-11-10 08:59:16 -05:00
|
|
|
}
|
2016-02-29 18:59:49 -05:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void draw(Graphics2D graphics, Rectangle2D bounds) {
|
|
|
|
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
|
|
|
|
}
|
2016-06-18 19:48:00 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the shape specific (visual) properties
|
|
|
|
*
|
|
|
|
* @return the shape specific properties
|
|
|
|
*/
|
|
|
|
protected XmlObject getShapeProperties() {
|
|
|
|
return getChild(CTShapeProperties.class, PML_NS, "spPr");
|
|
|
|
}
|
2011-08-11 04:38:19 -04:00
|
|
|
}
|