* bug#71159: [PATCH] Stipple support for MS Windows @ 2024-05-24 1:27 Elijah G. 2024-05-29 23:25 ` Elijah G. 0 siblings, 1 reply; 15+ messages in thread From: Elijah G. @ 2024-05-24 1:27 UTC (permalink / raw) To: 71159 [-- Attachment #1: Type: text/plain, Size: 201 bytes --] This patch add stipple bitmap support to MS Windows. I tested this patch with gnus.xbm file and other stipple pattern from its bitmap data. If anyone have a feedback i would gladly read it. Thanks. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: [PATCH] Stipple support for MS Windows --] [-- Type: text/x-patch, Size: 7603 bytes --] From da8f1bb3591851c044c8fd7029bbfb9a05f947f1 Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" <eg642616@gmail.com> Date: Fri, 10 May 2024 20:36:42 -0600 Subject: [PATCH] Stipple support for MS Windows * src/w32term.h (w32_bitmap_record): Add stipple value. * src/w32term.c: (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_background, w32_draw_glyph_string_bg_rect) (w32_draw_stretch_glyph_string): Use new stipple function. * src/image.c: (image_create_bitmap_from_data): Create stipple bitmap. (image_create_bitmap_from_file): Add suuport for pixmap and create stipple bitmap. --- src/image.c | 56 ++++++++++++++++++++++++++++++++++++++++++++----- src/w32term.c | 58 +++++++++++++++++++++++++++++++++------------------ src/w32term.h | 1 + 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/src/image.c b/src/image.c index e93fc3183af..e2c6b29b332 100644 --- a/src/image.c +++ b/src/image.c @@ -214,6 +214,13 @@ #define n_planes n_image_planes static unsigned long *colors_in_color_table (int *n); #endif +#ifdef HAVE_NTGUI +static HBITMAP w32_create_pixmap_from_bitmap_data (int width, + int height, + char *data); + +#endif + #if defined (HAVE_WEBP) || defined (HAVE_GIF) static void anim_prune_animation_cache (Lisp_Object); #endif @@ -602,7 +609,12 @@ image_create_bitmap_from_data (struct frame *f, char *bits, FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, bits); - if (! bitmap) + Emacs_Pixmap stipple; + + /* Convert X bitmap to W32 bitmap */ + stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); + + if (!bitmap || !stipple) return -1; #endif /* HAVE_NTGUI */ @@ -681,6 +693,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_NTGUI dpyinfo->bitmaps[id - 1].pixmap = bitmap; + dpyinfo->bitmaps[id - 1].stipple = stipple; dpyinfo->bitmaps[id - 1].hinst = NULL; dpyinfo->bitmaps[id - 1].depth = 1; #endif /* HAVE_NTGUI */ @@ -699,7 +712,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ - || defined HAVE_ANDROID + || defined HAVE_ANDROID || defined HAVE_NTGUI static char *slurp_file (image_fd, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -711,10 +724,43 @@ image_create_bitmap_from_data (struct frame *f, char *bits, ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) - return -1; /* W32_TODO : bitmap support */ -#else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); + +#ifdef HAVE_NTGUI + ptrdiff_t id, size; + int width, height, rc; + image_fd fd; + char *contents, *data; + Emacs_Pixmap bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + id = image_allocate_bitmap_record (f); + bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); + + dpyinfo->bitmaps[id - 1].height = width; + dpyinfo->bitmaps[id - 1].width = height; + dpyinfo->bitmaps[id - 1].stipple = bitmap; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); + + xfree (contents); + xfree (data); + return id; #endif #ifdef HAVE_NS diff --git a/src/w32term.c b/src/w32term.c index a9aff304771..b68f0b4e3d6 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1248,6 +1248,37 @@ w32_clear_glyph_string_rect (struct glyph_string *s, real_w, real_h); } +/* Fill background with bitmap pattern from S at specified position + given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is + used to get foreground and background color context and HDC where + fill it. */ + +static void +w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, + int x, int y, unsigned int width, unsigned int height) +{ + /* BUG: stipple bitmap has the inverted colors, inverting + those 2 functions color must fix this. */ + + SetTextColor (hdc, gc->background); + SetBkColor (hdc, gc->foreground); + + Emacs_Pixmap bm; + HBRUSH hb; + RECT r; + + bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; + hb = CreatePatternBrush (bm); + + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + + FillRect (hdc, &r, hb); + + DeleteObject (hb); +} /* Draw the background of glyph_string S. If S->background_filled_p is non-zero don't draw it. FORCE_P non-zero means draw the @@ -1264,21 +1295,16 @@ w32_draw_glyph_string_background (struct glyph_string *s, bool force_p) { int box_line_width = max (s->face->box_horizontal_line_width, 0); -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); s->background_filled_p = true; } - else -#endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be much smaller. So in that case we always clear the @@ -2286,16 +2312,12 @@ w32_draw_image_foreground_1 (struct glyph_string *s, HBITMAP pixmap) static void w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); } else -#endif w32_clear_glyph_string_rect (s, x, y, w, h); } @@ -2500,16 +2522,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); -#if 0 /* TODO: stipple */ if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); } else -#endif { w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); } diff --git a/src/w32term.h b/src/w32term.h index 3120c8bd71f..1eb6a660248 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -58,6 +58,7 @@ #define CP_DEFAULT 1004 { Emacs_Pixmap pixmap; char *file; + Emacs_Pixmap stipple; HINSTANCE hinst; /* Used to load the file */ int refcount; /* Record some info about this pixmap. */ -- 2.44.0.windows.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-05-24 1:27 bug#71159: [PATCH] Stipple support for MS Windows Elijah G. @ 2024-05-29 23:25 ` Elijah G. 2024-05-31 0:12 ` Elijah G. 0 siblings, 1 reply; 15+ messages in thread From: Elijah G. @ 2024-05-29 23:25 UTC (permalink / raw) To: 71159, Eli Zaretskii [-- Attachment #1: Type: text/plain, Size: 81 bytes --] I'm sending here the fixed patch, now there is no problem with fg and bg color. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Stipple-support-for-MS-Windows.patch --] [-- Type: text/x-patch, Size: 9628 bytes --] From e222f44f2677550b107bb1c84fbe63069b81208c Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" <eg642616@gmail.com> Date: Fri, 10 May 2024 20:36:42 -0600 Subject: [PATCH] Stipple support for MS Windows * etc/NEWS: Announce support for stipples in MS-Windows. * src/w32term.h (w32_bitmap_record): Add stipple value. * src/w32term.c: (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_background, w32_draw_glyph_string_bg_rect) (w32_draw_stretch_glyph_string): Use new stipple function. * src/image.c: (image_create_bitmap_from_data): Create stipple bitmap. (image_create_bitmap_from_file): Add suuport for pixmap and create stipple bitmap. --- etc/NEWS | 3 ++ src/image.c | 98 ++++++++++++++++++++++++++++++++++++++++++--------- src/w32term.c | 55 ++++++++++++++++++----------- src/w32term.h | 1 + 4 files changed, 121 insertions(+), 36 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index a79a5844a22..ff1932d42ca 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2779,6 +2779,9 @@ title bars' and scroll bars' appearance. If the new user option will disregard the system's Dark mode and will always use the default Light mode. +--- +*** Emacs on MS-Windows now supports the :stipple face attribute + \f ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/src/image.c b/src/image.c index 3138ef25a63..427b530cb3a 100644 --- a/src/image.c +++ b/src/image.c @@ -130,6 +130,12 @@ #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 +#define XBM_BIT_SHUFFLE(b) (~(b)) + +#else + +#define XBM_BIT_SHUFFLE(b) (b) + #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -214,6 +220,13 @@ #define n_planes n_image_planes static unsigned long *colors_in_color_table (int *n); #endif +#ifdef HAVE_NTGUI +static HBITMAP w32_create_pixmap_from_bitmap_data (int width, + int height, + char *data); + +#endif + #if defined (HAVE_WEBP) || defined (HAVE_GIF) static void anim_prune_animation_cache (Lisp_Object); #endif @@ -596,13 +609,29 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ #ifdef HAVE_NTGUI - Lisp_Object frame UNINIT; /* The value is not used. */ - Emacs_Pixmap bitmap; + Emacs_Pixmap stipple, bitmap; bitmap = CreateBitmap (width, height, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, + dpyinfo->n_planes, + dpyinfo->n_cbits, bits); - if (! bitmap) + + /* Convert X bitmap to W32 bitmap. */ + /* Windows mono bitmaps are reversed compared with X. */ + { + USE_SAFE_ALLOCA; + char *invertedBits; + int nbytes, i; + + invertedBits = bits; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + SAFE_NALLOCA (bits, 1, nbytes); + + for (i = 0; i < nbytes; i++) + bits[i] = XBM_BIT_SHUFFLE(invertedBits[i]); + } + stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); + if (!bitmap || !stipple) return -1; #endif /* HAVE_NTGUI */ @@ -681,6 +710,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_NTGUI dpyinfo->bitmaps[id - 1].pixmap = bitmap; + dpyinfo->bitmaps[id - 1].stipple = stipple; dpyinfo->bitmaps[id - 1].hinst = NULL; dpyinfo->bitmaps[id - 1].depth = 1; #endif /* HAVE_NTGUI */ @@ -699,7 +729,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ - || defined HAVE_ANDROID + || defined HAVE_ANDROID || defined HAVE_NTGUI static char *slurp_file (image_fd, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -711,10 +741,53 @@ image_create_bitmap_from_data (struct frame *f, char *bits, ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) - return -1; /* W32_TODO : bitmap support */ -#else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); + +#ifdef HAVE_NTGUI + ptrdiff_t id, size; + int width, height, rc; + image_fd fd; + char *contents, *data; + Emacs_Pixmap bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + { + /* Windows mono bitmaps are reversed compared with X. */ + + int nbytes, i; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + for (i = 0; i < nbytes; i++) + data[i] = XBM_BIT_SHUFFLE(data[i]); + } + + id = image_allocate_bitmap_record (f); + bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); + + dpyinfo->bitmaps[id - 1].height = width; + dpyinfo->bitmaps[id - 1].width = height; + dpyinfo->bitmaps[id - 1].stipple = bitmap; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); + + xfree (contents); + xfree (data); + return id; #endif #ifdef HAVE_NS @@ -4747,7 +4820,6 @@ w32_create_pixmap_from_bitmap_data (int width, int height, char *data) int i, j, w1, w2; unsigned char *bits, *p; HBITMAP bmp; - w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */ w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */ bits = alloca (height * w2); @@ -4800,12 +4872,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img, img->pixmap = new_pixmap; } -#define XBM_BIT_SHUFFLE(b) (~(b)) - -#else - -#define XBM_BIT_SHUFFLE(b) (b) - #endif /* HAVE_NTGUI */ diff --git a/src/w32term.c b/src/w32term.c index 2bcd5d86a38..8a0cea417ca 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1248,6 +1248,34 @@ w32_clear_glyph_string_rect (struct glyph_string *s, real_w, real_h); } +/* Fill background with bitmap pattern from S at specified position + given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is + used to get foreground and background color context and HDC where + fill it. */ + +static void +w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, + int x, int y, unsigned int width, unsigned int height) +{ + SetTextColor (hdc, gc->foreground); + SetBkColor (hdc, gc->background); + + RECT r; + Emacs_Pixmap bm; + HBRUSH hb + + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + + bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; + + hb = CreatePatternBrush (bm); + FillRect (hdc, &r, hb); + + DeleteObject (hb); +} /* Draw the background of glyph_string S. If S->background_filled_p 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) { int box_line_width = max (s->face->box_horizontal_line_width, 0); -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); s->background_filled_p = true; } - else -#endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be 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) static void w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); } else -#endif w32_clear_glyph_string_rect (s, x, y, w, h); } @@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); -#if 0 /* TODO: stipple */ if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); } else -#endif { w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); } diff --git a/src/w32term.h b/src/w32term.h index 3120c8bd71f..1eb6a660248 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -58,6 +58,7 @@ #define CP_DEFAULT 1004 { Emacs_Pixmap pixmap; char *file; + Emacs_Pixmap stipple; HINSTANCE hinst; /* Used to load the file */ int refcount; /* Record some info about this pixmap. */ -- 2.44.0.windows.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-05-29 23:25 ` Elijah G. @ 2024-05-31 0:12 ` Elijah G. 2024-06-01 14:03 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-01 14:28 ` Eli Zaretskii 0 siblings, 2 replies; 15+ messages in thread From: Elijah G. @ 2024-05-31 0:12 UTC (permalink / raw) To: 71159; +Cc: Eli Zaretskii [-- Attachment #1: Type: text/plain, Size: 116 bytes --] I've updated the patch for delete all the conflicts generated by ae7d0e86b37eabc434c48f85f56df0a221e0e7c7 commit. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Final Patch --] [-- Type: text/x-patch, Size: 9761 bytes --] From e52e8200df7f41b709de892f3789b14fcc994882 Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" <eg642616@gmail.com> Date: Fri, 10 May 2024 20:36:42 -0600 Subject: [PATCH] Stipple support for MS Windows * etc/NEWS: Announce support for stipples in MS-Windows. * src/w32term.h (w32_bitmap_record): Add stipple value. * src/w32term.c: (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_background, w32_draw_glyph_string_bg_rect) (w32_draw_stretch_glyph_string): Use new stipple function. * src/image.c: (image_create_bitmap_from_data): Create stipple bitmap. (image_create_bitmap_from_file): Add suuport for pixmap and create stipple bitmap. --- etc/NEWS | 3 ++ src/image.c | 99 ++++++++++++++++++++++++++++++++++++++++++--------- src/w32term.c | 55 +++++++++++++++++----------- src/w32term.h | 1 + 4 files changed, 122 insertions(+), 36 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 3c672ffed8f..f0aec17371f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2827,6 +2827,9 @@ thumbnail images and show them in the thumbnail buffer. Unlike with using 'convert', this fallback method is synchronous, so Emacs will wait until all the thumbnails are created and displayed, before showing them. +--- +*** Emacs on MS-Windows now supports the :stipple face attribute + \f ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/src/image.c b/src/image.c index 3138ef25a63..941d85d3a0b 100644 --- a/src/image.c +++ b/src/image.c @@ -130,6 +130,12 @@ #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 +#define XBM_BIT_SHUFFLE(b) (~(b)) + +#else + +#define XBM_BIT_SHUFFLE(b) (b) + #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -214,6 +220,13 @@ #define n_planes n_image_planes static unsigned long *colors_in_color_table (int *n); #endif +#ifdef HAVE_NTGUI +static HBITMAP w32_create_pixmap_from_bitmap_data (int width, + int height, + char *data); + +#endif + #if defined (HAVE_WEBP) || defined (HAVE_GIF) static void anim_prune_animation_cache (Lisp_Object); #endif @@ -596,13 +609,30 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ #ifdef HAVE_NTGUI - Lisp_Object frame UNINIT; /* The value is not used. */ - Emacs_Pixmap bitmap; + Emacs_Pixmap stipple, bitmap; bitmap = CreateBitmap (width, height, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, + dpyinfo->n_planes, + dpyinfo->n_cbits, bits); - if (! bitmap) + + /* Convert X bitmap to W32 bitmap. */ + /* Windows mono bitmaps are reversed compared with X. */ + { + char *invertedBits; + int nbytes, i; + ptrdiff_t sa_avail; /* Used only for SAFE_NALLOCA. */ + + invertedBits = bits; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + sa_avail = MAX_ALLOCA + + SAFE_NALLOCA (bits, 1, nbytes); + + for (i = 0; i < nbytes; i++) + bits[i] = XBM_BIT_SHUFFLE(invertedBits[i]); + } + stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); + if (!bitmap || !stipple) return -1; #endif /* HAVE_NTGUI */ @@ -681,6 +711,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_NTGUI dpyinfo->bitmaps[id - 1].pixmap = bitmap; + dpyinfo->bitmaps[id - 1].stipple = stipple; dpyinfo->bitmaps[id - 1].hinst = NULL; dpyinfo->bitmaps[id - 1].depth = 1; #endif /* HAVE_NTGUI */ @@ -699,7 +730,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ - || defined HAVE_ANDROID + || defined HAVE_ANDROID || defined HAVE_NTGUI static char *slurp_file (image_fd, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -711,10 +742,53 @@ image_create_bitmap_from_data (struct frame *f, char *bits, ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) - return -1; /* W32_TODO : bitmap support */ -#else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); + +#ifdef HAVE_NTGUI + ptrdiff_t id, size; + int width, height, rc; + image_fd fd; + char *contents, *data; + Emacs_Pixmap bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + { + /* Windows mono bitmaps are reversed compared with X. */ + + int nbytes, i; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + for (i = 0; i < nbytes; i++) + data[i] = XBM_BIT_SHUFFLE(data[i]); + } + + id = image_allocate_bitmap_record (f); + bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); + + dpyinfo->bitmaps[id - 1].height = width; + dpyinfo->bitmaps[id - 1].width = height; + dpyinfo->bitmaps[id - 1].stipple = bitmap; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); + + xfree (contents); + xfree (data); + return id; #endif #ifdef HAVE_NS @@ -4747,7 +4821,6 @@ w32_create_pixmap_from_bitmap_data (int width, int height, char *data) int i, j, w1, w2; unsigned char *bits, *p; HBITMAP bmp; - w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */ w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */ bits = alloca (height * w2); @@ -4800,12 +4873,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img, img->pixmap = new_pixmap; } -#define XBM_BIT_SHUFFLE(b) (~(b)) - -#else - -#define XBM_BIT_SHUFFLE(b) (b) - #endif /* HAVE_NTGUI */ 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, real_w, real_h); } +/* Fill background with bitmap pattern from S at specified position + given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is + used to get foreground and background color context and HDC where + fill it. */ + +static void +w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, + int x, int y, unsigned int width, unsigned int height) +{ + SetTextColor (hdc, gc->foreground); + SetBkColor (hdc, gc->background); + + RECT r; + Emacs_Pixmap bm; + HBRUSH hb; + + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + + bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; + + hb = CreatePatternBrush (bm); + FillRect (hdc, &r, hb); + + DeleteObject (hb); +} /* Draw the background of glyph_string S. If S->background_filled_p 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) { int box_line_width = max (s->face->box_horizontal_line_width, 0); -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); s->background_filled_p = true; } - else -#endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be 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) static void w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); } else -#endif w32_clear_glyph_string_rect (s, x, y, w, h); } @@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); -#if 0 /* TODO: stipple */ if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); } else -#endif { w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); } 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 @@ #define CP_DEFAULT 1004 { Emacs_Pixmap pixmap; char *file; + Emacs_Pixmap stipple; HINSTANCE hinst; /* Used to load the file */ int refcount; /* Record some info about this pixmap. */ -- 2.44.0.windows.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-05-31 0:12 ` Elijah G. @ 2024-06-01 14:03 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-01 18:54 ` Elijah G. 2024-06-01 14:28 ` Eli Zaretskii 1 sibling, 1 reply; 15+ messages in thread From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-01 14:03 UTC (permalink / raw) To: Elijah G.; +Cc: 71159, Eli Zaretskii "Elijah G." <eg642616@gmail.com> writes: > I've updated the patch for delete all the conflicts generated by > ae7d0e86b37eabc434c48f85f56df0a221e0e7c7 commit. Thank you. Please find several comments below: > * src/w32term.c: > (w32_fill_stipple_pattern): New function. > (w32_draw_glyph_string_background, w32_draw_glyph_string_bg_rect) > (w32_draw_stretch_glyph_string): Use new stipple function. Please delete the redundant colon after the file name. > * src/image.c: > (image_create_bitmap_from_data): Create stipple bitmap. > (image_create_bitmap_from_file): Add suuport for pixmap and create > stipple bitmap. Likewise. This commit message is also excessively wide, and must be filled to remain within 64 columns. > +#ifdef HAVE_NTGUI > +static HBITMAP w32_create_pixmap_from_bitmap_data (int width, > + int height, > + char *data); > + > +#endif It should be aesthetically better if the parameter names were deleted from this declaration's type list, and all of the types placed on one line. > + int nbytes, i; > + ptrdiff_t sa_avail; /* Used only for SAFE_NALLOCA. */ ??? Please insert this boilerplate by means of the `USE_SAFE_ALLOCA' macro. > + invertedBits = bits; > + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; > + sa_avail = MAX_ALLOCA > + > + SAFE_NALLOCA (bits, 1, nbytes); Shouldn't you subsequently call SAFE_FREE? > + for (i = 0; i < nbytes; i++) > + bits[i] = XBM_BIT_SHUFFLE(invertedBits[i]); Absent space between macro name and parameters. > + data[i] = XBM_BIT_SHUFFLE(data[i]); Here also. > + Emacs_Pixmap stipple; Should not the object in this field be released in `free_bitmap_record'? ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-01 14:03 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-01 18:54 ` Elijah G. 2024-06-02 1:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 4:54 ` Eli Zaretskii 0 siblings, 2 replies; 15+ messages in thread From: Elijah G. @ 2024-06-01 18:54 UTC (permalink / raw) To: 71159; +Cc: luangruo, eliz [-- Attachment #1: Type: text/plain, Size: 2255 bytes --] Po Lu via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org> writes: > "Elijah G." <eg642616@gmail.com> writes: > >> I've updated the patch for delete all the conflicts generated by >> ae7d0e86b37eabc434c48f85f56df0a221e0e7c7 commit. > > Thank you. Please find several comments below: > >> * src/w32term.c: >> (w32_fill_stipple_pattern): New function. >> (w32_draw_glyph_string_background, w32_draw_glyph_string_bg_rect) >> (w32_draw_stretch_glyph_string): Use new stipple function. > > Please delete the redundant colon after the file name. > >> * src/image.c: >> (image_create_bitmap_from_data): Create stipple bitmap. >> (image_create_bitmap_from_file): Add suuport for pixmap and create >> stipple bitmap. > > Likewise. This commit message is also excessively wide, and must be > filled to remain within 64 columns. It's now fixed, sorry about that i couldn't find how to insert change-log skeleton or amend with vc.el, those where generated by `diff-add-change-log-entries-other-window'. >> +#ifdef HAVE_NTGUI >> +static HBITMAP w32_create_pixmap_from_bitmap_data (int width, >> + int height, >> + char *data); >> + >> +#endif > > It should be aesthetically better if the parameter names were deleted > from this declaration's type list, and all of the types placed on one > line. Done. >> + int nbytes, i; >> + ptrdiff_t sa_avail; /* Used only for SAFE_NALLOCA. */ > > ??? Please insert this boilerplate by means of the `USE_SAFE_ALLOCA' > macro. > >> + invertedBits = bits; >> + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; >> + sa_avail = MAX_ALLOCA >> + >> + SAFE_NALLOCA (bits, 1, nbytes); > > Shouldn't you subsequently call SAFE_FREE? Thank you, i forgot calling SAFE_FREE, i only defined sa_avail instead using USE_SAFE_ALLOCA because i was getting an unused variable warning. It's now fixed. >> + for (i = 0; i < nbytes; i++) >> + bits[i] = XBM_BIT_SHUFFLE(invertedBits[i]); > > Absent space between macro name and parameters. > >> + data[i] = XBM_BIT_SHUFFLE(data[i]); > > Here also. Done. >> + Emacs_Pixmap stipple; > > Should not the object in this field be released in `free_bitmap_record'? Yes, i forgot about it, it's fixed. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Stipple-support-for-MS-Windows.patch --] [-- Type: text/x-patch, Size: 9602 bytes --] From 6db0266a99dff476eb66ff00b310f650bd3ad0ea Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" <eg642616@gmail.com> Date: Fri, 10 May 2024 20:36:42 -0600 Subject: [PATCH] Stipple support for MS Windows * etc/NEWS: Announce support for stipples in MS-Windows. * src/w32term.h (w32_bitmap_record): Add stipple value. * src/w32term.c (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_background) (w32_draw_glyph_string_bg_rect w32_draw_stretch_glyph_string): Use new stipple function. * 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 | 3 ++ src/image.c | 101 ++++++++++++++++++++++++++++++++++++++++++-------- src/w32term.c | 55 +++++++++++++++++---------- src/w32term.h | 1 + 4 files changed, 125 insertions(+), 35 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 3c672ffed8f..f0aec17371f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2827,6 +2827,9 @@ thumbnail images and show them in the thumbnail buffer. Unlike with using 'convert', this fallback method is synchronous, so Emacs will wait until all the thumbnails are created and displayed, before showing them. +--- +*** Emacs on MS-Windows now supports the :stipple face attribute + \f ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/src/image.c b/src/image.c index 3138ef25a63..42f72780c24 100644 --- a/src/image.c +++ b/src/image.c @@ -130,6 +130,12 @@ #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 +#define XBM_BIT_SHUFFLE(b) (~(b)) + +#else + +#define XBM_BIT_SHUFFLE(b) (b) + #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -214,6 +220,11 @@ #define n_planes n_image_planes static unsigned long *colors_in_color_table (int *n); #endif +#ifdef HAVE_NTGUI +static HBITMAP w32_create_pixmap_from_bitmap_data (int, int, char *); + +#endif + #if defined (HAVE_WEBP) || defined (HAVE_GIF) static void anim_prune_animation_cache (Lisp_Object); #endif @@ -596,13 +607,34 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ #ifdef HAVE_NTGUI - Lisp_Object frame UNINIT; /* The value is not used. */ - Emacs_Pixmap bitmap; + Emacs_Pixmap stipple, bitmap; bitmap = CreateBitmap (width, height, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, + dpyinfo->n_planes, + dpyinfo->n_cbits, bits); - if (! bitmap) + + /* Convert X bitmap to W32 bitmap. */ + /* Windows mono bitmaps are reversed compared with X. */ + USE_SAFE_ALLOCA; + + { + char *invertedBits; + int nbytes, i; + + invertedBits = bits; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + SAFE_NALLOCA (bits, 1, nbytes); + + for (i = 0; i < nbytes; i++) + bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); + } + + stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); + + SAFE_FREE (); + + if (!bitmap || !stipple) return -1; #endif /* HAVE_NTGUI */ @@ -681,6 +713,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_NTGUI dpyinfo->bitmaps[id - 1].pixmap = bitmap; + dpyinfo->bitmaps[id - 1].stipple = stipple; dpyinfo->bitmaps[id - 1].hinst = NULL; dpyinfo->bitmaps[id - 1].depth = 1; #endif /* HAVE_NTGUI */ @@ -699,7 +732,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ - || defined HAVE_ANDROID + || defined HAVE_ANDROID || defined HAVE_NTGUI static char *slurp_file (image_fd, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -711,10 +744,53 @@ image_create_bitmap_from_data (struct frame *f, char *bits, ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) - return -1; /* W32_TODO : bitmap support */ -#else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); + +#ifdef HAVE_NTGUI + ptrdiff_t id, size; + int width, height, rc; + image_fd fd; + char *contents, *data; + Emacs_Pixmap bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + { + /* Windows mono bitmaps are reversed compared with X. */ + + int nbytes, i; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + for (i = 0; i < nbytes; i++) + data[i] = XBM_BIT_SHUFFLE (data[i]); + } + + id = image_allocate_bitmap_record (f); + bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); + + dpyinfo->bitmaps[id - 1].height = width; + dpyinfo->bitmaps[id - 1].width = height; + dpyinfo->bitmaps[id - 1].stipple = bitmap; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); + + xfree (contents); + xfree (data); + return id; #endif #ifdef HAVE_NS @@ -1037,6 +1113,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) #ifdef HAVE_NTGUI DeleteObject (bm->pixmap); + DeleteObject (bm->stipple); #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -4800,12 +4877,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img, img->pixmap = new_pixmap; } -#define XBM_BIT_SHUFFLE(b) (~(b)) - -#else - -#define XBM_BIT_SHUFFLE(b) (b) - #endif /* HAVE_NTGUI */ 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, real_w, real_h); } +/* Fill background with bitmap pattern from S at specified position + given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is + used to get foreground and background color context and HDC where + fill it. */ + +static void +w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, + int x, int y, unsigned int width, unsigned int height) +{ + SetTextColor (hdc, gc->foreground); + SetBkColor (hdc, gc->background); + + RECT r; + Emacs_Pixmap bm; + HBRUSH hb; + + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + + bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; + + hb = CreatePatternBrush (bm); + FillRect (hdc, &r, hb); + + DeleteObject (hb); +} /* Draw the background of glyph_string S. If S->background_filled_p 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) { int box_line_width = max (s->face->box_horizontal_line_width, 0); -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); s->background_filled_p = true; } - else -#endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be 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) static void w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); } else -#endif w32_clear_glyph_string_rect (s, x, y, w, h); } @@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); -#if 0 /* TODO: stipple */ if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); } else -#endif { w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); } 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 @@ #define CP_DEFAULT 1004 { Emacs_Pixmap pixmap; char *file; + Emacs_Pixmap stipple; HINSTANCE hinst; /* Used to load the file */ int refcount; /* Record some info about this pixmap. */ -- 2.44.0.windows.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-01 18:54 ` Elijah G. @ 2024-06-02 1:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 1:40 ` Elijah G. 2024-06-02 4:54 ` Eli Zaretskii 1 sibling, 1 reply; 15+ messages in thread From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 1:34 UTC (permalink / raw) To: Elijah G.; +Cc: 71159, Eli Zaretskii "Elijah G." <eg642616@gmail.com> writes: > Yes, i forgot about it, it's fixed. Have you assigned copyright for this change to the FSF? ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 1:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 1:40 ` Elijah G. 2024-06-02 1:49 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 15+ messages in thread From: Elijah G. @ 2024-06-02 1:40 UTC (permalink / raw) To: Po Lu; +Cc: 71159, Eli Zaretskii Po Lu <luangruo@yahoo.com> writes: > "Elijah G." <eg642616@gmail.com> writes: > >> Yes, i forgot about it, it's fixed. > > Have you assigned copyright for this change to the FSF? Yes, I already have assigned the copyright for my future changes. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 1:40 ` Elijah G. @ 2024-06-02 1:49 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 4:54 ` Eli Zaretskii 0 siblings, 1 reply; 15+ messages in thread From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 1:49 UTC (permalink / raw) To: Elijah G.; +Cc: 71159, Eli Zaretskii "Elijah G." <eg642616@gmail.com> writes: > Po Lu <luangruo@yahoo.com> writes: > >> "Elijah G." <eg642616@gmail.com> writes: >> >>> Yes, i forgot about it, it's fixed. >> >> Have you assigned copyright for this change to the FSF? > > Yes, I already have assigned the copyright for my future changes. Very well. Eli, have you any further objections to this patch, or should I install it now. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 1:49 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 4:54 ` Eli Zaretskii 2024-06-02 7:56 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 15+ messages in thread From: Eli Zaretskii @ 2024-06-02 4:54 UTC (permalink / raw) To: Po Lu; +Cc: 71159, eg642616 > From: Po Lu <luangruo@yahoo.com> > Cc: 71159@debbugs.gnu.org, Eli Zaretskii <eliz@gnu.org> > Date: Sun, 02 Jun 2024 09:49:26 +0800 > > "Elijah G." <eg642616@gmail.com> writes: > > > Po Lu <luangruo@yahoo.com> writes: > > > >> "Elijah G." <eg642616@gmail.com> writes: > >> > >>> Yes, i forgot about it, it's fixed. > >> > >> Have you assigned copyright for this change to the FSF? > > > > Yes, I already have assigned the copyright for my future changes. > > Very well. Eli, have you any further objections to this patch, or > should I install it now. I just sent a few more comments. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 4:54 ` Eli Zaretskii @ 2024-06-02 7:56 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 0 replies; 15+ messages in thread From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 7:56 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 71159, eg642616 Eli Zaretskii <eliz@gnu.org> writes: > I just sent a few more comments. Thanks, everyone. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-01 18:54 ` Elijah G. 2024-06-02 1:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-02 4:54 ` Eli Zaretskii 2024-06-02 5:27 ` Elijah G. 1 sibling, 1 reply; 15+ messages in thread From: Eli Zaretskii @ 2024-06-02 4:54 UTC (permalink / raw) To: Elijah G.; +Cc: luangruo, 71159 > From: "Elijah G." <eg642616@gmail.com> > Cc: Po Lu <luangruo@yahoo.com>, 71159@debbugs.gnu.org, Eli Zaretskii > <eliz@gnu.org> > Date: Sat, 01 Jun 2024 12:54:22 -0600 > > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -2827,6 +2827,9 @@ thumbnail images and show them in the thumbnail buffer. Unlike with > using 'convert', this fallback method is synchronous, so Emacs will wait > until all the thumbnails are created and displayed, before showing them. > > +--- > +*** Emacs on MS-Windows now supports the :stipple face attribute This should end with a period, and :stipple should be quoted as ':stipple'. > + Emacs_Pixmap stipple, bitmap; > bitmap = CreateBitmap (width, height, > - FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, > - FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, > + dpyinfo->n_planes, > + dpyinfo->n_cbits, > bits); Please rewrite this as follows: Emacs_Pixmap stipple; Emacs_Pixmap bitmap = CreateBitmap (width, height, dpyinfo->n_planes, dpyinfo->n_cbits, bits); > + { > + char *invertedBits; > + int nbytes, i; > + > + invertedBits = bits; > + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; Also here, please initialize the local variables where appropriate: { char invertedBits = bits; int nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height, i; Thanks. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 4:54 ` Eli Zaretskii @ 2024-06-02 5:27 ` Elijah G. 2024-06-02 6:37 ` Eli Zaretskii 0 siblings, 1 reply; 15+ messages in thread From: Elijah G. @ 2024-06-02 5:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: luangruo, 71159 [-- Attachment #1: Type: text/plain, Size: 38 bytes --] Thank you, i've fixed now the patch. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Stipple-support-for-MS-Windows.patch --] [-- Type: text/x-patch, Size: 9646 bytes --] From 5b92c1e284bacd4661336228395c751bfe730666 Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" <eg642616@gmail.com> Date: Fri, 10 May 2024 20:36:42 -0600 Subject: [PATCH] Stipple support for MS Windows * etc/NEWS: Announce support for stipples in MS-Windows. * src/w32term.h (w32_bitmap_record): Add stipple value. * src/w32term.c (w32_fill_stipple_pattern): New function. (w32_draw_glyph_string_background) (w32_draw_glyph_string_bg_rect w32_draw_stretch_glyph_string): Use new stipple function. * 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 | 3 ++ src/image.c | 102 +++++++++++++++++++++++++++++++++++++++++--------- src/w32term.c | 55 +++++++++++++++++---------- src/w32term.h | 1 + 4 files changed, 124 insertions(+), 37 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 3c672ffed8f..7106089d6c7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2827,6 +2827,9 @@ thumbnail images and show them in the thumbnail buffer. Unlike with using 'convert', this fallback method is synchronous, so Emacs will wait until all the thumbnails are created and displayed, before showing them. +--- +*** Emacs on MS-Windows now supports the ':stipple' face attribute. + \f ---------------------------------------------------------------------- This file is part of GNU Emacs. 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 @@ #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 +#define XBM_BIT_SHUFFLE(b) (~(b)) + +#else + +#define XBM_BIT_SHUFFLE(b) (b) + #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -214,6 +220,11 @@ #define n_planes n_image_planes static unsigned long *colors_in_color_table (int *n); #endif +#ifdef HAVE_NTGUI +static HBITMAP w32_create_pixmap_from_bitmap_data (int, int, char *); + +#endif + #if defined (HAVE_WEBP) || defined (HAVE_GIF) static void anim_prune_animation_cache (Lisp_Object); #endif @@ -596,13 +607,31 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */ #ifdef HAVE_NTGUI - Lisp_Object frame UNINIT; /* The value is not used. */ - Emacs_Pixmap bitmap; - bitmap = CreateBitmap (width, height, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes, - FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits, - bits); - if (! bitmap) + Emacs_Pixmap stipple; + Emacs_Pixmap bitmap = CreateBitmap (width, height, dpyinfo->n_planes, + dpyinfo->n_cbits, bits); + + /* Convert X bitmap to W32 bitmap. */ + /* Windows mono bitmaps are reversed compared with X. */ + USE_SAFE_ALLOCA; + + { + char *invertedBits; + int nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height, i; + + invertedBits = bits; + + SAFE_NALLOCA (bits, 1, nbytes); + + for (i = 0; i < nbytes; i++) + bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); + } + + stipple = w32_create_pixmap_from_bitmap_data (width, height, bits); + + SAFE_FREE (); + + if (!bitmap || !stipple) return -1; #endif /* HAVE_NTGUI */ @@ -681,6 +710,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #ifdef HAVE_NTGUI dpyinfo->bitmaps[id - 1].pixmap = bitmap; + dpyinfo->bitmaps[id - 1].stipple = stipple; dpyinfo->bitmaps[id - 1].hinst = NULL; dpyinfo->bitmaps[id - 1].depth = 1; #endif /* HAVE_NTGUI */ @@ -699,7 +729,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits, #endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */ #if defined HAVE_HAIKU || defined HAVE_NS || defined HAVE_PGTK \ - || defined HAVE_ANDROID + || defined HAVE_ANDROID || defined HAVE_NTGUI static char *slurp_file (image_fd, ptrdiff_t *); static Lisp_Object image_find_image_fd (Lisp_Object, image_fd *); static bool xbm_read_bitmap_data (struct frame *, char *, char *, @@ -711,10 +741,53 @@ image_create_bitmap_from_data (struct frame *f, char *bits, ptrdiff_t image_create_bitmap_from_file (struct frame *f, Lisp_Object file) { -#if defined (HAVE_NTGUI) - return -1; /* W32_TODO : bitmap support */ -#else Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); + +#ifdef HAVE_NTGUI + ptrdiff_t id, size; + int width, height, rc; + image_fd fd; + char *contents, *data; + Emacs_Pixmap bitmap; + + if (!STRINGP (image_find_image_fd (file, &fd))) + return -1; + + contents = slurp_file (fd, &size); + + if (!contents) + return -1; + + rc = xbm_read_bitmap_data (f, contents, contents + size, + &width, &height, &data, 0); + + if (!rc) + { + xfree (contents); + return -1; + } + + { + /* Windows mono bitmaps are reversed compared with X. */ + + int nbytes, i; + nbytes = (width + CHAR_BIT - 1) / CHAR_BIT * height; + + for (i = 0; i < nbytes; i++) + data[i] = XBM_BIT_SHUFFLE (data[i]); + } + + id = image_allocate_bitmap_record (f); + bitmap = w32_create_pixmap_from_bitmap_data (width, height, data); + + dpyinfo->bitmaps[id - 1].height = width; + dpyinfo->bitmaps[id - 1].width = height; + dpyinfo->bitmaps[id - 1].stipple = bitmap; + dpyinfo->bitmaps[id - 1].file = xlispstrdup (file); + + xfree (contents); + xfree (data); + return id; #endif #ifdef HAVE_NS @@ -1037,6 +1110,7 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm) #ifdef HAVE_NTGUI DeleteObject (bm->pixmap); + DeleteObject (bm->stipple); #endif /* HAVE_NTGUI */ #ifdef HAVE_NS @@ -4800,12 +4874,6 @@ convert_mono_to_color_image (struct frame *f, struct image *img, img->pixmap = new_pixmap; } -#define XBM_BIT_SHUFFLE(b) (~(b)) - -#else - -#define XBM_BIT_SHUFFLE(b) (b) - #endif /* HAVE_NTGUI */ 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, real_w, real_h); } +/* Fill background with bitmap pattern from S at specified position + given by X and Y. WIDTH and HEIGHT specifies bitmap size, GC is + used to get foreground and background color context and HDC where + fill it. */ + +static void +w32_fill_stipple_pattern (HDC hdc, struct glyph_string *s, Emacs_GC *gc, + int x, int y, unsigned int width, unsigned int height) +{ + SetTextColor (hdc, gc->foreground); + SetBkColor (hdc, gc->background); + + RECT r; + Emacs_Pixmap bm; + HBRUSH hb; + + r.left = x; + r.top = y; + r.right = x + width; + r.bottom = y + height; + + bm = FRAME_DISPLAY_INFO (s->f)->bitmaps[s->face->stipple - 1].stipple; + + hb = CreatePatternBrush (bm); + FillRect (hdc, &r, hb); + + DeleteObject (hb); +} /* Draw the background of glyph_string S. If S->background_filled_p 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) { int box_line_width = max (s->face->box_horizontal_line_width, 0); -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, s->x, - s->y + box_line_width, - s->background_width, - s->height - 2 * box_line_width); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, s->x, + s->y + box_line_width, + s->background_width, + s->height - 2 * box_line_width); s->background_filled_p = true; } - else -#endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font dimensions, since the actual glyphs might be 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) static void w32_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) { -#if 0 /* TODO: stipple */ if (s->stippled_p) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, s->gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), s->gc, x, y, w, h); - XSetFillStyle (s->display, s->gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, s->gc, x, y, w, h); } else -#endif w32_clear_glyph_string_rect (s, x, y, w, h); } @@ -2500,16 +2519,12 @@ w32_draw_stretch_glyph_string (struct glyph_string *s) get_glyph_string_clip_rect (s, &r); w32_set_clip_rectangle (hdc, &r); -#if 0 /* TODO: stipple */ if (s->face->stipple) { /* Fill background with a stipple pattern. */ - XSetFillStyle (s->display, gc, FillOpaqueStippled); - XFillRectangle (s->display, FRAME_W32_WINDOW (s->f), gc, x, y, w, h); - XSetFillStyle (s->display, gc, FillSolid); + w32_fill_stipple_pattern (s->hdc, s, gc, x, y, w, h); } else -#endif { w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h); } 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 @@ #define CP_DEFAULT 1004 { Emacs_Pixmap pixmap; char *file; + Emacs_Pixmap stipple; HINSTANCE hinst; /* Used to load the file */ int refcount; /* Record some info about this pixmap. */ -- 2.44.0.windows.1 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-02 5:27 ` Elijah G. @ 2024-06-02 6:37 ` Eli Zaretskii 0 siblings, 0 replies; 15+ messages in thread From: Eli Zaretskii @ 2024-06-02 6:37 UTC (permalink / raw) To: Elijah G.; +Cc: luangruo, 71159-done > From: "Elijah G." <eg642616@gmail.com> > Cc: luangruo@yahoo.com, 71159@debbugs.gnu.org > Date: Sat, 01 Jun 2024 23:27:58 -0600 > > Thank you, i've fixed now the patch. Thanks, installed on the master branch, and closing the bug. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-05-31 0:12 ` Elijah G. 2024-06-01 14:03 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-01 14:28 ` Eli Zaretskii 2024-06-01 19:04 ` Elijah G. 1 sibling, 1 reply; 15+ messages in thread From: Eli Zaretskii @ 2024-06-01 14:28 UTC (permalink / raw) To: Elijah G.; +Cc: 71159 > From: "Elijah G." <eg642616@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org> > Date: Thu, 30 May 2024 18:12:42 -0600 > > I've updated the patch for delete all the conflicts generated by > ae7d0e86b37eabc434c48f85f56df0a221e0e7c7 commit. Thanks, but is this the right patch? It includes a syntax error, which GCC announces like this: image.c: In function 'image_create_bitmap_from_data': image.c:627:26: error: expected ';' before 'do' 627 | sa_avail = MAX_ALLOCA | ^ | ; image.c:623:15: warning: variable 'sa_avail' set but not used [-Wunused-but-set-variable] 623 | ptrdiff_t sa_avail; /* Used only for SAFE_NALLOCA. */ | ^~~~~~~~ Makefile:457: recipe for target `image.o' failed make[2]: *** [image.o] Error 1 I'm guessing that you sent the wrong patch, because you couldn't have built Emacs with this one. So, while the fix is trivial, I haven't installed this, out of fear that other parts might be incorrect. ^ permalink raw reply [flat|nested] 15+ messages in thread
* bug#71159: [PATCH] Stipple support for MS Windows 2024-06-01 14:28 ` Eli Zaretskii @ 2024-06-01 19:04 ` Elijah G. 0 siblings, 0 replies; 15+ messages in thread From: Elijah G. @ 2024-06-01 19:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 71159 Eli Zaretskii <eliz@gnu.org> writes: >> From: "Elijah G." <eg642616@gmail.com> >> Cc: Eli Zaretskii <eliz@gnu.org> >> Date: Thu, 30 May 2024 18:12:42 -0600 >> >> I've updated the patch for delete all the conflicts generated by >> ae7d0e86b37eabc434c48f85f56df0a221e0e7c7 commit. > > Thanks, but is this the right patch? It includes a syntax error, > which GCC announces like this: > > image.c: In function 'image_create_bitmap_from_data': > image.c:627:26: error: expected ';' before 'do' > 627 | sa_avail = MAX_ALLOCA > | ^ > | ; > image.c:623:15: warning: variable 'sa_avail' set but not used [-Wunused-but-set-variable] > 623 | ptrdiff_t sa_avail; /* Used only for SAFE_NALLOCA. */ > | ^~~~~~~~ > Makefile:457: recipe for target `image.o' failed > make[2]: *** [image.o] Error 1 > > I'm guessing that you sent the wrong patch, because you couldn't have > built Emacs with this one. So, while the fix is trivial, I haven't > installed this, out of fear that other parts might be incorrect. I didn't know about that, i think it was an error that i didn't notice when i was generating the patch file, i was having troubles with my local repo. It should now be fixed in the new patch sent. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-06-02 7:56 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-05-24 1:27 bug#71159: [PATCH] Stipple support for MS Windows Elijah G. 2024-05-29 23:25 ` Elijah G. 2024-05-31 0:12 ` Elijah G. 2024-06-01 14:03 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-01 18:54 ` Elijah G. 2024-06-02 1:34 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 1:40 ` Elijah G. 2024-06-02 1:49 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 4:54 ` Eli Zaretskii 2024-06-02 7:56 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors 2024-06-02 4:54 ` Eli Zaretskii 2024-06-02 5:27 ` Elijah G. 2024-06-02 6:37 ` Eli Zaretskii 2024-06-01 14:28 ` Eli Zaretskii 2024-06-01 19:04 ` Elijah G.
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.