Commit 5ab80286 authored by Eli Zaretskii's avatar Eli Zaretskii

Fix display of composed text with :box face attribute

* src/xdisp.c (get_next_display_element): For a composition on a
display or overlay string, set the end_of_box_run_p flag if the
string ends at the last character included in the composition.
(fill_gstring_glyph_string): Fix the way the width of a gstring
glyph string is calculated: use the values calculated in
gui_produce_glyphs, since the latter adjusts the width due to the
face's ':box' attribute.
* src/xterm.c (x_draw_glyph_string_box):
* src/w32term.c (w32_draw_glyph_string_box):
* src/nsterm.m (ns_dumpglyphs_box_or_relief): Support automatic
compositions, which have the right_box_line_p flag set on the last
glyph produced from the composition.  (Bug#40687)

* src/w32term.c (w32_compute_glyph_string_overhangs): Update to be
consistent with xterm.c in its support of automatic composition
glyph strings.
* src/dispextern.h (enum glyph_type): More accurate commentary.
* src/.gdbinit (pgx): Display slice.img members only for image
glyphs.
parent 7b15cc3e
Pipeline #5345 failed with stage
in 59 minutes and 32 seconds
......@@ -500,6 +500,9 @@ define pgx
# IMAGE_GLYPH
if ($g.type == 3)
printf "IMAGE[%d]", $g.u.img_id
if ($g.slice.img.x || $g.slice.img.y || $g.slice.img.width || $g.slice.img.height)
printf " slice=%d,%d,%d,%d" ,$g.slice.img.x, $g.slice.img.y, $g.slice.img.width, $g.slice.img.height
end
end
# STRETCH_GLYPH
if ($g.type == 4)
......@@ -551,9 +554,6 @@ define pgx
if ($g.right_box_line_p)
printf " ]"
end
if ($g.slice.img.x || $g.slice.img.y || $g.slice.img.width || $g.slice.img.height)
printf " slice=%d,%d,%d,%d" ,$g.slice.img.x, $g.slice.img.y, $g.slice.img.width, $g.slice.img.height
end
printf "\n"
end
document pgx
......
......@@ -369,7 +369,7 @@ enum glyph_type
/* Glyph describes a character. */
CHAR_GLYPH,
/* Glyph describes a static composition. */
/* Glyph describes a static or automatic composition. */
COMPOSITE_GLYPH,
/* Glyph describes a glyphless character. */
......
......@@ -3872,8 +3872,21 @@ Function modeled after x_draw_glyph_string_box ().
last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
? WINDOW_RIGHT_EDGE_X (s->w)
: window_box_right (s->w, s->area));
last_glyph = (s->cmp || s->img
? s->first_glyph : s->first_glyph + s->nchars-1);
if (s->cmp || s->img)
last_glyph = s->first_glyph;
else if (s->first_glyph->type == COMPOSITE_GLYPH
&& s->first_glyph->u.cmp.automatic)
{
struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
struct glyph *g = s->first_glyph;
for (last_glyph = g++;
g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
&& g->slice.cmp.to < s->cmp_to;
last_glyph = g++)
;
}
else
last_glyph = s->first_glyph + s->nchars - 1;
right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
? last_x - 1 : min (last_x, s->x + s->background_width) - 1));
......
......@@ -1101,19 +1101,28 @@ w32_set_glyph_string_clipping_exactly (struct glyph_string *src,
static void
w32_compute_glyph_string_overhangs (struct glyph_string *s)
{
if (s->cmp == NULL
&& s->first_glyph->type == CHAR_GLYPH
&& !s->font_not_found_p)
if (s->cmp == NULL)
{
struct font *font = s->font;
struct font_metrics metrics;
if (s->first_glyph->type == CHAR_GLYPH && !s->font_not_found_p)
{
struct font *font = s->font;
font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
}
else if (s->first_glyph->type == COMPOSITE_GLYPH)
{
Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
composition_gstring_width (gstring, s->cmp_from, s->cmp_to, &metrics);
s->right_overhang = (metrics.rbearing > metrics.width
? metrics.rbearing - metrics.width : 0);
s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
}
}
else if (s->cmp)
else
{
s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
s->left_overhang = -s->cmp->lbearing;
......@@ -1725,10 +1734,26 @@ w32_draw_glyph_string_box (struct glyph_string *s)
? WINDOW_RIGHT_EDGE_X (s->w)
: window_box_right (s->w, s->area));
/* The glyph that may have a right box line. */
last_glyph = (s->cmp || s->img
? s->first_glyph
: s->first_glyph + s->nchars - 1);
/* The glyph that may have a right box line. For static
compositions and images, the right-box flag is on the first glyph
of the glyph string; for other types it's on the last glyph. */
if (s->cmp || s->img)
last_glyph = s->first_glyph;
else if (s->first_glyph->type == COMPOSITE_GLYPH
&& s->first_glyph->u.cmp.automatic)
{
/* For automatic compositions, we need to look up the last glyph
in the composition. */
struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
struct glyph *g = s->first_glyph;
for (last_glyph = g++;
g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
&& g->slice.cmp.to < s->cmp_to;
last_glyph = g++)
;
}
else
last_glyph = s->first_glyph + s->nchars - 1;
vwidth = eabs (s->face->box_vertical_line_width);
hwidth = eabs (s->face->box_horizontal_line_width);
......
......@@ -7617,7 +7617,13 @@ get_next_display_element (struct it *it)
/* Otherwise, the box comes from the underlying face.
If this is the last string character displayed, check
the next buffer location. */
else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
else if (((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
/* For a composition, see if the string ends
at the last character included in the
composition. */
|| (it->what == IT_COMPOSITION
&& (IT_STRING_CHARPOS (*it) + it->cmp_it.nchars
>= SCHARS (it->string))))
/* n_overlay_strings is unreliable unless
overlay_string_index is non-negative. */
&& ((it->current.overlay_string_index >= 0
......@@ -27567,12 +27573,18 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
s->face = FACE_FROM_ID (s->f, face_id);
lgstring = composition_gstring_from_id (s->cmp_id);
s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
/* The width of a composition glyph string is the sum of the
composition's glyph widths. */
s->width = s->first_glyph->pixel_width;
glyph++;
while (glyph < last
&& glyph->u.cmp.automatic
&& glyph->u.cmp.id == s->cmp_id
&& s->cmp_to == glyph->slice.cmp.from)
s->cmp_to = (glyph++)->slice.cmp.to + 1;
{
s->width += glyph->pixel_width;
s->cmp_to = (glyph++)->slice.cmp.to + 1;
}
for (i = s->cmp_from; i < s->cmp_to; i++)
{
......@@ -27582,7 +27594,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id,
/* Ensure that the code is only 2 bytes wide. */
s->char2b[i] = code & 0xFFFF;
}
s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
return glyph - s->row->glyphs[s->area];
}
......@@ -2986,10 +2986,26 @@ x_draw_glyph_string_box (struct glyph_string *s)
? WINDOW_RIGHT_EDGE_X (s->w)
: window_box_right (s->w, s->area));
/* The glyph that may have a right box line. */
last_glyph = (s->cmp || s->img
? s->first_glyph
: s->first_glyph + s->nchars - 1);
/* The glyph that may have a right box line. For static
compositions and images, the right-box flag is on the first glyph
of the glyph string; for other types it's on the last glyph. */
if (s->cmp || s->img)
last_glyph = s->first_glyph;
else if (s->first_glyph->type == COMPOSITE_GLYPH
&& s->first_glyph->u.cmp.automatic)
{
/* For automatic compositions, we need to look up the last glyph
in the composition. */
struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
struct glyph *g = s->first_glyph;
for (last_glyph = g++;
g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
&& g->slice.cmp.to < s->cmp_to;
last_glyph = g++)
;
}
else
last_glyph = s->first_glyph + s->nchars - 1;
vwidth = eabs (s->face->box_vertical_line_width);
hwidth = eabs (s->face->box_horizontal_line_width);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment