aboutsummaryrefslogtreecommitdiff
path: root/generic/Image.c
diff options
context:
space:
mode:
authorlecoanet2003-04-16 09:49:22 +0000
committerlecoanet2003-04-16 09:49:22 +0000
commit3261805fee19e346b4d1f84b23816daa1628764a (patch)
tree63ca1d7e4b0a3d9ae49cc0888e58033c3ef3fe22 /generic/Image.c
parenteed2656db0adae2c234c3d74af0913746ed5c444 (diff)
downloadtkzinc-3261805fee19e346b4d1f84b23816daa1628764a.zip
tkzinc-3261805fee19e346b4d1f84b23816daa1628764a.tar.gz
tkzinc-3261805fee19e346b4d1f84b23816daa1628764a.tar.bz2
tkzinc-3261805fee19e346b4d1f84b23816daa1628764a.tar.xz
Update from the Windows port and general cleanup/restructure
Diffstat (limited to 'generic/Image.c')
-rw-r--r--generic/Image.c1151
1 files changed, 450 insertions, 701 deletions
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 <malloc.h>
-#include <memory.h>
-
#include "Types.h"
#include "Image.h"
#include "WidgetInfo.h"
#include "Geo.h"
+#include "Draw.h"
+
+#include <memory.h>
#include <ctype.h>
-#ifdef GLX
+#ifdef GL
#include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <GL/glu.h>
-#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