From 3261805fee19e346b4d1f84b23816daa1628764a Mon Sep 17 00:00:00 2001 From: lecoanet Date: Wed, 16 Apr 2003 09:49:22 +0000 Subject: Update from the Windows port and general cleanup/restructure --- generic/Image.c | 1151 ++++++++++++++++++++++--------------------------------- 1 file changed, 450 insertions(+), 701 deletions(-) (limited to 'generic/Image.c') diff --git a/generic/Image.c b/generic/Image.c index 00f5f22..2a0f7c3 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -25,20 +25,16 @@ */ -#include -#include - #include "Types.h" #include "Image.h" #include "WidgetInfo.h" #include "Geo.h" +#include "Draw.h" + +#include #include -#ifdef GLX +#ifdef GL #include -#include -#include -#include -#include "Draw.h" #endif @@ -48,7 +44,7 @@ static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ static int images_inited = 0; static Tcl_HashTable images; -#ifdef GLX +#ifdef GL static Tcl_HashTable font_textures; #endif @@ -56,14 +52,13 @@ typedef struct _ImageStruct { union { struct { Pixmap pixmap; - Pixmap mask_pmap; Screen *screen; } x; struct { -#ifdef GLX +#ifdef GL GLuint texobj; #endif - struct _WidgetInfo *wi; + struct _ZnWInfo *wi; } gl; } i; struct _ImageBits *bits; @@ -77,177 +72,34 @@ typedef struct _ImageStruct { typedef struct _ImageBits { - int width; - int height; - unsigned char *bpixels; /* Needed at least to know the bounds (Pick), or if - * the image is a bitmap. Can be NULL if no mask is - * defined for the image (i.e the image is - * rectangular) and the image is not a bitmap. */ + unsigned char *bpixels; /* Needed for bitmaps. Set to NULL if the image + * is a photo. */ int rowstride; -#ifdef GLX +#ifdef GL ZnReal t; /* Texture parameters for the image. */ ZnReal s; -#endif - - /* Bookeeping */ - - Tcl_HashEntry *hash; /* From this it is easy to get the image/bitmap - * name. */ - XImage *ipixels; /* Keep this to create textures and pixmaps as - * needed. NULL if the image is a bitmap. This - * can be tested to tell if this is an image or - * a bitmap. */ - XImage *mask; /* Keep this to build special clip mask in X (Icon). - * Can be NULL if no mask is defined for the image - * (i.e the image is rectangular) or if the image - * is a bitmap. */ -#ifdef GLX int t_width; /* Texture size used for this image. */ int t_height; unsigned char *t_bits; /* Can be NULL if texture is not used (no GL * rendering active on this image). */ #endif + + /* Bookeeping */ + Tk_Image tkimage; /* Keep this handle to be informed of changes */ + Tk_PhotoHandle tkphoto; + int width; + int height; + Tcl_HashEntry *hash; /* From this it is easy to get the image/bitmap + * name. */ Image images; /* Linked list of widget/display dependant * specializations of this image. If NULL, the * image has no specialization and can be freed. */ } ImageBits; -#ifdef GLX -/* - * Working only for 16 bits displays with 5r6g5b mask, - * and 24/32 bits displays. Byte ordering ok on Intel - * plateform only. - */ -static void -From5r6g5b(unsigned char *data, - int width, - int height, - int bytes_per_line, - int t_width, - int t_height, - unsigned char *bpixels, - int bstride, - unsigned char *t_bits) -{ - int x, y; - int rowstride = t_width * 4; - unsigned char *obptr; - unsigned char *bptr, *bp2; - unsigned char alpha; - unsigned short temp; - - bptr = t_bits; - - for (y = 0; y < height; y++) { - bp2 = bptr; - obptr = data; - for (x = 0; x < width; x++) { - /* - * Configure the alpha value. - */ - if (bpixels) { - alpha = ZnGetBitmapPixel(bpixels, bstride, x, y) ? 255 : 0; - } - else { - alpha = 255; - } +char *ZnNameOfImage(ZnImage image); - /* - * Dispatch the 3 color components. - */ - temp = ((unsigned short *)obptr)[0]; - *bp2 = (temp >> 8) & 0xf8; /* r */ - bp2++; - *bp2 = (temp >> 3) & 0xfc; /* v */ - bp2++; - *bp2 = (temp << 3); /* b */ - bp2++; - *bp2 = alpha; - bp2++; - obptr += 2; - } - for (x = width; x < t_width; x++) { - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - } - bptr += rowstride; - data += bytes_per_line; - } - for (y = height; y < t_height; y++) { - memset(bptr, 0, rowstride); - bptr += rowstride; - } -} - -static void -From8r8g8b(unsigned char *data, - int width, - int height, - int bytes_per_line, - int t_width, - int t_height, - unsigned char *bpixels, - int bstride, - unsigned char *t_bits) -{ - int x, y; - int rowstride = t_width * 4; - unsigned char *obptr; - unsigned char *bptr, *bp2; - unsigned char alpha; - - bptr = t_bits; - - for (y = 0; y < height; y++) { - bp2 = bptr; - obptr = data; - for (x = 0; x < width; x++) { - /* - * Configure the alpha value. - */ - if (bpixels) { - alpha = ZnGetBitmapPixel(bpixels, bstride, x, y) ? 255 : 0; - } - else { - alpha = 255; - } - - /* - * Dispatch the 3 color components. - * Be careful the Red and Blue are swapped it works on an Intel - * plateform but may need some more tests to be fully generic. - */ - *bp2++ = obptr[2]; /* r */ - *bp2++ = obptr[1]; /* v */ - *bp2++ = obptr[0]; /* b */ - obptr += 4; - *bp2++ = alpha; - } - for (x = width; x < t_width; x++) { - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - *bp2 = 0; - bp2++; - } - bptr += rowstride; - data += bytes_per_line; - } - for (y = height; y < t_height; y++) { - memset(bptr, 0, rowstride); - bptr += rowstride; - } -} +#ifdef GL static int To2Power(int a) @@ -270,99 +122,73 @@ To2Power(int a) ********************************************************************************** */ static void -InvalidateImage(ClientData client_data, - int x, - int y, - int width, - int height, - int image_width, - int image_height) +InvalidateImage(ClientData client_data __unused, + int x __unused, + int y __unused, + int width __unused, + int height __unused, + int image_width __unused, + int image_height __unused) { /* * Void stub that keeps the Tk image mecanism happy. Zinc does - * _not_ implement image update. + * _not_ implement image update yet. */ } -static void -GatherImageBits(WidgetInfo *wi, - Tk_Image tkimage, - ImageBits *bits) +ZnImage +ZnGetImage(ZnWInfo *wi, + Tk_Uid image_name) { - Pixmap pmap; - int depth = DefaultDepthOfScreen(wi->screen); - int x, y; - unsigned char *line; - GC gc; - XImage *im1, *im2; - ZnBool full_mask=True; + Tcl_HashEntry *entry; + int new; + ImageBits *bits; + ZnBool for_gl = wi->render>0; + Image image; - /* - * Nothing known about this image, collect the image bits. - */ - pmap = XCreatePixmap(wi->dpy, RootWindowOfScreen(wi->screen), - bits->width, bits->height, depth); - gc = XCreateGC(wi->dpy, pmap, 0, NULL); - XSetForeground(wi->dpy, gc, 0); - XFillRectangle(wi->dpy, pmap, gc, 0, 0, bits->width, bits->height); - Tk_RedrawImage(tkimage, 0, 0, bits->width, bits->height, pmap, 0, 0); - im1 = bits->ipixels = XGetImage(wi->dpy, pmap, 0, 0, - bits->width, bits->height, ~0L, ZPixmap); - - XSetForeground(wi->dpy, gc, 1); - XFillRectangle(wi->dpy, pmap, gc, 0, 0, bits->width, bits->height); - Tk_RedrawImage(tkimage, 0, 0, bits->width, bits->height, pmap, 0, 0); - im2 = XGetImage(wi->dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); - XFreePixmap(wi->dpy, pmap); - - /* - * The image structure can be setup locally (TODO). - */ - XFreeGC(wi->dpy, gc); - pmap = XCreatePixmap(wi->dpy, RootWindowOfScreen(wi->screen), - bits->width, bits->height, 1); - gc = XCreateGC(wi->dpy, pmap, 0, NULL); - XSetForeground(wi->dpy, gc, 0); - XFillRectangle(wi->dpy, pmap, gc, 0, 0, bits->width, bits->height); - XFreeGC(wi->dpy, gc); - bits->mask = XGetImage(wi->dpy, pmap, 0, 0, bits->width, bits->height, 1, XYPixmap); - XFreePixmap(wi->dpy, pmap); - - bits->rowstride = bits->mask->bytes_per_line; - bits->bpixels = ZnMalloc(bits->height * bits->rowstride); - memset(bits->bpixels, 0, bits->height * bits->rowstride); - line = bits->bpixels; - for (y = 0; y < bits->height; y++) { - for (x = 0; x < bits->width; x++) { - if (XGetPixel(im1, x, y) == XGetPixel(im2, x, y)) { - XPutPixel(bits->mask, x, y, 1L); - line[x >> 3] |= 0x80 >> (x & 7); - } - else { - full_mask = False; + /*printf("ZnGetImage: %s\n", image_name);*/ + if (!images_inited) { + Tcl_InitHashTable(&images, TCL_STRING_KEYS); + images_inited = 1; + } + image_name = Tk_GetUid(image_name); + entry = Tcl_FindHashEntry(&images, image_name); + if (entry != NULL) { + /*printf("Image %s déjà connue\n", image_name);*/ + bits = (ImageBits *) Tcl_GetHashValue(entry); + } + else { + /*printf("Nouvelle Image %s\n", image_name);*/ + if (strcmp(image_name, "") == 0) { + return ZnUnspecifiedImage; + } + bits = ZnMalloc(sizeof(ImageBits)); + bits->tkphoto = Tk_FindPhoto(wi->interp, image_name); + if (bits->tkphoto == NULL) { + im_val_err: + ZnWarning("unknown or bogus photo image \""); + ZnWarning(image_name); + ZnWarning("\"\n"); + ZnFree(bits); + return ZnUnspecifiedImage; + } + else { + Tk_PhotoGetSize(bits->tkphoto, &bits->width, &bits->height); + if ((bits->width == 0) || (bits->height == 0)) { + goto im_val_err; } +#ifdef GL + bits->t_bits = NULL; +#endif + bits->images = NULL; + bits->bpixels = NULL; + bits->tkimage = Tk_GetImage(wi->interp, wi->win, image_name, + InvalidateImage, (ClientData) bits); + entry = Tcl_CreateHashEntry(&images, image_name, &new); + bits->hash = entry; + Tcl_SetHashValue(entry, (ClientData) bits); } - line += bits->rowstride; } - - XDestroyImage(im2); - if (full_mask) { - XDestroyImage(bits->mask); - bits->mask = NULL; - ZnFree(bits->bpixels); - bits->bpixels = NULL; - } -} - -static Image -GetImageInstance(WidgetInfo *wi, - ImageBits *bits) -{ - int depth = DefaultDepthOfScreen(wi->screen); - ZnBool for_gl = wi->render>0; - XGCValues values; - GC gc; - Image image; /* * Try to find an image instance that fits this widget/display. @@ -386,33 +212,35 @@ GetImageInstance(WidgetInfo *wi, image->bits = bits; image->refcount = 1; image->for_gl = for_gl; + if (image->for_gl) { image->i.gl.wi = wi; -#ifdef GLX +#ifdef GL image->i.gl.texobj = 0; #endif } else { + Tk_Image tkimage; + image->i.x.screen = wi->screen; - image->i.x.pixmap = XCreatePixmap(wi->dpy, RootWindowOfScreen(wi->screen), - bits->width, bits->height, depth); - gc = XCreateGC(wi->dpy, image->i.x.pixmap, 0, NULL); - XPutImage(wi->dpy, image->i.x.pixmap, gc, bits->ipixels, 0, 0, 0, 0, - bits->width, bits->height); - XFreeGC(wi->dpy, gc); - if (bits->mask) { - image->i.x.mask_pmap = XCreatePixmap(wi->dpy, RootWindowOfScreen(wi->screen), - bits->width, bits->height, 1); - values.foreground = 1; - values.background = 0; - gc = XCreateGC(wi->dpy, image->i.x.mask_pmap, - GCForeground|GCBackground, &values); - XPutImage(wi->dpy, image->i.x.mask_pmap, gc, bits->mask, 0, 0, 0, 0, - bits->width, bits->height); - XFreeGC(wi->dpy, gc); + if (bits->images == NULL) { + /* This is the first instance we can use safely the + * main tkimage. + */ + tkimage = bits->tkimage; } else { - image->i.x.mask_pmap = None; + /* Create a temporary tkimage to draw the pixmap. + */ + tkimage = Tk_GetImage(wi->interp, wi->win, image_name, NULL, NULL); + } + image->i.x.pixmap = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), + bits->width, bits->height, + DefaultDepthOfScreen(wi->screen)); + Tk_RedrawImage(tkimage, 0, 0, bits->width, bits->height, + image->i.x.pixmap, 0, 0); + if (tkimage != bits->tkimage) { + Tk_FreeImage(tkimage); } } image->next = bits->images; @@ -421,73 +249,6 @@ GetImageInstance(WidgetInfo *wi, return image; } -ZnImage -ZnGetImage(WidgetInfo *wi, - Tk_Uid image_name) -{ - Tcl_HashEntry *entry; - int new; - ImageBits *bits; - Tk_Image tkimage; - - /*printf("ZnGetImage: %s\n", image_name);*/ - if (!images_inited) { - Tcl_InitHashTable(&images, TCL_STRING_KEYS); - images_inited = 1; - } - image_name = Tk_GetUid(image_name); - entry = Tcl_FindHashEntry(&images, image_name); - if (entry != NULL) { - /*printf("Image %s déjà connue\n", image_name);*/ - bits = (ImageBits *) Tcl_GetHashValue(entry); - return GetImageInstance(wi, bits); - } - else { - /*printf("Nouvelle Image %s\n", image_name);*/ - if (strcmp(image_name, "") == 0) { - return ZnUnspecifiedImage; - } - bits = ZnMalloc(sizeof(ImageBits)); - tkimage = Tk_GetImage(wi->interp, wi->win, image_name, - InvalidateImage, (ClientData) bits); - if (tkimage == NULL) { - im_val_err: - ZnFree(bits); - ZnWarning("unknown or bogus image \""); - ZnWarning(image_name); - ZnWarning("\"\n"); - return ZnUnspecifiedImage; - } - else { - Tk_SizeOfImage(tkimage, &bits->width, &bits->height); - if ((bits->width == 0) || (bits->height == 0)) { - Tk_FreeImage(tkimage); - goto im_val_err; - } - } -#ifdef GLX - bits->t_bits = NULL; -#endif - bits->images = NULL; - bits->mask = NULL; - bits->bpixels = NULL; - bits->ipixels = NULL; - entry = Tcl_CreateHashEntry(&images, image_name, &new); - bits->hash = entry; - Tcl_SetHashValue(entry, (ClientData) bits); - } - - if (!bits->ipixels) { - /* - * First time use of the image, read in - * the bits and free the Tk image. - */ - GatherImageBits(wi, tkimage, bits); - Tk_FreeImage(tkimage); - } - return GetImageInstance(wi, bits); -} - /* ********************************************************************************** * @@ -496,17 +257,13 @@ ZnGetImage(WidgetInfo *wi, ********************************************************************************** */ ZnImage -ZnGetBitmap(WidgetInfo *wi, +ZnGetBitmap(ZnWInfo *wi, Tk_Uid bitmap_name) { Tcl_HashEntry *entry; ImageBits *bits; - Pixmap pmap; - XImage *mask; Image image; ZnBool for_gl = wi->render>0; - int x, y, new, width, height; - unsigned char *line; /*printf("ZnGetBitmap: %s\n", bitmap_name);*/ if (!images_inited) { @@ -519,28 +276,29 @@ ZnGetBitmap(WidgetInfo *wi, bits = (ImageBits *) Tcl_GetHashValue(entry); } else { + Pixmap pmap; + XImage *mask; + int x, y, new; + unsigned char *line; + pmap = Tk_GetBitmap(wi->interp, wi->win, bitmap_name); if (pmap == ZnUnspecifiedImage) { return ZnUnspecifiedImage; } - Tk_SizeOfBitmap(wi->dpy, pmap, &width, &height); bits = ZnMalloc(sizeof(ImageBits)); - bits->width = width; - bits->height = height; -#ifdef GLX + Tk_SizeOfBitmap(wi->dpy, pmap, &bits->width, &bits->height); +#ifdef GL bits->t_bits = NULL; #endif bits->images = NULL; - bits->mask = NULL; - bits->bpixels = NULL; - bits->ipixels = NULL; - mask = XGetImage(wi->dpy, pmap, 0, 0, width, height, 1L, XYPixmap); + mask = XGetImage(wi->dpy, pmap, 0, 0, (unsigned int) bits->width, + (unsigned int) bits->height, 1L, XYPixmap); bits->rowstride = mask->bytes_per_line; - bits->bpixels = ZnMalloc(height * bits->rowstride); - memset(bits->bpixels, 0, height * bits->rowstride); + bits->bpixels = ZnMalloc((unsigned int) (bits->height * bits->rowstride)); + memset(bits->bpixels, 0, (unsigned int) (bits->height * bits->rowstride)); line = bits->bpixels; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { + for (y = 0; y < bits->height; y++) { + for (x = 0; x < bits->width; x++) { if (XGetPixel(mask, x, y)) { line[x >> 3] |= 0x80 >> (x & 7); } @@ -579,13 +337,12 @@ ZnGetBitmap(WidgetInfo *wi, image->for_gl = for_gl; if (image->for_gl) { image->i.gl.wi = wi; -#ifdef GLX +#ifdef GL image->i.gl.texobj = 0; #endif } else { image->i.x.screen = wi->screen; - image->i.x.mask_pmap = None; /* * Need to get a pixmap that match this dpy. */ @@ -615,6 +372,19 @@ ZnGetImageByValue(ZnImage image) /* ********************************************************************************** * + * ZnImageIsBitmap -- + * + ********************************************************************************** + */ +ZnBool +ZnImageIsBitmap(ZnImage image) +{ + return (((Image) image)->bits->bpixels != NULL); +} + +/* + ********************************************************************************** + * * ZnFreeImage -- * ********************************************************************************** @@ -649,24 +419,20 @@ ZnFreeImage(ZnImage image) prev->next = this->next; } if (this->for_gl) { -#ifdef GLX - WidgetInfo *wi = this->i.gl.wi; +#ifdef GL + ZnWInfo *wi = this->i.gl.wi; if (this->i.gl.texobj && wi->win) { - glXMakeCurrent(wi->dpy, ZnWindowId(wi->win), wi->gl_context); + ZnGLMakeCurrent(wi); glDeleteTextures(1, &this->i.gl.texobj); + ZnGLRelease(wi); } #endif } - else if (bits->ipixels) { + else if (!ZnImageIsBitmap(image)) { /* - * This is an image, we need to free the pixmaps. + * This is an image, we need to free the instances. */ - if (this->i.x.pixmap != None) { - XFreePixmap(DisplayOfScreen(this->i.x.screen), this->i.x.pixmap); - } - if (this->i.x.mask_pmap != None) { - XFreePixmap(DisplayOfScreen(this->i.x.screen), this->i.x.mask_pmap); - } + Tk_FreePixmap(DisplayOfScreen(this->i.x.screen), this->i.x.pixmap); } else { /* @@ -681,20 +447,17 @@ ZnFreeImage(ZnImage image) */ if (bits->images == NULL) { /*printf("destruction complète de l'image %s\n", ZnNameOfImage(this));*/ -#ifdef GLX +#ifdef GL if (bits->t_bits) { ZnFree(bits->t_bits); } #endif - if (bits->mask) { - XDestroyImage(bits->mask); - } - if (bits->ipixels) { - XDestroyImage(bits->ipixels); - } - if (bits->bpixels) { + if (ZnImageIsBitmap(image)) { ZnFree(bits->bpixels); } + else { + Tk_FreeImage(bits->tkimage); + } Tcl_DeleteHashEntry(bits->hash); ZnFree(bits); } @@ -727,40 +490,30 @@ ZnSizeOfImage(ZnImage image, int *width, int *height) { - Image im = (Image) image; - *width = im->bits->width; - *height = im->bits->height; + Image this = (Image) image; + + *width = this->bits->width; + *height = this->bits->height; } /* ********************************************************************************** * - * ZnImagePattern -- + * ZnImagePixmap -- * ********************************************************************************** */ -char * -ZnImagePattern(ZnImage image, - int *stride) +Pixmap +ZnImagePixmap(ZnImage image) { - if (stride) { - *stride = ((Image) image)->bits->rowstride; - } - return ((Image) image)->bits->bpixels; -} + Image this = (Image) image; -/* - ********************************************************************************** - * - * ZnImageIsBitmap -- - * - ********************************************************************************** - */ -ZnBool -ZnImageIsBitmap(ZnImage image) -{ - return (((Image) image)->bits->ipixels == NULL); + if (this->for_gl) { + printf("Bogus use of an image, it was created for GL and used in an X11 context\n"); + return None; + } + return this->i.x.pixmap; } /* @@ -770,31 +523,38 @@ ZnImageIsBitmap(ZnImage image) * ********************************************************************************** */ -XImage * -ZnImageMask(ZnImage image) +char * +ZnImageMask(ZnImage image, + int *stride) { - return ((Image) image)->bits->mask; + Image this = (Image) image; + + if (stride) { + *stride = this->bits->rowstride; + } + return this->bits->bpixels; } /* ********************************************************************************** * - * ZnImagePixmap -- + * ZnImageRegion -- * ********************************************************************************** */ -Pixmap -ZnImagePixmap(ZnImage image, - Pixmap *mask_pmap) +TkRegion +ZnImageRegion(ZnImage image) { - if (((Image) image)->for_gl) { - printf("Bogus use of an image, it was created for GL and use in an X11 context\n"); - return None; + if (ZnImageIsBitmap(image)) { + return NULL; } - if (mask_pmap) { - *mask_pmap = ((Image) image)->i.x.mask_pmap; + else { +#ifdef PTK + return NULL; +#else + return TkPhotoGetValidRegion(((Image) image)->bits->tkphoto); +#endif } - return ((Image) image)->i.x.pixmap; } /* @@ -804,28 +564,32 @@ ZnImagePixmap(ZnImage image, * ********************************************************************************** */ -#ifdef GLX +#ifdef GL GLuint ZnImageTex(ZnImage image, ZnReal *t, ZnReal *s) { - Image this = (Image) image; - ImageBits *bits = this->bits; - ZnBool is_bmap = ZnImageIsBitmap(image); - int depth, t_size; + Image this = (Image) image; + ImageBits *bits = this->bits; + ZnBool is_bmap = ZnImageIsBitmap(image); + unsigned int t_size, width, height; + Tk_PhotoImageBlock block; + int green_off, blue_off, alpha_off; if (!this->for_gl) { + printf("Bogus use of an image, it was created for X11 and used in a GL context\n"); return 0; } + ZnSizeOfImage(image, &width, &height); if (!bits->t_bits) { /*printf("chargement texture pour image %s\n", ZnNameOfImage(this));*/ - bits->t_width = To2Power(bits->width); - bits->t_height = To2Power(bits->height); - bits->s = bits->width / (ZnReal) bits->t_width; - bits->t = bits->height / (ZnReal) bits->t_height; + bits->t_width = To2Power((int) width); + bits->t_height = To2Power((int) height); + bits->s = width / (ZnReal) bits->t_width; + bits->t = height / (ZnReal) bits->t_height; if (is_bmap) { - int i, j; + unsigned int i, j; unsigned char *ostart, *dstart, *d, *o; t_size = bits->t_width * bits->t_height; @@ -833,10 +597,10 @@ ZnImageTex(ZnImage image, memset(bits->t_bits, 0, t_size); ostart = bits->bpixels; dstart = bits->t_bits; - for (i = 0; i < bits->height; i++) { + for (i = 0; i < height; i++) { d = dstart; o = ostart; - for (j = 0; j < bits->width; j++) { + for (j = 0; j < width; j++) { *d++ = ZnGetBitmapPixel(bits->bpixels, bits->rowstride, j, i) ? 255 : 0; } ostart += bits->rowstride; @@ -844,24 +608,42 @@ ZnImageTex(ZnImage image, } } else { - t_size = bits->t_width * 4 * bits->t_height; + unsigned int x, y, t_stride; + unsigned char *obptr, *bptr, *bp2, *pixels; + + t_stride = bits->t_width * 4; + t_size = t_stride * bits->t_height; bits->t_bits = ZnMalloc(t_size); - if (this->for_gl) { - depth = DefaultDepthOfScreen(this->i.gl.wi->screen); - } - else { - depth = DefaultDepthOfScreen(this->i.x.screen); - } - if (depth == 16) { - From5r6g5b(bits->ipixels->data, bits->width, bits->height, - bits->ipixels->bytes_per_line, bits->t_width, bits->t_height, - bits->bpixels, bits->rowstride, bits->t_bits); - } - else if ((depth == 24) || (depth == 32)) { - From8r8g8b(bits->ipixels->data, bits->width, bits->height, - bits->ipixels->bytes_per_line, bits->t_width, bits->t_height, - bits->bpixels, bits->rowstride, bits->t_bits); + Tk_PhotoGetImage(bits->tkphoto, &block); + green_off = block.offset[1] - block.offset[0]; + blue_off = block.offset[2] - block.offset[0]; + alpha_off = block.offset[3] - block.offset[0]; + pixels = block.pixelPtr; + bptr = bits->t_bits; + + for (y = 0; y < height; y++) { + bp2 = bptr; + obptr = pixels; + for (x = 0; x < width; x++) { + *bp2++ = obptr[0]; /* r */ + *bp2++ = obptr[green_off]; /* g */ + *bp2++ = obptr[blue_off]; /* b */ + *bp2++ = obptr[alpha_off]; /* alpha */ + obptr += 4; + } + /*for (x = width; x < t_width; x++) { + *bp2 = 0; bp2++; + *bp2 = 0; bp2++; + *bp2 = 0; bp2++; + *bp2 = 0; bp2++; + }*/ + bptr += t_stride; + pixels += block.pitch; } + /*for (y = height; y < t_height; y++) { + memset(bptr, 0, t_stride); + bptr += t_stride; + }*/ } } if (!this->i.gl.texobj) { @@ -885,6 +667,7 @@ ZnImageTex(ZnImage image, } glBindTexture(GL_TEXTURE_2D, 0); } + *t = this->bits->t; *s = this->bits->s; return this->i.gl.texobj; @@ -892,25 +675,25 @@ ZnImageTex(ZnImage image, #endif - -#ifdef GLX +#ifdef GL /* Copyright (c) Mark J. Kilgard, 1997. */ /* This program is freely distributable without licensing fees and is provided without guarantee or warrantee expressed or implied. This program is -not- in the public domain. */ -#define MAX_GLYPHS_PER_GRAB 512 /* this is big enough for 2^9 glyph - * character sets */ +#define MAX_CHAR (256-32-1) +#define MIN_CHAR 32 +#define MAX_GLYPHS_PER_GRAB 256 typedef struct { - unsigned short c; /* Potentially support 16-bit glyphs. */ - unsigned char width; - unsigned char height; - char xoffset; - char yoffset; - char advance; + unsigned char c; char dummy; /* Space holder for alignment reasons. */ + short width; + short height; + short xoffset; + short yoffset; + short advance; short x; short y; } TexGlyphInfo; @@ -918,21 +701,21 @@ typedef struct { typedef struct _TexFontInfo { GLuint texobj; struct _TexFont *txf; - WidgetInfo *wi; - int refcount; + ZnWInfo *wi; + unsigned int refcount; struct _TexFontInfo *next; } TexFontInfo; typedef struct _TexFont { TexFontInfo *tfi; - ZnFont tkfont; + Tk_Font tkfont; int tex_width; int tex_height; - int max_ascent; - int max_descent; - int num_glyphs; - int min_glyph; - int range; + int ascent; + int descent; + unsigned int num_glyphs; + unsigned int min_glyph; + unsigned int range; unsigned char *teximage; TexGlyphInfo *tgi; ZnTexGVI *tgvi; @@ -952,9 +735,9 @@ typedef struct { typedef struct { int min_char; int max_char; - int max_ascent; - int max_descent; - int num_glyphs; + int ascent; + int descent; + unsigned int num_glyphs; PerGlyphInfo glyph[1]; } FontInfo, *FontInfoPtr; @@ -1015,7 +798,7 @@ void placeGlyph(FontInfoPtr font, int c, unsigned char *texarea, - int stride, + unsigned int stride, int x, int y) { @@ -1044,51 +827,50 @@ placeGlyph(FontInfoPtr font, } FontInfoPtr -SuckGlyphsFromServer(ZnWindow win, - ZnFont font) +SuckGlyphsFromServer(ZnWInfo *wi, + Tk_Font font) { - Display *dpy = Tk_Display(win); - XFontStruct *fontinfo = NULL; Pixmap offscreen = 0; XImage *image = NULL; GC xgc = 0; XGCValues values; - int width, height, pixwidth; - int i, j; - XCharStruct *charinfo=NULL; - XChar2b character; + unsigned int width, height, length, pixwidth; + unsigned int i, j; + char str[] = " "; unsigned char *bitmapData = NULL; - int x, y; - int numchars, spanLength=0; - int charWidth=0, charHeight=0, maxSpanLength; + unsigned int x, y; + int num_chars, spanLength=0; + unsigned int charWidth=0, maxSpanLength; int grabList[MAX_GLYPHS_PER_GRAB]; - int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; - int numToGrab, thisglyph; + unsigned int glyphsPerGrab = MAX_GLYPHS_PER_GRAB; + unsigned int numToGrab, thisglyph; FontInfoPtr myfontinfo = NULL; - - fontinfo = XQueryFont(dpy, Tk_FontId(font)); - if (!fontinfo) { - return NULL; - } - - numchars = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1; - if (numchars < 1) { - return NULL; - } + Tk_FontMetrics fm; - myfontinfo = (FontInfoPtr) ZnMalloc(sizeof(FontInfo) + (numchars - 1) * sizeof(PerGlyphInfo)); + Tk_GetFontMetrics(font, &fm); + num_chars = (MAX_CHAR-MIN_CHAR)+1; + myfontinfo = ZnMalloc(sizeof(FontInfo) + num_chars * sizeof(PerGlyphInfo)); if (!myfontinfo) { return NULL; } - myfontinfo->num_glyphs = numchars; - myfontinfo->min_char = fontinfo->min_char_or_byte2; - myfontinfo->max_char = fontinfo->max_char_or_byte2; - myfontinfo->max_ascent = fontinfo->max_bounds.ascent; - myfontinfo->max_descent = fontinfo->max_bounds.descent; + myfontinfo->min_char = MIN_CHAR; + myfontinfo->max_char = MAX_CHAR; + myfontinfo->num_glyphs = num_chars; + myfontinfo->ascent = fm.ascent; + myfontinfo->descent = fm.descent; - width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing; - height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent; + /* + * Try to guess a good approximation for the largest character + * in the font. This guess may be quite wrong for symbol fonts + * and for non european languages. + */ + *str = 'W'; + Tk_MeasureChars(font, str, 1, 0, TK_AT_LEAST_ONE, &width); + *str = 'M'; + Tk_MeasureChars(font, str, 1, 0, TK_AT_LEAST_ONE, &length); + width = MAX(width, length); + height = myfontinfo->ascent + myfontinfo->descent; maxSpanLength = (width + 7) / 8; /* Be careful determining the width of the pixmap; the X protocol allows @@ -1099,110 +881,85 @@ SuckGlyphsFromServer(ZnWindow win, glyphsPerGrab = (1 << 15) / (8 * maxSpanLength); } pixwidth = glyphsPerGrab * 8 * maxSpanLength; - offscreen = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), - pixwidth, height, 1); - + offscreen = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), + (int) pixwidth, (int) height, 1); + + values.background = WhitePixelOfScreen(wi->screen); + values.foreground = WhitePixelOfScreen(wi->screen); values.font = Tk_FontId(font); - values.background = 0; - values.foreground = 0; - xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values); - - XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); - XSetForeground(dpy, xgc, 1); + xgc = XCreateGC(wi->dpy, offscreen, GCBackground|GCForeground|GCFont, &values); + XFillRectangle(wi->dpy, offscreen, xgc, 0, 0, pixwidth, height); + values.foreground = BlackPixelOfScreen(wi->screen); + XChangeGC(wi->dpy, xgc, GCForeground, &values); numToGrab = 0; - if (fontinfo->per_char == NULL) { - charinfo = &(fontinfo->min_bounds); - charWidth = charinfo->rbearing - charinfo->lbearing; - charHeight = charinfo->ascent + charinfo->descent; - spanLength = (charWidth + 7) / 8; - } for (i = 0; i < myfontinfo->num_glyphs; i++) { - if (fontinfo->per_char != NULL) { - charinfo = &(fontinfo->per_char[i]); - charWidth = charinfo->rbearing - charinfo->lbearing; - charHeight = charinfo->ascent + charinfo->descent; - if (charWidth == 0 || charHeight == 0) { - /* Still must move raster pos even if empty character */ - myfontinfo->glyph[i].width = 0; - myfontinfo->glyph[i].height = 0; - myfontinfo->glyph[i].xoffset = 0; - myfontinfo->glyph[i].yoffset = 0; - myfontinfo->glyph[i].advance = charinfo->width; - myfontinfo->glyph[i].bitmap = NULL; - goto PossiblyDoGrab; - } + *str = i + myfontinfo->min_char; + Tk_MeasureChars(font, str, 1, 0, TK_AT_LEAST_ONE, &charWidth); + + myfontinfo->glyph[i].width = charWidth; + myfontinfo->glyph[i].height = height; + myfontinfo->glyph[i].xoffset = 0; + myfontinfo->glyph[i].yoffset = myfontinfo->descent; + myfontinfo->glyph[i].advance = charWidth; + myfontinfo->glyph[i].bitmap = NULL; + if (charWidth != 0) { + Tk_DrawChars(wi->dpy, offscreen, xgc, font, str, 1, + (int) (8*maxSpanLength*numToGrab), myfontinfo->ascent); + grabList[numToGrab] = i; + numToGrab++; } - grabList[numToGrab] = i; - - /* XXX is this right for large fonts? */ - character.byte2 = (i + fontinfo->min_char_or_byte2) & 255; - character.byte1 = (i + fontinfo->min_char_or_byte2) >> 8; - - XDrawString16(dpy, offscreen, xgc, - -charinfo->lbearing + 8 * maxSpanLength * numToGrab, - charinfo->ascent, &character, 1); - - numToGrab++; - PossiblyDoGrab: if ((numToGrab >= glyphsPerGrab) || (i == myfontinfo->num_glyphs - 1)) { - image = XGetImage(dpy, offscreen, 0, 0, pixwidth, height, 1, XYPixmap); + image = XGetImage(wi->dpy, offscreen, 0, 0, pixwidth, height, 1, XYPixmap); + for (j = 0; j < numToGrab; j++) { - thisglyph = grabList[j]; - if (fontinfo->per_char != NULL) { - charinfo = &(fontinfo->per_char[thisglyph]); - charWidth = charinfo->rbearing - charinfo->lbearing; - charHeight = charinfo->ascent + charinfo->descent; - spanLength = (charWidth + 7) / 8; - } - bitmapData = ZnMalloc(height * spanLength * sizeof(char)); - if (bitmapData == NULL) { - goto FreeFontAndReturn; + thisglyph = grabList[j]; + charWidth = myfontinfo->glyph[thisglyph].width; + spanLength = (charWidth + 7) / 8; + bitmapData = ZnMalloc(height * spanLength * sizeof(char)); + if (bitmapData == NULL) { + goto FreeFontAndReturn; } memset(bitmapData, 0, height * spanLength * sizeof(char)); - for (y = 0; y < charHeight; y++) { - for (x = 0; x < charWidth; x++) { - /* XXX The algorithm used to suck across the font ensures that - each glyph begins on a byte boundary. In theory this would - make it convienent to copy the glyph into a byte oriented - bitmap. We actually use the XGetPixel function to extract - each pixel from the image which is not that efficient. We - could either do tighter packing in the pixmap or more - efficient extraction from the image. Oh well. */ - if (XGetPixel(image, j * maxSpanLength * 8 + x, y)) { - bitmapData[y * spanLength + x / 8] |= (1 << (x & 7)); - } - } - } - myfontinfo->glyph[thisglyph].width = charWidth; - myfontinfo->glyph[thisglyph].height = charHeight; - myfontinfo->glyph[thisglyph].xoffset = charinfo->lbearing; - myfontinfo->glyph[thisglyph].yoffset = charinfo->descent; - myfontinfo->glyph[thisglyph].advance = charinfo->width; - myfontinfo->glyph[thisglyph].bitmap = bitmapData; + myfontinfo->glyph[thisglyph].bitmap = bitmapData; + for (y = 0; y < height; y++) { + for (x = 0; x < charWidth; x++) { + /* XXX The algorithm used to suck across the font ensures that + each glyph begins on a byte boundary. In theory this would + make it convienent to copy the glyph into a byte oriented + bitmap. We actually use the XGetPixel function to extract + each pixel from the image which is not that efficient. We + could either do tighter packing in the pixmap or more + efficient extraction from the image. Oh well. */ + if (XGetPixel(image, (int) (j*maxSpanLength*8) + x, y) == BlackPixelOfScreen(wi->screen)) { + bitmapData[y * spanLength + x / 8] |= (1 << (x & 7)); + } + } + } } XDestroyImage(image); numToGrab = 0; /* do we need to clear the offscreen pixmap to get more? */ if (i < myfontinfo->num_glyphs - 1) { - XSetForeground(dpy, xgc, 0); - XFillRectangle(dpy, offscreen, xgc, 0, 0, + values.foreground = WhitePixelOfScreen(wi->screen); + XChangeGC(wi->dpy, xgc, GCForeground, &values); + XFillRectangle(wi->dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height); - XSetForeground(dpy, xgc, 1); + values.foreground = BlackPixelOfScreen(wi->screen); + XChangeGC(wi->dpy, xgc, GCForeground, &values); } } } - XFreeFontInfo(NULL, fontinfo, 1); - XFreeGC(dpy, xgc); - XFreePixmap(dpy, offscreen); + + XFreeGC(wi->dpy, xgc); + Tk_FreePixmap(wi->dpy, offscreen); return myfontinfo; FreeFontAndReturn: - XFreeFontInfo(NULL, fontinfo, 1); XDestroyImage(image); - XFreeGC(dpy, xgc); - XFreePixmap(dpy, offscreen); + XFreeGC(wi->dpy, xgc); + Tk_FreePixmap(wi->dpy, offscreen); for (i = 0; i < myfontinfo->num_glyphs; i++) { if (myfontinfo->glyph[i].bitmap) ZnFree(myfontinfo->glyph[i].bitmap); @@ -1219,28 +976,37 @@ SuckGlyphsFromServer(ZnWindow win, ********************************************************************************** */ ZnTexFontInfo -ZnGetTexFont(WidgetInfo *wi, - ZnFont font) +ZnGetTexFont(ZnWInfo *wi, + Tk_Font font) { TexFont *txf; TexFontInfo *tfi; static int inited = 0; Tcl_HashEntry *entry; - char const *fontname = Tk_NameOfFont(font); int new; + unsigned char *glisto = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijmklmnopqrstuvwxyz{|}~°ÀÂÇÈÉÊËÎÏÔÙÛÜàâçèéêëîïôùûü~`"; + unsigned char *glist=NULL, *glist2=NULL; + TexGlyphInfo *tgi; + unsigned int i, j; + int min_glyph, max_glyph; + int gap = 1; /* gap between glyphs */ + int px, py, maxheight; + int width, height; + unsigned int texw, texh; + GLfloat xstep, ystep; + GLuint max_tex_size[1]; if (!inited) { - Tcl_InitHashTable(&font_textures, TCL_STRING_KEYS); + Tcl_InitHashTable(&font_textures, TCL_ONE_WORD_KEYS); inited = 1; } - entry = Tcl_FindHashEntry(&font_textures, fontname); + entry = Tcl_FindHashEntry(&font_textures, (char *) font); if (entry != NULL) { - /*printf("found font: %d |%s|\n", wi, fontname);*/ txf = (TexFont *) Tcl_GetHashValue(entry); } else { - /*printf("new font: %d |%s|\n", wi, fontname);*/ + /*printf("Loading a new texture font for %s\n", Tk_NameOfFont(font));*/ txf = ZnMalloc(sizeof(TexFont)); if (txf == NULL) { return NULL; @@ -1249,88 +1015,21 @@ ZnGetTexFont(WidgetInfo *wi, txf->tgi = NULL; txf->tgvi = NULL; txf->lut = NULL; - txf->teximage = NULL; txf->tkfont = font; - entry = Tcl_CreateHashEntry(&font_textures, fontname, &new); + entry = Tcl_CreateHashEntry(&font_textures, (char *) font, &new); Tcl_SetHashValue(entry, (ClientData) txf); txf->hash = entry; - } - - /* - * 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) { - tfi->refcount++; - return tfi; - } - } - /* - * Not found allocate a new texture object. - */ - tfi = ZnMalloc(sizeof(TexFontInfo)); - if (tfi == NULL) { - ZnFree(txf); - return NULL; - } - tfi->refcount = 1; - tfi->texobj = 0; - tfi->wi = wi; - tfi->txf = txf; - tfi->next = txf->tfi; - txf->tfi = tfi; - - return tfi; -} - - -/* - ********************************************************************************** - * - * ZnNameOfTexFont -- - * - ********************************************************************************** - */ -char * -ZnNameOfTexFont(ZnTexFontInfo tfi) -{ - return Tcl_GetHashKey(&font_textures, ((TexFontInfo *) tfi)->txf->hash); -} - -/* - ********************************************************************************** - * - * ZnTexFontTex -- - * - ********************************************************************************** - */ -GLuint -ZnTexFontTex(ZnTexFontInfo tfi) -{ - TexFontInfo *this = (TexFontInfo *) tfi; - TexFont *txf = this->txf; - unsigned char *glisto = "\t\x14\x15\x16\x17 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijmklmnopqrstuvwxyz{|}~°ÀÂÇÈÉÊËÎÏÔÙÛÜàâçèéêëîïôùûü~`"; - unsigned char *glist=NULL, *glist2=NULL; - TexGlyphInfo *tgi; - int i, j; - int min_glyph, max_glyph; - int gap = 1; /* gap between glyphs */ - int px, py, maxheight; - int width, height; - GLfloat xstep, ystep, texw, texh; - GLuint max_tex_size[1]; - if (!txf->teximage) { /*printf("Chargement de la texture pour la fonte %s\n", ZnNameOfTexFont(tfi));*/ glGetIntegerv(GL_MAX_TEXTURE_SIZE, max_tex_size); - fontinfo = SuckGlyphsFromServer(this->wi->win, txf->tkfont); + fontinfo = SuckGlyphsFromServer(wi, txf->tkfont); if (fontinfo == NULL) { goto error; } - txf->max_ascent = fontinfo->max_ascent; - txf->max_descent = fontinfo->max_descent; + txf->ascent = fontinfo->ascent; + txf->descent = fontinfo->descent; txf->num_glyphs = strlen(glisto); /* @@ -1339,7 +1038,7 @@ ZnTexFontTex(ZnTexFontInfo tfi) */ texw = 128; texh = 64; - while (texh < txf->max_ascent+txf->max_descent) { + while (texh < (unsigned int) (txf->ascent+txf->descent)) { texh *= 2; } if (texh > max_tex_size[0]) { @@ -1352,7 +1051,6 @@ ZnTexFontTex(ZnTexFontInfo tfi) if (txf->teximage == NULL) { goto error; } - /*memset(txf->teximage, 0x55, texw * texh * sizeof(unsigned char));*/ txf->tgi = ZnMalloc(txf->num_glyphs * sizeof(TexGlyphInfo)); if (txf->tgi == NULL) { @@ -1392,7 +1090,7 @@ ZnTexFontTex(ZnTexFontInfo tfi) if ((height > 0) && (width > 0)) { for (j = i; j < txf->num_glyphs;) { if ((height > 0) && (width > 0)) { - if (px + width + gap < texw) { + if ((unsigned int) (px + width + gap) < texw) { foundWidthFit = 1; if (j != i) { i--; /* Step back so i loop increment leaves us at same character. */ @@ -1428,7 +1126,7 @@ ZnTexFontTex(ZnTexFontInfo tfi) py += maxheight + gap; px = gap; maxheight = height; - if (py + height + gap >= texh) { + if ((unsigned int) (py + height + gap) >= texh) { if (texh*2 < max_tex_size[0]) { texh *= 2; ZnFree(txf->teximage); @@ -1469,20 +1167,20 @@ ZnTexFontTex(ZnTexFontInfo tfi) 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].t0[0] = tgi->x / ((GLfloat) texw) + xstep; + txf->tgvi[c].t0[1] = tgi->y / ((GLfloat) texh) + ystep; txf->tgvi[c].v0[0] = tgi->xoffset; txf->tgvi[c].v0[1] = tgi->yoffset - tgi->height; - txf->tgvi[c].t1[0] = (tgi->x + tgi->width) / texw + xstep; - txf->tgvi[c].t1[1] = tgi->y / texh + ystep; + txf->tgvi[c].t1[0] = (tgi->x + tgi->width) / ((GLfloat) texw) + xstep; + txf->tgvi[c].t1[1] = tgi->y / ((GLfloat) texh) + ystep; txf->tgvi[c].v1[0] = (tgi->xoffset + tgi->width); txf->tgvi[c].v1[1] = tgi->yoffset - tgi->height; - txf->tgvi[c].t2[0] = (tgi->x + tgi->width) / texw + xstep; - txf->tgvi[c].t2[1] = (tgi->y + tgi->height) / texh + ystep; + txf->tgvi[c].t2[0] = (tgi->x + tgi->width) / ((GLfloat) texw) + xstep; + txf->tgvi[c].t2[1] = (tgi->y + tgi->height) / ((GLfloat) texh) + ystep; txf->tgvi[c].v2[0] = (tgi->xoffset + tgi->width); txf->tgvi[c].v2[1] = tgi->yoffset; - txf->tgvi[c].t3[0] = tgi->x / texw + xstep; - txf->tgvi[c].t3[1] = (tgi->y + tgi->height) / texh + ystep; + txf->tgvi[c].t3[0] = tgi->x / ((GLfloat) texw) + xstep; + txf->tgvi[c].t3[1] = (tgi->y + tgi->height) / ((GLfloat) texh) + ystep; txf->tgvi[c].v3[0] = tgi->xoffset; txf->tgvi[c].v3[1] = tgi->yoffset; txf->tgvi[c].advance = tgi->advance; @@ -1509,7 +1207,37 @@ ZnTexFontTex(ZnTexFontInfo tfi) txf->lut = ZnMalloc(txf->range * sizeof(ZnTexGVI *)); if (txf->lut == NULL) { - goto error; + error: + if (glist) { + ZnFree(glist); + } + if (glist2) { + ZnFree(glist2); + } + if (fontinfo) { + for (i = 0; i < fontinfo->num_glyphs; i++) { + if (fontinfo->glyph[i].bitmap) + ZnFree(fontinfo->glyph[i].bitmap); + } + ZnFree(fontinfo); + } + if (txf->tgi) { + ZnFree(txf->tgi); + txf->tgi = NULL; + } + if (txf->tgvi) { + ZnFree(txf->tgvi); + txf->tgvi = NULL; + } + if (txf->lut) { + ZnFree(txf->lut); + txf->lut = NULL; + } + if (txf->teximage) { + ZnFree(txf->teximage); + txf->teximage = NULL; + } + return 0; } memset(txf->lut, 0, txf->range * sizeof(ZnTexGVI *)); for (i = 0; i < txf->num_glyphs; i++) { @@ -1525,6 +1253,61 @@ ZnTexFontTex(ZnTexFontInfo tfi) ZnFree(glist2); } + /* + * 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) { + tfi->refcount++; + return tfi; + } + } + /* + * Not found allocate a new texture object. + */ + tfi = ZnMalloc(sizeof(TexFontInfo)); + if (tfi == NULL) { + ZnFree(txf); + return NULL; + } + tfi->refcount = 1; + tfi->texobj = 0; + tfi->wi = wi; + tfi->txf = txf; + tfi->next = txf->tfi; + txf->tfi = tfi; + + return tfi; +} + + +/* + ********************************************************************************** + * + * ZnNameOfTexFont -- + * + ********************************************************************************** + */ +char const * +ZnNameOfTexFont(ZnTexFontInfo tfi) +{ + return Tk_NameOfFont((Tk_Font) Tcl_GetHashKey(&font_textures, + ((TexFontInfo *) tfi)->txf->hash)); +} + +/* + ********************************************************************************** + * + * ZnTexFontTex -- + * + ********************************************************************************** + */ +GLuint +ZnTexFontTex(ZnTexFontInfo tfi) +{ + TexFontInfo *this = (TexFontInfo *) tfi; + TexFont *txf = this->txf; + if (!this->texobj) { glGenTextures(1, &this->texobj); /*printf("%d creation texture %d pour la fonte %s\n", @@ -1541,40 +1324,6 @@ ZnTexFontTex(ZnTexFontInfo tfi) /*printf("%d utilisation de la texture %d\n", this->wi, this->texobj);*/ return this->texobj; - - error: - if (glist) { - ZnFree(glist); - } - if (glist2) { - ZnFree(glist2); - } - if (fontinfo) { - for (i = 0; i < fontinfo->num_glyphs; i++) { - if (fontinfo->glyph[i].bitmap) - ZnFree(fontinfo->glyph[i].bitmap); - } - ZnFree(fontinfo); - } - - if (txf->tgi) { - ZnFree(txf->tgi); - txf->tgi = NULL; - } - if (txf->tgvi) { - ZnFree(txf->tgvi); - txf->tgvi = NULL; - } - if (txf->lut) { - ZnFree(txf->lut); - txf->lut = NULL; - } - if (txf->teximage) { - ZnFree(txf->teximage); - txf->teximage = NULL; - } - - return 0; } @@ -1589,7 +1338,7 @@ void ZnFreeTexFont(ZnTexFontInfo tfi) { TexFontInfo *this = ((TexFontInfo *) tfi); - WidgetInfo *wi = this->wi; + ZnWInfo *wi = this->wi; TexFont *txf = this->txf; TexFontInfo *prev, *scan; @@ -1619,8 +1368,9 @@ ZnFreeTexFont(ZnTexFontInfo tfi) if (this->texobj && wi->win) { /*printf("%d Libération de la texture %d pour la fonte %s\n", wi, this->texobj, ZnNameOfTexFont(tfi));*/ - glXMakeCurrent(wi->dpy, ZnWindowId(wi->win), wi->gl_context); + ZnGLMakeCurrent(wi); glDeleteTextures(1, &this->texobj); + ZnGLRelease(wi); } /* @@ -1649,7 +1399,7 @@ ZnFreeTexFont(ZnTexFontInfo tfi) */ ZnBool ZnCharInTexFont(ZnTexFontInfo tfi, - int c) + unsigned int c) { TexFont *txf = ((TexFontInfo *) tfi)->txf; @@ -1670,7 +1420,7 @@ ZnCharInTexFont(ZnTexFontInfo tfi, */ ZnTexGVI * ZnTexFontGVI(ZnTexFontInfo tfi, - int c) + unsigned int c) { TexFont *txf = ((TexFontInfo *) tfi)->txf; ZnTexGVI *tgvi; @@ -1701,5 +1451,4 @@ ZnTexFontGVI(ZnTexFontInfo tfi, return txf->lut[(int)'!' - txf->min_glyph]; } - #endif -- cgit v1.1