diff options
| author | Eli Zaretskii | 2010-01-01 06:39:56 -0500 |
|---|---|---|
| committer | Eli Zaretskii | 2010-01-01 06:39:56 -0500 |
| commit | 5e65aec01a9bc5a147e492f11dd0115c98bedef4 (patch) | |
| tree | e4e90662056e2320c9a6941a96b7caaf9227313a /src | |
| parent | e5a2fec7b4a8c1435d74d50796259b3e4b895cd4 (diff) | |
| download | emacs-5e65aec01a9bc5a147e492f11dd0115c98bedef4.tar.gz emacs-5e65aec01a9bc5a147e492f11dd0115c98bedef4.zip | |
Retrospective commit from 2009-10-17.
Continue working on display of R2L glyph rows. Reverse glyphs in
term.c:append_glyph rather than in extend_face_to_end_of_line.
Fix bidi iteration near BEGV and ZV.
dispextern.h (struct glyph): New members resolved_level and
bidi_type.
xdisp.c (append_glyph, append_composite_glyph)
(produce_image_glyph, append_stretch_glyph): Set them.
term.c (append_glyph): Ditto.
xdisp.c (display_line, next_element_from_buffer): Set the glyph
row's reversed_p flag if the paragraph base direction is odd.
(extend_face_to_end_of_line): Don't reverse the glyphs here.
term.c (append_glyph): Reverse glyphs here.
bidi.c (bidi_get_next_char_visually): Don't exit early when at ZV.
(bidi_paragraph_init): Don't step over a newline if at BEGV.
(bidi_paragraph_init): Handle empty buffers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog.bidi | 24 | ||||
| -rw-r--r-- | src/bidi.c | 13 | ||||
| -rw-r--r-- | src/dispextern.h | 7 | ||||
| -rw-r--r-- | src/term.c | 25 | ||||
| -rw-r--r-- | src/xdisp.c | 53 |
5 files changed, 96 insertions, 26 deletions
diff --git a/src/ChangeLog.bidi b/src/ChangeLog.bidi index ae5807ce13a..9824981c086 100644 --- a/src/ChangeLog.bidi +++ b/src/ChangeLog.bidi | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2009-10-17 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * dispextern.h (struct glyph): New members resolved_level and | ||
| 4 | bidi_type. | ||
| 5 | |||
| 6 | * xdisp.c (append_glyph, append_composite_glyph) | ||
| 7 | (produce_image_glyph, append_stretch_glyph): Set them. | ||
| 8 | |||
| 9 | * term.c (append_glyph): Ditto. | ||
| 10 | |||
| 11 | * xdisp.c (display_line, next_element_from_buffer): Set the glyph | ||
| 12 | row's reversed_p flag if the paragraph base direction is odd. | ||
| 13 | (extend_face_to_end_of_line): Don't reverse the glyphs here. | ||
| 14 | |||
| 15 | * term.c (append_glyph): Reverse glyphs here. | ||
| 16 | |||
| 17 | * bidi.c (bidi_get_next_char_visually): Don't exit early when at | ||
| 18 | ZV. | ||
| 19 | (bidi_paragraph_init): Don't step over a newline if at BEGV. | ||
| 20 | |||
| 21 | 2009-10-16 Eli Zaretskii <eliz@gnu.org> | ||
| 22 | |||
| 23 | * bidi.c (bidi_paragraph_init): Handle empty buffers. | ||
| 24 | |||
| 1 | 2009-10-10 Eli Zaretskii <eliz@gnu.org> | 25 | 2009-10-10 Eli Zaretskii <eliz@gnu.org> |
| 2 | 26 | ||
| 3 | * xdisp.c (set_cursor_from_row): Skip over glyphs near end of row | 27 | * xdisp.c (set_cursor_from_row): Skip over glyphs near end of row |
diff --git a/src/bidi.c b/src/bidi.c index f6ca8cd20e9..3a2d45cdb4d 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -853,8 +853,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 853 | { | 853 | { |
| 854 | EMACS_INT bytepos = bidi_it->bytepos; | 854 | EMACS_INT bytepos = bidi_it->bytepos; |
| 855 | 855 | ||
| 856 | /* Special case for an empty buffer. */ | ||
| 857 | if (bytepos == BEGV_BYTE && bytepos == ZV_BYTE) | ||
| 858 | dir = L2R; | ||
| 856 | /* We should never be called at EOB or before BEGV. */ | 859 | /* We should never be called at EOB or before BEGV. */ |
| 857 | if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) | 860 | else if (bytepos >= ZV_BYTE || bytepos < BEGV_BYTE) |
| 858 | abort (); | 861 | abort (); |
| 859 | 862 | ||
| 860 | if (dir == L2R) | 863 | if (dir == L2R) |
| @@ -883,9 +886,11 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it) | |||
| 883 | return; | 886 | return; |
| 884 | 887 | ||
| 885 | /* If we are on a newline, get past it to where the next | 888 | /* If we are on a newline, get past it to where the next |
| 886 | paragraph might start. */ | 889 | paragraph might start. But don't do that at BEGV since then |
| 890 | we are potentially in a new paragraph that doesn't yet | ||
| 891 | exist. */ | ||
| 887 | pos = bidi_it->charpos; | 892 | pos = bidi_it->charpos; |
| 888 | if (FETCH_CHAR (bytepos) == '\n') | 893 | if (bytepos > BEGV_BYTE && FETCH_CHAR (bytepos) == '\n') |
| 889 | { | 894 | { |
| 890 | bytepos++; | 895 | bytepos++; |
| 891 | pos++; | 896 | pos++; |
| @@ -1900,8 +1905,6 @@ bidi_get_next_char_visually (struct bidi_it *bidi_it) | |||
| 1900 | 1905 | ||
| 1901 | old_level = bidi_it->resolved_level; | 1906 | old_level = bidi_it->resolved_level; |
| 1902 | new_level = bidi_level_of_next_char (bidi_it); | 1907 | new_level = bidi_level_of_next_char (bidi_it); |
| 1903 | if (bidi_it->ch == BIDI_EOB) | ||
| 1904 | return; | ||
| 1905 | 1908 | ||
| 1906 | /* Reordering of resolved levels (clause L2) is implemented by | 1909 | /* Reordering of resolved levels (clause L2) is implemented by |
| 1907 | jumping to the other edge of the level and flipping direction of | 1910 | jumping to the other edge of the level and flipping direction of |
diff --git a/src/dispextern.h b/src/dispextern.h index ae6ecbb0d5c..5f18b7f3a4a 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -370,6 +370,13 @@ struct glyph | |||
| 370 | /* Non-zero means don't display cursor here. */ | 370 | /* Non-zero means don't display cursor here. */ |
| 371 | unsigned avoid_cursor_p : 1; | 371 | unsigned avoid_cursor_p : 1; |
| 372 | 372 | ||
| 373 | /* Resolved bidirection level of the characters [0..63]. */ | ||
| 374 | unsigned resolved_level : 6; | ||
| 375 | |||
| 376 | /* Resolved bidirectional type of this character, see enum | ||
| 377 | bidi_type_t below. */ | ||
| 378 | unsigned bidi_type : 5; | ||
| 379 | |||
| 373 | #define FACE_ID_BITS 20 | 380 | #define FACE_ID_BITS 20 |
| 374 | 381 | ||
| 375 | /* Face of the glyph. This is a realized face ID, | 382 | /* Face of the glyph. This is a realized face ID, |
diff --git a/src/term.c b/src/term.c index fda06d6b2ed..7c9e05f36b2 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -1545,6 +1545,26 @@ append_glyph (it) | |||
| 1545 | + it->glyph_row->used[it->area]); | 1545 | + it->glyph_row->used[it->area]); |
| 1546 | end = it->glyph_row->glyphs[1 + it->area]; | 1546 | end = it->glyph_row->glyphs[1 + it->area]; |
| 1547 | 1547 | ||
| 1548 | /* If the glyph row is reversed, we need to prepend the glyph rather | ||
| 1549 | than append it. */ | ||
| 1550 | if (it->glyph_row->reversed_p && it->area == TEXT_AREA) | ||
| 1551 | { | ||
| 1552 | struct glyph *g; | ||
| 1553 | int move_by = it->pixel_width; | ||
| 1554 | |||
| 1555 | /* Make room for the new glyphs. */ | ||
| 1556 | if (move_by > end - glyph) /* don't overstep end of this area */ | ||
| 1557 | move_by = end - glyph; | ||
| 1558 | for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) | ||
| 1559 | g[move_by] = *g; | ||
| 1560 | glyph = it->glyph_row->glyphs[it->area]; | ||
| 1561 | end = glyph + move_by; | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | /* BIDI Note: we put the glyphs of a "multi-pixel" character left to | ||
| 1565 | right, even in the REVERSED_P case, since (a) all of its u.ch are | ||
| 1566 | identical, and (b) the PADDING_P flag needs to be set for the | ||
| 1567 | leftmost one, because we write to the terminal left-to-right. */ | ||
| 1548 | for (i = 0; | 1568 | for (i = 0; |
| 1549 | i < it->pixel_width && glyph < end; | 1569 | i < it->pixel_width && glyph < end; |
| 1550 | ++i) | 1570 | ++i) |
| @@ -1556,6 +1576,11 @@ append_glyph (it) | |||
| 1556 | glyph->padding_p = i > 0; | 1576 | glyph->padding_p = i > 0; |
| 1557 | glyph->charpos = CHARPOS (it->position); | 1577 | glyph->charpos = CHARPOS (it->position); |
| 1558 | glyph->object = it->object; | 1578 | glyph->object = it->object; |
| 1579 | if (it->bidi_p) | ||
| 1580 | { | ||
| 1581 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 1582 | glyph->bidi_type = it->bidi_it.type; | ||
| 1583 | } | ||
| 1559 | 1584 | ||
| 1560 | ++it->glyph_row->used[it->area]; | 1585 | ++it->glyph_row->used[it->area]; |
| 1561 | ++glyph; | 1586 | ++glyph; |
diff --git a/src/xdisp.c b/src/xdisp.c index 581a7a0faa2..90f16b938c0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -6571,6 +6571,12 @@ next_element_from_buffer (it) | |||
| 6571 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') | 6571 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n') |
| 6572 | { | 6572 | { |
| 6573 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6573 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
| 6574 | /* If the paragraph base direction is R2L, its glyphs should | ||
| 6575 | be reversed. */ | ||
| 6576 | if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0) | ||
| 6577 | it->glyph_row->reversed_p = 1; | ||
| 6578 | if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0) | ||
| 6579 | it->glyph_row->reversed_p = 1; | ||
| 6574 | bidi_get_next_char_visually (&it->bidi_it); | 6580 | bidi_get_next_char_visually (&it->bidi_it); |
| 6575 | } | 6581 | } |
| 6576 | else | 6582 | else |
| @@ -6585,6 +6591,8 @@ next_element_from_buffer (it) | |||
| 6585 | it->bidi_it.charpos = IT_CHARPOS (*it); | 6591 | it->bidi_it.charpos = IT_CHARPOS (*it); |
| 6586 | it->bidi_it.bytepos = IT_BYTEPOS (*it); | 6592 | it->bidi_it.bytepos = IT_BYTEPOS (*it); |
| 6587 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); | 6593 | bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it); |
| 6594 | if (it->glyph_row && (it->bidi_it.level_stack[0].level & 1) != 0) | ||
| 6595 | it->glyph_row->reversed_p = 1; | ||
| 6588 | do { | 6596 | do { |
| 6589 | /* Now return to buffer position where we were asked to | 6597 | /* Now return to buffer position where we were asked to |
| 6590 | get the next display element, and produce that. */ | 6598 | get the next display element, and produce that. */ |
| @@ -16538,27 +16546,6 @@ extend_face_to_end_of_line (it) | |||
| 16538 | while (it->current_x <= it->last_visible_x) | 16546 | while (it->current_x <= it->last_visible_x) |
| 16539 | PRODUCE_GLYPHS (it); | 16547 | PRODUCE_GLYPHS (it); |
| 16540 | 16548 | ||
| 16541 | /* If the paragraph base direction is right to left, reverse the | ||
| 16542 | glyphs of a non-empty glyph row. */ | ||
| 16543 | if (it->bidi_p && it->bidi_it.level_stack[0].level == 1) | ||
| 16544 | { | ||
| 16545 | if (text_len > 0) | ||
| 16546 | { | ||
| 16547 | struct glyph *gleft = it->glyph_row->glyphs[TEXT_AREA]; | ||
| 16548 | struct glyph *gright = | ||
| 16549 | gleft + it->glyph_row->used[TEXT_AREA] - 1; | ||
| 16550 | struct glyph tem; | ||
| 16551 | |||
| 16552 | for ( ; gleft < gright; gleft++, gright--) | ||
| 16553 | { | ||
| 16554 | tem = *gleft; | ||
| 16555 | *gleft = *gright; | ||
| 16556 | *gright = tem; | ||
| 16557 | } | ||
| 16558 | } | ||
| 16559 | it->glyph_row->reversed_p = 1; | ||
| 16560 | } | ||
| 16561 | |||
| 16562 | /* Don't count these blanks really. It would let us insert a left | 16549 | /* Don't count these blanks really. It would let us insert a left |
| 16563 | truncation glyph below and make us set the cursor on them, maybe. */ | 16550 | truncation glyph below and make us set the cursor on them, maybe. */ |
| 16564 | it->current_x = saved_x; | 16551 | it->current_x = saved_x; |
| @@ -16850,6 +16837,10 @@ display_line (it) | |||
| 16850 | row->displays_text_p = 1; | 16837 | row->displays_text_p = 1; |
| 16851 | row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; | 16838 | row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; |
| 16852 | it->starts_in_middle_of_char_p = 0; | 16839 | it->starts_in_middle_of_char_p = 0; |
| 16840 | /* If the paragraph base direction is R2L, its glyphs should be | ||
| 16841 | reversed. */ | ||
| 16842 | if (it->bidi_p && (it->bidi_it.level_stack[0].level & 1) != 0) | ||
| 16843 | row->reversed_p = 1; | ||
| 16853 | 16844 | ||
| 16854 | /* Arrange the overlays nicely for our purposes. Usually, we call | 16845 | /* Arrange the overlays nicely for our purposes. Usually, we call |
| 16855 | display_line on only one line at a time, in which case this | 16846 | display_line on only one line at a time, in which case this |
| @@ -20932,6 +20923,11 @@ append_glyph (it) | |||
| 20932 | glyph->u.ch = it->char_to_display; | 20923 | glyph->u.ch = it->char_to_display; |
| 20933 | glyph->slice = null_glyph_slice; | 20924 | glyph->slice = null_glyph_slice; |
| 20934 | glyph->font_type = FONT_TYPE_UNKNOWN; | 20925 | glyph->font_type = FONT_TYPE_UNKNOWN; |
| 20926 | if (it->bidi_p) | ||
| 20927 | { | ||
| 20928 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 20929 | glyph->bidi_type = it->bidi_it.type; | ||
| 20930 | } | ||
| 20935 | ++it->glyph_row->used[area]; | 20931 | ++it->glyph_row->used[area]; |
| 20936 | } | 20932 | } |
| 20937 | else | 20933 | else |
| @@ -20984,6 +20980,11 @@ append_composite_glyph (it) | |||
| 20984 | glyph->face_id = it->face_id; | 20980 | glyph->face_id = it->face_id; |
| 20985 | glyph->slice = null_glyph_slice; | 20981 | glyph->slice = null_glyph_slice; |
| 20986 | glyph->font_type = FONT_TYPE_UNKNOWN; | 20982 | glyph->font_type = FONT_TYPE_UNKNOWN; |
| 20983 | if (it->bidi_p) | ||
| 20984 | { | ||
| 20985 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 20986 | glyph->bidi_type = it->bidi_it.type; | ||
| 20987 | } | ||
| 20987 | ++it->glyph_row->used[area]; | 20988 | ++it->glyph_row->used[area]; |
| 20988 | } | 20989 | } |
| 20989 | else | 20990 | else |
| @@ -21158,6 +21159,11 @@ produce_image_glyph (it) | |||
| 21158 | glyph->u.img_id = img->id; | 21159 | glyph->u.img_id = img->id; |
| 21159 | glyph->slice = slice; | 21160 | glyph->slice = slice; |
| 21160 | glyph->font_type = FONT_TYPE_UNKNOWN; | 21161 | glyph->font_type = FONT_TYPE_UNKNOWN; |
| 21162 | if (it->bidi_p) | ||
| 21163 | { | ||
| 21164 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 21165 | glyph->bidi_type = it->bidi_it.type; | ||
| 21166 | } | ||
| 21161 | ++it->glyph_row->used[area]; | 21167 | ++it->glyph_row->used[area]; |
| 21162 | } | 21168 | } |
| 21163 | else | 21169 | else |
| @@ -21204,6 +21210,11 @@ append_stretch_glyph (it, object, width, height, ascent) | |||
| 21204 | glyph->u.stretch.height = height; | 21210 | glyph->u.stretch.height = height; |
| 21205 | glyph->slice = null_glyph_slice; | 21211 | glyph->slice = null_glyph_slice; |
| 21206 | glyph->font_type = FONT_TYPE_UNKNOWN; | 21212 | glyph->font_type = FONT_TYPE_UNKNOWN; |
| 21213 | if (it->bidi_p) | ||
| 21214 | { | ||
| 21215 | glyph->resolved_level = it->bidi_it.resolved_level; | ||
| 21216 | glyph->bidi_type = it->bidi_it.type; | ||
| 21217 | } | ||
| 21207 | ++it->glyph_row->used[area]; | 21218 | ++it->glyph_row->used[area]; |
| 21208 | } | 21219 | } |
| 21209 | else | 21220 | else |