Skip to content

Instantly share code, notes, and snippets.

@PrimaryFeather
Last active November 21, 2017 04:34
Show Gist options
  • Save PrimaryFeather/aae25c1d92a5a0c18d655415e1488ed2 to your computer and use it in GitHub Desktop.
Save PrimaryFeather/aae25c1d92a5a0c18d655415e1488ed2 to your computer and use it in GitHub Desktop.
A BitmapFont extension that allows text to be colored by encasing it in tags like {style color=#123456}this{/style}.
package starling.extensions
{
import starling.display.Image;
import starling.display.MeshBatch;
import starling.text.BitmapCharLocation;
import starling.text.BitmapFont;
import starling.text.TextFormat;
import starling.text.TextOptions;
import starling.textures.Texture;
public class StyledBitmapFont extends BitmapFont
{
private var _helperImage:Image;
public function StyledBitmapFont(texture:Texture=null, fontXml:XML=null)
{
super(texture, fontXml);
_helperImage = new Image(texture);
}
override public function fillMeshBatch(meshBatch:MeshBatch, width:Number, height:Number,
text:String, format:TextFormat,
options:TextOptions = null):void
{
var colorSequence:Array = [];
var strippedText:String = parseText(text, format.color, colorSequence);
var charLocations:Vector.<BitmapCharLocation> = arrangeChars(
width, height, strippedText, format, options);
var charLocation:BitmapCharLocation;
var numChars:int = charLocations.length;
var color:uint = format.color;
for (var i:int=0; i<numChars; ++i)
{
charLocation = charLocations[i];
while (colorSequence[0] <= charLocation.index)
{
colorSequence.shift();
color = colorSequence.shift();
}
_helperImage.texture = charLocation.char.texture;
_helperImage.readjustSize();
_helperImage.x = charLocation.x;
_helperImage.y = charLocation.y;
_helperImage.scale = charLocation.scale;
_helperImage.color = color;
meshBatch.addMesh(_helperImage);
}
BitmapCharLocation.rechargePool();
}
private static function parseText(text:String, defaultColor:uint,
sequence:Array):String
{
const startTag:RegExp = /{style color=#(.*?)}/g;
const endTag:RegExp = /{\/style}/g;
const colorStack:Array = [defaultColor];
const matches:Array = [];
addMatches(startTag, true);
addMatches(endTag, false);
matches.sort(byIndex);
var outText:String = "";
var currentPos:int = 0;
var totalTagLength:int = 0;
var match:Object;
sequence.push(0, defaultColor);
for each (match in matches)
{
if (match.isStartTag)
colorStack.push(parseInt(match[1], 16));
else
colorStack.pop();
sequence.push(match.index - totalTagLength, colorStack[colorStack.length-1]);
outText += text.substring(currentPos, match.index);
currentPos = match.index + match[0].length;
totalTagLength += match[0].length;
}
outText += text.substring(currentPos, text.length);
return outText;
function addMatches(regex:RegExp, isStartTag:Boolean):void
{
var match:Object;
while ((match = regex.exec(text)) != null)
{
match.isStartTag = isStartTag;
matches[matches.length] = match;
regex.lastIndex = match.index + 1;
}
}
function byIndex(a:Object, b:Object):int
{
return a.index < b.index ? -1 : 1;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment