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

Last change on this file since 4191 was 4191, checked in by stoecker, 13 years ago

remove old debug stuff

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