diff options
| author | Cecilio Pardo | 2024-11-04 18:58:40 +0100 |
|---|---|---|
| committer | Eli Zaretskii | 2024-11-05 14:37:07 +0200 |
| commit | 4e8bf2977e6d1abf6d3cf82e9c1ae3dee5bfcda0 (patch) | |
| tree | c52d029ee9f13d91f075bf2b34d0380274955d84 /src | |
| parent | 8a7910fb67e3b89de430d3b3e5009b145ec0c602 (diff) | |
| download | emacs-4e8bf2977e6d1abf6d3cf82e9c1ae3dee5bfcda0.tar.gz emacs-4e8bf2977e6d1abf6d3cf82e9c1ae3dee5bfcda0.zip | |
Support :transform-smoothing on images (MS-Windows) (bug#57166)
* src/dispextern.h (struct image): Add field 'smoothing' for
NTGUI.
* src/image.c (image_set_transform): Assign the 'smoothing'
field of the image struct.
* src/w32gdiplus.h: Add references to more GDI+ functions.
* src/w32image.c (gdiplus_init): Add references to more GDI+
functions.
* src/w32term.c (w32_draw_image_foreground): If the image is
marked for smoothing and GDI+ is available, draw it with GDI+
bilinear interpolation.
* etc/NEWS: New entry for this change.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 1 | ||||
| -rw-r--r-- | src/image.c | 10 | ||||
| -rw-r--r-- | src/w32gdiplus.h | 27 | ||||
| -rw-r--r-- | src/w32image.c | 25 | ||||
| -rw-r--r-- | src/w32term.c | 60 |
5 files changed, 109 insertions, 14 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index cc248a4472e..004eb82d87a 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3172,6 +3172,7 @@ struct image | |||
| 3172 | #endif /* HAVE_ANDROID */ | 3172 | #endif /* HAVE_ANDROID */ |
| 3173 | #ifdef HAVE_NTGUI | 3173 | #ifdef HAVE_NTGUI |
| 3174 | XFORM xform; | 3174 | XFORM xform; |
| 3175 | bool smoothing; | ||
| 3175 | #endif | 3176 | #endif |
| 3176 | #ifdef HAVE_HAIKU | 3177 | #ifdef HAVE_HAIKU |
| 3177 | /* The affine transformation to apply to this image. */ | 3178 | /* The affine transformation to apply to this image. */ |
diff --git a/src/image.c b/src/image.c index 34936977a40..db7f6acd171 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -3049,12 +3049,10 @@ image_set_transform (struct frame *f, struct image *img) | |||
| 3049 | flip = !NILP (image_spec_value (img->spec, QCflip, NULL)); | 3049 | flip = !NILP (image_spec_value (img->spec, QCflip, NULL)); |
| 3050 | 3050 | ||
| 3051 | # if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_HAIKU \ | 3051 | # if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_HAIKU \ |
| 3052 | || defined HAVE_ANDROID | 3052 | || defined HAVE_ANDROID || defined HAVE_NTGUI |
| 3053 | /* We want scale up operations to use a nearest neighbor filter to | 3053 | /* We want scale up operations to use a nearest neighbor filter to |
| 3054 | show real pixels instead of munging them, but scale down | 3054 | show real pixels instead of munging them, but scale down |
| 3055 | operations to use a blended filter, to avoid aliasing and the like. | 3055 | operations to use a blended filter, to avoid aliasing and the like. */ |
| 3056 | |||
| 3057 | TODO: implement for Windows. */ | ||
| 3058 | bool smoothing; | 3056 | bool smoothing; |
| 3059 | Lisp_Object s = image_spec_value (img->spec, QCtransform_smoothing, NULL); | 3057 | Lisp_Object s = image_spec_value (img->spec, QCtransform_smoothing, NULL); |
| 3060 | if (NILP (s)) | 3058 | if (NILP (s)) |
| @@ -3067,6 +3065,10 @@ image_set_transform (struct frame *f, struct image *img) | |||
| 3067 | img->use_bilinear_filtering = smoothing; | 3065 | img->use_bilinear_filtering = smoothing; |
| 3068 | #endif | 3066 | #endif |
| 3069 | 3067 | ||
| 3068 | #ifdef HAVE_NTGUI | ||
| 3069 | img->smoothing = smoothing; | ||
| 3070 | #endif | ||
| 3071 | |||
| 3070 | /* Perform scale transformation. */ | 3072 | /* Perform scale transformation. */ |
| 3071 | 3073 | ||
| 3072 | matrix3x3 matrix | 3074 | matrix3x3 matrix |
diff --git a/src/w32gdiplus.h b/src/w32gdiplus.h index 9d05ae6c190..b438b1a64f8 100644 --- a/src/w32gdiplus.h +++ b/src/w32gdiplus.h | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc) | 2 | typedef GpStatus (WINGDIPAPI *GdiplusStartup_Proc) |
| 3 | (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *); | 3 | (ULONG_PTR *, GdiplusStartupInput *, GdiplusStartupOutput *); |
| 4 | typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR); | 4 | typedef VOID (WINGDIPAPI *GdiplusShutdown_Proc) (ULONG_PTR); |
| 5 | typedef GpStatus (WINGDIPAPI *GdipCreateFromHDC_Proc) | ||
| 6 | (HDC hdc, GpGraphics **graphics); | ||
| 7 | typedef GpStatus (WINGDIPAPI *GdipDeleteGraphics_Proc) (GpGraphics *graphics); | ||
| 5 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc) | 8 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItemSize_Proc) |
| 6 | (GpImage *, PROPID, UINT *); | 9 | (GpImage *, PROPID, UINT *); |
| 7 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc) | 10 | typedef GpStatus (WINGDIPAPI *GdipGetPropertyItem_Proc) |
| @@ -20,6 +23,15 @@ typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromStream_Proc) | |||
| 20 | (IStream *, GpBitmap **); | 23 | (IStream *, GpBitmap **); |
| 21 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromScan0_Proc) | 24 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromScan0_Proc) |
| 22 | (INT, INT, INT, PixelFormat, BYTE*, GpBitmap**); | 25 | (INT, INT, INT, PixelFormat, BYTE*, GpBitmap**); |
| 26 | typedef GpStatus (WINGDIPAPI *GdipCreateBitmapFromHBITMAP_Proc) | ||
| 27 | (HBITMAP hbm, HPALETTE hpal, GpBitmap** bitmap); | ||
| 28 | typedef GpStatus (WINGDIPAPI *GdipSetInterpolationMode_Proc) | ||
| 29 | (GpGraphics *graphics, InterpolationMode interpolationMode); | ||
| 30 | typedef GpStatus (WINGDIPAPI *GdipDrawImageRectRectI_Proc) | ||
| 31 | (GpGraphics *graphics, GpImage *image, INT dstx, INT dsty, INT dstwidth, | ||
| 32 | INT dstheight, INT srcx, INT srcy, INT srcwidth, INT srcheight, | ||
| 33 | GpUnit srcUnit, GDIPCONST GpImageAttributes* imageAttributes, | ||
| 34 | DrawImageAbort callback, VOID * callbackData); | ||
| 23 | typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT); | 35 | typedef IStream * (WINAPI *SHCreateMemStream_Proc) (const BYTE *, UINT); |
| 24 | typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc) | 36 | typedef GpStatus (WINGDIPAPI *GdipCreateHBITMAPFromBitmap_Proc) |
| 25 | (GpBitmap *, HBITMAP *, ARGB); | 37 | (GpBitmap *, HBITMAP *, ARGB); |
| @@ -41,6 +53,8 @@ typedef GpStatus (WINGDIPAPI *GdipImageRotateFlip_Proc) | |||
| 41 | 53 | ||
| 42 | extern GdiplusStartup_Proc fn_GdiplusStartup; | 54 | extern GdiplusStartup_Proc fn_GdiplusStartup; |
| 43 | extern GdiplusShutdown_Proc fn_GdiplusShutdown; | 55 | extern GdiplusShutdown_Proc fn_GdiplusShutdown; |
| 56 | extern GdipCreateFromHDC_Proc fn_GdipCreateFromHDC; | ||
| 57 | extern GdipDeleteGraphics_Proc fn_GdipDeleteGraphics; | ||
| 44 | extern GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; | 58 | extern GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; |
| 45 | extern GdipGetPropertyItem_Proc fn_GdipGetPropertyItem; | 59 | extern GdipGetPropertyItem_Proc fn_GdipGetPropertyItem; |
| 46 | extern GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount; | 60 | extern GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount; |
| @@ -49,6 +63,9 @@ extern GdipImageGetFrameCount_Proc fn_GdipImageGetFrameCount; | |||
| 49 | extern GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; | 63 | extern GdipImageSelectActiveFrame_Proc fn_GdipImageSelectActiveFrame; |
| 50 | extern GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; | 64 | extern GdipCreateBitmapFromFile_Proc fn_GdipCreateBitmapFromFile; |
| 51 | extern GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; | 65 | extern GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; |
| 66 | extern GdipCreateBitmapFromHBITMAP_Proc fn_GdipCreateBitmapFromHBITMAP; | ||
| 67 | extern GdipDrawImageRectRectI_Proc fn_GdipDrawImageRectRectI; | ||
| 68 | extern GdipSetInterpolationMode_Proc fn_GdipSetInterpolationMode; | ||
| 52 | extern GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; | 69 | extern GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; |
| 53 | extern SHCreateMemStream_Proc fn_SHCreateMemStream; | 70 | extern SHCreateMemStream_Proc fn_SHCreateMemStream; |
| 54 | extern GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; | 71 | extern GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; |
| @@ -73,6 +90,11 @@ extern GdipImageRotateFlip_Proc fn_GdipImageRotateFlip; | |||
| 73 | # undef GdipCreateBitmapFromFile | 90 | # undef GdipCreateBitmapFromFile |
| 74 | # undef GdipCreateBitmapFromStream | 91 | # undef GdipCreateBitmapFromStream |
| 75 | # undef GdipCreateBitmapFromScan0 | 92 | # undef GdipCreateBitmapFromScan0 |
| 93 | # undef GdipCreateBitmapFromHBITMAP | ||
| 94 | # undef GdipCreateFromHDC | ||
| 95 | # undef GdipDrawImageRectRectI | ||
| 96 | # undef GdipSetInterpolationMode | ||
| 97 | # undef GdipDeleteGraphics | ||
| 76 | # undef SHCreateMemStream | 98 | # undef SHCreateMemStream |
| 77 | # undef GdipCreateHBITMAPFromBitmap | 99 | # undef GdipCreateHBITMAPFromBitmap |
| 78 | # undef GdipDisposeImage | 100 | # undef GdipDisposeImage |
| @@ -96,6 +118,11 @@ extern GdipImageRotateFlip_Proc fn_GdipImageRotateFlip; | |||
| 96 | # define GdipCreateBitmapFromFile fn_GdipCreateBitmapFromFile | 118 | # define GdipCreateBitmapFromFile fn_GdipCreateBitmapFromFile |
| 97 | # define GdipCreateBitmapFromStream fn_GdipCreateBitmapFromStream | 119 | # define GdipCreateBitmapFromStream fn_GdipCreateBitmapFromStream |
| 98 | # define GdipCreateBitmapFromScan0 fn_GdipCreateBitmapFromScan0 | 120 | # define GdipCreateBitmapFromScan0 fn_GdipCreateBitmapFromScan0 |
| 121 | # define GdipCreateBitmapFromHBITMAP fn_GdipCreateBitmapFromHBITMAP | ||
| 122 | # define GdipCreateFromHDC fn_GdipCreateFromHDC | ||
| 123 | # define GdipDrawImageRectRectI fn_GdipDrawImageRectRectI | ||
| 124 | # define GdipSetInterpolationMode fn_GdipSetInterpolationMode | ||
| 125 | # define GdipDeleteGraphics fn_GdipDeleteGraphics | ||
| 99 | # define SHCreateMemStream fn_SHCreateMemStream | 126 | # define SHCreateMemStream fn_SHCreateMemStream |
| 100 | # define GdipCreateHBITMAPFromBitmap fn_GdipCreateHBITMAPFromBitmap | 127 | # define GdipCreateHBITMAPFromBitmap fn_GdipCreateHBITMAPFromBitmap |
| 101 | # define GdipDisposeImage fn_GdipDisposeImage | 128 | # define GdipDisposeImage fn_GdipDisposeImage |
diff --git a/src/w32image.c b/src/w32image.c index 44eed087528..da4d6843ba9 100644 --- a/src/w32image.c +++ b/src/w32image.c | |||
| @@ -42,6 +42,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 42 | #ifdef WINDOWSNT | 42 | #ifdef WINDOWSNT |
| 43 | GdiplusStartup_Proc fn_GdiplusStartup; | 43 | GdiplusStartup_Proc fn_GdiplusStartup; |
| 44 | GdiplusShutdown_Proc fn_GdiplusShutdown; | 44 | GdiplusShutdown_Proc fn_GdiplusShutdown; |
| 45 | GdipCreateFromHDC_Proc fn_GdipCreateFromHDC; | ||
| 46 | GdipDeleteGraphics_Proc fn_GdipDeleteGraphics; | ||
| 45 | GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; | 47 | GdipGetPropertyItemSize_Proc fn_GdipGetPropertyItemSize; |
| 46 | GdipGetPropertyItem_Proc fn_GdipGetPropertyItem; | 48 | GdipGetPropertyItem_Proc fn_GdipGetPropertyItem; |
| 47 | GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount; | 49 | GdipImageGetFrameDimensionsCount_Proc fn_GdipImageGetFrameDimensionsCount; |
| @@ -53,6 +55,9 @@ GdipCreateBitmapFromStream_Proc fn_GdipCreateBitmapFromStream; | |||
| 53 | GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; | 55 | GdipCreateBitmapFromScan0_Proc fn_GdipCreateBitmapFromScan0; |
| 54 | SHCreateMemStream_Proc fn_SHCreateMemStream; | 56 | SHCreateMemStream_Proc fn_SHCreateMemStream; |
| 55 | GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; | 57 | GdipCreateHBITMAPFromBitmap_Proc fn_GdipCreateHBITMAPFromBitmap; |
| 58 | GdipCreateBitmapFromHBITMAP_Proc fn_GdipCreateBitmapFromHBITMAP; | ||
| 59 | GdipDrawImageRectRectI_Proc fn_GdipDrawImageRectRectI; | ||
| 60 | GdipSetInterpolationMode_Proc fn_GdipSetInterpolationMode; | ||
| 56 | GdipDisposeImage_Proc fn_GdipDisposeImage; | 61 | GdipDisposeImage_Proc fn_GdipDisposeImage; |
| 57 | GdipGetImageHeight_Proc fn_GdipGetImageHeight; | 62 | GdipGetImageHeight_Proc fn_GdipGetImageHeight; |
| 58 | GdipGetImageWidth_Proc fn_GdipGetImageWidth; | 63 | GdipGetImageWidth_Proc fn_GdipGetImageWidth; |
| @@ -80,6 +85,14 @@ gdiplus_init (void) | |||
| 80 | get_proc_addr (gdiplus_lib, "GdiplusShutdown"); | 85 | get_proc_addr (gdiplus_lib, "GdiplusShutdown"); |
| 81 | if (!fn_GdiplusShutdown) | 86 | if (!fn_GdiplusShutdown) |
| 82 | return false; | 87 | return false; |
| 88 | fn_GdipCreateFromHDC = (GdipCreateFromHDC_Proc) | ||
| 89 | get_proc_addr (gdiplus_lib, "GdipCreateFromHDC"); | ||
| 90 | if (!fn_GdipCreateFromHDC) | ||
| 91 | return false; | ||
| 92 | fn_GdipDeleteGraphics = (GdipDeleteGraphics_Proc) | ||
| 93 | get_proc_addr (gdiplus_lib, "GdipDeleteGraphics"); | ||
| 94 | if (!fn_GdipDeleteGraphics) | ||
| 95 | return false; | ||
| 83 | fn_GdipGetPropertyItemSize = (GdipGetPropertyItemSize_Proc) | 96 | fn_GdipGetPropertyItemSize = (GdipGetPropertyItemSize_Proc) |
| 84 | get_proc_addr (gdiplus_lib, "GdipGetPropertyItemSize"); | 97 | get_proc_addr (gdiplus_lib, "GdipGetPropertyItemSize"); |
| 85 | if (!fn_GdipGetPropertyItemSize) | 98 | if (!fn_GdipGetPropertyItemSize) |
| @@ -120,6 +133,18 @@ gdiplus_init (void) | |||
| 120 | get_proc_addr (gdiplus_lib, "GdipCreateHBITMAPFromBitmap"); | 133 | get_proc_addr (gdiplus_lib, "GdipCreateHBITMAPFromBitmap"); |
| 121 | if (!fn_GdipCreateHBITMAPFromBitmap) | 134 | if (!fn_GdipCreateHBITMAPFromBitmap) |
| 122 | return false; | 135 | return false; |
| 136 | fn_GdipCreateBitmapFromHBITMAP = (GdipCreateBitmapFromHBITMAP_Proc) | ||
| 137 | get_proc_addr (gdiplus_lib, "GdipCreateBitmapFromHBITMAP"); | ||
| 138 | if (!fn_GdipCreateBitmapFromHBITMAP) | ||
| 139 | return false; | ||
| 140 | fn_GdipDrawImageRectRectI = (GdipDrawImageRectRectI_Proc) | ||
| 141 | get_proc_addr (gdiplus_lib, "GdipDrawImageRectRectI"); | ||
| 142 | if (!fn_GdipDrawImageRectRectI) | ||
| 143 | return false; | ||
| 144 | fn_GdipSetInterpolationMode = (GdipSetInterpolationMode_Proc) | ||
| 145 | get_proc_addr (gdiplus_lib, "GdipSetInterpolationMode"); | ||
| 146 | if (!fn_GdipSetInterpolationMode) | ||
| 147 | return false; | ||
| 123 | fn_GdipDisposeImage = (GdipDisposeImage_Proc) | 148 | fn_GdipDisposeImage = (GdipDisposeImage_Proc) |
| 124 | get_proc_addr (gdiplus_lib, "GdipDisposeImage"); | 149 | get_proc_addr (gdiplus_lib, "GdipDisposeImage"); |
| 125 | if (!fn_GdipDisposeImage) | 150 | if (!fn_GdipDisposeImage) |
diff --git a/src/w32term.c b/src/w32term.c index 88622700386..e18f39dd2a8 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -24,6 +24,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 24 | #include "blockinput.h" | 24 | #include "blockinput.h" |
| 25 | #include "w32term.h" | 25 | #include "w32term.h" |
| 26 | #include "w32common.h" /* for OS version info */ | 26 | #include "w32common.h" /* for OS version info */ |
| 27 | #include <wtypes.h> | ||
| 28 | #include <gdiplus.h> | ||
| 29 | #include "w32gdiplus.h" | ||
| 27 | 30 | ||
| 28 | #include <ctype.h> | 31 | #include <ctype.h> |
| 29 | #include <errno.h> | 32 | #include <errno.h> |
| @@ -2106,16 +2109,53 @@ w32_draw_image_foreground (struct glyph_string *s) | |||
| 2106 | compat_hdc, s->slice.x, s->slice.y, SRCCOPY); | 2109 | compat_hdc, s->slice.x, s->slice.y, SRCCOPY); |
| 2107 | else | 2110 | else |
| 2108 | { | 2111 | { |
| 2109 | int pmode = 0; | 2112 | #ifdef HAVE_NATIVE_IMAGE_API |
| 2110 | /* Windows 9X doesn't support HALFTONE. */ | 2113 | if (s->img->smoothing && w32_gdiplus_startup ()) |
| 2111 | if (os_subtype == OS_SUBTYPE_NT | 2114 | { |
| 2112 | && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0) | 2115 | GpGraphics *graphics; |
| 2113 | SetBrushOrgEx (s->hdc, 0, 0, NULL); | 2116 | if (GdipCreateFromHDC (s->hdc, &graphics) == Ok) |
| 2114 | StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height, | 2117 | { |
| 2115 | compat_hdc, orig_slice_x, orig_slice_y, | 2118 | GpBitmap *gp_bitmap; |
| 2116 | orig_slice_width, orig_slice_height, SRCCOPY); | 2119 | /* Can't create a GpBitmap from a HBITMAP that was |
| 2117 | if (pmode) | 2120 | ever selected into a DC, so we need to copy. */ |
| 2118 | SetStretchBltMode (s->hdc, pmode); | 2121 | HBITMAP copy |
| 2122 | = CopyImage (GetCurrentObject (compat_hdc, OBJ_BITMAP), | ||
| 2123 | IMAGE_BITMAP, 0, 0, 0); | ||
| 2124 | if (GdipCreateBitmapFromHBITMAP (copy, NULL, | ||
| 2125 | &gp_bitmap) == Ok) | ||
| 2126 | { | ||
| 2127 | GdipSetInterpolationMode (graphics, | ||
| 2128 | InterpolationModeHighQualityBilinear); | ||
| 2129 | GdipDrawImageRectRectI (graphics, | ||
| 2130 | gp_bitmap, x, y, | ||
| 2131 | s->slice.width, | ||
| 2132 | s->slice.height, | ||
| 2133 | orig_slice_x, | ||
| 2134 | orig_slice_y, | ||
| 2135 | orig_slice_width, | ||
| 2136 | orig_slice_height, | ||
| 2137 | UnitPixel, | ||
| 2138 | NULL, NULL, NULL); | ||
| 2139 | GdipDisposeImage (gp_bitmap); | ||
| 2140 | } | ||
| 2141 | DeleteObject (copy); | ||
| 2142 | GdipDeleteGraphics (graphics); | ||
| 2143 | } | ||
| 2144 | } | ||
| 2145 | else | ||
| 2146 | #endif | ||
| 2147 | { | ||
| 2148 | int pmode = 0; | ||
| 2149 | /* Windows 9X doesn't support HALFTONE. */ | ||
| 2150 | if (os_subtype == OS_SUBTYPE_NT | ||
| 2151 | && (pmode = SetStretchBltMode (s->hdc, HALFTONE)) != 0) | ||
| 2152 | SetBrushOrgEx (s->hdc, 0, 0, NULL); | ||
| 2153 | StretchBlt (s->hdc, x, y, s->slice.width, s->slice.height, | ||
| 2154 | compat_hdc, orig_slice_x, orig_slice_y, | ||
| 2155 | orig_slice_width, orig_slice_height, SRCCOPY); | ||
| 2156 | if (pmode) | ||
| 2157 | SetStretchBltMode (s->hdc, pmode); | ||
| 2158 | } | ||
| 2119 | } | 2159 | } |
| 2120 | 2160 | ||
| 2121 | /* When the image has a mask, we can expect that at | 2161 | /* When the image has a mask, we can expect that at |