From: Eli Zaretskii Date: Fri, 20 Aug 2010 14:19:39 +0000 (+0300) Subject: Fix mouse clicks, drag, and highlight in R2L lines. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~438^2~45^2~511^2~27^2~2 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2396cbba625bc61b38be5b0be9d4c69e93de50f4;p=emacs.git Fix mouse clicks, drag, and highlight in R2L lines. dispnew.c (buffer_posn_from_coords): Fix calculation of buffer position for R2L lines by mirroring the pixel position wrt the text are box. Improve commentary. --- diff --git a/src/ChangeLog b/src/ChangeLog index c3f250aa519..d6b1c2347a2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2010-08-20 Eli Zaretskii + + * dispnew.c (buffer_posn_from_coords): Fix calculation of buffer + position for R2L lines by mirroring the pixel position wrt the + text are box. Improve commentary. + 2010-08-20 Andreas Schwab * image.c (imagemagick_clear_image): Remove debugging output. diff --git a/src/dispnew.c b/src/dispnew.c index 35893872c73..efcfd101782 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5351,9 +5351,15 @@ update_frame_line (struct frame *f, int vpos) ***********************************************************************/ /* Determine what's under window-relative pixel position (*X, *Y). - Return the object (string or buffer) that's there. + Return the OBJECT (string or buffer) that's there. Return in *POS the position in that object. - Adjust *X and *Y to character positions. */ + Adjust *X and *Y to character positions. + Return in *DX and *DY the pixel coordinates of the click, + relative to the top left corner of OBJECT, or relative to + the top left corner of the character glyph at (*X, *Y) + if OBJECT is nil. + Return WIDTH and HEIGHT of the object at (*X, *Y), or zero + if the coordinates point to an empty area of the display. */ Lisp_Object buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *pos, Lisp_Object *object, int *dx, int *dy, int *width, int *height) @@ -5366,7 +5372,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p #ifdef HAVE_WINDOW_SYSTEM struct image *img = 0; #endif - int x0, x1; + int x0, x1, to_x; /* We used to set current_buffer directly here, but that does the wrong thing with `face-remapping-alist' (bug#2044). */ @@ -5377,8 +5383,29 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p start_display (&it, w, startp); x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w); - move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1, - MOVE_TO_X | MOVE_TO_Y); + + /* First, move to the beginning of the row corresponding to *Y. We + need to be in that row to get the correct value of base paragraph + direction for the paragraph at *X. */ + move_it_to (&it, -1, 0, *y, -1, MOVE_TO_X | MOVE_TO_Y); + + /* TO_X is the pixel position that the iterator will compute for the + glyph at *X. This is because iterator positions are not offset + due to hscroll. */ + to_x = x0 + it.first_visible_x; + if (it.bidi_it.paragraph_dir == R2L) + /* For lines in an R2L paragraph, we need to mirror TO_X wrt the + text area. This is because the iterator, even in R2L + paragraphs, delivers glyphs as if they started at the left + margin of the window. (When we actually produce glyphs for + display, we reverse their order in PRODUCE_GLYPHS, but the + iterator doesn't know about that.) The following line adjusts + the pixel position to the iterator geometry, which is what + move_it_* routines use. */ + to_x = window_box_width (w, TEXT_AREA) - to_x; + + /* Now move horizontally in the row to the glyph under *X. */ + move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); Fset_buffer (old_current_buffer);