diff options
| author | Elias G. Perez | 2024-05-10 20:36:42 -0600 |
|---|---|---|
| committer | Eli Zaretskii | 2024-06-02 09:35:32 +0300 |
| commit | 48bb25c0e37f8489b06b82a4c32f0c6dcc0856e9 (patch) | |
| tree | 82d030c39adf851221e1d2eb317d2df33b1a86a4 /src | |
| parent | 5ad8ebe6e2808df001255e1f34e8c880e1e57ad4 (diff) | |
| download | emacs-48bb25c0e37f8489b06b82a4c32f0c6dcc0856e9.tar.gz emacs-48bb25c0e37f8489b06b82a4c32f0c6dcc0856e9.zip | |
Stipple support for MS Windows (bug#71159)
* src/w32term.c (w32_fill_stipple_pattern): New function.
(w32_draw_glyph_string_bg_rect w32_draw_stretch_glyph_string)
(w32_draw_glyph_string_background): Use new stipple function.
* src/w32term.h (w32_bitmap_record): Add stipple value.
* src/image.c (image_create_bitmap_from_data): Create stipple
bitmap.
(image_create_bitmap_from_file): Add suuport for pixmap and
create stipple bitmap.
(free_bitmap_record): Release stipple.
* etc/NEWS: Announce support for stipples in MS-Windows.
Diffstat (limited to 'src')
| -rw-r--r-- | src/image.c | 102 | ||||
| -rw-r--r-- | src/w32term.c | 55 | ||||
| -rw-r--r-- | src/w32term.h | 1 |
3 files changed, 121 insertions, 37 deletions
diff --git a/src/image.c b/src/image.c index 3138ef25a63..321073a4fd9 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -130,6 +130,12 @@ typedef struct w32_bitmap_record Bitmap_Record; | |||
| 130 | #define PIX_MASK_RETAIN 0 | 130 | #define PIX_MASK_RETAIN 0 |
| 131 | #define PIX_MASK_DRAW 1 | 131 | #define PIX_MASK_DRAW 1 |
| 132 | 132 | ||
| 133 | #define XBM_BIT_SHUFFLE(b) (~(b)) | ||
| 134 | |||
| 135 | #else | ||
| 136 | |||
| 137 | #define XBM_BIT_SHUFFLE(b) (b) | ||
| 138 | |||
| 133 | #endif /* HAVE_NTGUI */ | 139 | #endif /* HAVE_NTGUI */ |
| 134 | 140 | ||
| 135 | #ifdef HAVE_NS | 141 | #ifdef HAVE_NS |
| @@ -214,6 +220,11 @@ static void free_color_table (void); | |||
| 214 | static unsigned long *colors_in_color_table (int *n); | 220 | static unsigned long *colors_in_color_table (int *n); |
| 215 | #endif | 221 | #endif |
| 216 | 222 | ||
| 223 | #ifdef HAVE_NTGUI | ||
| 224 | static HBITMAP w32_create_pixmap_from_bitmap_data (int, int, char *); | ||
| 225 | |||
| 226 | #endif | ||
| 227 | |||
| 217 | #if defined (HAVE_WEBP) || defined (HAVE_GIF) | 228 | #if defined (HAVE_WEBP) || defined (HAVE_GIF) |
| 218 | static void anim_prune_animation_cache (Lisp_Object); | 229 | static void anim_prune_animation_cache (Lisp_Object); |
| 219 | #endif | 230 | #endif |
| @@ -596,13 +607,31 @@ image_create_bitmap_from_data (struct frame *f, char *bits, | |||
| 596 | #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ | 607 | #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ |
| 597 | 608 | ||
| 598 | #ifdef HAVE_NTGUI | 609 | #ifdef HAVE_NTGUI |
| 599 | Lisp_Object frame UNINIT; /* The value is not used. */ | 610 | Emacs_Pixmap stipple; |
| 600 | Emacs_Pixmap bitmap; | 611 | Emacs_Pixmap bitmap = CreateBitmap (width, height, dpyinfo->n_planes, |
| 601 | bitmap = CreateBitmap (width, height, | 612 | dpyinfo->n_cbits, bits); |
| 602 | FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, | 613 | |
| 603 | FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, | 614 | /* Convert X bitmap to W32 bitmap. */ |
| 604 | bits); | 615 | /* Windows mono bitmaps are reversed compared with X. */ |
| 605 | if (! bitmap) | 616 | USE_SAFE_ALLOCA; |
| 617 | |||
| 618 | { | ||
| 619 | char *invertedBits; | ||
| 620 | int nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height, i; | ||
| 621 | |||
| 622 | invertedBits = bits; | ||
| 623 | |||
| 624 | SAFE_NALLOCA (bits, 1, nbytes); | ||
| 625 | |||
| 626 | for (i = 0; i < nbytes; i++) | ||
| 627 | bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); | ||
| 628 | } | ||
| 629 | |||
| 630 | stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); | ||
| 631 | |||
| 632 | SAFE_FREE (); | ||
| 633 | |||
| 634 | if (!bitmap || !stipple) | ||
| 606 | return -1; | 635 | return -1; |
| 607 | #endif /* HAVE_NTGUI */ | 636 | #endif /* HAVE_NTGUI */ |
| 608 | 637 | ||
| @@ -681,6 +710,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, | |||
| 681 | 710 | ||
| 682 | #ifdef HAVE_NTGUI | 711 | #ifdef HAVE_NTGUI |
| 683 | dpyinfo->bitmaps[id - 1].pixmap = bitmap; | 712 | dpyinfo->bitmaps[id - 1].pixmap = bitmap; |
| 713 | dpyinfo->bitmaps[id - 1].stipple = stipple; | ||
| 684 | dpyinfo->bitmaps[id - 1].hinst = NULL; | 714 | dpyinfo->bitmaps[id - 1].hinst = NULL; |
| 685 | dpyinfo->bitmaps[id - 1].depth = 1; | 715 | dpyinfo->bitmaps[id - 1].depth = 1; |
| 686 | #endif /* HAVE_NTGUI */ | 716 | #endif /* HAVE_NTGUI */ |
| @@ -699,7 +729,7 @@ typedef int image_fd; | |||
| 699 | #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ | 729 | #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ |
| 700 | 730 | ||
| 701 | #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ | 731 | #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ |
| 702 | || defined HAVE_ANDROID | 732 | || defined HAVE_ANDROID || defined HAVE_NTGUI |
| 703 | static char *slurp_file (image_fd, ptrdiff_t *); | 733 | static char *slurp_file (image_fd, ptrdiff_t *); |
| 704 | static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); | 734 | static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); |
| 705 | static bool xbm_read_bitmap_data (struct frame *, char *, char *, | 735 | static bool xbm_read_bitmap_data (struct frame *, char *, char *, |
| @@ -711,10 +741,53 @@ static bool xbm_read_bitmap_data (struct frame *, char *, char *, | |||
| 711 | ptrdiff_t | 741 | ptrdiff_t |
| 712 | image_create_bitmap_from_file (struct frame *f, Lisp_Object file) | 742 | image_create_bitmap_from_file (struct frame *f, Lisp_Object file) |
| 713 | { | 743 | { |
| 714 | #if defined (HAVE_NTGUI) | ||
| 715 | return -1; /* W32_TODO : bitmap support */ | ||
| 716 | #else | ||
| 717 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); | 744 | Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 745 | |||
| 746 | #ifdef HAVE_NTGUI | ||
| 747 | ptrdiff_t id, size; | ||
| 748 | int width, height, rc; | ||
| 749 | image_fd fd; | ||
| 750 | char *contents, *data; | ||
| 751 | Emacs_Pixmap bitmap; | ||
| 752 | |||
| 753 | if (!STRINGP (image_find_image_fd (file, &fd))) | ||
| 754 | return -1; | ||
| 755 | |||
| 756 | contents = slurp_file (fd, &size); | ||
| 757 | |||
| 758 | if (!contents) | ||
| 759 | return -1; | ||
| 760 | |||
| 761 | rc = xbm_read_bitmap_data (f, contents, contents + size, | ||
| 762 | &width, &height, &data, 0); | ||
| 763 | |||
| 764 | if (!rc) | ||
| 765 | { | ||
| 766 | xfree (contents); | ||
| 767 | return -1; | ||
| 768 | } | ||
| 769 | |||
| 770 | { | ||
| 771 | /* Windows mono bitmaps are reversed compared with X. */ | ||
| 772 | |||
| 773 | int nbytes, i; | ||
| 774 | nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; | ||
| 775 | |||
| 776 | for (i = 0; i < nbytes; i++) | ||
| 777 | data[i] = XBM_BIT_SHUFFLE (data[i]); | ||
| 778 | } | ||
| 779 | |||
| 780 | id = image_allocate_bitmap_record (f); | ||
| 781 | bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); | ||
| 782 | |||
| 783 | dpyinfo->bitmaps[id - 1].height = width; | ||
| 784 | dpyinfo->bitmaps[id - 1].width = height; | ||
| 785 | dpyinfo->bitmaps[id - 1].stipple = bitmap; | ||
| 786 | dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); | ||
| 787 | |||
| 788 | xfree (contents); | ||
| 789 | xfree (data); | ||
| 790 | return id; | ||
| 718 | #endif | 791 | #endif |
| 719 | 792 | ||
| 720 | #ifdef HAVE_NS | 793 | #ifdef HAVE_NS |
| @@ -1037,6 +1110,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) | |||
| 1037 | 1110 | ||
| 1038 | #ifdef HAVE_NTGUI | 1111 | #ifdef HAVE_NTGUI |
| 1039 | DeleteObject (bm->pixmap); | 1112 | DeleteObject (bm->pixmap); |
| 1113 | DeleteObject (bm->stipple); | ||
| 1040 | #endif /* HAVE_NTGUI */ | 1114 | #endif /* HAVE_NTGUI */ |
| 1041 | 1115 | ||
| 1042 | #ifdef HAVE_NS | 1116 | #ifdef HAVE_NS |
| @@ -4800,12 +4874,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img, | |||
| 4800 | img->pixmap = new_pixmap; | 4874 | img->pixmap = new_pixmap; |
| 4801 | } | 4875 | } |
| 4802 | 4876 | ||
| 4803 | #define XBM_BIT_SHUFFLE(b) (~(b)) | ||
| 4804 | |||
| 4805 | #else | ||
| 4806 | |||
| 4807 | #define XBM_BIT_SHUFFLE(b) (b) | ||
| 4808 | |||
| 4809 | #endif /* HAVE_NTGUI */ | 4877 | #endif /* HAVE_NTGUI */ |
| 4810 | 4878 | ||
| 4811 | 4879 | ||
diff --git a/src/w32term.c b/src/w32term.c index 2bcd5d86a38..3ef6d0f11f1 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -1248,6 +1248,34 @@ w32_clear_glyph_string_rect (struct glyph_string *s, | |||
| 1248 | real_w, real_h); | 1248 | real_w, real_h); |
| 1249 | } | 1249 | } |
| 1250 | 1250 | ||
| 1251 | /* Fill background with bitmap pattern from S at specified position | ||
| 1252 | given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is | ||
| 1253 | used to get foreground and background color context and HDC where | ||
| 1254 | fill it. */ | ||
| 1255 | |||
| 1256 | static void | ||
| 1257 | w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, | ||
| 1258 | int x, int y, unsigned int width, unsigned int height) | ||
| 1259 | { | ||
| 1260 | SetTextColor (hdc, gc->foreground); | ||
| 1261 | SetBkColor (hdc, gc->background); | ||
| 1262 | |||
| 1263 | RECT r; | ||
| 1264 | Emacs_Pixmap bm; | ||
| 1265 | HBRUSH hb; | ||
| 1266 | |||
| 1267 | r.left = x; | ||
| 1268 | r.top = y; | ||
| 1269 | r.right = x + width; | ||
| 1270 | r.bottom = y + height; | ||
| 1271 | |||
| 1272 | bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; | ||
| 1273 | |||
| 1274 | hb = CreatePatternBrush (bm); | ||
| 1275 | FillRect (hdc, &r, hb); | ||
| 1276 | |||
| 1277 | DeleteObject (hb); | ||
| 1278 | } | ||
| 1251 | 1279 | ||
| 1252 | /* Draw the background of glyph_string S. If S->background_filled_p | 1280 | /* Draw the background of glyph_string S. If S->background_filled_p |
| 1253 | is non-zero don't draw it. FORCE_P non-zero means draw the | 1281 | is non-zero don't draw it. FORCE_P non-zero means draw the |
| @@ -1264,21 +1292,16 @@ w32_draw_glyph_string_background (struct glyph_string *s, bool force_p) | |||
| 1264 | { | 1292 | { |
| 1265 | int box_line_width = max (s->face->box_horizontal_line_width, 0); | 1293 | int box_line_width = max (s->face->box_horizontal_line_width, 0); |
| 1266 | 1294 | ||
| 1267 | #if 0 /* TODO: stipple */ | ||
| 1268 | if (s->stippled_p) | 1295 | if (s->stippled_p) |
| 1269 | { | 1296 | { |
| 1270 | /* Fill background with a stipple pattern. */ | 1297 | /* Fill background with a stipple pattern. */ |
| 1271 | XSetFillStyle (s->display, s->gc, FillOpaqueStippled); | 1298 | w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, |
| 1272 | XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, | 1299 | s->y + box_line_width, |
| 1273 | s->y + box_line_width, | 1300 | s->background_width, |
| 1274 | s->background_width, | 1301 | s->height - 2 * box_line_width); |
| 1275 | s->height - 2 * box_line_width); | ||
| 1276 | XSetFillStyle (s->display, s->gc, FillSolid); | ||
| 1277 | s->background_filled_p = true; | 1302 | s->background_filled_p = true; |
| 1278 | } | 1303 | } |
| 1279 | else | 1304 | else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width |
| 1280 | #endif | ||
| 1281 | if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width | ||
| 1282 | /* When xdisp.c ignores FONT_HEIGHT, we cannot trust | 1305 | /* When xdisp.c ignores FONT_HEIGHT, we cannot trust |
| 1283 | font dimensions, since the actual glyphs might be | 1306 | font dimensions, since the actual glyphs might be |
| 1284 | much smaller. So in that case we always clear the | 1307 | much smaller. So in that case we always clear the |
| @@ -2286,16 +2309,12 @@ w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap) | |||
| 2286 | static void | 2309 | static void |
| 2287 | w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) | 2310 | w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) |
| 2288 | { | 2311 | { |
| 2289 | #if 0 /* TODO: stipple */ | ||
| 2290 | if (s->stippled_p) | 2312 | if (s->stippled_p) |
| 2291 | { | 2313 | { |
| 2292 | /* Fill background with a stipple pattern. */ | 2314 | /* Fill background with a stipple pattern. */ |
| 2293 | XSetFillStyle (s->display, s->gc, FillOpaqueStippled); | 2315 | w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); |
| 2294 | XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); | ||
| 2295 | XSetFillStyle (s->display, s->gc, FillSolid); | ||
| 2296 | } | 2316 | } |
| 2297 | else | 2317 | else |
| 2298 | #endif | ||
| 2299 | w32_clear_glyph_string_rect (s, x, y, w, h); | 2318 | w32_clear_glyph_string_rect (s, x, y, w, h); |
| 2300 | } | 2319 | } |
| 2301 | 2320 | ||
| @@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) | |||
| 2500 | get_glyph_string_clip_rect (s, &r); | 2519 | get_glyph_string_clip_rect (s, &r); |
| 2501 | w32_set_clip_rectangle (hdc, &r); | 2520 | w32_set_clip_rectangle (hdc, &r); |
| 2502 | 2521 | ||
| 2503 | #if 0 /* TODO: stipple */ | ||
| 2504 | if (s->face->stipple) | 2522 | if (s->face->stipple) |
| 2505 | { | 2523 | { |
| 2506 | /* Fill background with a stipple pattern. */ | 2524 | /* Fill background with a stipple pattern. */ |
| 2507 | XSetFillStyle (s->display, gc, FillOpaqueStippled); | 2525 | w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); |
| 2508 | XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); | ||
| 2509 | XSetFillStyle (s->display, gc, FillSolid); | ||
| 2510 | } | 2526 | } |
| 2511 | else | 2527 | else |
| 2512 | #endif | ||
| 2513 | { | 2528 | { |
| 2514 | w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); | 2529 | w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); |
| 2515 | } | 2530 | } |
diff --git a/src/w32term.h b/src/w32term.h index a19be1a9e6a..38eac4230dd 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -58,6 +58,7 @@ struct w32_bitmap_record | |||
| 58 | { | 58 | { |
| 59 | Emacs_Pixmap pixmap; | 59 | Emacs_Pixmap pixmap; |
| 60 | char *file; | 60 | char *file; |
| 61 | Emacs_Pixmap stipple; | ||
| 61 | HINSTANCE hinst; /* Used to load the file */ | 62 | HINSTANCE hinst; /* Used to load the file */ |
| 62 | int refcount; | 63 | int refcount; |
| 63 | /* Record some info about this pixmap. */ | 64 | /* Record some info about this pixmap. */ |