aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Third2020-08-02 20:43:56 +0100
committerAlan Third2020-08-04 20:50:01 +0100
commit519a93e067f459ceddb57573261a52118086b73d (patch)
tree5d3411e476eb7bb4082bfcba925de00d6cbc0659 /src
parent6e70b3793b9cb7730ab8a7132aa6e99f1ca13f98 (diff)
downloademacs-519a93e067f459ceddb57573261a52118086b73d.tar.gz
emacs-519a93e067f459ceddb57573261a52118086b73d.zip
Don't smooth images when scaling up (bug#38394)
* src/image.c (image_set_transform [HAVE_XRENDER]): Use different filter when scaling up vs scaling down. * src/nsimage.m (ns_image_set_smoothing): ([EmacsImage setSmoothing:]): New functions. * src/nsterm.h: Add definitions. * src/nsterm.m (ns_dumpglyphs_image): Disable smoothing if requested.
Diffstat (limited to 'src')
-rw-r--r--src/image.c20
-rw-r--r--src/nsimage.m12
-rw-r--r--src/nsterm.h3
-rw-r--r--src/nsterm.m12
4 files changed, 44 insertions, 3 deletions
diff --git a/src/image.c b/src/image.c
index e7e0a93313b..e236b389210 100644
--- a/src/image.c
+++ b/src/image.c
@@ -259,6 +259,8 @@ cr_put_image_to_cr_data (struct image *img)
259 cairo_matrix_t matrix; 259 cairo_matrix_t matrix;
260 cairo_pattern_get_matrix (img->cr_data, &matrix); 260 cairo_pattern_get_matrix (img->cr_data, &matrix);
261 cairo_pattern_set_matrix (pattern, &matrix); 261 cairo_pattern_set_matrix (pattern, &matrix);
262 cairo_pattern_set_filter
263 (pattern, cairo_pattern_get_filter (img->cr_data));
262 cairo_pattern_destroy (img->cr_data); 264 cairo_pattern_destroy (img->cr_data);
263 } 265 }
264 cairo_surface_destroy (surface); 266 cairo_surface_destroy (surface);
@@ -2114,6 +2116,15 @@ image_set_transform (struct frame *f, struct image *img)
2114 double rotation = 0.0; 2116 double rotation = 0.0;
2115 compute_image_rotation (img, &rotation); 2117 compute_image_rotation (img, &rotation);
2116 2118
2119# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
2120 /* We want scale up operations to use a nearest neighbour filter to
2121 show real pixels instead of munging them, but scale down
2122 operations to use a blended filter, to avoid aliasing and the like.
2123
2124 TODO: implement for Windows. */
2125 bool scale_down = (width < img->width) || (height < img->height);
2126# endif
2127
2117 /* Perform scale transformation. */ 2128 /* Perform scale transformation. */
2118 2129
2119 matrix3x3 matrix 2130 matrix3x3 matrix
@@ -2225,11 +2236,14 @@ image_set_transform (struct frame *f, struct image *img)
2225 /* Under NS the transform is applied to the drawing surface at 2236 /* Under NS the transform is applied to the drawing surface at
2226 drawing time, so store it for later. */ 2237 drawing time, so store it for later. */
2227 ns_image_set_transform (img->pixmap, matrix); 2238 ns_image_set_transform (img->pixmap, matrix);
2239 ns_image_set_smoothing (img->pixmap, scale_down);
2228# elif defined USE_CAIRO 2240# elif defined USE_CAIRO
2229 cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0], 2241 cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0],
2230 matrix[1][1], matrix[2][0], matrix[2][1]}; 2242 matrix[1][1], matrix[2][0], matrix[2][1]};
2231 cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0); 2243 cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0);
2232 cairo_pattern_set_matrix (pattern, &cr_matrix); 2244 cairo_pattern_set_matrix (pattern, &cr_matrix);
2245 cairo_pattern_set_filter (pattern, scale_down
2246 ? CAIRO_FILTER_BEST : CAIRO_FILTER_NEAREST);
2233 /* Dummy solid color pattern just to record pattern matrix. */ 2247 /* Dummy solid color pattern just to record pattern matrix. */
2234 img->cr_data = pattern; 2248 img->cr_data = pattern;
2235# elif defined (HAVE_XRENDER) 2249# elif defined (HAVE_XRENDER)
@@ -2246,14 +2260,14 @@ image_set_transform (struct frame *f, struct image *img)
2246 XDoubleToFixed (matrix[1][2]), 2260 XDoubleToFixed (matrix[1][2]),
2247 XDoubleToFixed (matrix[2][2])}}}; 2261 XDoubleToFixed (matrix[2][2])}}};
2248 2262
2249 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture, FilterBest, 2263 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture,
2250 0, 0); 2264 scale_down ? FilterBest : FilterNearest, 0, 0);
2251 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat); 2265 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat);
2252 2266
2253 if (img->mask_picture) 2267 if (img->mask_picture)
2254 { 2268 {
2255 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture, 2269 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture,
2256 FilterBest, 0, 0); 2270 scale_down ? FilterBest : FilterNearest, 0, 0);
2257 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture, 2271 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture,
2258 &tmat); 2272 &tmat);
2259 } 2273 }
diff --git a/src/nsimage.m b/src/nsimage.m
index 07750de95fe..966e7044f12 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -199,6 +199,12 @@ ns_image_set_transform (void *img, double m[3][3])
199 [(EmacsImage *)img setTransform:m]; 199 [(EmacsImage *)img setTransform:m];
200} 200}
201 201
202void
203ns_image_set_smoothing (void *img, bool smooth)
204{
205 [(EmacsImage *)img setSmoothing:smooth];
206}
207
202unsigned long 208unsigned long
203ns_get_pixel (void *img, int x, int y) 209ns_get_pixel (void *img, int x, int y)
204{ 210{
@@ -591,4 +597,10 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
591 [transform setTransformStruct:tm]; 597 [transform setTransformStruct:tm];
592} 598}
593 599
600- (void)setSmoothing: (BOOL) s
601{
602 smoothing = s;
603}
604
605
594@end 606@end
diff --git a/src/nsterm.h b/src/nsterm.h
index 8d5371c8f24..a511fef5b98 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -640,6 +640,7 @@ typedef id instancetype;
640 unsigned long xbm_fg; 640 unsigned long xbm_fg;
641@public 641@public
642 NSAffineTransform *transform; 642 NSAffineTransform *transform;
643 BOOL smoothing;
643} 644}
644+ (instancetype)allocInitFromFile: (Lisp_Object)file; 645+ (instancetype)allocInitFromFile: (Lisp_Object)file;
645- (void)dealloc; 646- (void)dealloc;
@@ -658,6 +659,7 @@ typedef id instancetype;
658- (Lisp_Object)getMetadata; 659- (Lisp_Object)getMetadata;
659- (BOOL)setFrame: (unsigned int) index; 660- (BOOL)setFrame: (unsigned int) index;
660- (void)setTransform: (double[3][3]) m; 661- (void)setTransform: (double[3][3]) m;
662- (void)setSmoothing: (BOOL)s;
661@end 663@end
662 664
663 665
@@ -1200,6 +1202,7 @@ extern int ns_image_width (void *img);
1200extern int ns_image_height (void *img); 1202extern int ns_image_height (void *img);
1201extern void ns_image_set_size (void *img, int width, int height); 1203extern void ns_image_set_size (void *img, int width, int height);
1202extern void ns_image_set_transform (void *img, double m[3][3]); 1204extern void ns_image_set_transform (void *img, double m[3][3]);
1205extern void ns_image_set_smoothing (void *img, bool smooth);
1203extern unsigned long ns_get_pixel (void *img, int x, int y); 1206extern unsigned long ns_get_pixel (void *img, int x, int y);
1204extern void ns_put_pixel (void *img, int x, int y, unsigned long argb); 1207extern void ns_put_pixel (void *img, int x, int y, unsigned long argb);
1205extern void ns_set_alpha (void *img, int x, int y, unsigned char a); 1208extern void ns_set_alpha (void *img, int x, int y, unsigned char a);
diff --git a/src/nsterm.m b/src/nsterm.m
index df7f716f51e..572b859a982 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4043,10 +4043,22 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
4043 4043
4044 [doTransform concat]; 4044 [doTransform concat];
4045 4045
4046 /* Smoothing is the default, so if we don't want smoothing we
4047 have to turn it off. */
4048 if (! img->smoothing)
4049 [[NSGraphicsContext currentContext]
4050 setImageInterpolation:NSImageInterpolationNone];
4051
4046 [img drawInRect:ir fromRect:ir 4052 [img drawInRect:ir fromRect:ir
4047 operation:NSCompositingOperationSourceOver 4053 operation:NSCompositingOperationSourceOver
4048 fraction:1.0 respectFlipped:YES hints:nil]; 4054 fraction:1.0 respectFlipped:YES hints:nil];
4049 4055
4056 /* Apparently image interpolation is not reset with
4057 restoreGraphicsState, so we have to manually reset it. */
4058 if (! img->smoothing)
4059 [[NSGraphicsContext currentContext]
4060 setImageInterpolation:NSImageInterpolationDefault];
4061
4050 [[NSGraphicsContext currentContext] restoreGraphicsState]; 4062 [[NSGraphicsContext currentContext] restoreGraphicsState];
4051 } 4063 }
4052 4064