aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 06:27:51 -0500
committerEli Zaretskii2010-01-01 06:27:51 -0500
commitc143c213258b4dc980dab0629e571ff0c227fc34 (patch)
tree01977cfa7bda8a1b3e9cc260da29c7eda511ab84 /src
parentb44d9321f299626113e7b2e15371b20f7ad38892 (diff)
downloademacs-c143c213258b4dc980dab0629e571ff0c227fc34.tar.gz
emacs-c143c213258b4dc980dab0629e571ff0c227fc34.zip
Retrospective commit from 2009-10-08.
Finish up working on paragraph's base direction. Start working on display of right-to-left glyph rows. Rewrite set_cursor_from_row to support bidi. xdisp.c (string_buffer_position_lim): New function. (string_buffer_position): Most of code moved to string_buffer_position_lim. Last argument and return value are now EMACS_INT; all callers changed. (set_cursor_from_row): Rewritten to support bidirectional text and reversed glyph rows. dispextern.h <string_buffer_position>: Update prototype. bidi.c (bidi_paragraph_init): Fix initialization of POS. dispextern.h (struct glyph_row): New member reversed_p. buffer.c (syms_of_buffer): Remove DEFVAR_LISP_NOPRO for default-direction-reversed, default-bidi-display-reordering, and default-paragraph-direction.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog.bidi23
-rw-r--r--src/bidi.c5
-rw-r--r--src/buffer.c17
-rw-r--r--src/buffer.h6
-rw-r--r--src/dispextern.h7
-rw-r--r--src/xdisp.c503
6 files changed, 376 insertions, 185 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi
index db1d6c5bce0..cb44f665ad4 100644
--- a/src/ChangeLog.bidi
+++ b/src/ChangeLog.bidi
@@ -1,3 +1,26 @@
12009-10-08 Eli Zaretskii <eliz@gnu.org>
2
3 * xdisp.c (string_buffer_position_lim): New function.
4 (string_buffer_position): Most of code moved to
5 string_buffer_position_lim. Last argument and return value are
6 now EMACS_INT; all callers changed.
7 (set_cursor_from_row): Rewritten to support bidirectional text and
8 reversed glyph rows.
9
10 dispextern.h <string_buffer_position>: Update prototype.
11
122009-10-07 Eli Zaretskii <eliz@gnu.org>
13
14 * bidi.c (bidi_paragraph_init): Fix initialization of POS.
15
16 * dispextern.h (struct glyph_row): New member reversed_p.
17
182009-10-06 Eli Zaretskii <eliz@gnu.org>
19
20 * buffer.c (syms_of_buffer): Remove DEFVAR_LISP_NOPRO for
21 default-direction-reversed, default-bidi-display-reordering, and
22 default-paragraph-direction.
23
12009-10-05 Eli Zaretskii <eliz@gnu.org> 242009-10-05 Eli Zaretskii <eliz@gnu.org>
2 25
3 * buffer.h (struct buffer): New member paragraph_direction. 26 * buffer.h (struct buffer): New member paragraph_direction.
diff --git a/src/bidi.c b/src/bidi.c
index fc7e326cfb5..840eb6a81b6 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1,5 +1,5 @@
1/* Low-level bidirectional buffer-scanning functions for GNU Emacs. 1/* Low-level bidirectional buffer-scanning functions for GNU Emacs.
2 Copyright (C) 2000, 2001, 2004, 2005 Free Software Foundation, Inc. 2 Copyright (C) 2000, 2001, 2004, 2005, 2009 Free Software Foundation, Inc.
3 3
4This file is part of GNU Emacs. 4This file is part of GNU Emacs.
5 5
@@ -875,10 +875,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
875 875
876 /* If we are on a newline, get past it to where the next 876 /* If we are on a newline, get past it to where the next
877 paragraph might start. */ 877 paragraph might start. */
878 pos = bidi_it->charpos;
878 if (FETCH_CHAR (bytepos) == '\n') 879 if (FETCH_CHAR (bytepos) == '\n')
879 { 880 {
880 bytepos++; 881 bytepos++;
881 pos = bidi_it->charpos + 1; 882 pos++;
882 } 883 }
883 884
884 /* We are either at the beginning of a paragraph or in the 885 /* We are either at the beginning of a paragraph or in the
diff --git a/src/buffer.c b/src/buffer.c
index 8484abcdbb5..0d9247eb61b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5532,26 +5532,11 @@ This is the same as (default-value 'abbrev-mode). */);
5532 doc: /* Default value of `ctl-arrow' for buffers that do not override it. 5532 doc: /* Default value of `ctl-arrow' for buffers that do not override it.
5533This is the same as (default-value 'ctl-arrow). */); 5533This is the same as (default-value 'ctl-arrow). */);
5534 5534
5535 DEFVAR_LISP_NOPRO ("default-bidi-display-reordering",
5536 &buffer_defaults.bidi_display_reordering,
5537 doc: /* *Default value of `bidi-display-reordering' for buffers not overriding it.
5538This is the same as (default-value 'bidi-display-reordering). */);
5539
5540 DEFVAR_LISP_NOPRO ("default-direction-reversed",
5541 &buffer_defaults.direction_reversed,
5542 doc: /* Default value of `direction-reversed' for buffers that do not override it.
5543This is the same as (default-value 'direction-reversed). */);
5544
5545 DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters", 5535 DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
5546 &buffer_defaults.enable_multibyte_characters, 5536 &buffer_defaults.enable_multibyte_characters,
5547 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it. 5537 doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
5548This is the same as (default-value 'enable-multibyte-characters). */); 5538This is the same as (default-value 'enable-multibyte-characters). */);
5549 5539
5550 DEFVAR_LISP_NOPRO ("default-paragraph-direction",
5551 &buffer_defaults.paragraph_direction,
5552 doc: /* Default value of `paragraph-direction' for buffers that do not override it.
5553This is the same as (default-value 'paragraph-direction). */);
5554
5555 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system", 5540 DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
5556 &buffer_defaults.buffer_file_coding_system, 5541 &buffer_defaults.buffer_file_coding_system,
5557 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it. 5542 doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
@@ -5810,7 +5795,7 @@ See also the variable `bidi-display-reordering'. */);
5810 5795
5811 DEFVAR_PER_BUFFER ("bidi-display-reordering", 5796 DEFVAR_PER_BUFFER ("bidi-display-reordering",
5812 &current_buffer->bidi_display_reordering, Qnil, 5797 &current_buffer->bidi_display_reordering, Qnil,
5813 doc: /*Non-nil means reorder bidirectional text for display in the visual order. 5798 doc: /* Non-nil means reorder bidirectional text for display in the visual order.
5814See also the variable `direction-reversed'. */); 5799See also the variable `direction-reversed'. */);
5815 5800
5816 DEFVAR_PER_BUFFER ("paragraph-direction", 5801 DEFVAR_PER_BUFFER ("paragraph-direction",
diff --git a/src/buffer.h b/src/buffer.h
index 205bf865879..b3f131a46c1 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -664,9 +664,9 @@ struct buffer
664 /* Non-nil means set beginning of lines at the right edge of 664 /* Non-nil means set beginning of lines at the right edge of
665 windows. */ 665 windows. */
666 Lisp_Object direction_reversed; 666 Lisp_Object direction_reversed;
667 /* If non-nil, specifies which direction of text to force in each 667 /* If non-nil, specifies which direction of text to force in all the
668 paragraph. Nil means determine paragraph direction dynamically 668 paragraphs of the buffer. Nil means determine paragraph
669 for each paragraph. */ 669 direction dynamically for each paragraph. */
670 Lisp_Object paragraph_direction; 670 Lisp_Object paragraph_direction;
671 /* Non-nil means do selective display; 671 /* Non-nil means do selective display;
672 see doc string in syms_of_buffer (buffer.c) for details. */ 672 see doc string in syms_of_buffer (buffer.c) for details. */
diff --git a/src/dispextern.h b/src/dispextern.h
index d07b70df6cc..ae6ecbb0d5c 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -876,6 +876,10 @@ struct glyph_row
876 the bottom line of the window, but not end of the buffer. */ 876 the bottom line of the window, but not end of the buffer. */
877 unsigned indicate_bottom_line_p : 1; 877 unsigned indicate_bottom_line_p : 1;
878 878
879 /* Non-zero means the row was reversed to display text in a
880 right-to-left paragraph. */
881 unsigned reversed_p : 1;
882
879 /* Continuation lines width at the start of the row. */ 883 /* Continuation lines width at the start of the row. */
880 int continuation_lines_width; 884 int continuation_lines_width;
881 885
@@ -2811,7 +2815,8 @@ extern int bidi_mirror_char P_ ((int));
2811struct glyph_row *row_containing_pos P_ ((struct window *, int, 2815struct glyph_row *row_containing_pos P_ ((struct window *, int,
2812 struct glyph_row *, 2816 struct glyph_row *,
2813 struct glyph_row *, int)); 2817 struct glyph_row *, int));
2814int string_buffer_position P_ ((struct window *, Lisp_Object, int)); 2818EMACS_INT string_buffer_position P_ ((struct window *, Lisp_Object,
2819 EMACS_INT));
2815int line_bottom_y P_ ((struct it *)); 2820int line_bottom_y P_ ((struct it *));
2816int display_prop_intangible_p P_ ((Lisp_Object)); 2821int display_prop_intangible_p P_ ((Lisp_Object));
2817void resize_echo_area_exactly P_ ((void)); 2822void resize_echo_area_exactly P_ ((void));
diff --git a/src/xdisp.c b/src/xdisp.c
index e8eb21c4e5a..c9f93889b30 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4594,43 +4594,46 @@ display_prop_string_p (prop, string)
4594 return 0; 4594 return 0;
4595} 4595}
4596 4596
4597 4597/* Look for STRING in overlays and text properties in W's buffer,
4598/* Determine which buffer position in W's buffer STRING comes from. 4598 between character positions FROM and TO (excluding TO).
4599 AROUND_CHARPOS is an approximate position where it could come from. 4599 BACK_P non-zero means look back (in this case, TO is supposed to be
4600 Value is the buffer position or 0 if it couldn't be determined. 4600 less than FROM).
4601 Value is the first character position where STRING was found, or
4602 zero if it wasn't found before hitting TO.
4601 4603
4602 W's buffer must be current. 4604 W's buffer must be current.
4603 4605
4604 This function is necessary because we don't record buffer positions
4605 in glyphs generated from strings (to keep struct glyph small).
4606 This function may only use code that doesn't eval because it is 4606 This function may only use code that doesn't eval because it is
4607 called asynchronously from note_mouse_highlight. */ 4607 called asynchronously from note_mouse_highlight. */
4608 4608
4609int 4609static EMACS_INT
4610string_buffer_position (w, string, around_charpos) 4610string_buffer_position_lim (w, string, from, to, back_p)
4611 struct window *w; 4611 struct window *w;
4612 Lisp_Object string; 4612 Lisp_Object string;
4613 int around_charpos; 4613 EMACS_INT from, to;
4614 int back_p;
4614{ 4615{
4615 Lisp_Object limit, prop, pos; 4616 Lisp_Object limit, prop, pos;
4616 const int MAX_DISTANCE = 1000;
4617 int found = 0; 4617 int found = 0;
4618 4618
4619 pos = make_number (around_charpos); 4619 pos = make_number (from);
4620 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV)); 4620
4621 while (!found && !EQ (pos, limit)) 4621 if (!back_p) /* looking forward */
4622 { 4622 {
4623 prop = Fget_char_property (pos, Qdisplay, Qnil); 4623 limit = make_number (min (to, ZV));
4624 if (!NILP (prop) && display_prop_string_p (prop, string)) 4624 while (!found && !EQ (pos, limit))
4625 found = 1; 4625 {
4626 else 4626 prop = Fget_char_property (pos, Qdisplay, Qnil);
4627 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit); 4627 if (!NILP (prop) && display_prop_string_p (prop, string))
4628 found = 1;
4629 else
4630 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
4631 limit);
4632 }
4628 } 4633 }
4629 4634 else /* looking back */
4630 if (!found)
4631 { 4635 {
4632 pos = make_number (around_charpos); 4636 limit = make_number (max (to, BEGV));
4633 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4634 while (!found && !EQ (pos, limit)) 4637 while (!found && !EQ (pos, limit))
4635 { 4638 {
4636 prop = Fget_char_property (pos, Qdisplay, Qnil); 4639 prop = Fget_char_property (pos, Qdisplay, Qnil);
@@ -4645,6 +4648,35 @@ string_buffer_position (w, string, around_charpos)
4645 return found ? XINT (pos) : 0; 4648 return found ? XINT (pos) : 0;
4646} 4649}
4647 4650
4651/* Determine which buffer position in W's buffer STRING comes from.
4652 AROUND_CHARPOS is an approximate position where it could come from.
4653 Value is the buffer position or 0 if it couldn't be determined.
4654
4655 W's buffer must be current.
4656
4657 This function is necessary because we don't record buffer positions
4658 in glyphs generated from strings (to keep struct glyph small).
4659 This function may only use code that doesn't eval because it is
4660 called asynchronously from note_mouse_highlight. */
4661
4662EMACS_INT
4663string_buffer_position (w, string, around_charpos)
4664 struct window *w;
4665 Lisp_Object string;
4666 EMACS_INT around_charpos;
4667{
4668 Lisp_Object limit, prop, pos;
4669 const int MAX_DISTANCE = 1000;
4670 EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
4671 around_charpos + MAX_DISTANCE,
4672 0);
4673
4674 if (!found)
4675 found = string_buffer_position_lim (w, string, around_charpos,
4676 around_charpos - MAX_DISTANCE, 1);
4677 return found;
4678}
4679
4648 4680
4649 4681
4650/*********************************************************************** 4682/***********************************************************************
@@ -12405,160 +12437,299 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
12405 struct glyph *glyph = row->glyphs[TEXT_AREA]; 12437 struct glyph *glyph = row->glyphs[TEXT_AREA];
12406 struct glyph *end = glyph + row->used[TEXT_AREA]; 12438 struct glyph *end = glyph + row->used[TEXT_AREA];
12407 struct glyph *cursor = NULL; 12439 struct glyph *cursor = NULL;
12408 /* The first glyph that starts a sequence of glyphs from a string
12409 that is a value of a display property. */
12410 struct glyph *string_start;
12411 /* The X coordinate of string_start. */
12412 int string_start_x;
12413 /* The last known character position in row. */ 12440 /* The last known character position in row. */
12414 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta; 12441 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
12415 /* The last known character position before string_start. */
12416 int string_before_pos;
12417 int x = row->x; 12442 int x = row->x;
12418 int cursor_x = x; 12443 int cursor_x = x;
12419 /* Last buffer position covered by an overlay. */ 12444 EMACS_INT pt_old = PT - delta;
12420 int cursor_from_overlay_pos = 0; 12445 EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
12421 int pt_old = PT - delta; 12446 EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
12422 12447 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
12423 /* Skip over glyphs not having an object at the start of the row. 12448 /* Non-zero means we've found a match for cursor position, but that
12424 These are special glyphs like truncation marks on terminal 12449 glyph has the avoid_cursor_p flag set. */
12425 frames. */ 12450 int match_with_avoid_cursor = 0;
12451 /* Non-zero means we've seen at least one glyph that came from a
12452 display string. */
12453 int string_seen = 0;
12454
12455 /* Skip over glyphs not having an object at the start and the end of
12456 the row. These are special glyphs like truncation marks on
12457 terminal frames. */
12426 if (row->displays_text_p) 12458 if (row->displays_text_p)
12427 while (glyph < end 12459 {
12428 && INTEGERP (glyph->object) 12460 if (!row->reversed_p)
12429 && glyph->charpos < 0) 12461 {
12462 while (glyph < end
12463 && INTEGERP (glyph->object)
12464 && glyph->charpos < 0)
12465 {
12466 x += glyph->pixel_width;
12467 ++glyph;
12468 }
12469 while (end > glyph
12470 && INTEGERP ((end - 1)->object)
12471 && (end - 1)->charpos < 0)
12472 --end;
12473 glyph_before = glyph - 1;
12474 glyph_after = end;
12475 }
12476 else
12477 {
12478 struct glyph *g;
12479
12480 /* If the glyph row is reversed, we need to process it from back
12481 to front, so swap the edge pointers. */
12482 end = glyph - 1;
12483 glyph += row->used[TEXT_AREA] - 1;
12484 /* Reverse the known positions in the row. */
12485 last_pos = pos_after = MATRIX_ROW_START_CHARPOS (row) + delta;
12486 pos_before = MATRIX_ROW_END_CHARPOS (row) + delta;
12487
12488 while (glyph > end + 1
12489 && INTEGERP (glyph->object)
12490 && glyph->charpos < 0)
12491 {
12492 --glyph;
12493 x -= glyph->pixel_width;
12494 }
12495 if (INTEGERP (glyph->object) && glyph->charpos < 0)
12496 --glyph;
12497 /* By default, put the cursor on the rightmost glyph. */
12498 for (g = end + 1; g < glyph; g++)
12499 x += g->pixel_width;
12500 cursor_x = x;
12501 while (end < glyph
12502 && INTEGERP (end->object)
12503 && end->charpos < 0)
12504 ++end;
12505 glyph_before = glyph + 1;
12506 glyph_after = end;
12507 }
12508 }
12509
12510 /* Step 1: Try to find the glyph whose character position
12511 corresponds to point. If that's not possible, find 2 glyphs
12512 whose character positions are the closest to point, one before
12513 point, the other after it. */
12514 if (!row->reversed_p)
12515 while (/* not marched to end of glyph row */
12516 glyph < end
12517 /* glyph was not inserted by redisplay for internal purposes */
12518 && !INTEGERP (glyph->object))
12430 { 12519 {
12520 if (BUFFERP (glyph->object))
12521 {
12522 EMACS_INT dpos = glyph->charpos - pt_old;
12523
12524 if (!glyph->avoid_cursor_p)
12525 {
12526 /* If we hit point, we've found the glyph on which to
12527 display the cursor. */
12528 if (dpos == 0)
12529 {
12530 match_with_avoid_cursor = 0;
12531 break;
12532 }
12533 /* See if we've found a better approximation to
12534 POS_BEFORE or to POS_AFTER. Note that we want the
12535 first (leftmost) glyph of all those that are the
12536 closest from below, and the last (rightmost) of all
12537 those from above. */
12538 if (0 > dpos && dpos > pos_before - pt_old)
12539 {
12540 pos_before = glyph->charpos;
12541 glyph_before = glyph;
12542 }
12543 else if (0 < dpos && dpos <= pos_after - pt_old)
12544 {
12545 pos_after = glyph->charpos;
12546 glyph_after = glyph;
12547 }
12548 }
12549 else if (dpos == 0)
12550 match_with_avoid_cursor = 1;
12551 }
12552 else if (STRINGP (glyph->object))
12553 string_seen = 1;
12431 x += glyph->pixel_width; 12554 x += glyph->pixel_width;
12432 ++glyph; 12555 ++glyph;
12433 } 12556 }
12557 else if (glyph > end) /* row is reversed */
12558 while (!INTEGERP (glyph->object))
12559 {
12560 if (BUFFERP (glyph->object))
12561 {
12562 EMACS_INT dpos = glyph->charpos - pt_old;
12434 12563
12435 string_start = NULL; 12564 if (!glyph->avoid_cursor_p)
12436 while (glyph < end 12565 {
12437 && !INTEGERP (glyph->object) 12566 if (dpos == 0)
12438 && (!BUFFERP (glyph->object) 12567 {
12439 || (last_pos = glyph->charpos) != pt_old 12568 match_with_avoid_cursor = 0;
12440 || glyph->avoid_cursor_p)) 12569 break;
12570 }
12571 if (0 > dpos && dpos > pos_before - pt_old)
12572 {
12573 pos_before = glyph->charpos;
12574 glyph_before = glyph;
12575 }
12576 else if (0 < dpos && dpos <= pos_after - pt_old)
12577 {
12578 pos_after = glyph->charpos;
12579 glyph_after = glyph;
12580 }
12581 }
12582 else if (dpos == 0)
12583 match_with_avoid_cursor = 1;
12584 }
12585 else if (STRINGP (glyph->object))
12586 string_seen = 1;
12587 --glyph;
12588 if (glyph == end)
12589 break;
12590 x -= glyph->pixel_width;
12591 }
12592
12593 /* Step 2: If we didn't find an exact match for point, we need to
12594 look for a proper place to put the cursor among glyphs between
12595 GLYPH_BEFORE and GLYPH_AFTER. */
12596 if (glyph->charpos != pt_old)
12441 { 12597 {
12442 if (! STRINGP (glyph->object)) 12598 if (row->ends_in_ellipsis_p && pos_after == last_pos)
12443 { 12599 {
12444 string_start = NULL; 12600 EMACS_INT ellipsis_pos;
12445 x += glyph->pixel_width; 12601
12446 ++glyph; 12602 /* Scan back over the ellipsis glyphs. */
12447 /* If we are beyond the cursor position computed from the 12603 if (!row->reversed_p)
12448 last overlay seen, that overlay is not in effect for 12604 {
12449 current cursor position. Reset the cursor information 12605 ellipsis_pos = (glyph - 1)->charpos;
12450 computed from that overlay. */ 12606 while (glyph > row->glyphs[TEXT_AREA]
12451 if (cursor_from_overlay_pos 12607 && (glyph - 1)->charpos == ellipsis_pos)
12452 && last_pos >= cursor_from_overlay_pos) 12608 glyph--, x -= glyph->pixel_width;
12609 /* That loop always goes one position too far, including
12610 the glyph before the ellipsis. So scan forward over
12611 that one. */
12612 x += glyph->pixel_width;
12613 glyph++;
12614 }
12615 else /* row is reversed */
12453 { 12616 {
12454 cursor_from_overlay_pos = 0; 12617 ellipsis_pos = (glyph + 1)->charpos;
12455 cursor = NULL; 12618 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
12619 && (glyph + 1)->charpos == ellipsis_pos)
12620 glyph++, x += glyph->pixel_width;
12621 x -= glyph->pixel_width;
12622 glyph--;
12456 } 12623 }
12457 } 12624 }
12458 else 12625 else if (match_with_avoid_cursor)
12459 { 12626 {
12460 if (string_start == NULL) 12627 cursor = glyph_after;
12461 { 12628 x = -1;
12462 string_before_pos = last_pos; 12629 }
12463 string_start = glyph; 12630 else if (string_seen)
12464 string_start_x = x; 12631 {
12465 } 12632 int incr = row->reversed_p ? -1 : +1;
12466 /* Skip all glyphs from a string. */ 12633
12467 do 12634 /* Need to find the glyph that came out of a string which is
12635 present at point. That glyph is somewhere between
12636 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
12637 positioned between POS_BEFORE and POS_AFTER in the
12638 buffer. */
12639 struct glyph *stop = glyph_after;
12640 EMACS_INT pos = pos_before;
12641
12642 x = -1;
12643 for (glyph = glyph_before + incr;
12644 row->reversed_p ? glyph > stop : glyph < stop; )
12468 { 12645 {
12469 Lisp_Object cprop; 12646
12470 int pos; 12647 /* Any glyphs that come from the buffer are here because
12471 if ((cursor == NULL || glyph > cursor) 12648 of bidi reordering. Skip them, and only pay
12472 && (cprop = Fget_char_property (make_number ((glyph)->charpos), 12649 attention to glyphs that came from some string. */
12473 Qcursor, (glyph)->object), 12650 if (STRINGP (glyph->object))
12474 !NILP (cprop))
12475 && (pos = string_buffer_position (w, glyph->object,
12476 string_before_pos),
12477 (pos == 0 /* from overlay */
12478 || pos == pt_old)))
12479 { 12651 {
12480 /* Compute the first buffer position after the overlay. 12652 Lisp_Object str;
12481 If the `cursor' property tells us how many positions 12653 EMACS_INT tem;
12482 are associated with the overlay, use that. Otherwise, 12654
12483 estimate from the buffer positions of the glyphs 12655 str = glyph->object;
12484 before and after the overlay. */ 12656 tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
12485 cursor_from_overlay_pos = (pos ? 0 : last_pos 12657 if (pos <= tem)
12486 + (INTEGERP (cprop) ? XINT (cprop) : 0)); 12658 {
12487 cursor = glyph; 12659 /* If the string from which this glyph came is
12488 cursor_x = x; 12660 found in the buffer at point, then we've
12661 found the glyph we've been looking for. */
12662 if (tem == pt_old)
12663 {
12664 /* The glyphs from this string could have
12665 been reordered. Find the one with the
12666 smallest string position. Or there could
12667 be a character in the string with the
12668 `cursor' property, which means display
12669 cursor on that character's glyph. */
12670 int strpos = glyph->charpos;
12671
12672 cursor = glyph;
12673 for (glyph += incr;
12674 EQ (glyph->object, str);
12675 glyph += incr)
12676 {
12677 Lisp_Object cprop;
12678 int gpos = glyph->charpos;
12679
12680 cprop = Fget_char_property (make_number (gpos),
12681 Qcursor,
12682 glyph->object);
12683 if (!NILP (cprop))
12684 {
12685 cursor = glyph;
12686 break;
12687 }
12688 if (glyph->charpos < strpos)
12689 {
12690 strpos = glyph->charpos;
12691 cursor = glyph;
12692 }
12693 }
12694
12695 goto compute_x;
12696 }
12697 pos = tem + 1; /* don't find previous instances */
12698 }
12699 /* This string is not what we want; skip all of the
12700 glyphs that came from it. */
12701 do
12702 glyph += incr;
12703 while ((row->reversed_p ? glyph > stop : glyph < stop)
12704 && EQ (glyph->object, str));
12489 } 12705 }
12490 x += glyph->pixel_width; 12706 else
12491 ++glyph; 12707 glyph += incr;
12492 } 12708 }
12493 while (glyph < end && EQ (glyph->object, string_start->object)); 12709
12710 /* If we reached the end of the line, and END was from a string,
12711 the cursor is not on this line. */
12712 if (glyph == end
12713 && STRINGP ((glyph - incr)->object)
12714 && row->continued_p)
12715 return 0;
12494 } 12716 }
12495 } 12717 }
12496 12718
12719 compute_x:
12497 if (cursor != NULL) 12720 if (cursor != NULL)
12721 glyph = cursor;
12722 if (x < 0)
12498 { 12723 {
12499 glyph = cursor; 12724 struct glyph *g;
12500 x = cursor_x;
12501 }
12502 else if (row->ends_in_ellipsis_p && glyph == end)
12503 {
12504 /* Scan back over the ellipsis glyphs, decrementing positions. */
12505 while (glyph > row->glyphs[TEXT_AREA]
12506 && (glyph - 1)->charpos == last_pos)
12507 glyph--, x -= glyph->pixel_width;
12508 /* That loop always goes one position too far, including the
12509 glyph before the ellipsis. So scan forward over that one. */
12510 x += glyph->pixel_width;
12511 glyph++;
12512 }
12513 else if (string_start
12514 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
12515 {
12516 /* We may have skipped over point because the previous glyphs
12517 are from string. As there's no easy way to know the
12518 character position of the current glyph, find the correct
12519 glyph on point by scanning from string_start again. */
12520 Lisp_Object limit;
12521 Lisp_Object string;
12522 struct glyph *stop = glyph;
12523 int pos;
12524
12525 limit = make_number (pt_old + 1);
12526 glyph = string_start;
12527 x = string_start_x;
12528 string = glyph->object;
12529 pos = string_buffer_position (w, string, string_before_pos);
12530 /* If POS == 0, STRING is from overlay. We skip such glyphs
12531 because we always put the cursor after overlay strings. */
12532 while (pos == 0 && glyph < stop)
12533 {
12534 string = glyph->object;
12535 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12536 if (glyph < stop)
12537 pos = string_buffer_position (w, glyph->object, string_before_pos);
12538 }
12539 12725
12540 while (glyph < stop) 12726 /* Need to compute x that corresponds to GLYPH. */
12727 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
12541 { 12728 {
12542 pos = XINT (Fnext_single_char_property_change 12729 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
12543 (make_number (pos), Qdisplay, Qnil, limit)); 12730 abort ();
12544 if (pos > pt_old) 12731 x += g->pixel_width;
12545 break;
12546 /* Skip glyphs from the same string. */
12547 string = glyph->object;
12548 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12549 /* Skip glyphs from an overlay. */
12550 while (glyph < stop
12551 && ! string_buffer_position (w, glyph->object, pos))
12552 {
12553 string = glyph->object;
12554 SKIP_GLYPHS (glyph, stop, x, EQ (glyph->object, string));
12555 }
12556 } 12732 }
12557
12558 /* If we reached the end of the line, and END was from a string,
12559 the cursor is not on this line. */
12560 if (glyph == end && row->continued_p)
12561 return 0;
12562 } 12733 }
12563 12734
12564 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA]; 12735 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
@@ -16343,20 +16514,24 @@ extend_face_to_end_of_line (it)
16343 PRODUCE_GLYPHS (it); 16514 PRODUCE_GLYPHS (it);
16344 16515
16345 /* If the paragraph base direction is right to left, reverse the 16516 /* If the paragraph base direction is right to left, reverse the
16346 glyphs of non-empty line. */ 16517 glyphs of a non-empty glyph row. */
16347 if (it->bidi_p && it->bidi_it.level_stack[0].level == 1 16518 if (it->bidi_p && it->bidi_it.level_stack[0].level == 1)
16348 && text_len > 0)
16349 { 16519 {
16350 struct glyph *gleft = it->glyph_row->glyphs[TEXT_AREA]; 16520 if (text_len > 0)
16351 struct glyph *gright = gleft + it->glyph_row->used[TEXT_AREA] - 1;
16352 struct glyph tem;
16353
16354 for ( ; gleft < gright; gleft++, gright--)
16355 { 16521 {
16356 tem = *gleft; 16522 struct glyph *gleft = it->glyph_row->glyphs[TEXT_AREA];
16357 *gleft = *gright; 16523 struct glyph *gright =
16358 *gright = tem; 16524 gleft + it->glyph_row->used[TEXT_AREA] - 1;
16525 struct glyph tem;
16526
16527 for ( ; gleft < gright; gleft++, gright--)
16528 {
16529 tem = *gleft;
16530 *gleft = *gright;
16531 *gright = tem;
16532 }
16359 } 16533 }
16534 it->glyph_row->reversed_p = 1;
16360 } 16535 }
16361 16536
16362 /* Don't count these blanks really. It would let us insert a left 16537 /* Don't count these blanks really. It would let us insert a left
@@ -23181,7 +23356,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
23181 associated with the end position, which must not be 23356 associated with the end position, which must not be
23182 highlighted. */ 23357 highlighted. */
23183 Lisp_Object prev_object; 23358 Lisp_Object prev_object;
23184 int pos; 23359 EMACS_INT pos;
23185 23360
23186 while (glyph > row->glyphs[TEXT_AREA]) 23361 while (glyph > row->glyphs[TEXT_AREA])
23187 { 23362 {
@@ -23813,7 +23988,8 @@ note_mouse_highlight (f, x, y)
23813 && XFASTINT (w->last_modified) == BUF_MODIFF (b) 23988 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
23814 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) 23989 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
23815 { 23990 {
23816 int hpos, vpos, pos, i, dx, dy, area; 23991 int hpos, vpos, i, dx, dy, area;
23992 EMACS_INT pos;
23817 struct glyph *glyph; 23993 struct glyph *glyph;
23818 Lisp_Object object; 23994 Lisp_Object object;
23819 Lisp_Object mouse_face = Qnil, overlay = Qnil, position; 23995 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
@@ -24101,7 +24277,7 @@ note_mouse_highlight (f, x, y)
24101 struct glyph_row *r 24277 struct glyph_row *r
24102 = MATRIX_ROW (w->current_matrix, vpos); 24278 = MATRIX_ROW (w->current_matrix, vpos);
24103 int start = MATRIX_ROW_START_CHARPOS (r); 24279 int start = MATRIX_ROW_START_CHARPOS (r);
24104 int pos = string_buffer_position (w, object, start); 24280 EMACS_INT pos = string_buffer_position (w, object, start);
24105 if (pos > 0) 24281 if (pos > 0)
24106 { 24282 {
24107 help = Fget_char_property (make_number (pos), 24283 help = Fget_char_property (make_number (pos),
@@ -24156,7 +24332,8 @@ note_mouse_highlight (f, x, y)
24156 struct glyph_row *r 24332 struct glyph_row *r
24157 = MATRIX_ROW (w->current_matrix, vpos); 24333 = MATRIX_ROW (w->current_matrix, vpos);
24158 int start = MATRIX_ROW_START_CHARPOS (r); 24334 int start = MATRIX_ROW_START_CHARPOS (r);
24159 int pos = string_buffer_position (w, object, start); 24335 EMACS_INT pos = string_buffer_position (w, object,
24336 start);
24160 if (pos > 0) 24337 if (pos > 0)
24161 pointer = Fget_char_property (make_number (pos), 24338 pointer = Fget_char_property (make_number (pos),
24162 Qpointer, w->buffer); 24339 Qpointer, w->buffer);