package sprites.util;
import sprites.Sprite;
import sprites.Texture;
import java.util.HashMap;
import java.util.Map;
public class BitmapFont {
private static char[] lowercase = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z' };
private static char[] uppercase = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z' };
private static char[] signs = { ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')',
'*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', ':', ';', '<', '=', '>', '?' };
private static char[] extra = { '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'};
private Map<Character, Sprite> glyphMap;
private float glyphWidthRatio;
private float glyphHeightRatio;
private int glyphWidth;
private int glyphHeight;
private Texture font;
/**
* Creates a new BitmapFont where each Glyph has a fixed height and width.
* @param font
* @param glyphWidth
* @param glyphHeight
*/
public BitmapFont(Texture font, int glyphWidth,
int glyphHeight) {
this.font = font;
this.glyphWidth = glyphWidth;
this.glyphHeight = glyphHeight;
this.glyphWidthRatio = this.font.getWidthRatio() / 32f;
this.glyphHeightRatio = this.font.getHeightRatio() / 4f;
this.glyphMap = new HashMap<Character, Sprite>();
for(int i = 0; i < lowercase.length ; i++){
Sprite g = new Sprite(font, glyphWidth, glyphHeight, i*this.glyphWidthRatio, 0, this.glyphWidthRatio, this.glyphHeightRatio);
this.glyphMap.put(lowercase[i], g);
}
for(int i = 0; i < uppercase.length ; i++){
Sprite g = new Sprite(font, glyphWidth, glyphHeight, i*this.glyphWidthRatio, this.glyphHeightRatio, this.glyphWidthRatio, this.glyphHeightRatio);
this.glyphMap.put(uppercase[i], g);
}
for(int i = 0; i < signs.length ; i++){
Sprite g = new Sprite(font, glyphWidth, glyphHeight, i*this.glyphWidthRatio, 2*this.glyphHeightRatio, this.glyphWidthRatio, this.glyphHeightRatio);
this.glyphMap.put(signs[i], g);
}
for(int i = 0; i < extra.length ; i++){
Sprite g = new Sprite(font, glyphWidth, glyphHeight, i*this.glyphWidthRatio, 3*this.glyphHeightRatio, this.glyphWidthRatio, this.glyphHeightRatio);
this.glyphMap.put(extra[i], g);
}
}
/**
* Creates a new BitmapFont, where each Glyph has a fixed height but differs in width.
* @param font
* @param glyphHeight
* @param glyphWidths
*/
public BitmapFont(Texture font, int glyphHeight, int[][] glyphWidths){
if(glyphWidths.length != 4 && glyphWidths[0].length != 0){
throw new IllegalArgumentException("The array defining the glyph widths needs to be of dimension 4x32");
}
this.font = font;
this.glyphHeight = glyphHeight;
this.glyphHeightRatio = this.font.getHeightRatio() / 4f;
this.glyphWidthRatio = 0;
this.glyphMap = new HashMap<Character, Sprite>();
float tpos = 0;
int width;
float widthInTexture;
for(int i = 0; i < lowercase.length; i++){
width = glyphWidths[0][i];
widthInTexture = (((float) width) / font.getWidth()) * font.getWidthRatio();
Sprite g = new Sprite(font, glyphWidths[0][i], glyphHeight, tpos, 0, widthInTexture, this.glyphHeightRatio);
tpos += widthInTexture;
this.glyphMap.put(lowercase[i], g);
}
tpos = 0;
for(int i = 0; i < uppercase.length; i++){
width = glyphWidths[1][i];
widthInTexture = (((float) width) / font.getWidth()) * font.getWidthRatio();
Sprite g = new Sprite(font, glyphWidths[1][i], glyphHeight, tpos, this.glyphHeightRatio, widthInTexture, this.glyphHeightRatio);
tpos += widthInTexture;
this.glyphMap.put(uppercase[i], g);
}
tpos = 0;
for(int i = 0; i < signs.length; i++){
width = glyphWidths[2][i];
widthInTexture = (((float) width) / font.getWidth()) * font.getWidthRatio();
Sprite g = new Sprite(font, glyphWidths[2][i], glyphHeight, tpos, 2*this.glyphHeightRatio, widthInTexture, this.glyphHeightRatio);
tpos += widthInTexture;
this.glyphMap.put(signs[i], g);
}
tpos = 0;
for(int i = 0; i < extra.length; i++){
width = glyphWidths[3][i];
widthInTexture = (((float) width) / font.getWidth()) * font.getWidthRatio();
Sprite g = new Sprite(font, glyphWidths[3][i], glyphHeight, tpos, 3*this.glyphHeightRatio, widthInTexture, this.glyphHeightRatio);
tpos += widthInTexture;
this.glyphMap.put(extra[i], g);
}
}
public Sprite getGlyph(char c){
return this.glyphMap.get(c);
}
/**
* Returns either the general width of every glyph in this font or 0 if the width of each glyph differs from another.
* @return
*/
public int getGlyphWidth() {
return glyphWidth;
}
public int getGlyphHeight() {
return glyphHeight;
}
public int getStringWidth(String string){
if(string.length() < 1){
return 0;
}
int length = 0;
int maxLength = 0;
for(int i = 0; i < string.length() ; i++){
char c = string.charAt(i);
if(c == '\n'){
maxLength = length > maxLength ? length : maxLength;
length = 0;
} else {
Sprite sprite = this.getGlyph(c);
length += sprite.getWidth();
}
}
maxLength = length > maxLength ? length : maxLength;
return maxLength;
}
public int getStringHeight(String string){
int height = this.glyphHeight;
for(int i = 0; i < string.length() ; i++){
char c = string.charAt(i);
if(c == '\n'){
height += this.glyphHeight;
}
}
return height;
}
}