aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--generic/Image.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/generic/Image.c b/generic/Image.c
new file mode 100644
index 0000000..1b9093b
--- /dev/null
+++ b/generic/Image.c
@@ -0,0 +1,262 @@
+/*
+ * Image.c -- Image support routines.
+ *
+ * Authors : Patrick LECOANET
+ * Creation date : Wed Dec 8 11:04:44 1999
+ */
+
+/*
+ * Copyright (c) 1999 CENA, Patrick Lecoanet --
+ *
+ * This code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this code; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <malloc.h>
+
+#include "Types.h"
+#include "Image.h"
+
+
+static const char rcsid[] = "$Id$";
+static const char compile_id[] = "$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $";
+
+
+/*
+ * Key used to index the bitmap_masks hash table.
+ */
+typedef struct {
+ Display *dpy;
+ Pixmap bitmap;
+} BitmapKey;
+
+typedef struct _ImagePixmap {
+ Display *dpy;
+ Pixmap pixmap;
+ struct _ImagePixmap *next;
+} ImagePixmap;
+
+
+static Tcl_HashTable image_bits;
+static Tcl_HashTable bitmap_masks;
+
+
+/*
+ **********************************************************************************
+ *
+ * GetImageBits --
+ *
+ **********************************************************************************
+ */
+ImageBits *
+GetImageBits(RadarWindow win,
+ RadarImage image)
+{
+ static int inited = 0;
+ Tcl_HashEntry *entry;
+ XImage *im1, *im2, *mask;
+ Pixmap pmap;
+ Display *dpy = Tk_Display(win);
+ int depth = Tk_Depth(win);
+ int x, y, new, width, height;
+ XGCValues values;
+ GC gc;
+ ImageBits *im_bits;
+ RadarBool full_mask=True;
+
+ if (!inited) {
+ Tcl_InitHashTable(&image_bits, TCL_ONE_WORD_KEYS);
+ inited = 1;
+ }
+ entry = Tcl_FindHashEntry(&image_bits, (char *) image);
+ if (entry != NULL) {
+ im_bits = (ImageBits *) Tcl_GetHashValue(entry);
+ }
+ else {
+ Tk_SizeOfImage(image, &width, &height);
+ im_bits = (ImageBits *) RadarMalloc(sizeof(ImageBits));
+ im_bits->pixmaps = NULL;
+ pmap = XCreatePixmap(dpy, RadarWindowId(win), width, height, depth);
+
+ values.foreground = 0;
+ gc = XCreateGC(dpy, pmap, GCForeground, &values);
+ XFillRectangle(dpy, pmap, gc, 0, 0, width, height);
+ Tk_RedrawImage(image, 0, 0, width, height, pmap, 0, 0);
+ im_bits->pixels = im1 = XGetImage(dpy, pmap, 0, 0, width, height, ~0L, ZPixmap);
+ im_bits->width = width;
+ im_bits->height = height;
+
+ values.foreground = 1;
+ XChangeGC(dpy, gc, GCForeground, &values);
+ XFillRectangle(dpy, pmap, gc, 0, 0, width, height);
+ XFreeGC(dpy, gc);
+ Tk_RedrawImage(image, 0, 0, width, height, pmap, 0, 0);
+ im2 = XGetImage(dpy, pmap, 0, 0, width, height, ~0L, ZPixmap);
+ XFreePixmap(dpy, pmap);
+
+ /*
+ * The image structure can be setup locally (TODO).
+ */
+ pmap = XCreatePixmap(dpy, RadarWindowId(win), width, height, 1);
+ values.foreground = 0;
+ gc = XCreateGC(dpy, pmap, GCForeground, &values);
+ XFillRectangle(dpy, pmap, gc, 0, 0, width, height);
+ XFreeGC(dpy, gc);
+ mask = XGetImage(dpy, pmap, 0, 0, width, height, 1, XYPixmap);
+ XFreePixmap(dpy, pmap);
+
+ for (x = 0; x < width; x++) {
+ for (y = 0; y < height; y++) {
+ if (XGetPixel(im1, x, y) == XGetPixel(im2, x, y)) {
+ XPutPixel(mask, x, y, 1L);
+ }
+ else {
+ full_mask = False;
+ }
+ }
+ }
+
+ XDestroyImage(im2);
+ if (full_mask) {
+ XDestroyImage(mask);
+ im_bits->mask = RadarUnspecifiedPattern;
+ }
+ else {
+ im_bits->mask = mask;
+ }
+
+ entry = Tcl_CreateHashEntry(&image_bits, (char *) image, &new);
+ Tcl_SetHashValue(entry, (ClientData) im_bits);
+ }
+
+ return im_bits;
+}
+
+void
+InvalidateImage(RadarImage image)
+{
+ Tcl_HashEntry *entry;
+ ImageBits *im_bits;
+ ImagePixmap *im_pmap, *next_im_pmap;
+
+ /*
+ * Destroy the image entry and wait the cache fault to
+ * reload the new one.
+ */
+ entry = Tcl_FindHashEntry(&image_bits, (char *) image);
+ if (entry != NULL) {
+ im_bits = (ImageBits *) Tcl_GetHashValue(entry);
+ XDestroyImage(im_bits->pixels);
+ if (im_bits->mask) {
+ XDestroyImage(im_bits->mask);
+ }
+ im_pmap = im_bits->pixmaps;
+ while (im_pmap) {
+ next_im_pmap = im_pmap->next;
+ XFreePixmap(im_pmap->dpy, im_pmap->pixmap);
+ RadarFree(im_pmap);
+ im_pmap = next_im_pmap;
+ }
+ RadarFree(im_bits);
+ Tcl_DeleteHashEntry(entry);
+ }
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetImagePixmap --
+ *
+ **********************************************************************************
+ */
+Pixmap
+GetImagePixmap(RadarWindow win,
+ RadarImage image)
+{
+ ImageBits *im_bits;
+ Display *dpy = Tk_Display(win);
+ int depth = Tk_Depth(win);
+ ImagePixmap *im_pmap, *next_im_pmap;
+ Pixmap pixmap;
+
+ im_bits = GetImageBits(win, image);
+ im_pmap = next_im_pmap = im_bits->pixmaps;
+ while (next_im_pmap && (im_pmap->dpy != dpy)) {
+ im_pmap = next_im_pmap;
+ next_im_pmap = next_im_pmap->next;
+ }
+ if (!im_pmap || (im_pmap->dpy != dpy)) {
+ next_im_pmap = (ImagePixmap *) RadarMalloc(sizeof(ImagePixmap));
+ next_im_pmap->next = NULL;
+ next_im_pmap->dpy = dpy;
+ pixmap = XCreatePixmap(dpy, RadarWindowId(win),
+ im_bits->width, im_bits->height, depth);
+ Tk_RedrawImage(image, 0, 0, im_bits->width, im_bits->height, pixmap, 0, 0);
+ next_im_pmap->pixmap = pixmap;
+ if (im_pmap) {
+ im_pmap->next = next_im_pmap;
+ }
+ else {
+ im_bits->pixmaps = next_im_pmap;
+ }
+ }
+ else {
+ pixmap = im_pmap->pixmap;
+ }
+
+ return pixmap;
+}
+
+
+/*
+ **********************************************************************************
+ *
+ * GetBitmapMask --
+ *
+ **********************************************************************************
+ */
+XImage *
+GetBitmapMask(Display *dpy,
+ Pixmap bitmap)
+{
+ static int inited = 0;
+ BitmapKey key;
+ Tcl_HashEntry *entry;
+ XImage *mask;
+ int w, h, new;
+
+ if (!inited) {
+ Tcl_InitHashTable(&bitmap_masks, (sizeof(Display *)+sizeof(Pixmap)) / sizeof(int));
+ inited = 1;
+ }
+ key.dpy = dpy;
+ key.bitmap = bitmap;
+ entry = Tcl_FindHashEntry(&bitmap_masks, (char *) &key);
+ if (entry != NULL) {
+ mask = (XImage *) Tcl_GetHashValue(entry);
+ }
+ else {
+ Tk_SizeOfBitmap(dpy, bitmap, &w, &h);
+ mask = XGetImage(dpy, bitmap, 0, 0, w, h, 1L, XYPixmap);
+ key.dpy = dpy;
+ key.bitmap = bitmap;
+ entry = Tcl_CreateHashEntry(&bitmap_masks, (char *) &key, &new);
+ Tcl_SetHashValue(entry, (ClientData) mask);
+ }
+
+ return mask;
+}