emacs-diffs
[Top][All Lists]
Advanced

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

master 0f67ddd8d9e: Implement dots and dashes on MS-Windows


From: Po Lu
Subject: master 0f67ddd8d9e: Implement dots and dashes on MS-Windows
Date: Fri, 10 May 2024 04:45:49 -0400 (EDT)

branch: master
commit 0f67ddd8d9e855ce0b9c17a4a1410dbd40318055
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Implement dots and dashes on MS-Windows
    
    * src/haikuterm.c (haiku_draw_dash): Correct whitespace error.
    
    * src/w32term.c (w32_draw_dash, w32_fill_underline)
    (w32_draw_glyph_string): Port display of dash and dot underline
    styles from X.
---
 src/haikuterm.c |   2 +-
 src/w32term.c   | 102 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 91 insertions(+), 13 deletions(-)

diff --git a/src/haikuterm.c b/src/haikuterm.c
index 09d70230bab..c194a348df3 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -839,7 +839,7 @@ haiku_draw_dash (struct frame *f, struct glyph_string *s, 
int width,
                               s->x + width - 1),
                          y_center);
 
-      which  = !which;
+      which = !which;
     }
 }
 
diff --git a/src/w32term.c b/src/w32term.c
index 9b10e4c3342..a9aff304771 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -2535,6 +2535,89 @@ w32_draw_stretch_glyph_string (struct glyph_string *s)
   s->background_filled_p = true;
 }
 
+/* Draw a dashed underline of thickness THICKNESS and width WIDTH onto F
+   at a vertical offset of OFFSET from the position of the glyph string
+   S, with each segment SEGMENT pixels in length, and in the color
+   FOREGROUND.  */
+
+static void
+w32_draw_dash (struct frame *f, struct glyph_string *s,
+              COLORREF foreground, int width, char segment,
+              int offset, int thickness)
+{
+  int y_base, which, length, x, doffset;
+  HDC hdc = s->hdc;
+
+  /* A pen with PS_DASH (or PS_DOT) is unsuitable for two reasons: first
+     that PS_DASH does not accept width values greater than 1, with
+     itself considered equivalent to PS_SOLID if such a value be
+     specified, and second that it does not provide for an offset to be
+     applied to the pattern, absent which Emacs cannot align dashes that
+     are displayed at locations not multiples of each other.  I can't be
+     bothered to research this matter further, so, for want of a better
+     option, draw the specified pattern manually.  */
+
+  y_base = s->ybase + offset;
+
+  /* Remove redundant portions of OFFSET.  */
+  doffset = s->x % (segment * 2);
+
+  /* Set which to the phase of the first dash that ought to be drawn and
+     length to its length.  */
+  which = doffset < segment;
+  length = segment - (s->x % segment);
+
+  /* Begin drawing this dash.  */
+  for (x = s->x; x < s->x + width; x += length, length = segment)
+    {
+      if (which)
+       w32_fill_area (f, hdc, foreground, x, y_base, length,
+                      thickness);
+
+      which = !which;
+    }
+}
+
+/* Draw an underline of STYLE onto F at an offset of POSITION from the
+   baseline of the glyph string S, in the color FOREGROUND that is
+   THICKNESS in height.  */
+
+static void
+w32_fill_underline (struct frame *f, struct glyph_string *s,
+                   COLORREF foreground,
+                   enum face_underline_type style, int position,
+                   int thickness)
+{
+  int segment;
+
+  segment = thickness * 3;
+
+  switch (style)
+    {
+      /* FACE_UNDERLINE_DOUBLE_LINE is treated identically to SINGLE, as
+        the second line will be filled by another invocation of this
+        function.  */
+    case FACE_UNDERLINE_SINGLE:
+    case FACE_UNDERLINE_DOUBLE_LINE:
+      w32_fill_area (s->f, s->hdc, foreground, s->x,
+                    s->ybase + position, s->width, thickness);
+      break;
+
+    case FACE_UNDERLINE_DOTS:
+      segment = thickness;
+      FALLTHROUGH;
+
+    case FACE_UNDERLINE_DASHES:
+      w32_draw_dash (f, s, foreground, s->width, segment, position,
+                    thickness);
+      break;
+
+    case FACE_NO_UNDERLINE:
+    case FACE_UNDERLINE_WAVE:
+    default:
+      emacs_abort ();
+    }
+}
 
 /* Draw glyph string S.  */
 
@@ -2652,17 +2735,14 @@ w32_draw_glyph_string (struct glyph_string *s)
 
               w32_draw_underwave (s, color);
             }
-          else if (s->face->underline == FACE_UNDERLINE_SINGLE
-                  || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE)
+          else if (s->face->underline >= FACE_UNDERLINE_SINGLE)
             {
               unsigned long thickness, position;
-              int y;
              COLORREF foreground;
 
               if (s->prev
-                 && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE)
-                     || (s->prev->face->underline
-                         == FACE_UNDERLINE_DOUBLE_LINE))
+                 && (s->prev->face->underline != FACE_UNDERLINE_WAVE
+                     && 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
@@ -2739,15 +2819,14 @@ w32_draw_glyph_string (struct glyph_string *s)
                 thickness = (s->y + s->height) - (s->ybase + position);
               s->underline_thickness = thickness;
               s->underline_position = position;
-              y = s->ybase + position;
 
               if (s->face->underline_defaulted_p)
                foreground = s->gc->foreground;
              else
                foreground = s->face->underline_color;
 
-             w32_fill_area (s->f, s->hdc, foreground, s->x, y,
-                            s->width, thickness);
+             w32_fill_underline (s->f, s, foreground, s->face->underline,
+                                 position, thickness);
 
              /* Place a second underline above the first if this was
                 requested in the face specification.  */
@@ -2756,9 +2835,8 @@ w32_draw_glyph_string (struct glyph_string *s)
                {
                  /* Compute the position of the second underline.  */
                  position = position - thickness - 1;
-                 y        = s->ybase + position;
-                 w32_fill_area (s->f, s->hdc, foreground, s->x, y,
-                                s->width, thickness);
+                 w32_fill_underline (s->f, s, foreground, s->face->underline,
+                                     position, thickness);
                }
             }
         }



reply via email to

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