face_index findex, int cursor_start, int cursor_width,
int cursor_height)
{
- struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+ Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object window;
struct display_glyph_area sdga;
- dga->height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p);
- dga->width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p);
+ dga->height = IMAGE_INSTANCE_HEIGHT (p);
+ dga->width = IMAGE_INSTANCE_WIDTH (p);
+
+ /* The first thing we are going to do is update the display
+ characteristics of the subwindow. This also clears the dirty
+ flags as a side effect. */
+ update_subwindow (image_instance);
/* This makes the glyph area fit into the display area. */
if (!redisplay_normalize_glyph_area (db, dga))
cases.*/
sdga.xoffset = -dga->xoffset;
sdga.yoffset = -dga->yoffset;
- sdga.height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p);
- sdga.width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p);
+ sdga.height = IMAGE_INSTANCE_HEIGHT (p);
+ sdga.width = IMAGE_INSTANCE_WIDTH (p);
if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0)
{
redisplay_output_layout
Output a widget hierarchy. This can safely call itself recursively.
+
+ The complexity of outputting layouts is deciding whether to do it or
+ not. Consider a layout enclosing some text, the text changes and is
+ marked as dirty, but the enclosing layout has not been marked as
+ dirty so no updates occur and the text will potentially be truncated.
+ Alternatively we hold a back pointer in the image instance to the
+ parent and mark the parent as dirty. But the layout code assumes that
+ if the layout is dirty then the whole layout should be redisplayed,
+ so we then get lots of flashing even though only the text has changed
+ size. Of course if the text shrinks in size then we do actually need
+ to redisplay the layout to repaint the exposed area. So what happens
+ if we make a non-structural change like changing color? Either we
+ redisplay everything, or we redisplay nothing. These are exactly the
+ issues lwlib has to grapple with. We really need to know what has
+ actually changed and make a layout decision based on that. We also
+ really need to know what has changed so that we can only make the
+ neccessary changes in update_subwindow. This has all now been
+ implemented, Viva la revolution!
****************************************************************************/
void
redisplay_output_layout (struct window *w,
face_index findex, int cursor_start, int cursor_width,
int cursor_height)
{
- struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+ Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object window, rest;
Emchar_dynarr *buf = Dynarr_new (Emchar);
struct frame *f = XFRAME (w->frame);
int layout_height, layout_width;
/* We bogusly don't take f->extents_changed and f->glyphs_changed
into account. This is because if we do we always redisplay the
- entire layout. So far I have seen no ill effects to we'll see. */
+ entire layout. So far I have seen no ill effects so we'll see. */
int frame_really_changed = (f->buffers_changed ||
f->clip_changed ||
f->faces_changed ||
XSETWINDOW (window, w);
- layout_height = glyph_height (image_instance, Qnil, findex, window);
- layout_width = glyph_width (image_instance, Qnil, findex, window);
+ layout_height = glyph_height (image_instance, window);
+ layout_width = glyph_width (image_instance, window);
dga->height = layout_height;
dga->width = layout_width;
/* Highly dodgy optimization. We want to only output the whole
layout if we really have to. */
- if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (p))
+ if (frame_really_changed
+ || IMAGE_INSTANCE_LAYOUT_CHANGED (p)
+ || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
+ || IMAGE_INSTANCE_SIZE_CHANGED (p)
+ || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
{
/* First clear the area we are drawing into. This is the easiest
thing to do since we have many gaps that we have to make sure are
/* First determine if the image is visible at all */
if (IMAGE_INSTANCEP (child))
{
- struct Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child);
+ Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child);
/* The enclosing layout offsets are +ve at this point */
struct display_glyph_area cdga;
cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset;
cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset;
- cdga.width = glyph_width (child, Qnil, findex, window);
- cdga.height = glyph_height (child, Qnil, findex, window);
+ cdga.width = glyph_width (child, window);
+ cdga.height = glyph_height (child, window);
/* Although normalization is done by the output routines
we have to do it here so that they don't try and
xzero (dl);
/* Munge boxes into display lines. */
dl.ypos = (cdb.ypos - cdga.yoffset)
- + glyph_ascent (child, Qnil, findex, window);
- dl.ascent = glyph_ascent (child, Qnil, findex, window);
- dl.descent = glyph_descent (child, Qnil, findex, window);
+ + glyph_ascent (child, window);
+ dl.ascent = glyph_ascent (child, window);
+ dl.descent = glyph_descent (child, window);
dl.top_clip = cdga.yoffset;
dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height);
/* output_string doesn't understand offsets in
}
}
}
+
+ /* Update any display properties. I'm not sure whether this actually
+ does anything for layouts except clear the changed flags. */
+ update_subwindow (image_instance);
+
Dynarr_free (buf);
}
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
- struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+ Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object window;
XSETWINDOW (window, w);