001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint; 003 004import java.awt.Color; 005import java.util.Objects; 006 007import org.openstreetmap.josm.Main; 008import org.openstreetmap.josm.data.osm.OsmPrimitive; 009import org.openstreetmap.josm.data.osm.Relation; 010import org.openstreetmap.josm.data.osm.Way; 011import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 012import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 013import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer; 014import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference; 015import org.openstreetmap.josm.tools.CheckParameterUtil; 016import org.openstreetmap.josm.tools.Utils; 017 018public class AreaElemStyle extends ElemStyle { 019 020 /** 021 * If fillImage == null, color is the fill-color, otherwise 022 * an arbitrary color value sampled from the fillImage 023 */ 024 public Color color; 025 public MapImage fillImage; 026 public TextElement text; 027 public Float extent; 028 029 protected AreaElemStyle(Cascade c, Color color, MapImage fillImage, Float extent, TextElement text) { 030 super(c, 1f); 031 CheckParameterUtil.ensureParameterNotNull(color); 032 this.color = color; 033 this.extent = extent; 034 this.fillImage = fillImage; 035 this.text = text; 036 } 037 038 public static AreaElemStyle create(final Environment env) { 039 final Cascade c = env.mc.getCascade(env.layer); 040 MapImage fillImage = null; 041 Color color = null; 042 Float extent = null; 043 044 IconReference iconRef = c.get(FILL_IMAGE, null, IconReference.class); 045 if (iconRef != null) { 046 fillImage = new MapImage(iconRef.iconName, iconRef.source, false); 047 048 color = new Color(fillImage.getImage(false).getRGB( 049 fillImage.getWidth() / 2, fillImage.getHeight() / 2) 050 ); 051 052 fillImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fill-image-alpha", 255)))); 053 Integer pAlpha = Utils.color_float2int(c.get(FILL_OPACITY, null, float.class)); 054 if (pAlpha != null) { 055 fillImage.alpha = pAlpha; 056 } 057 } else { 058 color = c.get(FILL_COLOR, null, Color.class); 059 if (color != null) { 060 int alpha = color.getAlpha(); 061 if (alpha == 255) { 062 // Assume alpha value has not been specified by the user if 063 // is set to fully opaque. Use default value in this case. 064 // It is not an ideal solution, but a little tricky to get this 065 // right, especially as named map colors can be changed in 066 // the preference GUI and written to the preferences file. 067 alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50)))); 068 } 069 Integer pAlpha = Utils.color_float2int(c.get(FILL_OPACITY, null, float.class)); 070 if (pAlpha != null) { 071 alpha = pAlpha; 072 } 073 color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha); 074 } 075 } 076 077 TextElement text = null; 078 Keyword textPos = c.get(TEXT_POSITION, null, Keyword.class); 079 if (textPos == null || "center".equals(textPos.val)) { 080 text = TextElement.create(env, PaintColors.AREA_TEXT.get(), true); 081 } 082 083 extent = c.get(FILL_EXTENT, null, float.class); 084 085 if (color != null) 086 return new AreaElemStyle(c, color, fillImage, extent, text); 087 else 088 return null; 089 } 090 091 @Override 092 public void paintPrimitive(OsmPrimitive osm, MapPaintSettings paintSettings, StyledMapRenderer painter, 093 boolean selected, boolean outermember, boolean member) { 094 Color myColor = color; 095 if (osm instanceof Way) { 096 if (color != null) { 097 if (selected) { 098 myColor = paintSettings.getSelectedColor(color.getAlpha()); 099 } else if (outermember) { 100 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 101 } 102 } 103 painter.drawArea((Way) osm, myColor, fillImage, extent, painter.isInactiveMode() || osm.isDisabled(), text); 104 } else if (osm instanceof Relation) { 105 if (color != null && (selected || outermember)) { 106 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 107 } 108 painter.drawArea((Relation) osm, myColor, fillImage, extent, painter.isInactiveMode() || osm.isDisabled(), text); 109 } 110 } 111 112 @Override 113 public boolean equals(Object obj) { 114 if (obj == null || getClass() != obj.getClass()) 115 return false; 116 if (!super.equals(obj)) 117 return false; 118 AreaElemStyle other = (AreaElemStyle) obj; 119 // we should get the same image object due to caching 120 if (!Objects.equals(fillImage, other.fillImage)) 121 return false; 122 if (!Objects.equals(color, other.color)) 123 return false; 124 if (extent != other.extent) 125 return false; 126 if (!Objects.equals(text, other.text)) 127 return false; 128 return true; 129 } 130 131 @Override 132 public int hashCode() { 133 int hash = 3; 134 hash = 61 * hash + color.hashCode(); 135 hash = 61 * hash + (extent != null ? Float.floatToIntBits(extent) : 0); 136 hash = 61 * hash + (fillImage != null ? fillImage.hashCode() : 0); 137 hash = 61 * hash + (text != null ? text.hashCode() : 0); 138 return hash; 139 } 140 141 @Override 142 public String toString() { 143 return "AreaElemStyle{" + super.toString() + "color=" + Utils.toString(color) + 144 " fillImage=[" + fillImage + "]}"; 145 } 146}