aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorElias G. Perez2024-05-10 20:36:42 -0600
committerEli Zaretskii2024-06-02 09:35:32 +0300
commit48bb25c0e37f8489b06b82a4c32f0c6dcc0856e9 (patch)
tree82d030c39adf851221e1d2eb317d2df33b1a86a4 /src
parent5ad8ebe6e2808df001255e1f34e8c880e1e57ad4 (diff)
downloademacs-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.c102
-rw-r--r--src/w32term.c55
-rw-r--r--src/w32term.h1
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);
214static unsigned long *colors_in_color_table (int *n); 220static unsigned long *colors_in_color_table (int *n);
215#endif 221#endif
216 222
223#ifdef HAVE_NTGUI
224static 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)
218static void anim_prune_animation_cache (Lisp_Object); 229static 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
703static char *slurp_file (image_fd, ptrdiff_t *); 733static char *slurp_file (image_fd, ptrdiff_t *);
704static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); 734static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *);
705static bool xbm_read_bitmap_data (struct frame *, char *, char *, 735static bool xbm_read_bitmap_data (struct frame *, char *, char *,
@@ -711,10 +741,53 @@ static bool xbm_read_bitmap_data (struct frame *, char *, char *,
711ptrdiff_t 741ptrdiff_t
712image_create_bitmap_from_file (struct frame *f, Lisp_Object file) 742image_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
1256static void
1257w32_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)
2286static void 2309static void
2287w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) 2310w32_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. */