/**
* Represents a font. Data is stored similarly to tilesets in an array, with the ability to remap characters
* that have a unicode point larger than the array can hold.
*/
class Font {
constructor( fontData ) {
/**
* The standard width for a character. Used as the default if none is specified for a character.
*/
this.standardWidth = 5;
/**
* Number of pixels between each character
*/
this.letterSpacing = 1;
/**
* The tile size of the tile sheet where the characters are drawn
*/
this.tileSize = 16;
/**
* The number of columns in the tile sheet
*/
this.width = 16;
/**
* The number of rows in the tile sheet
*/
this.height = 16;
/**
* The x origin in pixels of the character relative to the bottom left.
*/
this.originX = 1;
/**
* The y origin in pixels of the character relative to the bottom left.
*/
this.originY = 3;
/**
* Object mapping unicode points to character information.
* Used for changing a characters size or remapping unicode points larger than what fits on the tile sheet.
*/
this.charData = null;
/**
* Uint8ClampedArray of the tile sheet data.
* Generated by the constructor.
*/
this.data = null;
if ( fontData ) {
this.standardWidth = fontData.standardWidth;
this.letterSpacing = fontData.letterSpacing;
this.tileSize = fontData.tileSize;
this.width = fontData.width;
this.height = fontData.height;
this.originX = fontData.originX;
this.originY = fontData.originY;
this.charData = fontData.charData;
this.data = new Uint8ClampedArray( this.width * this.height * this.tileSize * this.tileSize );
const { data } = fontData;
let runPosition = 0;
let dataPosition = 0;
while ( runPosition < data.length ) {
const runLength = data[runPosition];
const paletteId = parseInt( data[runPosition + 1], 10 );
for ( let j = 0; j < runLength; j += 1 ) {
this.data[dataPosition] = paletteId;
dataPosition += 1;
}
runPosition += 2;
}
}
}
/**
* Get the base index in the data array for the character
* @param {number} charCode - the unicode point for the character
*/
baseIndexForChar( charCode ) {
let codePoint = charCode;
if ( charCode >= this.width * this.height ) {
const key = charCode.toString();
if ( this.charData && this.charData[key] ) {
if ( this.charData[key] !== undefined ) {
codePoint = this.charData[key].remap;
}
}
}
return codePoint * this.tileSize * this.tileSize;
}
/**
* Get the width of a character
* @param {number} charCode - the unicode point for the character
*/
widthForChar( charCode ) {
const charKey = charCode.toString();
if ( this.charData && this.charData[charKey] ) {
if ( this.charData[charKey].width !== undefined ) {
return this.charData[charKey].width;
}
}
return this.standardWidth;
}
}
export default Font;