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 }