parse symbol TextureAtlas from theme

This commit is contained in:
Hannes Janetzek 2013-06-21 09:43:14 +02:00
parent 8403ab87e0
commit f24240ae27
3 changed files with 110 additions and 23 deletions

View File

@ -24,8 +24,11 @@ import java.util.Stack;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory; 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.Area;
import org.oscim.theme.renderinstruction.AreaLevel; import org.oscim.theme.renderinstruction.AreaLevel;
import org.oscim.theme.renderinstruction.BitmapUtils;
import org.oscim.theme.renderinstruction.Circle; import org.oscim.theme.renderinstruction.Circle;
import org.oscim.theme.renderinstruction.Line; import org.oscim.theme.renderinstruction.Line;
import org.oscim.theme.renderinstruction.LineSymbol; import org.oscim.theme.renderinstruction.LineSymbol;
@ -40,6 +43,7 @@ import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import android.graphics.Bitmap;
import android.util.Log; import android.util.Log;
/** /**
@ -49,7 +53,7 @@ public class RenderThemeHandler extends DefaultHandler {
private final static String TAG = RenderThemeHandler.class.getName(); private final static String TAG = RenderThemeHandler.class.getName();
private static enum Element { 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"; private static final String ELEMENT_NAME_RENDER_THEME = "rendertheme";
@ -120,7 +124,7 @@ public class RenderThemeHandler extends DefaultHandler {
private final Stack<Rule> mRuleStack = new Stack<Rule>(); private final Stack<Rule> mRuleStack = new Stack<Rule>();
private final HashMap<String, RenderInstruction> tmpStyleHash = private final HashMap<String, RenderInstruction> tmpStyleHash =
new HashMap<String, RenderInstruction>(10); new HashMap<String, RenderInstruction>(10);
private TextureAtlas mTextureAtlas;
private int mLevel; private int mLevel;
private RenderTheme mRenderTheme; private RenderTheme mRenderTheme;
@ -131,7 +135,9 @@ public class RenderThemeHandler extends DefaultHandler {
} }
mRenderTheme.complete(mRulesList, mLevel); mRenderTheme.complete(mRulesList, mLevel);
//mRenderTheme.mTextureAtlas = mTextureAtlas;
mTextureAtlas = null;
mRulesList.clear(); mRulesList.clear();
tmpStyleHash.clear(); tmpStyleHash.clear();
mRuleStack.clear(); mRuleStack.clear();
@ -226,8 +232,12 @@ public class RenderThemeHandler extends DefaultHandler {
Text text = Text.create(localName, attributes, true); Text text = Text.create(localName, attributes, true);
mCurrentRule.addRenderingInstruction(text); mCurrentRule.addRenderingInstruction(text);
// Caption caption = Caption.create(localName, attributes); if (text.symbol != null) {
// mCurrentRule.addRenderingInstruction(caption); 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)) { else if ("circle".equals(localName)) {
@ -258,6 +268,12 @@ public class RenderThemeHandler extends DefaultHandler {
checkState(localName, Element.RENDERING_INSTRUCTION); checkState(localName, Element.RENDERING_INSTRUCTION);
Symbol symbol = Symbol.create(localName, attributes); Symbol symbol = Symbol.create(localName, attributes);
mCurrentRule.addRenderingInstruction(symbol); 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)) { else if (ELEMENT_NAME_USE_STYLE_LINE.equals(localName)) {
@ -305,6 +321,12 @@ public class RenderThemeHandler extends DefaultHandler {
else else
Log.d(TAG, "BUG not a path text style: " + style); 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 { } else {
throw new SAXException("unknown element: " + localName); 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 @Override
public void warning(SAXParseException exception) { public void warning(SAXParseException exception) {
Log.d(TAG, exception.getMessage()); Log.d(TAG, exception.getMessage());
@ -349,6 +425,14 @@ public class RenderThemeHandler extends DefaultHandler {
throw new SAXException(UNEXPECTED_ELEMENT + elementName); throw new SAXException(UNEXPECTED_ELEMENT + elementName);
} }
return; 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); throw new SAXException("unknown enum value: " + element);

View File

@ -14,14 +14,11 @@
*/ */
package org.oscim.theme.renderinstruction; package org.oscim.theme.renderinstruction;
import java.io.IOException; import org.oscim.renderer.atlas.TextureRegion;
import org.oscim.theme.IRenderCallback; import org.oscim.theme.IRenderCallback;
import org.oscim.theme.RenderThemeHandler; import org.oscim.theme.RenderThemeHandler;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import android.graphics.Bitmap;
/** /**
* Represents an icon on the map. * Represents an icon on the map.
*/ */
@ -32,11 +29,8 @@ public final class Symbol extends RenderInstruction {
* @param attributes * @param attributes
* the attributes of the XML element. * the attributes of the XML element.
* @return a new Symbol with the given rendering attributes. * @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) public static Symbol create(String elementName, Attributes attributes) {
throws IOException {
String src = null; String src = null;
for (int i = 0; i < attributes.getLength(); ++i) { 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 { public Symbol(String src) {
super(); this.src = src;
bitmap = BitmapUtils.createBitmap(src);
} }
@Override @Override
public void destroy() { public void destroy() {
bitmap.recycle();
} }
@Override @Override

View File

@ -19,6 +19,7 @@ import java.util.Locale;
import org.oscim.graphics.Color; import org.oscim.graphics.Color;
import org.oscim.graphics.Paint.FontFamily; import org.oscim.graphics.Paint.FontFamily;
import org.oscim.graphics.Paint.FontStyle; import org.oscim.graphics.Paint.FontStyle;
import org.oscim.renderer.atlas.TextureRegion;
import org.oscim.theme.IRenderCallback; import org.oscim.theme.IRenderCallback;
import org.oscim.theme.RenderThemeHandler; import org.oscim.theme.RenderThemeHandler;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -33,6 +34,7 @@ import android.graphics.Typeface;
* Represents a text along a polyline on the map. * Represents a text along a polyline on the map.
*/ */
public final class Text extends RenderInstruction { public final class Text extends RenderInstruction {
/** /**
* @param elementName * @param elementName
* the name of the XML element. * the name of the XML element.
@ -53,6 +55,7 @@ public final class Text extends RenderInstruction {
String style = null; String style = null;
float dy = 0; float dy = 0;
int priority = Integer.MAX_VALUE; int priority = Integer.MAX_VALUE;
String symbol = null;
for (int i = 0; i < attributes.getLength(); ++i) { for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
@ -79,6 +82,8 @@ public final class Text extends RenderInstruction {
priority = Integer.parseInt(value); priority = Integer.parseInt(value);
} else if ("dy".equals(name)) { } else if ("dy".equals(name)) {
dy = Float.parseFloat(value); dy = Float.parseFloat(value);
} else if ("symbol".equals(name)) {
symbol = value;
} else { } else {
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i); RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
} }
@ -87,7 +92,7 @@ public final class Text extends RenderInstruction {
validate(elementName, textKey, fontSize, strokeWidth); validate(elementName, textKey, fontSize, strokeWidth);
return new Text(style, textKey, fontFamily, fontStyle, fontSize, fill, stroke, 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, 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 float fontSize;
public final Paint paint; public final Paint paint;
public final Paint stroke; public final Paint stroke;
public final String textKey; public final String textKey;
public final String style; public final String symbol;
public final boolean caption; public final boolean caption;
public final float dy; public final float dy;
public final int priority; public final int priority;
@ -117,11 +125,13 @@ public final class Text extends RenderInstruction {
public float fontHeight; public float fontHeight;
public float fontDescent; public float fontDescent;
public TextureRegion texture;
public static Text createText(float fontSize, float strokeWidth, int fill, int outline, public static Text createText(float fontSize, float strokeWidth, int fill, int outline,
boolean billboard) { boolean billboard) {
Text t = new Text("", "", FontFamily.DEFAULT, FontStyle.NORMAL, 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(); FontMetrics fm = t.paint.getFontMetrics();
t.fontHeight = (float) Math.ceil(Math.abs(fm.bottom) + Math.abs(fm.top)); t.fontHeight = (float) Math.ceil(Math.abs(fm.bottom) + Math.abs(fm.top));
t.fontDescent = (float) Math.ceil(Math.abs(fm.bottom)); 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, private Text(String style, String textKey, FontFamily fontFamily, FontStyle fontStyle,
float fontSize, float fontSize, int fill, int outline, float strokeWidth, float dy, boolean caption,
int fill, int outline, float strokeWidth, float dy, boolean caption, int priority) { String symbol, int priority) {
this.style = style; this.style = style;
this.textKey = textKey; this.textKey = textKey;
this.caption = caption; this.caption = caption;
this.dy = -dy; this.dy = -dy;
this.priority = priority; this.priority = priority;
this.symbol = symbol;
//paint = Graphics.res.getPaint(); //paint = Graphics.res.getPaint();
paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint = new Paint(Paint.ANTI_ALIAS_FLAG);