aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2010-01-01 06:39:56 -0500
committerEli Zaretskii2010-01-01 06:39:56 -0500
commit5e65aec01a9bc5a147e492f11dd0115c98bedef4 (patch)
treee4e90662056e2320c9a6941a96b7caaf9227313a /src
parente5a2fec7b4a8c1435d74d50796259b3e4b895cd4 (diff)
downloademacs-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.bidi24
-rw-r--r--src/bidi.c13
-rw-r--r--src/dispextern.h7
-rw-r--r--src/term.c25
-rw-r--r--src/xdisp.c53
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 @@
12009-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
212009-10-16 Eli Zaretskii <eliz@gnu.org>
22
23 * bidi.c (bidi_paragraph_init): Handle empty buffers.
24
12009-10-10 Eli Zaretskii <eliz@gnu.org> 252009-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