aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32term.c
diff options
context:
space:
mode:
authorEli Zaretskii2019-06-29 14:51:41 +0300
committerEli Zaretskii2019-06-29 14:51:41 +0300
commit74a5a332fee8a346cf65ed6656c1b08dc1df5fde (patch)
tree9b6488ab0dccc372c643f5b521e731f26886cfb4 /src/w32term.c
parent67b50770c050c55a26cd13b9568b01a80a449885 (diff)
downloademacs-74a5a332fee8a346cf65ed6656c1b08dc1df5fde.tar.gz
emacs-74a5a332fee8a346cf65ed6656c1b08dc1df5fde.zip
Support native image transforms on MS-Windows
This changeset also rearranges native image transform code for other platforms to make it cleaner, and also removes the support for native cropping. For the discussions, see https://lists.gnu.org/archive/html/emacs-devel/2019-06/msg00242.html * src/w32term.c (w32_image_rotations_p, transform): New functions. (w32_draw_image_foreground): If image rotation is requested and supported, call PlgBlt to transform the image. (w32_initialize): Populate the PlgBlt function pointer if it is supported. * src/w32term.h (w32_image_rotations_p): Add prototype. * src/dispextern.h (struct image) [HAVE_NTGUI]: New member xform. * src/image.c (compute_image_rotation): Renamed from image_set_rotation. Only compute and returns the rotation angle; leave the matrix calculation for later. Log an error message if the :rotation parameter is not a number. (image_set_crop): Function deleted. We no longer support native cropping, as one can display an image slice instead. (image_set_transform): Compute the transform matrix in its entirety here, in two variants: one for XRender and Cairo, the other for NS and MS-Windows. call compute_image_size and compute_image_rotation internally. (lookup_image) [HAVE_NATIVE_TRANSFORMS]: Call only image_set_transform. No need to pass the transform matrix to image_set_transform. (Fimage_transforms_p): Return a list of transform capabilities rather than a simple boolean. Support TTY frames as well. * src/nsimage.m (setTransform:): Don't invert the matrix, as it is already inverted in image.c. * test/manual/image-transforms-tests.el (test-cropping): State in the text that only ImageMagick supports cropping. * doc/lispref/display.texi (Image Descriptors): Update the documentation of native image transforms. (ImageMagick Images): Move the description of ':crop' here. * etc/NEWS: Minor copyedits of the feature announcement.
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c69
1 files changed, 62 insertions, 7 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 97a5fc63892..c6e175e7e5c 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -117,6 +117,10 @@ typedef struct tagGLYPHSET
117/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */ 117/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */
118BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); 118BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
119 119
120/* PlgBlt is available since Windows 2000. */
121BOOL (WINAPI *pfnPlgBlt) (HDC, const POINT *, HDC, int, int, int, int, HBITMAP, int, int);
122
123
120#ifndef LWA_ALPHA 124#ifndef LWA_ALPHA
121#define LWA_ALPHA 0x02 125#define LWA_ALPHA 0x02
122#endif 126#endif
@@ -1753,6 +1757,26 @@ w32_draw_glyph_string_box (struct glyph_string *s)
1753 } 1757 }
1754} 1758}
1755 1759
1760bool
1761w32_image_rotations_p (void)
1762{
1763 return pfnPlgBlt != NULL;
1764}
1765
1766static POINT
1767transform (int x0, int y0, int x, int y, XFORM *xform)
1768{
1769 POINT pt;
1770
1771 /* See https://docs.microsoft.com/en-us/windows/desktop/api/Wingdi/nf-wingdi-setworldtransform */
1772 pt.x =
1773 x0 + (x - x0) * xform->eM11 + (y - y0) * xform->eM21 + xform->eDx + 0.5f;
1774 pt.y =
1775 y0 + (x - x0) * xform->eM12 + (y - y0) * xform->eM22 + xform->eDy + 0.5f;
1776
1777 return pt;
1778}
1779
1756 1780
1757/* Draw foreground of image glyph string S. */ 1781/* Draw foreground of image glyph string S. */
1758 1782
@@ -1798,20 +1822,31 @@ w32_draw_image_foreground (struct glyph_string *s)
1798 } 1822 }
1799 else 1823 else
1800 { 1824 {
1801 DebPrint (("w32_draw_image_foreground: GetObject failed!\n")); 1825 DebPrint (("w32_draw_image_foreground: GetObject(pixmap) failed!\n"));
1802 orig_width = s->slice.width; 1826 orig_width = s->slice.width;
1803 orig_height = s->slice.height; 1827 orig_height = s->slice.height;
1804 } 1828 }
1805 1829
1806 double w_factor = 1.0, h_factor = 1.0; 1830 double w_factor = 1.0, h_factor = 1.0;
1807 bool scaled = false; 1831 bool scaled = false, need_xform = false;
1808 int orig_slice_width = s->slice.width, 1832 int orig_slice_width = s->slice.width,
1809 orig_slice_height = s->slice.height; 1833 orig_slice_height = s->slice.height;
1810 int orig_slice_x = s->slice.x, orig_slice_y = s->slice.y; 1834 int orig_slice_x = s->slice.x, orig_slice_y = s->slice.y;
1811 /* For scaled images we need to restore the original slice's 1835 POINT corner[3];
1812 dimensions and origin coordinates, from before the scaling. */ 1836 if ((s->img->xform.eM12 != 0 || s->img->xform.eM21 != 0
1813 if (s->img->width != orig_width || s->img->height != orig_height) 1837 || s->img->xform.eDx != 0 || s->img->xform.eDy != 0)
1838 /* PlgBlt is not available on Windows 9X. */
1839 && pfnPlgBlt)
1814 { 1840 {
1841 need_xform = true;
1842 corner[0] = transform (x, y, x, y, &s->img->xform);
1843 corner[1] = transform (x, y, x + orig_width, y, &s->img->xform);
1844 corner[2] = transform (x, y, x, y + orig_height, &s->img->xform);
1845 }
1846 else if (s->img->width != orig_width || s->img->height != orig_height)
1847 {
1848 /* For scaled images we need to restore the original slice's
1849 dimensions and origin coordinates, from before the scaling. */
1815 scaled = true; 1850 scaled = true;
1816 w_factor = (double) orig_width / (double) s->img->width; 1851 w_factor = (double) orig_width / (double) s->img->width;
1817 h_factor = (double) orig_height / (double) s->img->height; 1852 h_factor = (double) orig_height / (double) s->img->height;
@@ -1828,7 +1863,15 @@ w32_draw_image_foreground (struct glyph_string *s)
1828 1863
1829 SetTextColor (s->hdc, RGB (255, 255, 255)); 1864 SetTextColor (s->hdc, RGB (255, 255, 255));
1830 SetBkColor (s->hdc, RGB (0, 0, 0)); 1865 SetBkColor (s->hdc, RGB (0, 0, 0));
1831 if (!scaled) 1866 if (need_xform)
1867 {
1868 if (!pfnPlgBlt (s->hdc, corner, compat_hdc,
1869 s->slice.x, s->slice.y,
1870 orig_width, orig_height,
1871 s->img->mask, s->slice.x, s->slice.y))
1872 DebPrint (("PlgBlt failed!"));
1873 }
1874 else if (!scaled)
1832 { 1875 {
1833 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1876 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1834 compat_hdc, s->slice.x, s->slice.y, SRCINVERT); 1877 compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
@@ -1865,7 +1908,14 @@ w32_draw_image_foreground (struct glyph_string *s)
1865 { 1908 {
1866 SetTextColor (s->hdc, s->gc->foreground); 1909 SetTextColor (s->hdc, s->gc->foreground);
1867 SetBkColor (s->hdc, s->gc->background); 1910 SetBkColor (s->hdc, s->gc->background);
1868 if (!scaled) 1911 if (need_xform)
1912 {
1913 if (!pfnPlgBlt (s->hdc, corner, compat_hdc,
1914 s->slice.x, s->slice.y,
1915 orig_width, orig_height, NULL, 0, 0))
1916 DebPrint (("PlgBlt failed!"));
1917 }
1918 else if (!scaled)
1869 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height, 1919 BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1870 compat_hdc, s->slice.x, s->slice.y, SRCCOPY); 1920 compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1871 else 1921 else
@@ -7354,6 +7404,11 @@ w32_initialize (void)
7354 7404
7355 LOAD_PROC (user_lib, SetLayeredWindowAttributes); 7405 LOAD_PROC (user_lib, SetLayeredWindowAttributes);
7356 7406
7407 /* PlgBlt is not available on Windows 9X. */
7408 HMODULE hgdi = LoadLibrary ("gdi32.dll");
7409 if (hgdi)
7410 LOAD_PROC (hgdi, PlgBlt);
7411
7357#undef LOAD_PROC 7412#undef LOAD_PROC
7358 7413
7359 /* Ensure scrollbar handles are at least 5 pixels. */ 7414 /* Ensure scrollbar handles are at least 5 pixels. */