3 #include "../loader/Interpreter.h"
4 #include "../loader/TypeDescription.h"
11 using loader::FieldDescription;
12 using loader::Interpreter;
13 using loader::TypeDescription;
18 int Font::StringWidth(const char *s) const {
20 for (int i(0); s[i]; ++i) {
30 return (width < col ? col : width) * CharWidth();
33 int Font::StringHeight(const char *s) const {
43 return height * CharHeight();
47 void Font::DrawChar(char c, SDL_Surface *dest, const Vector<int> &position) const {
50 int col(colOffset + (c % 0x10));
51 int row(rowOffset + (c / 0x10));
52 sprite->Draw(dest, position, col, row);
55 void Font::DrawString(const char *s, SDL_Surface *dest, const Vector<int> &positionIn, int maxWidth) const {
58 Vector<int> position(positionIn);
59 Vector<int> lineHead(positionIn);
60 Vector<int> step(CharWidth(), 0);
61 Vector<int> lineBreak(0, CharHeight());
62 for (int i(0), col(0); s[i] && (maxWidth <= 0 || col < maxWidth); ++i) {
64 lineHead += lineBreak;
68 DrawChar(s[i], dest, position);
75 void Font::DrawStringRight(const char *s, SDL_Surface *dest, const Vector<int> &positionIn, int maxWidth) const {
76 // NOTE: this does not handle line breaks
81 while (length < maxWidth && s[length] != '\0') {
85 length = std::strlen(s);
87 Vector<int> position(positionIn.X() - length * CharWidth(), positionIn.Y());
89 DrawString(s, dest, position, length);
92 void Font::DrawDigit(int digit, SDL_Surface *dest, const Vector<int> &position) const {
95 DrawChar(digit + 0x30, dest, position);
98 void Font::DrawNumber(int numberIn, SDL_Surface *dest, const Vector<int> &positionIn, int digits) const {
101 int number(numberIn);
102 if (digits > 0 && numberIn >= pow(10.0, digits)) {
103 numberIn = pow(10.0, digits) - 1;
106 Vector<int> position(positionIn);
107 Vector<int> step(sprite->Width(), 0);
111 while (number < pow(10.0, i) && i > 0) {
118 while (m <= number) {
124 DrawDigit((number / m) % 10, dest, position);
129 void Font::DrawNumberRight(int number, SDL_Surface *dest, const Vector<int> &positionIn, int digits) const {
132 Vector<int> position(positionIn);
134 position.X() -= digits * CharWidth();
135 } else if (number == 0) {
136 position.X() -= CharWidth();
138 for (int i = number; i > 0; i /= 10) {
139 position.X() -= CharWidth();
143 DrawNumber(number, dest, position, digits);
147 void Font::CreateTypeDescription() {
150 TypeDescription &td(TypeDescription::Create(TYPE_ID, "Font"));
152 "Simple font with fixed-width characters using a sprite for rendering.\n"
153 "Characters from strings are mapped as follows:\n"
154 "<pre>sprite column = column offset + (character % 16)\n"
155 "sprite row = row offset + (character / 16)</pre>");
156 td.SetConstructor(&Construct);
157 td.SetSize(sizeof(Font));
159 td.AddField("sprite", FieldDescription(((char *)&f.sprite) - ((char *)&f), Sprite::TYPE_ID).SetReferenced().SetDescription("a sprite where each tile corresponds to a character"));
160 td.AddField("columnoffset", FieldDescription(((char *)&f.colOffset) - ((char *)&f), Interpreter::NUMBER_ID).SetDescription("offset of the column of the first character"));
161 td.AddField("rowoffset", FieldDescription(((char *)&f.rowOffset) - ((char *)&f), Interpreter::NUMBER_ID).SetDescription("offset of the row of the first character"));
164 void Font::Construct(void *data) {