Subject: bug#12364: 24.2.50; wrong overhang display for gstring compositions

From: YAMAMOTO Mitsuharu <[email-masked]>
Date: Fri, 07 Sep 2012 17:47:23 +0900

>>>>> On Thu, 06 Sep 2012 11:37:26 +0900, YAMAMOTO Mitsuharu <[email-masked]> said:

> Steps to Reproduce:
> 1. $ emacs -Q &
> 2. evaluate (set-fontset-font t 'arabic (font-spec :family "arial" :size 30))
> 3. C-u C-\ arabic RET
> 4. u S u
>    At this moment, the two grapheme clusters look connected.
> 5. C-b C-p
>    Now the two grapheme clusters look unconnected.

> See also the "u-S-u" example in the first screenshot in
> http://lists.gnu.org/archive/html/bug-gnu-emacs/2012-09/msg00178.html .

> I think at least the two occurrences of the following line in xdisp.c
> are wrong.

>       int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);

> The value of s->cmp seems to be NULL for the "gstring" cases.

I tried making a fix.  The change for xterm.c is so the box cursor can
invert the left overhang of the succeeding glyph.  The attached
screenshots show the difference between with (first) and without
(second) the patch with respect to the following steps.

1. emacs -Q -D &
2. (set-frame-font "Times-32") C-j
3. C-u y
4. C-a C-SPC C-e M-o b
5. C-a C-SPC C-e M-o i
6. C-b C-b

				     YAMAMOTO Mitsuharu
				[email-masked]

=== modified file 'src/xdisp.c'
*** src/xdisp.c	2012-09-05 03:37:32 +0000
--- src/xdisp.c	2012-09-07 01:21:28 +0000
***************
*** 23050,23056 ****
      {
        int x = 0, i;
        struct glyph *glyphs = s->row->glyphs[s->area];
!       int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
        int end = s->row->used[s->area];
  
        for (i = first; i < end && s->right_overhang > x; ++i)
--- 23050,23057 ----
      {
        int x = 0, i;
        struct glyph *glyphs = s->row->glyphs[s->area];
!       int first = (s->first_glyph - glyphs
! 		   + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
        int end = s->row->used[s->area];
  
        for (i = first; i < end && s->right_overhang > x; ++i)
***************
*** 23073,23079 ****
    int i, k, x;
    int end = s->row->used[s->area];
    struct glyph *glyphs = s->row->glyphs[s->area];
!   int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
  
    k = -1;
    x = 0;
--- 23074,23081 ----
    int i, k, x;
    int end = s->row->used[s->area];
    struct glyph *glyphs = s->row->glyphs[s->area];
!   int first = (s->first_glyph - glyphs
! 	       + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
  
    k = -1;
    x = 0;

=== modified file 'src/xterm.c'
*** src/xterm.c	2012-09-07 01:27:44 +0000
--- src/xterm.c	2012-09-07 03:41:30 +0000
***************
*** 2975,2980 ****
--- 2975,2981 ----
  		XSetClipMask (next->display, next->gc, None);
  		next->hl = save;
  		next->num_clips = 0;
+ 		next->clip_head = s->next;
  	      }
  	}
      }