all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: mohkale@kisara.moe
To: 62994@debbugs.gnu.org
Cc: Mohsin Kaleem <mohkale@kisara.moe>
Subject: bug#62994: [PATCH v6] Add support for colored and styled underlines on tty frames
Date: Sun, 14 Apr 2024 14:56:32 +0100	[thread overview]
Message-ID: <20240414135632.432193-1-mohkale@kisara.moe> (raw)
In-Reply-To: <handler.62994.B.168208734930664.ack@debbugs.gnu.org>

From: Mohsin Kaleem <mohkale@kisara.moe>

* src/dispextern.h (face, face_underline_type, syms_of_xfacse,
internal-set-lisp-face-attribute, gui_supports_face_attributes_p):
Add definitions for new underline styles of Double-line, Dots and
Dashes.  Rename FACE_UNDER_LINE and FACE_UNDER_WAVE to make definitions
consistent.  Delete tty_underline_p from the face struct and use just
underline going forward.  Add a flag to check whether styled underlines
are available.
* lisp/cus-face.el (custom-face-attributes): Add entries for Double-line,
Dots and Dashes so they can be set through `customize'.
* src/termchar.c (tty_display_info): Add an entry for the escape
sequence to set the underline style and color on terminal frames.
* src/term.c (init_tty, tty_capable_p, turn_on_face): Read and save the
underline style escape sequence from the Smulx termcap (alternatively if
the Su flag is set use a default sequence).  Allow checking for support
of styled underlines in the current terminal frame.  Output the necessary
escape sequences to activate a styled underline on turn_on_face; this is
currently only used for the new special underline styles, a default
straight underline will still use the "us" termcap.  Output escape
sequence to set underline color when set in the face and supported by
the tty.  Save a default value for this sequence on init_tty when styled
underlines are supported.
* src/xfaces.c (tty_supports_face_attributes_p, realize_tty_face,
map_tty_color): Assert whether styled underlines are supported by the
current terminal on display-supports-face-attributes-p checks.  Populate
the correct underline style and color in the face spec when realizing a
face.  Allow map_tty_color to map underline colors alongside foreground
and background.  The interface of map_tty_color was amended to allow the
caller to supply the underline color instead of accessing it through the
face attributes.
* src/xterm.c (x_draw_glyph_string): Updated to use renamed
FACE_UNDERLINE_SINGLE and FACE_UNDERLINE_WAVE face_underline_type
enumerations.
---
 doc/lispref/display.texi |  15 ++--
 etc/NEWS                 |  16 ++++
 lisp/cus-face.el         |   5 +-
 src/dispextern.h         |  12 ++-
 src/term.c               |  50 +++++++++++-
 src/termchar.h           |   7 ++
 src/xfaces.c             | 161 ++++++++++++++++++++++++++++++++-------
 src/xterm.c              |   6 +-
 8 files changed, 226 insertions(+), 46 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index fba15578f4f..8425aa23422 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2685,12 +2685,15 @@ Face Attributes
 @var{color} is either a string, or the symbol @code{foreground-color},
 meaning the foreground color of the face.  Omitting the attribute
 @code{:color} means to use the foreground color of the face.
-@var{style} should be a symbol @code{line} or @code{wave}, meaning to
-use a straight or wavy line.  Omitting the attribute @code{:style}
-means to use a straight line.  @var{position}, if non-@code{nil}, means to
-display the underline at the descent of the text, instead of at the
-baseline level.  If it is a number, then it specifies the amount of
-pixels above the descent to display the underline.
+@var{style} is a symbol which sets the line-style to of the underline.
+It should be one of @code{line}, @code{double-line}, @code{wave},
+@code{dots}, or @code{dashes}.  GUI frames only support @code{line} and
+@code{wave}.  Terminal frames can support all aforementioned underline
+styles.  Omitting the attribute @code{:style} means to use a straight
+line.  @var{position}, if non-@code{nil}, means to display the underline
+at the descent of the text, instead of at the baseline level.  If it is
+a number, then it specifies the amount of pixels above the descent to
+display the underline.
 @end table
 
 @cindex overlined text
diff --git a/etc/NEWS b/etc/NEWS
index bc8be557711..7926f34f85a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -424,6 +424,22 @@ Use 'TAB' in the minibuffer to show or hide the password.  Likewise,
 there is an icon on the mode-line, which toggles the visibility of the
 password when clicking with 'mouse-1'.
 
+** Terminal Emacs
+
+---
+*** Support for 'styled' and 'colored' underline face attributes on TTY frames.
+If your terminals termcap or terminfo database entry has the 'Su' or
+'Smulx' capability defined, Emacs will now emit the prescribed escape
+sequence necessary to render faces with styled underlines on TTY
+frames.
+
+Styled underlines are any underlines containing a non-default
+underline style or a color other than the foreground-color.
+The available underline styles for TTY frames are 'single',
+'double-line', 'wave', 'dots, and 'dashes'.  These are currently
+supported by Kitty, libvte, and st (through the undercurl patch) among
+other terminals.
+
 \f
 * Editing Changes in Emacs 30.1
 
diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 47afa841f5e..d0a1a66e29f 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -141,7 +141,10 @@ custom-face-attributes
 		   (const :format "" :value :style)
 		   (choice :tag "Style"
 			   (const :tag "Line" line)
-			   (const :tag "Wave" wave))
+			   (const :tag "Double line" double-line)
+			   (const :tag "Wave" wave)
+			   (const :tag "Dots" dots)
+			   (const :tag "Dashes" dashes))
                    (const :format "" :value :position)
                    (choice :tag "Position"
                            (const :tag "At Default Position" nil)
diff --git a/src/dispextern.h b/src/dispextern.h
index f29377f3596..fc5e53bb055 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1690,9 +1690,13 @@ #define FONT_TOO_HIGH(ft)						\
 
 enum face_underline_type
 {
+	/* Note: Order matches the order of the Smulx terminfo extension. */
   FACE_NO_UNDERLINE = 0,
-  FACE_UNDER_LINE,
-  FACE_UNDER_WAVE
+  FACE_UNDERLINE_SINGLE,
+  FACE_UNDERLINE_DOUBLE_LINE,
+  FACE_UNDERLINE_WAVE,
+  FACE_UNDERLINE_DOTS,
+  FACE_UNDERLINE_DASHES,
 };
 
 /* Structure describing a realized face.
@@ -1776,7 +1780,7 @@ #define FONT_TOO_HIGH(ft)						\
   ENUM_BF (face_box_type) box : 2;
 
   /* Style of underlining. */
-  ENUM_BF (face_underline_type) underline : 2;
+  ENUM_BF (face_underline_type) underline : 3;
 
   /* If `box' above specifies a 3D type, true means use box_color for
      drawing shadows.  */
@@ -1808,7 +1812,6 @@ #define FONT_TOO_HIGH(ft)						\
      string meaning the default color of the TTY.  */
   bool_bf tty_bold_p : 1;
   bool_bf tty_italic_p : 1;
-  bool_bf tty_underline_p : 1;
   bool_bf tty_reverse_p : 1;
   bool_bf tty_strike_through_p : 1;
 
@@ -3426,6 +3429,7 @@ #define TTY_CAP_BOLD		0x04
 #define TTY_CAP_DIM		0x08
 #define TTY_CAP_ITALIC  	0x10
 #define TTY_CAP_STRIKE_THROUGH	0x20
+#define TTY_CAP_UNDERLINE_STYLED	(0x32 & TTY_CAP_UNDERLINE)
 
 \f
 /***********************************************************************
diff --git a/src/term.c b/src/term.c
index 3fa244be824..37174027e04 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2014,8 +2014,19 @@ turn_on_face (struct frame *f, int face_id)
 	OUTPUT1 (tty, tty->TS_enter_dim_mode);
     }
 
-  if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
-    OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
+  if (face->underline && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
+    {
+      if (face->underline == FACE_UNDERLINE_SINGLE
+	  || !tty->TF_set_underline_style)
+	OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
+      else if (tty->TF_set_underline_style)
+	{
+	  char *p;
+	  p = tparam (tty->TF_set_underline_style, NULL, 0, face->underline, 0, 0, 0);
+	  OUTPUT (tty, p);
+	  xfree (p);
+	}
+    }
 
   if (face->tty_strike_through_p
       && MAY_USE_WITH_COLORS_P (tty, NC_STRIKE_THROUGH))
@@ -2041,6 +2052,14 @@ turn_on_face (struct frame *f, int face_id)
 	  OUTPUT (tty, p);
 	  xfree (p);
 	}
+
+	ts = tty->TF_set_underline_color;
+	if (ts && face->underline_color)
+	  {
+		p = tparam (ts, NULL, 0, face->underline_color, 0, 0, 0);
+		OUTPUT (tty, p);
+		xfree (p);
+	  }
     }
 }
 
@@ -2061,7 +2080,7 @@ turn_off_face (struct frame *f, int face_id)
       if (face->tty_bold_p
 	  || face->tty_italic_p
 	  || face->tty_reverse_p
-	  || face->tty_underline_p
+	  || face->underline
 	  || face->tty_strike_through_p)
 	{
 	  OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
@@ -2073,7 +2092,7 @@ turn_off_face (struct frame *f, int face_id)
     {
       /* If we don't have "me" we can only have those appearances
 	 that have exit sequences defined.  */
-      if (face->tty_underline_p)
+      if (face->underline)
 	OUTPUT_IF (tty, tty->TS_exit_underline_mode);
     }
 
@@ -2104,6 +2123,9 @@ #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit)				\
   TTY_CAPABLE_P_TRY (tty,
 		     TTY_CAP_UNDERLINE,	  tty->TS_enter_underline_mode,
 		     NC_UNDERLINE);
+  TTY_CAPABLE_P_TRY (tty,
+		     TTY_CAP_UNDERLINE_STYLED,	  tty->TF_set_underline_style,
+		     NC_UNDERLINE);
   TTY_CAPABLE_P_TRY (tty,
 		     TTY_CAP_BOLD,	  tty->TS_enter_bold_mode, NC_BOLD);
   TTY_CAPABLE_P_TRY (tty,
@@ -4360,6 +4382,26 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   tty->TF_underscore = tgetflag ("ul");
   tty->TF_teleray = tgetflag ("xt");
 
+  /* Styled underlines.  Support for this is provided either by the
+     escape sequence in Smulx or the Su flag.  The latter results in a
+     common default escape sequence and is not recommended.  */
+#ifdef TERMINFO
+  tty->TF_set_underline_style = tigetstr ("Smulx");
+  if (tty->TF_set_underline_style == (char *) (intptr_t) -1)
+    tty->TF_set_underline_style = NULL;
+#else
+  tty->TF_set_underline_style = tgetstr ("Smulx", address);
+#endif
+  if (!tty->TF_set_underline_style && tgetflag ("Su"))
+    /* Default to the kitty escape sequence.  See
+       https://sw.kovidgoyal.net/kitty/underlines/ */
+    tty->TF_set_underline_style = "\x1b[4:%p1%dm";
+
+  if (tty->TF_set_underline_style)
+    /* Standard escape sequence to set the underline color.
+       Requires a single parameter, the color index.  */
+    tty->TF_set_underline_color = "\x1b[58:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm";
+
 #else /* DOS_NT */
 #ifdef WINDOWSNT
   {
diff --git a/src/termchar.h b/src/termchar.h
index 2d845107e11..a1df5a19518 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -171,6 +171,13 @@ #define EMACS_TERMCHAR_H
                                    non-blank position.  Must clear before writing _.  */
   int TF_teleray;               /* termcap xt flag: many weird consequences.
                                    For t1061. */
+  const char *TF_set_underline_style; /* termcap Smulx entry: Switches the underline
+					 style based on the parameter.  Param should
+					 be one of: 0 (none), 1 (straight), 2 (double-line),
+					 3 (wave), 4 (dots), or 5 (dashes).  */
+  const char *TF_set_underline_color; /* Enabled when TF_set_underline_style is set:
+                                         Sets the color of the underline.  Accepts a
+                                         single parameter, the color index.  */
 
   int RPov;                     /* # chars to start a TS_repeat */
 
diff --git a/src/xfaces.c b/src/xfaces.c
index d4583e1a78f..6480bfe1fff 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3311,7 +3311,11 @@ DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
                 }
 
               else if (EQ (key, QCstyle)
-                       && !(EQ (val, Qline) || EQ (val, Qwave)))
+                       && !(EQ (val, Qline)
+                            || EQ (val, Qdouble_line)
+                            || EQ (val, Qwave)
+                            || EQ (val, Qdots)
+                            || EQ (val, Qdashes)))
                 {
                   valid_p = false;
                   break;
@@ -5275,6 +5279,7 @@ gui_supports_face_attributes_p (struct frame *f,
                                 Lisp_Object attrs[LFACE_VECTOR_SIZE],
                                 struct face *def_face)
 {
+  Lisp_Object val;
   Lisp_Object *def_attrs = def_face->lface;
   Lisp_Object lattrs[LFACE_VECTOR_SIZE];
 
@@ -5369,6 +5374,14 @@ gui_supports_face_attributes_p (struct frame *f,
       return false;
     }
 
+  /* Check supported underline styles. */
+  val = attrs[LFACE_UNDERLINE_INDEX];
+  if (!UNSPECIFIEDP (val))
+    if (EQ (CAR_SAFE (val), QCstyle))
+      if (!(EQ (CAR_SAFE (CDR_SAFE (val)), Qline)
+	    || EQ (CAR_SAFE (CDR_SAFE (val)), Qwave)))
+	return false; /* Unsupported underline style.  */
+
   /* Everything checks out, this face is supported.  */
   return true;
 }
@@ -5462,11 +5475,20 @@ tty_supports_face_attributes_p (struct frame *f,
   if (!UNSPECIFIEDP (val))
     {
       if (STRINGP (val))
-	return false;		/* ttys can't use colored underlines */
-      else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))
-	return false;		/* ttys can't use wave underlines */
+	test_caps |= TTY_CAP_UNDERLINE_STYLED;
+      else if (EQ (CAR_SAFE (val), QCstyle))
+	{
+	  if (!(EQ (CAR_SAFE (CDR_SAFE (val)), Qline)
+		|| EQ (CAR_SAFE (CDR_SAFE (val)), Qdouble_line)
+		|| EQ (CAR_SAFE (CDR_SAFE (val)), Qwave)
+		|| EQ (CAR_SAFE (CDR_SAFE (val)), Qdots)
+		|| EQ (CAR_SAFE (CDR_SAFE (val)), Qdashes)))
+	    return false; /* Face uses an unsupported underline style.  */
+
+	  test_caps |= TTY_CAP_UNDERLINE_STYLED;
+	}
       else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
-	return false;		/* same as default */
+	return false;  /* same as default */
       else
 	test_caps |= TTY_CAP_UNDERLINE;
     }
@@ -6321,7 +6343,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
   if (EQ (underline, Qt))
     {
       /* Use default color (same as foreground color).  */
-      face->underline = FACE_UNDER_LINE;
+      face->underline = FACE_UNDERLINE_SINGLE;
       face->underline_defaulted_p = true;
       face->underline_color = 0;
       face->underline_at_descent_line_p = false;
@@ -6330,7 +6352,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
   else if (STRINGP (underline))
     {
       /* Use specified color.  */
-      face->underline = FACE_UNDER_LINE;
+      face->underline = FACE_UNDERLINE_SINGLE;
       face->underline_defaulted_p = false;
       face->underline_color
 	= load_color (f, face, underline,
@@ -6350,7 +6372,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
     {
       /* `(:color COLOR :style STYLE)'.
          STYLE being one of `line' or `wave'. */
-      face->underline = FACE_UNDER_LINE;
+      face->underline = FACE_UNDERLINE_SINGLE;
       face->underline_color = 0;
       face->underline_defaulted_p = true;
       face->underline_at_descent_line_p = false;
@@ -6387,9 +6409,11 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
           else if (EQ (keyword, QCstyle))
             {
               if (EQ (value, Qline))
-                face->underline = FACE_UNDER_LINE;
+                face->underline = FACE_UNDERLINE_SINGLE;
               else if (EQ (value, Qwave))
-                face->underline = FACE_UNDER_WAVE;
+                face->underline = FACE_UNDERLINE_WAVE;
+              else
+                face->underline = FACE_UNDERLINE_SINGLE;
             }
 	  else if (EQ (keyword, QCposition))
 	    {
@@ -6440,17 +6464,18 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
 }
 
 
-/* Map a specified color of face FACE on frame F to a tty color index.
-   IDX is either LFACE_FOREGROUND_INDEX or LFACE_BACKGROUND_INDEX, and
-   specifies which color to map.  Set *DEFAULTED to true if mapping to the
+/* Map the specified color COLOR of face FACE on frame F to a tty
+   color index.  IDX is one of LFACE_FOREGROUND_INDEX,
+   LFACE_BACKGROUND_INDEX or LFACE_UNDERLINE_INDEX, and specifies
+   which color to map.  Set *DEFAULTED to true if mapping to the
    default foreground/background colors.  */
 
 static void
-map_tty_color (struct frame *f, struct face *face,
-	       enum lface_attribute_index idx, bool *defaulted)
+map_tty_color (struct frame *f, struct face *face, Lisp_Object color,
+               enum lface_attribute_index idx, bool *defaulted)
 {
-  Lisp_Object frame, color, def;
-  bool foreground_p = idx == LFACE_FOREGROUND_INDEX;
+  Lisp_Object frame, def;
+  bool foreground_p = idx != LFACE_BACKGROUND_INDEX;
   unsigned long default_pixel =
     foreground_p ? FACE_TTY_DEFAULT_FG_COLOR : FACE_TTY_DEFAULT_BG_COLOR;
   unsigned long pixel = default_pixel;
@@ -6459,10 +6484,11 @@ map_tty_color (struct frame *f, struct face *face,
     foreground_p ? FACE_TTY_DEFAULT_BG_COLOR : FACE_TTY_DEFAULT_FG_COLOR;
 #endif
 
-  eassert (idx == LFACE_FOREGROUND_INDEX || idx == LFACE_BACKGROUND_INDEX);
+  eassert (idx == LFACE_FOREGROUND_INDEX
+           || idx == LFACE_BACKGROUND_INDEX
+           || idx == LFACE_UNDERLINE_INDEX);
 
   XSETFRAME (frame, f);
-  color = face->lface[idx];
 
   if (STRINGP (color)
       && SCHARS (color)
@@ -6507,13 +6533,21 @@ map_tty_color (struct frame *f, struct face *face,
 #endif /* MSDOS */
     }
 
-  if (foreground_p)
-    face->foreground = pixel;
-  else
-    face->background = pixel;
+  switch (idx)
+    {
+    case LFACE_FOREGROUND_INDEX:
+      face->foreground = pixel;
+      break;
+    case LFACE_UNDERLINE_INDEX:
+      face->underline_color = pixel;
+      break;
+    case LFACE_BACKGROUND_INDEX:
+    default:
+      face->background = pixel;
+      break;
+    }
 }
 
-
 /* Realize the fully-specified face with attributes ATTRS in face
    cache CACHE for ASCII characters.  Do it for TTY frame CACHE->f.
    Value is a pointer to the newly created realized face.  */
@@ -6524,6 +6558,7 @@ realize_tty_face (struct face_cache *cache,
 {
   struct face *face;
   int weight, slant;
+  Lisp_Object underline;
   bool face_colors_defaulted = false;
   struct frame *f = cache->f;
 
@@ -6543,16 +6578,83 @@ realize_tty_face (struct face_cache *cache,
     face->tty_bold_p = true;
   if (slant != 100)
     face->tty_italic_p = true;
-  if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
-    face->tty_underline_p = true;
   if (!NILP (attrs[LFACE_INVERSE_INDEX]))
     face->tty_reverse_p = true;
   if (!NILP (attrs[LFACE_STRIKE_THROUGH_INDEX]))
     face->tty_strike_through_p = true;
 
+  /* Text underline.  */
+  underline = attrs[LFACE_UNDERLINE_INDEX];
+  if (NILP (underline))
+    {
+      face->underline = FACE_NO_UNDERLINE;
+      face->underline_color = 0;
+    }
+  else if (EQ (underline, Qt))
+    {
+      face->underline = FACE_UNDERLINE_SINGLE;
+      face->underline_color = 0;
+    }
+  else if (STRINGP (underline))
+    {
+      face->underline = FACE_UNDERLINE_SINGLE;
+      bool underline_color_defaulted;
+      map_tty_color (f, face, underline, LFACE_UNDERLINE_INDEX,
+		     &underline_color_defaulted);
+    }
+  else if (CONSP (underline))
+    {
+      /* `(:color COLOR :style STYLE)'.
+	 STYLE being one of `line', `double-line', `wave', `dots' or `dashes'.  */
+      face->underline = FACE_UNDERLINE_SINGLE;
+      face->underline_color = 0;
+
+      while (CONSP (underline))
+	{
+	  Lisp_Object keyword, value;
+
+	  keyword = XCAR (underline);
+	  underline = XCDR (underline);
+
+	  if (!CONSP (underline))
+	    break;
+	  value = XCAR (underline);
+	  underline = XCDR (underline);
+
+	  if (EQ (keyword, QCcolor))
+	    {
+	      if (EQ (value, Qforeground_color))
+		face->underline_color = 0;
+	      else if (STRINGP (value))
+		{
+		  bool underline_color_defaulted;
+		  map_tty_color (f, face, value, LFACE_UNDERLINE_INDEX,
+				 &underline_color_defaulted);
+		}
+	    }
+	  else if (EQ (keyword, QCstyle))
+	    {
+	      if (EQ (value, Qline))
+		face->underline = FACE_UNDERLINE_SINGLE;
+	      else if (EQ (value, Qdouble_line))
+		face->underline = FACE_UNDERLINE_DOUBLE_LINE;
+	      else if (EQ (value, Qwave))
+		face->underline = FACE_UNDERLINE_WAVE;
+	      else if (EQ (value, Qdots))
+		face->underline = FACE_UNDERLINE_DOTS;
+	      else if (EQ (value, Qdashes))
+		face->underline = FACE_UNDERLINE_DASHES;
+	      else
+		face->underline = FACE_UNDERLINE_SINGLE;
+	    }
+	}
+    }
+
   /* Map color names to color indices.  */
-  map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
-  map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
+  map_tty_color (f, face, face->lface[LFACE_FOREGROUND_INDEX],
+                 LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
+  map_tty_color (f, face, face->lface[LFACE_BACKGROUND_INDEX],
+                 LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
 
   /* Swap colors if face is inverse-video.  If the colors are taken
      from the frame colors, they are already inverted, since the
@@ -7238,6 +7340,9 @@ syms_of_xfaces (void)
   DEFSYM (QCposition, ":position");
   DEFSYM (Qline, "line");
   DEFSYM (Qwave, "wave");
+  DEFSYM (Qdouble_line, "double-line");
+  DEFSYM (Qdots, "dots");
+  DEFSYM (Qdashes, "dashes");
   DEFSYM (Qreleased_button, "released-button");
   DEFSYM (Qpressed_button, "pressed-button");
   DEFSYM (Qflat_button, "flat-button");
diff --git a/src/xterm.c b/src/xterm.c
index e08ffd15b18..360541ac0b9 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10957,7 +10957,7 @@ x_draw_glyph_string (struct glyph_string *s)
       /* Draw underline.  */
       if (s->face->underline)
         {
-          if (s->face->underline == FACE_UNDER_WAVE)
+          if (s->face->underline == FACE_UNDERLINE_WAVE)
             {
               if (s->face->underline_defaulted_p)
                 x_draw_underwave (s, decoration_width);
@@ -10971,13 +10971,13 @@ x_draw_glyph_string (struct glyph_string *s)
                   XSetForeground (display, s->gc, xgcv.foreground);
                 }
             }
-          else if (s->face->underline == FACE_UNDER_LINE)
+          else if (s->face->underline == FACE_UNDERLINE_SINGLE)
             {
               unsigned long thickness, position;
               int y;
 
               if (s->prev
-		  && s->prev->face->underline == FACE_UNDER_LINE
+		  && s->prev->face->underline == FACE_UNDERLINE_SINGLE
 		  && (s->prev->face->underline_at_descent_line_p
 		      == s->face->underline_at_descent_line_p)
 		  && (s->prev->face->underline_pixels_above_descent_line
-- 
2.44.0






  parent reply	other threads:[~2024-04-14 13:56 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-21 14:29 bug#62994: Support styled underlines on TTY frames Mohsin Kaleem
     [not found] ` <handler.62994.B.168208734930664.ack@debbugs.gnu.org>
2023-04-21 14:34   ` bug#62994: [PATCH 0/3] Support styled underlines on tty Emacs frames mohkale
2023-04-21 14:34     ` bug#62994: [PATCH 1/3] Add face definitions for more underline styles mohkale
2023-04-21 15:58       ` Eli Zaretskii
2023-04-21 16:08         ` Mohsin Kaleem
2023-04-21 14:34     ` bug#62994: [PATCH 2/3] Add support for styled underlines on tty frames mohkale
2023-04-21 16:07       ` Eli Zaretskii
     [not found]         ` <878rel5fqr.fsf@kisara.moe>
2023-04-21 17:49           ` Eli Zaretskii
2023-04-21 18:04             ` Mohsin Kaleem
2023-04-21 18:43               ` Mohsin Kaleem
2023-04-22  7:00                 ` Eli Zaretskii
2023-04-22  9:32                   ` Mohsin Kaleem
2023-04-22  6:47               ` Eli Zaretskii
2023-04-22  9:57                 ` Mohsin Kaleem
2023-04-21 14:34     ` bug#62994: [PATCH 3/3] Add support for colored " mohkale
2023-04-21 16:12       ` Eli Zaretskii
     [not found]         ` <875y9p5fg0.fsf@kisara.moe>
2023-04-21 17:56           ` Eli Zaretskii
2023-04-21 15:52     ` bug#62994: [PATCH 0/3] Support styled underlines on tty Emacs frames Eli Zaretskii
2023-04-21 16:10       ` Mohsin Kaleem
2023-04-21 19:24   ` bug#62994: [PATCH v2 0/1] " mohkale
2023-04-21 19:24     ` bug#62994: [PATCH v2 1/1] Add support for colored and styled underlines on tty frames mohkale
2023-04-24  9:21       ` Robert Pluim
2023-04-22 10:21   ` bug#62994: [PATCH v3 0/1] Support styled underlines on tty Emacs frames mohkale
2023-04-22 10:21     ` bug#62994: [PATCH v3 1/1] Add support for colored and styled underlines on tty frames mohkale
2024-02-12  1:28       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-28 11:30     ` bug#62994: [PATCH v3 0/1] Support styled underlines on tty Emacs frames Mohsin Kaleem
2024-01-28 12:05       ` Eli Zaretskii
     [not found]         ` <86fryg62kh.fsf@kisara.moe>
2024-01-29 12:37           ` Eli Zaretskii
2024-02-11 17:40   ` bug#62994: [PATCH v4] Add support for colored and styled underlines on tty frames mohkale
2024-02-11 18:05   ` bug#62994: [PATCH v5] " mohkale
2024-02-11 18:07     ` Mohsin Kaleem
2024-02-12  1:43     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-12 13:50       ` Eli Zaretskii
2024-02-12 14:49         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-10 17:20           ` Mohsin Kaleem
2024-03-10 17:15       ` Mohsin Kaleem
2024-03-10 17:45         ` Eli Zaretskii
2024-03-10 18:22           ` Mohsin Kaleem
2024-03-10 18:51             ` Jim Porter
2024-03-10 19:28               ` Eli Zaretskii
2024-03-10 19:47                 ` Jim Porter
2024-03-11  2:07                 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-10 19:27             ` Eli Zaretskii
2024-02-12 12:48     ` Eli Zaretskii
2024-03-10 18:08       ` Mohsin Kaleem
2024-03-14 10:20         ` Eli Zaretskii
2024-02-14 19:40     ` Jim Porter
2024-03-10 18:10       ` Mohsin Kaleem
2024-04-14 13:56   ` mohkale [this message]
2024-04-14 14:13     ` bug#62994: [PATCH v6] " Mohsin Kaleem
2024-04-20  8:16     ` Eli Zaretskii
2024-04-21 14:51       ` Mohsin Kaleem
2024-04-21 15:57         ` Eli Zaretskii
2024-04-21 16:09           ` Mohsin Kaleem
2024-04-21 16:11   ` bug#62994: [PATCH v7] " Mohsin Kaleem
2024-04-22  0:44     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-22  6:01       ` Eli Zaretskii
2024-04-22 17:35         ` Jim Porter
2024-04-23  0:53         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-23  6:02           ` Eli Zaretskii
2024-04-23  7:32             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-22 17:52       ` Mohsin Kaleem
2024-04-22 17:53   ` bug#62994: [PATCH v8] " Mohsin Kaleem
2024-04-27  9:11     ` Eli Zaretskii
2024-04-29  1:04       ` Jim Porter
2024-04-29  4:52         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-29  7:25           ` Eli Zaretskii
2024-04-29 11:36             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-29  7:10         ` Eli Zaretskii
2024-04-30 17:53       ` Mohsin Kaleem
2024-04-30 18:20         ` Eli Zaretskii
2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 2/3] Add support for styled underlines on tty frames mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 3/3] Add support for colored " mohkale
2024-02-11 17:23   ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames Mohsin Kaleem
2024-02-11 17:46     ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240414135632.432193-1-mohkale@kisara.moe \
    --to=mohkale@kisara.moe \
    --cc=62994@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.