| /* ==================================================================== |
| 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.hslf.usermodel; |
| |
| import java.awt.Color; |
| |
| import org.apache.poi.ddf.AbstractEscherOptRecord; |
| import org.apache.poi.ddf.EscherChildAnchorRecord; |
| import org.apache.poi.ddf.EscherClientAnchorRecord; |
| import org.apache.poi.ddf.EscherContainerRecord; |
| import org.apache.poi.ddf.EscherOptRecord; |
| import org.apache.poi.ddf.EscherProperty; |
| import org.apache.poi.ddf.EscherPropertyTypes; |
| import org.apache.poi.ddf.EscherRecord; |
| import org.apache.poi.ddf.EscherSimpleProperty; |
| import org.apache.poi.ddf.EscherSpRecord; |
| import org.apache.poi.hslf.exceptions.HSLFException; |
| 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.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.Placeholder; |
| import org.apache.poi.sl.usermodel.Shadow; |
| import org.apache.poi.sl.usermodel.ShapeContainer; |
| 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.LittleEndian; |
| import org.apache.poi.util.POILogFactory; |
| import org.apache.poi.util.POILogger; |
| import org.apache.poi.util.Units; |
| |
| /** |
| * An abstract simple (non-group) shape. |
| * This is the parent class for all primitive shapes like Line, Rectangle, etc. |
| */ |
| public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<HSLFShape,HSLFTextParagraph> { |
| private static final POILogger LOG = POILogFactory.getLogger(HSLFSimpleShape.class); |
| |
| public final static double DEFAULT_LINE_WIDTH = 0.75; |
| |
| private static final EscherPropertyTypes[] ADJUST_VALUES = { |
| EscherPropertyTypes.GEOMETRY__ADJUSTVALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST2VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST3VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST4VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST5VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST6VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST7VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST8VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST9VALUE, |
| EscherPropertyTypes.GEOMETRY__ADJUST10VALUE |
| }; |
| |
| /** |
| * Hyperlink |
| */ |
| protected HSLFHyperlink _hyperlink; |
| |
| /** |
| * Create a SimpleShape object and initialize it from the supplied Record container. |
| * |
| * @param escherRecord <code>EscherSpContainer</code> container which holds information about this shape |
| * @param parent the parent of the shape |
| */ |
| protected HSLFSimpleShape(EscherContainerRecord escherRecord, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){ |
| super(escherRecord, parent); |
| } |
| |
| /** |
| * Create a new Shape |
| * |
| * @param isChild <code>true</code> if the Line is inside a group, <code>false</code> otherwise |
| * @return the record container which holds this shape |
| */ |
| @Override |
| protected EscherContainerRecord createSpContainer(boolean isChild) { |
| EscherContainerRecord ecr = super.createSpContainer(isChild); |
| ecr.setRecordId( EscherContainerRecord.SP_CONTAINER ); |
| |
| EscherSpRecord sp = new EscherSpRecord(); |
| int flags = EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HASSHAPETYPE; |
| if (isChild) { |
| flags |= EscherSpRecord.FLAG_CHILD; |
| } |
| sp.setFlags(flags); |
| ecr.addChildRecord(sp); |
| |
| AbstractEscherOptRecord opt = new EscherOptRecord(); |
| opt.setRecordId(EscherOptRecord.RECORD_ID); |
| ecr.addChildRecord(opt); |
| |
| EscherRecord anchor; |
| if(isChild) { |
| anchor = new EscherChildAnchorRecord(); |
| } else { |
| anchor = new EscherClientAnchorRecord(); |
| |
| //hack. internal variable EscherClientAnchorRecord.shortRecord can be |
| //initialized only in fillFields(). We need to set shortRecord=false; |
| byte[] header = new byte[16]; |
| LittleEndian.putUShort(header, 0, 0); |
| LittleEndian.putUShort(header, 2, 0); |
| LittleEndian.putInt(header, 4, 8); |
| anchor.fillFields(header, 0, null); |
| } |
| ecr.addChildRecord(anchor); |
| |
| return ecr; |
| } |
| |
| /** |
| * Returns width of the line in in points |
| */ |
| public double getLineWidth(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEWIDTH); |
| return (prop == null) ? DEFAULT_LINE_WIDTH : Units.toPoints(prop.getPropertyValue()); |
| } |
| |
| /** |
| * Sets the width of line in in points |
| * @param width the width of line in in points |
| */ |
| public void setLineWidth(double width){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEWIDTH, Units.toEMU(width)); |
| } |
| |
| /** |
| * Sets the color of line |
| * |
| * @param color new color of the line |
| */ |
| public void setLineColor(Color color){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| if (color == null) { |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH, 0x80000); |
| } else { |
| int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__COLOR, rgb); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH, 0x180018); |
| } |
| } |
| |
| /** |
| * @return color of the line. If color is not set returns {@code null} |
| */ |
| public Color getLineColor(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| |
| EscherSimpleProperty p = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH); |
| if(p != null && (p.getPropertyValue() & 0x8) == 0) { |
| return null; |
| } |
| |
| return getColor(EscherPropertyTypes.LINESTYLE__COLOR, EscherPropertyTypes.LINESTYLE__OPACITY); |
| } |
| |
| /** |
| * @return background color of the line. If color is not set returns {@code null} |
| */ |
| public Color getLineBackgroundColor(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| |
| EscherSimpleProperty p = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH); |
| if(p != null && (p.getPropertyValue() & 0x8) == 0) { |
| return null; |
| } |
| |
| return getColor(EscherPropertyTypes.LINESTYLE__BACKCOLOR, EscherPropertyTypes.LINESTYLE__OPACITY); |
| } |
| |
| /** |
| * Sets the background color of line |
| * |
| * @param color new background color of the line |
| */ |
| public void setLineBackgroundColor(Color color){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| if (color == null) { |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH, 0x80000); |
| opt.removeEscherProperty(EscherPropertyTypes.LINESTYLE__BACKCOLOR); |
| } else { |
| int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 0).getRGB(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__BACKCOLOR, rgb); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__NOLINEDRAWDASH, 0x180018); |
| } |
| } |
| |
| /** |
| * Gets line cap. |
| * |
| * @return cap of the line. |
| */ |
| public LineCap getLineCap(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDCAPSTYLE); |
| return (prop == null) ? LineCap.FLAT : LineCap.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| /** |
| * Sets line cap. |
| * |
| * @param pen new style of the line. |
| */ |
| public void setLineCap(LineCap pen){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDCAPSTYLE, pen == LineCap.FLAT ? -1 : pen.nativeId); |
| } |
| |
| /** |
| * Gets line dashing. |
| * |
| * @return dashing of the line. |
| */ |
| public LineDash getLineDash(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEDASHING); |
| return (prop == null) ? LineDash.SOLID : LineDash.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| /** |
| * Sets line dashing. |
| * |
| * @param pen new style of the line. |
| */ |
| public void setLineDash(LineDash pen){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEDASHING, pen == LineDash.SOLID ? -1 : pen.nativeId); |
| } |
| |
| /** |
| * Gets the line compound style |
| * |
| * @return the compound style of the line. |
| */ |
| public LineCompound getLineCompound() { |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTYLE); |
| return (prop == null) ? LineCompound.SINGLE : LineCompound.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| /** |
| * Sets the line compound style |
| * |
| * @param style new compound style of the line. |
| */ |
| public void setLineCompound(LineCompound style){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTYLE, style == LineCompound.SINGLE ? -1 : style.nativeId); |
| } |
| |
| /** |
| * Returns line style. One of the constants defined in this class. |
| * |
| * @return style of the line. |
| */ |
| @Override |
| public StrokeStyle getStrokeStyle(){ |
| return new StrokeStyle() { |
| @Override |
| public PaintStyle getPaint() { |
| return DrawPaint.createSolidPaint(HSLFSimpleShape.this.getLineColor()); |
| } |
| |
| @Override |
| public LineCap getLineCap() { |
| return null; |
| } |
| |
| @Override |
| public LineDash getLineDash() { |
| return HSLFSimpleShape.this.getLineDash(); |
| } |
| |
| @Override |
| public LineCompound getLineCompound() { |
| return HSLFSimpleShape.this.getLineCompound(); |
| } |
| |
| @Override |
| public double getLineWidth() { |
| return HSLFSimpleShape.this.getLineWidth(); |
| } |
| }; |
| } |
| |
| @Override |
| public Color getFillColor() { |
| return getFill().getForegroundColor(); |
| } |
| |
| @Override |
| public void setFillColor(Color color) { |
| getFill().setForegroundColor(color); |
| } |
| |
| @Override |
| public Guide getAdjustValue(String name) { |
| if (name == null || !name.matches("adj([1-9]|10)?")) { |
| LOG.log(POILogger.INFO, "Adjust value '"+name+"' not supported. Using default value."); |
| return null; |
| } |
| |
| name = name.replace("adj", ""); |
| if (name.isEmpty()) { |
| name = "1"; |
| } |
| |
| final int adjInt = Integer.parseInt(name); |
| if (adjInt < 1 || adjInt > 10) { |
| throw new HSLFException("invalid adjust value: "+adjInt); |
| } |
| |
| |
| EscherPropertyTypes escherProp = ADJUST_VALUES[adjInt]; |
| |
| int adjval = getEscherProperty(escherProp, -1); |
| |
| if (adjval == -1) { |
| return null; |
| } |
| |
| // Bug 59004 |
| // the adjust value are format dependent, we scale them up so they match the OOXML ones. |
| // see https://social.msdn.microsoft.com/Forums/en-US/33e458e6-58df-48fe-9a10-e303ab08991d/preset-shapes-for-ppt?forum=os_binaryfile |
| |
| // usually we deal with length units and only very few degree units: |
| boolean isDegreeUnit = false; |
| switch (getShapeType()) { |
| case ARC: |
| case BLOCK_ARC: |
| case CHORD: |
| case PIE: |
| isDegreeUnit = (adjInt == 1 || adjInt == 2); |
| break; |
| case CIRCULAR_ARROW: |
| case LEFT_CIRCULAR_ARROW: |
| case LEFT_RIGHT_CIRCULAR_ARROW: |
| isDegreeUnit = (adjInt == 2 || adjInt == 3 || adjInt == 4); |
| break; |
| case MATH_NOT_EQUAL: |
| isDegreeUnit = (adjInt == 2); |
| break; |
| } |
| |
| return new Guide(name, "val "+Math.rint(adjval * (isDegreeUnit ? 65536. : 100000./21000.))); |
| } |
| |
| @Override |
| public CustomGeometry getGeometry() { |
| PresetGeometries dict = PresetGeometries.getInstance(); |
| ShapeType st = getShapeType(); |
| String name = (st != null) ? st.getOoxmlName() : null; |
| CustomGeometry geom = dict.get(name); |
| if (geom == null) { |
| if (name == null) { |
| name = (st != null) ? st.toString() : "<unknown>"; |
| } |
| LOG.log(POILogger.WARN, "No preset shape definition for shapeType: "+name); |
| } |
| |
| return geom; |
| } |
| |
| |
| public double getShadowAngle() { |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.SHADOWSTYLE__OFFSETX); |
| int offX = (prop == null) ? 0 : prop.getPropertyValue(); |
| prop = getEscherProperty(opt, EscherPropertyTypes.SHADOWSTYLE__OFFSETY); |
| int offY = (prop == null) ? 0 : prop.getPropertyValue(); |
| return Math.toDegrees(Math.atan2(offY, offX)); |
| } |
| |
| public double getShadowDistance() { |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.SHADOWSTYLE__OFFSETX); |
| int offX = (prop == null) ? 0 : prop.getPropertyValue(); |
| prop = getEscherProperty(opt, EscherPropertyTypes.SHADOWSTYLE__OFFSETY); |
| int offY = (prop == null) ? 0 : prop.getPropertyValue(); |
| return Units.toPoints((long)Math.hypot(offX, offY)); |
| } |
| |
| /** |
| * @return color of the line. If color is not set returns <code>java.awt.Color.black</code> |
| */ |
| public Color getShadowColor(){ |
| Color clr = getColor(EscherPropertyTypes.SHADOWSTYLE__COLOR, EscherPropertyTypes.SHADOWSTYLE__OPACITY); |
| return clr == null ? Color.black : clr; |
| } |
| |
| @Override |
| public Shadow<HSLFShape,HSLFTextParagraph> getShadow() { |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| if (opt == null) { |
| return null; |
| } |
| EscherProperty shadowType = opt.lookup(EscherPropertyTypes.SHADOWSTYLE__TYPE); |
| if (shadowType == null) { |
| return null; |
| } |
| |
| return new Shadow<HSLFShape,HSLFTextParagraph>(){ |
| @Override |
| public SimpleShape<HSLFShape,HSLFTextParagraph> getShadowParent() { |
| return HSLFSimpleShape.this; |
| } |
| |
| @Override |
| public double getDistance() { |
| return getShadowDistance(); |
| } |
| |
| @Override |
| public double getAngle() { |
| return getShadowAngle(); |
| } |
| |
| @Override |
| public double getBlur() { |
| // TODO Auto-generated method stub |
| return 0; |
| } |
| |
| @Override |
| public SolidPaint getFillStyle() { |
| return DrawPaint.createSolidPaint(getShadowColor()); |
| } |
| |
| }; |
| } |
| |
| public DecorationShape getLineHeadDecoration(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWHEAD); |
| return (prop == null) ? null : DecorationShape.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineHeadDecoration(DecorationShape decoShape){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWHEAD, decoShape == null ? -1 : decoShape.nativeId); |
| } |
| |
| public DecorationSize getLineHeadWidth(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWWIDTH); |
| return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineHeadWidth(DecorationSize decoSize){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId); |
| } |
| |
| public DecorationSize getLineHeadLength(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWLENGTH); |
| return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineHeadLength(DecorationSize decoSize){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINESTARTARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId); |
| } |
| |
| public DecorationShape getLineTailDecoration(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWHEAD); |
| return (prop == null) ? null : DecorationShape.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineTailDecoration(DecorationShape decoShape){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWHEAD, decoShape == null ? -1 : decoShape.nativeId); |
| } |
| |
| public DecorationSize getLineTailWidth(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWWIDTH); |
| return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineTailWidth(DecorationSize decoSize){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWWIDTH, decoSize == null ? -1 : decoSize.nativeId); |
| } |
| |
| public DecorationSize getLineTailLength(){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| EscherSimpleProperty prop = getEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWLENGTH); |
| return (prop == null) ? null : DecorationSize.fromNativeId(prop.getPropertyValue()); |
| } |
| |
| public void setLineTailLength(DecorationSize decoSize){ |
| AbstractEscherOptRecord opt = getEscherOptRecord(); |
| setEscherProperty(opt, EscherPropertyTypes.LINESTYLE__LINEENDARROWLENGTH, decoSize == null ? -1 : decoSize.nativeId); |
| } |
| |
| |
| |
| @Override |
| public LineDecoration getLineDecoration() { |
| return new LineDecoration() { |
| |
| @Override |
| public DecorationShape getHeadShape() { |
| return HSLFSimpleShape.this.getLineHeadDecoration(); |
| } |
| |
| @Override |
| public DecorationSize getHeadWidth() { |
| return HSLFSimpleShape.this.getLineHeadWidth(); |
| } |
| |
| @Override |
| public DecorationSize getHeadLength() { |
| return HSLFSimpleShape.this.getLineHeadLength(); |
| } |
| |
| @Override |
| public DecorationShape getTailShape() { |
| return HSLFSimpleShape.this.getLineTailDecoration(); |
| } |
| |
| @Override |
| public DecorationSize getTailWidth() { |
| return HSLFSimpleShape.this.getLineTailWidth(); |
| } |
| |
| @Override |
| public DecorationSize getTailLength() { |
| return HSLFSimpleShape.this.getLineTailLength(); |
| } |
| }; |
| } |
| |
| @Override |
| public HSLFShapePlaceholderDetails getPlaceholderDetails() { |
| return new HSLFShapePlaceholderDetails(this); |
| } |
| |
| |
| @Override |
| public Placeholder getPlaceholder() { |
| return getPlaceholderDetails().getPlaceholder(); |
| } |
| |
| @Override |
| public void setPlaceholder(Placeholder placeholder) { |
| getPlaceholderDetails().setPlaceholder(placeholder); |
| } |
| |
| |
| @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 HSLFHyperlink getHyperlink(){ |
| return _hyperlink; |
| } |
| |
| @Override |
| public HSLFHyperlink createHyperlink() { |
| if (_hyperlink == null) { |
| _hyperlink = HSLFHyperlink.createHyperlink(this); |
| } |
| return _hyperlink; |
| } |
| |
| /** |
| * Sets the hyperlink - used when the document is parsed |
| * |
| * @param link the hyperlink |
| */ |
| protected void setHyperlink(HSLFHyperlink link) { |
| _hyperlink = link; |
| } |
| |
| @Override |
| public boolean isPlaceholder() { |
| // currently we only identify TextShapes as placeholders |
| return false; |
| } |
| } |