source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java@ 3896

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

allow a stylesource to override the background color. This may not be the ideal solution yet, but has to do for now.

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.mapcss;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Color;
7import java.io.IOException;
8import java.io.InputStream;
9import java.util.ArrayList;
10import java.util.List;
11import java.util.Map.Entry;
12
13import org.openstreetmap.josm.data.osm.Node;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.gui.mappaint.Cascade;
16import org.openstreetmap.josm.gui.mappaint.Environment;
17import org.openstreetmap.josm.gui.mappaint.MultiCascade;
18import org.openstreetmap.josm.gui.mappaint.Range;
19import org.openstreetmap.josm.gui.mappaint.StyleSource;
20import org.openstreetmap.josm.gui.mappaint.mapcss.parser.MapCSSParser;
21import org.openstreetmap.josm.gui.mappaint.mapcss.parser.ParseException;
22import org.openstreetmap.josm.gui.mappaint.mapcss.parser.TokenMgrError;
23import org.openstreetmap.josm.gui.preferences.SourceEntry;
24import org.openstreetmap.josm.io.MirroredInputStream;
25import org.openstreetmap.josm.tools.LanguageInfo;
26import org.openstreetmap.josm.tools.Utils;
27
28public class MapCSSStyleSource extends StyleSource {
29
30 final public List<MapCSSRule> rules;
31 private Color backgroundColorOverride;
32
33 public MapCSSStyleSource(String url, String name, String shortdescription) {
34 super(url, name, shortdescription);
35 rules = new ArrayList<MapCSSRule>();
36 }
37
38 public MapCSSStyleSource(SourceEntry entry) {
39 super(entry);
40 rules = new ArrayList<MapCSSRule>();
41 }
42
43 @Override
44 public void loadStyleSource() {
45 init();
46 rules.clear();
47 try {
48 MapCSSParser parser = new MapCSSParser(getSourceInputStream(), "UTF-8");
49 parser.sheet(this);
50 loadMeta();
51 loadCanvas();
52 } catch(IOException e) {
53 System.err.println(tr("Warning: failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
54 e.printStackTrace();
55 logError(e);
56 } catch (TokenMgrError e) {
57 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
58 e.printStackTrace();
59 logError(e);
60 } catch (ParseException e) {
61 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
62 e.printStackTrace();
63 logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
64 }
65 }
66
67 public InputStream getSourceInputStream() throws IOException {
68 MirroredInputStream in = new MirroredInputStream(url);
69 InputStream zip = in.getZipEntry("mapcss", "style");
70 if (zip != null) {
71 zipIcons = in.getFile();
72 return zip;
73 } else {
74 zipIcons = null;
75 return in;
76 }
77 }
78
79 /**
80 * load meta info from a selector "meta"
81 */
82 private void loadMeta() {
83 Cascade c = constructSpecial("meta");
84 String pTitle = c.get("title", null, String.class);
85 if (title == null) {
86 title = pTitle;
87 }
88 String pIcon = c.get("icon", null, String.class);
89 if (icon == null) {
90 icon = pIcon;
91 }
92 }
93
94 private void loadCanvas() {
95 Cascade c = constructSpecial("canvas");
96 backgroundColorOverride = c.get("background-color", null, Color.class);
97 }
98
99 private Cascade constructSpecial(String type) {
100
101 MultiCascade mc = new MultiCascade();
102 Node n = new Node();
103 String code = LanguageInfo.getJOSMLocaleCode();
104 n.put("lang", code);
105 // create a fake environment to read the meta data block
106 Environment env = new Environment(n, mc, "default", this);
107
108 NEXT_RULE:
109 for (MapCSSRule r : rules) {
110 for (Selector s : r.selectors) {
111 if (s.base.equals(type)) {
112 for (Condition cnd : s.conds) {
113 if (!cnd.applies(env))
114 continue NEXT_RULE;
115 }
116 for (Instruction i : r.declaration) {
117 i.execute(env);
118 }
119 }
120 }
121 }
122 return mc.getCascade("default");
123 }
124
125 public Color getBackgroundColorOverride() {
126 return backgroundColorOverride;
127 }
128
129 @Override
130 public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
131 Environment env = new Environment(osm, mc, null, this);
132 for (MapCSSRule r : rules) {
133 for (Selector s : r.selectors) {
134 if (s.applies(env)) {
135 if (s.range.contains(scale)) {
136 mc.range = Range.cut(mc.range, s.range);
137 } else {
138 mc.range = mc.range.reduceAround(scale, s.range);
139 continue;
140 }
141
142 String sub = s.subpart;
143 if (sub == null) {
144 sub = "default";
145 }
146
147 if (sub.equals("*")) {
148 for (Entry<String, Cascade> entry : mc.getLayers()) {
149 env.layer = entry.getKey();
150 if (Utils.equal(env.layer, "*")) {
151 continue;
152 }
153 for (Instruction i : r.declaration) {
154 i.execute(env);
155 }
156 }
157 } else {
158 env.layer = sub;
159 for (Instruction i : r.declaration) {
160 i.execute(env);
161 }
162 }
163 }
164 }
165 }
166 }
167
168 @Override
169 public String toString() {
170 return Utils.join("\n", rules);
171 }
172}
Note: See TracBrowser for help on using the repository browser.