aboutsummaryrefslogtreecommitdiff
path: root/generic/Image.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/Image.c')
-rw-r--r--generic/Image.c111
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)
{