#include "glyphs.h"
#include "redisplay.h"
#include "faces.h"
+#include "gutter.h"
static int compare_runes (struct window *w, struct rune *crb,
struct rune *drb);
/*****************************************************************************
compare_runes
- Compare to runes to see if each of their fields is equal. If so,
+ Compare two runes to see if each of their fields is equal. If so,
return true otherwise return false.
****************************************************************************/
static int
else if (crb->type != drb->type)
return 0;
else if (crb->type == RUNE_CHAR &&
- (crb->object.chr.ch != drb->object.chr.ch))
+ !CHARC_EQ (crb->object.cglyph, drb->object.cglyph))
return 0;
else if (crb->type == RUNE_HLINE &&
(crb->object.hline.thickness != drb->object.hline.thickness ||
return 0;
/* Only check dirtiness if we know something has changed. */
else if (crb->type == RUNE_DGLYPH &&
- ((XFRAME (w->frame)->glyphs_changed &&
- XGLYPH_DIRTYP (crb->object.dglyph.glyph)) ||
+ (XGLYPH_DIRTYP (crb->object.dglyph.glyph) ||
crb->findex != drb->findex))
{
/* We need some way of telling redisplay_output_layout () that the
XSETWINDOW (window, w);
image = glyph_image_instance (crb->object.dglyph.glyph,
window, ERROR_ME_NOT, 1);
+
+ if (!IMAGE_INSTANCEP (image))
+ return 0;
ii = XIMAGE_INSTANCE (image);
- if (TEXT_IMAGE_INSTANCEP (image) &&
- (crb->findex != drb->findex ||
+ if (TEXT_IMAGE_INSTANCEP (image) &&
+ (crb->findex != drb->findex ||
WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)))
return 0;
- /* It is quite common of the two glyphs to be EQ since in many
+ /* It is quite common for the two glyphs to be EQ since in many
cases they will actually be the same object. This does not
mean, however, that nothing has changed. We therefore need to
check the current hash of the glyph against the last recorded
- display hash. See update_subwindow (). */
- if (IMAGE_INSTANCE_DISPLAY_HASH (ii) == 0 ||
- IMAGE_INSTANCE_DISPLAY_HASH (ii) !=
- internal_hash (image, IMAGE_INSTANCE_HASH_DEPTH) ||
- crb->findex != drb->findex ||
+ display hash and the pending display items. See
+ update_subwindow (). */
+ if (image_instance_changed (image) ||
+ crb->findex != drb->findex ||
WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))
{
/* We now now we are going to re-output the glyph, but since
changes, send a hint to the output routines that they can
take some short cuts. This is most useful for
layouts. This flag should get reset by the output
- routines.
+ routines.
#### It is possible for us to get here when the
face_cachel is dirty. I do not know what the implications
}
else
{
- DEVMETH (d, output_begin, (d));
-
- /* #### This is a gross kludge. Cursor handling is such a royal
- pain in the ass. */
- if (rb->type == RUNE_DGLYPH &&
- (EQ (rb->object.dglyph.glyph, Vtruncation_glyph) ||
- EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)))
- rb->cursor_type = NO_CURSOR;
- else
- rb->cursor_type = CURSOR_OFF;
+ {
+ MAYBE_DEVMETH (d, frame_output_begin, (f));
+ MAYBE_DEVMETH (d, window_output_begin, (w));
+ }
+ rb->cursor_type = CURSOR_OFF;
dl->cursor_elt = -1;
output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width);
}
if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d))))
{
if (!no_output_end)
- DEVMETH (d, output_end, (d));
+ {
+ MAYBE_DEVMETH (d, window_output_end, (w));
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
return 1;
}
output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width);
if (!no_output_end)
- DEVMETH (d, output_end, (d));
+ {
+ MAYBE_DEVMETH (d, window_output_end, (w));
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
return 1;
}
else
make_int (ADJ_BUFPOS), w->buffer);
if (!no_output_end)
- DEVMETH (d, output_end, (d));
+ {
+ MAYBE_DEVMETH (d, window_output_end, (w));
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
return 1;
}
}
if (!no_output_end)
- DEVMETH (d, output_end, (d));
+ {
+ MAYBE_DEVMETH (d, window_output_end, (w));
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
return 0;
}
#undef ADJ_BUFPOS
(f, dl->ypos - 1, rb->xpos));
if (run_end_begin_meths)
- DEVMETH (d, output_begin, (d));
+ {
+ MAYBE_DEVMETH (d, frame_output_begin, (f));
+ MAYBE_DEVMETH (d, window_output_begin, (w));
+ }
output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width);
if (run_end_begin_meths)
- DEVMETH (d, output_end, (d));
+ {
+ MAYBE_DEVMETH (d, window_output_end, (w));
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
}
}
Remove subwindows from the area in the box defined by the given
parameters.
****************************************************************************/
-static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height,
- Lisp_Object ignored_window)
+static void
+redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height,
+ Lisp_Object ignored_window)
{
- int elt;
+ Lisp_Object rest;
- for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+ LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
{
- struct subwindow_cachel *cachel =
- Dynarr_atp (f->subwindow_cachels, elt);
-
- if (cachel->being_displayed
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
+ if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
+ &&
+ IMAGE_INSTANCE_DISPLAY_X (ii)
+ + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) > x
+ &&
+ IMAGE_INSTANCE_DISPLAY_X (ii) < x + width
&&
- cachel->x + cachel->width > x && cachel->x < x + width
+ IMAGE_INSTANCE_DISPLAY_Y (ii)
+ + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) > y
&&
- cachel->y + cachel->height > y && cachel->y < y + height
+ IMAGE_INSTANCE_DISPLAY_Y (ii) < y + height
&&
- !EQ (cachel->subwindow, ignored_window))
+ !EQ (XCAR (rest), ignored_window))
{
- unmap_subwindow (cachel->subwindow);
+ unmap_subwindow (XCAR (rest));
}
}
}
****************************************************************************/
void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height)
{
- if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
+ if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))))
{
redisplay_unmap_subwindows (f, x, y, width, height, Qnil);
}
static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width,
int height, Lisp_Object subwindow)
{
- if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
+ if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))))
{
redisplay_unmap_subwindows (f, x, y, width, height, subwindow);
}
/* 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);
+ redisplay_subwindow (image_instance);
/* This makes the glyph area fit into the display area. */
if (!redisplay_normalize_glyph_area (db, dga))
sdga.height = IMAGE_INSTANCE_HEIGHT (p);
sdga.width = IMAGE_INSTANCE_WIDTH (p);
- if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0)
+ if (redisplay_display_boxes_in_window_p (w, db, &sdga) == 0
+ ||
+ /* We only want to do full subwindow display for windows that
+ are completely in the gutter, otherwise we must clip to be
+ safe. */
+ display_boxes_in_gutter_p (XFRAME (w->frame), db, &sdga) <= 0)
{
map_subwindow (image_instance, db->xpos, db->ypos, dga);
}
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
+ necessary changes in update_subwindow. This has all now been
implemented, Viva la revolution!
****************************************************************************/
void
-redisplay_output_layout (struct window *w,
+redisplay_output_layout (Lisp_Object domain,
Lisp_Object image_instance,
struct display_box* db, struct display_glyph_area* dga,
face_index findex, int cursor_start, int cursor_width,
int cursor_height)
{
Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
- Lisp_Object window, rest;
- Emchar_dynarr *buf = Dynarr_new (Emchar);
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
+ Lisp_Object rest, window = DOMAIN_WINDOW (domain);
+ Charc_dynarr *buf = Dynarr_new (Charc);
+ struct window *w = XWINDOW (window);
+ struct device *d = DOMAIN_XDEVICE (domain);
int layout_height, layout_width;
- XSETWINDOW (window, w);
-
- layout_height = glyph_height (image_instance, window);
- layout_width = glyph_width (image_instance, window);
+ layout_height = glyph_height (image_instance, domain);
+ layout_width = glyph_width (image_instance, domain);
dga->height = layout_height;
dga->width = layout_width;
-
+#ifdef DEBUG_WIDGET_OUTPUT
+ printf ("outputing layout glyph %p\n", p);
+#endif
/* This makes the glyph area fit into the display area. */
if (!redisplay_normalize_glyph_area (db, dga))
return;
/* Flip through the widgets in the layout displaying as necessary */
LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p))
{
- Lisp_Object child = XCAR (rest);
+ Lisp_Object child = glyph_image_instance (XCAR (rest), image_instance,
+ ERROR_ME_NOT, 1);
struct display_box cdb;
/* For losing HP-UX */
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, window);
- cdga.height = glyph_height (child, window);
+ cdga.width = glyph_width (child, image_instance);
+ cdga.height = glyph_height (child, image_instance);
- IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) =
+ IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) =
IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p);
/* Although normalization is done by the output routines
continue;
/* We have to invert the offset here as normalization
will have made them positive which the output
- routines will treat as a truely +ve offset. */
+ routines will treat as a truly +ve offset. */
cdga.xoffset = -cdga.xoffset;
cdga.yoffset = -cdga.yoffset;
struct display_line dl; /* this is fake */
Lisp_Object string =
IMAGE_INSTANCE_TEXT_STRING (childii);
- convert_bufbyte_string_into_emchar_dynarr
- (XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
+ Charset_ID charsets[NUM_LEADING_BYTES];
+ struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
+
+ find_charsets_in_bufbyte_string (charsets,
+ XSTRING_DATA (string),
+ XSTRING_LENGTH (string));
+ ensure_face_cachel_complete (cachel, window, charsets);
+
+ convert_bufbyte_string_into_charc_dynarr
+ (XSTRING_DATA (string), XSTRING_LENGTH (string),
+ buf);
redisplay_normalize_display_box (&cdb, &cdga);
/* Offsets are now +ve again so be careful
xzero (dl);
/* Munge boxes into display lines. */
dl.ypos = (cdb.ypos - cdga.yoffset)
- + glyph_ascent (child, window);
- dl.ascent = glyph_ascent (child, window);
- dl.descent = glyph_descent (child, window);
+ + glyph_ascent (child, image_instance);
+ dl.ascent = glyph_ascent (child, image_instance);
+ dl.descent = glyph_descent (child, image_instance);
dl.top_clip = cdga.yoffset;
dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height);
/* output_string doesn't understand offsets in
break;
case IMAGE_WIDGET:
+ if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (childii), Qlayout))
+ {
+ redisplay_output_layout (image_instance, child, &cdb, &cdga, findex,
+ 0, 0, 0);
+ break;
+ }
case IMAGE_SUBWINDOW:
if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) ||
IMAGE_INSTANCE_DIRTYP (childii))
0, 0, 0);
break;
- case IMAGE_LAYOUT:
- redisplay_output_layout (w, child, &cdb, &cdga, findex,
- 0, 0, 0);
- break;
-
case IMAGE_NOTHING:
/* nothing is as nothing does */
break;
IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0;
}
}
-
+
/* Update any display properties. I'm not sure whether this actually
does anything for layouts except clear the changed flags. */
- update_subwindow (image_instance);
+ redisplay_subwindow (image_instance);
Dynarr_free (buf);
}
{
redisplay_clear_clipped_region (window, findex,
db, dga,
- (int)IMAGE_INSTANCE_PIXMAP_MASK (p),
+ (IMAGE_INSTANCE_PIXMAP_MASK (p) != 0),
Qnil);
/* This shrinks the display box to exactly enclose the glyph
redisplay_clear_clipped_region
Clear the area in the dest display_box not covered by the src
- display_glyph_area using the given face. This is a common occurance
+ display_glyph_area using the given face. This is a common occurrence
for images shorter than the display line. Clipping can be played
around with by altering these. glyphsrc should be normalized.
****************************************************************************/
||
-glyphsrc->xoffset >= glyphsrc->width
||
- -glyphsrc->yoffset >= glyphsrc->height)
+ -glyphsrc->yoffset >= glyphsrc->height
+ ||
+ /* #### Not sure why this wasn't coped with before but normalizing
+ to zero width or height is definitely wrong. */
+ (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width
+ &&
+ dest->width - glyphsrc->xoffset <= 0)
+ ||
+ (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height
+ &&
+ dest->height - glyphsrc->yoffset <= 0))
{
/* It's all clipped out */
return 0;
/*****************************************************************************
redisplay_display_boxes_in_window_p
- Determine whether the require display_glyph_area is completely inside
- the window. 0 means the display_box is not in the window. 1 means the
- display_box and the display_glyph_area are in the window. -1 means
+ Determine whether the required display_glyph_area is completely inside
+ the window. -1 means the display_box is not in the window. 1 means the
+ display_box and the display_glyph_area are in the window. 0 means
the display_box is in the window but the display_glyph_area is not.
****************************************************************************/
static int
if (db->xpos < left || db->ypos < top
|| db->xpos + db->width > right
|| db->ypos + db->height > bottom)
- /* We are not displaying in a window at all */
- return 0;
+ /* We are not displaying in a window at all */
+ return -1;
if (db->xpos + dga->xoffset >= left
&&
db->ypos + dga->yoffset + dga->height <= bottom)
return 1;
- return -1;
+ return 0;
}
/*****************************************************************************
If window is topmost, clear the internal border above it.
****************************************************************************/
-static void
+void
redisplay_clear_top_of_window (struct window *w)
{
Lisp_Object window;
display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
- DEVMETH (d, output_begin, (d));
+ MAYBE_DEVMETH (d, window_output_begin, (w));
while (first_line <= last_line)
{
}
#endif
- /* This has to be done after we've updated the values. We don't
- call output_end for tty frames. Redisplay will do this after all
- tty windows have been updated. This cuts down on cursor
- flicker. */
- if (FRAME_TTY_P (f))
- redisplay_redraw_cursor (f, 0);
- else
- DEVMETH (d, output_end, (d));
+ redisplay_redraw_cursor (f, 0);
+ MAYBE_DEVMETH (d, window_output_end, (w));
}
/*****************************************************************************
}
/* Perform any output initialization. */
- DEVMETH (d, output_begin, (d));
+ MAYBE_DEVMETH (d, window_output_begin, (w));
/* If the window's structure has changed clear the internal border
above it if it is topmost (the function will check). */
- if (f->windows_structure_changed)
+ if (f->windows_structure_changed || f->faces_changed)
redisplay_clear_top_of_window (w);
/* Output each line. */
if (window_needs_vertical_divider (w)
&& (f->windows_structure_changed || f->clear))
{
- DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed));
+ MAYBE_DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed));
}
/* Clear the rest of the window, if necessary. */
get invalidated when it should be. */
INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d);
- /* We don't call output_end for tty frames. Redisplay will do this
- after all tty windows have been updated. This cuts down on
- cursor flicker. */
- if (FRAME_TTY_P (f))
- redisplay_redraw_cursor (f, 0);
- else
- DEVMETH (d, output_end, (d));
+ redisplay_redraw_cursor (f, 0);
+ MAYBE_DEVMETH (d, window_output_end, (w));
#ifdef HAVE_SCROLLBARS
update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0);