From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "Elijah G." Newsgroups: gmane.emacs.devel Subject: Re: Stipples support in MS-Windows port Date: Sat, 25 May 2024 18:27:45 -0600 Message-ID: <86cyp9h0xq.fsf@gmail.com> References: <87a5l49a53.fsf@yahoo.com> <87seyw7udp.fsf@yahoo.com> <87wmo0zzni.fsf@yahoo.com> <86r0e83gez.fsf@gnu.org> <861q661vgf.fsf@gmail.com> <86le4dvxx9.fsf@gmail.com> <87frulynby.fsf@yahoo.com> <86zfslctt8.fsf@gmail.com> <86r0dwag4n.fsf@gnu.org> <86r0dww9ne.fsf@gmail.com> <86le43x6ss.fsf@gmail.com> <86o78z8jw2.fsf@gnu.org> <86o78yr45t.fsf@gmail.com> <86h6em1hih.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="13961"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/30.0.50 (windows-nt) Cc: luangruo@yahoo.com, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun May 26 02:28:58 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sB1ku-0003M5-VO for ged-emacs-devel@m.gmane-mx.org; Sun, 26 May 2024 02:28:57 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sB1k1-0008Qa-5K; Sat, 25 May 2024 20:28:01 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sB1jz-0008Ow-Kj for emacs-devel@gnu.org; Sat, 25 May 2024 20:27:59 -0400 Original-Received: from mail-oo1-xc42.google.com ([2607:f8b0:4864:20::c42]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sB1jt-0003Ps-LG; Sat, 25 May 2024 20:27:59 -0400 Original-Received: by mail-oo1-xc42.google.com with SMTP id 006d021491bc7-5b2a2ef4e4cso5575000eaf.0; Sat, 25 May 2024 17:27:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1716683270; x=1717288070; darn=gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=vhiG3bYwncX1PN6/Ec4qHCiPmElk8sOE4WggSUo2MoY=; b=gUCtRkggLjkH3GNct29sgfLUkuHQU78fLdPWdBPA/sA5JlPL0dmMQpctGYdjqrCeBq r36wRbN/QS3KrCi9ObGXavkBPaLZorTJMG8eSXwXUmB/fmhjZTGxm4rHgfhUR0o3r5Rb ocJO04eoAblb0qNZ5xrF2ti2rnUikn8UPy4KWPCWUjQ9egiX8g7zt0Ooq7hzw2Iqf5+D YECffBs7dMr+csdIEV88nJ3xbfGBr0yFB5GeF2lWQertR2Hk49jXirDXtrge6Hs3e9bA MPzQqGBueen9lsrX6a3gEZo/Oq8zcIWN6kq+ntpc9NLUlPnNnJ1c5c7nuzaRPKu9zUVG HQnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716683270; x=1717288070; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=vhiG3bYwncX1PN6/Ec4qHCiPmElk8sOE4WggSUo2MoY=; b=M78n4rfNBD3K+ozXhKv8/E1yF2/AfgNKOHqYz3ptlewVDb3J62v/JYp4OE8y0wqYXP 4WuPc63W+0kpk/cGrkpEmTccKUxcqIJVvxpJA56moPqaw75+6sR41n3mkMcU0oKplagf BwXAD77AASzjjCsn26sRL7X0gnefo0ZSEiPdT1C4S4UVow4nhsF+jbQMlEHkUQD8kNVW C6uP8/jY3R8U6Ea8HXrEjM/JiVzBSIzcn/PtpUA65MJRuNF+Uoget9CZftDPztu8RPpS yA97WS5OmUTWJUlLUkE7FF9X0IichSb/SZMsRH+jcv+xPivHzVB3btghZ7nkWve5jGON SbFQ== X-Forwarded-Encrypted: i=1; AJvYcCVPF/KVX5G5qDQ0QlpYEWRJcnd6gbwxy+m2JK2WIfSCnydAAZUJuo6fTV69IwoDG/UqbAwRWLDBr/9z+oP7jZbilrVH X-Gm-Message-State: AOJu0YyvaKLCFz2lKKgZ8e633wFw9aAy19m3NCYUWFOsuT7zzL6fv2Rx /kigEW3UpT2CCM6TjqA2YU2pA5w4Jqku2LNlr8u6/UpZcBgcFxvl4GeLA7Rn X-Google-Smtp-Source: AGHT+IFrOOUSBgjgspEIB102/qZCgAURjchd9/3oAAVh5PYny+4Xrj27DFiJvB4WLjkhDKjoep5/og== X-Received: by 2002:a4a:7609:0:b0:5b9:70f8:4b64 with SMTP id 006d021491bc7-5b970f851f2mr4726778eaf.8.1716683269942; Sat, 25 May 2024 17:27:49 -0700 (PDT) Original-Received: from LIBERO ([187.184.24.187]) by smtp.gmail.com with ESMTPSA id 006d021491bc7-5b96c4e3019sm973640eaf.27.2024.05.25.17.27.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 25 May 2024 17:27:49 -0700 (PDT) In-Reply-To: <86h6em1hih.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 25 May 2024 10:24:06 +0300") Received-SPF: pass client-ip=2607:f8b0:4864:20::c42; envelope-from=eg642616@gmail.com; helo=mail-oo1-xc42.google.com X-Spam_score_int: 2 X-Spam_score: 0.2 X-Spam_bar: / X-Spam_report: (0.2 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, PDS_OTHER_BAD_TLD=1.999, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_TEMPERROR=0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:319566 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> + /* Convert X bitmap to W32 bitmap */ > ^ > Style: C comments should end in a period and 2 spaces before "*/". Thank you, it's now fixed. >> + 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); >> + printf("%s\n", dpyinfo->bitmaps[id - 1].file); > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > This printf should probably be removed or commented out. It was already removed from the patch that i sent to bug-gnu-emacs (bug#71159). I'm wondering if the patch must be here or to the bug tracker, if should it be sent here i think bug#71159 can be closed. >> +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. */ > > Can we fix this before installing, please? If there are problems with > inverting the colors that you are unsure how to fix, please describe > those problems in detail, so that others could provide advice or code. I would like fix it, but I don't have a clear answer as to why this problem happens, I just left the notice there as a temp solution in case someone comes up with a better solution. I could see that BitBlt maybe can fix this (I've had problems for test it). Also I don't think w32_create_pixmap_from_bitmap_data cause this problem, as far as i could see it's a problem with the bitmap data image_create_bitmap_from_data (struct frame *f, char *bits, ^^^^ (as example this function) One solution that i was thinking is using a kind of inverse-video for make it use fg as bg and vice-versa but I'm not sure how. Also I was thinking in modifying bitmap data with something like this, but i don't have idea how: for (i = 0; i < height; i++) { -- Invert bitmap data-- for (j = 0; j < w1; j++) { -- Invert bitmap data-- } } > Finally, this change needs a NEWS entry, in the "Changes in Emacs 30.1 > on Non-Free Operating Systems" section. Done. >> I would like if someone else can test it for see if there are any >> issues. > > Please suggest how to test this. Sure, after apply patch and build Emacs, i open runemacs.exe with -Q, inside the scratch-buffer i paste these code snippets and eval them: (let* ((w (window-font-width)) (stipple `(,w 1 ,(apply #'unibyte-string (append (make-list (1- (/ (+ w 7) 8)) ?\0) '(1)))))) (insert "\n" (propertize (concat (make-string 15 ?\s) "THIS IS A TEST" (make-string 15 ?\s)) 'face `(:background "red" :foreground "blue" :stipple ,stipple)))) The first makes a stipple with blue lines with a red background. (let ((str "foobar")) (make-face 'foo) (set-face-stipple 'foo (list 2 2 (string 1 2))) (put-text-property 0 3 'face 'foo str) (insert str)) This one makes a chess board-like stipple. font-lock-mode must be disabled for make this work. Also i use this for test xbm files, in my case i use gnus.xbm file from etc/images/gnus/: (set-face-attribute 'region nil :stipple "path/to/xbm/file") This set a stipple attribute to region face. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Stipple-support-for-MS-Windows.patch >From 1fefedc98ad2e6cd214c14e26a94188beb444d5c Mon Sep 17 00:00:00 2001 From: "Elias G. Perez" 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 | 56 ++++++++++++++++++++++++++++++++++++++++++++----- src/w32term.c | 58 +++++++++++++++++++++++++++++++++------------------ src/w32term.h | 1 + 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index a79a5844a22..3f9145ba582 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. ++++ +*** Support for stipples. + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/src/image.c b/src/image.c index 3138ef25a63..f062e8e4475 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 2bcd5d86a38..900f33f3ede 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 --=-=-=--