]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix display of cursor at end of empty lines
authorEli Zaretskii <eliz@gnu.org>
Sat, 30 May 2015 09:33:08 +0000 (12:33 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 30 May 2015 09:33:08 +0000 (12:33 +0300)
* src/xdisp.c (normal_char_ascent_descent): Accept additional
argument: the character to use for metrics in case the font
declares too large ascent and descent values.  Add 1 pixel to
ascent and descent values.
(normal_char_height): Accept additional argument: the character to
use for metrics in case the font declares too large height value.
Call normal_char_ascent_descent instead of doing calculations for
a different default character.
(estimate_mode_line_height, handle_single_display_spec)
(calc_pixel_width_or_height, produce_stretch_glyph)
(calc_line_height_property, produce_glyphless_glyph): All callers
changed.
(append_space_for_newline): Make sure the space glyph produced at
end of line has correct ascent and descent values, and the glyph
row has correct height, even when it's empty.

src/xdisp.c

index 1fd84f8ade064d5cb50c0b03b6b07e258935cda8..50d7376b28a22b84afa1ac7639ee0faea51544e8 100644 (file)
@@ -833,7 +833,9 @@ static void x_draw_bottom_divider (struct window *w);
 static void notice_overwritten_cursor (struct window *,
                                        enum glyph_row_area,
                                        int, int, int, int);
-static int  normal_char_height (struct font *);
+static int  normal_char_height (struct font *, int);
+static void normal_char_ascent_descent (struct font *, int, int *, int *);
+
 static void append_stretch_glyph (struct it *, Lisp_Object,
                                   int, int, int);
 
@@ -1762,7 +1764,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id)
          if (face)
            {
              if (face->font)
-               height = normal_char_height (face->font);
+               height = normal_char_height (face->font, -1);
              if (face->box_line_width > 0)
                height += 2 * face->box_line_width;
            }
@@ -4889,7 +4891,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
            {
              struct face *face = FACE_FROM_ID (it->f, it->face_id);
              it->voffset = - (XFLOATINT (value)
-                              * (normal_char_height (face->font)));
+                              * (normal_char_height (face->font, -1)));
            }
 #endif /* HAVE_WINDOW_SYSTEM */
        }
@@ -19212,10 +19214,22 @@ 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.  */
+         /* Make sure this space glyph has the right ascent and
+            descent values, or else cursor at end of line will look
+            funny.  */
          g = it->glyph_row->glyphs[TEXT_AREA] + n;
-         g->ascent = it->glyph_row->ascent;
+         struct font *font = face->font ? face->font : FRAME_FONT (it->f);
+         if (n == 0 || it->glyph_row->height < font->pixel_size)
+           {
+             normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
+             it->max_ascent = it->ascent;
+             it->max_descent = it->descent;
+             /* Make sure compute_line_metrics recomputes the row height.  */
+             it->glyph_row->height = 0;
+           }
+
+         g->ascent = it->max_ascent;
+         g->descent = it->max_descent;
 
          it->override_ascent = -1;
          it->constrain_row_ascent_descent_p = false;
@@ -23930,7 +23944,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
 #ifdef HAVE_WINDOW_SYSTEM
       if (EQ (prop, Qheight))
        return OK_PIXELS (font
-                         ? normal_char_height (font)
+                         ? normal_char_height (font, -1)
                          : FRAME_LINE_HEIGHT (it->f));
       if (EQ (prop, Qwidth))
        return OK_PIXELS (font
@@ -24569,39 +24583,14 @@ get_per_char_metric (struct font *font, XChar2b *char2b)
   return &metrics;
 }
 
-/* A subroutine that computes a reasonable "normal character height"
-   for fonts that claim preposterously large vertical dimensions, but
-   whose glyphs are actually reasonably sized.  */
-static int
-normal_char_height (struct font *font)
-{
-  int default_height = FONT_HEIGHT (font);
-
-  /* If the font claims too large height, use the metrics of the SPC
-     character instead.  Note that this could still fail to produce a
-     better value if the font or the font driver don't support the
-     functionality required by get_per_char_metric.  */
-  if (FONT_TOO_HIGH (font))
-    {
-      XChar2b char2b;
-
-      /* Get metrics of the SPC character.  */
-      if (get_char_glyph_code (' ', font, &char2b))
-       {
-         struct font_metrics *pcm = get_per_char_metric (font, &char2b);
-
-         if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
-           default_height = pcm->ascent + pcm->descent;
-       }
-    }
-  return default_height;
-}
-
-/* A subroutine that computes "normal" values of ascent and descent
-   for fonts that claim preposterously large values, but whose glyphs
-   actually have reasonable dimensions.  */
+/* A subroutine that computes "normal" values of ASCENT and DESCENT
+   for FONT.  Values are taken from font-global ones, except for fonts
+   that claim preposterously large values, but whose glyphs actually
+   have reasonable dimensions.  C is the character to use for metrics
+   if the font-global values are too large; if C is negative, the
+   function selects a default character.  */
 static void
-normal_char_ascent_descent (struct font *font, int *ascent, int *descent)
+normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
 {
   *ascent = FONT_BASE (font);
   *descent = FONT_DESCENT (font);
@@ -24610,20 +24599,39 @@ normal_char_ascent_descent (struct font *font, int *ascent, int *descent)
     {
       XChar2b char2b;
 
-      /* Get metrics of a reasonably sized ASCII character.  */
-      if (get_char_glyph_code ('{', font, &char2b))
+      /* Get metrics of C, defaulting to a reasonably sized ASCII
+        character.  */
+      if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
        {
          struct font_metrics *pcm = get_per_char_metric (font, &char2b);
 
          if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
            {
-             *ascent = pcm->ascent;
-             *descent = pcm->descent;
+             /* We add 1 pixel to character dimensions as heuristics
+                that produces nicer display, e.g. when the face has
+                the box attribute.  */
+             *ascent = pcm->ascent + 1;
+             *descent = pcm->descent + 1;
            }
        }
     }
 }
 
+/* A subroutine that computes a reasonable "normal character height"
+   for fonts that claim preposterously large vertical dimensions, but
+   whose glyphs are actually reasonably sized.  C is the charcater
+   whose metrics to use for those fonts, or -1 for default
+   character.  */
+static int
+normal_char_height (struct font *font, int c)
+{
+  int ascent, descent;
+
+  normal_char_ascent_descent (font, c, &ascent, &descent);
+
+  return ascent + descent;
+}
+
 /* EXPORT for RIF:
    Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
    frame F.  Overhangs of glyphs other than type CHAR_GLYPH are
@@ -25923,7 +25931,7 @@ produce_stretch_glyph (struct it *it)
   /* Compute height.  */
   if (FRAME_WINDOW_P (it->f))
     {
-      int default_height = normal_char_height (font);
+      int default_height = normal_char_height (font, ' ');
 
       if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
          && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
@@ -26159,7 +26167,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
        boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
     }
 
-  normal_char_ascent_descent (font, &ascent, &descent);
+  normal_char_ascent_descent (font, -1, &ascent, &descent);
 
   if (override)
     {
@@ -26285,7 +26293,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
      ASCII face.  */
   face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
   font = face->font ? face->font : FRAME_FONT (it->f);
-  normal_char_ascent_descent (font, &it->ascent, &it->descent);
+  normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
   it->ascent += font->baseline_offset;
   it->descent -= font->baseline_offset;
   base_height = it->ascent + it->descent;