diff options
| author | Po Lu | 2024-04-28 21:30:52 +0800 |
|---|---|---|
| committer | Po Lu | 2024-04-28 21:30:52 +0800 |
| commit | 7341e600b7bc554df44784b6aa135bed8fcb61f1 (patch) | |
| tree | 1f1737d65097687d9485aa343530013b8be9be48 /src | |
| parent | 9d9881aceaefef56687baeb75eef94be1c7b22af (diff) | |
| download | emacs-7341e600b7bc554df44784b6aa135bed8fcb61f1.tar.gz emacs-7341e600b7bc554df44784b6aa135bed8fcb61f1.zip | |
Implement dots and dashes on PGTK
* src/image.c (image_create_bitmap_from_file) [HAVE_PGTK]:
Remove unused variable.
* src/pgtkterm.c (pgtk_draw_dash, pgtk_fill_underline)
(pgtk_draw_glyph_string): New functions, ported from X.
Diffstat (limited to 'src')
| -rw-r--r-- | src/image.c | 1 | ||||
| -rw-r--r-- | src/pgtkterm.c | 91 |
2 files changed, 76 insertions, 16 deletions
diff --git a/src/image.c b/src/image.c index ab61e49f695..b15d68bf9bf 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -766,7 +766,6 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file) | |||
| 766 | ptrdiff_t id, size; | 766 | ptrdiff_t id, size; |
| 767 | int fd, width, height, rc; | 767 | int fd, width, height, rc; |
| 768 | char *contents, *data; | 768 | char *contents, *data; |
| 769 | void *bitmap; | ||
| 770 | 769 | ||
| 771 | if (!STRINGP (image_find_image_fd (file, &fd))) | 770 | if (!STRINGP (image_find_image_fd (file, &fd))) |
| 772 | return -1; | 771 | return -1; |
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 8441189ab8d..72bc636485a 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -53,7 +53,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 53 | #include "termhooks.h" | 53 | #include "termhooks.h" |
| 54 | #include "termopts.h" | 54 | #include "termopts.h" |
| 55 | #include "termchar.h" | 55 | #include "termchar.h" |
| 56 | #include "emacs-icon.h" | ||
| 57 | #include "menu.h" | 56 | #include "menu.h" |
| 58 | #include "window.h" | 57 | #include "window.h" |
| 59 | #include "keyboard.h" | 58 | #include "keyboard.h" |
| @@ -1239,7 +1238,7 @@ pgtk_set_glyph_string_gc (struct glyph_string *s) | |||
| 1239 | line or menu if we don't have X toolkit support. */ | 1238 | line or menu if we don't have X toolkit support. */ |
| 1240 | 1239 | ||
| 1241 | static void | 1240 | static void |
| 1242 | pgtk_set_glyph_string_clipping (struct glyph_string *s, cairo_t * cr) | 1241 | pgtk_set_glyph_string_clipping (struct glyph_string *s, cairo_t *cr) |
| 1243 | { | 1242 | { |
| 1244 | XRectangle r[2]; | 1243 | XRectangle r[2]; |
| 1245 | int n = get_glyph_string_clip_rects (s, r, 2); | 1244 | int n = get_glyph_string_clip_rects (s, r, 2); |
| @@ -1260,7 +1259,7 @@ pgtk_set_glyph_string_clipping (struct glyph_string *s, cairo_t * cr) | |||
| 1260 | 1259 | ||
| 1261 | static void | 1260 | static void |
| 1262 | pgtk_set_glyph_string_clipping_exactly (struct glyph_string *src, | 1261 | pgtk_set_glyph_string_clipping_exactly (struct glyph_string *src, |
| 1263 | struct glyph_string *dst, cairo_t * cr) | 1262 | struct glyph_string *dst, cairo_t *cr) |
| 1264 | { | 1263 | { |
| 1265 | dst->clip[0].x = src->x; | 1264 | dst->clip[0].x = src->x; |
| 1266 | dst->clip[0].y = src->y; | 1265 | dst->clip[0].y = src->y; |
| @@ -2434,6 +2433,73 @@ pgtk_draw_stretch_glyph_string (struct glyph_string *s) | |||
| 2434 | s->background_filled_p = true; | 2433 | s->background_filled_p = true; |
| 2435 | } | 2434 | } |
| 2436 | 2435 | ||
| 2436 | |||
| 2437 | /* Draw a dashed underline of thickness THICKNESS and width WIDTH onto F | ||
| 2438 | at a vertical offset of OFFSET from the position of the glyph string | ||
| 2439 | S, with each segment SEGMENT pixels in length. */ | ||
| 2440 | |||
| 2441 | static void | ||
| 2442 | pgtk_draw_dash (struct frame *f, struct glyph_string *s, | ||
| 2443 | unsigned long foreground, int width, | ||
| 2444 | char segment, int offset, int thickness) | ||
| 2445 | { | ||
| 2446 | cairo_t *cr; | ||
| 2447 | double cr_segment, y_center; | ||
| 2448 | |||
| 2449 | cr = pgtk_begin_cr_clip (s->f); | ||
| 2450 | pgtk_set_cr_source_with_color (f, foreground, false); | ||
| 2451 | cr_segment = (double) segment; | ||
| 2452 | y_center = s->ybase + offset + (thickness / 2.0); | ||
| 2453 | |||
| 2454 | cairo_set_dash (cr, &cr_segment, 1, s->x); | ||
| 2455 | cairo_set_line_width (cr, thickness); | ||
| 2456 | cairo_move_to (cr, s->x, y_center); | ||
| 2457 | cairo_line_to (cr, s->x + width, y_center); | ||
| 2458 | cairo_stroke (cr); | ||
| 2459 | pgtk_end_cr_clip (f); | ||
| 2460 | } | ||
| 2461 | |||
| 2462 | /* Draw an underline of STYLE onto F at an offset of POSITION from the | ||
| 2463 | baseline of the glyph string S in the color provided by FOREGROUND, | ||
| 2464 | DECORATION_WIDTH in length, and THICKNESS in height. */ | ||
| 2465 | |||
| 2466 | static void | ||
| 2467 | pgtk_fill_underline (struct frame *f, struct glyph_string *s, | ||
| 2468 | unsigned long foreground, | ||
| 2469 | enum face_underline_type style, int position, | ||
| 2470 | int decoration_width, int thickness) | ||
| 2471 | { | ||
| 2472 | int segment; | ||
| 2473 | |||
| 2474 | segment = thickness * 3; | ||
| 2475 | |||
| 2476 | switch (style) | ||
| 2477 | { | ||
| 2478 | /* FACE_UNDERLINE_DOUBLE_LINE is treated identically to SINGLE, as | ||
| 2479 | the second line will be filled by another invocation of this | ||
| 2480 | function. */ | ||
| 2481 | case FACE_UNDERLINE_SINGLE: | ||
| 2482 | case FACE_UNDERLINE_DOUBLE_LINE: | ||
| 2483 | pgtk_fill_rectangle (f, foreground, s->x, s->ybase + position, | ||
| 2484 | decoration_width, thickness, false); | ||
| 2485 | break; | ||
| 2486 | |||
| 2487 | case FACE_UNDERLINE_DOTS: | ||
| 2488 | segment = thickness; | ||
| 2489 | FALLTHROUGH; | ||
| 2490 | |||
| 2491 | case FACE_UNDERLINE_DASHES: | ||
| 2492 | pgtk_draw_dash (f, s, foreground, decoration_width, segment, | ||
| 2493 | position, thickness); | ||
| 2494 | break; | ||
| 2495 | |||
| 2496 | case FACE_NO_UNDERLINE: | ||
| 2497 | case FACE_UNDERLINE_WAVE: | ||
| 2498 | default: | ||
| 2499 | emacs_abort (); | ||
| 2500 | } | ||
| 2501 | } | ||
| 2502 | |||
| 2437 | static void | 2503 | static void |
| 2438 | pgtk_draw_glyph_string (struct glyph_string *s) | 2504 | pgtk_draw_glyph_string (struct glyph_string *s) |
| 2439 | { | 2505 | { |
| @@ -2553,17 +2619,14 @@ pgtk_draw_glyph_string (struct glyph_string *s) | |||
| 2553 | else | 2619 | else |
| 2554 | pgtk_draw_underwave (s, s->face->underline_color); | 2620 | pgtk_draw_underwave (s, s->face->underline_color); |
| 2555 | } | 2621 | } |
| 2556 | else if (s->face->underline == FACE_UNDERLINE_SINGLE | 2622 | else if (s->face->underline >= FACE_UNDERLINE_SINGLE) |
| 2557 | || s->face->underline == FACE_UNDERLINE_DOUBLE_LINE) | ||
| 2558 | { | 2623 | { |
| 2559 | unsigned long thickness, position; | 2624 | unsigned long thickness, position; |
| 2560 | int y; | ||
| 2561 | unsigned long foreground; | 2625 | unsigned long foreground; |
| 2562 | 2626 | ||
| 2563 | if (s->prev | 2627 | if (s->prev |
| 2564 | && ((s->prev->face->underline == FACE_UNDERLINE_SINGLE) | 2628 | && (s->prev->face->underline != FACE_UNDERLINE_WAVE |
| 2565 | || (s->prev->face->underline | 2629 | && s->prev->face->underline >= FACE_UNDERLINE_SINGLE) |
| 2566 | == FACE_UNDERLINE_DOUBLE_LINE)) | ||
| 2567 | && (s->prev->face->underline_at_descent_line_p | 2630 | && (s->prev->face->underline_at_descent_line_p |
| 2568 | == s->face->underline_at_descent_line_p) | 2631 | == s->face->underline_at_descent_line_p) |
| 2569 | && (s->prev->face->underline_pixels_above_descent_line | 2632 | && (s->prev->face->underline_pixels_above_descent_line |
| @@ -2619,15 +2682,14 @@ pgtk_draw_glyph_string (struct glyph_string *s) | |||
| 2619 | thickness = (s->y + s->height) - (s->ybase + position); | 2682 | thickness = (s->y + s->height) - (s->ybase + position); |
| 2620 | s->underline_thickness = thickness; | 2683 | s->underline_thickness = thickness; |
| 2621 | s->underline_position = position; | 2684 | s->underline_position = position; |
| 2622 | y = s->ybase + position; | ||
| 2623 | 2685 | ||
| 2624 | if (s->face->underline_defaulted_p) | 2686 | if (s->face->underline_defaulted_p) |
| 2625 | foreground = s->xgcv.foreground; | 2687 | foreground = s->xgcv.foreground; |
| 2626 | else | 2688 | else |
| 2627 | foreground = s->face->underline_color; | 2689 | foreground = s->face->underline_color; |
| 2628 | 2690 | ||
| 2629 | pgtk_fill_rectangle (s->f, foreground, s->x, y, s->width, | 2691 | pgtk_fill_underline (s->f, s, foreground, s->face->underline, |
| 2630 | thickness, false); | 2692 | position, s->width, thickness); |
| 2631 | 2693 | ||
| 2632 | /* Place a second underline above the first if this was | 2694 | /* Place a second underline above the first if this was |
| 2633 | requested in the face specification. */ | 2695 | requested in the face specification. */ |
| @@ -2636,9 +2698,8 @@ pgtk_draw_glyph_string (struct glyph_string *s) | |||
| 2636 | { | 2698 | { |
| 2637 | /* Compute the position of the second underline. */ | 2699 | /* Compute the position of the second underline. */ |
| 2638 | position = position - thickness - 1; | 2700 | position = position - thickness - 1; |
| 2639 | y = s->ybase + position; | 2701 | pgtk_fill_underline (s->f, s, foreground, s->face->underline, |
| 2640 | pgtk_fill_rectangle (s->f, foreground, s->x, y, s->width, | 2702 | position, s->width, thickness); |
| 2641 | thickness, false); | ||
| 2642 | } | 2703 | } |
| 2643 | } | 2704 | } |
| 2644 | } | 2705 | } |