package com.xenoage.zong.io.symbols; import com.xenoage.utils.async.AsyncProducer; import com.xenoage.utils.async.AsyncResult; import com.xenoage.utils.io.FileUtils; import com.xenoage.utils.io.InputStream; import com.xenoage.utils.xml.XmlReader; import com.xenoage.zong.symbols.PathSymbol; import com.xenoage.zong.symbols.Symbol; import static com.xenoage.utils.PlatformUtils.platformUtils; import static com.xenoage.utils.log.Log.log; import static com.xenoage.utils.log.Report.remark; /** * A {@link SvgSymbolReader} creates a {@link Symbol} from a SVG file. * * @author Andreas Wenger */ class SvgSymbolReader implements AsyncProducer<PathSymbol> { //parameters private final String id; private final String svgFilepath; //state private AsyncResult<PathSymbol> result; public SvgSymbolReader(String svgFilepath) { this.svgFilepath = svgFilepath; this.id = FileUtils.getNameWithoutExt(svgFilepath); } /** * Creates a {@link Symbol} from the given SVG file. * If an error occurs, an {@link IllegalStateException} is thrown. */ @Override public void produce(AsyncResult<PathSymbol> result) { this.result = result; step1_openFile(); } private void step1_openFile() { log(remark("Loading symbol \"" + id + "\", file: \"" + svgFilepath + "\" ...")); platformUtils().openFileAsync(svgFilepath, new AsyncResult<InputStream>() { @Override public void onSuccess(InputStream stream) { step2_readFile(stream); } @Override public void onFailure(Exception ex) { result.onFailure(ex); } }); } private void step2_readFile(InputStream stream) { //create xml reader XmlReader xmlReader = platformUtils().createXmlReader(stream); //read id element. it has the format "type:id", e.g. //"path:clef-g", or "styled:warning". If there is no ":", //the type "path" is used. //styles: path, styled, rect PathSymbol ret = null; Exception ex = null; try { if (xmlReader.openNextChildElement()) { String elementId = xmlReader.getAttribute("id"); if (elementId == null || elementId.indexOf(':') == -1) { //no format information. use path. ret = SvgPathSymbolReader.read(id, xmlReader); } else { String format = elementId.split(":")[0]; switch (format) { case "path": ret = SvgPathSymbolReader.read(id, xmlReader); break; case "rect": ex = new IllegalStateException("Could not load \"" + svgFilepath + "\": \"" + format + "\" (rect is no longer supported. Convert it into a path)"); break; case "styled": ex = new IllegalStateException("Could not load \"" + svgFilepath + "\": \"" + format + "\" (currently styled symbols are not supported)"); break; default: ex = new IllegalStateException("Unknown symbol format in \"" + svgFilepath + "\": \"" + format + "\""); break; } } } } catch (Exception readerEx) { ex = readerEx; } finally { xmlReader.close(); } if (ex != null) result.onFailure(ex); else result.onSuccess(ret); } }