diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Image.c | 111 |
1 files changed, 73 insertions, 38 deletions
diff --git a/generic/Image.c b/generic/Image.c index 7802b31..09ecdd3 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -38,6 +38,7 @@ #include <stdlib.h> #endif +#include <tkFont.h> static const char rcsid[] = "$Id$"; static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; @@ -52,6 +53,7 @@ static Tcl_HashTable font_textures; typedef struct _ClientStruct { void (*inv_proc)(void *cd); void *client_data; + int refcount; } ClientStruct; typedef struct _ImageStruct { @@ -132,14 +134,17 @@ InvalidateImage(ClientData client_data, int y __unused, int width __unused, int height __unused, - int image_width __unused, - int image_height __unused) + int image_width, + int image_height) { ImageBits *bits = (ImageBits *) client_data; Image this; int num_cs, count, i; ClientStruct *cs; + char *image_name; + /* printf("Invalidation, bits: %d, %d %d %d %d %d %d\n", + client_data, x, y, width, height, image_width, image_height);*/ if (ZnImageIsBitmap(bits->images)) { /* This is a bitmap nothing to update * (This should not happen) */ @@ -157,15 +162,20 @@ InvalidateImage(ClientData client_data, bits->valid_region = NULL; } + bits->width = image_width; + bits->height = image_height; + image_name = ZnNameOfImage(bits->images); + + /* + * The photo pointer must be updated. It changes when creating an new image with + * the same name as an old. The image is first deleted then re-instantiated. + * As a side effect we also rely on it for telling if an image is a photo. + */ + bits->tkphoto = Tk_FindPhoto(bits->wi->interp, image_name); + count = 0; this = bits->images; while (this) { - if (bits->tkphoto) { - Tk_PhotoGetSize(bits->tkphoto, &bits->width, &bits->height); - } - else { - Tk_SizeOfImage(bits->tkimage, &bits->width, &bits->height); - } #ifdef GL if (this->for_gl) { if (this->i.texobj) { @@ -197,7 +207,6 @@ InvalidateImage(ClientData client_data, } /*printf("Invalidate on image %s with %d clients\n", Tcl_GetHashKey(&images, bits->hash), count);*/ - } ZnImage @@ -222,11 +231,11 @@ ZnGetImage(ZnWInfo *wi, image_name = Tk_GetUid(image_name); entry = Tcl_FindHashEntry(&images, image_name); if (entry != NULL) { - /*printf("Image %s déjà connue\n", image_name);*/ + /*printf("Image \"%s\" is in cache\n", image_name);*/ bits = (ImageBits *) Tcl_GetHashValue(entry); } else { - /*printf("Nouvelle Image %s\n", image_name);*/ + /*printf("New image \"%s\"\n", image_name);*/ if (strcmp(image_name, "") == 0) { return ZnUnspecifiedImage; } @@ -314,7 +323,7 @@ ZnGetImage(ZnWInfo *wi, */ for (image = bits->images; image != NULL; image = image->next) { if (image->for_gl == for_gl) { - if ((for_gl && (image->wi == wi)) || + if ((for_gl && (image->wi->dpy == wi->dpy)) || (!for_gl && (image->wi->screen == wi->screen))) { if (!ZnImageIsBitmap(image)) { cs_ptr = ZnListArray(image->clients); @@ -322,6 +331,7 @@ ZnGetImage(ZnWInfo *wi, for (i = 0; i < num_cs; i++, cs_ptr++) { if ((cs_ptr->inv_proc == inv_proc) && (cs_ptr->client_data == client_data)) { + cs_ptr->refcount++; return image; } } @@ -329,7 +339,9 @@ ZnGetImage(ZnWInfo *wi, */ cs.inv_proc = inv_proc; cs.client_data = client_data; + cs.refcount = 1; ZnListAdd(image->clients, &cs, ZnListTail); + return image; } image->refcount++; return image; @@ -340,9 +352,10 @@ ZnGetImage(ZnWInfo *wi, /* * Create a new instance for this case. */ + /*printf("new instance for \"%s\"\n", image_name);*/ image = ZnMalloc(sizeof(ImageStruct)); image->bits = bits; - image->refcount = 1; + image->refcount = 0; image->for_gl = for_gl; image->wi = wi; @@ -350,8 +363,12 @@ ZnGetImage(ZnWInfo *wi, image->clients = ZnListNew(1, sizeof(ClientStruct)); cs.inv_proc = inv_proc; cs.client_data = client_data; + cs.refcount = 1; ZnListAdd(image->clients, &cs, ZnListTail); } + else { + image->refcount++; + } /* Init the real resource and let the client load it * on demand */ @@ -395,15 +412,19 @@ ZnGetImageByValue(ZnImage image, for (i = 0; i < num_cs; i++, cs_ptr++) { if ((cs_ptr->inv_proc == inv_proc) && (cs_ptr->client_data == client_data)) { + cs_ptr->refcount++; return image; } } cs.inv_proc = inv_proc; cs.client_data = client_data; + cs.refcount = 1; ZnListAdd(this->clients, &cs, ZnListTail); } + else { + this->refcount++; + } - this->refcount++; return image; } @@ -435,7 +456,7 @@ ZnFreeImage(ZnImage image, Image prev, scan, this = ((Image) image); ImageBits *bits = this->bits; ClientStruct *cs_ptr; - int i, num_cs; + int i, num_cs, rm_image; /*printf("ZnFreeImage: %s\n", ZnNameOfImage(image));*/ /* @@ -453,16 +474,21 @@ ZnFreeImage(ZnImage image, for (i = 0; i < num_cs; i++, cs_ptr++) { if ((cs_ptr->inv_proc == inv_proc) && (cs_ptr->client_data == client_data)) { - ZnListDelete(this->clients, i); - this->refcount--; + cs_ptr->refcount--; + if (cs_ptr->refcount == 0) { + ZnListDelete(this->clients, i); + } break; } } + rm_image = ZnListSize(this->clients)==0; } else { this->refcount--; + rm_image = this->refcount==0; } - if (this->refcount != 0) { + + if (!rm_image) { return; } @@ -478,9 +504,12 @@ ZnFreeImage(ZnImage image, if (this->for_gl) { #ifdef GL ZnWInfo *wi = this->wi; - if (this->i.texobj && wi->win) { + if (this->i.texobj) { ZnGLMakeCurrent(wi); + /* printf("%d Libération de la texture %d pour l'image %s\n", + wi, this->i.texobj, ZnNameOfImage(image));*/ glDeleteTextures(1, &this->i.texobj); + this->i.texobj = 0; ZnGLRelease(wi); } #endif @@ -954,6 +983,7 @@ ZnImageTex(ZnImage image, t_stride = bits->t_width * 4; t_size = t_stride * bits->t_height; + /*printf("t_width: %d(%d), t_height: %d(%d)\n", bits->t_width, width, bits->t_height, height);*/ bits->t_bits = ZnMalloc(t_size); Tk_PhotoGetImage(bits->tkphoto, &block); green_off = block.offset[1] - block.offset[0]; @@ -1006,8 +1036,8 @@ ZnImageTex(ZnImage image, if (!this->i.texobj) { glGenTextures(1, &this->i.texobj); - /*printf("creation texture %d pour image %s\n", - this->i.texobj, ZnNameOfImage(this));*/ + /*printf("%d creation texture %d pour image %s\n", + bits, this->i.texobj, ZnNameOfImage(this));*/ glBindTexture(GL_TEXTURE_2D, this->i.texobj); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -1027,7 +1057,7 @@ ZnImageTex(ZnImage image, if (glGetError() != GL_NO_ERROR) { ZnWarning("Can't allocate the texture for image "); ZnWarning(ZnNameOfImage(image)); - ZnWarning("\n"); + ZnWarning("\n"); } glBindTexture(GL_TEXTURE_2D, 0); } @@ -1063,8 +1093,8 @@ typedef struct { } TexGlyphInfo; typedef struct _TexFontInfo { - GLuint texobj; struct _TexFont *txf; + GLuint texobj; ZnWInfo *wi; unsigned int refcount; struct _TexFontInfo *next; @@ -1084,7 +1114,7 @@ typedef struct _TexFont { TexGlyphInfo *tgi; ZnTexGVI *tgvi; ZnTexGVI **lut; -#ifndef PTK +#ifndef PTK_800 Tcl_Encoding enc; #endif Tcl_HashEntry *hash; @@ -1193,7 +1223,7 @@ placeGlyph(FontInfoPtr font, } } -#ifdef PTK +#ifdef PTK_800 FontInfoPtr SuckGlyphsFromServer(ZnWInfo *wi, Tk_Font font) @@ -1211,7 +1241,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, unsigned int width, height, length, pixwidth; unsigned int i, j; char str_from[] = " "; -#ifndef PTK +#ifndef PTK_800 char str_utf[8]; #endif unsigned char *bitmapData = NULL; @@ -1246,7 +1276,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, width = 0; for (i = 0; i < myfontinfo->num_glyphs; i++) { *str_from = i + myfontinfo->min_char; -#ifdef PTK +#ifdef PTK_800 Tk_MeasureChars(font, str_from, 1, 0, TK_AT_LEAST_ONE, &length); #else Tcl_ExternalToUtf(wi->interp, enc, str_from, 1, @@ -1289,7 +1319,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, numToGrab = 0; for (i = 0; i < myfontinfo->num_glyphs; i++) { *str_from = i + myfontinfo->min_char; -#ifdef PTK +#ifdef PTK_800 Tk_MeasureChars(font, str_from, 1, 0, TK_AT_LEAST_ONE, &charWidth); #else Tcl_ExternalToUtf(wi->interp, enc, str_from, 1, @@ -1305,7 +1335,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, myfontinfo->glyph[i].advance = charWidth; myfontinfo->glyph[i].bitmap = NULL; if (charWidth != 0) { -#ifdef PTK +#ifdef PTK_800 Tk_DrawChars(wi->dpy, offscreen, xgc, font, str_from, 1, (int) (8*maxSpanLength*numToGrab), myfontinfo->ascent); #else @@ -1376,7 +1406,7 @@ SuckGlyphsFromServer(ZnWInfo *wi, return NULL; } -#ifndef PTK +#ifndef PTK_800 Tcl_Encoding ZnGetFontEncoding(ZnWInfo *wi, Tk_Font tkfont) @@ -1457,12 +1487,17 @@ ZnGetTexFont(ZnWInfo *wi, int width, height; unsigned int texw, texh; GLfloat xstep, ystep; + TkFont *tft = (TkFont *) font; if (!inited) { Tcl_InitHashTable(&font_textures, TCL_ONE_WORD_KEYS); inited = 1; } + /* printf("family: %s, size: %d, weight: %d, slant: %d, underline: %d, overstrike: %d\n", + 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); if (entry != NULL) { txf = (TexFont *) Tcl_GetHashValue(entry); @@ -1480,13 +1515,13 @@ ZnGetTexFont(ZnWInfo *wi, /* Get a local reference to the font, it will be deallocated * when no further references on this TexFont exist. */ txf->tkfont = Tk_GetFont(wi->interp, wi->win, Tk_NameOfFont(font)); -#ifndef PTK +#ifndef PTK_800 txf->enc = ZnGetFontEncoding(wi, txf->tkfont); #endif /*printf("Chargement de la texture pour la fonte %s\n", ZnNameOfTexFont(tfi));*/ -#ifdef PTK +#ifdef PTK_800 fontinfo = SuckGlyphsFromServer(wi, txf->tkfont); #else fontinfo = SuckGlyphsFromServer(wi, txf->tkfont, txf->enc); @@ -1714,7 +1749,7 @@ ZnGetTexFont(ZnWInfo *wi, ZnFree(txf->teximage); txf->teximage = NULL; } -#ifndef PTK +#ifndef PTK_800 Tcl_FreeEncoding(txf->enc); #endif Tk_FreeFont(txf->tkfont); @@ -1747,7 +1782,7 @@ ZnGetTexFont(ZnWInfo *wi, * Now locate the texture obj in the texture list for this widget. */ for (tfi = txf->tfi; tfi != NULL; tfi = tfi->next) { - if (tfi->wi == wi) { + if (tfi->wi->dpy == wi->dpy) { tfi->refcount++; return tfi; } @@ -1760,9 +1795,9 @@ ZnGetTexFont(ZnWInfo *wi, return NULL; } tfi->refcount = 1; - tfi->texobj = 0; tfi->wi = wi; tfi->txf = txf; + tfi->texobj = 0; tfi->next = txf->tfi; txf->tfi = tfi; @@ -1861,7 +1896,7 @@ ZnFreeTexFont(ZnTexFontInfo tfi) else { prev->next = this->next; } - if (this->texobj && wi->win) { + if (this->texobj) { /*printf("%d Libération de la texture %d pour la fonte %s\n", wi, this->texobj, ZnNameOfTexFont(tfi));*/ ZnGLMakeCurrent(wi); @@ -1880,7 +1915,7 @@ ZnFreeTexFont(ZnTexFontInfo tfi) ZnFree(txf->tgvi); ZnFree(txf->lut); ZnFree(txf->teximage); -#ifndef PTK +#ifndef PTK_800 Tcl_FreeEncoding(txf->enc); #endif Tcl_DeleteHashEntry(txf->hash); @@ -1918,7 +1953,7 @@ ZnCharInTexFont(ZnTexFontInfo tfi, * ********************************************************************************** */ -#ifndef PTK +#ifndef PTK_800 Tcl_Encoding ZnTexFontEncoding(ZnTexFontInfo tfi) { |