changeset 95335:23247857c2d7

(draw_glyphs): If mouse-highlighting is on, attempt to draw overlap glyphs with appropriate highlighting.
author Chong Yidong <cyd@stupidchicken.com>
date Tue, 27 May 2008 03:11:39 +0000
parents efd8500fd7f0
children 2a530ec1e5f9
files src/xdisp.c
diffstat 1 files changed, 74 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Tue May 27 03:11:09 2008 +0000
+++ b/src/xdisp.c	Tue May 27 03:11:39 2008 +0000
@@ -19887,9 +19887,7 @@
   struct glyph_string *head, *tail;
   struct glyph_string *s;
   struct glyph_string *clip_head = NULL, *clip_tail = NULL;
-  int last_x, area_width;
-  int x_reached;
-  int i, j;
+  int i, j, x_reached, last_x, area_left = 0;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   DECLARE_HDC (hdc);
 
@@ -19906,16 +19904,15 @@
     {
       /* X is relative to the left edge of W, without scroll bars
 	 or fringes.  */
-      x += WINDOW_LEFT_EDGE_X (w);
+      area_left = WINDOW_LEFT_EDGE_X (w);
       last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
     }
   else
     {
-      int area_left = window_box_left (w, area);
-      x += area_left;
-      area_width = window_box_width (w, area);
-      last_x = area_left + area_width;
-    }
+      area_left = window_box_left (w, area);
+      last_x = area_left + window_box_width (w, area);
+    }
+  x += area_left;
 
   /* Build a doubly-linked list of glyph_string structures between
      head and tail from what we have to draw.  Note that the macro
@@ -19933,8 +19930,30 @@
      strings built above.  */
   if (head && !overlaps && row->contains_overlapping_glyphs_p)
     {
+      struct glyph_string *h, *t;
+      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+      int mouse_beg_col, mouse_end_col, check_mouse_face = 0;
       int dummy_x = 0;
-      struct glyph_string *h, *t;
+
+      /* If mouse highlighting is on, we may need to draw adjacent
+	 glyphs using mouse-face highlighting.  */
+      if (area == TEXT_AREA && row->mouse_face_p)
+	{
+	  struct glyph_row *mouse_beg_row, *mouse_end_row;
+
+	  mouse_beg_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
+	  mouse_end_row = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
+
+	  if (row >= mouse_beg_row && row <= mouse_end_row)
+	    {
+	      check_mouse_face = 1;
+	      mouse_beg_col = (row == mouse_beg_row)
+		? dpyinfo->mouse_face_beg_col : 0;
+	      mouse_end_col = (row == mouse_end_row)
+		? dpyinfo->mouse_face_end_col
+		: row->used[TEXT_AREA];
+	    }
+	}
 
       /* Compute overhangs for all glyph strings.  */
       if (FRAME_RIF (f)->compute_glyph_string_overhangs)
@@ -19949,10 +19968,24 @@
       i = left_overwritten (head);
       if (i >= 0)
 	{
+	  enum draw_glyphs_face overlap_hl;
+
+	  /* If this row contains mouse highlighting, attempt to draw
+	     the overlapped glyphs with the correct highlight.  This
+	     code fails if the overlap encompasses more than one glyph
+	     and mouse-highlight spans only some of these glyphs.
+	     However, making it work perfectly involves a lot more
+	     code, and I don't know if the pathological case occurs in
+	     practice, so we'll stick to this for now.  --- cyd  */
+	  if (check_mouse_face
+	      && mouse_beg_col < start && mouse_end_col > i)
+	    overlap_hl = DRAW_MOUSE_FACE;
+	  else
+	    overlap_hl = DRAW_NORMAL_TEXT;
+
 	  j = i;
 	  BUILD_GLYPH_STRINGS (j, start, h, t,
-			       DRAW_NORMAL_TEXT, dummy_x, last_x);
-	  start = i;
+			       overlap_hl, dummy_x, last_x);
 	  compute_overhangs_and_x (t, head->x, 1);
 	  prepend_glyph_string_lists (&head, &tail, h, t);
 	  clip_head = head;
@@ -19968,9 +20001,17 @@
       i = left_overwriting (head);
       if (i >= 0)
 	{
+	  enum draw_glyphs_face overlap_hl;
+
+	  if (check_mouse_face
+	      && mouse_beg_col < start && mouse_end_col > i)
+	    overlap_hl = DRAW_MOUSE_FACE;
+	  else
+	    overlap_hl = DRAW_NORMAL_TEXT;
+
 	  clip_head = head;
 	  BUILD_GLYPH_STRINGS (i, start, h, t,
-			       DRAW_NORMAL_TEXT, dummy_x, last_x);
+			       overlap_hl, dummy_x, last_x);
 	  for (s = h; s; s = s->next)
 	    s->background_filled_p = 1;
 	  compute_overhangs_and_x (t, head->x, 1);
@@ -19984,8 +20025,16 @@
       i = right_overwritten (tail);
       if (i >= 0)
 	{
+	  enum draw_glyphs_face overlap_hl;
+
+	  if (check_mouse_face
+	      && mouse_beg_col < i && mouse_end_col > end)
+	    overlap_hl = DRAW_MOUSE_FACE;
+	  else
+	    overlap_hl = DRAW_NORMAL_TEXT;
+
 	  BUILD_GLYPH_STRINGS (end, i, h, t,
-			       DRAW_NORMAL_TEXT, x, last_x);
+			       overlap_hl, x, last_x);
 	  compute_overhangs_and_x (h, tail->x + tail->width, 0);
 	  append_glyph_string_lists (&head, &tail, h, t);
 	  clip_tail = tail;
@@ -19999,10 +20048,17 @@
       i = right_overwriting (tail);
       if (i >= 0)
 	{
+	  enum draw_glyphs_face overlap_hl;
+	  if (check_mouse_face
+	      && mouse_beg_col < i && mouse_end_col > end)
+	    overlap_hl = DRAW_MOUSE_FACE;
+	  else
+	    overlap_hl = DRAW_NORMAL_TEXT;
+
 	  clip_tail = tail;
 	  i++;			/* We must include the Ith glyph.  */
 	  BUILD_GLYPH_STRINGS (end, i, h, t,
-			       DRAW_NORMAL_TEXT, x, last_x);
+			       overlap_hl, x, last_x);
 	  for (s = h; s; s = s->next)
 	    s->background_filled_p = 1;
 	  compute_overhangs_and_x (h, tail->x + tail->width, 0);
@@ -20030,10 +20086,8 @@
       int x0 = clip_head ? clip_head->x : (head ? head->x : x);
       int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
 		: (tail ? tail->x + tail->background_width : x));
-
-      int text_left = window_box_left (w, TEXT_AREA);
-      x0 -= text_left;
-      x1 -= text_left;
+      x0 -= area_left;
+      x1 -= area_left;
 
       notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
 				 row->y, MATRIX_ROW_BOTTOM_Y (row));
@@ -20044,7 +20098,7 @@
   if (row->full_width_p)
     x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
   else
-    x_reached -= window_box_left (w, area);
+    x_reached -= area_left;
 
   RELEASE_HDC (hdc, f);