Mercurial > hg > dmlib
diff 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 |
line wrap: on
line diff
--- a/fontconv.c Sat Oct 06 11:22:38 2012 +0300 +++ b/fontconv.c Sat Oct 06 12:21:31 2012 +0300 @@ -12,18 +12,13 @@ #include "dmfile.h" #include "dmimage.h" #include "dmtext.h" +#include "dmresw.h" enum { OFMT_DMFONT, }; -enum -{ - IFMT_IMAGE, - IFMT_FONT, -}; - char *optInFilename = NULL, *optOutFilename = NULL; int optOutFormat = OFMT_DMFONT, optSplitWidth = 8, @@ -120,12 +115,10 @@ if ((font = dmNewBitmapFont(xglyphs * yglyphs, width, height)) == NULL) return DMERR_MALLOC; -/* - fprintf(stderr, "%d x %d split as %d x %d blocks => %d x %d = %d glyphs\n", + dmMsg(1, "%d x %d split as %d x %d blocks => %d x %d = %d glyphs.\n", image->w, image->h, width, height, xglyphs, yglyphs, xglyphs * yglyphs); -*/ nglyph = 0; for (yc = 0; yc < yglyphs; yc++) @@ -160,11 +153,101 @@ } +int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font) +{ + int maxglyph, nglyphs, n; + if (font == NULL) + return DMERR_NULLPTR; + + if (font->nglyphs > DMFONT_MAX_GLYPHS || + font->width > DMFONT_MAX_WIDTH || + font->height > DMFONT_MAX_HEIGHT || + font->width < DMFONT_MIN_WIDTH || + font->height < DMFONT_MIN_HEIGHT) + return DMERR_INVALID_DATA; + + // Count number of actually existing glyphs + for (maxglyph = nglyphs = n = 0; n < font->nglyphs; n++) + { + SDL_Surface *glyph = font->glyphs[n]; + if (glyph != NULL) + { + maxglyph = n; + if (glyph->w < DMFONT_MIN_WIDTH || + glyph->h < DMFONT_MIN_HEIGHT || + glyph->w > DMFONT_MAX_WIDTH || + glyph->h > DMFONT_MAX_HEIGHT) + continue; + nglyphs++; + } + } + + // Write the DMFONT header + if (!dmf_write_str(res, (Uint8 *) DMFONT_MAGIC, 6)) + return DMERR_FWRITE; + + dmf_write_le16(res, DMFONT_VERSION); + dmf_write_le16(res, nglyphs); + dmf_write_le16(res, maxglyph + 1); + dmfputc(font->width, res); + dmfputc(font->height, res); + + if (nglyphs > 0) + { + int i; + SDL_Surface *glyph = font->glyphs[maxglyph]; + + // If there are actual glyphs stored, save this + dmfputc(glyph->format->BitsPerPixel, res); + dmf_write_le32(res, glyph->format->Rmask); + dmf_write_le32(res, glyph->format->Gmask); + dmf_write_le32(res, glyph->format->Bmask); + dmf_write_le32(res, glyph->format->Amask); + + for (i = 0; i < font->nglyphs; i++) + { + glyph = font->glyphs[i]; + if (glyph != NULL) + { + int y; + Uint8 *pixels = glyph->pixels; + + if (glyph->w < DMFONT_MIN_WIDTH || + glyph->h < DMFONT_MIN_HEIGHT || + glyph->w > DMFONT_MAX_WIDTH || + glyph->h > DMFONT_MAX_HEIGHT) + continue; + + // Each glyph has its table index and w/h stored + dmf_write_le16(res, i); + dmfputc(glyph->w, res); + dmfputc(glyph->h, res); + + // Write the pixel data + for (y = 0; y < glyph->h; y++) + { + if (dmfwrite(pixels, glyph->format->BytesPerPixel, glyph->w, res) != (size_t) glyph->w) + return DMERR_FWRITE; + pixels += glyph->pitch; + } + } + } + } + + return DMERR_OK; +} + + int main(int argc, char *argv[]) { DMResource *inFile = NULL; DMBitmapFont *font = NULL; + SDL_Surface *fontbmap = NULL; int res; +#ifdef DM_GFX_TTF_TEXT + BOOL initTTF = FALSE; + TTF_Font *ttf = NULL; +#endif dmInitProg("fontconv", "Bitmap font converter", "0.2", NULL, NULL); dmVerbosity = 1; @@ -180,6 +263,15 @@ dmError("Input or output file not specified!\n"); return 1; } + +#ifdef DM_GFX_TTF_TEXT + if (TTF_Init() < 0) + { + dmError("Could not initialize FreeType/TTF: %s\n", SDL_GetError()); + goto error_exit; + } + initTTF = TRUE; +#endif // Open the source file if ((inFile = dmf_create_stdio(optInFilename, "rb")) == NULL) @@ -189,10 +281,38 @@ return 1; } - if ((res = dmLoadBitmapFont(inFile, &font)) != DMERR_OK) + + if ((res = dmLoadBitmapFont(inFile, &font)) == DMERR_OK) + { + dmMsg(1, "Input is a TSFONT/DMFONT font file.\n"); + } +#ifdef DM_GFX_TTF_TEXT + else + if ((ttf = TTF_OpenFont(optInFilename, optSplitWidth)) != NULL) { - SDL_Surface *fontbmap; + int i; + SDL_Color col = { 255, 255, 255, 100 }; //255, 255, 255, 100 }; + dmMsg(1, "Input is a TTF TrueType font, rendering at %d x %d.\n", + optSplitWidth, optSplitHeight); + + TTF_SetFontStyle(ttf, TTF_STYLE_NORMAL); + + if ((font = dmNewBitmapFont(256, optSplitWidth - 1, optSplitHeight+4)) == NULL) + { + goto error_exit; + } + for (i = 0; i < 255; i++) + { + char str[2]; + str[0] = i; + str[1] = 0; + font->glyphs[i] = TTF_RenderText_Blended(ttf, str, col); + } + } +#endif + else + { dmfseek(inFile, 0L, SEEK_SET); if ((fontbmap = dmLoadImage(inFile)) == NULL) @@ -201,13 +321,16 @@ goto error_exit; } + dmMsg(1, "Input is a bitmap image (%d x %d, %d bpp), splitting to %d x %d.\n", + fontbmap->w, fontbmap->h, fontbmap->format->BitsPerPixel, + optSplitWidth, optSplitHeight); + if ((res = dmCreateBitmapFontFromImage(fontbmap, optSplitWidth, optSplitHeight, &font)) != DMERR_OK) { dmError("Could not create a font from image, %d: %s\n", res, dmErrorStr(res)); goto error_exit; } - SDL_FreeSurface(fontbmap); } if (font == NULL) @@ -220,6 +343,8 @@ { DMResource *file; + dmMsg(1, "Outputting a DMFONT format bitmap font.\n"); + if (optOutFilename == NULL) file = dmf_create_stdio_stream(stdout); else @@ -243,9 +368,15 @@ } error_exit: + +#ifdef DM_GFX_TTF_TEXT + if (initTTF) + TTF_Quit(); +#endif dmf_close(inFile); dmFreeBitmapFont(font); + SDL_FreeSurface(fontbmap); return 0; }