From 0e9366c1c4c608c9bbb0b36a20c750b88aa2e8e3 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Mon, 12 Nov 2001 09:50:52 +0000 Subject: Optimisation de la taille de la texture utilis�e pour stocker une fonte. --- generic/Image.c | 62 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 13 deletions(-) (limited to 'generic/Image.c') diff --git a/generic/Image.c b/generic/Image.c index d3f9563..3ce8aac 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -643,7 +643,7 @@ GetTexFont(ZnWindow win, ZnFont font) { unsigned char *glisto = " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijmklmnopqrstuvwxyz?.;,!*:\"'èéêëïîôâàçûùü/+@#$%^&()\\-_<>\t\020\021\022\023"; - unsigned char *glist = NULL; + unsigned char *glist=NULL, *glist2=NULL; TexFont *txf; TexGlyphInfo *tgi; int i, j; @@ -654,6 +654,7 @@ GetTexFont(ZnWindow win, GLfloat xstep, ystep, texw, texh; static int inited = 0; Tcl_HashEntry *entry; + int max_tex_size[1]; if (!inited) { Tcl_InitHashTable(&font_textures, sizeof(ZnFont)/sizeof(int)); @@ -668,12 +669,17 @@ GetTexFont(ZnWindow win, if (txf == NULL) { goto error; } + glGetIntegerv(GL_MAX_TEXTURE_SIZE, max_tex_size); txf->tgi = NULL; txf->tgvi = NULL; txf->lut = NULL; txf->teximage = NULL; - texw = txf->tex_width = 256; /* Size of texture */ - texh = txf->tex_height = 256; + /* + * Initial size of texture. + * Assume that max_tex_size is at least 256 texels. + */ + texw = 128; + texh = 64; xstep = 0/*0.5 / texw*/; ystep = 0/*0.5 / texh*/; @@ -681,8 +687,8 @@ GetTexFont(ZnWindow win, if (txf->teximage == NULL) { goto error; } - memset(txf->teximage, 0x55, texw * texh * sizeof(unsigned char)); - + /*memset(txf->teximage, 0x55, texw * texh * sizeof(unsigned char));*/ + fontinfo = SuckGlyphsFromServer(win, font); if (fontinfo == NULL) { goto error; @@ -691,8 +697,6 @@ GetTexFont(ZnWindow win, txf->max_ascent = fontinfo->max_ascent; txf->max_descent = fontinfo->max_descent; txf->num_glyphs = strlen(glisto); - glist = ZnMalloc((txf->num_glyphs+1) * sizeof(unsigned char)); - strcpy(glist, glisto); txf->tgi = (TexGlyphInfo *) ZnMalloc(txf->num_glyphs * sizeof(TexGlyphInfo)); if (txf->tgi == NULL) { @@ -703,8 +707,17 @@ GetTexFont(ZnWindow win, goto error; } + glist = ZnMalloc((txf->num_glyphs+1) * sizeof(unsigned char)); + strcpy(glist, glisto); qsort(glist, txf->num_glyphs, sizeof(unsigned char), glyphCompare); - + /* + * Keep a cache a the sorted list in case we need to + * restart the allocation process. + */ + glist2 = ZnMalloc((txf->num_glyphs+1) * sizeof(unsigned char)); + strcpy(glist2, glist); + + restart: px = gap; py = gap; maxheight = 0; @@ -759,8 +772,25 @@ GetTexFont(ZnWindow win, px = gap; maxheight = height; if (py + height + gap >= texh) { - ZnWarning("Font texture overflow"); - goto error; /* Overflowed texture space */ + if (texh*2 < max_tex_size[0]) { + texh *= 2; + ZnFree(txf->teximage); + txf->teximage = ZnMalloc(texw * texh * sizeof(unsigned char)); + strcpy(glist, glist2); + goto restart; + } + else if (texw*2 < max_tex_size[0]) { + texw *= 2; + ZnFree(txf->teximage); + txf->teximage = ZnMalloc(texw * texh * sizeof(unsigned char)); + strcpy(glist, glist2); + goto restart; + } + else { + /* Overflowed texture space */ + ZnWarning("Font texture overflow"); + goto error; + } } c = i; } @@ -782,7 +812,6 @@ GetTexFont(ZnWindow win, c = i; } glist[c] = 0; /* Mark processed; don't process again. */ - txf->tgvi[c].t0[0] = tgi->x / texw + xstep; txf->tgvi[c].t0[1] = tgi->y / texh + ystep; txf->tgvi[c].v0[0] = tgi->xoffset; @@ -813,6 +842,9 @@ GetTexFont(ZnWindow win, max_glyph = txf->tgi[i].c; } } + txf->tex_width = texw; + txf->tex_height = texh; + /*printf("texture width: %g, texture height: %g\n", texw, texh);*/ /* printf("min glyph: (%d) \"%c\", max glyph: (%d) \"%c\"\n", min_glyph, min_glyph, max_glyph, max_glyph);*/ txf->min_glyph = min_glyph; @@ -833,7 +865,7 @@ GetTexFont(ZnWindow win, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY4, 256, 256, 0, + glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY4, txf->tex_width, txf->tex_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, txf->teximage); for (i = 0; i < fontinfo->num_glyphs; i++) { @@ -842,7 +874,8 @@ GetTexFont(ZnWindow win, } ZnFree(fontinfo); ZnFree(glist); - + ZnFree(glist2); + entry = Tcl_CreateHashEntry(&font_textures, (char *) font, &new); Tcl_SetHashValue(entry, (ClientData) txf); return txf; @@ -852,6 +885,9 @@ GetTexFont(ZnWindow win, if (glist) { ZnFree(glist); } + if (glist2) { + ZnFree(glist2); + } if (fontinfo) { for (i = 0; i < fontinfo->num_glyphs; i++) { if (fontinfo->glyph[i].bitmap) -- cgit v1.1