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