diff options
| author | Po Lu | 2024-05-10 16:44:35 +0800 |
|---|---|---|
| committer | Po Lu | 2024-05-10 16:45:33 +0800 |
| commit | 0f67ddd8d9e855ce0b9c17a4a1410dbd40318055 (patch) | |
| tree | 1e9b17d42d30427db9b19320605ac48058cbe9f5 /src | |
| parent | 4306aba2d0447fd79c0b749a984ccd7bdbc92361 (diff) | |
| download | emacs-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.c | 2 | ||||
| -rw-r--r-- | 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, | |||
| 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 | |||
| 2543 | static void | ||
| 2544 | w32_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 | |||
| 2585 | static void | ||
| 2586 | w32_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 | } |