Subject: bug#71159: closed (Re: bug#71159: [PATCH] Stipple support for MS Windows)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 02 Jun 2024 06:38:02 +0000

Your bug report

#71159: [PATCH] Stipple support for MS Windows

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
71159: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=71159
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#71159: [PATCH] Stipple support for MS Windows
From: Eli Zaretskii <[email-masked]>
To: "Elijah G." <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Sun, 02 Jun 2024 09:37:08 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: "Elijah G." <[email-masked]>
> Cc: [email-masked],  [email-masked]
> 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.

Subject: [PATCH] Stipple support for MS Windows
From: "Elijah G." <[email-masked]>
To: [email-masked]
Date: Thu, 23 May 2024 19:27:19 -0600
List-Id: <debbugs-submit.debbugs.gnu.org>

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.

>From da8f1bb3591851c044c8fd7029bbfb9a05f947f1 Mon Sep 17 00:00:00 2001
From: "Elias G. Perez" <[email-masked]>
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