diff options
| author | Eli Zaretskii | 2010-01-01 06:27:51 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-01-01 06:27:51 -0500 |
| commit | c143c213258b4dc980dab0629e571ff0c227fc34 (patch) | |
| tree | 01977cfa7bda8a1b3e9cc260da29c7eda511ab84 /src | |
| parent | b44d9321f299626113e7b2e15371b20f7ad38892 (diff) | |
| download | emacs-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.bidi | 23 | ||||
| -rw-r--r-- | src/bidi.c | 5 | ||||
| -rw-r--r-- | src/buffer.c | 17 | ||||
| -rw-r--r-- | src/buffer.h | 6 | ||||
| -rw-r--r-- | src/dispextern.h | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 503 |
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 @@ | |||
| 1 | 2009-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 | |||
| 12 | 2009-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 | |||
| 18 | 2009-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 | |||
| 1 | 2009-10-05 Eli Zaretskii <eliz@gnu.org> | 24 | 2009-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 | ||
| 4 | This file is part of GNU Emacs. | 4 | This 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. |
| 5533 | This is the same as (default-value 'ctl-arrow). */); | 5533 | This 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. | ||
| 5538 | This 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. | ||
| 5543 | This 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. |
| 5548 | This is the same as (default-value 'enable-multibyte-characters). */); | 5538 | This 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. | ||
| 5553 | This 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 | ¤t_buffer->bidi_display_reordering, Qnil, | 5797 | ¤t_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. |
| 5814 | See also the variable `direction-reversed'. */); | 5799 | See 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)); | |||
| 2811 | struct glyph_row *row_containing_pos P_ ((struct window *, int, | 2815 | struct 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)); |
| 2814 | int string_buffer_position P_ ((struct window *, Lisp_Object, int)); | 2818 | EMACS_INT string_buffer_position P_ ((struct window *, Lisp_Object, |
| 2819 | EMACS_INT)); | ||
| 2815 | int line_bottom_y P_ ((struct it *)); | 2820 | int line_bottom_y P_ ((struct it *)); |
| 2816 | int display_prop_intangible_p P_ ((Lisp_Object)); | 2821 | int display_prop_intangible_p P_ ((Lisp_Object)); |
| 2817 | void resize_echo_area_exactly P_ ((void)); | 2822 | void 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 | ||
| 4609 | int | 4609 | static EMACS_INT |
| 4610 | string_buffer_position (w, string, around_charpos) | 4610 | string_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 | |||
| 4662 | EMACS_INT | ||
| 4663 | string_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); |