aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2024-05-10 16:44:35 +0800
committerPo Lu2024-05-10 16:45:33 +0800
commit0f67ddd8d9e855ce0b9c17a4a1410dbd40318055 (patch)
tree1e9b17d42d30427db9b19320605ac48058cbe9f5 /src
parent4306aba2d0447fd79c0b749a984ccd7bdbc92361 (diff)
downloademacs-0f67ddd8d9e855ce0b9c17a4a1410dbd40318055.tar.gz
emacs-0f67ddd8d9e855ce0b9c17a4a1410dbd40318055.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/haikuterm.c2
-rw-r--r--src/w32term.c102
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,
839 s->x + width - 1), 839 s->x + width - 1),
840 y_center); 840 y_center);
841 841
842 which = !which; 842 which = !which;
843 } 843 }
844} 844}
845 845
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)
2535 s->background_filled_p = true; 2535 s->background_filled_p = true;
2536} 2536}
2537 2537
2538/* Draw a dashed underline of thickness THICKNESS and width WIDTH onto F
2539 at a vertical offset of OFFSET from the position of the glyph string
2540 S, with each segment SEGMENT pixels in length, and in the color
2541 FOREGROUND. */
2542
2543static void
2544w32_draw_dash (struct frame *f, struct glyph_string *s,
2545 COLORREF foreground, int width, char segment,
2546 int offset, int thickness)
2547{
2548 int y_base, which, length, x, doffset;
2549 HDC hdc = s->hdc;
2550
2551 /* A pen with PS_DASH (or PS_DOT) is unsuitable for two reasons: first
2552 that PS_DASH does not accept width values greater than 1, with
2553 itself considered equivalent to PS_SOLID if such a value be
2554 specified, and second that it does not provide for an offset to be
2555 applied to the pattern, absent which Emacs cannot align dashes that
2556 are displayed at locations not multiples of each other. I can't be
2557 bothered to research this matter further, so, for want of a better
2558 option, draw the specified pattern manually. */
2559
2560 y_base = s->ybase + offset;
2561
2562 /* Remove redundant portions of OFFSET. */
2563 doffset = s->x % (segment * 2);
2564
2565 /* Set which to the phase of the first dash that ought to be drawn and
2566 length to its length. */
2567 which = doffset < segment;
2568 length = segment - (s->x % segment);
2569
2570 /* Begin drawing this dash. */
2571 for (x = s->x; x < s->x + width; x += length, length = segment)
2572 {
2573 if (which)
2574 w32_fill_area (f, hdc, foreground, x, y_base, length,
2575 thickness);
2576
2577 which = !which;
2578 }
2579}
2580
2581/* Draw an underline of STYLE onto F at an offset of POSITION from the
2582 baseline of the glyph string S, in the color FOREGROUND that is
2583 THICKNESS in height. */
2584
2585static void
2586w32_fill_underline (struct frame *f, struct glyph_string *s,
2587 COLORREF foreground,
2588 enum face_underline_type style, int position,
2589 int thickness)
2590{
2591 int segment;
2592
2593 segment = thickness * 3;
2594
2595 switch (style)
2596 {
2597 /* FACE_UNDERLINE_DOUBLE_LINE is treated identically to SINGLE, as
2598 the second line will be filled by another invocation of this
2599 function. */
2600 case FACE_UNDERLINE_SINGLE:
2601 case FACE_UNDERLINE_DOUBLE_LINE:
2602 w32_fill_area (s->f, s->hdc, foreground, s->x,
2603 s->ybase + position, s->width, thickness);
2604 break;
2605
2606 case FACE_UNDERLINE_DOTS:
2607 segment = thickness;
2608 FALLTHROUGH;
2609
2610 case FACE_UNDERLINE_DASHES:
2611 w32_draw_dash (f, s, foreground, s->width, segment, position,
2612 thickness);
2613 break;
2614
2615 case FACE_NO_UNDERLINE:
2616 case FACE_UNDERLINE_WAVE:
2617 default:
2618 emacs_abort ();
2619 }
2620}
2538 2621
2539/* Draw glyph string S. */ 2622/* Draw glyph string S. */
2540 2623
@@ -2652,17 +2735,14 @@ w32_draw_glyph_string (struct glyph_string *s)
2652 2735
2653 w32_draw_underwave (s, color); 2736 w32_draw_underwave (s, color);
2654 } 2737 }
2655 else if (s->face->underline == FACE_UNDERLINE_SINGLE 2738 else if (s->face->underline >= FACE_UNDERLINE_SINGLE)
2656 || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE)
2657 { 2739 {
2658 unsigned long thickness, position; 2740 unsigned long thickness, position;
2659 int y;
2660 COLORREF foreground; 2741 COLORREF foreground;
2661 2742
2662 if (s->prev 2743 if (s->prev
2663 && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) 2744 && (s->prev->face->underline != FACE_UNDERLINE_WAVE
2664 || (s->prev->face->underline 2745 && s->prev->face->underline >= FACE_UNDERLINE_SINGLE)
2665 == FACE_UNDERLINE_DOUBLE_LINE))
2666 && (s->prev->face->underline_at_descent_line_p 2746 && (s->prev->face->underline_at_descent_line_p
2667 == s->face->underline_at_descent_line_p) 2747 == s->face->underline_at_descent_line_p)
2668 && (s->prev->face->underline_pixels_above_descent_line 2748 && (s->prev->face->underline_pixels_above_descent_line
@@ -2739,15 +2819,14 @@ w32_draw_glyph_string (struct glyph_string *s)
2739 thickness = (s->y + s->height) - (s->ybase + position); 2819 thickness = (s->y + s->height) - (s->ybase + position);
2740 s->underline_thickness = thickness; 2820 s->underline_thickness = thickness;
2741 s->underline_position = position; 2821 s->underline_position = position;
2742 y = s->ybase + position;
2743 2822
2744 if (s->face->underline_defaulted_p) 2823 if (s->face->underline_defaulted_p)
2745 foreground = s->gc->foreground; 2824 foreground = s->gc->foreground;
2746 else 2825 else
2747 foreground = s->face->underline_color; 2826 foreground = s->face->underline_color;
2748 2827
2749 w32_fill_area (s->f, s->hdc, foreground, s->x, y, 2828 w32_fill_underline (s->f, s, foreground, s->face->underline,
2750 s->width, thickness); 2829 position, thickness);
2751 2830
2752 /* Place a second underline above the first if this was 2831 /* Place a second underline above the first if this was
2753 requested in the face specification. */ 2832 requested in the face specification. */
@@ -2756,9 +2835,8 @@ w32_draw_glyph_string (struct glyph_string *s)
2756 { 2835 {
2757 /* Compute the position of the second underline. */ 2836 /* Compute the position of the second underline. */
2758 position = position - thickness - 1; 2837 position = position - thickness - 1;
2759 y = s->ybase + position; 2838 w32_fill_underline (s->f, s, foreground, s->face->underline,
2760 w32_fill_area (s->f, s->hdc, foreground, s->x, y, 2839 position, thickness);
2761 s->width, thickness);
2762 } 2840 }
2763 } 2841 }
2764 } 2842 }