changeset 75:e6535609c161

Initial implementation of loading and saving of bitmap fonts.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 02 Oct 2012 05:51:08 +0300
parents 23ac82365a65
children 7d201aed1fd9
files dmtext.h dmtext_bm.c
diffstat 2 files changed, 117 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/dmtext.h	Tue Oct 02 05:49:50 2012 +0300
+++ b/dmtext.h	Tue Oct 02 05:51:08 2012 +0300
@@ -21,6 +21,10 @@
 /* Bitmapped fonts and text
  */
 #ifdef DM_GFX_BM_TEXT
+
+#define DMFONT_MAGIC    "DMFONT"
+#define DMFONT_VERSION  0x0100
+
 typedef struct
 {
     int width, height;
@@ -33,6 +37,7 @@
 DMBitmapFont *dmNewBitmapFont(int nglyphs);
 int dmFreeBitmapFont(DMBitmapFont *font);
 int dmLoadBitmapFont(DMResource *res, DMBitmapFont **pfont);
+int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font);
 int dmCreateBitmapFontFromImage(SDL_Surface *image, int width, int height, DMBitmapFont **pfont);
 
 void dmDrawBMTextConst(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *str);
--- a/dmtext_bm.c	Tue Oct 02 05:49:50 2012 +0300
+++ b/dmtext_bm.c	Tue Oct 02 05:51:08 2012 +0300
@@ -103,12 +103,6 @@
 }
 
 
-int dmLoadBitmapFont(DMResource *res, DMBitmapFont **pfont)
-{
-    return DMERR_OK;
-}
-
-
 int dmCreateBitmapFontFromImage(SDL_Surface *image, int width, int height, DMBitmapFont **pfont)
 {
     int glyph, xc, yc, xglyphs, yglyphs;
@@ -163,24 +157,124 @@
     return DMERR_OK;
 }
 
+
+int dmLoadBitmapFont(DMResource *res, DMBitmapFont **pfont)
+{
+    DMBitmapFont *font;
+    char magic[8];
+    Uint16 version;
+    Uint32 width, height, nglyphs;
+    
+    // Check magic and version
+    dmf_read_str(res, (Uint8 *) &magic, 6);
+    dmf_read_le16(res, &version);
+    
+    if (memcmp(magic, DMFONT_MAGIC, 6) != 0)
+        return DMERR_INVALID;
+
+    if (version != DMFONT_VERSION)
+        return DMERR_VERSION;
+    
+    // Check other data
+    dmf_read_le32(res, &width);
+    dmf_read_le32(res, &height);
+    dmf_read_le32(res, &nglyphs);
+
+    if (width > 128 || height > 128 || nglyphs > 1024)
+        return DMERR_INVALID_DATA;
+
+    // Allocate font
+    if ((*pfont = font = dmNewBitmapFont(nglyphs)) == NULL)
+        return DMERR_MALLOC;
+
+    font->width = width;
+    font->height = height;
+    font->nglyphs = nglyphs;
+
+    // Read glyph data, if any
+    if (nglyphs > 0)
+    {
+        Uint32 i, BitsPerPixel, Rmask, Gmask, Bmask, Amask, pitch;
+
+        BitsPerPixel = dmfgetc(res);
+        dmf_read_le32(res, &Rmask);
+        dmf_read_le32(res, &Gmask);
+        dmf_read_le32(res, &Bmask);
+        dmf_read_le32(res, &Amask);
+
+        for (i = 0; i < nglyphs; i++)
+        {
+            int y;
+            Uint8 *pixels;
+            SDL_Surface *glyph;
+            dmf_read_le32(res, &width);
+            dmf_read_le32(res, &height);
+            dmf_read_le32(res, &pitch);
+            
+            font->glyphs[i] = glyph = SDL_CreateRGBSurface(
+                SDL_SWSURFACE, width, height,
+                BitsPerPixel, Rmask, Gmask,
+                Bmask,
+                Amask);
+            
+            if (glyph == NULL)
+                return DMERR_MALLOC;
+
+            pixels = glyph->pixels;
+            for (y = 0; y < glyph->h; y++)
+            {
+                if (dmfread(pixels, glyph->format->BytesPerPixel, glyph->w, res) != glyph->w)
+                    return DMERR_FREAD;
+                pixels += glyph->pitch;
+            }
+        }
+    }
+
+    return DMERR_OK;
+}
+
+
 int dmSaveBitmapFont(DMResource *res, DMBitmapFont *font)
 {
-    int i;
-
-    dmf_write_str(res, (Uint8 *) "DMFONT", 6);
-    dmf_write_le16(res, 0x0100);
+    if (font == NULL)
+        return DMERR_NULLPTR;
+    
+    if (!dmf_write_str(res, (Uint8 *) DMFONT_MAGIC, 6))
+        return DMERR_FWRITE;
+    
+    dmf_write_le16(res, DMFONT_VERSION);
     dmf_write_le32(res, font->width);
     dmf_write_le32(res, font->height);
     dmf_write_le32(res, font->nglyphs);
-
-    for (i = 0; i < font->nglyphs; i++)
+    
+    if (font->nglyphs > 0)
     {
-        SDL_Surface *glyph = font->glyphs[i];
-        dmf_write_le32(res, glyph->w);
-        dmf_write_le32(res, glyph->h);
-        dmf_write_le32(res, glyph->pitch);
-        dmf_write_str(res, glyph->pixels, glyph->h * glyph->pitch);
+        int i;
+        SDL_Surface *glyph = font->glyphs[0];
+
+        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++)
+        {
+            int y;
+            glyph = font->glyphs[i];
+            Uint8 *pixels = glyph->pixels;
+
+            dmf_write_le32(res, glyph->w);
+            dmf_write_le32(res, glyph->h);
+
+            for (y = 0; y < glyph->h; y++)
+            {
+                if (dmfwrite(pixels, glyph->format->BytesPerPixel, glyph->w, res) != glyph->w)
+                    return DMERR_FWRITE;
+                pixels += glyph->pitch;
+            }
+        }
     }
-        
+
     return DMERR_OK;
 }