changeset 81124:0c6ff12ab2fb

(search_image_cache): New function. Require background color match if background color is unspecified in the image spec. (uncache_image, lookup_image): Use it.
author Chong Yidong <cyd@stupidchicken.com>
date Sun, 03 Jun 2007 00:23:33 +0000
parents 307d03f3c7ab
children 227d6fc4a26c
files src/image.c
diffstat 1 files changed, 37 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/image.c	Sun Jun 03 00:21:56 2007 +0000
+++ b/src/image.c	Sun Jun 03 00:23:33 2007 +0000
@@ -1609,6 +1609,7 @@
 			     Image Cache
  ***********************************************************************/
 
+static struct image *search_image_cache P_ ((struct frame *, Lisp_Object, unsigned));
 static void cache_image P_ ((struct frame *f, struct image *img));
 static void postprocess_image P_ ((struct frame *, struct image *));
 
@@ -1631,24 +1632,47 @@
 }
 
 
-/* Search frame F for an images with spec SPEC, and free it.  */
+/* Find an image matching SPEC in the cache, and return it.  If no
+   image is found, return NULL.  */
+static struct image *
+search_image_cache (f, spec, hash)
+     struct frame *f;
+     Lisp_Object spec;
+     unsigned hash;
+{
+  struct image *img;
+  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+  Lisp_Object specified_bg = image_spec_value (spec, QCbackground, NULL);
+  int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
+
+  /* If the image spec does not specify a background color, the cached
+     image must have the same background color as the current frame.
+     The following code be improved.  For example, jpeg does not
+     support transparency, but currently a jpeg image spec won't match
+     a cached spec created with a different frame background.  The
+     extra memory usage is probably negligible in practice.  */
+  if (!c) return NULL;
+
+  for (img = c->buckets[i]; img; img = img->next)
+    if (img->hash == hash
+	&& !NILP (Fequal (img->spec, spec))
+	&& (STRINGP (specified_bg)
+	    || img->background == FRAME_BACKGROUND_PIXEL (f)))
+      break;
+  return img;
+}
+
+
+/* Search frame F for an image with spec SPEC, and free it.  */
 
 static void
 uncache_image (f, spec)
      struct frame *f;
      Lisp_Object spec;
 {
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
-  struct image *img;
-  unsigned hash = sxhash (spec, 0);
-  int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
-
-  for (img = c->buckets[i]; img; img = img->next)
-    if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
-      {
-	free_image (f, img);
-	break;
-      }
+  struct image *img = search_image_cache (f, spec, sxhash (spec, 0));
+  if (img)
+    free_image (f, img);
 }
 
 
@@ -1875,9 +1899,7 @@
      struct frame *f;
      Lisp_Object spec;
 {
-  struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
   struct image *img;
-  int i;
   unsigned hash;
   struct gcpro gcpro1;
   EMACS_TIME now;
@@ -1891,12 +1913,7 @@
 
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec, 0);
-  i = hash % IMAGE_CACHE_BUCKETS_SIZE;
-
-  for (img = c->buckets[i]; img; img = img->next)
-    if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
-      break;
-
+  img = search_image_cache (f, spec, hash);
   if (img && img->load_failed_p)
     {
       free_image (f, img);