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

Last change on this file since 5217 was 5217, checked in by bastiK, 12 years ago

mapcss: change z-index handling

In contrast to previous default z-index of 1000 for nodes and -1000 for areas, the default z-index is
now always 0. An additional "major-z-index" is used to sort elemstyles by category, this property
can be adjusted in the style, so icons can be rendered below lines, if you want to.

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