[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] scratch/large-fonts 1d87cb3: Avoid very high screen lines
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] scratch/large-fonts 1d87cb3: Avoid very high screen lines with some fonts |
Date: |
Wed, 27 May 2015 15:04:00 +0000 |
branch: scratch/large-fonts
commit 1d87cb3cfa08086be96f78ab09d99f3e7ba8ca60
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
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)
---
src/xdisp.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/src/xdisp.c b/src/xdisp.c
index 87f110e..a1b7cf1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2150,7 +2150,7 @@ get_phys_cursor_geometry (struct window *w, struct
glyph_row *row,
struct glyph *glyph, int *xp, int *yp, int *heightp)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int x, y, wd, h, h0, y0;
+ int x, y, wd, h, h0, y0, ascent;
/* Compute the width of the rectangle to draw. If on a stretch
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,
wd = min (FRAME_COLUMN_WIDTH (f), wd);
w->phys_cursor_width = wd;
- y = w->phys_cursor.y + row->ascent - glyph->ascent;
+ /* Don't let the hollow cursor glyph descend below the glyph row's
+ ascent value, lest the hollow cursor looks funny. */
+ y = w->phys_cursor.y;
+ ascent = row->ascent;
+ if (row->ascent < glyph->ascent)
+ {
+ y =- glyph->ascent - row->ascent;
+ ascent = glyph->ascent;
+ }
/* If y is below window bottom, ensure that we still see a cursor. */
h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
- h = max (h0, glyph->ascent + glyph->descent);
- h0 = min (h0, glyph->ascent + glyph->descent);
+ h = max (h0, ascent + glyph->descent);
+ h0 = min (h0, ascent + glyph->descent);
y0 = WINDOW_HEADER_LINE_HEIGHT (w);
if (y < y0)
@@ -19171,6 +19179,7 @@ append_space_for_newline (struct it *it, bool
default_face_p)
struct text_pos saved_pos;
Lisp_Object saved_object;
struct face *face;
+ struct glyph *g;
saved_object = it->object;
saved_pos = it->position;
@@ -19202,6 +19211,11 @@ append_space_for_newline (struct it *it, bool
default_face_p)
PRODUCE_GLYPHS (it);
+ /* Make sure this space glyph has the right ascent value, or
+ else hollow cursor at end of line will look funny. */
+ g = it->glyph_row->glyphs[TEXT_AREA] + n;
+ g->ascent = it->glyph_row->ascent;
+
it->override_ascent = -1;
it->constrain_row_ascent_descent_p = false;
it->current_x = saved_x;
@@ -25282,6 +25296,12 @@ draw_glyphs (struct window *w, int x, struct glyph_row
*row,
} \
}
+/* A heuristic test for fonts that claim they need a preposterously
+ large vertical space. The heuristics is in the factor of 3. We
+ ignore the ascent and descent values reported by such fonts, and
+ instead go by the values reported for individual glyphs. */
+#define FONT_TOO_HIGH(ft) ((ft)->ascent + (ft)->descent > 3*(ft)->pixel_size)
+
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
@@ -26398,6 +26418,22 @@ x_produce_glyphs (struct it *it)
it->phys_ascent = pcm->ascent + boff;
it->phys_descent = pcm->descent - boff;
it->pixel_width = pcm->width;
+ /* Don't use font-global values for ascent and descent
+ if they result in an exceedingly large line height. */
+ if (it->override_ascent < 0)
+ {
+ if (FONT_TOO_HIGH (font))
+ {
+ it->ascent = it->phys_ascent;
+ it->descent = it->phys_descent;
+ /* These limitations are enforced by an
+ assertion near the end of this function. */
+ if (it->ascent < 0)
+ it->ascent = 0;
+ if (it->descent < 0)
+ it->descent = 0;
+ }
+ }
}
else
{
@@ -26525,8 +26561,18 @@ x_produce_glyphs (struct it *it)
}
else
{
- it->ascent = FONT_BASE (font) + boff;
- it->descent = FONT_DESCENT (font) - boff;
+ if (FONT_TOO_HIGH (font))
+ {
+ it->ascent = font->pixel_size + boff - 1;
+ it->descent = -boff + 1;
+ if (it->descent < 0)
+ it->descent = 0;
+ }
+ else
+ {
+ it->ascent = FONT_BASE (font) + boff;
+ it->descent = FONT_DESCENT (font) - boff;
+ }
}
if (EQ (height, Qt))
@@ -26597,8 +26643,38 @@ x_produce_glyphs (struct it *it)
it->pixel_width = next_tab_x - x;
it->nglyphs = 1;
- it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
- it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
+ if (FONT_TOO_HIGH (font))
+ {
+ if (get_char_glyph_code (' ', font, &char2b))
+ {
+ pcm = get_per_char_metric (font, &char2b);
+ if (pcm->width == 0
+ && pcm->rbearing == 0 && pcm->lbearing == 0)
+ pcm = NULL;
+ }
+
+ if (pcm)
+ {
+ it->ascent = pcm->ascent + boff;
+ it->descent = pcm->descent - boff;
+ }
+ else
+ {
+ it->ascent = font->pixel_size + boff - 1;
+ it->descent = -boff + 1;
+ }
+ if (it->ascent < 0)
+ it->ascent = 0;
+ if (it->descent < 0)
+ it->descent = 0;
+ }
+ else
+ {
+ it->ascent = FONT_BASE (font) + boff;
+ it->descent = FONT_DESCENT (font) - boff;
+ }
+ it->phys_ascent = it->ascent;
+ it->phys_descent = it->descent;
if (it->glyph_row)
{