001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint; 003 004import org.openstreetmap.josm.data.osm.OsmPrimitive; 005import org.openstreetmap.josm.data.osm.Way; 006import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 007import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer; 008import org.openstreetmap.josm.tools.CheckParameterUtil; 009 010public class RepeatImageElemStyle extends ElemStyle implements StyleKeys { 011 012 public enum LineImageAlignment { TOP, CENTER, BOTTOM } 013 014 public MapImage pattern; 015 public float offset; 016 public float spacing; 017 public float phase; 018 public LineImageAlignment align; 019 020 public RepeatImageElemStyle(Cascade c, MapImage pattern, float offset, float spacing, float phase, LineImageAlignment align) { 021 super(c, 2.9f); 022 CheckParameterUtil.ensureParameterNotNull(pattern); 023 CheckParameterUtil.ensureParameterNotNull(align); 024 this.pattern = pattern; 025 this.offset = offset; 026 this.spacing = spacing; 027 this.phase = phase; 028 this.align = align; 029 } 030 031 public static RepeatImageElemStyle create(Environment env) { 032 MapImage pattern = NodeElemStyle.createIcon(env, REPEAT_IMAGE_KEYS); 033 if (pattern == null) 034 return null; 035 Cascade c = env.mc.getCascade(env.layer); 036 float offset = c.get(REPEAT_IMAGE_OFFSET, 0f, Float.class); 037 float spacing = c.get(REPEAT_IMAGE_SPACING, 0f, Float.class); 038 float phase = - c.get(REPEAT_IMAGE_PHASE, 0f, Float.class); 039 040 LineImageAlignment align = LineImageAlignment.CENTER; 041 Keyword alignKW = c.get(REPEAT_IMAGE_ALIGN, Keyword.CENTER, Keyword.class); 042 if ("top".equals(alignKW.val)) { 043 align = LineImageAlignment.TOP; 044 } else if ("bottom".equals(alignKW.val)) { 045 align = LineImageAlignment.BOTTOM; 046 } 047 048 return new RepeatImageElemStyle(c, pattern, offset, spacing, phase, align); 049 } 050 051 @Override 052 public void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, StyledMapRenderer painter, 053 boolean selected, boolean outermember, boolean member) { 054 Way w = (Way) primitive; 055 painter.drawRepeatImage(w, pattern.getImage(), offset, spacing, phase, align); 056 } 057 058 @Override 059 public boolean isProperLineStyle() { 060 return true; 061 } 062 063 @Override 064 public boolean equals(Object obj) { 065 if (obj == null || getClass() != obj.getClass()) 066 return false; 067 if (!super.equals(obj)) 068 return false; 069 final RepeatImageElemStyle other = (RepeatImageElemStyle) obj; 070 if (!this.pattern.equals(other.pattern)) return false; 071 if (this.offset != other.offset) return false; 072 if (this.spacing != other.spacing) return false; 073 if (this.phase != other.phase) return false; 074 if (this.align != other.align) return false; 075 return true; 076 } 077 078 @Override 079 public int hashCode() { 080 int hash = 7; 081 hash = 83 * hash + this.pattern.hashCode(); 082 hash = 83 * hash + Float.floatToIntBits(this.offset); 083 hash = 83 * hash + Float.floatToIntBits(this.spacing); 084 hash = 83 * hash + Float.floatToIntBits(this.phase); 085 hash = 83 * hash + this.align.hashCode(); 086 return hash; 087 } 088 089 @Override 090 public String toString() { 091 return "RepeatImageStyle{" + super.toString() + "pattern=[" + pattern + 092 "], offset=" + offset + ", spacing=" + spacing + 093 ", phase=" + (-phase) + ", align=" + align + "}"; 094 } 095}