From a971c0a724a6bcdb958143b747f94c151d40359d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 6 Nov 2010 15:45:37 +0200 Subject: [PATCH] Support R2L lines in tool-tip text. xfns.c (Fx_show_tip): If any of the tool-tip text lines is R2L, adjust width of tool-tip frame to the width of text, excluding the stretch glyph at the beginning of R2L glyph rows. w32fns.c (Fx_show_tip): Likewise. --- src/ChangeLog | 8 +++++ src/w32fns.c | 81 ++++++++++++++++++++++++++++++++++++++++++++------- src/xfns.c | 69 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 140 insertions(+), 18 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 142cfeb57d7..81e9eb8215e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2010-11-06 Eli Zaretskii + + * xfns.c (Fx_show_tip): If any of the tool-tip text lines is R2L, + adjust width of tool-tip frame to the width of text, excluding the + stretch glyph at the beginning of R2L glyph rows. + + * w32fns.c (Fx_show_tip): Likewise. + 2010-11-06 Jan Djärv * nsfont.m: Include termchar for new mouse-highlight. diff --git a/src/w32fns.c b/src/w32fns.c index 15dbb404737..5a4f1354993 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -5657,7 +5657,7 @@ Text larger than the specified size is clipped. */) int root_x, root_y; struct buffer *old_buffer; struct text_pos pos; - int i, width, height; + int i, width, height, seen_reversed_p; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int old_windows_or_buffers_changed = windows_or_buffers_changed; int count = SPECPDL_INDEX (); @@ -5787,7 +5787,7 @@ Text larger than the specified size is clipped. */) try_window (FRAME_ROOT_WINDOW (f), pos, 0); /* Compute width and height of the tooltip. */ - width = height = 0; + width = height = seen_reversed_p = 0; for (i = 0; i < w->desired_matrix->nrows; ++i) { struct glyph_row *row = &w->desired_matrix->rows[i]; @@ -5801,24 +5801,83 @@ Text larger than the specified size is clipped. */) /* Let the row go over the full width of the frame. */ row->full_width_p = 1; -#ifdef TODO /* Investigate why some fonts need more width than is - calculated for some tooltips. */ - /* There's a glyph at the end of rows that is use to place - the cursor there. Don't include the width of this glyph. */ + row_width = row->pixel_width; if (row->used[TEXT_AREA]) { - last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - row_width = row->pixel_width - last->pixel_width; - } - else + if (!row->reversed_p) + { +#ifdef TODO /* Investigate why some fonts need more width than is + calculated for some tooltips. */ + + /* There's a glyph at the end of rows that is used to + place the cursor there. Don't include the width of + this glyph. */ + last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; + if (INTEGERP (last->object)) + row_width -= last->pixel_width; #endif - row_width = row->pixel_width; + } + else + { + /* There could be a stretch glyph at the beginning of R2L + rows that is produced by extend_face_to_end_of_line. + Don't count that glyph. */ + struct glyph *g = row->glyphs[TEXT_AREA]; + + if (g->type == STRETCH_GLYPH && INTEGERP (g->object)) + { + row_width -= g->pixel_width; + seen_reversed_p = 1; + } + } + } /* TODO: find why tips do not draw along baseline as instructed. */ height += row->height; width = max (width, row_width); } + /* If we've seen partial-length R2L rows, we need to re-adjust the + tool-tip frame width and redisplay it again, to avoid over-wide + tips due to the stretch glyph that extends R2L lines to full + width of the frame. */ + if (seen_reversed_p) + { + /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, + not in pixels. */ + width /= WINDOW_FRAME_COLUMN_WIDTH (w); + w->total_cols = make_number (width); + FRAME_TOTAL_COLS (f) = width; + adjust_glyphs (f); + clear_glyph_matrix (w->desired_matrix); + clear_glyph_matrix (w->current_matrix); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); + width = height = 0; + /* Recompute width and height of the tooltip. */ + for (i = 0; i < w->desired_matrix->nrows; ++i) + { + struct glyph_row *row = &w->desired_matrix->rows[i]; + struct glyph *last; + int row_width; + + if (!row->enabled_p || !row->displays_text_p) + break; + row->full_width_p = 1; + row_width = row->pixel_width; +#ifdef TODO /* See above. */ + if (row->used[TEXT_AREA] && !row->reversed_p) + { + last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; + if (INTEGERP (last->object)) + row_width -= last->pixel_width; + } +#endif + + height += row->height; + width = max (width, row_width); + } + } + /* Add the frame's internal border to the width and height the X window should have. */ height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); diff --git a/src/xfns.c b/src/xfns.c index 6492bbd8a23..8ef9c92523e 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5017,7 +5017,7 @@ Text larger than the specified size is clipped. */) int root_x, root_y; struct buffer *old_buffer; struct text_pos pos; - int i, width, height; + int i, width, height, seen_reversed_p; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int old_windows_or_buffers_changed = windows_or_buffers_changed; int count = SPECPDL_INDEX (); @@ -5158,7 +5158,7 @@ Text larger than the specified size is clipped. */) try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE); /* Compute width and height of the tooltip. */ - width = height = 0; + width = height = seen_reversed_p = 0; for (i = 0; i < w->desired_matrix->nrows; ++i) { struct glyph_row *row = &w->desired_matrix->rows[i]; @@ -5173,19 +5173,74 @@ Text larger than the specified size is clipped. */) row->full_width_p = 1; row_width = row->pixel_width; - /* There's a glyph at the end of rows that is used to place - the cursor there. Don't include the width of this glyph. */ if (row->used[TEXT_AREA]) { - last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; - if (INTEGERP (last->object)) - row_width -= last->pixel_width; + /* There's a glyph at the end of rows that is used to place + the cursor there. Don't include the width of this glyph. */ + if (!row->reversed_p) + { + last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; + if (INTEGERP (last->object)) + row_width -= last->pixel_width; + } + else + { + /* There could be a stretch glyph at the beginning of R2L + rows that is produced by extend_face_to_end_of_line. + Don't count that glyph. */ + struct glyph *g = row->glyphs[TEXT_AREA]; + + if (g->type == STRETCH_GLYPH && INTEGERP (g->object)) + { + row_width -= g->pixel_width; + seen_reversed_p = 1; + } + } } height += row->height; width = max (width, row_width); } + /* If we've seen partial-length R2L rows, we need to re-adjust the + tool-tip frame width and redisplay it again, to avoid over-wide + tips due to the stretch glyph that extends R2L lines to full + width of the frame. */ + if (seen_reversed_p) + { + /* w->total_cols and FRAME_TOTAL_COLS want the width in columns, + not in pixels. */ + width /= WINDOW_FRAME_COLUMN_WIDTH (w); + w->total_cols = make_number (width); + FRAME_TOTAL_COLS (f) = width; + adjust_glyphs (f); + clear_glyph_matrix (w->desired_matrix); + clear_glyph_matrix (w->current_matrix); + try_window (FRAME_ROOT_WINDOW (f), pos, 0); + width = height = 0; + /* Recompute width and height of the tooltip. */ + for (i = 0; i < w->desired_matrix->nrows; ++i) + { + struct glyph_row *row = &w->desired_matrix->rows[i]; + struct glyph *last; + int row_width; + + if (!row->enabled_p || !row->displays_text_p) + break; + row->full_width_p = 1; + row_width = row->pixel_width; + if (row->used[TEXT_AREA] && !row->reversed_p) + { + last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1]; + if (INTEGERP (last->object)) + row_width -= last->pixel_width; + } + + height += row->height; + width = max (width, row_width); + } + } + /* Add the frame's internal border to the width and height the X window should have. */ height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f); -- 2.39.2