Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
showbdf - shows a BDF font on the screen
3
Placed in the public domain by Andre de Leiradella on 21-jan-2003.
4
 
5
You'll need SDL, SDLmain and SDL_gfxPrimitives to compile this program.
6
*/
7
 
8
#include 
9
#include 
10
#include 
11
#include 
12
#include 
13
#include "SDL_bdf.h"
14
#include "SDL_gfxPrimitives.h"
15
 
16
/* Reads a byte from a rwops. */
17
static int ReadByteRwops(void *info) {
18
	unsigned char b;
19
 
20
	if (SDL_RWread((SDL_RWops *)info, &b, 1, 1) != 1)
21
		return -1;
22
	return b;
23
}
24
 
25
/* Put a pixel on a SDL surface. */
26
static void PutPixel(void *surface, int x, int y, unsigned int color) {
27
	pixelColor((SDL_Surface *)surface, (Sint16)x, (Sint16)y, (Uint32)color);
28
}
29
 
30
/* Put a pixel on a b&w surface with 1 bit per pixel. The first 4 bytes hold the width of the surface. */
31
static void PutBWPixel(void *surface, int x, int y, unsigned int color) {
32
	(void)color;
33
	y *= *(int *)surface;
34
	((unsigned char *)surface)[y + x / 8 + sizeof(int)] |= 1 << (x & 7);
35
}
36
 
37
/*
38
Example showing how to simulate anti-aliased text reducing the size of an
39
image. This function will render a text to a new SDL_Surface.
40
*/
41
static SDL_Surface *DrawAAH(BDF_Font *font, char *text, int entities, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
42
	SDL_Surface   *surface;
43
	int	      x0, y0, w, h, a;
44
	unsigned char *pixels, *aux, *endimage, *endline;
45
	static Uint8  alpha[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
46
 
47
	if (entities)
48
		BDF_SizeEntitiesH(font, text, &x0, &y0, &w, &h);
49
	else
50
		BDF_SizeH(font, text, &x0, &y0, &w, &h);
51
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
52
	surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
53
#else
54
	surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
55
#endif
56
	if (surface == NULL)
57
		return NULL;
58
	boxRGBA(surface, 0, 0, surface->w - 1, surface->h - 1, r0, g0, b0, 255);
59
	w = (w + 7) / 8;
60
	h = ((h + 3) / 4) * 4;
61
	a = w * h * + sizeof(int);
62
	pixels = (unsigned char *)malloc(a);
63
	if (pixels == NULL) {
64
		SDL_OutOfMemory();
65
		SDL_FreeSurface(surface);
66
		return NULL;
67
	}
68
	memset(pixels, 0, a);
69
	*(int *)pixels = w;
70
	if (entities)
71
		BDF_DrawEntitiesH(pixels, PutBWPixel, font, text, x0, y0, 0);
72
	else
73
		BDF_DrawH(pixels, PutBWPixel, font, text, x0, y0, 0);
74
	aux = pixels + sizeof(int);
75
	endimage = aux + w * h;
76
	for (y0 = 0; aux < endimage; y0++, aux += w * 3)
77
		for (endline = aux + w, x0 = 0; aux < endline; x0 += 2, aux++) {
78
			a = alpha[aux[0] & 15];
79
			a += alpha[aux[w] & 15];
80
			a += alpha[aux[w * 2] & 15];
81
			a += alpha[aux[w * 3] & 15];
82
			pixelRGBA(surface, x0, y0, r, g, b, a * 255 / 16);
83
			a = alpha[(aux[0] >> 4) & 15];
84
			a += alpha[(aux[w] >> 4) & 15];
85
			a += alpha[(aux[w * 2] >> 4) & 15];
86
			a += alpha[(aux[w * 3] >> 4) & 15];
87
			pixelRGBA(surface, x0 + 1, y0, r, g, b, a * 255 / 16);
88
		}
89
	free(pixels);
90
	return surface;
91
}
92
 
93
/* Calls DrawAAH to render the text without support to entities. */
94
static SDL_Surface *RenderAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
95
	return DrawAAH(font, text, 0, r0, g0, b0, r, g, b);
96
}
97
 
98
/* Calls DrawAAH to render the text with support to entities. */
99
static SDL_Surface *RenderEntitiesAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) {
100
	return DrawAAH(font, text, 1, r0, g0, b0, r, g, b);
101
}
102
 
103
int main(int argc, char *argv[]) {
104
	SDL_RWops   *rwops;
105
	BDF_Font    *font;
106
	SDL_Surface *screen, *aatext;
107
	int	    x0, y0, w, h;
108
	SDL_Rect    pos;
109
	SDL_Event   event;
110
	char	    *text = "The quick fox jumped over the lazy dog";
111
 
112
	if (argc != 2) {
113
		fprintf(stderr, "Usage: showbdf \n");
114
		return -1;
115
	}
116
	/* Reads the font. */
117
	rwops = SDL_RWFromFile(argv[1], "rb");
118
	font = BDF_OpenFont(ReadByteRwops, (void *)rwops, &w);
119
	SDL_RWclose(rwops);
120
	/* Check for error code. */
121
	switch (w) {
122
		case BDF_MEMORYERROR:
123
			fprintf(stderr, "Not enough memory reading BDF font\n");
124
			return -1;
125
		case BDF_READERROR:
126
			fprintf(stderr, "Error while reading BDF font\n");
127
			return -1;
128
		case BDF_WRONGVERSION:
129
			fprintf(stderr, "Wrong BDF font version, can only handle versions up to 2.2\n");
130
			return -1;
131
		case BDF_CANNOTHANDLEVERTICAL:
132
			fprintf(stderr, "Wrong BDF font direction, can only handle horizontal direction\n");
133
			return -1;
134
		case BDF_TOOMANYCHARACTERS:
135
		case BDF_TOOFEWCHARACTERS:
136
		case BDF_PARSEERROR:
137
			fprintf(stderr, "Invalid BDF font\n");
138
			return -1;
139
	}
140
	/* Init SDL. */
141
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
142
		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
143
		return -1;
144
	}
145
	atexit(SDL_Quit);
146
	/* Check the size of the image required to acomodate the rendered text. */
147
	BDF_SizeH(font, text, &x0, &y0, &w, &h);
148
	/* Set the video a little bit bigger than the minimum. */
149
	screen = SDL_SetVideoMode(w + 10, h + 15 + (h + 3) / 4, 0, SDL_SWSURFACE);
150
	if (screen == NULL) {
151
		fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", w + 10, h + 15 + (h + 3) / 4, SDL_GetError());
152
		return -1;
153
	}
154
	/* Clear the screen to white. */
155
	boxColor(screen, 0, 0, screen->w - 1, screen->h - 1, 0xFFFFFFFF);
156
	/* Render the text to the screen with black. */
157
	BDF_DrawH((void *)screen, PutPixel, font, text, x0 + 5, y0 + 5, 0x000000FF);
158
	/* Render the same text with white blackgorund and black foreground to a new surface. */
159
	aatext = RenderAAH(font, text, 255, 255, 255, 0, 0, 0);
160
	if (aatext == NULL) {
161
		fprintf(stderr, "Couldn't render anti-aliased text: %s\n", SDL_GetError());
162
		return -1;
163
	}
164
	/* Blit it to the screen. */
165
	pos.x = (screen->w - aatext->w) / 2;
166
	pos.y = h + 5 + aatext->h / 2;
167
	SDL_BlitSurface(aatext, NULL, screen, &pos);
168
	SDL_FreeSurface(aatext);
169
	/* Update the screen. */
170
	SDL_UpdateRect(screen, 0, 0, 0, 0);
171
	/* Wait for something to happen... */
172
	for(;;) {
173
		if (SDL_WaitEvent(&event) < 0) {
174
			fprintf(stderr, "SDL_PullEvent() error: %s\n", SDL_GetError());
175
			return -1;
176
		}
177
		switch (event.type) {
178
			case SDL_MOUSEBUTTONDOWN:
179
			case SDL_KEYDOWN:
180
			case SDL_QUIT:
181
				BDF_CloseFont(font);
182
				return 0;
183
		}
184
	}
185
}