source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java@ 4040

Last change on this file since 4040 was 4040, checked in by bastiK, 13 years ago

fixed #6210 - Selected a way rendered on top of unselected nodes

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import static org.openstreetmap.josm.tools.Utils.equal;
5
6import java.awt.Font;
7import java.util.HashMap;
8import java.util.Map;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.osm.OsmPrimitive;
12import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings;
13import org.openstreetmap.josm.data.osm.visitor.paint.MapPainter;
14import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.RelativeFloat;
15
16abstract public class ElemStyle {
17
18 public float z_index;
19 public float object_z_index;
20 public boolean isModifier; // false, if style can serve as main style for the
21 // primitive; true, if it is a highlight or modifier
22
23 public ElemStyle(float z_index, float object_z_index, boolean isModifier) {
24 this.z_index = z_index;
25 this.object_z_index = object_z_index;
26 this.isModifier = isModifier;
27 }
28
29 protected ElemStyle(Cascade c, float default_z_index) {
30 z_index = c.get("z-index", default_z_index, Float.class);
31 object_z_index = c.get("object-z-index", 0f, Float.class);
32 isModifier = c.get("modifier", false, Boolean.class);
33 }
34
35 /**
36 * draws a primitive
37 * @param primitive
38 * @param paintSettings
39 * @param painter
40 * @param selected true, if primitive is selected
41 * @param member true, if primitive is not selected and member of a selected relation
42 */
43 public abstract void paintPrimitive(OsmPrimitive primitive, MapPaintSettings paintSettings, MapPainter painter, boolean selected, boolean member);
44
45 public boolean isProperLineStyle() {
46 return false;
47 }
48
49 /**
50 * Get a property value of type Width
51 * @param c the cascade
52 * @param key property key for the width value
53 * @param relativeTo reference width. Only needed, when relative width syntax
54 * is used, e.g. "+4".
55 */
56 protected static Float getWidth(Cascade c, String key, Float relativeTo) {
57 Float width = c.get(key, null, Float.class, true);
58 if (width != null) {
59 if (width > 0)
60 return width;
61 } else {
62 Keyword widthKW = c.get(key, null, Keyword.class, true);
63 if (equal(widthKW, Keyword.THINNEST))
64 return 0f;
65 if (equal(widthKW, Keyword.DEFAULT))
66 return (float) MapPaintSettings.INSTANCE.getDefaultSegmentWidth();
67 if (relativeTo != null) {
68 RelativeFloat width_rel = c.get(key, null, RelativeFloat.class, true);
69 if (width_rel != null)
70 return relativeTo + width_rel.val;
71 }
72 }
73 return null;
74 }
75
76 /* ------------------------------------------------------------------------------- */
77 /* cached values */
78 /* ------------------------------------------------------------------------------- */
79 /*
80 * Two preference values and the set of created fonts are cached in order to avoid
81 * expensive lookups and to avoid too many font objects
82 * (in analogy to flyweight pattern).
83 *
84 * FIXME: cached preference values are not updated if the user changes them during
85 * a JOSM session. Should have a listener listening to preference changes.
86 */
87 static private String DEFAULT_FONT_NAME = null;
88 static private Float DEFAULT_FONT_SIZE = null;
89 static private void initDefaultFontParameters() {
90 if (DEFAULT_FONT_NAME != null) return; // already initialized - skip initialization
91 DEFAULT_FONT_NAME = Main.pref.get("mappaint.font", "Helvetica");
92 DEFAULT_FONT_SIZE = (float) Main.pref.getInteger("mappaint.fontsize", 8);
93 }
94
95 static private class FontDescriptor {
96 public String name;
97 public int style;
98 public int size;
99
100 public FontDescriptor(String name, int style, int size){
101 this.name = name;
102 this.style = style;
103 this.size = size;
104 }
105
106 @Override
107 public int hashCode() {
108 final int prime = 31;
109 int result = 1;
110 result = prime * result + ((name == null) ? 0 : name.hashCode());
111 result = prime * result + size;
112 result = prime * result + style;
113 return result;
114 }
115 @Override
116 public boolean equals(Object obj) {
117 if (this == obj)
118 return true;
119 if (obj == null)
120 return false;
121 if (getClass() != obj.getClass())
122 return false;
123 FontDescriptor other = (FontDescriptor) obj;
124 if (name == null) {
125 if (other.name != null)
126 return false;
127 } else if (!name.equals(other.name))
128 return false;
129 if (size != other.size)
130 return false;
131 if (style != other.style)
132 return false;
133 return true;
134 }
135 }
136
137 static private final Map<FontDescriptor, Font> FONT_MAP = new HashMap<FontDescriptor, Font>();
138 static private Font getCachedFont(FontDescriptor fd) {
139 Font f = FONT_MAP.get(fd);
140 if (f != null) return f;
141 f = new Font(fd.name, fd.style, fd.size);
142 FONT_MAP.put(fd, f);
143 return f;
144 }
145
146 static private Font getCachedFont(String name, int style, int size){
147 return getCachedFont(new FontDescriptor(name, style, size));
148 }
149
150 protected static Font getFont(Cascade c) {
151 initDefaultFontParameters(); // populated cached preferences, if necesary
152 String name = c.get("font-family", DEFAULT_FONT_NAME, String.class);
153 float size = c.get("font-size", DEFAULT_FONT_SIZE, Float.class);
154 int weight = Font.PLAIN;
155 Keyword weightKW = c.get("font-weight", null, Keyword.class);
156 if (weightKW != null && equal(weightKW, "bold")) {
157 weight = Font.BOLD;
158 }
159 int style = Font.PLAIN;
160 Keyword styleKW = c.get("font-style", null, Keyword.class);
161 if (styleKW != null && equal(styleKW.val, "italic")) {
162 style = Font.ITALIC;
163 }
164 return getCachedFont(name, style | weight, Math.round(size));
165 }
166
167 @Override
168 public boolean equals(Object o) {
169 if (!(o instanceof ElemStyle))
170 return false;
171 ElemStyle s = (ElemStyle) o;
172 return z_index == s.z_index && object_z_index == s.object_z_index && isModifier == s.isModifier;
173 }
174
175 @Override
176 public int hashCode() {
177 int hash = 5;
178 hash = 41 * hash + Float.floatToIntBits(this.z_index);
179 hash = 41 * hash + Float.floatToIntBits(this.object_z_index);
180 hash = 41 * hash + (isModifier ? 1 : 0);
181 return hash;
182 }
183
184 @Override
185 public String toString() {
186 if (z_index != 0f || object_z_index != 0f)
187 return String.format("z_idx=%s/%s ", z_index, object_z_index) + (isModifier ? "modifier " : "");
188 return "";
189 }
190}
Note: See TracBrowser for help on using the repository browser.