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 |
||
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 | }>>>>><> |