12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148 |
- /*
- * ====================================================================
- * 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;
-
- import java.awt.Color;
- import java.awt.geom.Rectangle2D;
-
- 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;
- import org.apache.poi.sl.usermodel.FillStyle;
- import org.apache.poi.sl.usermodel.LineDecoration;
- import org.apache.poi.sl.usermodel.LineDecoration.DecorationShape;
- import org.apache.poi.sl.usermodel.LineDecoration.DecorationSize;
- import org.apache.poi.sl.usermodel.PaintStyle;
- import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
- import org.apache.poi.sl.usermodel.ShapeType;
- import org.apache.poi.sl.usermodel.SimpleShape;
- import org.apache.poi.sl.usermodel.StrokeStyle;
- 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;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
- 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.CTTransform2D;
- import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
- import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
- import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
- import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
- import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
- import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
- import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
-
- /**
- * Represents a single (non-group) shape in a .pptx slide show
- */
- @Beta
- 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);
- }
-
- @Override
- public void setShapeType(ShapeType type) {
- 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(){
- 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 getXfrm(boolean create) {
- PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- XmlObject xo = shape.getShapeProperties();
- if (xo instanceof CTShapeProperties && ((CTShapeProperties)xo).isSetXfrm()) {
- setValue(((CTShapeProperties)xo).getXfrm());
- return true;
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- 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() +" doesn't have xfrm element.");
- return null;
- }
- }
- }
-
- @Override
- public Rectangle2D getAnchor() {
-
- CTTransform2D xfrm = getXfrm(false);
- if (xfrm == null || !xfrm.isSetOff()) {
- return null;
- }
-
- CTPoint2D off = xfrm.getOff();
- double x = Units.toPoints(off.getX());
- double y = Units.toPoints(off.getY());
- CTPositiveSize2D ext = xfrm.getExt();
- double cx = Units.toPoints(ext.getCx());
- double cy = Units.toPoints(ext.getCy());
- return new Rectangle2D.Double(x, y, cx, cy);
- }
-
- @Override
- public void setAnchor(Rectangle2D anchor) {
- 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());
- off.setX(x);
- off.setY(y);
- CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm
- .addNewExt();
- long cx = Units.toEMU(anchor.getWidth());
- long cy = Units.toEMU(anchor.getHeight());
- ext.setCx(cx);
- ext.setCy(cy);
- }
-
- @Override
- public void setRotation(double theta) {
- CTTransform2D xfrm = getXfrm(true);
- if (xfrm != null) {
- xfrm.setRot((int) (theta * 60000));
- }
- }
-
- @Override
- public double getRotation() {
- CTTransform2D xfrm = getXfrm(false);
- return (xfrm == null || !xfrm.isSetRot()) ? 0 : (xfrm.getRot() / 60000.d);
- }
-
- @Override
- public void setFlipHorizontal(boolean flip) {
- CTTransform2D xfrm = getXfrm(true);
- if (xfrm != null) {
- xfrm.setFlipH(flip);
- }
- }
-
- @Override
- public void setFlipVertical(boolean flip) {
- CTTransform2D xfrm = getXfrm(true);
- if (xfrm != null) {
- xfrm.setFlipV(flip);
- }
- }
-
- @Override
- public boolean getFlipHorizontal() {
- CTTransform2D xfrm = getXfrm(false);
- return (xfrm != null && xfrm.isSetFlipH()) && xfrm.getFlipH();
- }
-
- @Override
- public boolean getFlipVertical() {
- CTTransform2D xfrm = getXfrm(false);
- return (xfrm != null && xfrm.isSetFlipV()) && xfrm.getFlipV();
- }
-
-
- /**
- * Get default line properties defined in the theme (if any).
- * Used internally to resolve shape properties.
- *
- * @return line properties from the theme of null
- */
- private CTLineProperties getDefaultLineProperties() {
- CTShapeStyle style = getSpStyle();
- if (style == null) {
- return null;
- }
- CTStyleMatrixReference lnRef = style.getLnRef();
- if (lnRef == null) {
- return null;
- }
- // 1-based index of a line style within the style matrix
- int idx = (int)lnRef.getIdx();
-
- XSLFTheme theme = getSheet().getTheme();
- if (theme == null) {
- return null;
- }
- CTBaseStyles styles = theme.getXmlObject().getThemeElements();
- if (styles == null) {
- return null;
- }
- CTStyleMatrix styleMatrix = styles.getFmtScheme();
- if (styleMatrix == null) {
- return null;
- }
- CTLineStyleList lineStyles = styleMatrix.getLnStyleLst();
- if (lineStyles == null || lineStyles.sizeOfLnArray() < idx) {
- return null;
- }
-
- return lineStyles.getLnArray(idx - 1);
- }
-
- /**
- * @param color the color to paint the shape outline.
- * A <code>null</code> value turns off the shape outline.
- */
- public void setLineColor(Color color) {
- 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);
- }
- }
-
- /**
- *
- * @return the color of the shape outline or <code>null</code>
- * if outline is turned off
- */
- @SuppressWarnings("WeakerAccess")
- public Color getLineColor() {
- PaintStyle ps = getLinePaint();
- if (ps instanceof SolidPaint) {
- return ((SolidPaint)ps).getSolidColor().getColor();
- }
- return null;
- }
-
- @SuppressWarnings("WeakerAccess")
- protected PaintStyle getLinePaint() {
- XSLFSheet sheet = getSheet();
- final XSLFTheme theme = sheet.getTheme();
- final boolean hasPlaceholder = getPlaceholder() != null;
- PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- CTLineProperties spPr = getLn(shape, false);
- XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(spPr);
-
- if (fp != null && fp.isSetNoFill()) {
- setValue(null);
- return true;
- }
-
- PackagePart pp = shape.getSheet().getPackagePart();
- PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
- 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, hasPlaceholder);
-
- // line color was not found, check if it is defined in the theme
- if (paint == null) {
- paint = getThemePaint(style, pp);
- }
- }
-
- if (paint != null) {
- setValue(paint);
- return true;
- }
-
- return false;
- }
-
- PaintStyle getThemePaint(CTShapeStyle style, PackagePart pp) {
- // get a reference to a line style within the style matrix.
- CTStyleMatrixReference lnRef = style.getLnRef();
- if (lnRef == null) {
- return null;
- }
- int idx = (int)lnRef.getIdx();
- CTSchemeColor phClr = lnRef.getSchemeClr();
- if(idx <= 0){
- return null;
- }
-
- CTLineProperties props = theme.getXmlObject().getThemeElements().getFmtScheme().getLnStyleLst().getLnArray(idx - 1);
- XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
- return selectPaint(fp, phClr, pp, theme, hasPlaceholder);
- }
- };
- fetchShapeProperty(fetcher);
-
- return fetcher.getValue();
- }
-
- /**
- *
- * @param width line width in points. <code>0</code> means no line
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineWidth(double width) {
- CTLineProperties lnPr = getLn(this, true);
- if (lnPr == null) {
- return;
- }
-
- if (width == 0.) {
- 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 {
- if (lnPr.isSetNoFill()) {
- lnPr.unsetNoFill();
- }
-
- lnPr.setW(Units.toEMU(width));
- }
- }
-
- /**
- * @return line width in points. <code>0</code> means no line.
- */
- @SuppressWarnings("WeakerAccess")
- public double getLineWidth() {
- PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- CTLineProperties ln = getLn(shape, false);
- if (ln != null) {
- if (ln.isSetNoFill()) {
- setValue(0.);
- return true;
- }
-
- if (ln.isSetW()) {
- setValue(Units.toPoints(ln.getW()));
- return true;
- }
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- double lineWidth = 0;
- if (fetcher.getValue() == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- if (defaultLn != null) {
- if (defaultLn.isSetW()) {
- lineWidth = Units.toPoints(defaultLn.getW());
- }
- }
- } else {
- lineWidth = fetcher.getValue();
- }
-
- return lineWidth;
- }
-
-
- /**
- * @param compound set the line compound style
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineCompound(LineCompound compound) {
- CTLineProperties ln = getLn(this, true);
- if (ln == null) {
- return;
- }
- if (compound == null) {
- if (ln.isSetCmpd()) {
- ln.unsetCmpd();
- }
- } else {
- STCompoundLine.Enum xCmpd;
- switch (compound) {
- default:
- case SINGLE:
- xCmpd = STCompoundLine.SNG;
- break;
- case DOUBLE:
- xCmpd = STCompoundLine.DBL;
- break;
- case THICK_THIN:
- xCmpd = STCompoundLine.THICK_THIN;
- break;
- case THIN_THICK:
- xCmpd = STCompoundLine.THIN_THICK;
- break;
- case TRIPLE:
- xCmpd = STCompoundLine.TRI;
- break;
- }
- ln.setCmpd(xCmpd);
- }
- }
-
- /**
- * @return the line compound
- */
- @SuppressWarnings("WeakerAccess")
- public LineCompound getLineCompound() {
- PropertyFetcher<Integer> fetcher = new PropertyFetcher<Integer>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- CTLineProperties ln = getLn(shape, false);
- if (ln != null) {
- STCompoundLine.Enum stCmpd = ln.getCmpd();
- if (stCmpd != null) {
- setValue(stCmpd.intValue());
- return true;
- }
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- Integer cmpd = fetcher.getValue();
- if (cmpd == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- 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;
- }
- }
- }
-
- return null;
- }
-
- /**
- *
- * @param dash a preset line dashing scheme to stroke thr shape outline
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineDash(LineDash dash) {
- CTLineProperties ln = getLn(this, true);
- if (ln == null) {
- return;
- }
- if (dash == null) {
- if (ln.isSetPrstDash()) {
- ln.unsetPrstDash();
- }
- } else {
- CTPresetLineDashProperties ldp = ln.isSetPrstDash() ? ln.getPrstDash() : ln.addNewPrstDash();
- ldp.setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
- }
- }
-
- /**
- * @return a preset line dashing scheme to stroke the shape outline
- */
- @SuppressWarnings("WeakerAccess")
- public LineDash getLineDash() {
-
- PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- CTLineProperties ln = getLn(shape, false);
- if (ln == null || !ln.isSetPrstDash()) {
- return false;
- }
-
- setValue(LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue()));
- return true;
- }
- };
- fetchShapeProperty(fetcher);
-
- LineDash dash = fetcher.getValue();
- if (dash == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- if (defaultLn != null && defaultLn.isSetPrstDash()) {
- dash = LineDash.fromOoxmlId(defaultLn.getPrstDash().getVal().intValue());
- }
- }
- return dash;
- }
-
- /**
- *
- * @param cap the line end cap style
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineCap(LineCap cap) {
- CTLineProperties ln = getLn(this, true);
- if (ln == null) {
- return;
- }
-
- if (cap == null) {
- if (ln.isSetCap()) {
- ln.unsetCap();
- }
- } else {
- ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
- }
- }
-
- /**
- *
- * @return the line end cap style
- */
- @SuppressWarnings("WeakerAccess")
- public LineCap getLineCap() {
- PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- CTLineProperties ln = getLn(shape, false);
- if (ln != null && ln.isSetCap()) {
- setValue(LineCap.fromOoxmlId(ln.getCap().intValue()));
- return true;
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- LineCap cap = fetcher.getValue();
- if (cap == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- if (defaultLn != null && defaultLn.isSetCap()) {
- cap = LineCap.fromOoxmlId(defaultLn.getCap().intValue());
- }
- }
- return cap;
- }
-
- @Override
- public void setFillColor(Color color) {
- XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(getShapeProperties());
- if (fp == null) {
- return;
- }
- if (color == null) {
- if (fp.isSetSolidFill()) {
- fp.unsetSolidFill();
- }
-
- if (fp.isSetGradFill()) {
- fp.unsetGradFill();
- }
-
- if (fp.isSetPattFill()) {
- fp.unsetGradFill();
- }
-
- if (fp.isSetBlipFill()) {
- fp.unsetBlipFill();
- }
-
- if (!fp.isSetNoFill()) {
- fp.addNewNoFill();
- }
- } else {
- if (fp.isSetNoFill()) {
- fp.unsetNoFill();
- }
-
- CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill();
-
- XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
- col.setColor(color);
- }
- }
-
- @Override
- public Color getFillColor() {
- PaintStyle ps = getFillPaint();
- if (ps instanceof SolidPaint) {
- return DrawPaint.applyColorTransform(((SolidPaint)ps).getSolidColor());
- }
- return null;
- }
-
- /**
- * @return shadow of this shape or null if shadow is disabled
- */
- @Override
- public XSLFShadow getShadow() {
- PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
- @Override
- public boolean fetch(XSLFShape shape) {
- XSLFEffectProperties ep = XSLFPropertiesDelegate.getEffectDelegate(shape.getShapeProperties());
- if (ep != null && ep.isSetEffectLst()) {
- CTOuterShadowEffect obj = ep.getEffectLst().getOuterShdw();
- setValue(obj == null ? NO_SHADOW : obj);
- return true;
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- CTOuterShadowEffect obj = fetcher.getValue();
- if (obj == null) {
- // fill color was not found, check if it is defined in the theme
- CTShapeStyle style = getSpStyle();
- 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) {
- CTStyleMatrix styleMatrix = getSheet().getTheme().getXmlObject().getThemeElements().getFmtScheme();
- CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
- obj = ef.getEffectLst().getOuterShdw();
- }
- }
- }
- return (obj == null || obj == NO_SHADOW) ? null : new XSLFShadow(obj, this);
- }
-
- /**
- * @return definition of the shape geometry
- */
- @Override
- public CustomGeometry getGeometry() {
- XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
-
- if (gp == null) {
- return null;
- }
-
- CustomGeometry geom;
- PresetGeometries dict = PresetGeometries.getInstance();
- 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 (gp.isSetCustGeom()){
- XMLStreamReader staxReader = gp.getCustGeom().newXMLStreamReader();
- geom = PresetGeometries.convertCustomGeometry(staxReader);
- try {
- staxReader.close();
- }
- catch (XMLStreamException e) {
- LOG.log(POILogger.WARN,
- "An error occurred while closing a Custom Geometry XML Stream Reader: " + e.getMessage());
- }
- } else {
- geom = dict.get("rect");
- }
- return geom;
- }
-
- @Override
- void copy(XSLFShape sh){
- super.copy(sh);
-
- XSLFSimpleShape s = (XSLFSimpleShape)sh;
-
- Color srsSolidFill = s.getFillColor();
- Color tgtSoliFill = getFillColor();
- if(srsSolidFill != null && !srsSolidFill.equals(tgtSoliFill)){
- setFillColor(srsSolidFill);
- }
-
- 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());
- blip.setEmbed(relId);
- }
-
- Color srcLineColor = s.getLineColor();
- Color tgtLineColor = getLineColor();
- if(srcLineColor != null && !srcLineColor.equals(tgtLineColor)) {
- setLineColor(srcLineColor);
- }
-
- double srcLineWidth = s.getLineWidth();
- double tgtLineWidth = getLineWidth();
- if(srcLineWidth != tgtLineWidth) {
- setLineWidth(srcLineWidth);
- }
-
- LineDash srcLineDash = s.getLineDash();
- LineDash tgtLineDash = getLineDash();
- if(srcLineDash != null && srcLineDash != tgtLineDash) {
- setLineDash(srcLineDash);
- }
-
- LineCap srcLineCap = s.getLineCap();
- LineCap tgtLineCap = getLineCap();
- if(srcLineCap != null && srcLineCap != tgtLineCap) {
- setLineCap(srcLineCap);
- }
-
- }
-
- /**
- * Specifies the line end decoration, such as a triangle or arrowhead.
- *
- * @param style the line end docoration style
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineHeadDecoration(DecorationShape style) {
- 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();
- }
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration shape
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationShape getLineHeadDecoration() {
- 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 decoration width of the head of a line.
- *
- * @param style the decoration width
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineHeadWidth(DecorationSize style) {
- 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();
- }
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration width
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationSize getLineHeadWidth() {
- 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.
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineHeadLength(DecorationSize style) {
- 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();
- }
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration length
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationSize getLineHeadLength() {
- 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.
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineTailDecoration(DecorationShape style) {
- 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();
- }
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration shape
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationShape getLineTailDecoration() {
- 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.
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineTailWidth(DecorationSize style) {
- 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();
- }
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration width
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationSize getLineTailWidth() {
- 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.
- */
- @SuppressWarnings("WeakerAccess")
- public void setLineTailLength(DecorationSize style) {
- 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();
- }
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ooxmlId));
- }
- }
-
- /**
- * @return the line end decoration length
- */
- @SuppressWarnings("WeakerAccess")
- public DecorationSize getLineTailLength() {
- 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;
- }
-
- @Override
- public Guide getAdjustValue(String name) {
- XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
-
- if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) {
- //noinspection deprecation
- for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) {
- if (g.getName().equals(name)) {
- return new Guide(g.getName(), g.getFmla());
- }
- }
- }
-
- return null;
- }
-
- @Override
- public LineDecoration getLineDecoration() {
- return new LineDecoration() {
- @Override
- public DecorationShape getHeadShape() {
- return getLineHeadDecoration();
- }
-
- @Override
- public DecorationSize getHeadWidth() {
- return getLineHeadWidth();
- }
-
- @Override
- public DecorationSize getHeadLength() {
- return getLineHeadLength();
- }
-
- @Override
- public DecorationShape getTailShape() {
- return getLineTailDecoration();
- }
-
- @Override
- public DecorationSize getTailWidth() {
- return getLineTailWidth();
- }
-
- @Override
- public DecorationSize getTailLength() {
- return getLineTailLength();
- }
- };
- }
-
- /**
- * fetch shape fill as a java.awt.Paint
- *
- * @return either Color or GradientPaint or TexturePaint or null
- */
- @Override
- public FillStyle getFillStyle() {
- return XSLFSimpleShape.this::getFillPaint;
- }
-
- @Override
- public StrokeStyle getStrokeStyle() {
- return new StrokeStyle() {
- @Override
- public PaintStyle getPaint() {
- return XSLFSimpleShape.this.getLinePaint();
- }
-
- @Override
- public LineCap getLineCap() {
- return XSLFSimpleShape.this.getLineCap();
- }
-
- @Override
- public LineDash getLineDash() {
- return XSLFSimpleShape.this.getLineDash();
- }
-
- @Override
- public double getLineWidth() {
- return XSLFSimpleShape.this.getLineWidth();
- }
-
- @Override
- public LineCompound getLineCompound() {
- return XSLFSimpleShape.this.getLineCompound();
- }
-
- };
- }
-
- @Override
- public void setStrokeStyle(Object... styles) {
- if (styles.length == 0) {
- // remove stroke
- setLineColor(null);
- return;
- }
-
- // TODO: handle PaintStyle
- for (Object st : styles) {
- if (st instanceof Number) {
- setLineWidth(((Number)st).doubleValue());
- } else if (st instanceof LineCap) {
- setLineCap((LineCap)st);
- } else if (st instanceof LineDash) {
- setLineDash((LineDash)st);
- } else if (st instanceof LineCompound) {
- setLineCompound((LineCompound)st);
- } else if (st instanceof Color) {
- setLineColor((Color)st);
- }
- }
- }
-
- @Override
- public XSLFHyperlink getHyperlink() {
- CTNonVisualDrawingProps cNvPr = getCNvPr();
- if (!cNvPr.isSetHlinkClick()) {
- return null;
- }
- return new XSLFHyperlink(cNvPr.getHlinkClick(), getSheet());
- }
-
- @Override
- public XSLFHyperlink createHyperlink() {
- XSLFHyperlink hl = getHyperlink();
- if (hl == null) {
- CTNonVisualDrawingProps cNvPr = getCNvPr();
- hl = new XSLFHyperlink(cNvPr.addNewHlinkClick(), getSheet());
- }
- return hl;
- }
-
- private static CTLineProperties getLn(XSLFShape shape, boolean create) {
- XmlObject pr = shape.getShapeProperties();
- if (!(pr instanceof CTShapeProperties)) {
- LOG.log(POILogger.WARN, shape.getClass() +" doesn't have line properties");
- return null;
- }
-
- CTShapeProperties spr = (CTShapeProperties)pr;
- return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn();
- }
- }
|