aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
authorlecoanet2004-05-10 15:41:55 +0000
committerlecoanet2004-05-10 15:41:55 +0000
commit96f898b005d363247b69705d3367097f7823deb6 (patch)
treecbcf793d30af55d8bc4e4c56e2042db21eac13eb /generic
parenta8fcb0c3ec8e2a14e2ade2555bbc030b6ef89c9a (diff)
downloadtkzinc-96f898b005d363247b69705d3367097f7823deb6.zip
tkzinc-96f898b005d363247b69705d3367097f7823deb6.tar.gz
tkzinc-96f898b005d363247b69705d3367097f7823deb6.tar.bz2
tkzinc-96f898b005d363247b69705d3367097f7823deb6.tar.xz
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).
Diffstat (limited to 'generic')
-rw-r--r--generic/Image.c128
1 files changed, 96 insertions, 32 deletions
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) {