Permalink
Browse files

Render theme rules traversal & callback, closes #912

  • Loading branch information...
1 parent 5edd23e commit 0c469a968e65a2b1a2a8250ae787e1435ee4c44d @devemux86 devemux86 committed Dec 19, 2016
@@ -17,6 +17,7 @@
import org.mapsforge.core.graphics.Filter;
import org.mapsforge.map.model.common.Observable;
+import org.mapsforge.map.rendertheme.ThemeCallback;
/**
* Encapsulates the display characteristics for a MapView, such as tile size and background color. The size of map tiles
@@ -77,6 +78,7 @@ public static synchronized void setDeviceScaleFactor(float scaleFactor) {
private int fixedTileSize;
private int maxTextWidth = DEFAULT_MAX_TEXT_WIDTH;
private float maxTextWidthFactor = DEFAULT_MAX_TEXT_WIDTH_FACTOR;
+ private ThemeCallback themeCallback;
private int tileSize = DEFAULT_TILE_SIZE;
private int tileSizeMultiple = 64;
private float userScaleFactor = defaultUserScaleFactor;
@@ -147,6 +149,13 @@ public synchronized float getScaleFactor() {
}
/**
+ * Theme callback.
+ */
+ public synchronized ThemeCallback getThemeCallback() {
+ return this.themeCallback;
+ }
+
+ /**
* Width and height of a map tile in pixel after system and user scaling is applied.
*/
public synchronized int getTileSize() {
@@ -221,6 +230,13 @@ public void setMaxTextWidthFactor(float maxTextWidthFactor) {
}
/**
+ * Theme callback.
+ */
+ public synchronized void setThemeCallback(ThemeCallback themeCallback) {
+ this.themeCallback = themeCallback;
+ }
+
+ /**
* Clamps the tile size to a multiple of the supplied value.
* <p/>
* The default value of tileSizeMultiple will be overwritten with this call.
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 devemux86
+ *
+ * This program is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.mapsforge.map.rendertheme;
+
+/**
+ * Callback methods for render theme.
+ */
+public interface ThemeCallback {
+ /**
+ * @return the color-int
+ */
+ int getColor(int color);
+}
@@ -95,12 +95,19 @@ public static XmlPullParserException createXmlPullParserException(String element
* Supported formats are {@code #RRGGBB} and {@code #AARRGGBB}.
*/
public static int getColor(GraphicFactory graphicFactory, String colorString) {
+ return getColor(graphicFactory, colorString, null);
+ }
+
+ /**
+ * Supported formats are {@code #RRGGBB} and {@code #AARRGGBB}.
+ */
+ public static int getColor(GraphicFactory graphicFactory, String colorString, ThemeCallback themeCallback) {
if (colorString.isEmpty() || colorString.charAt(0) != '#') {
throw new IllegalArgumentException(UNSUPPORTED_COLOR_FORMAT + colorString);
} else if (colorString.length() == 7) {
- return getColor(graphicFactory, colorString, 255, 1);
+ return getColor(graphicFactory, colorString, 255, 1, themeCallback);
} else if (colorString.length() == 9) {
- return getColor(graphicFactory, colorString, Integer.parseInt(colorString.substring(1, 3), 16), 3);
+ return getColor(graphicFactory, colorString, Integer.parseInt(colorString.substring(1, 3), 16), 3, themeCallback);
} else {
throw new IllegalArgumentException(UNSUPPORTED_COLOR_FORMAT + colorString);
}
@@ -221,12 +228,16 @@ private static String getAbsoluteName(String relativePathPrefix, String name) {
return relativePathPrefix + name;
}
- private static int getColor(GraphicFactory graphicFactory, String colorString, int alpha, int rgbStartIndex) {
+ private static int getColor(GraphicFactory graphicFactory, String colorString, int alpha, int rgbStartIndex, ThemeCallback themeCallback) {
int red = Integer.parseInt(colorString.substring(rgbStartIndex, rgbStartIndex + 2), 16);
int green = Integer.parseInt(colorString.substring(rgbStartIndex + 2, rgbStartIndex + 4), 16);
int blue = Integer.parseInt(colorString.substring(rgbStartIndex + 4, rgbStartIndex + 6), 16);
- return graphicFactory.createColor(alpha, red, green, blue);
+ int color = graphicFactory.createColor(alpha, red, green, blue);
+ if (themeCallback != null) {
+ color = themeCallback.getColor(color);
+ }
+ return color;
}
private static File getFile(String parentPath, String pathName) {
@@ -88,11 +88,11 @@ private void extractValues(String elementName,
} else if (CAT.equals(name)) {
this.category = value;
} else if (FILL.equals(name)) {
- this.fill.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.fill.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (SCALE.equals(name)) {
this.scale = scaleFromValue(value);
} else if (STROKE.equals(name)) {
- this.stroke.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.stroke.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (STROKE_WIDTH.equals(name)) {
this.strokeWidth = XmlUtils.parseNonNegativeFloat(name, value) * displayModel.getScaleFactor();
} else if (SYMBOL_HEIGHT.equals(name)) {
@@ -182,7 +182,7 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (DY.equals(name)) {
this.dy = Float.parseFloat(value) * displayModel.getScaleFactor();
} else if (FILL.equals(name)) {
- this.fill.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.fill.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (FONT_FAMILY.equals(name)) {
fontFamily = FontFamily.fromString(value);
} else if (FONT_SIZE.equals(name)) {
@@ -194,7 +194,7 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (PRIORITY.equals(name)) {
this.priority = Integer.parseInt(value);
} else if (STROKE.equals(name)) {
- this.stroke.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.stroke.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (STROKE_WIDTH.equals(name)) {
this.stroke.setStrokeWidth(XmlUtils.parseNonNegativeFloat(name, value) * displayModel.getScaleFactor());
} else if (SYMBOL_ID.equals(name)) {
@@ -87,11 +87,11 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (CAT.equals(name)) {
this.category = value;
} else if (FILL.equals(name)) {
- this.fill.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.fill.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (SCALE_RADIUS.equals(name)) {
this.scaleRadius = Boolean.parseBoolean(value);
} else if (STROKE.equals(name)) {
- this.stroke.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.stroke.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (STROKE_WIDTH.equals(name)) {
this.strokeWidth = XmlUtils.parseNonNegativeFloat(name, value) * displayModel.getScaleFactor();
} else {
@@ -93,7 +93,7 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (SCALE.equals(name)) {
this.scale = scaleFromValue(value);
} else if (STROKE.equals(name)) {
- this.stroke.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.stroke.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (STROKE_DASHARRAY.equals(name)) {
this.strokeDasharray = parseFloatArray(name, value);
for (int f = 0; f < this.strokeDasharray.length; ++f) {
@@ -107,7 +107,7 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (DY.equals(name)) {
this.dy = Float.parseFloat(value) * displayModel.getScaleFactor();
} else if (FILL.equals(name)) {
- this.fill.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.fill.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (FONT_FAMILY.equals(name)) {
fontFamily = FontFamily.fromString(value);
} else if (FONT_SIZE.equals(name)) {
@@ -127,7 +127,7 @@ private void extractValues(GraphicFactory graphicFactory, DisplayModel displayMo
} else if (SCALE.equals(name)) {
this.scale = scaleFromValue(value);
} else if (STROKE.equals(name)) {
- this.stroke.setColor(XmlUtils.getColor(graphicFactory, value));
+ this.stroke.setColor(XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback()));
} else if (STROKE_WIDTH.equals(name)) {
this.stroke.setStrokeWidth(XmlUtils.parseNonNegativeFloat(name, value) * displayModel.getScaleFactor());
} else {
@@ -1,6 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2015 Ludwig M Brinckmann
+ * Copyright 2016 devemux86
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
@@ -217,4 +218,10 @@ private synchronized void matchWay(RenderCallback renderCallback, final RenderCo
this.wayMatchingCache.put(matchingCacheKey, matchingList);
}
+
+ public void traverseRules(Rule.RuleVisitor visitor) {
+ for (Rule rule : this.rulesList) {
+ rule.apply(visitor);
+ }
+ }
}
@@ -18,6 +18,7 @@
import org.mapsforge.core.graphics.Color;
import org.mapsforge.core.graphics.GraphicFactory;
+import org.mapsforge.map.model.DisplayModel;
import org.mapsforge.map.rendertheme.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -39,13 +40,15 @@
float baseStrokeWidth;
float baseTextSize;
+ private final DisplayModel displayModel;
boolean hasBackgroundOutside;
int mapBackground;
int mapBackgroundOutside;
private Integer version;
- public RenderThemeBuilder(GraphicFactory graphicFactory, String elementName, XmlPullParser pullParser)
+ public RenderThemeBuilder(GraphicFactory graphicFactory, DisplayModel displayModel, String elementName, XmlPullParser pullParser)
throws XmlPullParserException {
+ this.displayModel = displayModel;
this.baseStrokeWidth = 1f;
this.baseTextSize = 1f;
this.mapBackground = graphicFactory.createColor(Color.WHITE);
@@ -75,9 +78,9 @@ private void extractValues(GraphicFactory graphicFactory, String elementName, Xm
} else if (VERSION.equals(name)) {
this.version = Integer.valueOf(XmlUtils.parseNonNegativeInteger(name, value));
} else if (MAP_BACKGROUND.equals(name)) {
- this.mapBackground = XmlUtils.getColor(graphicFactory, value);
+ this.mapBackground = XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback());
} else if (MAP_BACKGROUND_OUTSIDE.equals(name)) {
- this.mapBackgroundOutside = XmlUtils.getColor(graphicFactory, value);
+ this.mapBackgroundOutside = XmlUtils.getColor(graphicFactory, value, displayModel.getThemeCallback());
this.hasBackgroundOutside = true;
} else if (BASE_STROKE_WIDTH.equals(name)) {
this.baseStrokeWidth = XmlUtils.parseNonNegativeFloat(name, value);
@@ -159,7 +159,7 @@ private void startElement() throws XmlPullParserException {
try {
if ("rendertheme".equals(qName)) {
checkState(qName, Element.RENDER_THEME);
- this.renderTheme = new RenderThemeBuilder(this.graphicFactory, qName, pullParser).build();
+ this.renderTheme = new RenderThemeBuilder(this.graphicFactory, this.displayModel, qName, pullParser).build();
} else if (ELEMENT_NAME_RULE.equals(qName)) {
checkState(qName, Element.RULE);
Rule rule = new RuleBuilder(qName, pullParser, this.ruleStack).build();
@@ -1,6 +1,7 @@
/*
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
* Copyright 2014-2015 Ludwig M Brinckmann
+ * Copyright 2016 devemux86
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
@@ -28,18 +29,26 @@
import java.util.List;
import java.util.Map;
-abstract class Rule {
+public abstract class Rule {
static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_KEY = new HashMap<List<String>, AttributeMatcher>();
static final Map<List<String>, AttributeMatcher> MATCHERS_CACHE_VALUE = new HashMap<List<String>, AttributeMatcher>();
+ public static class RuleVisitor {
+ public void apply(Rule r) {
+ for (Rule subRule : r.subRules) {
+ this.apply(subRule);
+ }
+ }
+ }
+
String cat;
final ClosedMatcher closedMatcher;
final ElementMatcher elementMatcher;
final byte zoomMax;
final byte zoomMin;
- private final ArrayList<RenderInstruction> renderInstructions; // NOSONAR NOPMD we need specific interface
- private final ArrayList<Rule> subRules; // NOSONAR NOPMD we need specific interface
+ public final ArrayList<RenderInstruction> renderInstructions; // NOSONAR NOPMD we need specific interface
+ public final ArrayList<Rule> subRules; // NOSONAR NOPMD we need specific interface
Rule(RuleBuilder ruleBuilder) {
this.cat = ruleBuilder.cat;
@@ -60,6 +69,10 @@ void addSubRule(Rule rule) {
this.subRules.add(rule);
}
+ void apply(RuleVisitor v) {
+ v.apply(this);
+ }
+
void destroy() {
for (RenderInstruction ri : this.renderInstructions) {
ri.destroy();

0 comments on commit 0c469a9

Please sign in to comment.