emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 8e1ae12: Fix display of cursor on underlined text


From: Eli Zaretskii
Subject: [Emacs-diffs] master 8e1ae12: Fix display of cursor on underlined text
Date: Sun, 5 Mar 2017 10:50:28 -0500 (EST)

branch: master
commit 8e1ae12c37d373007daabcba51b78163a88e55f4
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Fix display of cursor on underlined text
    
    * 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  | 26 ++++++++++++++++++++++----
 src/w32term.c | 36 +++++++++++++++++++++++++++++-------
 src/xterm.c   | 34 ++++++++++++++++++++++++++++------
 3 files changed, 79 insertions(+), 17 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index 80261d6..bc89925 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -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)
diff --git a/src/w32term.c b/src/w32term.c
index 28bf6fb..6a98fc7 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -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)
                 {
diff --git a/src/xterm.c b/src/xterm.c
index 24d1702..57e64c4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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;
                     }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]