diff --git a/flixel/graphics/frames/bmfont/BMFont.hx b/flixel/graphics/frames/bmfont/BMFont.hx index f315a886dd..edb9a575b8 100644 --- a/flixel/graphics/frames/bmfont/BMFont.hx +++ b/flixel/graphics/frames/bmfont/BMFont.hx @@ -3,7 +3,6 @@ package flixel.graphics.frames.bmfont; import flixel.system.FlxAssets; import haxe.io.Bytes; import haxe.io.BytesInput; -import haxe.xml.Access; import openfl.utils.Assets; using StringTools; @@ -34,16 +33,16 @@ class BMFont public static function fromXml(xml:Xml) { - final xmlAccess = new Access(xml); - final info = BMFontInfo.fromXml(xmlAccess.node.info); - final common = BMFontCommon.fromXml(xmlAccess.node.common); - final pages = BMFontPage.listFromXml(xmlAccess.node.pages); - final chars = BMFontChar.listFromXml(xmlAccess.node.chars); + final main = new BMFontXml(xml); + final info = BMFontInfo.fromXml(main.node.get("info")); + final common = BMFontCommon.fromXml(main.node.get("common")); + final pages = BMFontPage.listFromXml(main.node.get("pages")); + final chars = BMFontChar.listFromXml(main.node.get("chars")); var kerning:Array = null; - if (xmlAccess.hasNode.kernings) + if (main.hasNode("kernings")) { - kerning = BMFontKerning.listFromXml(xmlAccess.node.kernings); + kerning = BMFontKerning.listFromXml(main.node.get("kernings")); } return new BMFont(info, common, pages, chars, kerning); diff --git a/flixel/graphics/frames/bmfont/BMFontChar.hx b/flixel/graphics/frames/bmfont/BMFontChar.hx index 7f4b19f432..3a19c8a47e 100644 --- a/flixel/graphics/frames/bmfont/BMFontChar.hx +++ b/flixel/graphics/frames/bmfont/BMFontChar.hx @@ -1,7 +1,6 @@ package flixel.graphics.frames.bmfont; import haxe.io.BytesInput; -import haxe.xml.Access; import UnicodeString; using StringTools; @@ -29,26 +28,26 @@ class BMFontChar public var chnl:Int; public var letter:Null = null; - static inline function fromXml(charNode:Access):BMFontChar + static inline function fromXml(charNode:BMFontXml):BMFontChar { return { - id: Std.parseInt(charNode.att.id), - x: Std.parseInt(charNode.att.x), - y: Std.parseInt(charNode.att.y), - width: Std.parseInt(charNode.att.width), - height: Std.parseInt(charNode.att.height), - xoffset: (charNode.has.xoffset) ? Std.parseInt(charNode.att.xoffset) : 0, - yoffset: (charNode.has.yoffset) ? Std.parseInt(charNode.att.yoffset) : 0, - xadvance: (charNode.has.xadvance) ? Std.parseInt(charNode.att.xadvance) : 0, - page: Std.parseInt(charNode.att.page), - chnl: Std.parseInt(charNode.att.chnl), - letter: charNode.has.letter ? charNode.att.letter : null + id: charNode.att.int("id"), + x: charNode.att.int("x"), + y: charNode.att.int("y"), + width: charNode.att.int("width"), + height: charNode.att.int("height"), + xoffset: charNode.att.intSafe("xoffset", 0), + yoffset: charNode.att.intSafe("yoffset", 0), + xadvance: charNode.att.intSafe("xadvance", 0), + page: charNode.att.intWarn("page", -1), + chnl: charNode.att.intWarn("chnl", -1), + letter: charNode.att.stringSafe("letter") }; } - static function listFromXml(charsNode:Access):Array + static function listFromXml(charsNode:BMFontXml):Array { - final chars = charsNode.nodes.char; + final chars = charsNode.nodes("char"); return [ for (char in chars) fromXml(char) ]; } diff --git a/flixel/graphics/frames/bmfont/BMFontCommon.hx b/flixel/graphics/frames/bmfont/BMFontCommon.hx index 9bd1bdf8ea..f02ec06343 100644 --- a/flixel/graphics/frames/bmfont/BMFontCommon.hx +++ b/flixel/graphics/frames/bmfont/BMFontCommon.hx @@ -1,7 +1,6 @@ package flixel.graphics.frames.bmfont; import haxe.io.BytesInput; -import haxe.xml.Access; /** * Common data used internally via `FlxBitmapFont.fromAngelCode` to serialize text, xml or binary @@ -25,20 +24,20 @@ class BMFontCommon public var greenChnl:Int; public var blueChnl:Int; - static function fromXml(commonNode:Access):BMFontCommon + static function fromXml(commonNode:BMFontXml):BMFontCommon { return { - lineHeight: Std.parseInt(commonNode.att.lineHeight), - base: Std.parseInt(commonNode.att.base), - scaleW: Std.parseInt(commonNode.att.scaleW), - scaleH: Std.parseInt(commonNode.att.scaleH), - pages: Std.parseInt(commonNode.att.pages), - packed: commonNode.att.packed != '0', - alphaChnl: (commonNode.has.alphaChnl) ? Std.parseInt(commonNode.att.alphaChnl) : 0, - redChnl: (commonNode.has.redChnl) ? Std.parseInt(commonNode.att.redChnl) : 0, - greenChnl: (commonNode.has.greenChnl) ? Std.parseInt(commonNode.att.greenChnl) : 0, - blueChnl: (commonNode.has.blueChnl) ? Std.parseInt(commonNode.att.blueChnl) : 0 + lineHeight: commonNode.att.int("lineHeight"), + base: commonNode.att.intWarn("base", -1), + scaleW: commonNode.att.intWarn("scaleW", 1), + scaleH: commonNode.att.intWarn("scaleH", 1), + pages: commonNode.att.intSafe("pages", 0), + packed: commonNode.att.boolSafe("packed", false), + alphaChnl: commonNode.att.intSafe("alphaChnl", 0), + redChnl: commonNode.att.intSafe("redChnl", 0), + greenChnl: commonNode.att.intSafe("greenChnl", 0), + blueChnl: commonNode.att.intSafe("blueChnl", 0) }; } @@ -50,10 +49,10 @@ class BMFontCommon var scaleH:Int = 1; var pages:Int = 0; var packed:Bool = false; - var alphaChnl:Int = -1; - var redChnl:Int = -1; - var greenChnl:Int = -1; - var blueChnl:Int = -1; + var alphaChnl:Int = 0; + var redChnl:Int = 0; + var greenChnl:Int = 0; + var blueChnl:Int = 0; BMFontUtil.forEachAttribute(commonText, function(key:String, value:String) diff --git a/flixel/graphics/frames/bmfont/BMFontInfo.hx b/flixel/graphics/frames/bmfont/BMFontInfo.hx index 3743304daa..84050b8566 100644 --- a/flixel/graphics/frames/bmfont/BMFontInfo.hx +++ b/flixel/graphics/frames/bmfont/BMFontInfo.hx @@ -1,7 +1,6 @@ package flixel.graphics.frames.bmfont; import haxe.io.BytesInput; -import haxe.xml.Access; /** * Info data used internally via `FlxBitmapFont.fromAngelCode` to serialize text, xml or binary @@ -29,22 +28,22 @@ class BMFontInfo public var outline:Int = 0; public var fixedHeight:Bool = false; - static function fromXml(infoNode:Access):BMFontInfo + static function fromXml(infoNode:BMFontXml):BMFontInfo { return { - face: infoNode.att.face, - size: Std.parseInt(infoNode.att.size), - bold: infoNode.att.bold != '0', - italic: infoNode.att.italic != '0', - smooth: infoNode.att.smooth != '0', - charset: infoNode.att.charset, - unicode: infoNode.att.unicode != '0', - stretchH: Std.parseInt(infoNode.att.stretchH), - aa: Std.parseInt(infoNode.att.aa), - padding: BMFontPadding.fromString(infoNode.att.padding), - spacing: BMFontSpacing.fromString(infoNode.att.spacing), - outline: infoNode.has.outline ? Std.parseInt(infoNode.att.outline) : 0, - fixedHeight: infoNode.has.fixedHeight && infoNode.att.fixedHeight != '0' + face: infoNode.att.string("face"), + size: infoNode.att.int("size"), + bold: infoNode.att.boolSafe("bold", false), + italic: infoNode.att.boolSafe("italic", false), + smooth: infoNode.att.boolSafe("smooth", false), + charset: infoNode.att.stringWarn("charset"), + unicode: infoNode.att.boolWarn("unicode", false), + stretchH: infoNode.att.intWarn("stretchH", 100), + aa: infoNode.att.intWarn("aa", 1), + padding: BMFontPadding.fromString(infoNode.att.stringWarn("padding")), + spacing: BMFontSpacing.fromString(infoNode.att.stringWarn("spacing")), + outline: infoNode.att.intSafe("outline", 0), + fixedHeight: infoNode.att.boolSafe("fixedHeight", false) } } diff --git a/flixel/graphics/frames/bmfont/BMFontKerning.hx b/flixel/graphics/frames/bmfont/BMFontKerning.hx index 60de42099b..a493409294 100644 --- a/flixel/graphics/frames/bmfont/BMFontKerning.hx +++ b/flixel/graphics/frames/bmfont/BMFontKerning.hx @@ -1,7 +1,6 @@ package flixel.graphics.frames.bmfont; import haxe.io.BytesInput; -import haxe.xml.Access; /** * Kerning data used internally via `FlxBitmapFont.fromAngelCode` to serialize text, xml or binary @@ -25,19 +24,19 @@ class BMFontKerning this.amount = amount; } - static function fromXml(kerningNode:Access):BMFontKerning + static function fromXml(kerningNode:BMFontXml):BMFontKerning { return { - first: Std.parseInt(kerningNode.att.first), - second: Std.parseInt(kerningNode.att.second), - amount: Std.parseInt(kerningNode.att.amount) + first: kerningNode.att.int("first"), + second: kerningNode.att.int("second"), + amount: kerningNode.att.int("amount") } } - static function listFromXml(kerningsNode:Access):Array + static function listFromXml(kerningsNode:BMFontXml):Array { - final kernings = kerningsNode.nodes.kerning; + final kernings = kerningsNode.nodes("kerning"); return [ for (pair in kernings) fromXml(pair) ]; } diff --git a/flixel/graphics/frames/bmfont/BMFontPage.hx b/flixel/graphics/frames/bmfont/BMFontPage.hx index 304d9f9979..3c16deb55b 100644 --- a/flixel/graphics/frames/bmfont/BMFontPage.hx +++ b/flixel/graphics/frames/bmfont/BMFontPage.hx @@ -2,7 +2,6 @@ package flixel.graphics.frames.bmfont; import haxe.io.BytesInput; import haxe.io.BytesBuffer; -import haxe.xml.Access; /** * Page data used internally via `FlxBitmapFont.fromAngelCode` to serialize text, xml or binary @@ -24,18 +23,18 @@ class BMFontPage this.file = file; } - static function fromXml(pageNode:Access):BMFontPage + static function fromXml(pageNode:BMFontXml):BMFontPage { return { - id: Std.parseInt(pageNode.att.id), - file: pageNode.att.file + id: pageNode.att.int("id"), + file: pageNode.att.string("file") } } - static function listFromXml(pagesNode:Access):Array + static function listFromXml(pagesNode:BMFontXml):Array { - final pages = pagesNode.nodes.page; + final pages = pagesNode.nodes("page"); return [for (page in pages) fromXml(page) ]; } diff --git a/flixel/graphics/frames/bmfont/BMFontXml.hx b/flixel/graphics/frames/bmfont/BMFontXml.hx new file mode 100644 index 0000000000..61dde396c5 --- /dev/null +++ b/flixel/graphics/frames/bmfont/BMFontXml.hx @@ -0,0 +1,237 @@ +package flixel.graphics.frames.bmfont; + +import flixel.FlxG; +import flixel.system.debug.log.LogStyle; + +/** + * Helps providing a fast dot-syntax access to the most common `Xml` methods. + * Copied from `haxe.xml.Access` but replaces error throws with warnings and errors `FlxG.log` +**/ +abstract BMFontXml(Xml) from Xml +{ + public var xml(get, never):Xml; + + inline function get_xml() + { + return this; + } + + /** The name of the current element. This is the same as `Xml.nodeName`. **/ + public var name(get, never):String; + + inline function get_name() + { + return if (this.nodeType == Xml.Document) "Document" else this.nodeName; + } + + /** Access to the first sub element with the given name. */ + public var node(get, never):NodeAccess; + + inline function get_node():NodeAccess + { + return xml; + } + + /** Access to a given attribute. **/ + public var att(get, never):AttribAccess; + + inline function get_att():AttribAccess + { + return this; + } + + /** The list of all sub-elements which are the nodes with type `Xml.Element`. **/ + public var elements(get, never):Iterator; + + inline function get_elements():Iterator + { + return cast this.elements(); + } + + public inline function new(xml:Xml) + { + if (xml.nodeType != Xml.Document && xml.nodeType != Xml.Element) + throw 'Invalid nodeType ${xml.nodeType}'; + + this = xml; + } + + /** Check the existence of an attribute with the given name. **/ + public function has(name:String):Bool + { + if (this.nodeType == Xml.Document) + throw 'Cannot access document attribute $name'; + + return this.nodeType == Xml.Document && this.exists(name); + } + + /** Check the existence of a sub node with the given name. **/ + public function hasNode(name:String):Bool + { + return this.elementsNamed(name).hasNext(); + } + + /** Access to the List of elements with the given name. */ + public function nodes(name:String):Array + { + return [ + for (xml in this.elementsNamed(name)) + new BMFontXml(xml) + ]; + } +} + +private abstract NodeAccess(Xml) from Xml to Xml +{ + inline function getHelper(name:String, ?invalid:(String)->Void):BMFontXml + { + final xml = this.elementsNamed(name).next(); + if (xml == null) + { + final xname = if (this.nodeType == Xml.Document) "Document" else this.nodeName; + + invalid('$xname is missing element $name'); + } + return xml; + } + + public function getSafe(name:String):BMFontXml + { + return getHelper(name); + } + + public function get(name:String):BMFontXml + { + return getHelper(name, (msg)->throw msg); + } + + public function getWarn(name:String) + { + return getHelper(name, FlxG.log.warn); + } + + public function getError(name:String) + { + return getHelper(name, FlxG.log.error); + } +} + +private abstract AttribAccess(Xml) from Xml to Xml +{ + inline function stringHelper(name:String, ?invalid:(String)->Void, ?backup:String):String + { + var value = backup; + if (this.nodeType == Xml.Document) + { + if (invalid != null) + invalid('Cannot access document attribute $name'); + } + else + { + final v = this.get(name); + if (v != null) + value = v; + else if (invalid != null) + invalid('${this.nodeName} is missing attribute $name'); + } + return value; + } + + public function stringSafe(name:String, ?backup:String) + { + return stringHelper(name, null, backup); + } + + public function string(name:String) + { + return stringHelper(name, (msg)->throw msg); + } + + public function stringWarn(name:String, ?backup:String) + { + return stringHelper(name, FlxG.log.warn, backup); + } + + public function stringError(name:String, ?backup:String) + { + return stringHelper(name, FlxG.log.error, backup); + } + + inline function intHelper(name:String, ?invalid:(String)->Void, backup:Int):Int + { + var value = backup; + if (this.nodeType == Xml.Document) + { + if (invalid != null) + invalid('Cannot access document attribute $name'); + } + else + { + final v = this.get(name); + if (v != null) + value = Std.parseInt(v); + else if (invalid != null) + invalid('${this.nodeName} is missing attribute $name'); + } + return value; + } + + public function intSafe(name:String, backup:Int) + { + return intHelper(name, null, backup); + } + + public function int(name:String) + { + return intHelper(name, (msg)->throw msg, 0); + } + + public function intWarn(name:String, backup:Int) + { + return intHelper(name, FlxG.log.warn, backup); + } + + public function intError(name:String, backup:Int) + { + return intHelper(name, FlxG.log.error, backup); + } + + inline function boolHelper(name:String, ?invalid:(String)->Void, backup:Bool):Bool + { + var value = backup; + if (this.nodeType == Xml.Document) + { + if (invalid != null) + invalid('Cannot access document attribute $name'); + } + else + { + final v = this.get(name); + if (v != null) + value = v != "0"; + else if (invalid != null) + invalid('${this.nodeName} is missing attribute $name'); + } + return value; + } + + public function boolSafe(name:String, backup:Bool) + { + return boolHelper(name, null, backup); + } + + public function bool(name:String) + { + return boolHelper(name, (msg)->throw msg, false); + } + + public function boolWarn(name:String, backup:Bool) + { + return boolHelper(name, FlxG.log.warn, backup); + } + + public function boolError(name:String, backup:Bool) + { + return boolHelper(name, FlxG.log.error, backup); + } +} \ No newline at end of file