diff options
| author | Eli Zaretskii | 2015-05-27 17:56:16 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-05-27 17:56:16 +0300 |
| commit | 1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60 (patch) | |
| tree | ad88f33f5e597e144625d017207353cfb1c16a42 | |
| parent | 171981622f072546aed135668e53fdeb7b012631 (diff) | |
| download | emacs-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.c | 92 |
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 | { |