From 96f898b005d363247b69705d3367097f7823deb6 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Mon, 10 May 2004 15:41:55 +0000 Subject: Reworked once more the font loading code to fix a bug occuring under windows. This time GL fonts loading is deferred to just before drawing. This fix the drawing problem that occured the first time a window was mapped (and may be other problems has well). --- generic/Image.c | 128 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 32 deletions(-) (limited to 'generic/Image.c') diff --git a/generic/Image.c b/generic/Image.c index 7157bdf..d293894 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -183,7 +183,6 @@ InvalidateImage(ClientData client_data, if (this->for_gl) { if (this->i.texobj) { ZnGLContextEntry *ce; - /*OutputDebugString("InvalidateImage\n");*/ ce = ZnGLMakeCurrent(this->dpy, 0); glDeleteTextures(1, &this->i.texobj); ZnGLReleaseContext(ce); @@ -515,7 +514,6 @@ ZnFreeImage(ZnImage image, #ifdef GL if (this->i.texobj) { ZnGLContextEntry *ce; - /*OutputDebugString("FreeImage\n");*/ ce = ZnGLMakeCurrent(this->dpy, 0); /* printf("%d Liberation de la texture %d pour l'image %s\n", wi, this->i.texobj, ZnNameOfImage(image));*/ @@ -1116,6 +1114,13 @@ typedef struct _TexFont { Tcl_HashEntry *hash; } TexFont; +typedef struct _DeferredGLGlyphs { + ZnWInfo *wi; + TexFont *txf; +} DeferredGLGlyphsStruct; + +ZnList DeferredGLGlyphs; + #ifndef PTK_800 #include "CharsetUTF8.h" @@ -1124,9 +1129,8 @@ typedef struct _TexFont { #endif -static int +static void SuckGlyphsFromServer(ZnWInfo *wi, - Tk_Font font, TexFont *txf) { Pixmap offscreen = 0; @@ -1149,7 +1153,8 @@ SuckGlyphsFromServer(ZnWInfo *wi, #endif ZnGLContextEntry *ce = ZnGetGLContext(wi->dpy); - Tk_GetFontMetrics(font, &fm); + /*printf("loading a font \n");*/ + Tk_GetFontMetrics(txf->tkfont, &fm); #ifndef PTK_800 txf->num_glyphs = Tcl_NumUtfChars(ZnDefaultCharset, strlen(ZnDefaultCharset)); #else @@ -1185,7 +1190,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, #else next = cur + 1; #endif - Tk_MeasureChars(font, cur, next - cur, 0, TK_AT_LEAST_ONE, &length); + Tk_MeasureChars(txf->tkfont, cur, next - cur, 0, TK_AT_LEAST_ONE, &length); txf->glyph[i].width = length; txf->max_char_width = MAX(txf->max_char_width, length); @@ -1265,7 +1270,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, XSetBackground(wi->dpy, xgc, WhitePixelOfScreen(wi->screen)); XFillRectangle(wi->dpy, offscreen, xgc, 0, 0, pixwidth, height); XSetForeground(wi->dpy, xgc, BlackPixelOfScreen(wi->screen)); - XSetFont(wi->dpy, xgc, Tk_FontId(font)); + XSetFont(wi->dpy, xgc, Tk_FontId(txf->tkfont)); numToGrab = 0; cur = ZnDefaultCharset; @@ -1278,7 +1283,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, next = cur + 1; #endif if (txf->glyph[i].width != 0) { - Tk_DrawChars(wi->dpy, offscreen, xgc, font, cur, next - cur, + Tk_DrawChars(wi->dpy, offscreen, xgc, txf->tkfont, cur, next - cur, (int) (8*maxSpanLength*numToGrab), txf->ascent); grabList[numToGrab] = i; numToGrab++; @@ -1330,7 +1335,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, XFreeGC(wi->dpy, xgc); Tk_FreePixmap(wi->dpy, offscreen); - return 1; + return; FreeAndReturn: if (txf->glyph) { @@ -1345,10 +1350,68 @@ SuckGlyphsFromServer(ZnWInfo *wi, ZnFree(txf->teximage); txf->teximage = NULL; } + ZnWarning("Cannot load font texture for font "); + ZnWarning(Tk_NameOfFont(txf->tkfont)); + ZnWarning("\n"); +} + +static void +ZnNeedToGetGLGlyphs(ZnWInfo *wi, + TexFont *txf) +{ + DeferredGLGlyphsStruct dgg, *dggp; + int i, num; + + if (!DeferredGLGlyphs) { + DeferredGLGlyphs = ZnListNew(4, sizeof(DeferredGLGlyphsStruct)); + } + dggp = ZnListArray(DeferredGLGlyphs); + num = ZnListSize(DeferredGLGlyphs); + for (i = 0; i < num; i++, dggp++) { + if (dggp->txf == txf) { + return; + } + } + + dgg.wi = wi; + dgg.txf = txf; + ZnListAdd(DeferredGLGlyphs, &dgg, ZnListTail); + /*printf("adding a font to load\n");*/ +} + +void +ZnGetDeferredGLGlyphs(void) +{ + DeferredGLGlyphsStruct *dggp; + int i, num = ZnListSize(DeferredGLGlyphs); + + if (!num) { + return; + } + dggp = ZnListArray(DeferredGLGlyphs); + for (i = 0; i < num; i++, dggp++) { + SuckGlyphsFromServer(dggp->wi, dggp->txf); + } + ZnListEmpty(DeferredGLGlyphs); +} - return 0; +static void +ZnRemovedDeferredGLGlyph(TexFont *txf) +{ + DeferredGLGlyphsStruct *dggp; + int i, num; + + dggp = ZnListArray(DeferredGLGlyphs); + num = ZnListSize(DeferredGLGlyphs); + for (i = 0; i < num; i++, dggp++) { + if (dggp->txf == txf) { + ZnListDelete(DeferredGLGlyphs, i); + return; + } + } } + /* ********************************************************************************** * @@ -1367,7 +1430,7 @@ ZnGetTexFont(ZnWInfo *wi, int new; if (!inited) { - Tcl_InitHashTable(&font_textures, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&font_textures, TCL_STRING_KEYS); inited = 1; } @@ -1375,12 +1438,13 @@ ZnGetTexFont(ZnWInfo *wi, tft->fa.family, tft->fa.size, tft->fa.weight, tft->fa.slant, tft->fa.underline, tft->fa.overstrike); */ - entry = Tcl_FindHashEntry(&font_textures, (char *) font); + entry = Tcl_FindHashEntry(&font_textures, Tk_NameOfFont(font)); if (entry != NULL) { + /*printf("Found an already created font %s\n", Tk_NameOfFont(font));*/ txf = (TexFont *) Tcl_GetHashValue(entry); } else { - /*printf("Loading a new texture font for %s\n", Tk_NameOfFont(font));*/ + /*printf("Creating a new texture font for %s\n", Tk_NameOfFont(font));*/ txf = ZnMalloc(sizeof(TexFont)); if (txf == NULL) { return NULL; @@ -1394,13 +1458,10 @@ ZnGetTexFont(ZnWInfo *wi, * when no further references on this TexFont exist. */ txf->tkfont = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(font)); - /*printf("Chargement de la texture pour la fonte %s\n", - ZnNameOfTexFont(tfi));*/ - if (!SuckGlyphsFromServer(wi, txf->tkfont, txf)) { - goto error; - } + /*printf("Scheduling glyph loading for font %s\n", ZnNameOfTexFont(tfi));*/ + ZnNeedToGetGLGlyphs(wi, txf); - entry = Tcl_CreateHashEntry(&font_textures, (char *) font, &new); + entry = Tcl_CreateHashEntry(&font_textures, Tk_NameOfFont(font), &new); Tcl_SetHashValue(entry, (ClientData) txf); txf->hash = entry; } @@ -1429,14 +1490,6 @@ ZnGetTexFont(ZnWInfo *wi, txf->tfi = tfi; return tfi; - - error: - Tk_FreeFont(txf->tkfont); - ZnFree(txf); - ZnWarning("Cannot load font texture for font "); - ZnWarning(Tk_NameOfFont(font)); - ZnWarning("\n"); - return 0; } @@ -1466,6 +1519,9 @@ ZnTexFontTex(ZnTexFontInfo tfi) TexFontInfo *this = (TexFontInfo *) tfi; TexFont *txf = this->txf; + if (!txf->teximage) { + return 0; + } if (!this->texobj) { glGenTextures(1, &this->texobj); /*printf("%d creation texture %d pour la fonte %s\n", @@ -1532,20 +1588,25 @@ ZnFreeTexFont(ZnTexFontInfo tfi) } if (this->texobj) { ZnGLContextEntry *ce; - /*printf("%d Liberation de la texture %d pour la fonte %s\n", + /*printf("%d Freeing texture %d from font %s\n", this->dpy, this->texobj, ZnNameOfTexFont(tfi));*/ - /*OutputDebugString("FreeFont\n");*/ ce = ZnGLMakeCurrent(this->dpy, 0); - glDeleteTextures(1, &this->texobj); - ZnGLReleaseContext(ce); + if (ce) { + glDeleteTextures(1, &this->texobj); + ZnGLReleaseContext(ce); + } } + /* + * Remove the font from the deferred load list + */ + ZnRemovedDeferredGLGlyph(txf); /* * There is no more client for this font * deallocate the structures. */ if (txf->tfi == NULL) { - /*printf("%d destruction complète du txf pour %s\n", this, ZnNameOfTexFont(tfi));*/ + /*printf("%d Freeing txf for %s\n", this, ZnNameOfTexFont(tfi));*/ Tk_FreeFont(txf->tkfont); ZnFree(txf->glyph); ZnFree(txf->tgvi); @@ -1586,6 +1647,9 @@ ZnGetFontIndex(ZnTexFontInfo tfi, */ txf = ((TexFontInfo *) tfi)->txf; tgvi = txf->tgvi; + if (!tgvi) { + return -1; + } min = 127; max = txf->num_glyphs; while (min < max) { -- cgit v1.1