/* * VectorSymbol.java * * Created on 5. Februar 2005, 15:23 */ package ika.geo; import java.awt.*; import java.security.InvalidParameterException; /** * VectorSymbol - graphic attributes for a vector path. Used to draw the vector. * @author Bernhard Jenny, Institute of Cartography, ETH Zurich. */ public class VectorSymbol extends Symbol implements java.io.Serializable, Cloneable { private static final long serialVersionUID = 1756423008209209816L; /** * The color used to draw the interior of a vector path. */ protected Color fillColor = Color.white; /** * The color used to draw the outer border of a vector path. */ protected Color strokeColor = Color.black; /** * The width used to draw the outer border of a vector path. */ protected float strokeWidth = 1; /** * True: the interior of a vector is filled with the fillColor. False: no filling * is drawn. */ protected boolean filled = false; /** * True: the outer border of a vector is drawn with the storkeColor. False: the * outer line is not drawn. */ protected boolean stroked = true; /** * The length of a single dash. Set to 0 or smaller if line should not be dashed. * Unit: pixels. */ protected float dashLength = 0; /** * If scaleInvariant is true, the symbol is independent of the * current scale of the map. */ protected boolean scaleInvariant = false; /** * The end decoration of lines. Possible values: BasicStroke.CAP_BUTT, * BasicStroke.CAP_ROUND, and BasicStroke.CAP_SQUARE */ private int cap = BasicStroke.CAP_SQUARE; /** Creates a new instance of VectorSymbol */ public VectorSymbol() { } /** * Creates a new instance of VectorSymbol * @param fillColor The color used to fill the interior a vector. If null, * the symbol is not filled. * @param strokeColor The color used to stroke the outter border of a vector. * If null, the symbol is not stroked. * @param strokeWidth The width of the stroke that is used to draw the * border of a vector path. The smallest possible value is 0, which is the * thinnest line that can be drawn. If strokeWidth is 0, the new * VectorSymbol is scale invariant. */ public VectorSymbol(Color fillColor, Color strokeColor, float strokeWidth) { this.fillColor = fillColor == null ? Color.WHITE : fillColor; this.filled = fillColor != null; this.strokeColor = strokeColor == null ? Color.BLACK : strokeColor ; this.stroked = strokeColor != null; if (strokeWidth < 0.f) { strokeWidth = 0.f; } this.strokeWidth = strokeWidth; this.setScaleInvariant(strokeWidth == 0.f); } @Override public VectorSymbol clone() { VectorSymbol copy = new VectorSymbol(); this.copyTo(copy); return copy; } public void copyTo(VectorSymbol dest) { dest.fillColor = this.fillColor; dest.strokeColor = this.strokeColor; dest.strokeWidth = this.strokeWidth; dest.filled = this.filled; dest.stroked = this.stroked; dest.dashLength = this.dashLength; dest.scaleInvariant = this.scaleInvariant; dest.cap = this.cap; } public boolean equals(VectorSymbol vectorSymbol) { if (this == vectorSymbol) { return true; } return vectorSymbol.fillColor.equals(this.fillColor) && vectorSymbol.strokeColor.equals(this.strokeColor) && vectorSymbol.strokeWidth == this.strokeWidth && vectorSymbol.filled == this.filled && vectorSymbol.stroked == this.stroked && vectorSymbol.dashLength == this.dashLength && vectorSymbol.scaleInvariant == this.scaleInvariant && vectorSymbol.cap == this.cap; } /** * */ public Color getFillColor() { return this.fillColor; } public void setFillColor(Color fillColor) { this.fillColor = fillColor; } /** * alpha 0: completely transparent; 255: completely opaque. */ public int getFillTransparency() { if (this.fillColor == null) { return 255; } return this.fillColor.getAlpha(); } /** * Important: This method will generate a new internal Color object. Any * reference obtained by getFillColor will no longer be valid! * If fillColor is null, the passed alpha value will not be retained. * @param alpha 0: completely transparent; 255: completely opaque. */ public void setFillTransparancy(int alpha) { this.fillColor = ika.utils.ColorUtils.transparentColor(this.fillColor, alpha); } /** * Returns true if the fill color is partially transparent. */ public boolean isFillTransparent() { if (this.fillColor == null) { return false; } return this.fillColor.getAlpha() < 255; } public Color getStrokeColor() { return this.strokeColor; } public void setStrokeColor(Color strokeColor) { this.strokeColor = strokeColor; } public float getStrokeWidth() { return strokeWidth; } public final float getScaledStrokeWidth(double scale) { float w = scaleInvariant ? strokeWidth : (float)(strokeWidth * scale); return w < 0f ? 0f : w; } public void setStrokeWidth(float strokeWidth) { this.strokeWidth = strokeWidth; } public boolean isFilled() { return this.filled; } public void setFilled(boolean filled) { this.filled = filled; } public boolean isStroked() { return stroked; } public void setStroked(boolean stroked) { this.stroked = stroked; } public boolean isDashed() { return this.getDashLength() > 0; } public float getDashLength() { return dashLength; } public final float getScaledDashLength(double scale) { return scaleInvariant ? (float)(dashLength * scale) : dashLength; } public void setDashLength(float dashLength) { this.dashLength = dashLength; } public boolean isScaleInvariant() { return scaleInvariant; } public void setScaleInvariant(boolean scaleInvariant) { this.scaleInvariant = scaleInvariant; } public int getCap() { return cap; } public void setCap(int cap) { if (cap == BasicStroke.CAP_BUTT || cap == BasicStroke.CAP_ROUND || cap == BasicStroke.CAP_SQUARE) { this.cap = cap; } else { throw new InvalidParameterException("invalid line cap"); } } /** * Returns a Stroke for drawing in a Graphics2D using g2d.setStroke(). * @param scale The scale of the map. Used for computing the stroke width and dash * length when this symbol is scale invariant. * @return A Stroke that can be used to draw into Graphics2d. */ public final Stroke getStroke(double scale) { final float scaledStrokeWidth = getScaledStrokeWidth(scale); BasicStroke stroke; if (dashLength <= 0f) { stroke = new BasicStroke(scaledStrokeWidth, this.cap, BasicStroke.JOIN_MITER); } else { float scaledDashLength = getScaledDashLength(scale); stroke = new BasicStroke(scaledStrokeWidth, this.cap, BasicStroke.JOIN_BEVEL, 0, new float[] {scaledDashLength, scaledDashLength}, 0); } return stroke; } @Override public String toString() { StringBuilder str = new StringBuilder(); String nl = System.getProperty("line.separator"); str.append("Fill: ").append(this.filled).append(" color: ").append(this.fillColor); str.append(nl); str.append("Stroke: ").append(this.stroked).append(" color: ").append(this.strokeColor); str.append(" width: ").append(this.strokeWidth); str.append(" dash length: ").append(this.dashLength); str.append(nl); str.append("Scale invariant: ").append(this.scaleInvariant); return str.toString(); } }