mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-02-02 20:16:25 +00:00
Initial implementation of display of R2L paragraphs in GUI sessions.
xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for append_stretch_glyph. (set_cursor_from_row) <cursor_x>: Remove unused variable. Fix off-by-one error in computing x at end of text in the row. (extend_face_to_end_of_line): If the row is reversed, prepend a stretch glyph whose width is such that the rightmost glyph will be drawn at the right margin of the window. (append_stretch_glyph): In reversed row, prepend the glyph rather than append it. Set resolved_level and bidi_type of the glyph.
This commit is contained in:
parent
9cbb0335ff
commit
2204f4de61
@ -1,3 +1,17 @@
|
||||
2010-04-10 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Implement display of R2L paragraphs in GUI sessions.
|
||||
|
||||
* xdisp.c [HAVE_WINDOW_SYSTEM]: Add prototype for
|
||||
append_stretch_glyph.
|
||||
(set_cursor_from_row) <cursor_x>: Remove unused variable. Fix
|
||||
off-by-one error in computing x at end of text in the row.
|
||||
(extend_face_to_end_of_line): If the row is reversed, prepend a
|
||||
stretch glyph whose width is such that the rightmost glyph will be
|
||||
drawn at the right margin of the window.
|
||||
(append_stretch_glyph): In reversed row, prepend the glyph rather
|
||||
than append it. Set resolved_level and bidi_type of the glyph.
|
||||
|
||||
2010-04-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* xdisp.c (set_cursor_from_row): Don't dereference glyphs beyond
|
||||
|
75
src/xdisp.c
75
src/xdisp.c
@ -999,6 +999,8 @@ static void display_tool_bar_line P_ ((struct it *, int));
|
||||
static void notice_overwritten_cursor P_ ((struct window *,
|
||||
enum glyph_row_area,
|
||||
int, int, int, int));
|
||||
static void append_stretch_glyph P_ ((struct it *, Lisp_Object,
|
||||
int, int, int));
|
||||
|
||||
|
||||
|
||||
@ -12548,7 +12550,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
|
||||
/* The last known character position in row. */
|
||||
int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
|
||||
int x = row->x;
|
||||
int cursor_x = x;
|
||||
EMACS_INT pt_old = PT - delta;
|
||||
EMACS_INT pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
|
||||
EMACS_INT pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
|
||||
@ -12616,7 +12617,6 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
|
||||
rightmost (first in the reading order) glyph. */
|
||||
for (g = end + 1; g < glyph; g++)
|
||||
x += g->pixel_width;
|
||||
cursor_x = x;
|
||||
while (end < glyph
|
||||
&& INTEGERP ((end + 1)->object)
|
||||
&& (end + 1)->charpos <= 0)
|
||||
@ -12631,7 +12631,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
|
||||
rightmost glyph. Case in point: an empty last line that is
|
||||
part of an R2L paragraph. */
|
||||
cursor = end - 1;
|
||||
x = -1; /* will be computed below, at lable compute_x */
|
||||
x = -1; /* will be computed below, at label compute_x */
|
||||
}
|
||||
|
||||
/* Step 1: Try to find the glyph whose character position
|
||||
@ -12767,7 +12767,7 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
|
||||
string_seen = 1;
|
||||
}
|
||||
--glyph;
|
||||
if (glyph == end)
|
||||
if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
|
||||
break;
|
||||
x -= glyph->pixel_width;
|
||||
}
|
||||
@ -16772,9 +16772,11 @@ append_space_for_newline (it, default_face_p)
|
||||
|
||||
|
||||
/* Extend the face of the last glyph in the text area of IT->glyph_row
|
||||
to the end of the display line. Called from display_line.
|
||||
If the glyph row is empty, add a space glyph to it so that we
|
||||
know the face to draw. Set the glyph row flag fill_line_p. */
|
||||
to the end of the display line. Called from display_line. If the
|
||||
glyph row is empty, add a space glyph to it so that we know the
|
||||
face to draw. Set the glyph row flag fill_line_p. If the glyph
|
||||
row is R2L, prepend a stretch glyph to cover the empty space to the
|
||||
left of the leftmost glyph. */
|
||||
|
||||
static void
|
||||
extend_face_to_end_of_line (it)
|
||||
@ -16791,7 +16793,7 @@ extend_face_to_end_of_line (it)
|
||||
to the end of the line. If the background equals the background
|
||||
of the frame, we don't have to do anything. */
|
||||
if (it->face_before_selective_p)
|
||||
face = FACE_FROM_ID (it->f, it->saved_face_id);
|
||||
face = FACE_FROM_ID (f, it->saved_face_id);
|
||||
else
|
||||
face = FACE_FROM_ID (f, it->face_id);
|
||||
|
||||
@ -16799,7 +16801,8 @@ extend_face_to_end_of_line (it)
|
||||
&& it->glyph_row->displays_text_p
|
||||
&& face->box == FACE_NO_BOX
|
||||
&& face->background == FRAME_BACKGROUND_PIXEL (f)
|
||||
&& !face->stipple)
|
||||
&& !face->stipple
|
||||
&& !it->glyph_row->reversed_p)
|
||||
return;
|
||||
|
||||
/* Set the glyph row flag indicating that the face of the last glyph
|
||||
@ -16826,6 +16829,44 @@ extend_face_to_end_of_line (it)
|
||||
it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
|
||||
it->glyph_row->used[TEXT_AREA] = 1;
|
||||
}
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (it->glyph_row->reversed_p)
|
||||
{
|
||||
/* Prepend a stretch glyph to the row, such that the
|
||||
rightmost glyph will be drawn flushed all the way to the
|
||||
right margin of the window. The stretch glyph that will
|
||||
occupy the empty space, if any, to the left of the
|
||||
glyphs. */
|
||||
struct font *font = face->font ? face->font : FRAME_FONT (f);
|
||||
struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
|
||||
struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
|
||||
struct glyph *g;
|
||||
int row_width, stretch_ascent, stretch_width;
|
||||
struct text_pos saved_pos;
|
||||
int saved_face_id, saved_avoid_cursor;
|
||||
|
||||
for (row_width = 0, g = row_start; g < row_end; g++)
|
||||
row_width += g->pixel_width;
|
||||
stretch_width = WINDOW_BOX_RIGHT_EDGE_X(it->w)
|
||||
- WINDOW_BOX_LEFT_EDGE_X(it->w)
|
||||
- WINDOW_TOTAL_FRINGE_WIDTH(it->w)
|
||||
- row_width;
|
||||
stretch_ascent =
|
||||
(((it->ascent + it->descent)
|
||||
* FONT_BASE (font)) / FONT_HEIGHT (font));
|
||||
saved_pos = it->position;
|
||||
saved_avoid_cursor = it->avoid_cursor_p;
|
||||
saved_face_id = it->face_id;
|
||||
bzero (&it->position, sizeof it->position);
|
||||
it->avoid_cursor_p = 1;
|
||||
it->face_id = face->id;
|
||||
append_stretch_glyph (it, make_number (0), stretch_width,
|
||||
it->ascent + it->descent, stretch_ascent);
|
||||
it->position = saved_pos;
|
||||
it->avoid_cursor_p = saved_avoid_cursor;
|
||||
it->face_id = saved_face_id;
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -21658,6 +21699,17 @@ append_stretch_glyph (it, object, width, height, ascent)
|
||||
glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
|
||||
if (glyph < it->glyph_row->glyphs[area + 1])
|
||||
{
|
||||
/* If the glyph row is reversed, we need to prepend the glyph
|
||||
rather than append it. */
|
||||
if (it->glyph_row->reversed_p && area == TEXT_AREA)
|
||||
{
|
||||
struct glyph *g;
|
||||
|
||||
/* Make room for the additional glyph. */
|
||||
for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
|
||||
g[1] = *g;
|
||||
glyph = it->glyph_row->glyphs[area];
|
||||
}
|
||||
glyph->charpos = CHARPOS (it->position);
|
||||
glyph->object = object;
|
||||
glyph->pixel_width = width;
|
||||
@ -21684,6 +21736,11 @@ append_stretch_glyph (it, object, width, height, ascent)
|
||||
abort ();
|
||||
glyph->bidi_type = it->bidi_it.type;
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->resolved_level = 0;
|
||||
glyph->bidi_type = UNKNOWN_BT;
|
||||
}
|
||||
++it->glyph_row->used[area];
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user