/pptx/src/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
Java | 971 lines | 731 code | 111 blank | 129 comment | 200 complexity | 90e9bcad3d44264dac9d11db9a001e3f MD5 | raw file
- /*
- * ====================================================================
- * 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.util.ArrayList;
- import java.util.List;
-
- import net.pbdavey.awt.Graphics2D;
-
- import org.apache.poi.util.Beta;
- import org.apache.poi.util.Units;
- import org.apache.poi.xslf.model.PropertyFetcher;
- import org.apache.poi.xslf.model.geom.CustomGeometry;
- import org.apache.poi.xslf.model.geom.Outline;
- import org.apache.poi.xslf.model.geom.Path;
- import org.apache.poi.xslf.model.geom.PresetGeometries;
- import org.apache.xmlbeans.XmlObject;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
- //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.CTPresetLineDashProperties;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
- 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.CTTransform2D;
- 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;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
- import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
-
- import and.awt.Color;
- import and.awt.Paint;
- import and.awt.Shape;
- import and.awt.geom.AffineTransform;
- import and.awt.geom.Ellipse2D;
- import and.awt.geom.GeneralPath;
- import and.awt.geom.Rectangle2D;
-
- /**
- * Represents a single (non-group) shape in a .pptx slide show
- *
- * @author Yegor Kozlov
- */
- @Beta
- public abstract class XSLFSimpleShape extends XSLFShape {
- private static CTOuterShadowEffect NO_SHADOW = CTOuterShadowEffect.Factory.newInstance();
-
- private final XmlObject _shape;
- private final XSLFSheet _sheet;
- private CTShapeProperties _spPr;
- private CTShapeStyle _spStyle;
- private CTNonVisualDrawingProps _nvPr;
- private CTPlaceholder _ph;
-
- /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) {
- _shape = shape;
- _sheet = sheet;
- }
-
- @Override
- public XmlObject getXmlObject() {
- return _shape;
- }
-
- /**
- *
- * @return the sheet this shape belongs to
- */
- public XSLFSheet getSheet() {
- return _sheet;
- }
-
- /**
- *
- * @param type
- */
- public void setShapeType(XSLFShapeType type){
- CTShape shape = (CTShape) getXmlObject();
- STShapeType.Enum geom = STShapeType.Enum.forInt(type.getIndex());
- shape.getSpPr().getPrstGeom().setPrst(geom);
- }
-
- public XSLFShapeType getShapeType(){
- CTShape shape = (CTShape) getXmlObject();
- STShapeType.Enum geom = shape.getSpPr().getPrstGeom().getPrst();
- return XSLFShapeType.forInt(geom.intValue());
- }
-
- @Override
- public String getShapeName() {
- return getNvPr().getName();
- }
-
- @Override
- public int getShapeId() {
- return (int) getNvPr().getId();
- }
-
- protected CTNonVisualDrawingProps getNvPr() {
- if (_nvPr == null) {
- XmlObject[] rs = _shape
- .selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
- if (rs.length != 0) {
- _nvPr = (CTNonVisualDrawingProps) rs[0];
- }
- }
- return _nvPr;
- }
-
- protected CTShapeProperties getSpPr() {
- if (_spPr == null) {
- for (XmlObject obj : _shape.selectPath("*")) {
- if (obj instanceof CTShapeProperties) {
- _spPr = (CTShapeProperties) obj;
- }
- }
- }
- if (_spPr == null) {
- throw new IllegalStateException("CTShapeProperties was not found.");
- }
- return _spPr;
- }
-
- protected CTShapeStyle getSpStyle() {
- if (_spStyle == null) {
- for (XmlObject obj : _shape.selectPath("*")) {
- if (obj instanceof CTShapeStyle) {
- _spStyle = (CTShapeStyle) obj;
- }
- }
- }
- return _spStyle;
- }
-
- protected CTPlaceholder getCTPlaceholder() {
- if (_ph == null) {
- XmlObject[] obj = _shape.selectPath(
- "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph");
- if (obj.length == 1) {
- _ph = (CTPlaceholder) obj[0];
- }
- }
- return _ph;
- }
-
- CTTransform2D getXfrm() {
- PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>() {
- public boolean fetch(XSLFSimpleShape shape) {
- CTShapeProperties pr = shape.getSpPr();
- if (pr.isSetXfrm()) {
- setValue(pr.getXfrm());
- return true;
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
- return fetcher.getValue();
- }
-
- @Override
- public Rectangle2D getAnchor() {
-
- CTTransform2D xfrm = getXfrm();
-
- CTPoint2D off = xfrm.getOff();
- long x = off.getX();
- long y = off.getY();
- CTPositiveSize2D ext = xfrm.getExt();
- long cx = ext.getCx();
- long cy = ext.getCy();
- return new Rectangle2D.Double(
- Units.toPoints(x), Units.toPoints(y),
- Units.toPoints(cx), Units.toPoints(cy));
- }
-
- @Override
- public void setAnchor(Rectangle2D anchor) {
- CTShapeProperties spPr = getSpPr();
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
- 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) {
- CTShapeProperties spPr = getSpPr();
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
- xfrm.setRot((int) (theta * 60000));
- }
-
- @Override
- public double getRotation() {
- CTTransform2D xfrm = getXfrm();
- return (double) xfrm.getRot() / 60000;
- }
-
- @Override
- public void setFlipHorizontal(boolean flip) {
- CTShapeProperties spPr = getSpPr();
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
- xfrm.setFlipH(flip);
- }
-
- @Override
- public void setFlipVertical(boolean flip) {
- CTShapeProperties spPr = getSpPr();
- CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
- xfrm.setFlipV(flip);
- }
-
- @Override
- public boolean getFlipHorizontal() {
- return getXfrm().getFlipH();
- }
-
- @Override
- public boolean getFlipVertical() {
- return getXfrm().getFlipV();
- }
-
- /**
- * Get default line properties defined in the theme (if any).
- * Used internally to resolve shape properties.
- *
- * @return line propeties from the theme of null
- */
- CTLineProperties getDefaultLineProperties() {
- CTLineProperties ln = null;
- CTShapeStyle style = getSpStyle();
- if (style != null) {
- // 1-based index of a line style within the style matrix
- int idx = (int) style.getLnRef().getIdx();
- CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
- ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1);
- }
- return ln;
- }
-
- /**
- * @param color the color to paint the shape outline.
- * A <code>null</code> value turns off the shape outline.
- */
- public void setLineColor(Color color) {
- CTShapeProperties spPr = getSpPr();
- if (color == null) {
- if (spPr.isSetLn() && spPr.getLn().isSetSolidFill())
- spPr.getLn().unsetSolidFill();
- } else {
- CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
- .addNewLn();
-
- CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
- rgb.setVal(new byte[]{(byte) color.getRed(),
- (byte) color.getGreen(), (byte) color.getBlue()});
-
- CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln
- .getSolidFill() : ln.addNewSolidFill();
- fill.setSrgbClr(rgb);
- if(fill.isSetHslClr()) fill.unsetHslClr();
- if(fill.isSetPrstClr()) fill.unsetPrstClr();
- if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
- if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
- if(fill.isSetSysClr()) fill.unsetSysClr();
- }
- }
-
- /**
- *
- * @return the color of the shape outline or <code>null</code>
- * if outline is turned off
- */
- public Color getLineColor() {
- RenderableShape rShape = new RenderableShape(this);
- Paint paint = rShape.getLinePaint(null);
- if (paint instanceof Color) {
- return (Color) paint;
- }
- return null;
- }
-
- /**
- *
- * @param width line width in points. <code>0</code> means no line
- */
- public void setLineWidth(double width) {
- CTShapeProperties spPr = getSpPr();
- if (width == 0.) {
- if (spPr.isSetLn())
- spPr.getLn().unsetW();
- } else {
- CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
- .addNewLn();
- ln.setW(Units.toEMU(width));
- }
- }
-
- /**
- *
- * @return line width in points. <code>0</code> means no line.
- */
- public double getLineWidth() {
- PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>() {
- public boolean fetch(XSLFSimpleShape shape) {
- CTShapeProperties spPr = shape.getSpPr();
- CTLineProperties ln = spPr.getLn();
- 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 dash a preset line dashing scheme to stroke thr shape outline
- */
- public void setLineDash(LineDash dash) {
- CTShapeProperties spPr = getSpPr();
- if (dash == null) {
- if (spPr.isSetLn())
- spPr.getLn().unsetPrstDash();
- } else {
- CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory
- .newInstance();
- val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1));
- CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
- .addNewLn();
- ln.setPrstDash(val);
- }
- }
-
- /**
- * @return a preset line dashing scheme to stroke thr shape outline
- */
- public LineDash getLineDash() {
-
- PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>() {
- public boolean fetch(XSLFSimpleShape shape) {
- CTShapeProperties spPr = shape.getSpPr();
- CTLineProperties ln = spPr.getLn();
- if (ln != null) {
- CTPresetLineDashProperties ctDash = ln.getPrstDash();
- if (ctDash != null) {
- setValue(LineDash.values()[ctDash.getVal().intValue() - 1]);
- return true;
- }
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- LineDash dash = fetcher.getValue();
- if (dash == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- if (defaultLn != null) {
- CTPresetLineDashProperties ctDash = defaultLn.getPrstDash();
- if (ctDash != null) {
- dash = LineDash.values()[ctDash.getVal().intValue() - 1];
- }
- }
- }
- return dash;
- }
-
- /**
- *
- * @param cap the line end cap style
- */
- public void setLineCap(LineCap cap) {
- CTShapeProperties spPr = getSpPr();
- if (cap == null) {
- if (spPr.isSetLn())
- spPr.getLn().unsetCap();
- } else {
- CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
- .addNewLn();
- ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
- }
- }
-
- /**
- *
- * @return the line end cap style
- */
- public LineCap getLineCap() {
- PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>() {
- public boolean fetch(XSLFSimpleShape shape) {
- CTShapeProperties spPr = shape.getSpPr();
- CTLineProperties ln = spPr.getLn();
- if (ln != null) {
- STLineCap.Enum stCap = ln.getCap();
- if (stCap != null) {
- setValue(LineCap.values()[stCap.intValue() - 1]);
- return true;
- }
- }
- return false;
- }
- };
- fetchShapeProperty(fetcher);
-
- LineCap cap = fetcher.getValue();
- if (cap == null) {
- CTLineProperties defaultLn = getDefaultLineProperties();
- if (defaultLn != null) {
- STLineCap.Enum stCap = defaultLn.getCap();
- if (stCap != null) {
- cap = LineCap.values()[stCap.intValue() - 1];
- }
- }
- }
- return cap;
- }
-
- /**
- * Specifies a solid color fill. The shape is filled entirely with the
- * specified color.
- *
- * @param color the solid color fill. The value of <code>null</code> unsets
- * the solidFIll attribute from the underlying xml
- */
- public void setFillColor(Color color) {
- CTShapeProperties spPr = getSpPr();
- if (color == null) {
- if (spPr.isSetSolidFill()) spPr.unsetSolidFill();
-
- if (!spPr.isSetNoFill()) spPr.addNewNoFill();
- } else {
- if (spPr.isSetNoFill()) spPr.unsetNoFill();
-
- CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr
- .getSolidFill() : spPr.addNewSolidFill();
-
- CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
- rgb.setVal(new byte[]{(byte) color.getRed(),
- (byte) color.getGreen(), (byte) color.getBlue()});
-
- fill.setSrgbClr(rgb);
- if(fill.isSetHslClr()) fill.unsetHslClr();
- if(fill.isSetPrstClr()) fill.unsetPrstClr();
- if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
- if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
- if(fill.isSetSysClr()) fill.unsetSysClr();
- }
- }
-
- /**
- * @return solid fill color of null if not set or fill color
- * is not solid (pattern or gradient)
- */
- public Color getFillColor() {
- RenderableShape rShape = new RenderableShape(this);
- Paint paint = rShape.getFillPaint(null);
- if (paint instanceof Color) {
- return (Color) paint;
- }
- return null;
- }
-
- /**
- * @return shadow of this shape or null if shadow is disabled
- */
- public XSLFShadow getShadow() {
- PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>() {
- public boolean fetch(XSLFSimpleShape shape) {
- CTShapeProperties spPr = shape.getSpPr();
- if (spPr.isSetEffectLst()) {
- CTOuterShadowEffect obj = spPr.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) {
- // 1-based index of a shadow style within the style matrix
- int idx = (int) style.getEffectRef().getIdx();
- if(idx != 0) {
- CTStyleMatrix styleMatrix = _sheet.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);
- }
-
- @Override
- public void draw(Graphics2D graphics) {
- RenderableShape rShape = new RenderableShape(this);
- rShape.render(graphics);
-
- // draw line decorations
- Color lineColor = getLineColor();
- if(lineColor != null) {
- graphics.setPaint(lineColor);
- for(Outline o : getDecorationOutlines(graphics)){
- if(o.getPath().isFilled()){
- graphics.fill(o.getOutline());
- }
- if(o.getPath().isStroked()){
- graphics.draw(o.getOutline());
- }
- }
- }
- }
-
-
- /**
- * Walk up the inheritance tree and fetch shape properties.
- *
- * The following order of inheritance is assumed:
- * <p>
- * slide <-- slideLayout <-- slideMaster
- * </p>
- *
- * @param visitor the object that collects the desired property
- * @return true if the property was fetched
- */
- boolean fetchShapeProperty(PropertyFetcher visitor) {
- boolean ok = visitor.fetch(this);
-
- XSLFSimpleShape masterShape;
- XSLFSheet masterSheet = 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 = masterSheet.getMasterSheet();
- if (master != null) {
- masterShape = master.getPlaceholderByType(textType);
- if (masterShape != null) {
- ok = visitor.fetch(masterShape);
- }
- }
- }
- }
- return ok;
- }
-
- /**
- *
- * @return definition of the shape geometry
- */
- CustomGeometry getGeometry(){
- CTShapeProperties spPr = getSpPr();
- CustomGeometry geom;
- PresetGeometries dict = PresetGeometries.getInstance();
- if(spPr.isSetPrstGeom()){
- String name = spPr.getPrstGeom().getPrst().toString();
- geom = dict.get(name);
- if(geom == null) {
- throw new IllegalStateException("Unknown shape geometry: " + name);
- }
- } else if (spPr.isSetCustGeom()){
- geom = new CustomGeometry(spPr.getCustGeom());
- } else {
- geom = dict.get("rect");
- }
- return geom;
- }
-
-
- /**
- * draw any content within this shape (image, text, etc.).
- *
- * @param graphics the graphics to draw into
- */
- public void drawContent(Graphics2D graphics){
-
- }
-
- @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);
- }
-
- if(getSpPr().isSetBlipFill()){
- CTBlip blip = getSpPr().getBlipFill().getBlip();
- String blipId = blip.getEmbed();
-
- String relId = getSheet().importBlip(blipId, s.getSheet().getPackagePart());
- 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.
- */
- public void setLineHeadDecoration(LineDecoration style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
- if (style == null) {
- if (lnEnd.isSetType()) lnEnd.unsetType();
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineDecoration getLineHeadDecoration() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineDecoration.NONE;
-
- STLineEndType.Enum end = ln.getHeadEnd().getType();
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
- }
-
- /**
- * specifies decorations which can be added to the head of a line.
- */
- public void setLineHeadWidth(LineEndWidth style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
- if (style == null) {
- if (lnEnd.isSetW()) lnEnd.unsetW();
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndWidth getLineHeadWidth() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineEndWidth.MEDIUM;
-
- STLineEndWidth.Enum w = ln.getHeadEnd().getW();
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
- }
-
- /**
- * Specifies the line end width in relation to the line width.
- */
- public void setLineHeadLength(LineEndLength style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
-
- if (style == null) {
- if (lnEnd.isSetLen()) lnEnd.unsetLen();
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndLength getLineHeadLength() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetHeadEnd()) return LineEndLength.MEDIUM;
-
- STLineEndLength.Enum len = ln.getHeadEnd().getLen();
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
- }
-
- /**
- * Specifies the line end decoration, such as a triangle or arrowhead.
- */
- public void setLineTailDecoration(LineDecoration style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
- if (style == null) {
- if (lnEnd.isSetType()) lnEnd.unsetType();
- } else {
- lnEnd.setType(STLineEndType.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineDecoration getLineTailDecoration() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineDecoration.NONE;
-
- STLineEndType.Enum end = ln.getTailEnd().getType();
- return end == null ? LineDecoration.NONE : LineDecoration.values()[end.intValue() - 1];
- }
-
- /**
- * specifies decorations which can be added to the tail of a line.
- */
- public void setLineTailWidth(LineEndWidth style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
- if (style == null) {
- if (lnEnd.isSetW()) lnEnd.unsetW();
- } else {
- lnEnd.setW(STLineEndWidth.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndWidth getLineTailWidth() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineEndWidth.MEDIUM;
-
- STLineEndWidth.Enum w = ln.getTailEnd().getW();
- return w == null ? LineEndWidth.MEDIUM : LineEndWidth.values()[w.intValue() - 1];
- }
-
- /**
- * Specifies the line end width in relation to the line width.
- */
- public void setLineTailLength(LineEndLength style) {
- CTLineProperties ln = getSpPr().getLn();
- CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
-
- if (style == null) {
- if (lnEnd.isSetLen()) lnEnd.unsetLen();
- } else {
- lnEnd.setLen(STLineEndLength.Enum.forInt(style.ordinal() + 1));
- }
- }
-
- public LineEndLength getLineTailLength() {
- CTLineProperties ln = getSpPr().getLn();
- if (ln == null || !ln.isSetTailEnd()) return LineEndLength.MEDIUM;
-
- STLineEndLength.Enum len = ln.getTailEnd().getLen();
- return len == null ? LineEndLength.MEDIUM : LineEndLength.values()[len.intValue() - 1];
- }
-
- Outline getTailDecoration(Graphics2D graphics) {
- LineEndLength tailLength = getLineTailLength();
- LineEndWidth tailWidth = getLineTailWidth();
-
- double lineWidth = Math.max(2.5, getLineWidth());
-
- Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
- double x2 = anchor.getX() + anchor.getWidth(),
- y2 = anchor.getY() + anchor.getHeight();
-
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
- AffineTransform at = new AffineTransform();
- Shape shape = null;
- Path p = null;
- Rectangle2D bounds;
- double scaleY = Math.pow(2, tailWidth.ordinal());
- double scaleX = Math.pow(2, tailLength.ordinal());
- switch (getLineTailDecoration()) {
- case OVAL:
- p = new Path();
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
- bounds = shape.getBounds2D();
- at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
- break;
- case ARROW:
- p = new Path();
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));
- arrow.lineTo(0, 0);
- arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));
- shape = arrow;
- at.translate(x2, y2);
- at.rotate(alpha);
- break;
- case TRIANGLE:
- p = new Path();
- scaleY = tailWidth.ordinal() + 1;
- scaleX = tailLength.ordinal() + 1;
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
- triangle.lineTo(0, 0);
- triangle.lineTo((float) (-lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
- triangle.closePath();
- shape = triangle;
- at.translate(x2, y2);
- at.rotate(alpha);
- break;
- default:
- break;
- }
-
- if (shape != null) {
- shape = at.createTransformedShape(shape);
- }
- return shape == null ? null : new Outline(shape, p);
- }
-
- Outline getHeadDecoration(Graphics2D graphics) {
- LineEndLength headLength = getLineHeadLength();
- LineEndWidth headWidth = getLineHeadWidth();
-
- double lineWidth = Math.max(2.5, getLineWidth());
-
- Rectangle2D anchor = new RenderableShape(this).getAnchor(graphics);
- double x1 = anchor.getX(),
- y1 = anchor.getY();
-
- double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
-
- AffineTransform at = new AffineTransform();
- Shape shape = null;
- Path p = null;
- Rectangle2D bounds;
- double scaleY = 1;
- double scaleX = 1;
- switch (getLineHeadDecoration()) {
- case OVAL:
- p = new Path();
- shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
- bounds = shape.getBounds2D();
- at.translate(x1 - bounds.getWidth() / 2, y1 - bounds.getHeight() / 2);
- at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
- break;
- case STEALTH:
- case ARROW:
- p = new Path(false, true);
- GeneralPath arrow = new GeneralPath();
- arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));
- arrow.lineTo(0, 0);
- arrow.lineTo((float) (lineWidth * 3 * scaleX), (float) (lineWidth * scaleY * 2));
- shape = arrow;
- at.translate(x1, y1);
- at.rotate(alpha);
- break;
- case TRIANGLE:
- p = new Path();
- scaleY = headWidth.ordinal() + 1;
- scaleX = headLength.ordinal() + 1;
- GeneralPath triangle = new GeneralPath();
- triangle.moveTo((float) (lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
- triangle.lineTo(0, 0);
- triangle.lineTo((float) (lineWidth * scaleX), (float) (lineWidth * scaleY / 2));
- triangle.closePath();
- shape = triangle;
- at.translate(x1, y1);
- at.rotate(alpha);
- break;
- default:
- break;
- }
-
- if (shape != null) {
- shape = at.createTransformedShape(shape);
- }
- return shape == null ? null : new Outline(shape, p);
- }
-
- private List<Outline> getDecorationOutlines(Graphics2D graphics){
- List<Outline> lst = new ArrayList<Outline>();
-
- Outline head = getHeadDecoration(graphics);
- if(head != null) lst.add(head);
-
- Outline tail = getTailDecoration(graphics);
- if(tail != null) lst.add(tail);
- return lst;
- }
-
- }