/**
* DHTML Bitmap Fonts
* http://www.davidc.net/dhtml/bitmapfonts
*
* $Id: BitmapFont.js 130 2009-04-04 17:23:35Z david $
*
* Copyright (c) 2009 David C A Croft.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* This global variable is used to ensure a unique CSS class name for every instance.
*/
var _BitmapFont_UID = 0;
/**
* Constructs a new BitmapFont object.
*
* The parameter is an object containing the following keys:
* CharList, WidthList, RectList, OffsetList, KerningPairs, KerningValues,
* Image, ImageOver (optional), SpaceWidth, LineHeight.
*/
function BitmapFont(params)
{
this.fontDebug = false;
this.font = params;
// load images when page loaded
$(function() {
$('').attr('src', params.Image);
if (params.ImageOver) {
$('').attr('src', params.ImageOver);
}
});
// create a CSS class for the font characters
this.uid = _BitmapFont_UID ++;
var wordCss = '';
var letterCss = '';
letterCss += ' background-image: url(' + this.font.Image + ');';
letterCss += ' position: absolute;';
wordCss += ' position: relative; display: inline-block; zoom: 1; *display: inline;';
if (this.fontDebug) {
wordCss += ' border: 1px solid orange;';
letterCss += ' border: 1px solid green;';
}
this.createCSSClass('.fontword_' + this.uid, wordCss);
this.createCSSClass('.fontword_' + this.uid + ">DIV", letterCss);
if (this.font.ImageOver) {
this.createCSSClass('.hoverable:hover .fontword_' + this.uid + ">DIV", 'background-image: url(' + this.font.ImageOver + ');');
}
}
/**
* Draws the request text into a new DIV. Returns a jQuery object containing the DIV,
* for the caller to append to the DOM as required.
*/
BitmapFont.prototype.drawText = function (str)
{
var parentDiv = $('
');
var currentWord = this.beginWord(parentDiv);
var lastch = '';
var xPos = 0;
for (var i=0; i < str.length; ++i) {
var ch = str.charAt(i);
var choffset = this.findCharOffset(ch);
if (choffset >= 0) {
var chspan = $('
').appendTo(currentWord);
chspan.css('width', this.font.RectList[choffset][2] + 'px');
chspan.css('height', this.font.RectList[choffset][3] + 'px');
chspan.css('backgroundPosition', '-' + this.font.RectList[choffset][0] + 'px -' + this.font.RectList[choffset][1] + 'px');
var left = this.font.OffsetList[choffset][0] + this.getKerning(lastch, ch);
chspan.css('left', (xPos + left) + 'px');
chspan.css('top', this.font.OffsetList[choffset][1] + 'px');
lastch = ch;
xPos += this.font.RectList[choffset][2] + left;
}
else if (ch == ' ') {
currentWord.css('marginRight', this.font.SpaceWidth + 'px');
this.endWord(currentWord, xPos);
currentWord = this.beginWord(parentDiv);
lastch = '';
xPos = 0;
}
}
this.endWord(currentWord, xPos);
$('
').css('clear', 'left').appendTo(parentDiv);
return parentDiv;
}
/**
* Private function. Locates the required character in CharList.
*/
BitmapFont.prototype.findCharOffset = function (ch)
{
for (var i=0; i < this.font.CharList.length; ++i) {
if (this.font.CharList[i] == ch) {
return i;
}
}
return -1;
}
/**
* Private function. Determines the kerning offset for a given letter pair.
*/
BitmapFont.prototype.getKerning = function (ch1, ch2)
{
if (ch1 == '' || ch2 == '') return 0;
var search = ch1 + ch2;
for (var i=0; i < this.font.KerningPairs.length; ++i) {
if (this.font.KerningPairs[i] == search) {
return this.font.KerningValues[i];
}
}
return 0;
}
/**
* Private function. Initalises a new word.
*/
BitmapFont.prototype.beginWord = function (parentDiv)
{
var currentWord = $('
').appendTo(parentDiv);
currentWord.addClass('fontword_' + this.uid);
currentWord.css('height', this.font.LineHeight + 'px');
return currentWord;
}
/**
* Private function. Completes a word.
*/
BitmapFont.prototype.endWord = function (currentWord, xPos)
{
currentWord.css('width', xPos + 'px');
}
/**
* Private function. Creates a new CSS rule for the given selector.
* Credit to "Sam" for the original code.
* Source URL: http://webdevel.blogspot.com/2006/06/create-css-class-javascript.html
*/
BitmapFont.prototype.createCSSClass = function (selector, style)
{
// using information found at: http://www.quirksmode.org/dom/w3c_css.html
// doesn't work in older versions of Opera (< 9) due to lack of styleSheets support
if (!document.styleSheets) return;
if (document.getElementsByTagName("head").length == 0) return;
var stylesheet;
var mediaType;
if (document.styleSheets.length > 0) {
for (var i = 0; i
document.getElementsByTagName("head")[0].appendChild(styleSheetElement);
// select it
for (var i = 0; i