diff options
| author | Eli Zaretskii | 2010-03-06 11:06:24 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-03-06 11:06:24 -0500 |
| commit | f866d742007347ca7a6002cea3be13bdf582c5e7 (patch) | |
| tree | eabf4a67784de1c5b9fc52b7bc3a5daba29a54cd /src | |
| parent | 9dbadf5f1a700c5790837738410c06b481cd2222 (diff) | |
| download | emacs-f866d742007347ca7a6002cea3be13bdf582c5e7.tar.gz emacs-f866d742007347ca7a6002cea3be13bdf582c5e7.zip | |
Continue debugging continuation lines.
.gdbinit (prowlims, pmtxrows): New commands.
xdisp.c (display_line): Special-case the calculation of row->end
in rows that end at ZV, to avoid abort in CHAR_TO_BYTE. Handle
empty lines correctly when calculating row's max and min pos.
Display cursor at the first glyph row that has its ends_at_zv_p
flag set.
Diffstat (limited to 'src')
| -rw-r--r-- | src/.gdbinit | 22 | ||||
| -rw-r--r-- | src/ChangeLog.bidi | 10 | ||||
| -rw-r--r-- | src/xdisp.c | 100 |
3 files changed, 100 insertions, 32 deletions
diff --git a/src/.gdbinit b/src/.gdbinit index 8949e66134c..659bc870710 100644 --- a/src/.gdbinit +++ b/src/.gdbinit | |||
| @@ -613,6 +613,28 @@ document pgrowit | |||
| 613 | Pretty print all glyphs in it->glyph_row. | 613 | Pretty print all glyphs in it->glyph_row. |
| 614 | end | 614 | end |
| 615 | 615 | ||
| 616 | define prowlims | ||
| 617 | printf "start=%d,end=%d,reversed=%d,cont=%d\n", $arg0->start.pos.charpos, $arg0->end.pos.charpos, $arg0->reversed_p, $arg0->continued_p | ||
| 618 | end | ||
| 619 | document prowlims | ||
| 620 | Print important attributes of a glyph_row structure. | ||
| 621 | Takes one argument, a pointer to a glyph_row structure. | ||
| 622 | end | ||
| 623 | |||
| 624 | define pmtxrows | ||
| 625 | set $mtx = $arg0 | ||
| 626 | set $gl = $mtx->rows | ||
| 627 | set $glend = $mtx->rows + $mtx->nrows | ||
| 628 | while ($gl < $glend) | ||
| 629 | prowlims $gl | ||
| 630 | set $gl = $gl + 1 | ||
| 631 | end | ||
| 632 | end | ||
| 633 | document pmtxrows | ||
| 634 | Print data about glyph rows in a glyph matrix. | ||
| 635 | Takes one argument, a pointer to a glyph_matrix structure. | ||
| 636 | end | ||
| 637 | |||
| 616 | define xtype | 638 | define xtype |
| 617 | xgettype $ | 639 | xgettype $ |
| 618 | output $type | 640 | output $type |
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index 234723bf6f7..7f7eb0808d2 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2010-03-06 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * .gdbinit (prowlims, pmtxrows): New commands. | ||
| 4 | |||
| 5 | * xdisp.c (display_line): Special-case the calculation of row->end | ||
| 6 | in rows that end at ZV, to avoid abort in CHAR_TO_BYTE. Handle | ||
| 7 | empty lines correctly when calculating row's max and min pos. | ||
| 8 | Display cursor at the first glyph row that has its ends_at_zv_p | ||
| 9 | flag set. | ||
| 10 | |||
| 1 | 2010-02-20 Eli Zaretskii <eliz@gnu.org> | 11 | 2010-02-20 Eli Zaretskii <eliz@gnu.org> |
| 2 | 12 | ||
| 3 | * xdisp.c (set_cursor_from_row): Compare candidate cursor | 13 | * xdisp.c (set_cursor_from_row): Compare candidate cursor |
diff --git a/src/xdisp.c b/src/xdisp.c index 056a009a7d9..e481809164d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -17604,19 +17604,18 @@ display_line (it) | |||
| 17604 | compute_line_metrics (it); | 17604 | compute_line_metrics (it); |
| 17605 | 17605 | ||
| 17606 | /* Remember the position at which this line ends. */ | 17606 | /* Remember the position at which this line ends. */ |
| 17607 | if (!it->bidi_p) | 17607 | row->end = row_end = it->current; |
| 17608 | row->end = row_end = it->current; | 17608 | if (it->bidi_p) |
| 17609 | else | ||
| 17610 | { | 17609 | { |
| 17611 | EMACS_INT min_pos = row->start.pos.charpos, max_pos = 0; | ||
| 17612 | struct glyph *g; | ||
| 17613 | struct it save_it; | ||
| 17614 | struct text_pos tpos; | ||
| 17615 | |||
| 17616 | /* ROW->start and ROW->end must be the smallest and largest | 17610 | /* ROW->start and ROW->end must be the smallest and largest |
| 17617 | buffer positions in ROW. But if ROW was bidi-reordered, | 17611 | buffer positions in ROW. But if ROW was bidi-reordered, |
| 17618 | these two positions can be anywhere in the row, so we must | 17612 | these two positions can be anywhere in the row, so we must |
| 17619 | rescan all of the ROW's glyphs to find them. */ | 17613 | rescan all of the ROW's glyphs to find them. */ |
| 17614 | EMACS_INT min_pos = ZV + 1, max_pos = 0; | ||
| 17615 | struct glyph *g; | ||
| 17616 | struct it save_it; | ||
| 17617 | struct text_pos tpos; | ||
| 17618 | |||
| 17620 | for (g = row->glyphs[TEXT_AREA]; | 17619 | for (g = row->glyphs[TEXT_AREA]; |
| 17621 | g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; | 17620 | g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; |
| 17622 | g++) | 17621 | g++) |
| @@ -17629,34 +17628,68 @@ display_line (it) | |||
| 17629 | max_pos = g->charpos; | 17628 | max_pos = g->charpos; |
| 17630 | } | 17629 | } |
| 17631 | } | 17630 | } |
| 17632 | if (min_pos < row->start.pos.charpos) | 17631 | /* Empty lines have a valid buffer position at their first |
| 17632 | glyph, but that glyph's OBJECT is zero, as if it didn't come | ||
| 17633 | from a buffer. If we didn't find any valid buffer positions | ||
| 17634 | in this row, maybe we have such an empty line. */ | ||
| 17635 | if (min_pos == ZV + 1 && row->used[TEXT_AREA]) | ||
| 17633 | { | 17636 | { |
| 17634 | row->start.pos.charpos = min_pos; | 17637 | for (g = row->glyphs[TEXT_AREA]; |
| 17635 | row->start.pos.bytepos = CHAR_TO_BYTE (min_pos); | 17638 | g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; |
| 17639 | g++) | ||
| 17640 | { | ||
| 17641 | if (INTEGERP (g->object)) | ||
| 17642 | { | ||
| 17643 | if (g->charpos && g->charpos < min_pos) | ||
| 17644 | min_pos = g->charpos; | ||
| 17645 | if (g->charpos > max_pos) | ||
| 17646 | max_pos = g->charpos; | ||
| 17647 | } | ||
| 17648 | } | ||
| 17649 | } | ||
| 17650 | if (min_pos <= ZV) | ||
| 17651 | { | ||
| 17652 | if (min_pos != row->start.pos.charpos) | ||
| 17653 | { | ||
| 17654 | row->start.pos.charpos = min_pos; | ||
| 17655 | row->start.pos.bytepos = CHAR_TO_BYTE (min_pos); | ||
| 17656 | } | ||
| 17657 | if (max_pos == 0) | ||
| 17658 | max_pos = min_pos; | ||
| 17636 | } | 17659 | } |
| 17637 | if (max_pos == 0) | ||
| 17638 | max_pos = min_pos; | ||
| 17639 | /* For ROW->end, we need the position that is _after_ max_pos, | 17660 | /* For ROW->end, we need the position that is _after_ max_pos, |
| 17640 | in the logical order. */ | 17661 | in the logical order, unless we are at ZV. */ |
| 17641 | SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1)); | 17662 | if (row->ends_at_zv_p) |
| 17642 | /* If the character at max_pos+1 is a newline, skip that as | 17663 | { |
| 17643 | well. Note that this may skip some invisible text. */ | 17664 | row_end = row->end = it->current; |
| 17644 | if (FETCH_CHAR (tpos.bytepos) == '\n' | 17665 | if (!row->used[TEXT_AREA]) |
| 17645 | || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective)) | 17666 | { |
| 17646 | { | 17667 | row->start.pos.charpos = row_end.pos.charpos; |
| 17647 | save_it = *it; | 17668 | row->start.pos.bytepos = row_end.pos.bytepos; |
| 17648 | it->bidi_p = 0; | 17669 | } |
| 17649 | reseat_1 (it, tpos, 0); | ||
| 17650 | set_iterator_to_next (it, 1); | ||
| 17651 | row_end = it->current; | ||
| 17652 | *it = save_it; | ||
| 17653 | } | 17670 | } |
| 17654 | else | 17671 | else if (row->used[TEXT_AREA] && max_pos) |
| 17655 | { | 17672 | { |
| 17656 | row_end = it->current; | 17673 | SET_TEXT_POS (tpos, max_pos + 1, CHAR_TO_BYTE (max_pos + 1)); |
| 17657 | row_end.pos = tpos; | 17674 | /* If the character at max_pos+1 is a newline, skip that as |
| 17675 | well. Note that this may skip some invisible text. */ | ||
| 17676 | if (FETCH_CHAR (tpos.bytepos) == '\n' | ||
| 17677 | || (FETCH_CHAR (tpos.bytepos) == '\r' && it->selective)) | ||
| 17678 | { | ||
| 17679 | save_it = *it; | ||
| 17680 | it->bidi_p = 0; | ||
| 17681 | reseat_1 (it, tpos, 0); | ||
| 17682 | set_iterator_to_next (it, 1); | ||
| 17683 | row_end = it->current; | ||
| 17684 | *it = save_it; | ||
| 17685 | } | ||
| 17686 | else | ||
| 17687 | { | ||
| 17688 | row_end = it->current; | ||
| 17689 | row_end.pos = tpos; | ||
| 17690 | } | ||
| 17691 | row->end = row_end; | ||
| 17658 | } | 17692 | } |
| 17659 | row->end = row_end; | ||
| 17660 | } | 17693 | } |
| 17661 | 17694 | ||
| 17662 | /* Record whether this row ends inside an ellipsis. */ | 17695 | /* Record whether this row ends inside an ellipsis. */ |
| @@ -17680,8 +17713,11 @@ display_line (it) | |||
| 17680 | /* In bidi-reordered rows, keep checking for proper cursor | 17713 | /* In bidi-reordered rows, keep checking for proper cursor |
| 17681 | position even if one has been found already, because buffer | 17714 | position even if one has been found already, because buffer |
| 17682 | positions in such rows change non-linearly with ROW->VPOS, | 17715 | positions in such rows change non-linearly with ROW->VPOS, |
| 17683 | when a line is continued. */ | 17716 | when a line is continued. One exception: when we are at ZV, |
| 17684 | || it->bidi_p) | 17717 | display cursor on the first suitable glyph row, since all |
| 17718 | the empty rows after that also have their ends_at_zv_p flag | ||
| 17719 | set. */ | ||
| 17720 | || (it->bidi_p && !row->ends_at_zv_p)) | ||
| 17685 | && PT >= MATRIX_ROW_START_CHARPOS (row) | 17721 | && PT >= MATRIX_ROW_START_CHARPOS (row) |
| 17686 | && PT <= MATRIX_ROW_END_CHARPOS (row) | 17722 | && PT <= MATRIX_ROW_END_CHARPOS (row) |
| 17687 | && cursor_row_p (it->w, row)) | 17723 | && cursor_row_p (it->w, row)) |