Re: [AD] truecolor fonts

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


Milan Mimica wrote:

There is still a problem when merging a truecolor and non-truecolor font. Right now, it can result with a font with ranges of different color depth. It seems to work fine but the user wouldn't expect that.

Attached is my attemp to fix this. It allows merging 8-bit and truecolor fonts resulting a truecolor font. Converting a mono font to truecolor is not possible because you don't know in what color to draw a mono font and that's why I find it useless.

In addition, it is possible to upgrade/adapt the first font to the second one, allegro will figure out what to do. Right now, passing mono font as the first argument and color font as the second would return NULL, notwithstanding what docs say.

Also, it modifies the docs - do not let me write the docs!

It may be too hazardous to apply this patch at this rc stage, I don't know.

I also think we miss the userspace API to get font color depth, or at least something internal. is_color_font just isn't enough any more.

The patch adds a 'depth' member to the FONT_COLOR_DATA so it should be easy to add such function.


--
Milan Mimica
http://sparklet.sf.net
diff -u3pr allegro-4.2.0-old/docs/src/allegro._tx allegro-4.2.0/docs/src/allegro._tx
--- allegro-4.2.0-old/docs/src/allegro._tx	2005-09-02 01:32:56.000000000 +0200
+++ allegro-4.2.0/docs/src/allegro._tx	2005-09-02 13:31:27.000000000 +0200
@@ -6957,7 +6957,7 @@ bitmapped version of a TrueType font wit
    font containing all characters in the old fonts. In general, you cannot
    merge fonts of different types (eg, TrueType fonts and bitmapped fonts),
    but as a special case, this function can promote a monochrome bitmapped
-   font to a color font and merge those. Example:
+   font to a 8-bit color font or 8-color font to a truecolor font. Example:
 <codeblock>
       FONT *myfont;
       FONT *myfancy_font;
diff -u3pr allegro-4.2.0-old/include/allegro/internal/aintern.h allegro-4.2.0/include/allegro/internal/aintern.h
--- allegro-4.2.0-old/include/allegro/internal/aintern.h	2005-09-02 01:32:57.000000000 +0200
+++ allegro-4.2.0/include/allegro/internal/aintern.h	2005-09-02 01:34:10.000000000 +0200
@@ -266,6 +266,7 @@ typedef struct FONT_MONO_DATA 
 typedef struct FONT_COLOR_DATA
 {
    int begin, end;                  /* first char and one-past-the-end char */
+   int depth;                       /* font color depth */
    BITMAP **bitmaps;                /* our glyphs */
    struct FONT_COLOR_DATA *next;    /* linked list structure */
 } FONT_COLOR_DATA;
diff -u3pr allegro-4.2.0-old/src/datafile.c allegro-4.2.0/src/datafile.c
--- allegro-4.2.0-old/src/datafile.c	2005-09-02 01:32:58.000000000 +0200
+++ allegro-4.2.0/src/datafile.c	2005-09-02 02:52:43.000000000 +0200
@@ -423,6 +423,7 @@ static FONT_COLOR_DATA *read_font_color(
    
    cf->begin = pack_mgetl(pack);
    cf->end = pack_mgetl(pack) + 1;
+   cf->depth = depth;
    cf->next = NULL;
    max = cf->end - cf->begin;
 
diff -u3pr allegro-4.2.0-old/src/fontbmp.c allegro-4.2.0/src/fontbmp.c
--- allegro-4.2.0-old/src/fontbmp.c	2005-09-02 01:32:58.000000000 +0200
+++ allegro-4.2.0/src/fontbmp.c	2005-09-02 13:25:34.000000000 +0200
@@ -263,6 +263,7 @@ FONT *grab_font_from_bitmap(BITMAP *bmp)
 
 	 cf->begin = begin;
 	 cf->end = end;
+	 cf->depth = bitmap_color_depth(bmp);
 	 cf->next = 0;
       }
    }
diff -u3pr allegro-4.2.0-old/src/font.c allegro-4.2.0/src/font.c
--- allegro-4.2.0-old/src/font.c	2005-09-02 01:32:58.000000000 +0200
+++ allegro-4.2.0/src/font.c	2005-09-02 13:21:11.000000000 +0200
@@ -1145,6 +1145,67 @@ static FONT *upgrade_to_color(FONT* f)
 
 
 
+/* adapt_to_color, adapt_to_color_data:
+ *  Helper functions. Adapts a font to different color depth.
+ */
+static FONT_COLOR_DATA* adapt_to_color_data(FONT_COLOR_DATA* cf_in, int depth)
+{
+    FONT_COLOR_DATA* cf = _al_malloc(sizeof *cf);
+    BITMAP** bits = _al_malloc((cf_in->end - cf_in->begin)*sizeof *bits);
+    int i;
+
+    cf->begin = cf_in->begin;
+    cf->end = cf_in->end;
+    cf->bitmaps = bits;
+    cf->depth = depth;
+    cf->next = 0;
+
+    for(i = cf_in->begin; i < cf_in->end; i++) {
+        BITMAP* b1 = cf_in->bitmaps[i - cf_in->begin];
+        BITMAP* b2 = create_bitmap_ex(depth, b1->w, b2->h);
+        blit(b1, b2, 0, 0, 0, 0, b1->w, b1->h);
+        bits[i - cf_in->begin] = b2;
+    }
+
+    return cf;
+}
+
+
+
+static FONT *adapt_to_color(FONT* f, int depth)
+{
+   FONT *outf;
+   FONT_COLOR_DATA *cf = 0;
+   FONT_COLOR_DATA* cf_next = f->data;
+
+   if (is_mono_font(f))
+      return NULL;
+
+   if (cf_next->depth == depth)
+      return NULL;
+
+   outf = _al_malloc(sizeof *outf);
+   outf->vtable = font_vtable_color;
+   outf->height = f->height;
+
+   while(cf_next) {
+      if (cf) {
+         cf->next = adapt_to_color_data(cf_next, depth);
+         cf = cf->next;
+      }
+      else {
+         cf = adapt_to_color_data(cf_next, depth);
+         outf->data = cf;
+      }
+
+      cf_next = cf_next->next;
+   }
+
+   return outf;
+}
+
+
+
 /* color_copy_glyph_range:
  *  Colour font helper function. Copies (part of) a glyph range
  */
@@ -1165,6 +1226,7 @@ static FONT_COLOR_DATA *color_copy_glyph
 
    newcf->begin = begin;
    newcf->end = end;
+   newcf->depth = cf->depth;
    newcf->next = NULL;
    num = end - begin;
 
@@ -1250,26 +1312,60 @@ static FONT *color_extract_font_range(FO
  */
 static FONT *color_merge_fonts(FONT *font1, FONT *font2)
 {
-   FONT *fontout = NULL, *font2_upgr = NULL;
+   FONT *fontout = NULL, *font2_adapted = NULL;
    FONT_COLOR_DATA *cf, *cf1, *cf2;
-   
+
    if (!font1 || !font2)
       return NULL;
-      
-   /* Promote font 2 to colour if it is a monochrome font */
-   if (!is_color_font(font1))
+
+   cf1 = font1->data;
+   cf2 = font1->data;
+
+   /* We adapt the second font to the first one so swap fonts if needed. */
+   if (is_mono_font(font1)) {
+      FONT *tmp;
+
+      if (is_mono_font(font2))
+         return NULL;
+
+      /* swap */
+      tmp = font1;
+      font1 = font2;
+      font2 = tmp;
+   }
+   else if (is_color_font(font2)) {
+      FONT *tmp;
+
+      if (cf1->depth < cf2->depth) {
+         /* swap */
+         tmp = font1;
+         font1 = font2;
+         font2 = tmp;
+      }
+   }
+
+   /* Mono font can only be upgraded to 8-bit font. */
+   if (cf1->depth > 8 && is_mono_font(font2))
       return NULL;
-   
+
+   /* Promote font 2 to colour if it is a monochrome font */
    if (is_mono_font(font2)) {
-      font2_upgr = upgrade_to_color(font2);
+      font2_adapted = upgrade_to_color(font2);
       /* Couldn't update font */
-      if (!font2_upgr)
+      if (!font2_adapted)
+         return NULL;
+   }
+   /* Adapt font 2 to font 1 if needed */
+   else if (cf1->depth != cf2->depth) {
+      font2_adapted = adapt_to_color(font2, cf1->depth);
+      /* Couldn't update font */
+      if (!font2_adapted)
          return NULL;
    }
    else
-      font2_upgr = font2;
+      font2_adapted = font2;
 
-   if (!is_color_font(font2_upgr))
+   if (!is_color_font(font2_adapted))
       return NULL;
 
    /* Get output font */
@@ -1277,9 +1373,8 @@ static FONT *color_merge_fonts(FONT *fon
    fontout->height = MAX(font1->height, font2->height);
    fontout->vtable = font1->vtable;
    cf = fontout->data = NULL;
-   
-   cf1 = font1->data;
-   cf2 = font2_upgr->data;
+   cf2 = font2_adapted->data;
+
    while (cf1 || cf2) {
       if (cf1 && (!cf2 ||  (cf1->begin < cf2->begin))) {
          if (cf) {
@@ -1305,8 +1400,8 @@ static FONT *color_merge_fonts(FONT *fon
       }
    }
 
-   if (font2_upgr != font2)
-      destroy_font(font2_upgr);
+   if (font2_adapted != font2)
+      destroy_font(font2_adapted);
 
    return fontout;
 }


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