emacs-diffs
[Top][All Lists]
Advanced

[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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]