[AD] True colour fonts in datafiles and some datatype assumptions

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


The attached patch adds support for true colour fonts to the grabber and 
dat utilities and the datafile loading code.
In order for this to work, the code has to store the font colourdepth in 
the datafile. Previous versions of Allegro interpreted any non-zero value 
as a monochrome font and a 0 as a colour font (with hindsight, a very 
stupid convention that should have been the other way around). In 
practice, the dat utilities used 1 for monochrome fonts, so I've modified 
the code to interpret 1 as a monochrome font, and all other values as a 
colour font (0 and 8 both meaning an 8 bit font). As long as the datafile 
does not contain any true colour fonts, older versions of Allegro can read 
it just fine. If it does contain true colour fonts, the data for the true 
colour font is read back as garbage, but there's nothing I see we can do 
about that.

The dat and grabber utilities should really use the library functions for 
loading fonts now that they're there. I'll make a followup patch that does 
that; this patch is mostly to add the ability to load and write true 
colour fonts from and to datafiles.
The patch also fixes a number of `unsafe' assumptions on the size of 
datatypes. For the most part, it seems that these don't matter too much 
since they weren't spotted before. Some affected the font loading and 
saving code though, so I fixed them while I was at it.

Evert
Index: src/datafile.c
===================================================================
RCS file: /cvsroot/alleg/allegro/src/datafile.c,v
retrieving revision 1.33
diff -u -r1.33 datafile.c
--- src/datafile.c	1 Feb 2005 13:12:06 -0000	1.33
+++ src/datafile.c	30 Apr 2005 14:12:53 -0000
@@ -148,7 +148,7 @@
       case 15:
 	 /* 15bit hicolor */
 	 for (y=0; y<h; y++) {
-	    p16 = (unsigned short *)bmp->line[y];
+	    p16 = (uint16_t *)bmp->line[y];
 
 	    for (x=0; x<w; x++) {
 	       c = pack_igetw(f);
@@ -163,7 +163,7 @@
       case 16:
 	 /* 16bit hicolor */
 	 for (y=0; y<h; y++) {
-	    p16 = (unsigned short *)bmp->line[y];
+	    p16 = (uint16_t *)bmp->line[y];
 
 	    for (x=0; x<w; x++) {
 	       c = pack_igetw(f);
@@ -409,7 +409,7 @@
 /* read_font_color:
  *  Helper for read_font, below.
  */
-static FONT_COLOR_DATA *read_font_color(PACKFILE *pack, int *hmax)
+static FONT_COLOR_DATA *read_font_color(PACKFILE *pack, int *hmax, int depth)
 {
    FONT_COLOR_DATA *cf = NULL;
    int max = 0, i = 0;
@@ -432,9 +432,9 @@
       *allegro_errno = ENOMEM;
       return NULL;
    }
-   
+
    for (i = 0; i < max; i++) {
-      bits[i] = read_bitmap(pack, 8, FALSE);
+      bits[i] = read_bitmap(pack, depth, TRUE);
       if (!bits[i]) {
 	 while (i) {
 	    i--;
@@ -463,6 +463,7 @@
    FONT *f = NULL;
    int num_ranges = 0;
    int height = 0;
+   int depth;
 
    f = malloc(sizeof(FONT));
    if (!f) {
@@ -474,7 +475,8 @@
 
    num_ranges = pack_mgetw(pack);
    while (num_ranges--) {
-      if (pack_getc(pack)) {
+      depth = pack_getc(pack);
+      if (depth == 1) {
 	 FONT_MONO_DATA *mf = 0, *iter = (FONT_MONO_DATA *)f->data;
 	 
 	 f->vtable = font_vtable_mono;
@@ -494,10 +496,14 @@
       } 
       else {
 	 FONT_COLOR_DATA *cf = NULL, *iter = (FONT_COLOR_DATA *)f->data;
+         
+         /* Older versions of Allegro use `0' to indicate a colour font */
+         if (depth == 0)
+            depth = 8;
 
 	 f->vtable = font_vtable_color;
 
-	 cf = read_font_color(pack, &height);
+	 cf = read_font_color(pack, &height, depth);
 	 if (!cf) {
 	    destroy_font(f);
 	    return NULL;
Index: tools/plugins/datfont.c
===================================================================
RCS file: /cvsroot/alleg/allegro/tools/plugins/datfont.c,v
retrieving revision 1.26
diff -u -r1.26 datfont.c
--- tools/plugins/datfont.c	16 Jan 2005 12:35:14 -0000	1.26
+++ tools/plugins/datfont.c	30 Apr 2005 14:12:55 -0000
@@ -792,7 +792,8 @@
       font = import_scripted_font(filename);
    }
    else {
-      font = import_bitmap_font(filename, ' ', -1, TRUE);
+      //font = import_bitmap_font(filename, ' ', -1, TRUE);
+      font = load_bitmap_font(filename, NULL, NULL);
    }
 
    return datedit_construct(type, font, 0, prop);
@@ -850,6 +851,7 @@
 {
     FONT_COLOR_DATA* cf = f->data;
     int i = 0;
+    int depth;
 
    *allegro_errno = 0;
 
@@ -863,21 +865,109 @@
     cf = f->data;
 
     while(cf) {
-
-        /* mono, begin, end-1 */
-        pack_putc(0, pack);
+         
+        /* Get font color depth */
+        depth = bitmap_color_depth(cf->bitmaps[0]);
+
+        /* Compatibility with older versions: depth=0 means 8 bit */
+        if (depth == 8)
+            depth = 0;
+        
+        /* color, begin, end-1 */
+        pack_putc(depth, pack);
         pack_mputl(cf->begin, pack);
         pack_mputl(cf->end - 1, pack);
 
+        /* Save pixmap data */
         for(i = cf->begin; i < cf->end; i++) {
-            BITMAP* g = cf->bitmaps[i - cf->begin];
-            int y;
-
-            pack_mputw(g->w, pack);
-            pack_mputw(g->h, pack);
-
-            for(y = 0; y < g->h; y++) {
-                pack_fwrite(g->line[y], g->w, pack);
+            BITMAP* glyph = cf->bitmaps[i - cf->begin];
+            int x, y, c, r, g, b, a;
+            uint16_t *p16;
+            uint8_t *p24;
+            uint32_t *p32;
+
+            pack_mputw(glyph->w, pack);
+            pack_mputw(glyph->h, pack);
+
+            switch (depth) {
+
+               case 0:
+	          /* 256 colors */
+	          for (y=0; y<glyph->h; y++)
+	             for (x=0; x<glyph->w; x++)
+	                pack_putc(glyph->line[y][x], pack);
+	          break;
+
+               case 15:
+               case 16:
+	          /* hicolor */
+	          for (y=0; y<glyph->h; y++) {
+	             p16 = (uint16_t *)glyph->line[y];
+
+	             for (x=0; x<glyph->w; x++) {
+	                c = p16[x];
+	                r = getr_depth(depth, c);
+	                g = getg_depth(depth, c);
+	                b = getb_depth(depth, c);
+	                c = ((r<<8)&0xF800) | ((g<<3)&0x7E0) | ((b>>3)&0x1F);
+	                pack_iputw(c, pack);
+	             }
+	          }
+	          break;
+
+               case 24:
+	          /* 24 bit truecolor */
+	          for (y=0; y<glyph->h; y++) {
+	             p24 = (unsigned char *)glyph->line[y];
+
+	             for (x=0; x<glyph->w; x++) {
+	                c = READ3BYTES(p24);
+	                r = getr24(c);
+	                g = getg24(c);
+	                b = getb24(c);
+	                pack_putc(r, pack);
+	                pack_putc(g, pack);
+	                pack_putc(b, pack);
+	                p24 += 3;
+	             }
+	          }
+	          break;
+
+               case 32:
+	          /* 32 bit truecolor */
+	          for (y=0; y<glyph->h; y++) {
+	             p32 = (uint32_t *)glyph->line[y];
+
+	             for (x=0; x<glyph->w; x++) {
+	                c = p32[x];
+	                r = getr32(c);
+	                g = getg32(c);
+	                b = getb32(c);
+	                pack_putc(r, pack);
+	                pack_putc(g, pack);
+	                pack_putc(b, pack);
+	             }
+	          }
+	          break;
+
+               case -32:
+	          /* 32 bit truecolor with alpha channel */
+	          for (y=0; y<glyph->h; y++) {
+	             p32 = (uint32_t *)glyph->line[y];
+
+	             for (x=0; x<glyph->w; x++) {
+	                c = p32[x];
+	                r = getr32(c);
+	                g = getg32(c);
+	                b = getb32(c);
+	                a = geta32(c);
+	                pack_putc(r, pack);
+	                pack_putc(g, pack);
+	                pack_putc(b, pack);
+	                pack_putc(a, pack);
+	             }
+	          }
+	          break;
             }
 
         }
Index: tools/plugins/datimage.c
===================================================================
RCS file: /cvsroot/alleg/allegro/tools/plugins/datimage.c,v
retrieving revision 1.16
diff -u -r1.16 datimage.c
--- tools/plugins/datimage.c	19 Mar 2005 11:15:07 -0000	1.16
+++ tools/plugins/datimage.c	30 Apr 2005 14:12:55 -0000
@@ -51,16 +51,16 @@
 /* checks whether this RLE sprite has an alpha channel */
 static int rle_has_alpha(AL_CONST RLE_SPRITE *spr)
 {
-   signed long *p32;
+   int32_t *p32;
    int x, y, c;
 
    if (spr->color_depth != 32)
       return FALSE;
 
-   p32 = (signed long *)spr->dat;
+   p32 = (int32_t *)spr->dat;
 
    for (y=0; y<spr->h; y++) {
-      while ((unsigned long)*p32 != MASK_COLOR_32) {
+      while ((uint32_t)*p32 != MASK_COLOR_32) {
 	 if (*p32 < 0) {
 	    p32++;
 	 }
@@ -69,7 +69,7 @@
 	    p32++;
 
 	    while (x-- > 0) {
-	       c = (unsigned long)*p32;
+	       c = (uint32_t)*p32;
 	       if (geta32(c))
 		  return TRUE;
 	       p32++;
@@ -376,9 +376,9 @@
 {
    BITMAP *bmp = (BITMAP *)dat->dat;
    int x, y, c, r, g, b, a;
-   unsigned short *p16;
-   unsigned char *p24;
-   unsigned long *p32;
+   uint16_t *p16;
+   uint8_t *p24;
+   uint32_t *p32;
    int depth;
 
    if (bitmap_has_alpha(bmp))
@@ -405,7 +405,7 @@
       case 16:
 	 /* hicolor */
 	 for (y=0; y<bmp->h; y++) {
-	    p16 = (unsigned short *)bmp->line[y];
+	    p16 = (uint16_t *)bmp->line[y];
 
 	    for (x=0; x<bmp->w; x++) {
 	       c = p16[x];
@@ -421,7 +421,7 @@
       case 24:
 	 /* 24 bit truecolor */
 	 for (y=0; y<bmp->h; y++) {
-	    p24 = (unsigned char *)bmp->line[y];
+	    p24 = (uint8_t *)bmp->line[y];
 
 	    for (x=0; x<bmp->w; x++) {
 	       c = READ3BYTES(p24);
@@ -439,7 +439,7 @@
       case 32:
 	 /* 32 bit truecolor */
 	 for (y=0; y<bmp->h; y++) {
-	    p32 = (unsigned long *)bmp->line[y];
+	    p32 = (uint32_t *)bmp->line[y];
 
 	    for (x=0; x<bmp->w; x++) {
 	       c = p32[x];
@@ -456,7 +456,7 @@
       case -32:
 	 /* 32 bit truecolor with alpha channel */
 	 for (y=0; y<bmp->h; y++) {
-	    p32 = (unsigned long *)bmp->line[y];
+	    p32 = (uint32_t *)bmp->line[y];
 
 	    for (x=0; x<bmp->w; x++) {
 	       c = p32[x];
@@ -591,8 +591,8 @@
 {
    RLE_SPRITE *spr = (RLE_SPRITE *)dat->dat;
    int x, y, c, r, g, b, a;
-   signed short *p16;
-   signed long *p32;
+   int16_t *p16;
+   int32_t *p32;
    unsigned long eol_marker;
    int depth;
 
@@ -618,11 +618,11 @@
       case 15:
       case 16:
 	 /* hicolor */
-	 p16 = (signed short *)spr->dat;
+	 p16 = (int16_t *)spr->dat;
 	 eol_marker = (depth == 15) ? MASK_COLOR_15 : MASK_COLOR_16;
 
 	 for (y=0; y<spr->h; y++) {
-	    while ((unsigned short)*p16 != (unsigned short)eol_marker) {
+	    while ((uint16_t)*p16 != (uint16_t)eol_marker) {
 	       if (*p16 < 0) {
 		  /* skip count */
 		  pack_iputw(*p16, f);
@@ -636,7 +636,7 @@
 		  pack_iputw(x, f);
 
 		  while (x-- > 0) {
-		     c = (unsigned short)*p16;
+		     c = (uint16_t)*p16;
 		     r = getr_depth(depth, c);
 		     g = getg_depth(depth, c);
 		     b = getb_depth(depth, c);
@@ -656,11 +656,11 @@
       case 24:
       case 32:
 	 /* truecolor */
-	 p32 = (signed long *)spr->dat;
+	 p32 = (int32_t *)spr->dat;
 	 eol_marker = (depth == 24) ? MASK_COLOR_24 : MASK_COLOR_32;
 
 	 for (y=0; y<spr->h; y++) {
-	    while ((unsigned long)*p32 != eol_marker) {
+	    while ((uint32_t)*p32 != eol_marker) {
 	       if (*p32 < 0) {
 		  /* skip count */
 		  pack_iputl(*p32, f);
@@ -674,7 +674,7 @@
 		  pack_iputl(x, f);
 
 		  while (x-- > 0) {
-		     c = (unsigned long)*p32;
+		     c = (uint32_t)*p32;
 		     r = getr_depth(depth, c);
 		     g = getg_depth(depth, c);
 		     b = getb_depth(depth, c);
@@ -694,10 +694,10 @@
 
       case -32:
 	 /* truecolor with alpha channel */
-	 p32 = (signed long *)spr->dat;
+	 p32 = (int32_t *)spr->dat;
 
 	 for (y=0; y<spr->h; y++) {
-	    while ((unsigned long)*p32 != MASK_COLOR_32) {
+	    while ((uint32_t)*p32 != MASK_COLOR_32) {
 	       if (*p32 < 0) {
 		  /* skip count */
 		  pack_iputl(*p32, f);
@@ -711,7 +711,7 @@
 		  pack_iputl(x, f);
 
 		  while (x-- > 0) {
-		     c = (unsigned long)*p32;
+		     c = (uint32_t)*p32;
 		     r = getr32(c);
 		     g = getg32(c);
 		     b = getb32(c);
Index: tools/plugins/datsamp.c
===================================================================
RCS file: /cvsroot/alleg/allegro/tools/plugins/datsamp.c,v
retrieving revision 1.11
diff -u -r1.11 datsamp.c
--- tools/plugins/datsamp.c	13 Jul 2004 10:47:34 -0000	1.11
+++ tools/plugins/datsamp.c	30 Apr 2005 14:12:55 -0000
@@ -67,7 +67,7 @@
    int bps = spl->bits/8 * ((spl->stereo) ? 2 : 1);
    int len = spl->len * bps;
    int i;
-   signed short s;
+   int16_t s;
    PACKFILE *f;
 
    errno = 0;
@@ -94,7 +94,7 @@
       }
       else {
 	 for (i=0; i < (int)spl->len * ((spl->stereo) ? 2 : 1); i++) {
-	    s = ((signed short *)spl->data)[i];
+	    s = ((int16_t *)spl->data)[i];
 	    pack_iputw(s^0x8000, f);
 	 }
       }
@@ -132,7 +132,7 @@
       int i;
 
       for (i=0; i < (int)spl->len * ((spl->stereo) ? 2 : 1); i++) {
-	 pack_iputw(((unsigned short *)spl->data)[i], f);
+	 pack_iputw(((int16_t *)spl->data)[i], f);
       }
    }
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/