Skip to content

Instantly share code, notes, and snippets.

@ruby0x1
Created January 27, 2014 00:28
Show Gist options
  • Save ruby0x1/8641341 to your computer and use it in GitHub Desktop.
Save ruby0x1/8641341 to your computer and use it in GitHub Desktop.
random code from bmfont loader for haxe
public var dimensions : Vector;
public var spacing : Float = 0.0;
public var line_height : Float = 0.0;
public var font_size : Float = 0.0;
public var font_character_count : Int = 0;
public var pages : Map<Int, Texture>;
public var characters : Map<Int, Character>;
public var kernings : Map< KerningKey, Int >;
public var scale : Vector;
private var line_widths : Array<Float>;
typedef Character = {
var id : Int;
var x : Int;
var y : Int;
var width : Int;
var height : Int;
var xoffset : Int;
var yoffset : Int;
var xadvance : Int;
var page : Int;
}
typedef KerningKey = {
var glyph : Int;
var index : Int;
}
//this is not the best option
typedef KeyValuePair = {
var key : String;
var value : String;
}
//other stuff
public function load_from_string( _bitmap_file : String = '',
_folder : String = 'assets/',
?onloaded : Void->Void = null,
?custom_pages:Array<Texture> = null ) {
var lines : Array<String> = _bitmap_file.split("\n");
var _pages : Array<Dynamic> = new Array<Dynamic>();
//store the listener
onload = onloaded;
for(line in lines) {
var _initial_tokens = line.split(" ");
switch (_initial_tokens[0]) {
case "info":
_initial_tokens.remove("info");
var _items = _tokenize_font_line(_initial_tokens);
var _id = _items["face"].value;
if(_id.indexOf('"') != -1) {
_id = StringTools.replace(_id,'"', '');
}
//font size value for scale later
font_size = Std.parseInt(_items["size"].value);
id = _id;
case "common":
_initial_tokens.remove("common");
var _items = _tokenize_font_line(_initial_tokens);
//parse the line height
line_height = Std.parseInt( _items["lineHeight"].value );
case "page":
_initial_tokens.remove("page");
var _items = _tokenize_font_line(_initial_tokens);
//parse the page info
var _id = Std.parseInt( _items["id"].value );
var _file = _items["file"].value;
//remove arbitrary quotes ""
if(_file.indexOf('"') != -1) {
_file = StringTools.replace(_file,'"', '');
}
//remove trailing end line
_file = _file.substr(0,_file.length-1);
//Store the texture id's in the list
_pages.push({id:_id, file:_file});
//Set this so the count is maintained
pages.set(_id, null);
case "chars":
_initial_tokens.remove("chars");
var _items = _tokenize_font_line(_initial_tokens);
//parse the character count
font_character_count = Std.parseInt( _items["count"].value );
case "char":
_initial_tokens.remove("char");
var _items = _tokenize_font_line(_initial_tokens);
//parse character info
var _character_info : Character = {
id : Std.parseInt(_items["id"].value),
x : Std.parseInt(_items["x"].value),
y : Std.parseInt(_items["y"].value),
width : Std.parseInt(_items["width"].value),
height : Std.parseInt(_items["height"].value),
xoffset : Std.parseInt(_items["xoffset"].value),
yoffset : Std.parseInt(_items["yoffset"].value),
xadvance : Std.parseInt(_items["xadvance"].value),
page : Std.parseInt(_items["page"].value)
};
set_character(_character_info.id, _character_info);
case "kerning":
_initial_tokens.remove("char");
var _items = _tokenize_font_line(_initial_tokens);
var first = Std.parseInt(_items["first"].value);
var second = Std.parseInt(_items["second"].value);
var amount = Std.parseInt(_items["amount"].value);
set_kerning( first, second, amount );
} //switch
} //line in lines
//once all loaded, we can load up the pages textures
//but only if the custom pages wasn't specified
if(custom_pages == null) {
for(_page_item in _pages) {
//fetch the texture
var _t = Luxe.loadTexture( _folder + _page_item.file, one_page_loaded );
//store the texture in the map for use
pages.set(_page_item.id, _t);
}
} else {
var _id : Int = 0;
for(_page in custom_pages) {
pages.set(_id, _page);
++_id;
} //for each custom page
//still do the callback in case
on_all_pages_loaded();
} //if custom pages
} //load_from_string
public function set_kerning(_glyph:Int, _index:Int, _amount:Int) {
kernings.set({ glyph:_glyph, index:_index}, _amount);
}
public function get_kerning(_glyph:Int, _index:Int) {
var key = { glyph:_glyph, index:_index };
if(kernings.exists(key)) {
return kernings.get(key);
} else {
return 0;
}
}
private function _tokenize_font_line(_line_tokens:Array<String>) {
var _item_map : Map<String, KeyValuePair> = new Map();
for(_line_token in _line_tokens) {
var _items = _line_token.split("=");
_item_map.set( _items[0], { key:_items[0], value:_items[1] } );
}
return _item_map;
}
public function set_character( _index:Int, _char_info : Character ) {
characters.set( _index, _char_info);
}
//return the size of a piece of text for this font, at the given scale
public function get_text_dimensions(_string:String, _scale:Vector) {
// Set up variables
//line_widths caches the sizes for quicker renderering in a loop
line_widths.splice(0, line_widths.length);
//for calculating the entire size
var cumulative_x : Float = 0.0;
var cumulative_y : Float = 0.0;
var max_x : Float = 0.0;
var spc = characters[(' ').charCodeAt(0)];
//Iterate over each character, calculating size
for( i in 0 ... _string.length) {
var glyph = _string.charAt(i);
if( glyph == '\n' ){
cumulative_y += line_height * _scale.y;
max_x = Math.max( max_x, cumulative_x );
line_widths.push(cumulative_x);
cumulative_x = 0;
continue;
}
var c = characters[ glyph.charCodeAt(0) ];
// var _x : Float = cumulative_x + ( c.xoffset * _scale.x );
// var _y : Float = cumulative_y + ( c.yoffset * _scale.y );
// var _w : Float = c.width * _scale.x;
// var _h : Float = c.height * _scale.y;
var _x_advance : Float = 0.0;
if(c != null) {
_x_advance = c.xadvance;
}
//adjust culmative x value
var x_inc : Float = _x_advance;
// if( i < _string.length - 1 ){
// x_inc += get_kerning( glyph.charCodeAt(0), _string.charAt(i).charCodeAt(0) );
// }
if( glyph == '\t' ){
x_inc += spc.xadvance * 4;
}
cumulative_x += x_inc * _scale.x;
} //for each char
//account for the last line/only line
line_widths.push(cumulative_x);
max_x = Math.max( max_x, cumulative_x );
//Add one line of height. We do this because we want the
//total height and the culmative y is (at this point)
//the y at the *top* of the last line.
cumulative_y += line_height * _scale.y;
return new Vector( max_x, cumulative_y );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment