aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2019-01-20 17:59:12 +0200
committerEli Zaretskii2019-01-20 17:59:12 +0200
commit67b1053dcd958d21a964dc09c2ba9666e11240b2 (patch)
tree1eb1272130b47d1fa76f095b300a28df7e808a0f
parent551051596fe51d6e232315eeda8a0a79eb43bfdf (diff)
downloademacs-67b1053dcd958d21a964dc09c2ba9666e11240b2.tar.gz
emacs-67b1053dcd958d21a964dc09c2ba9666e11240b2.zip
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.
-rw-r--r--etc/NEWS8
-rw-r--r--src/dispextern.h2
-rw-r--r--src/image.c8
-rw-r--r--src/w32term.c76
4 files changed, 79 insertions, 15 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 9d91a30a583..21187474a28 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1505,8 +1505,12 @@ buffer's 'default-directory' and invoke that file name handler to make
1505the process. That way 'make-process' can start remote processes. 1505the process. That way 'make-process' can start remote processes.
1506 1506
1507+++ 1507+++
1508** Emacs now supports resizing images without ImageMagick on X window 1508** Emacs now supports resizing (scaling) of images without ImageMagick.
1509systems where the XRender extension is available, and on the NS port. 1509All modern systems are supported by this feature. (On GNU and Unix
1510systems, the XRender extension to X11 is required for this to be
1511available; the configure script will test for it and, if found, enable
1512scaling.)
1513
1510The new function 'image-scaling-p' can be used to test whether any 1514The new function 'image-scaling-p' can be used to test whether any
1511given frame supports resizing. 1515given frame supports resizing.
1512 1516
diff --git a/src/dispextern.h b/src/dispextern.h
index 9cea3218c16..894753669d0 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2938,7 +2938,7 @@ struct redisplay_interface
2938 2938
2939#ifdef HAVE_WINDOW_SYSTEM 2939#ifdef HAVE_WINDOW_SYSTEM
2940 2940
2941# if defined HAVE_XRENDER || defined HAVE_NS 2941# if defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI
2942# define HAVE_NATIVE_SCALING 2942# define HAVE_NATIVE_SCALING
2943# endif 2943# endif
2944 2944
diff --git a/src/image.c b/src/image.c
index bcc61dfccda..20148605817 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1900,6 +1900,12 @@ x_set_image_size (struct frame *f, struct image *img)
1900 img->height = height; 1900 img->height = height;
1901 } 1901 }
1902# endif 1902# endif
1903# ifdef HAVE_NTGUI
1904 /* Under HAVE_NTGUI, we will scale the image on the fly, when we
1905 draw it. See w32term.c:x_draw_image_foreground. */
1906 img->width = width;
1907 img->height = height;
1908# endif
1903#endif 1909#endif
1904} 1910}
1905 1911
@@ -9915,7 +9921,7 @@ DEFUN ("image-scaling-p", Fimage_scaling_p, Simage_scaling_p, 0, 1, 0,
9915Return t if FRAME supports native scaling, nil otherwise. */) 9921Return t if FRAME supports native scaling, nil otherwise. */)
9916 (Lisp_Object frame) 9922 (Lisp_Object frame)
9917{ 9923{
9918#ifdef HAVE_NS 9924#if defined (HAVE_NS) || defined (HAVE_NTGUI)
9919 return Qt; 9925 return Qt;
9920#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER) 9926#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
9921 int event_basep, error_basep; 9927 int event_basep, error_basep;
diff --git a/src/w32term.c b/src/w32term.c
index d13763d7db3..6fc86124199 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1874,9 +1874,24 @@ x_draw_image_foreground (struct glyph_string *s)
1874 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground); 1874 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1875 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush); 1875 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
1876 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap); 1876 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1877 LONG orig_width, orig_height;
1878 DIBSECTION dib;
1877 SetBkColor (compat_hdc, RGB (255, 255, 255)); 1879 SetBkColor (compat_hdc, RGB (255, 255, 255));
1878 SetTextColor (s->hdc, RGB (0, 0, 0)); 1880 SetTextColor (s->hdc, RGB (0, 0, 0));
1879 x_set_glyph_string_clipping (s); 1881 x_set_glyph_string_clipping (s);
1882 /* Extract the original dimensions of the bitmap. */
1883 if (GetObject (s->img->pixmap, sizeof (dib), &dib) > 0)
1884 {
1885 BITMAP bmp = dib.dsBm;
1886 orig_width = bmp.bmWidth;
1887 orig_height = bmp.bmHeight;
1888 }
1889 else
1890 {
1891 DebPrint (("x_draw_image_foreground: GetObject failed!\n"));
1892 orig_width = s->slice.width;
1893 orig_height = s->slice.height;
1894 }
1880 1895
1881 if (s->img->mask) 1896 if (s->img->mask)
1882 { 1897 {
@@ -1885,14 +1900,36 @@ x_draw_image_foreground (struct glyph_string *s)
1885 1900
1886 SetTextColor (s->hdc, RGB (255, 255, 255)); 1901 SetTextColor (s->hdc, RGB (255, 255, 255));
1887 SetBkColor (s->hdc, RGB (0, 0, 0)); 1902 SetBkColor (s->hdc, RGB (0, 0, 0));
1888 1903 if (s->slice.width == orig_width && s->slice.height == orig_height)
1889 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1904 {
1890 compat_hdc, s->slice.x, s->slice.y, SRCINVERT); 1905 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1891 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1906 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1892 mask_dc, s->slice.x, s->slice.y, SRCAND); 1907 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1893 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1908 mask_dc, s->slice.x, s->slice.y, SRCAND);
1894 compat_hdc, s->slice.x, s->slice.y, SRCINVERT); 1909 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1895 1910 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1911 }
1912 else
1913 {
1914 int pmode = 0;
1915 /* HALFTONE produces better results, especially when
1916 scaling to a larger size, but Windows 9X doesn't
1917 support HALFTONE. */
1918 if (os_subtype == OS_NT
1919 && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
1920 SetBrushOrgEx (s->hdc, 0, 0, NULL);
1921 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1922 compat_hdc, s->slice.x, s->slice.y,
1923 orig_width, orig_height, SRCINVERT);
1924 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1925 mask_dc, s->slice.x, s->slice.y,
1926 orig_width, orig_height, SRCAND);
1927 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1928 compat_hdc, s->slice.x, s->slice.y,
1929 orig_width, orig_height, SRCINVERT);
1930 if (pmode)
1931 SetStretchBltMode (s->hdc, pmode);
1932 }
1896 SelectObject (mask_dc, mask_orig_obj); 1933 SelectObject (mask_dc, mask_orig_obj);
1897 DeleteDC (mask_dc); 1934 DeleteDC (mask_dc);
1898 } 1935 }
@@ -1900,9 +1937,22 @@ x_draw_image_foreground (struct glyph_string *s)
1900 { 1937 {
1901 SetTextColor (s->hdc, s->gc->foreground); 1938 SetTextColor (s->hdc, s->gc->foreground);
1902 SetBkColor (s->hdc, s->gc->background); 1939 SetBkColor (s->hdc, s->gc->background);
1903 1940 if (s->slice.width == orig_width && s->slice.height == orig_height)
1904 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1941 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1905 compat_hdc, s->slice.x, s->slice.y, SRCCOPY); 1942 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1943 else
1944 {
1945 int pmode = 0;
1946 /* Windows 9X doesn't support HALFTONE. */
1947 if (os_subtype == OS_NT
1948 && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0)
1949 SetBrushOrgEx (s->hdc, 0, 0, NULL);
1950 StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1951 compat_hdc, s->slice.x, s->slice.y,
1952 orig_width, orig_height, SRCCOPY);
1953 if (pmode)
1954 SetStretchBltMode (s->hdc, pmode);
1955 }
1906 1956
1907 /* When the image has a mask, we can expect that at 1957 /* When the image has a mask, we can expect that at
1908 least part of a mouse highlight or a block cursor will 1958 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)
2031 if (s->slice.y == 0) 2081 if (s->slice.y == 0)
2032 y += s->img->vmargin; 2082 y += s->img->vmargin;
2033 2083
2084 /* FIXME (maybe): The below doesn't support image scaling. But it
2085 seems to never be called, because the conditions for its call in
2086 x_draw_image_glyph_string are never fulfilled (they will be if
2087 the #ifdef'ed away part of that function is ever activated). */
2034 if (s->img->pixmap) 2088 if (s->img->pixmap)
2035 { 2089 {
2036 HDC compat_hdc = CreateCompatibleDC (hdc); 2090 HDC compat_hdc = CreateCompatibleDC (hdc);