diff options
| author | Eli Zaretskii | 2019-01-20 17:59:12 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2019-01-20 17:59:12 +0200 |
| commit | 67b1053dcd958d21a964dc09c2ba9666e11240b2 (patch) | |
| tree | 1eb1272130b47d1fa76f095b300a28df7e808a0f | |
| parent | 551051596fe51d6e232315eeda8a0a79eb43bfdf (diff) | |
| download | emacs-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/NEWS | 8 | ||||
| -rw-r--r-- | src/dispextern.h | 2 | ||||
| -rw-r--r-- | src/image.c | 8 | ||||
| -rw-r--r-- | src/w32term.c | 76 |
4 files changed, 79 insertions, 15 deletions
| @@ -1505,8 +1505,12 @@ buffer's 'default-directory' and invoke that file name handler to make | |||
| 1505 | the process. That way 'make-process' can start remote processes. | 1505 | the 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. |
| 1509 | systems where the XRender extension is available, and on the NS port. | 1509 | All modern systems are supported by this feature. (On GNU and Unix |
| 1510 | systems, the XRender extension to X11 is required for this to be | ||
| 1511 | available; the configure script will test for it and, if found, enable | ||
| 1512 | scaling.) | ||
| 1513 | |||
| 1510 | The new function 'image-scaling-p' can be used to test whether any | 1514 | The new function 'image-scaling-p' can be used to test whether any |
| 1511 | given frame supports resizing. | 1515 | given 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, | |||
| 9915 | Return t if FRAME supports native scaling, nil otherwise. */) | 9921 | Return 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); |