// ================================================================================================= // // Starling Framework // Copyright 2011 Gamua OG. All Rights Reserved. // // This program is free software. You can redistribute and/or modify it // in accordance with the terms of the accompanying license agreement. // // ================================================================================================= package starling.text { import flash.geom.Rectangle; import flash.utils.Dictionary; import starling.display.DisplayObject; import starling.display.Image; import starling.display.Sprite; import starling.textures.Texture; import starling.utils.HAlign; import starling.utils.VAlign; /** The BitmapFont class parses bitmap font files and arranges the glyphs * in the form of a text. * * The class parses the XML format as it is used in the * AngelCode Bitmap Font Generator or * the Glyph Designer. * This is what the file format looks like: * *
* <font>
* <info face="BranchingMouse" size="40" />
* <common lineHeight="40" />
* <pages> <!-- currently, only one page is supported -->
* <page id="0" file="texture.png" />
* </pages>
* <chars>
* <char id="32" x="60" y="29" width="1" height="1" xoffset="0" yoffset="27" xadvance="8" />
* <char id="33" x="155" y="144" width="9" height="21" xoffset="0" yoffset="6" xadvance="9" />
* </chars>
* <kernings> <!-- Kerning is optional -->
* <kerning first="83" second="83" amount="-4"/>
* </kernings>
* </font>
*
*
* Pass an instance of this class to the method registerBitmapFont of the
* TextField class. Then, set the fontName property of the text field to the
* name value of the bitmap font. This will make the text field use the bitmap
* font.
*/
public class BitmapFont
{
/** Use this constant for the fontSize property of the TextField class to
* render the bitmap font in exactly the size it was created. */
public static const NATIVE_SIZE:int = -1;
private static const CHAR_SPACE:int = 32;
private static const CHAR_TAB:int = 9;
private static const CHAR_NEWLINE:int = 10;
private var mTexture:Texture;
private var mChars:Dictionary;
private var mName:String;
private var mSize:Number;
private var mLineHeight:Number;
/** Creates a bitmap font by parsing an XML file and uses the specified texture. */
public function BitmapFont(texture:Texture, fontXml:XML=null)
{
mName = "unknown";
mLineHeight = mSize = 14;
mTexture = texture;
mChars = new Dictionary();
if (fontXml)
parseFontXml(fontXml);
}
/** Disposes the texture of the bitmap font! */
public function dispose():void
{
if (mTexture)
mTexture.dispose();
}
private function parseFontXml(fontXml:XML):void
{
mName = fontXml.info.attribute("face");
mSize = parseFloat(fontXml.info.attribute("size"));
mLineHeight = parseFloat(fontXml.common.attribute("lineHeight"));
if (mSize <= 0)
{
trace("[Starling] Warning: invalid font size in '" + mName + "' font.");
mSize = (mSize == 0.0 ? 16.0 : mSize * -1.0);
}
for each (var charElement:XML in fontXml.chars.char)
{
var id:int = parseInt(charElement.attribute("id"));
var xOffset:Number = parseFloat(charElement.attribute("xoffset"));
var yOffset:Number = parseFloat(charElement.attribute("yoffset"));
var xAdvance:Number = parseFloat(charElement.attribute("xadvance"));
var region:Rectangle = new Rectangle();
region.x = parseFloat(charElement.attribute("x"));
region.y = parseFloat(charElement.attribute("y"));
region.width = parseFloat(charElement.attribute("width"));
region.height = parseFloat(charElement.attribute("height"));
var texture:Texture = Texture.fromTexture(mTexture, region);
var bitmapChar:BitmapChar = new BitmapChar(id, texture, xOffset, yOffset, xAdvance);
addChar(id, bitmapChar);
}
for each (var kerningElement:XML in fontXml.kernings.kerning)
{
var first:int = parseInt(kerningElement.attribute("first"));
var second:int = parseInt(kerningElement.attribute("second"));
var amount:Number = parseFloat(kerningElement.attribute("amount"));
getChar(second).addKerning(first, amount);
}
}
/** Returns a single bitmap char with a certain character ID. */
public function getChar(charID:int):BitmapChar
{
return mChars[charID];
}
/** Adds a bitmap char with a certain character ID. */
public function addChar(charID:int, bitmapChar:BitmapChar):void
{
mChars[charID] = bitmapChar;
}
/** Creates a display object that contains the given text by arranging individual chars. */
public function createDisplayObject(width:Number, height:Number, text:String,
fontSize:Number=-1, color:uint=0xffffff,
hAlign:String="center", vAlign:String="center",
autoScale:Boolean=true,
kerning:Boolean=true):DisplayObject
{
if (fontSize == NATIVE_SIZE) fontSize = mSize;
var lineContainer:Sprite;
var finished:Boolean = false;
while (!finished)
{
var scale:Number = fontSize / mSize;
lineContainer = new Sprite();
if (mLineHeight * scale <= height)
{
var containerWidth:Number = width / scale;
var containerHeight:Number = height / scale;
lineContainer.scaleX = lineContainer.scaleY = scale;
var lastWhiteSpace:int = -1;
var lastCharID:int = -1;
var currentX:Number = 0;
var currentLine:Sprite = new Sprite();
var numChars:int = text.length;
for (var i:int=0; i