diff options
| author | Pip Cet | 2020-06-04 22:28:53 +0000 |
|---|---|---|
| committer | Pip Cet | 2020-06-05 13:13:48 +0000 |
| commit | a984f39554cb33b9c2efbc843aabb283c69d503d (patch) | |
| tree | c359e14060b47281ee4a8d3b27cd02b85e5fe8d1 | |
| parent | 8ee367fe864d131a9d7f87677b9418ac78c922fa (diff) | |
| download | emacs-a984f39554cb33b9c2efbc843aabb283c69d503d.tar.gz emacs-a984f39554cb33b9c2efbc843aabb283c69d503d.zip | |
Avoid zero-width glyphs and the resulting cursor artifacts
* src/xdisp.c (fill_gstring_glyph_string): Handle unavailable glyphs.
(append_composite_glyph): Mark unavailable glyphs.
(gui_produce_glyphs): Make glyphs unavailable for zero-width
compositions. (Bug#41645)
| -rw-r--r-- | src/xdisp.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 327e8a183b1..52f6ab8e709 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -27689,10 +27689,12 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id, | |||
| 27689 | struct glyph *glyph, *last; | 27689 | struct glyph *glyph, *last; |
| 27690 | Lisp_Object lgstring; | 27690 | Lisp_Object lgstring; |
| 27691 | int i; | 27691 | int i; |
| 27692 | bool glyph_not_available_p; | ||
| 27692 | 27693 | ||
| 27693 | s->for_overlaps = overlaps; | 27694 | s->for_overlaps = overlaps; |
| 27694 | glyph = s->row->glyphs[s->area] + start; | 27695 | glyph = s->row->glyphs[s->area] + start; |
| 27695 | last = s->row->glyphs[s->area] + end; | 27696 | last = s->row->glyphs[s->area] + end; |
| 27697 | glyph_not_available_p = glyph->glyph_not_available_p; | ||
| 27696 | s->cmp_id = glyph->u.cmp.id; | 27698 | s->cmp_id = glyph->u.cmp.id; |
| 27697 | s->cmp_from = glyph->slice.cmp.from; | 27699 | s->cmp_from = glyph->slice.cmp.from; |
| 27698 | s->cmp_to = glyph->slice.cmp.to + 1; | 27700 | s->cmp_to = glyph->slice.cmp.to + 1; |
| @@ -27707,7 +27709,8 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id, | |||
| 27707 | && glyph->u.cmp.automatic | 27709 | && glyph->u.cmp.automatic |
| 27708 | && glyph->u.cmp.id == s->cmp_id | 27710 | && glyph->u.cmp.id == s->cmp_id |
| 27709 | && glyph->face_id == face_id | 27711 | && glyph->face_id == face_id |
| 27710 | && s->cmp_to == glyph->slice.cmp.from) | 27712 | && s->cmp_to == glyph->slice.cmp.from |
| 27713 | && glyph->glyph_not_available_p == glyph_not_available_p) | ||
| 27711 | { | 27714 | { |
| 27712 | s->width += glyph->pixel_width; | 27715 | s->width += glyph->pixel_width; |
| 27713 | s->cmp_to = (glyph++)->slice.cmp.to + 1; | 27716 | s->cmp_to = (glyph++)->slice.cmp.to + 1; |
| @@ -27722,6 +27725,12 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id, | |||
| 27722 | s->char2b[i] = code & 0xFFFF; | 27725 | s->char2b[i] = code & 0xFFFF; |
| 27723 | } | 27726 | } |
| 27724 | 27727 | ||
| 27728 | /* If the specified font could not be loaded, record that fact in | ||
| 27729 | S->font_not_found_p so that we can draw rectangles for the | ||
| 27730 | characters of the glyph string. */ | ||
| 27731 | if (glyph_not_available_p) | ||
| 27732 | s->font_not_found_p = true; | ||
| 27733 | |||
| 27725 | return glyph - s->row->glyphs[s->area]; | 27734 | return glyph - s->row->glyphs[s->area]; |
| 27726 | } | 27735 | } |
| 27727 | 27736 | ||
| @@ -28918,7 +28927,7 @@ append_composite_glyph (struct it *it) | |||
| 28918 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 28927 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
| 28919 | || it->phys_descent > it->descent); | 28928 | || it->phys_descent > it->descent); |
| 28920 | glyph->padding_p = false; | 28929 | glyph->padding_p = false; |
| 28921 | glyph->glyph_not_available_p = false; | 28930 | glyph->glyph_not_available_p = it->glyph_not_available_p; |
| 28922 | glyph->face_id = it->face_id; | 28931 | glyph->face_id = it->face_id; |
| 28923 | glyph->font_type = FONT_TYPE_UNKNOWN; | 28932 | glyph->font_type = FONT_TYPE_UNKNOWN; |
| 28924 | if (it->bidi_p) | 28933 | if (it->bidi_p) |
| @@ -30626,11 +30635,21 @@ gui_produce_glyphs (struct it *it) | |||
| 30626 | it->pixel_width | 30635 | it->pixel_width |
| 30627 | = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to, | 30636 | = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to, |
| 30628 | &metrics); | 30637 | &metrics); |
| 30629 | if (it->glyph_row | 30638 | if (it->pixel_width == 0) |
| 30630 | && (metrics.lbearing < 0 || metrics.rbearing > metrics.width)) | 30639 | { |
| 30631 | it->glyph_row->contains_overlapping_glyphs_p = true; | 30640 | it->glyph_not_available_p = true; |
| 30632 | it->ascent = it->phys_ascent = metrics.ascent; | 30641 | it->phys_ascent = it->ascent; |
| 30633 | it->descent = it->phys_descent = metrics.descent; | 30642 | it->phys_descent = it->descent; |
| 30643 | it->pixel_width = face->font->space_width; | ||
| 30644 | } | ||
| 30645 | else | ||
| 30646 | { | ||
| 30647 | if (it->glyph_row | ||
| 30648 | && (metrics.lbearing < 0 || metrics.rbearing > metrics.width)) | ||
| 30649 | it->glyph_row->contains_overlapping_glyphs_p = true; | ||
| 30650 | it->ascent = it->phys_ascent = metrics.ascent; | ||
| 30651 | it->descent = it->phys_descent = metrics.descent; | ||
| 30652 | } | ||
| 30634 | IT_APPLY_FACE_BOX(it, face); | 30653 | IT_APPLY_FACE_BOX(it, face); |
| 30635 | 30654 | ||
| 30636 | /* If face has an overline, add the height of the overline | 30655 | /* If face has an overline, add the height of the overline |