001 package org.bukkit.map; 002 003 import java.util.HashMap; 004 005 /** 006 * Represents a bitmap font drawable to a map. 007 */ 008 public class MapFont { 009 010 private final HashMap<Character, CharacterSprite> chars = new HashMap<Character, CharacterSprite>(); 011 private int height = 0; 012 protected boolean malleable = true; 013 014 /** 015 * Set the sprite for a given character. 016 * 017 * @param ch The character to set the sprite for. 018 * @param sprite The CharacterSprite to set. 019 * @throws IllegalStateException if this font is static. 020 */ 021 public void setChar(char ch, CharacterSprite sprite) { 022 if (!malleable) { 023 throw new IllegalStateException("this font is not malleable"); 024 } 025 026 chars.put(ch, sprite); 027 if (sprite.getHeight() > height) { 028 height = sprite.getHeight(); 029 } 030 } 031 032 /** 033 * Get the sprite for a given character. 034 * 035 * @param ch The character to get the sprite for. 036 * @return The CharacterSprite associated with the character, or null if 037 * there is none. 038 */ 039 public CharacterSprite getChar(char ch) { 040 return chars.get(ch); 041 } 042 043 /** 044 * Get the width of the given text as it would be rendered using this 045 * font. 046 * 047 * @param text The text. 048 * @return The width in pixels. 049 */ 050 public int getWidth(String text) { 051 if (!isValid(text)) { 052 throw new IllegalArgumentException("text contains invalid characters"); 053 } 054 055 if (text.length() == 0){ 056 return 0; 057 } 058 059 int result = 0; 060 for (int i = 0; i < text.length(); ++i) { 061 result += chars.get(text.charAt(i)).getWidth(); 062 } 063 result += text.length() - 1; // Account for 1px spacing between characters 064 065 return result; 066 } 067 068 /** 069 * Get the height of this font. 070 * 071 * @return The height of the font. 072 */ 073 public int getHeight() { 074 return height; 075 } 076 077 /** 078 * Check whether the given text is valid. 079 * 080 * @param text The text. 081 * @return True if the string contains only defined characters, false 082 * otherwise. 083 */ 084 public boolean isValid(String text) { 085 for (int i = 0; i < text.length(); ++i) { 086 char ch = text.charAt(i); 087 if (ch == '\u00A7' || ch == '\n') continue; 088 if (chars.get(ch) == null) return false; 089 } 090 return true; 091 } 092 093 /** 094 * Represents the graphics for a single character in a MapFont. 095 */ 096 public static class CharacterSprite { 097 098 private final int width; 099 private final int height; 100 private final boolean[] data; 101 102 public CharacterSprite(int width, int height, boolean[] data) { 103 this.width = width; 104 this.height = height; 105 this.data = data; 106 107 if (data.length != width * height) { 108 throw new IllegalArgumentException("size of data does not match dimensions"); 109 } 110 } 111 112 /** 113 * Get the value of a pixel of the character. 114 * 115 * @param row The row, in the range [0,8). 116 * @param col The column, in the range [0,8). 117 * @return True if the pixel is solid, false if transparent. 118 */ 119 public boolean get(int row, int col) { 120 if (row < 0 || col < 0 || row >= height || col >= width) return false; 121 return data[row * width + col]; 122 } 123 124 /** 125 * Get the width of the character sprite. 126 * 127 * @return The width of the character. 128 */ 129 public int getWidth() { 130 return width; 131 } 132 133 /** 134 * Get the height of the character sprite. 135 * 136 * @return The height of the character. 137 */ 138 public int getHeight() { 139 return height; 140 } 141 142 } 143 144 }