]> git.localhorst.tv Git - l2e.git/blob - src/graphics/Font.cpp
handle line breaks in Font::DrawString
[l2e.git] / src / graphics / Font.cpp
1 /*
2  * Font.cpp
3  *
4  *  Created on: Aug 8, 2012
5  *      Author: holy
6  */
7
8 #include "Font.h"
9
10 #include "../loader/Interpreter.h"
11 #include "../loader/TypeDescription.h"
12
13 #include <cmath>
14 #include <iostream>
15
16 using geometry::Vector;
17 using loader::FieldDescription;
18 using loader::Interpreter;
19 using loader::TypeDescription;
20 using std::pow;
21
22 namespace graphics {
23
24 void Font::DrawChar(char c, SDL_Surface *dest, const Vector<int> &position) const {
25         if (!sprite) return;
26
27         int col(colOffset + (c % 0x10));
28         int row(rowOffset + (c / 0x10));
29         sprite->Draw(dest, position, col, row);
30 }
31
32 void Font::DrawString(const char *s, SDL_Surface *dest, const Vector<int> &positionIn, int maxWidth) const {
33         if (!sprite) return;
34
35         Vector<int> position(positionIn);
36         Vector<int> lineHead(positionIn);
37         Vector<int> step(CharWidth(), 0);
38         Vector<int> lineBreak(0, CharHeight());
39         for (int i(0), col(0); s[i] && (maxWidth <= 0 || col < maxWidth); ++i) {
40                 if (s[i] == '\n') {
41                         lineHead += lineBreak;
42                         position = lineHead;
43                         col = 0;
44                 } else {
45                         DrawChar(s[i], dest, position);
46                         position += step;
47                         ++col;
48                 }
49         }
50 }
51
52 void Font::DrawStringRight(const char *s, SDL_Surface *dest, const Vector<int> &positionIn, int maxWidth) const {
53         // NOTE: this does not handle line breaks
54         if (!sprite) return;
55
56         int length(0);
57         while (length < maxWidth && s[length] != '\0') {
58                 ++length;
59         }
60         Vector<int> position(positionIn.X() - length * CharWidth(), positionIn.Y());
61
62         DrawString(s, dest, position, length);
63 }
64
65 void Font::DrawDigit(int digit, SDL_Surface *dest, const Vector<int> &position) const {
66         if (!sprite) return;
67
68         DrawChar(digit + 0x30, dest, position);
69 }
70
71 void Font::DrawNumber(int numberIn, SDL_Surface *dest, const Vector<int> &positionIn, int digits) const {
72         if (!sprite) return;
73
74         int number(numberIn);
75         if (digits > 0 && numberIn >= pow(10.0, digits)) {
76                 numberIn = pow(10.0, digits) - 1;
77         }
78
79         Vector<int> position(positionIn);
80         Vector<int> step(sprite->Width(), 0);
81
82         if (digits > 0) {
83                 int i(digits - 1);
84                 while (number < pow(10.0, i) && i > 0) {
85                         position += step;
86                         --i;
87                 }
88         }
89
90         int m(10);
91         while (m <= number) {
92                 m *= 10;
93         }
94
95         while (m > 9) {
96                 m /= 10;
97                 DrawDigit((number / m) % 10, dest, position);
98                 position += step;
99         }
100 }
101
102 void Font::DrawNumberRight(int number, SDL_Surface *dest, const Vector<int> &positionIn, int digits) const {
103         if (!sprite) return;
104
105         Vector<int> position(positionIn.X() - digits * CharWidth(), positionIn.Y());
106
107         DrawNumber(number, dest, position, digits);
108 }
109
110
111 void Font::CreateTypeDescription() {
112         Font f;
113
114         TypeDescription &td(TypeDescription::Create(TYPE_ID, "Font"));
115         td.SetDescription(
116                         "Simple font with fixed-width characters using a sprite for rendering.\n"
117                         "Characters from strings are mapped as follows:\n"
118                         "<pre>sprite column = column offset + (character % 16)\n"
119                         "sprite row    = row    offset + (character / 16)</pre>");
120         td.SetConstructor(&Construct);
121         td.SetSize(sizeof(Font));
122
123         td.AddField("sprite", FieldDescription(((char *)&f.sprite) - ((char *)&f), Sprite::TYPE_ID).SetReferenced().SetDescription("a sprite where each tile corresponds to a character"));
124         td.AddField("columnoffset", FieldDescription(((char *)&f.colOffset) - ((char *)&f), Interpreter::NUMBER_ID).SetDescription("offset of the column of the first character"));
125         td.AddField("rowoffset", FieldDescription(((char *)&f.rowOffset) - ((char *)&f), Interpreter::NUMBER_ID).SetDescription("offset of the row of the first character"));
126 }
127
128 void Font::Construct(void *data) {
129         new (data) Font;
130 }
131
132 }