diff --git a/docs/Changelog.md b/docs/Changelog.md
index fac7570f..7d126fe7 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -2,6 +2,7 @@
## New since 0.8.0
+- Mapsforge themes compatibility [#100](https://github.com/mapsforge/vtm/issues/100)
- vtm-theme-comparator module [#387](https://github.com/mapsforge/vtm/issues/387)
- Many other minor improvements and bug fixes
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.9.0)
diff --git a/vtm-android-example/res/menu/theme_menu.xml b/vtm-android-example/res/menu/theme_menu.xml
index 319b5428..7a93959d 100644
--- a/vtm-android-example/res/menu/theme_menu.xml
+++ b/vtm-android-example/res/menu/theme_menu.xml
@@ -21,8 +21,8 @@
android:id="@+id/theme_newtron"
android:title="@string/theme_newtron" />
+ android:id="@+id/theme_external"
+ android:title="@string/theme_external" />
- Osmagray
Tubes
NewTron
+ External theme
OK
Cancel
Error
@@ -17,6 +18,5 @@
Show nature
Hide nature
Grid
- load theme extern
diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
index ca88d0c4..87df685e 100644
--- a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
+++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java
@@ -43,11 +43,10 @@ public final class ValidRenderTheme implements ValidFileFilter {
try {
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
DefaultHandler renderThemeHandler;
- if(ThemeUtils.isMapsforgeTheme(new FileInputStream(file))) {
+ if (ThemeUtils.isMapsforgeTheme(new FileInputStream(file)))
renderThemeHandler = new XmlMapsforgeThemeBuilder(theme);
- }else{
+ else
renderThemeHandler = new XmlThemeBuilder(theme);
- }
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xmlReader.setContentHandler(renderThemeHandler);
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
diff --git a/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
index 74a4c458..b4e44ae5 100644
--- a/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java
@@ -51,6 +51,7 @@ public class MapsforgeMapActivity extends MapActivity {
private TileGridLayer mGridLayer;
private DefaultMapScaleBar mMapScaleBar;
+ private Menu mMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -85,6 +86,7 @@ public class MapsforgeMapActivity extends MapActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.theme_menu, menu);
+ mMenu = menu;
return true;
}
@@ -117,8 +119,8 @@ public class MapsforgeMapActivity extends MapActivity {
item.setChecked(true);
return true;
- case R.id.theme_load:
- startActivityForResult(new Intent(MapsforgeMapActivity.this, ThemeFilePicker.class),
+ case R.id.theme_external:
+ startActivityForResult(new Intent(this, ThemeFilePicker.class),
SELECT_THEME_FILE);
return true;
@@ -181,18 +183,13 @@ public class MapsforgeMapActivity extends MapActivity {
}
} else if (requestCode == SELECT_THEME_FILE) {
if (resultCode != RESULT_OK || intent == null || intent.getStringExtra(FilePicker.SELECTED_FILE) == null) {
- finish();
return;
}
- String themePath = intent.getStringExtra(FilePicker.SELECTED_FILE);
-
- ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(themePath);
- try {
- mMap.setTheme(externalRenderTheme, true);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ String file = intent.getStringExtra(FilePicker.SELECTED_FILE);
+ ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(file);
+ mMap.setTheme(externalRenderTheme);
+ mMenu.findItem(R.id.theme_external).setChecked(true);
}
}
diff --git a/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java b/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java
index 2151233a..78392b21 100644
--- a/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java
+++ b/vtm-android/src/org/oscim/android/canvas/AndroidCanvas.java
@@ -88,6 +88,14 @@ public class AndroidCanvas implements Canvas {
canvas.drawColor(color, color == Color.TRANSPARENT ? PorterDuff.Mode.CLEAR : PorterDuff.Mode.SRC_OVER);
}
+ @Override
+ public void fillRectangle(float x, float y, float width, float height, int color) {
+ RectF rect = new RectF(x, y, x + width, y + height);
+ android.graphics.Paint paint = new android.graphics.Paint();
+ paint.setColor(color);
+ canvas.drawRect(rect, paint);
+ }
+
@Override
public int getHeight() {
return canvas.getHeight();
@@ -97,12 +105,4 @@ public class AndroidCanvas implements Canvas {
public int getWidth() {
return canvas.getWidth();
}
-
- @Override
- public void fillRectangle(int x, int y, int width, int height, int color) {
- RectF rec = new RectF(x, y, x + width, y + height);
- android.graphics.Paint paint = new android.graphics.Paint();
- paint.setColor(color);
- canvas.drawRect(rec, paint);
- }
}
diff --git a/vtm-desktop/src/org/oscim/awt/AwtCanvas.java b/vtm-desktop/src/org/oscim/awt/AwtCanvas.java
index 57502a9a..a00aec32 100644
--- a/vtm-desktop/src/org/oscim/awt/AwtCanvas.java
+++ b/vtm-desktop/src/org/oscim/awt/AwtCanvas.java
@@ -186,6 +186,16 @@ public class AwtCanvas implements Canvas {
fillRectangle(0, 0, getWidth(), getHeight(), color);
}
+ @Override
+ public void fillRectangle(float x, float y, float width, float height, int color) {
+ java.awt.Color awtColor = color == Color.TRANSPARENT ? TRANSPARENT : new java.awt.Color(color);
+ Composite originalComposite = this.canvas.getComposite();
+ this.canvas.setComposite(AlphaComposite.getInstance(color == Color.TRANSPARENT ? AlphaComposite.CLEAR : AlphaComposite.SRC_OVER));
+ this.canvas.setColor(awtColor);
+ this.canvas.fillRect((int) x, (int) y, (int) width, (int) height);
+ this.canvas.setComposite(originalComposite);
+ }
+
@Override
public int getHeight() {
return this.bitmap != null ? this.bitmap.getHeight() : 0;
@@ -195,14 +205,4 @@ public class AwtCanvas implements Canvas {
public int getWidth() {
return this.bitmap != null ? this.bitmap.getWidth() : 0;
}
-
- @Override
- public void fillRectangle(int x, int y, int width, int height, int color) {
- java.awt.Color awtColor = color == Color.TRANSPARENT ? TRANSPARENT : new java.awt.Color(color);
- Composite originalComposite = this.canvas.getComposite();
- this.canvas.setComposite(AlphaComposite.getInstance(color == Color.TRANSPARENT ? AlphaComposite.CLEAR : AlphaComposite.SRC_OVER));
- this.canvas.setColor(awtColor);
- this.canvas.fillRect(x, y, width, height);
- this.canvas.setComposite(originalComposite);
- }
}
diff --git a/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java b/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java
index 6a8c3fae..45da0d63 100644
--- a/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java
+++ b/vtm-ios/src/org/oscim/ios/backend/IosCanvas.java
@@ -150,6 +150,14 @@ public class IosCanvas implements Canvas {
this.cgBitmapContext.fillRect(rect);
}
+ @Override
+ public void fillRectangle(float x, float y, float width, float height, int color) {
+ CGRect rect = new CGRect(x, y, width, height);
+ setFillColor(this.cgBitmapContext, (color));
+ this.cgBitmapContext.setBlendMode(CGBlendMode.Normal);
+ this.cgBitmapContext.fillRect(rect);
+ }
+
@Override
public int getHeight() {
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getHeight() : 0;
@@ -159,12 +167,4 @@ public class IosCanvas implements Canvas {
public int getWidth() {
return this.cgBitmapContext != null ? (int) this.cgBitmapContext.getWidth() : 0;
}
-
- @Override
- public void fillRectangle(int x, int y, int width, int height, int color) {
- CGRect rect = new CGRect(x, y, width, height);
- setFillColor(this.cgBitmapContext, (color));
- this.cgBitmapContext.setBlendMode(CGBlendMode.Normal);
- this.cgBitmapContext.fillRect(rect);
- }
}
diff --git a/vtm-playground/src/org/oscim/test/LineRenderTest.java b/vtm-playground/src/org/oscim/test/LineRenderTest.java
index 317fa03e..fa956089 100644
--- a/vtm-playground/src/org/oscim/test/LineRenderTest.java
+++ b/vtm-playground/src/org/oscim/test/LineRenderTest.java
@@ -72,9 +72,9 @@ public class LineRenderTest extends GdxMap {
line2 = new LineStyle(Color.GREEN, 1);
line4 = new LineStyle(Color.LTGRAY, 3);
} else {
- line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true);
- line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true);
- line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, false, null, true);
+ line1 = new LineStyle(0, null, Color.fade(Color.RED, 0.5f), 4.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true, null);
+ line2 = new LineStyle(0, null, Color.GREEN, 6.0f, Cap.BUTT, false, 0, 0, 0, 0, 1f, false, null, true, null);
+ line4 = new LineStyle(0, null, Color.LTGRAY, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, false, null, true, null);
}
TextureItem tex = new TextureItem(CanvasAdapter.getBitmapAsset("", "patterns/dot.png"));
@@ -90,8 +90,8 @@ public class LineRenderTest extends GdxMap {
.randomOffset(true)
.build();
- LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, true, null, true);
- LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 0, true, null, true);
+ LineStyle outline = new LineStyle(0, null, Color.BLUE, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 1f, true, null, true, null);
+ LineStyle outline2 = new LineStyle(0, null, Color.RED, 2.0f, Cap.ROUND, false, 0, 0, 0, 0, 0, true, null, true, null);
LineBucket ol = l.buckets.addLineBucket(0, outline);
LineBucket ol2 = l.buckets.addLineBucket(5, outline2);
diff --git a/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java b/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java
index c3425aa4..179b0bcc 100644
--- a/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java
+++ b/vtm-web/src/org/oscim/gdx/client/GwtCanvas.java
@@ -116,6 +116,11 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas {
// TODO
}
+ @Override
+ public void fillRectangle(float x, float y, float width, float height, int color) {
+ // TODO
+ }
+
@Override
public int getHeight() {
return this.bitmap != null ? this.bitmap.getHeight() : 0;
@@ -125,9 +130,4 @@ public class GwtCanvas implements org.oscim.backend.canvas.Canvas {
public int getWidth() {
return this.bitmap != null ? this.bitmap.getWidth() : 0;
}
-
- @Override
- public void fillRectangle(int x, int y, int width, int height, int color) {
- // TODO
- }
}
diff --git a/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/ThemeUtils.java b/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/ThemeUtils.java
new file mode 100644
index 00000000..98c7c185
--- /dev/null
+++ b/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/ThemeUtils.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 Longri
+ * Copyright 2017 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 .
+ */
+package org.oscim.theme;
+
+import java.io.InputStream;
+
+/**
+ * A utility class with theme specific helper methods.
+ */
+public final class ThemeUtils {
+
+ /**
+ * Check if the given InputStream is a Mapsforge render theme.
+ */
+ public static boolean isMapsforgeTheme(InputStream is) {
+ // TODO
+ return false;
+ }
+
+ private ThemeUtils() {
+ }
+}
diff --git a/vtm/resources/assets/shaders/linetex_layer_tex.glsl b/vtm/resources/assets/shaders/linetex_layer_tex.glsl
index 98a400dc..0ca64261 100644
--- a/vtm/resources/assets/shaders/linetex_layer_tex.glsl
+++ b/vtm/resources/assets/shaders/linetex_layer_tex.glsl
@@ -44,10 +44,9 @@ uniform float u_mode;
void
main(){
if (u_mode >= 1.0) {
-
- float step= 2.0;
- if (u_mode == 3.0){// dashed texture
- step =1.0;
+ float step = 2.0;
+ if (u_mode == 2.0) { // dashed texture
+ step = 1.0;
}
vec4 c=texture2D(tex,vec2(abs(mod(v_st.s+1.0,step)),(v_st.t+1.0)*0.5));
float fuzz=fwidth(c.a);
diff --git a/vtm/src/org/oscim/backend/canvas/Canvas.java b/vtm/src/org/oscim/backend/canvas/Canvas.java
index c74eb39e..f8a9a64c 100644
--- a/vtm/src/org/oscim/backend/canvas/Canvas.java
+++ b/vtm/src/org/oscim/backend/canvas/Canvas.java
@@ -55,9 +55,9 @@ public interface Canvas {
void fillColor(int color);
+ void fillRectangle(float x, float y, float width, float height, int color);
+
int getHeight();
int getWidth();
-
- void fillRectangle(int x, int y, int width, int height, int color);
}
diff --git a/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java b/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java
index 42fddf70..e5000614 100644
--- a/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java
+++ b/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java
@@ -1,6 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
- * Copyright 2016 devemux86
+ * Copyright 2016-2017 devemux86
* Copyright 2017 Longri
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@@ -359,7 +359,7 @@ public final class LineTexBucket extends LineBucket {
LineTexBucket lb = (LineTexBucket) b;
LineStyle line = lb.line.current();
- gl.uniform1f(shader.uMode, line.dashTexture? 3 : line.texture != null ? 1 : 0);
+ gl.uniform1f(shader.uMode, line.dashArray != null ? 2 : (line.texture != null ? 1 : 0));
if (line.texture != null)
line.texture.bind();
diff --git a/vtm/src/org/oscim/theme/SAXTerminationException.java b/vtm/src/org/oscim/theme/SAXTerminationException.java
new file mode 100644
index 00000000..b0463512
--- /dev/null
+++ b/vtm/src/org/oscim/theme/SAXTerminationException.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 Longri
+ *
+ * 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 .
+ */
+package org.oscim.theme;
+
+import org.xml.sax.SAXException;
+
+public class SAXTerminationException extends SAXException {
+ public SAXTerminationException() {
+ super();
+ }
+}
diff --git a/vtm/src/org/oscim/theme/ThemeLoader.java b/vtm/src/org/oscim/theme/ThemeLoader.java
index 88347c0c..a999d98d 100644
--- a/vtm/src/org/oscim/theme/ThemeLoader.java
+++ b/vtm/src/org/oscim/theme/ThemeLoader.java
@@ -1,6 +1,6 @@
/*
* Copyright 2013 Hannes Janetzek
- * Copyright 2016 devemux86
+ * Copyright 2016-2017 devemux86
* Copyright 2017 Longri
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@@ -18,21 +18,11 @@
*/
package org.oscim.theme;
-
import org.oscim.backend.CanvasAdapter;
import org.oscim.theme.IRenderTheme.ThemeException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-
-import javax.xml.parsers.ParserConfigurationException;
public class ThemeLoader {
- private static final Logger log = LoggerFactory.getLogger(ThemeLoader.class);
-
public static boolean USE_ATLAS;
public static boolean POT_TEXTURES;
@@ -56,21 +46,12 @@ public class ThemeLoader {
return load(theme, null);
}
-
-
public static IRenderTheme load(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
- IRenderTheme t = null;
-
- try {
- if(ThemeUtils.isMapsforgeTheme(theme.getRenderThemeAsStream())){
- t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback);
- }else{
- t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback);
- }
- } catch (IOException | ParserConfigurationException | SAXException e) {
- e.printStackTrace();
- }
-
+ IRenderTheme t;
+ if (ThemeUtils.isMapsforgeTheme(theme.getRenderThemeAsStream()))
+ t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback);
+ else
+ t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback);
if (t != null)
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / CanvasAdapter.DEFAULT_DPI - 1));
return t;
diff --git a/vtm/src/org/oscim/theme/ThemeUtils.java b/vtm/src/org/oscim/theme/ThemeUtils.java
index 75d227ca..e5b9d5d1 100644
--- a/vtm/src/org/oscim/theme/ThemeUtils.java
+++ b/vtm/src/org/oscim/theme/ThemeUtils.java
@@ -1,7 +1,6 @@
/*
* Copyright 2017 Longri
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
+ * Copyright 2017 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
@@ -16,63 +15,59 @@
*/
package org.oscim.theme;
+import org.oscim.utils.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
-import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
/**
- * Created by Longri on 30.08.2017.
+ * A utility class with theme specific helper methods.
*/
+public final class ThemeUtils {
-public class ThemeUtils {
-
- public static class SAXTerminatorException extends SAXException {
- public SAXTerminatorException() {
- super();
- }
- }
-
+ private static final Logger log = LoggerFactory.getLogger(ThemeUtils.class);
/**
- * Return true, if the given InputStream a Mapsforge render theme!
- *
- * @param stream
- * @return TRUE or FALSE
- * @throws IOException
- * @throws SAXException
- * @throws ParserConfigurationException
+ * Check if the given InputStream is a Mapsforge render theme.
*/
- public static boolean isMapsforgeTheme(InputStream stream) throws IOException, SAXException, ParserConfigurationException {
- final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false);
- SAXParserFactory factory = SAXParserFactory.newInstance();
- factory.setNamespaceAware(true);
-
- XMLReader xmlReader = factory.newSAXParser().getXMLReader();
- xmlReader.setContentHandler(new DefaultHandler() {
- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
- if (localName.equals("rendertheme")) {
- isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
- //we have all info's, break parsing
- throw new SAXTerminatorException();
- }
- }
- });
+ public static boolean isMapsforgeTheme(InputStream is) {
try {
- xmlReader.parse(new InputSource(stream));
- } catch (SAXTerminatorException e) {
- // do nothing
+ final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false);
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setNamespaceAware(true);
+ XMLReader xmlReader = factory.newSAXParser().getXMLReader();
+ xmlReader.setContentHandler(new DefaultHandler() {
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (localName.equals("rendertheme")) {
+ isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
+ // We have all info, break parsing
+ throw new SAXTerminationException();
+ }
+ }
+ });
+ try {
+ xmlReader.parse(new InputSource(is));
+ } catch (SAXTerminationException e) {
+ // Do nothing
+ }
+ return isMapsforgeTheme.get();
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ return false;
+ } finally {
+ IOUtils.closeQuietly(is);
}
- stream.close();
- return isMapsforgeTheme.get();
}
+ private ThemeUtils() {
+ }
}
diff --git a/vtm/src/org/oscim/theme/XmlMapsforgeThemeBuilder.java b/vtm/src/org/oscim/theme/XmlMapsforgeThemeBuilder.java
index 22aae9ad..714b6a53 100644
--- a/vtm/src/org/oscim/theme/XmlMapsforgeThemeBuilder.java
+++ b/vtm/src/org/oscim/theme/XmlMapsforgeThemeBuilder.java
@@ -25,7 +25,6 @@ import org.oscim.backend.XMLReaderAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.backend.canvas.Canvas;
import org.oscim.backend.canvas.Color;
-import org.oscim.backend.canvas.Paint;
import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.backend.canvas.Paint.FontFamily;
import org.oscim.backend.canvas.Paint.FontStyle;
@@ -65,7 +64,6 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Set;
import java.util.Stack;
-import java.util.regex.Pattern;
import static java.lang.Boolean.parseBoolean;
import static java.lang.Float.parseFloat;
@@ -74,11 +72,7 @@ import static java.lang.Integer.parseInt;
public class XmlMapsforgeThemeBuilder extends DefaultHandler {
private static final Logger log = LoggerFactory.getLogger(XmlMapsforgeThemeBuilder.class);
- private static final int RENDER_THEME_VERSION = 4;
- private static final Pattern SPLIT_PATTERN = Pattern.compile(",");
- private static final float REPEAT_GAP_DEFAULT = 200f;
- private static final float REPEAT_START_DEFAULT = 30f;
-
+ private static final int RENDER_THEME_VERSION = 6;
private enum Element {
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RENDERING_STYLE
@@ -93,6 +87,9 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
private static final String OUTLINE_STYLE = "O";
private static final String AREA_STYLE = "A";
+ private static final float REPEAT_GAP_DEFAULT = 200f;
+ private static final float REPEAT_START_DEFAULT = 30f;
+
/**
* @param theme an input theme containing valid render theme XML data.
* @return a new RenderTheme which is created by parsing the XML data from the input theme.
@@ -139,7 +136,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
private final Stack mRuleStack = new Stack<>();
private final HashMap mStyles = new HashMap<>(10);
- private final HashMap> mTextStyles = new HashMap<>(10);
+ private final HashMap> mTextStyles = new HashMap<>(10);
private final AreaBuilder> mAreaBuilder = AreaStyle.builder();
private final CircleBuilder> mCircleBuilder = CircleStyle.builder();
@@ -415,7 +412,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
if ("when-matched".equals(value))
selector |= Selector.WHEN_MATCHED;
} else {
- XmlMapsforgeThemeBuilder.logUnknownAttribute(localName, name, value, i);
+ logUnknownAttribute(localName, name, value, i);
}
}
@@ -424,8 +421,8 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if (closed == Closed.NO)
element = Rule.Element.LINE;
- XmlMapsforgeThemeBuilder.validateNonNegative("zoom-min", zoomMin);
- XmlMapsforgeThemeBuilder.validateNonNegative("zoom-max", zoomMax);
+ validateNonNegative("zoom-min", zoomMin);
+ validateNonNegative("zoom-max", zoomMax);
if (zoomMin > zoomMax)
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
@@ -449,7 +446,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
return texture;
}
- private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean symbolLine)
+ private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean hasSymbol)
throws SAXException {
String use = attributes.getValue("use");
@@ -463,7 +460,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
}
}
- LineStyle line = createLine(style, localName, attributes, mLevels++, false, symbolLine);
+ LineStyle line = createLine(style, localName, attributes, mLevels++, false, hasSymbol);
if (isStyle) {
mStyles.put(LINE_STYLE + line.style, line);
@@ -489,7 +486,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
* @return a new Line with the given rendering attributes.
*/
private LineStyle createLine(LineStyle line, String elementName, Attributes attributes,
- int level, boolean isOutline, boolean symbolLine) {
+ int level, boolean isOutline, boolean hasSymbol) {
LineBuilder> b = mLineBuilder.set(line);
b.isOutline(isOutline);
b.level(level);
@@ -556,10 +553,13 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("style".equals(name))
; // ignore
- else if ("dasharray".equals(name))
- ; // TBD
+ else if ("stroke-dasharray".equals(name)) {
+ b.dashArray = parseFloatArray(value);
+ for (int j = 0; j < b.dashArray.length; ++j) {
+ b.dashArray[j] = b.dashArray[j] * mScale;
+ }
- else if ("symbol-width".equals(name))
+ } else if ("symbol-width".equals(name))
b.symbolWidth = (int) (Integer.parseInt(value) * mScale);
else if ("symbol-height".equals(name))
@@ -568,31 +568,22 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
- else if ("stroke-dasharray".equals(name)) {
- b.strokeDasharray = parseFloatArray(value);
- for (int j = 0; j < b.strokeDasharray.length; ++j) {
- b.strokeDasharray[j] = b.strokeDasharray[j] * mScale;
- }
- } else if ("dy".equals(name)) {
- // NB: minus..
- //TODO b.dy = -Float.parseFloat(value) * mScale;
- } else if ("align-center".equals(name)) {
- //TODO handle align-center
- } else if ("repeat".equals(name)) {
- //TODO handle repeat
- } else if ("display".equals(name)) {
- //TODO handle display
- } else
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
+ else
logUnknownAttribute(elementName, name, value, i);
}
-
- if (b.strokeDasharray != null) {//create a dashed texture
+ if (b.dashArray != null) {
+ // Create a dashed texture
int bmpWidth = 0;
int bmpHeight = (int) (b.strokeWidth);
- if (bmpHeight < 1) bmpHeight = 2;
- for (float f : b.strokeDasharray) {
- if (f < 1) f = 1;
+ if (bmpHeight < 1)
+ bmpHeight = 2;
+ for (float f : b.dashArray) {
+ if (f < 1)
+ f = 1;
bmpWidth += f;
}
@@ -603,9 +594,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
boolean bw = false;
int x = 0;
- for (float f : b.strokeDasharray) {
- if (f < 1) f = 1;
- canvas.fillRectangle(x * factor, 0, (int) f * factor, bmpHeight * factor, (bw ? Color.TRANSPARENT : Color.WHITE));
+ for (float f : b.dashArray) {
+ if (f < 1)
+ f = 1;
+ canvas.fillRectangle(x * factor, 0, f * factor, bmpHeight * factor, (bw ? Color.TRANSPARENT : Color.WHITE));
x += f;
bw = !bw;
}
@@ -619,13 +611,12 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
b.stippleColor = b.fillColor;
b.fillColor = Color.TRANSPARENT;
b.strokeColor = Color.TRANSPARENT;
-
} else {
b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, b.symbolWidth, b.symbolHeight, b.symbolPercent);
- if (symbolLine) {
- // we have no way to set a repeatGap for the renderer,
- // so we create a texture that already contains this repeatGap.
+ if (hasSymbol) {
+ // We have no way to set a repeat gap for the renderer,
+ // so we create a texture that already contains this repeat gap.
float repeatGap = REPEAT_GAP_DEFAULT * mScale;
float repeatStart = REPEAT_START_DEFAULT * mScale;
int width = (int) (b.texture.width + repeatGap);
@@ -636,13 +627,13 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
canvas.drawBitmap(b.texture.bitmap, repeatStart, 0);
b.texture = new TextureItem(bmp);
- // we must set stipple values
+ // We must set stipple values
// The multipliers are determined empirically to
- // correspond to the representation at Mapsforge!
+ // correspond to the representation at Mapsforge.
b.stipple = b.texture.width * 3;
b.strokeWidth *= 2 * mScale;
- // use texture color
+ // Use texture color
b.stippleColor = Color.WHITE;
b.fillColor = Color.TRANSPARENT;
b.strokeColor = Color.TRANSPARENT;
@@ -736,9 +727,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
- else if ("symbol-scaling".equals(name)) {
- // no-op
- } else
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
+ else
logUnknownAttribute(elementName, name, value, i);
}
@@ -781,7 +773,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
if ("img".equals(name)) {
img = value;
} else {
- XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ logUnknownAttribute(elementName, name, value, i);
}
}
validateExists("img", img, elementName);
@@ -813,7 +805,7 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
Integer.parseInt(pos[3]));
}
} else {
- XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ logUnknownAttribute(elementName, name, value, i);
}
}
validateExists("id", regionName, elementName);
@@ -899,18 +891,15 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("base-text-scale".equals(name))
baseTextScale = Float.parseFloat(value);
- else if ("map-background-outside".equals(name)) {
- //TODO handle map-background-outside
- } else
- XmlMapsforgeThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ else
+ logUnknownAttribute(elementName, name, value, i);
}
validateExists("version", version, elementName);
- if (version != RENDER_THEME_VERSION)
- throw new ThemeException("invalid render theme version:"
- + version);
+ if (version > RENDER_THEME_VERSION)
+ throw new ThemeException("invalid render theme version:" + version);
validateNonNegative("base-stroke-width", baseStrokeWidth);
validateNonNegative("base-text-scale", baseTextScale);
@@ -1018,12 +1007,17 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
- else if ("display".equals(name)) {
- //TODO Handle display attribute NEVER, ALWAYS, IFSPACE;
- } else if ("symbol-id".equals(name)) {
- //TODO Handle symbol-id;
- } else if ("position".equals(name)) {
- //TODO Handle position: AUTO, CENTER, BELOW, BELOW_LEFT, BELOW_RIGHT, ABOVE, ABOVE_LEFT, ABOVE_RIGHT, LEFT, RIGHT
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
+ else if ("position".equals(name)) {
+ // Until implement position..
+ if (b.dy == 0) {
+ value = "below".equals(value) ? "-20" : "20";
+ // NB: minus..
+ b.dy = -Float.parseFloat(value) * mScale;
+ }
+
} else
logUnknownAttribute(elementName, name, value, i);
}
@@ -1115,15 +1109,10 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
- else if ("symbol-scaling".equals(name)) {
- // no-op
- } else if ("display".equals(name)) {
- //TODO Handle display attribute NEVER, ALWAYS, IFSPACE;
- } else if ("id".equals(name)) {
- //TODO Handle 'id'
- } else if ("priority".equals(name)) {
- //TODO Handle 'priority'
- } else
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
+ else
logUnknownAttribute(elementName, name, value, i);
}
@@ -1203,6 +1192,15 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
return mCategories == null || rule.cat == null || mCategories.contains(rule.cat);
}
+ private static float[] parseFloatArray(String dashString) {
+ String[] dashEntries = dashString.split(",");
+ float[] dashIntervals = new float[dashEntries.length];
+ for (int i = 0; i < dashEntries.length; ++i) {
+ dashIntervals[i] = Float.parseFloat(dashEntries[i]);
+ }
+ return dashIntervals;
+ }
+
private static void validateNonNegative(String name, float value) {
if (value < 0)
throw new ThemeException(name + " must not be negative: "
@@ -1214,13 +1212,4 @@ public class XmlMapsforgeThemeBuilder extends DefaultHandler {
throw new ThemeException("missing attribute " + name
+ " for element: " + elementName);
}
-
- private static float[] parseFloatArray(String dashString) {
- String[] dashEntries = SPLIT_PATTERN.split(dashString);
- float[] dashIntervals = new float[dashEntries.length];
- for (int i = 0; i < dashEntries.length; ++i) {
- dashIntervals[i] = Float.parseFloat(dashEntries[i]);
- }
- return dashIntervals;
- }
}
diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
index c5f9cb9c..3b93f684 100644
--- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java
+++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
@@ -405,7 +405,7 @@ public class XmlThemeBuilder extends DefaultHandler {
if ("when-matched".equals(value))
selector |= Selector.WHEN_MATCHED;
} else {
- XmlThemeBuilder.logUnknownAttribute(localName, name, value, i);
+ logUnknownAttribute(localName, name, value, i);
}
}
@@ -414,8 +414,8 @@ public class XmlThemeBuilder extends DefaultHandler {
else if (closed == Closed.NO)
element = Rule.Element.LINE;
- XmlThemeBuilder.validateNonNegative("zoom-min", zoomMin);
- XmlThemeBuilder.validateNonNegative("zoom-max", zoomMax);
+ validateNonNegative("zoom-min", zoomMin);
+ validateNonNegative("zoom-max", zoomMax);
if (zoomMin > zoomMax)
throw new ThemeException("zoom-min must be less or equal zoom-max: " + zoomMin);
@@ -462,9 +462,12 @@ public class XmlThemeBuilder extends DefaultHandler {
mCurrentRule.addStyle(line);
/* Note 'outline' will not be inherited, it's just a
* shortcut to add the outline RenderInstruction. */
- LineStyle outline = createOutline(attributes.getValue("outline"), attributes);
- if (outline != null)
- mCurrentRule.addStyle(outline);
+ String outlineValue = attributes.getValue("outline");
+ if (outlineValue != null) {
+ LineStyle outline = createOutline(outlineValue, attributes);
+ if (outline != null)
+ mCurrentRule.addStyle(outline);
+ }
}
}
}
@@ -555,6 +558,9 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
else
logUnknownAttribute(elementName, name, value, i);
}
@@ -648,6 +654,9 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
else
logUnknownAttribute(elementName, name, value, i);
}
@@ -691,7 +700,7 @@ public class XmlThemeBuilder extends DefaultHandler {
if ("img".equals(name)) {
img = value;
} else {
- XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ logUnknownAttribute(elementName, name, value, i);
}
}
validateExists("img", img, elementName);
@@ -723,7 +732,7 @@ public class XmlThemeBuilder extends DefaultHandler {
Integer.parseInt(pos[3]));
}
} else {
- XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ logUnknownAttribute(elementName, name, value, i);
}
}
validateExists("id", regionName, elementName);
@@ -810,15 +819,14 @@ public class XmlThemeBuilder extends DefaultHandler {
baseTextScale = Float.parseFloat(value);
else
- XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
+ logUnknownAttribute(elementName, name, value, i);
}
validateExists("version", version, elementName);
- if (version != RENDER_THEME_VERSION)
- throw new ThemeException("invalid render theme version:"
- + version);
+ if (version > RENDER_THEME_VERSION)
+ throw new ThemeException("invalid render theme version:" + version);
validateNonNegative("base-stroke-width", baseStrokeWidth);
validateNonNegative("base-text-scale", baseTextScale);
@@ -926,6 +934,9 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
else
logUnknownAttribute(elementName, name, value, i);
}
@@ -1017,6 +1028,9 @@ public class XmlThemeBuilder extends DefaultHandler {
else if ("symbol-percent".equals(name))
b.symbolPercent = Integer.parseInt(value);
+ else if ("symbol-scaling".equals(name))
+ ; // no-op
+
else
logUnknownAttribute(elementName, name, value, i);
}
diff --git a/vtm/src/org/oscim/theme/styles/LineStyle.java b/vtm/src/org/oscim/theme/styles/LineStyle.java
index 0021c560..162b80dc 100644
--- a/vtm/src/org/oscim/theme/styles/LineStyle.java
+++ b/vtm/src/org/oscim/theme/styles/LineStyle.java
@@ -48,25 +48,26 @@ public final class LineStyle extends RenderStyle {
public final int symbolWidth;
public final int symbolHeight;
public final int symbolPercent;
- public boolean dashTexture;
+
+ public final float[] dashArray;
public LineStyle(int stroke, float width) {
- this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
+ this(0, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true, null);
}
public LineStyle(int level, int stroke, float width) {
- this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true);
+ this(level, "", stroke, width, Cap.BUTT, true, 0, 0, 0, -1, 0, false, null, true, null);
}
public LineStyle(int stroke, float width, Cap cap) {
- this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true);
+ this(0, "", stroke, width, cap, true, 0, 0, 0, -1, 0, false, null, true, null);
}
public LineStyle(int level, String style, int color, float width,
Cap cap, boolean fixed,
int stipple, int stippleColor, float stippleWidth,
int fadeScale, float blur, boolean isOutline, TextureItem texture,
- boolean randomOffset) {
+ boolean randomOffset, float[] dashArray) {
this.level = level;
this.style = style;
@@ -91,6 +92,8 @@ public final class LineStyle extends RenderStyle {
this.symbolWidth = 0;
this.symbolHeight = 0;
this.symbolPercent = 100;
+
+ this.dashArray = dashArray;
}
private LineStyle(LineBuilder> b) {
@@ -114,7 +117,8 @@ public final class LineStyle extends RenderStyle {
this.symbolWidth = b.symbolWidth;
this.symbolHeight = b.symbolHeight;
this.symbolPercent = b.symbolPercent;
- this.dashTexture = b.strokeDasharray != null;
+
+ this.dashArray = b.dashArray;
}
@Override
@@ -146,7 +150,8 @@ public final class LineStyle extends RenderStyle {
public int symbolWidth;
public int symbolHeight;
public int symbolPercent;
- public float[] strokeDasharray;
+
+ public float[] dashArray;
public LineBuilder() {
}
@@ -176,6 +181,8 @@ public final class LineStyle extends RenderStyle {
this.symbolHeight = line.symbolHeight;
this.symbolPercent = line.symbolPercent;
+ this.dashArray = line.dashArray;
+
return self();
}
@@ -254,6 +261,11 @@ public final class LineStyle extends RenderStyle {
return self();
}
+ public T dashArray(float[] dashArray) {
+ this.dashArray = dashArray;
+ return self();
+ }
+
public T reset() {
level = -1;
style = null;
@@ -277,7 +289,9 @@ public final class LineStyle extends RenderStyle {
symbolWidth = 0;
symbolHeight = 0;
symbolPercent = 100;
- strokeDasharray = null;
+
+ dashArray = null;
+
return self();
}