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 }