[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 67b1053: Support native image resizing on MS-Window
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] master 67b1053: Support native image resizing on MS-Windows |
Date: |
Sun, 20 Jan 2019 11:00:20 -0500 (EST) |
branch: master
commit 67b1053dcd958d21a964dc09c2ba9666e11240b2
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
Support native image resizing on MS-Windows
* src/w32term.c (x_draw_image_foreground): Scale the image if
the requested dimensions are different from the bitmap
dimensions.
* src/image.c (Fimage_scaling_p): Return t when HAVE_NTGUI.
(x_set_image_size) [HAVE_NTGUI]: Record the scaled dimensions
in the image struct.
* src/dispextern.h (HAVE_NATIVE_SCALING): Define when
HAVE_NTGUI as well.
* etc/NEWS: Update the announcement of native image scaling.
---
etc/NEWS | 8 ++++--
src/dispextern.h | 2 +-
src/image.c | 8 +++++-
src/w32term.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++--------
4 files changed, 79 insertions(+), 15 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 9d91a30..2118747 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1505,8 +1505,12 @@ buffer's 'default-directory' and invoke that file name
handler to make
the process. That way 'make-process' can start remote processes.
+++
-** Emacs now supports resizing images without ImageMagick on X window
-systems where the XRender extension is available, and on the NS port.
+** Emacs now supports resizing (scaling) of images without ImageMagick.
+All modern systems are supported by this feature. (On GNU and Unix
+systems, the XRender extension to X11 is required for this to be
+available; the configure script will test for it and, if found, enable
+scaling.)
+
The new function 'image-scaling-p' can be used to test whether any
given frame supports resizing.
diff --git a/src/dispextern.h b/src/dispextern.h
index 9cea321..8947536 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2938,7 +2938,7 @@ struct redisplay_interface
#ifdef HAVE_WINDOW_SYSTEM
-# if defined HAVE_XRENDER || defined HAVE_NS
+# if defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI
# define HAVE_NATIVE_SCALING
# endif
diff --git a/src/image.c b/src/image.c
index bcc61df..2014860 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1900,6 +1900,12 @@ x_set_image_size (struct frame *f, struct image *img)
img->height = height;
}
# endif
+# ifdef HAVE_NTGUI
+ /* Under HAVE_NTGUI, we will scale the image on the fly, when we
+ draw it. See w32term.c:x_draw_image_foreground. */
+ img->width = width;
+ img->height = height;
+# endif
#endif
}
@@ -9915,7 +9921,7 @@ DEFUN ("image-scaling-p", Fimage_scaling_p,
Simage_scaling_p, 0, 1, 0,
Return t if FRAME supports native scaling, nil otherwise. */)
(Lisp_Object frame)
{
-#ifdef HAVE_NS
+#if defined (HAVE_NS) || defined (HAVE_NTGUI)
return Qt;
#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
int event_basep, error_basep;
diff --git a/src/w32term.c b/src/w32term.c
index d13763d..6fc8612 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1874,9 +1874,24 @@ x_draw_image_foreground (struct glyph_string *s)
HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
+ LONG orig_width, orig_height;
+ DIBSECTION dib;
SetBkColor (compat_hdc, RGB (255, 255, 255));
SetTextColor (s->hdc, RGB (0, 0, 0));
x_set_glyph_string_clipping (s);
+ /* Extract the original dimensions of the bitmap. */
+ if (GetObject (s->img->pixmap, sizeof (dib), &dib) > 0)
+ {
+ BITMAP bmp = dib.dsBm;
+ orig_width = bmp.bmWidth;
+ orig_height = bmp.bmHeight;
+ }
+ else
+ {
+ DebPrint (("x_draw_image_foreground: GetObject failed!\n"));
+ orig_width = s->slice.width;
+ orig_height = s->slice.height;
+ }
if (s->img->mask)
{
@@ -1885,14 +1900,36 @@ x_draw_image_foreground (struct glyph_string *s)
SetTextColor (s->hdc, RGB (255, 255, 255));
SetBkColor (s->hdc, RGB (0, 0, 0));
-
- BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
- compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
- BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
- mask_dc, s->slice.x, s->slice.y, SRCAND);
- BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
- compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
-
+ if (s->slice.width == orig_width && s->slice.height == orig_height)
+ {
+ BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
+ BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ mask_dc, s->slice.x, s->slice.y, SRCAND);
+ BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
+ }
+ else
+ {
+ int pmode = 0;
+ /* HALFTONE produces better results, especially when
+ scaling to a larger size, but Windows 9X doesn't
+ support HALFTONE. */
+ if (os_subtype == OS_NT
+ && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
+ SetBrushOrgEx (s->hdc, 0, 0, NULL);
+ StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y,
+ orig_width, orig_height, SRCINVERT);
+ StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ mask_dc, s->slice.x, s->slice.y,
+ orig_width, orig_height, SRCAND);
+ StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y,
+ orig_width, orig_height, SRCINVERT);
+ if (pmode)
+ SetStretchBltMode (s->hdc, pmode);
+ }
SelectObject (mask_dc, mask_orig_obj);
DeleteDC (mask_dc);
}
@@ -1900,9 +1937,22 @@ x_draw_image_foreground (struct glyph_string *s)
{
SetTextColor (s->hdc, s->gc->foreground);
SetBkColor (s->hdc, s->gc->background);
-
- BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
- compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
+ if (s->slice.width == orig_width && s->slice.height == orig_height)
+ BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
+ else
+ {
+ int pmode = 0;
+ /* Windows 9X doesn't support HALFTONE. */
+ if (os_subtype == OS_NT
+ && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
+ SetBrushOrgEx (s->hdc, 0, 0, NULL);
+ StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
+ compat_hdc, s->slice.x, s->slice.y,
+ orig_width, orig_height, SRCCOPY);
+ if (pmode)
+ SetStretchBltMode (s->hdc, pmode);
+ }
/* When the image has a mask, we can expect that at
least part of a mouse highlight or a block cursor will
@@ -2031,6 +2081,10 @@ w32_draw_image_foreground_1 (struct glyph_string *s,
HBITMAP pixmap)
if (s->slice.y == 0)
y += s->img->vmargin;
+ /* FIXME (maybe): The below doesn't support image scaling. But it
+ seems to never be called, because the conditions for its call in
+ x_draw_image_glyph_string are never fulfilled (they will be if
+ the #ifdef'ed away part of that function is ever activated). */
if (s->img->pixmap)
{
HDC compat_hdc = CreateCompatibleDC (hdc);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 67b1053: Support native image resizing on MS-Windows,
Eli Zaretskii <=