]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix display of cursor on underlined text
authorEli Zaretskii <eliz@gnu.org>
Sun, 5 Mar 2017 15:49:22 +0000 (17:49 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sun, 5 Mar 2017 15:49:22 +0000 (17:49 +0200)
* src/nsterm.m (ns_draw_text_decoration):
* src/xterm.c (x_draw_glyph_string):
* src/w32term.c (x_draw_glyph_string): Compute the position and
thickness of the underline by looking for the first glyph of the
run of underlined glyphs that includes the glyph string we are
drawing.  (Bug#25845)

src/nsterm.m
src/w32term.c
src/xterm.c

index 80261d6d763c97b34d2edb7795365b48559065eb..bc89925b0ef59f27b4c861e3979ef69d45c69e05 100644 (file)
@@ -3043,11 +3043,29 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face,
             }
           else
             {
-              struct font *font;
-              unsigned long descent;
+             /* If we are drawing in the middle of a glyph row, find
+                the first glyph in the run of underlined glyphs
+                preceding the beginning of glyph string S.  This is
+                because that glyph determines the underline position
+                and thickness for the entire run of the underlined
+                glyphs.  */
+             struct glyph *g0 = s->row->glyphs[s->area], *g;
+
+             for (g = s->first_glyph - 1; g >= g0; g--)
+               {
+                 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
+                 if (!(prev_face && prev_face->underline_p))
+                   break;
+               }
+
+             /* Now use the font of the last glyph we saw that
+                still has the underlined_p flag set.  */
+             struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
+             struct font *font = glyph_face->font;
+             if (font)
+               font_prepare_for_face (s->f, glyph_face);
 
-              font=s->font;
-              descent = s->y + s->height - s->ybase;
+              unsigned long descent = s->y + s->height - s->ybase;
 
               /* Use underline thickness of font, defaulting to 1. */
               thickness = (font && font->underline_thickness > 0)
index 28bf6fb3d9f0f5e5a8400f9c6df10e251a6ce426..6a98fc721cd7dfd18d6fbfb84b06af30ff36f5df 100644 (file)
@@ -2433,9 +2433,31 @@ x_draw_glyph_string (struct glyph_string *s)
                 }
               else
                 {
+                 /* If we are drawing in the middle of a glyph row,
+                    find the first glyph in the run of underlined
+                    glyphs preceding the beginning of glyph string S.
+                    This is because that glyph determines the
+                    underline position and thickness for the entire
+                    run of the underlined glyphs.  */
+                 struct glyph *g0 = s->row->glyphs[s->area], *g;
+
+                 for (g = s->first_glyph - 1; g >= g0; g--)
+                   {
+                     struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
+                     if (!(prev_face && prev_face->underline_p))
+                       break;
+                   }
+
+                 /* Now use the font of the last glyph we saw that
+                    still has the underlined_p flag set.  */
+                 struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
+                 struct font *font = glyph_face->font;
+                 if (font)
+                   font_prepare_for_face (s->f, glyph_face);
+
                   /* Get the underline thickness.  Default is 1 pixel.  */
-                  if (s->font && s->font->underline_thickness > 0)
-                    thickness = s->font->underline_thickness;
+                  if (font && font->underline_thickness > 0)
+                    thickness = font->underline_thickness;
                   else
                     thickness = 1;
                   if (x_underline_at_descent_line)
@@ -2451,10 +2473,10 @@ x_draw_glyph_string (struct glyph_string *s)
                          ROUND (x) = floor (x + 0.5)  */
 
                       if (x_use_underline_position_properties
-                          && s->font && s->font->underline_position >= 0)
-                        position = s->font->underline_position;
-                      else if (s->font)
-                        position = (s->font->descent + 1) / 2;
+                          && font && font->underline_position >= 0)
+                        position = font->underline_position;
+                      else if (font)
+                        position = (font->descent + 1) / 2;
                     }
                   position = max (position, underline_minimum_offset);
                 }
@@ -2465,7 +2487,7 @@ x_draw_glyph_string (struct glyph_string *s)
               if (s->y + s->height < s->ybase + position + thickness)
                 thickness = (s->y + s->height) - (s->ybase + position);
               s->underline_thickness = thickness;
-              s->underline_position =position;
+              s->underline_position =  position;
               y = s->ybase + position;
               if (s->face->underline_defaulted_p)
                 {
index 24d1702cec01d77b663c867a22001001c7f6624a..57e64c488879da291b14d065205abb6ed29134c3 100644 (file)
@@ -3636,9 +3636,31 @@ x_draw_glyph_string (struct glyph_string *s)
                 }
               else
                 {
+                 /* If we are drawing in the middle of a glyph row,
+                    find the first glyph in the run of underlined
+                    glyphs preceding the beginning of glyph string S.
+                    This is because that glyph determines the
+                    underline position and thickness for the entire
+                    run of the underlined glyphs.  */
+                 struct glyph *g0 = s->row->glyphs[s->area], *g;
+
+                 for (g = s->first_glyph - 1; g >= g0; g--)
+                   {
+                     struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
+                     if (!(prev_face && prev_face->underline_p))
+                       break;
+                   }
+
+                 /* Now use the font of the last glyph we saw that
+                    still has the underlined_p flag set.  */
+                 struct face *glyph_face = FACE_FROM_ID (s->f, g[1].face_id);
+                 struct font *font = glyph_face->font;
+                 if (font)
+                   font_prepare_for_face (s->f, glyph_face);
+
                   /* Get the underline thickness.  Default is 1 pixel.  */
-                  if (s->font && s->font->underline_thickness > 0)
-                    thickness = s->font->underline_thickness;
+                  if (font && font->underline_thickness > 0)
+                    thickness = font->underline_thickness;
                   else
                     thickness = 1;
                   if (x_underline_at_descent_line)
@@ -3654,10 +3676,10 @@ x_draw_glyph_string (struct glyph_string *s)
                          ROUND(x) = floor (x + 0.5)  */
 
                       if (x_use_underline_position_properties
-                          && s->font && s->font->underline_position >= 0)
-                        position = s->font->underline_position;
-                      else if (s->font)
-                        position = (s->font->descent + 1) / 2;
+                          && font && font->underline_position >= 0)
+                        position = font->underline_position;
+                      else if (font)
+                        position = (font->descent + 1) / 2;
                       else
                         position = underline_minimum_offset;
                     }