break;
case IMAGE_WIDGET:
+ print_internal (IMAGE_INSTANCE_WIDGET_TYPE (ii), printcharfun, 0);
+
+ if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+ {
+ write_c_string (" ", printcharfun);
+ print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 1);
+ }
+
if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
{
- write_c_string (" (", printcharfun);
+ write_c_string (" face=", printcharfun);
print_internal
(IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
- write_c_string (")", printcharfun);
}
- if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
- print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
case IMAGE_SUBWINDOW:
case IMAGE_LAYOUT:
else
write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
printcharfun);
-
- write_c_string ("-frame ", printcharfun);
}
- write_c_string (">", printcharfun);
+ write_c_string ("-frame>", printcharfun);
sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
write_c_string (buf, printcharfun);
return DEVMETH_OR_GIVEN (d1, image_instance_equal, (i1, i2, depth), 1);
}
+#if 0
+/* internal_hash will not go very far down a list because of the way
+ its written. For items we need to hash all elements so we provide
+ our own list hashing function. */
static unsigned long
full_list_hash (Lisp_Object obj, int depth)
{
if (!CONSP (obj))
return internal_hash (obj, depth + 1);
- LIST_LOOP (rest, obj)
+ hash = LISP_HASH (XCAR (obj));
+ LIST_LOOP (rest, XCDR (obj))
{
- hash = HASH2 (internal_hash (XCAR (rest), depth + 1), hash);
+ hash = HASH2 (hash, internal_hash (XCAR (rest), depth + 1));
}
return hash;
}
+#endif
static unsigned long
image_instance_hash (Lisp_Object obj, int depth)
displayed. */
hash = HASH4 (hash,
LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
- full_list_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
- full_list_hash
- (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i))
- ? IMAGE_INSTANCE_WIDGET_ITEMS (i)
- : IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i),
- depth + 1));
+ internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
+ internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1));
case IMAGE_SUBWINDOW:
hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
break;
unsigned int* descent, Lisp_Object domain)
{
struct font_metric_info fm;
- unsigned char charsets[NUM_LEADING_BYTES];
+ Charset_ID charsets[NUM_LEADING_BYTES];
struct face_cachel frame_cachel;
struct face_cachel *cachel;
Lisp_Object frame = FW_FRAME (domain);
Lisp_Object
query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain)
{
- unsigned char charsets[NUM_LEADING_BYTES];
+ Charset_ID charsets[NUM_LEADING_BYTES];
struct face_cachel frame_cachel;
struct face_cachel *cachel;
int i;
Lisp_Object pointer_fg = Qnil;
Lisp_Object pointer_bg = Qnil;
- if (dest_mask & (IMAGE_SUBWINDOW_MASK
- | IMAGE_WIDGET_MASK
- | IMAGE_TEXT_MASK))
- {
- if (!WINDOWP (domain))
- signal_simple_error ("Can't instantiate text or subwindow outside a window",
- instantiator);
- else if ((dest_mask & (IMAGE_SUBWINDOW_MASK
- | IMAGE_WIDGET_MASK))
- && MINI_WINDOW_P (XWINDOW (domain)))
- domain = Fnext_window (domain, Qnil, Qnil, Qnil);
- }
+ /* We have to put subwindow, widget and text image instances in
+ a per-window cache so that we can see the same glyph in
+ different windows. Unfortunately we do not know the type of
+ image_instance until after it has been created. We thus need
+ to be really careful how we place things. */
if (pointerp)
{
&&
dest_mask & (IMAGE_SUBWINDOW_MASK
| IMAGE_WIDGET_MASK
- | IMAGE_TEXT_MASK))
+ | IMAGE_LAYOUT_MASK
+ | IMAGE_TEXT_MASK)
+ && WINDOWP (domain))
{
instance = Fgethash (instantiator,
XWINDOW (domain)->subwindow_instance_cache,
&
(IMAGE_SUBWINDOW_MASK
| IMAGE_WIDGET_MASK
+ | IMAGE_LAYOUT_MASK
| IMAGE_TEXT_MASK ))
{
+#ifdef ERROR_CHECK_GLYPHS
+ if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT)
+ assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
+ FW_FRAME (domain)));
+#endif
+ if (!WINDOWP (domain))
+ signal_simple_error ("Can't instantiate text or subwindow outside a window",
+ instantiator);
+#ifdef ERROR_CHECK_GLYPHS
+ if (XIMAGE_INSTANCE_TYPE (instance) != IMAGE_TEXT)
+ assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
+ FW_FRAME (domain)));
+#endif
Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache);
}
unbind_to (speccount, Qnil);
+#ifdef ERROR_CHECK_GLYPHS
+ if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
+ &
+ (IMAGE_SUBWINDOW_MASK
+ | IMAGE_WIDGET_MASK
+ | IMAGE_LAYOUT_MASK
+ | IMAGE_TEXT_MASK ))
+ assert (EQ (Fgethash ((pointerp ? ls3 : instantiator),
+ XWINDOW (domain)->subwindow_instance_cache,
+ Qunbound), instance));
+#endif
}
else
free_list (ls3);
if (NILP (instance))
signal_simple_error ("Can't instantiate image (probably cached)",
instantiator);
+#ifdef ERROR_CHECK_GLYPHS
+ if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
+ & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
+ assert (EQ (XIMAGE_INSTANCE_SUBWINDOW_FRAME (instance),
+ FW_FRAME (domain)));
+#endif
return instance;
}
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
int count = specpdl_depth ();
- unsigned long display_hash = internal_hash (subwindow,
- IMAGE_INSTANCE_HASH_DEPTH);
/* The update method is allowed to call eval. Since it is quite
common for this function to get called from somewhere in
||
IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT)
{
- if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
- &&
- (display_hash != IMAGE_INSTANCE_DISPLAY_HASH (ii)
- ||
- IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0))
- {
- update_widget (subwindow);
- }
+ if (image_instance_changed (subwindow))
+ update_widget (subwindow);
/* Reset the changed flags. */
IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
- IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0;
IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
}
visual appearance. However, we would rather that then the other
way round - it simply means that we will get more displays than
we might need. We can get better hashing by making the depth
- negative - currently it will recurse down 5 levels.*/
- IMAGE_INSTANCE_DISPLAY_HASH (ii) = display_hash;
+ negative - currently it will recurse down 7 levels.*/
+ IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
+ IMAGE_INSTANCE_HASH_DEPTH);
unbind_to (count, Qnil);
}
+int
+image_instance_changed (Lisp_Object subwindow)
+{
+ Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
+
+ if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
+ IMAGE_INSTANCE_DISPLAY_HASH (ii))
+ return 1;
+ else if ((WIDGET_IMAGE_INSTANCEP (subwindow)
+ || LAYOUT_IMAGE_INSTANCEP (subwindow))
+ && !internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
+ IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0))
+ return 1;
+ else
+ return 0;
+}
+
/* Update all the subwindows on a frame. */
DEFUN ("update-widget-instances", Fupdate_widget_instances,1, 1, 0, /*
Given a FRAME, re-evaluate the display hash code for all widgets in the frame.
Dynarr_atp (f->subwindow_cachels, elt);
if (cachel->being_displayed &&
- XIMAGE_INSTANCE_TYPE (cachel->subwindow)
- == IMAGE_WIDGET)
+ image_instance_changed (cachel->subwindow))
{
- /* If a subwindow hash changed mark it so that redisplay
- will fix it. */
- if (internal_hash (cachel->subwindow,
- IMAGE_INSTANCE_HASH_DEPTH) !=
- XIMAGE_INSTANCE_DISPLAY_HASH (cachel->subwindow))
- {
- set_image_instance_dirty_p (cachel->subwindow, 1);
- MARK_FRAME_GLYPHS_CHANGED (f);
- }
+ set_image_instance_dirty_p (cachel->subwindow, 1);
+ MARK_FRAME_GLYPHS_CHANGED (f);
}
}
return Qnil;