uberpong/dev/lib/impact/font.js
2013-04-03 21:02:06 +02:00

153 lines
3.2 KiB
JavaScript
Executable file

ig.module(
'impact.font'
)
.requires(
'impact.image'
)
.defines(function(){ "use strict";
ig.Font = ig.Image.extend({
widthMap: [],
indices: [],
firstChar: 32,
alpha: 1,
letterSpacing: 1,
lineSpacing: 0,
onload: function( ev ) {
this._loadMetrics( this.data );
this.parent( ev );
},
widthForString: function( text ) {
// Multiline?
if( text.indexOf('\n') !== -1 ) {
var lines = text.split( '\n' );
var width = 0;
for( var i = 0; i < lines.length; i++ ) {
width = Math.max( width, this._widthForLine(lines[i]) );
}
return width;
}
else {
return this._widthForLine( text );
}
},
_widthForLine: function( text ) {
var width = 0;
for( var i = 0; i < text.length; i++ ) {
width += this.widthMap[text.charCodeAt(i) - this.firstChar] + this.letterSpacing;
}
return width;
},
heightForString: function( text ) {
return text.split('\n').length * (this.height + this.lineSpacing);
},
draw: function( text, x, y, align ) {
if( typeof(text) != 'string' ) {
text = text.toString();
}
// Multiline?
if( text.indexOf('\n') !== -1 ) {
var lines = text.split( '\n' );
var lineHeight = this.height + this.lineSpacing;
for( var i = 0; i < lines.length; i++ ) {
this.draw( lines[i], x, y + i * lineHeight, align );
}
return;
}
if( align == ig.Font.ALIGN.RIGHT || align == ig.Font.ALIGN.CENTER ) {
var width = this._widthForLine( text );
x -= align == ig.Font.ALIGN.CENTER ? width/2 : width;
}
if( this.alpha !== 1 ) {
ig.system.context.globalAlpha = this.alpha;
}
for( var i = 0; i < text.length; i++ ) {
var c = text.charCodeAt(i);
x += this._drawChar( c - this.firstChar, x, y );
}
if( this.alpha !== 1 ) {
ig.system.context.globalAlpha = 1;
}
ig.Image.drawCount += text.length;
},
_drawChar: function( c, targetX, targetY ) {
if( !this.loaded || c < 0 || c >= this.indices.length ) { return 0; }
var scale = ig.system.scale;
var charX = this.indices[c] * scale;
var charY = 0;
var charWidth = this.widthMap[c] * scale;
var charHeight = (this.height-2) * scale;
ig.system.context.drawImage(
this.data,
charX, charY,
charWidth, charHeight,
ig.system.getDrawPos(targetX), ig.system.getDrawPos(targetY),
charWidth, charHeight
);
return this.widthMap[c] + this.letterSpacing;
},
_loadMetrics: function( image ) {
// Draw the bottommost line of this font image into an offscreen canvas
// and analyze it pixel by pixel.
// A run of non-transparent pixels represents a character and its width
this.height = image.height-1;
this.widthMap = [];
this.indices = [];
var px = ig.getImagePixels( image, 0, image.height-1, image.width, 1 );
var currentChar = 0;
var currentWidth = 0;
for( var x = 0; x < image.width; x++ ) {
var index = x * 4 + 3; // alpha component of this pixel
if( px.data[index] > 127 ) {
currentWidth++;
}
else if( px.data[index] < 128 && currentWidth ) {
this.widthMap.push( currentWidth );
this.indices.push( x-currentWidth );
currentChar++;
currentWidth = 0;
}
}
this.widthMap.push( currentWidth );
this.indices.push( x-currentWidth );
}
});
ig.Font.ALIGN = {
LEFT: 0,
RIGHT: 1,
CENTER: 2
};
});