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