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.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<Rule> mRuleStack = new Stack<Rule>();
private final HashMap<String, RenderInstruction> tmpStyleHash =
new HashMap<String, RenderInstruction>(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);

View File

@ -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

View File

@ -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);