diff --git a/src/org/oscim/theme/RenderThemeHandler.java b/src/org/oscim/theme/RenderThemeHandler.java index 53ae70db..d0cf7fc2 100644 --- a/src/org/oscim/theme/RenderThemeHandler.java +++ b/src/org/oscim/theme/RenderThemeHandler.java @@ -24,8 +24,11 @@ import java.util.Stack; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; +import org.oscim.renderer.atlas.TextureAtlas; +import org.oscim.renderer.atlas.TextureAtlas.Rect; import org.oscim.theme.renderinstruction.Area; import org.oscim.theme.renderinstruction.AreaLevel; +import org.oscim.theme.renderinstruction.BitmapUtils; import org.oscim.theme.renderinstruction.Circle; import org.oscim.theme.renderinstruction.Line; import org.oscim.theme.renderinstruction.LineSymbol; @@ -40,6 +43,7 @@ import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; +import android.graphics.Bitmap; import android.util.Log; /** @@ -49,7 +53,7 @@ public class RenderThemeHandler extends DefaultHandler { private final static String TAG = RenderThemeHandler.class.getName(); private static enum Element { - RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE; + RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS; } private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme"; @@ -120,7 +124,7 @@ public class RenderThemeHandler extends DefaultHandler { private final Stack mRuleStack = new Stack(); private final HashMap tmpStyleHash = new HashMap(10); - + private TextureAtlas mTextureAtlas; private int mLevel; private RenderTheme mRenderTheme; @@ -131,7 +135,9 @@ public class RenderThemeHandler extends DefaultHandler { } mRenderTheme.complete(mRulesList, mLevel); + //mRenderTheme.mTextureAtlas = mTextureAtlas; + mTextureAtlas = null; mRulesList.clear(); tmpStyleHash.clear(); mRuleStack.clear(); @@ -226,8 +232,12 @@ public class RenderThemeHandler extends DefaultHandler { Text text = Text.create(localName, attributes, true); mCurrentRule.addRenderingInstruction(text); - // Caption caption = Caption.create(localName, attributes); - // mCurrentRule.addRenderingInstruction(caption); + if (text.symbol != null) { + if ((text.texture = mTextureAtlas.getTextureRegion(text.symbol)) == null) + Log.d(TAG, "missing texture atlas item '" + text.symbol + "'"); + else + Log.d(TAG, "using atlas item '" + text.symbol + "'"); + } } else if ("circle".equals(localName)) { @@ -258,6 +268,12 @@ public class RenderThemeHandler extends DefaultHandler { checkState(localName, Element.RENDERING_INSTRUCTION); Symbol symbol = Symbol.create(localName, attributes); mCurrentRule.addRenderingInstruction(symbol); + + if ((symbol.texture = mTextureAtlas.getTextureRegion(symbol.src)) == null) + Log.d(TAG, "missing texture atlas item '" + symbol.src + "'"); + else + Log.d(TAG, "using atlas item '" + symbol.src + "'"); + } else if (ELEMENT_NAME_USE_STYLE_LINE.equals(localName)) { @@ -305,6 +321,12 @@ public class RenderThemeHandler extends DefaultHandler { else Log.d(TAG, "BUG not a path text style: " + style); } + } else if ("atlas".equals(localName)) { + checkState(localName, Element.ATLAS); + createAtlas(localName, attributes); + } else if ("rect".equals(localName)) { + checkState(localName, Element.ATLAS); + createTextureRegion(localName, attributes); } else { throw new SAXException("unknown element: " + localName); } @@ -315,6 +337,60 @@ public class RenderThemeHandler extends DefaultHandler { } } + private void createAtlas(String elementName, Attributes attributes) throws IOException { + String img = null; + + for (int i = 0; i < attributes.getLength(); i++) { + String name = attributes.getLocalName(i); + String value = attributes.getValue(i); + + if ("img".equals(name)) { + img = value; + } else if ("name".equals(name)) { + //img = value; + } else { + RenderThemeHandler.logUnknownAttribute(elementName, name, value, i); + } + } + if (img == null) + throw new IllegalArgumentException( + "missing attribute 'img' for element: " + + elementName); + + Bitmap bitmap = BitmapUtils.createBitmap("jar:" + img); + mTextureAtlas = new TextureAtlas(bitmap); + } + + private void createTextureRegion(String elementName, Attributes attributes) { + String regionName = null; + Rect r = null; + + for (int i = 0, n = attributes.getLength(); i < n; i++) { + String name = attributes.getLocalName(i); + String value = attributes.getValue(i); + + if ("name".equals(name)) { + regionName = value; + } else if ("pos".equals(name)) { + String[] pos = value.split(" "); + if (pos.length == 4) { + r = new Rect(Integer.parseInt(pos[0]), + Integer.parseInt(pos[1]), + Integer.parseInt(pos[2]), + Integer.parseInt(pos[3])); + } + } else { + RenderThemeHandler.logUnknownAttribute(elementName, name, value, i); + } + } + if (regionName == null || r == null) + throw new IllegalArgumentException( + "missing attribute 'name' or 'rect' for element: " + + elementName); + + mTextureAtlas.addTextureRegion(regionName.intern(), r); + } + @Override public void warning(SAXParseException exception) { Log.d(TAG, exception.getMessage()); @@ -349,6 +425,14 @@ public class RenderThemeHandler extends DefaultHandler { throw new SAXException(UNEXPECTED_ELEMENT + elementName); } return; + case ATLAS: + parentElement = mElementStack.peek(); + // FIXME + if (parentElement != Element.RENDER_THEME + && parentElement != Element.ATLAS) { + throw new SAXException(UNEXPECTED_ELEMENT + elementName); + } + return; } throw new SAXException("unknown enum value: " + element); diff --git a/src/org/oscim/theme/renderinstruction/Symbol.java b/src/org/oscim/theme/renderinstruction/Symbol.java index 41c9d772..8af8a2b1 100644 --- a/src/org/oscim/theme/renderinstruction/Symbol.java +++ b/src/org/oscim/theme/renderinstruction/Symbol.java @@ -14,14 +14,11 @@ */ package org.oscim.theme.renderinstruction; -import java.io.IOException; - +import org.oscim.renderer.atlas.TextureRegion; import org.oscim.theme.IRenderCallback; import org.oscim.theme.RenderThemeHandler; import org.xml.sax.Attributes; -import android.graphics.Bitmap; - /** * Represents an icon on the map. */ @@ -32,11 +29,8 @@ public final class Symbol extends RenderInstruction { * @param attributes * the attributes of the XML element. * @return a new Symbol with the given rendering attributes. - * @throws IOException - * if an I/O error occurs while reading a resource. */ - public static Symbol create(String elementName, Attributes attributes) - throws IOException { + public static Symbol create(String elementName, Attributes attributes) { String src = null; for (int i = 0; i < attributes.getLength(); ++i) { @@ -61,17 +55,15 @@ public final class Symbol extends RenderInstruction { } } - public final Bitmap bitmap; + public final String src; + public TextureRegion texture; - public Symbol(String src) throws IOException { - super(); - - bitmap = BitmapUtils.createBitmap(src); + public Symbol(String src) { + this.src = src; } @Override public void destroy() { - bitmap.recycle(); } @Override diff --git a/src/org/oscim/theme/renderinstruction/Text.java b/src/org/oscim/theme/renderinstruction/Text.java index c0260a21..77d03ec3 100644 --- a/src/org/oscim/theme/renderinstruction/Text.java +++ b/src/org/oscim/theme/renderinstruction/Text.java @@ -19,6 +19,7 @@ import java.util.Locale; import org.oscim.graphics.Color; import org.oscim.graphics.Paint.FontFamily; import org.oscim.graphics.Paint.FontStyle; +import org.oscim.renderer.atlas.TextureRegion; import org.oscim.theme.IRenderCallback; import org.oscim.theme.RenderThemeHandler; import org.xml.sax.Attributes; @@ -33,6 +34,7 @@ import android.graphics.Typeface; * Represents a text along a polyline on the map. */ public final class Text extends RenderInstruction { + /** * @param elementName * the name of the XML element. @@ -53,6 +55,7 @@ public final class Text extends RenderInstruction { String style = null; float dy = 0; int priority = Integer.MAX_VALUE; + String symbol = null; for (int i = 0; i < attributes.getLength(); ++i) { String name = attributes.getLocalName(i); @@ -79,6 +82,8 @@ public final class Text extends RenderInstruction { priority = Integer.parseInt(value); } else if ("dy".equals(name)) { dy = Float.parseFloat(value); + } else if ("symbol".equals(name)) { + symbol = value; } else { RenderThemeHandler.logUnknownAttribute(elementName, name, value, i); } @@ -87,7 +92,7 @@ public final class Text extends RenderInstruction { validate(elementName, textKey, fontSize, strokeWidth); return new Text(style, textKey, fontFamily, fontStyle, fontSize, fill, stroke, strokeWidth, - dy, caption, priority); + dy, caption, symbol, priority); } private static void validate(String elementName, String textKey, float fontSize, @@ -104,12 +109,15 @@ public final class Text extends RenderInstruction { } } + public final String style; + public final float fontSize; public final Paint paint; public final Paint stroke; public final String textKey; - public final String style; + public final String symbol; + public final boolean caption; public final float dy; public final int priority; @@ -117,11 +125,13 @@ public final class Text extends RenderInstruction { public float fontHeight; public float fontDescent; + public TextureRegion texture; + public static Text createText(float fontSize, float strokeWidth, int fill, int outline, boolean billboard) { Text t = new Text("", "", FontFamily.DEFAULT, FontStyle.NORMAL, - fontSize, fill, outline, strokeWidth, 0, billboard, Integer.MAX_VALUE); + fontSize, fill, outline, strokeWidth, 0, billboard, null, Integer.MAX_VALUE); FontMetrics fm = t.paint.getFontMetrics(); t.fontHeight = (float) Math.ceil(Math.abs(fm.bottom) + Math.abs(fm.top)); t.fontDescent = (float) Math.ceil(Math.abs(fm.bottom)); @@ -161,14 +171,15 @@ public final class Text extends RenderInstruction { } private Text(String style, String textKey, FontFamily fontFamily, FontStyle fontStyle, - float fontSize, - int fill, int outline, float strokeWidth, float dy, boolean caption, int priority) { + float fontSize, int fill, int outline, float strokeWidth, float dy, boolean caption, + String symbol, int priority) { this.style = style; this.textKey = textKey; this.caption = caption; this.dy = -dy; this.priority = priority; + this.symbol = symbol; //paint = Graphics.res.getPaint(); paint = new Paint(Paint.ANTI_ALIAS_FLAG);