001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.mappaint.styleelement;
003
004import java.awt.Color;
005import java.awt.Shape;
006import java.awt.Stroke;
007import java.util.Objects;
008
009import org.openstreetmap.josm.gui.draw.SymbolShape;
010
011/**
012 * The definition of a symbol that should be rendered at the node position.
013 * @since 10827 Extracted from {@link NodeElement}
014 */
015public class Symbol {
016    private final SymbolShape symbolShape;
017    /**
018     * The width and height of this symbol
019     */
020    public final int size;
021    /**
022     * The stroke to use for the outline
023     */
024    public final Stroke stroke;
025    /**
026     * The color to draw the stroke with
027     */
028    public final Color strokeColor;
029    /**
030     * The color to fill the interior of the shape.
031     */
032    public final Color fillColor;
033
034    /**
035     * Create a new symbol
036     * @param symbol The symbol type
037     * @param size The overall size of the symbol, both width and height are the same
038     * @param stroke The stroke to use for the outline
039     * @param strokeColor The color to draw the stroke with
040     * @param fillColor The color to fill the interior of the shape.
041     */
042    public Symbol(SymbolShape symbol, int size, Stroke stroke, Color strokeColor, Color fillColor) {
043        if (stroke != null && strokeColor == null)
044            throw new IllegalArgumentException("Stroke given without color");
045        if (stroke == null && fillColor == null)
046            throw new IllegalArgumentException("Either a stroke or a fill color must be given");
047        this.symbolShape = symbol;
048        this.size = size;
049        this.stroke = stroke;
050        this.strokeColor = strokeColor;
051        this.fillColor = fillColor;
052    }
053
054    @Override
055    public boolean equals(Object obj) {
056        if (obj == null || getClass() != obj.getClass())
057            return false;
058        final Symbol other = (Symbol) obj;
059        return symbolShape == other.symbolShape &&
060                size == other.size &&
061                Objects.equals(stroke, other.stroke) &&
062                Objects.equals(strokeColor, other.strokeColor) &&
063                Objects.equals(fillColor, other.fillColor);
064    }
065
066    @Override
067    public int hashCode() {
068        return Objects.hash(symbolShape, size, stroke, strokeColor, fillColor);
069    }
070
071    @Override
072    public String toString() {
073        return "symbolShape=" + symbolShape + " size=" + size +
074                (stroke != null ? (" stroke=" + stroke + " strokeColor=" + strokeColor) : "") +
075                (fillColor != null ? (" fillColor=" + fillColor) : "");
076    }
077
078    /**
079     * Builds the shape for this symbol
080     * @param x The center x coordinate
081     * @param y The center y coordinate
082     * @return The symbol shape.
083     */
084    public Shape buildShapeAround(double x, double y) {
085        return symbolShape.shapeAround(x, y, size);
086    }
087}