aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-05-27 17:56:16 +0300
committerEli Zaretskii2015-05-27 17:56:16 +0300
commit1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60 (patch)
treead88f33f5e597e144625d017207353cfb1c16a42
parent171981622f072546aed135668e53fdeb7b012631 (diff)
downloademacs-1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60.tar.gz
emacs-1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60.zip
Avoid very high screen lines with some fonts
* src/xdisp.c (get_phys_cursor_geometry): Adjust the height of the cursor to avoid weird-looking hollow cursor with fonts that have large ascent values for some glyphs. This avoids having the hollow cursor start too low. (append_space_for_newline): Adjust the ascent value of the newline glyph, so that the hollow cursor at end of line displays correctly. (FONT_TOO_HIGH): New macro. (x_produce_glyphs): Use it to detect fonts that claim a preposterously large height, in which case we use per-glyph ascent and descent values. (Bug#20628)
-rw-r--r--src/xdisp.c92
1 files changed, 84 insertions, 8 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 87f110e667d..a1b7cf1438f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2150,7 +2150,7 @@ get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2150 struct glyph *glyph, int *xp, int *yp, int *heightp) 2150 struct glyph *glyph, int *xp, int *yp, int *heightp)
2151{ 2151{
2152 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2152 struct frame *f = XFRAME (WINDOW_FRAME (w));
2153 int x, y, wd, h, h0, y0; 2153 int x, y, wd, h, h0, y0, ascent;
2154 2154
2155 /* Compute the width of the rectangle to draw. If on a stretch 2155 /* Compute the width of the rectangle to draw. If on a stretch
2156 glyph, and `x-stretch-block-cursor' is nil, don't draw a 2156 glyph, and `x-stretch-block-cursor' is nil, don't draw a
@@ -2170,13 +2170,21 @@ get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2170 wd = min (FRAME_COLUMN_WIDTH (f), wd); 2170 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2171 w->phys_cursor_width = wd; 2171 w->phys_cursor_width = wd;
2172 2172
2173 y = w->phys_cursor.y + row->ascent - glyph->ascent; 2173 /* Don't let the hollow cursor glyph descend below the glyph row's
2174 ascent value, lest the hollow cursor looks funny. */
2175 y = w->phys_cursor.y;
2176 ascent = row->ascent;
2177 if (row->ascent < glyph->ascent)
2178 {
2179 y =- glyph->ascent - row->ascent;
2180 ascent = glyph->ascent;
2181 }
2174 2182
2175 /* If y is below window bottom, ensure that we still see a cursor. */ 2183 /* If y is below window bottom, ensure that we still see a cursor. */
2176 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height); 2184 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2177 2185
2178 h = max (h0, glyph->ascent + glyph->descent); 2186 h = max (h0, ascent + glyph->descent);
2179 h0 = min (h0, glyph->ascent + glyph->descent); 2187 h0 = min (h0, ascent + glyph->descent);
2180 2188
2181 y0 = WINDOW_HEADER_LINE_HEIGHT (w); 2189 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2182 if (y < y0) 2190 if (y < y0)
@@ -19171,6 +19179,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
19171 struct text_pos saved_pos; 19179 struct text_pos saved_pos;
19172 Lisp_Object saved_object; 19180 Lisp_Object saved_object;
19173 struct face *face; 19181 struct face *face;
19182 struct glyph *g;
19174 19183
19175 saved_object = it->object; 19184 saved_object = it->object;
19176 saved_pos = it->position; 19185 saved_pos = it->position;
@@ -19202,6 +19211,11 @@ append_space_for_newline (struct it *it, bool default_face_p)
19202 19211
19203 PRODUCE_GLYPHS (it); 19212 PRODUCE_GLYPHS (it);
19204 19213
19214 /* Make sure this space glyph has the right ascent value, or
19215 else hollow cursor at end of line will look funny. */
19216 g = it->glyph_row->glyphs[TEXT_AREA] + n;
19217 g->ascent = it->glyph_row->ascent;
19218
19205 it->override_ascent = -1; 19219 it->override_ascent = -1;
19206 it->constrain_row_ascent_descent_p = false; 19220 it->constrain_row_ascent_descent_p = false;
19207 it->current_x = saved_x; 19221 it->current_x = saved_x;
@@ -25282,6 +25296,12 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
25282 } \ 25296 } \
25283 } 25297 }
25284 25298
25299/* A heuristic test for fonts that claim they need a preposterously
25300 large vertical space. The heuristics is in the factor of 3. We
25301 ignore the ascent and descent values reported by such fonts, and
25302 instead go by the values reported for individual glyphs. */
25303#define FONT_TOO_HIGH(ft) ((ft)->ascent + (ft)->descent > 3*(ft)->pixel_size)
25304
25285/* Store one glyph for IT->char_to_display in IT->glyph_row. 25305/* Store one glyph for IT->char_to_display in IT->glyph_row.
25286 Called from x_produce_glyphs when IT->glyph_row is non-null. */ 25306 Called from x_produce_glyphs when IT->glyph_row is non-null. */
25287 25307
@@ -26398,6 +26418,22 @@ x_produce_glyphs (struct it *it)
26398 it->phys_ascent = pcm->ascent + boff; 26418 it->phys_ascent = pcm->ascent + boff;
26399 it->phys_descent = pcm->descent - boff; 26419 it->phys_descent = pcm->descent - boff;
26400 it->pixel_width = pcm->width; 26420 it->pixel_width = pcm->width;
26421 /* Don't use font-global values for ascent and descent
26422 if they result in an exceedingly large line height. */
26423 if (it->override_ascent < 0)
26424 {
26425 if (FONT_TOO_HIGH (font))
26426 {
26427 it->ascent = it->phys_ascent;
26428 it->descent = it->phys_descent;
26429 /* These limitations are enforced by an
26430 assertion near the end of this function. */
26431 if (it->ascent < 0)
26432 it->ascent = 0;
26433 if (it->descent < 0)
26434 it->descent = 0;
26435 }
26436 }
26401 } 26437 }
26402 else 26438 else
26403 { 26439 {
@@ -26525,8 +26561,18 @@ x_produce_glyphs (struct it *it)
26525 } 26561 }
26526 else 26562 else
26527 { 26563 {
26528 it->ascent = FONT_BASE (font) + boff; 26564 if (FONT_TOO_HIGH (font))
26529 it->descent = FONT_DESCENT (font) - boff; 26565 {
26566 it->ascent = font->pixel_size + boff - 1;
26567 it->descent = -boff + 1;
26568 if (it->descent < 0)
26569 it->descent = 0;
26570 }
26571 else
26572 {
26573 it->ascent = FONT_BASE (font) + boff;
26574 it->descent = FONT_DESCENT (font) - boff;
26575 }
26530 } 26576 }
26531 26577
26532 if (EQ (height, Qt)) 26578 if (EQ (height, Qt))
@@ -26597,8 +26643,38 @@ x_produce_glyphs (struct it *it)
26597 26643
26598 it->pixel_width = next_tab_x - x; 26644 it->pixel_width = next_tab_x - x;
26599 it->nglyphs = 1; 26645 it->nglyphs = 1;
26600 it->ascent = it->phys_ascent = FONT_BASE (font) + boff; 26646 if (FONT_TOO_HIGH (font))
26601 it->descent = it->phys_descent = FONT_DESCENT (font) - boff; 26647 {
26648 if (get_char_glyph_code (' ', font, &char2b))
26649 {
26650 pcm = get_per_char_metric (font, &char2b);
26651 if (pcm->width == 0
26652 && pcm->rbearing == 0 && pcm->lbearing == 0)
26653 pcm = NULL;
26654 }
26655
26656 if (pcm)
26657 {
26658 it->ascent = pcm->ascent + boff;
26659 it->descent = pcm->descent - boff;
26660 }
26661 else
26662 {
26663 it->ascent = font->pixel_size + boff - 1;
26664 it->descent = -boff + 1;
26665 }
26666 if (it->ascent < 0)
26667 it->ascent = 0;
26668 if (it->descent < 0)
26669 it->descent = 0;
26670 }
26671 else
26672 {
26673 it->ascent = FONT_BASE (font) + boff;
26674 it->descent = FONT_DESCENT (font) - boff;
26675 }
26676 it->phys_ascent = it->ascent;
26677 it->phys_descent = it->descent;
26602 26678
26603 if (it->glyph_row) 26679 if (it->glyph_row)
26604 { 26680 {