1 // Copyright (C) 2006 Jason Woofenden
3 // This file is part of VoR.
5 // VoR is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or (at your option)
10 // VoR is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with VoR; see the file COPYING. If not, write to the
17 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 // MA 02111-1307, USA.
22 #include <SDL_image.h>
27 extern SDL_Surface *surf_screen;
30 return cur_font->bounds[0].h;
33 void font_set(font *to) {
37 // return true if column of pixels (pix points to the top one) is all black
38 int line_clear(unsigned char* pix, int height, int width) {
40 for(i = 0; i < height; ++i) {
51 // return the number of consecutive colums of pixels are still clear (or still not clear)
52 int find_change(unsigned char* pix, int height, int width) {
54 int state = line_clear(pix, height, width);
57 for(i = 1; /*forever*/; pix += 3, ++i) {
58 if(line_clear(pix, height, width) != state) {
64 void font_free(font* garbage) {
65 SDL_FreeSurface(garbage->pixels);
69 font* font_load(const char *filename) {
76 new_font = (font*) malloc(sizeof(font));
78 fprintf(stderr, "couldn't allocate memory for font.\n");
81 new_font->pixels = (SDL_Surface*)IMG_Load(filename);
82 if(!new_font->pixels) {
83 fprintf(stderr, "couldn't load font file '%s'.\n", filename);
87 //SDL_SetColorKey(new_font->pixels, SDL_SRCCOLORKEY, 0);
89 pix = new_font->pixels->pixels;
91 // set all font rects to be the full height
92 for(i = 0; i < 94; ++i) {
93 new_font->bounds[i].y = 0;
94 new_font->bounds[i].h = new_font->pixels->h;
97 // find the characters
98 new_font->bounds[0].x = 0; // the first character starts at the begining
99 for(i = 0; i < 93; ) {
100 // find the end of the character
101 width = find_change(pix, new_font->pixels->h, new_font->pixels->pitch);
103 pix += width * new_font->pixels->format->BytesPerPixel;
104 new_font->bounds[i].w = width;
108 width = find_change(pix, new_font->pixels->h, new_font->pixels->pitch);
110 pix += width * new_font->pixels->format->BytesPerPixel;
111 new_font->bounds[i].x = x;
113 new_font->bounds[93].w = new_font->pixels->w - new_font->bounds[93].x; // the last character ends at the end
115 // There is a common problem where with some fonts there is a column of all
116 // black pixels between the parts of the double-quote, and this code thinks
117 // that it is two seperate characters. This code currently assumes that
118 // there is no such column. To change it so it assumes that the
119 // double-quote character looks like 2, change the loop above to start at
120 // zero, and uncomment the following indented stuff.
122 // // The above has 3 problems:
124 // // 1) space is missing from the begining
125 // // 2) ! is first instead of seccond
126 // // 3) " is taking 2nd and 3rd position
128 // // merge pieces of double-quote
129 // width = font_rects[2].x - font_rects[1].x;
130 // font_rects[2].w += width;
131 // font_rects[2].x = font_rects[1].x;
134 // font_rects[1].x = font_rects[0].x;
135 // font_rects[1].w = font_rects[0].w;
138 // the width of the space is set to half the space between the first two characters
139 width = new_font->bounds[1].x - (new_font->bounds[0].x + new_font->bounds[0].w);
140 new_font->space_width = width / 2;
141 new_font->letter_spacing = new_font->space_width / 4 ;
142 if(new_font->space_width < 2) {
143 new_font->space_width = 2;
145 if(new_font->letter_spacing < 1) {
146 new_font->letter_spacing = 1;
153 void font_write(int x, int y, const char* message) {
154 SDL_Rect dest = {x, y, 0, font_height()};
157 if(message[0] == 0) {
161 for(c = *message++; c; c = *message++) {
162 if(c > 31 && c < 127) {
164 dest.x += cur_font->space_width;
167 dest.w = cur_font->bounds[(int)c].w;
168 SDL_BlitSurface(cur_font->pixels, &(cur_font->bounds[(int)c]), surf_screen, &dest);
171 dest.x += cur_font->letter_spacing;
173 fprintf(stderr, "tried to print unknown char: %d (0x%x)\n", c, c);
178 // return the width in pixels of the string
179 int font_width(const char* message) {
183 if(message[0] == 0) {
187 for(c = *message++; c; c = *message++) {
188 if(c > 31 && c < 127) {
190 width += cur_font->space_width;
193 width += cur_font->bounds[(int)c].w;
195 width += cur_font->letter_spacing;
197 fprintf(stderr, "tried to print unknown char: %d (0x%x)\n", c, c);
201 // don't count spacing after the last char
203 width -= cur_font->letter_spacing;