diff --git a/docs/Changelog.md b/docs/Changelog.md index 6af29ac1..63967783 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -2,6 +2,7 @@ ## New since 0.18.0 +- Render themes: line texture improvements [#983](https://github.com/mapsforge/vtm/issues/983) [#985](https://github.com/mapsforge/vtm/issues/985) - MVT simplification [#956](https://github.com/mapsforge/vtm/pull/956) - `Parameters.SIMPLIFICATION_TOLERANCE`, `Parameters.SIMPLIFICATION_EXCEPTIONS` - libGDX 1.11.0 [#972](https://github.com/mapsforge/vtm/pull/972) [#977](https://github.com/mapsforge/vtm/pull/977) diff --git a/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/XmlThemeBuilder.java b/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/XmlThemeBuilder.java index 8e78025c..91bbae6a 100644 --- a/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm-web/src/org/oscim/gdx/emu/org/oscim/theme/XmlThemeBuilder.java @@ -49,6 +49,7 @@ import org.oscim.theme.styles.LineStyle.LineBuilder; import org.oscim.theme.styles.SymbolStyle.SymbolBuilder; import org.oscim.theme.styles.TextStyle.TextBuilder; import org.oscim.utils.FastMath; +import org.oscim.utils.Parameters; import org.oscim.utils.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -611,59 +612,75 @@ public class XmlThemeBuilder extends DefaultHandler { if (b.dashArray != null) { // Stroke dash array - if (b.dashArray.length % 2 != 0) { + if (b.dashArray.length == 2) { + b.randomOffset = false; + b.stipple = b.dashArray[0] < 1 ? 1 : (int) b.dashArray[0]; + if (mTheme.isMapsforgeTheme()) + b.stipple *= 8; + b.stippleWidth = 1; + b.stippleColor = Color.TRANSPARENT; + b.dashArray = null; + } else { // Odd number of entries is duplicated - float[] newDashArray = new float[b.dashArray.length * 2]; - System.arraycopy(b.dashArray, 0, newDashArray, 0, b.dashArray.length); - System.arraycopy(b.dashArray, 0, newDashArray, b.dashArray.length, b.dashArray.length); - b.dashArray = newDashArray; + if (b.dashArray.length % 2 != 0) { + float[] newDashArray = new float[b.dashArray.length * 2]; + System.arraycopy(b.dashArray, 0, newDashArray, 0, b.dashArray.length); + System.arraycopy(b.dashArray, 0, newDashArray, b.dashArray.length, b.dashArray.length); + b.dashArray = newDashArray; + } + int width = 0; + int height = b.strokeWidth < 1 ? 1 : (int) b.strokeWidth; + for (float f : b.dashArray) { + if (f < 1) + f = 1; + if (mTheme.isMapsforgeTheme()) + f *= 8; + width += f; + } + Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); + Canvas canvas = CanvasAdapter.newCanvas(); + canvas.setBitmap(bitmap); + int x = 0; + boolean transparent = false; + for (float f : b.dashArray) { + if (f < 1) + f = 1; + if (mTheme.isMapsforgeTheme()) + f *= 8; + canvas.fillRectangle(x, 0, f, height, transparent ? Color.TRANSPARENT : Color.WHITE); + x += f; + transparent = !transparent; + } + b.texture = new TextureItem(Utils.potBitmap(bitmap)); + b.texture.mipmap = true; + b.randomOffset = false; + b.stipple = width; + b.stippleWidth = 1; + b.stippleColor = b.fillColor; } - int width = 0; - int height = (int) (b.strokeWidth); - if (height < 1) - height = 1; - for (float f : b.dashArray) { - if (f < 1) - f = 1; - width += f; - } - Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); - Canvas canvas = CanvasAdapter.newCanvas(); - canvas.setBitmap(bitmap); - int x = 0; - boolean transparent = false; - for (float f : b.dashArray) { - if (f < 1) - f = 1; - canvas.fillRectangle(x, 0, f, height, transparent ? Color.TRANSPARENT : Color.WHITE); - x += f; - transparent = !transparent; - } - b.texture = new TextureItem(Utils.potBitmap(bitmap)); - //b.texture.mipmap = true; - b.randomOffset = false; - b.stipple = width; - b.stippleWidth = 1; - b.stippleColor = b.fillColor; } else { - if (src != null) - b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, mTheme.getResourceProvider(), b.symbolWidth, b.symbolHeight, b.symbolPercent); - - if (b.texture != null && hasSymbol) { - // Line symbol - int width = (int) (b.texture.width + b.repeatGap); + // Line symbol or pattern + if (src != null) { + b.symbolPercent *= 2; + float symbolScale = hasSymbol && Parameters.SYMBOL_SCALING == Parameters.SymbolScaling.ALL ? CanvasAdapter.symbolScale : 1; + b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, mTheme.getResourceProvider(), b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale)); + } + if (b.texture != null) { + int width = (int) (b.texture.width + (hasSymbol ? b.repeatGap : 0)); int height = b.texture.height; Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); Canvas canvas = CanvasAdapter.newCanvas(); canvas.setBitmap(bitmap); - canvas.drawBitmap(b.texture.bitmap, b.repeatStart, 0); + canvas.drawBitmap(b.texture.bitmap, (hasSymbol ? b.repeatStart : 0), 0); b.texture = new TextureItem(Utils.potBitmap(bitmap)); - //b.texture.mipmap = true; - b.fixed = true; + b.texture.mipmap = true; + if (hasSymbol) { + b.fixed = true; + b.strokeWidth = height * 0.25f; + } b.randomOffset = false; b.stipple = width; b.stippleWidth = 1; - b.strokeWidth = height * 0.5f; b.stippleColor = Color.WHITE; } } diff --git a/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java b/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java index 44252214..ed44addb 100644 --- a/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java +++ b/vtm/src/org/oscim/renderer/bucket/LineTexBucket.java @@ -385,7 +385,12 @@ public final class LineTexBucket extends LineBucket { LineTexBucket lb = (LineTexBucket) b; LineStyle line = lb.line.current(); - gl.uniform1i(shader.uMode, line.dashArray != null ? 2 : (line.texture != null ? 1 : 0)); + if (line.dashArray != null || (line.texture != null && !line.fixed)) + gl.uniform1i(shader.uMode, 2); + else if (line.texture != null) + gl.uniform1i(shader.uMode, 1); + else + gl.uniform1i(shader.uMode, 0); if (line.texture != null) line.texture.bind(); diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java index 0642237a..cd1b23e8 100644 --- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java +++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java @@ -632,61 +632,75 @@ public class XmlThemeBuilder { if (b.dashArray != null) { // Stroke dash array - if (b.dashArray.length % 2 != 0) { + if (b.dashArray.length == 2) { + b.randomOffset = false; + b.stipple = b.dashArray[0] < 1 ? 1 : (int) b.dashArray[0]; + if (mTheme.isMapsforgeTheme()) + b.stipple *= 8; + b.stippleWidth = 1; + b.stippleColor = Color.TRANSPARENT; + b.dashArray = null; + } else { // Odd number of entries is duplicated - float[] newDashArray = new float[b.dashArray.length * 2]; - System.arraycopy(b.dashArray, 0, newDashArray, 0, b.dashArray.length); - System.arraycopy(b.dashArray, 0, newDashArray, b.dashArray.length, b.dashArray.length); - b.dashArray = newDashArray; + if (b.dashArray.length % 2 != 0) { + float[] newDashArray = new float[b.dashArray.length * 2]; + System.arraycopy(b.dashArray, 0, newDashArray, 0, b.dashArray.length); + System.arraycopy(b.dashArray, 0, newDashArray, b.dashArray.length, b.dashArray.length); + b.dashArray = newDashArray; + } + int width = 0; + int height = b.strokeWidth < 1 ? 1 : (int) b.strokeWidth; + for (float f : b.dashArray) { + if (f < 1) + f = 1; + if (mTheme.isMapsforgeTheme()) + f *= 8; + width += f; + } + Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); + Canvas canvas = CanvasAdapter.newCanvas(); + canvas.setBitmap(bitmap); + int x = 0; + boolean transparent = false; + for (float f : b.dashArray) { + if (f < 1) + f = 1; + if (mTheme.isMapsforgeTheme()) + f *= 8; + canvas.fillRectangle(x, 0, f, height, transparent ? Color.TRANSPARENT : Color.WHITE); + x += f; + transparent = !transparent; + } + b.texture = new TextureItem(Utils.potBitmap(bitmap)); + b.texture.mipmap = true; + b.randomOffset = false; + b.stipple = width; + b.stippleWidth = 1; + b.stippleColor = b.fillColor; } - int width = 0; - int height = (int) (b.strokeWidth); - if (height < 1) - height = 1; - for (float f : b.dashArray) { - if (f < 1) - f = 1; - width += f; - } - Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); - Canvas canvas = CanvasAdapter.newCanvas(); - canvas.setBitmap(bitmap); - int x = 0; - boolean transparent = false; - for (float f : b.dashArray) { - if (f < 1) - f = 1; - canvas.fillRectangle(x, 0, f, height, transparent ? Color.TRANSPARENT : Color.WHITE); - x += f; - transparent = !transparent; - } - b.texture = new TextureItem(Utils.potBitmap(bitmap)); - //b.texture.mipmap = true; - b.randomOffset = false; - b.stipple = width; - b.stippleWidth = 1; - b.stippleColor = b.fillColor; } else { + // Line symbol or pattern if (src != null) { - float symbolScale = Parameters.SYMBOL_SCALING == Parameters.SymbolScaling.ALL ? CanvasAdapter.symbolScale : 1; + b.symbolPercent *= 2; + float symbolScale = hasSymbol && Parameters.SYMBOL_SCALING == Parameters.SymbolScaling.ALL ? CanvasAdapter.symbolScale : 1; b.texture = Utils.loadTexture(mTheme.getRelativePathPrefix(), src, mTheme.getResourceProvider(), b.symbolWidth, b.symbolHeight, (int) (b.symbolPercent * symbolScale)); } - - if (b.texture != null && hasSymbol) { - // Line symbol - int width = (int) (b.texture.width + b.repeatGap); + if (b.texture != null) { + int width = (int) (b.texture.width + (hasSymbol ? b.repeatGap : 0)); int height = b.texture.height; Bitmap bitmap = CanvasAdapter.newBitmap(width, height, 0); Canvas canvas = CanvasAdapter.newCanvas(); canvas.setBitmap(bitmap); - canvas.drawBitmap(b.texture.bitmap, b.repeatStart, 0); + canvas.drawBitmap(b.texture.bitmap, (hasSymbol ? b.repeatStart : 0), 0); b.texture = new TextureItem(Utils.potBitmap(bitmap)); - //b.texture.mipmap = true; - b.fixed = true; + b.texture.mipmap = true; + if (hasSymbol) { + b.fixed = true; + b.strokeWidth = height * 0.25f; + } b.randomOffset = false; b.stipple = width; b.stippleWidth = 1; - b.strokeWidth = height * 0.5f; b.stippleColor = Color.WHITE; } }