Mercurial > hg > dmlib
comparison fontconv.c @ 178:63ff0fb944cd
Implement TTF to bitmap font conversion (crude).
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 06 Oct 2012 12:21:31 +0300 |
parents | 67d2cba58a87 |
children | 17d4cc4c3ed1 |
comparison
equal
deleted
inserted
replaced
177:eb293aa7a671 | 178:63ff0fb944cd |
---|---|
10 #include "dmlib.h" | 10 #include "dmlib.h" |
11 #include "dmargs.h" | 11 #include "dmargs.h" |
12 #include "dmfile.h" | 12 #include "dmfile.h" |
13 #include "dmimage.h" | 13 #include "dmimage.h" |
14 #include "dmtext.h" | 14 #include "dmtext.h" |
15 #include "dmresw.h" | |
15 | 16 |
16 enum | 17 enum |
17 { | 18 { |
18 OFMT_DMFONT, | 19 OFMT_DMFONT, |
19 }; | |
20 | |
21 enum | |
22 { | |
23 IFMT_IMAGE, | |
24 IFMT_FONT, | |
25 }; | 20 }; |
26 | 21 |
27 char *optInFilename = NULL, *optOutFilename = NULL; | 22 char *optInFilename = NULL, *optOutFilename = NULL; |
28 int optOutFormat = OFMT_DMFONT, | 23 int optOutFormat = OFMT_DMFONT, |
29 optSplitWidth = 8, | 24 optSplitWidth = 8, |
118 yglyphs = image->h / height; | 113 yglyphs = image->h / height; |
119 | 114 |
120 if ((font = dmNewBitmapFont(xglyphs * yglyphs, width, height)) == NULL) | 115 if ((font = dmNewBitmapFont(xglyphs * yglyphs, width, height)) == NULL) |
121 return DMERR_MALLOC; | 116 return DMERR_MALLOC; |
122 | 117 |
123 /* | 118 dmMsg(1, "%d x %d split as %d x %d blocks => %d x %d = %d glyphs.\n", |
124 fprintf(stderr, "%d x %d split as %d x %d blocks => %d x %d = %d glyphs\n", | |
125 image->w, image->h, | 119 image->w, image->h, |
126 width, height, | 120 width, height, |
127 xglyphs, yglyphs, xglyphs * yglyphs); | 121 xglyphs, yglyphs, xglyphs * yglyphs); |
128 */ | |
129 | 122 |
130 nglyph = 0; | 123 nglyph = 0; |
131 for (yc = 0; yc < yglyphs; yc++) | 124 for (yc = 0; yc < yglyphs; yc++) |
132 for (xc = 0; xc < xglyphs; xc++) | 125 for (xc = 0; xc < xglyphs; xc++) |
133 { | 126 { |
158 *pfont = font; | 151 *pfont = font; |
159 return DMERR_OK; | 152 return DMERR_OK; |
160 } | 153 } |
161 | 154 |
162 | 155 |
156 int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font) | |
157 { | |
158 int maxglyph, nglyphs, n; | |
159 if (font == NULL) | |
160 return DMERR_NULLPTR; | |
161 | |
162 if (font->nglyphs > DMFONT_MAX_GLYPHS || | |
163 font->width > DMFONT_MAX_WIDTH || | |
164 font->height > DMFONT_MAX_HEIGHT || | |
165 font->width < DMFONT_MIN_WIDTH || | |
166 font->height < DMFONT_MIN_HEIGHT) | |
167 return DMERR_INVALID_DATA; | |
168 | |
169 // Count number of actually existing glyphs | |
170 for (maxglyph = nglyphs = n = 0; n < font->nglyphs; n++) | |
171 { | |
172 SDL_Surface *glyph = font->glyphs[n]; | |
173 if (glyph != NULL) | |
174 { | |
175 maxglyph = n; | |
176 if (glyph->w < DMFONT_MIN_WIDTH || | |
177 glyph->h < DMFONT_MIN_HEIGHT || | |
178 glyph->w > DMFONT_MAX_WIDTH || | |
179 glyph->h > DMFONT_MAX_HEIGHT) | |
180 continue; | |
181 nglyphs++; | |
182 } | |
183 } | |
184 | |
185 // Write the DMFONT header | |
186 if (!dmf_write_str(res, (Uint8 *) DMFONT_MAGIC, 6)) | |
187 return DMERR_FWRITE; | |
188 | |
189 dmf_write_le16(res, DMFONT_VERSION); | |
190 dmf_write_le16(res, nglyphs); | |
191 dmf_write_le16(res, maxglyph + 1); | |
192 dmfputc(font->width, res); | |
193 dmfputc(font->height, res); | |
194 | |
195 if (nglyphs > 0) | |
196 { | |
197 int i; | |
198 SDL_Surface *glyph = font->glyphs[maxglyph]; | |
199 | |
200 // If there are actual glyphs stored, save this | |
201 dmfputc(glyph->format->BitsPerPixel, res); | |
202 dmf_write_le32(res, glyph->format->Rmask); | |
203 dmf_write_le32(res, glyph->format->Gmask); | |
204 dmf_write_le32(res, glyph->format->Bmask); | |
205 dmf_write_le32(res, glyph->format->Amask); | |
206 | |
207 for (i = 0; i < font->nglyphs; i++) | |
208 { | |
209 glyph = font->glyphs[i]; | |
210 if (glyph != NULL) | |
211 { | |
212 int y; | |
213 Uint8 *pixels = glyph->pixels; | |
214 | |
215 if (glyph->w < DMFONT_MIN_WIDTH || | |
216 glyph->h < DMFONT_MIN_HEIGHT || | |
217 glyph->w > DMFONT_MAX_WIDTH || | |
218 glyph->h > DMFONT_MAX_HEIGHT) | |
219 continue; | |
220 | |
221 // Each glyph has its table index and w/h stored | |
222 dmf_write_le16(res, i); | |
223 dmfputc(glyph->w, res); | |
224 dmfputc(glyph->h, res); | |
225 | |
226 // Write the pixel data | |
227 for (y = 0; y < glyph->h; y++) | |
228 { | |
229 if (dmfwrite(pixels, glyph->format->BytesPerPixel, glyph->w, res) != (size_t) glyph->w) | |
230 return DMERR_FWRITE; | |
231 pixels += glyph->pitch; | |
232 } | |
233 } | |
234 } | |
235 } | |
236 | |
237 return DMERR_OK; | |
238 } | |
239 | |
240 | |
163 int main(int argc, char *argv[]) | 241 int main(int argc, char *argv[]) |
164 { | 242 { |
165 DMResource *inFile = NULL; | 243 DMResource *inFile = NULL; |
166 DMBitmapFont *font = NULL; | 244 DMBitmapFont *font = NULL; |
245 SDL_Surface *fontbmap = NULL; | |
167 int res; | 246 int res; |
247 #ifdef DM_GFX_TTF_TEXT | |
248 BOOL initTTF = FALSE; | |
249 TTF_Font *ttf = NULL; | |
250 #endif | |
168 | 251 |
169 dmInitProg("fontconv", "Bitmap font converter", "0.2", NULL, NULL); | 252 dmInitProg("fontconv", "Bitmap font converter", "0.2", NULL, NULL); |
170 dmVerbosity = 1; | 253 dmVerbosity = 1; |
171 | 254 |
172 // Parse arguments | 255 // Parse arguments |
178 if (!optInFilename) | 261 if (!optInFilename) |
179 { | 262 { |
180 dmError("Input or output file not specified!\n"); | 263 dmError("Input or output file not specified!\n"); |
181 return 1; | 264 return 1; |
182 } | 265 } |
266 | |
267 #ifdef DM_GFX_TTF_TEXT | |
268 if (TTF_Init() < 0) | |
269 { | |
270 dmError("Could not initialize FreeType/TTF: %s\n", SDL_GetError()); | |
271 goto error_exit; | |
272 } | |
273 initTTF = TRUE; | |
274 #endif | |
183 | 275 |
184 // Open the source file | 276 // Open the source file |
185 if ((inFile = dmf_create_stdio(optInFilename, "rb")) == NULL) | 277 if ((inFile = dmf_create_stdio(optInFilename, "rb")) == NULL) |
186 { | 278 { |
187 dmError("Error opening input file '%s', %d: %s\n", | 279 dmError("Error opening input file '%s', %d: %s\n", |
188 optInFilename, errno, strerror(errno)); | 280 optInFilename, errno, strerror(errno)); |
189 return 1; | 281 return 1; |
190 } | 282 } |
191 | 283 |
192 if ((res = dmLoadBitmapFont(inFile, &font)) != DMERR_OK) | 284 |
193 { | 285 if ((res = dmLoadBitmapFont(inFile, &font)) == DMERR_OK) |
194 SDL_Surface *fontbmap; | 286 { |
195 | 287 dmMsg(1, "Input is a TSFONT/DMFONT font file.\n"); |
288 } | |
289 #ifdef DM_GFX_TTF_TEXT | |
290 else | |
291 if ((ttf = TTF_OpenFont(optInFilename, optSplitWidth)) != NULL) | |
292 { | |
293 int i; | |
294 SDL_Color col = { 255, 255, 255, 100 }; //255, 255, 255, 100 }; | |
295 dmMsg(1, "Input is a TTF TrueType font, rendering at %d x %d.\n", | |
296 optSplitWidth, optSplitHeight); | |
297 | |
298 TTF_SetFontStyle(ttf, TTF_STYLE_NORMAL); | |
299 | |
300 if ((font = dmNewBitmapFont(256, optSplitWidth - 1, optSplitHeight+4)) == NULL) | |
301 { | |
302 goto error_exit; | |
303 } | |
304 | |
305 for (i = 0; i < 255; i++) | |
306 { | |
307 char str[2]; | |
308 str[0] = i; | |
309 str[1] = 0; | |
310 font->glyphs[i] = TTF_RenderText_Blended(ttf, str, col); | |
311 } | |
312 } | |
313 #endif | |
314 else | |
315 { | |
196 dmfseek(inFile, 0L, SEEK_SET); | 316 dmfseek(inFile, 0L, SEEK_SET); |
197 | 317 |
198 if ((fontbmap = dmLoadImage(inFile)) == NULL) | 318 if ((fontbmap = dmLoadImage(inFile)) == NULL) |
199 { | 319 { |
200 dmError("Could not load image file '%s'.\n", optInFilename); | 320 dmError("Could not load image file '%s'.\n", optInFilename); |
201 goto error_exit; | 321 goto error_exit; |
202 } | 322 } |
323 | |
324 dmMsg(1, "Input is a bitmap image (%d x %d, %d bpp), splitting to %d x %d.\n", | |
325 fontbmap->w, fontbmap->h, fontbmap->format->BitsPerPixel, | |
326 optSplitWidth, optSplitHeight); | |
203 | 327 |
204 if ((res = dmCreateBitmapFontFromImage(fontbmap, optSplitWidth, optSplitHeight, &font)) != DMERR_OK) | 328 if ((res = dmCreateBitmapFontFromImage(fontbmap, optSplitWidth, optSplitHeight, &font)) != DMERR_OK) |
205 { | 329 { |
206 dmError("Could not create a font from image, %d: %s\n", | 330 dmError("Could not create a font from image, %d: %s\n", |
207 res, dmErrorStr(res)); | 331 res, dmErrorStr(res)); |
208 goto error_exit; | 332 goto error_exit; |
209 } | 333 } |
210 SDL_FreeSurface(fontbmap); | |
211 } | 334 } |
212 | 335 |
213 if (font == NULL) | 336 if (font == NULL) |
214 { | 337 { |
215 dmError("No font loaded.\n"); | 338 dmError("No font loaded.\n"); |
217 } | 340 } |
218 | 341 |
219 if (optOutFormat == OFMT_DMFONT) | 342 if (optOutFormat == OFMT_DMFONT) |
220 { | 343 { |
221 DMResource *file; | 344 DMResource *file; |
345 | |
346 dmMsg(1, "Outputting a DMFONT format bitmap font.\n"); | |
222 | 347 |
223 if (optOutFilename == NULL) | 348 if (optOutFilename == NULL) |
224 file = dmf_create_stdio_stream(stdout); | 349 file = dmf_create_stdio_stream(stdout); |
225 else | 350 else |
226 file = dmf_create_stdio(optOutFilename, "wb"); | 351 file = dmf_create_stdio(optOutFilename, "wb"); |
241 dmError("Error saving font, %d: %s\n", | 366 dmError("Error saving font, %d: %s\n", |
242 res, dmErrorStr(res)); | 367 res, dmErrorStr(res)); |
243 } | 368 } |
244 | 369 |
245 error_exit: | 370 error_exit: |
371 | |
372 #ifdef DM_GFX_TTF_TEXT | |
373 if (initTTF) | |
374 TTF_Quit(); | |
375 #endif | |
246 | 376 |
247 dmf_close(inFile); | 377 dmf_close(inFile); |
248 dmFreeBitmapFont(font); | 378 dmFreeBitmapFont(font); |
379 SDL_FreeSurface(fontbmap); | |
249 | 380 |
250 return 0; | 381 return 0; |
251 } | 382 } |