# HG changeset patch # User Eli Zaretskii # Date 1289051137 -7200 # Node ID 6316c70b291ec380e2358d1b484011d30bd473e1 # Parent 7a88e72dff578443714df998f0e59e44dcebdb3c 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. diff -r 7a88e72dff57 -r 6316c70b291e src/ChangeLog --- a/src/ChangeLog Sat Nov 06 13:08:58 2010 +0100 +++ b/src/ChangeLog Sat Nov 06 15:45:37 2010 +0200 @@ -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 -r 7a88e72dff57 -r 6316c70b291e src/w32fns.c --- a/src/w32fns.c Sat Nov 06 13:08:58 2010 +0100 +++ b/src/w32fns.c Sat Nov 06 15:45:37 2010 +0200 @@ -5657,7 +5657,7 @@ 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 @@ 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 @@ /* 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; + 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 + } + 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; + } + } } - else -#endif - row_width = row->pixel_width; /* 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 -r 7a88e72dff57 -r 6316c70b291e src/xfns.c --- a/src/xfns.c Sat Nov 06 13:08:58 2010 +0100 +++ b/src/xfns.c Sat Nov 06 15:45:37 2010 +0200 @@ -5017,7 +5017,7 @@ 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 @@ 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 @@ 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);