diff options
| author | Alan Third | 2019-01-02 21:00:09 +0000 |
|---|---|---|
| committer | Alan Third | 2019-01-10 19:24:20 +0000 |
| commit | a1b7a3f2a3957a399d6c3c7bcffa07ac67da82fc (patch) | |
| tree | 478594bd679f2db099fcb6320750f24fcedf5fc6 /src/xterm.c | |
| parent | c342b26371480316024e1e5d63cd8b3f035dda69 (diff) | |
| download | emacs-a1b7a3f2a3957a399d6c3c7bcffa07ac67da82fc.tar.gz emacs-a1b7a3f2a3957a399d6c3c7bcffa07ac67da82fc.zip | |
Add native image scaling (bug#33587)
* configure.ac: Test for XRender outside of xft checks.
* src/Makefile.in (XRENDER_LIBS): List XRender libs separately from
xft libs.
* lisp/image.el (image--get-imagemagick-and-warn): Allow resizing if
native scaling is available.
* src/dispextern.h: Add XRender and image scaling stuff.
(struct image): Add XRender Pictures.
* src/image.c (x_create_bitmap_mask):
(image_create_x_image_and_pixmap): Handle XRender Picture.
(scale_image_size):
(compute_image_size): Make available when any form of scaling is
enabled.
(x_set_image_size): New function.
(lookup_image): Set image size.
(x_create_x_image_and_pixmap): Create XRender Picture when necessary.
(x_put_x_image): Handle the case where desired size != actual size.
(free_image): Free XRender Pictures.
(Fimage_scaling_p): New function.
(syms_of_image): Add image-scaling-p.
* src/nsimage.m (ns_load_image): Remove NS specific resizing.
([EmacsImage setSizeFromSpec:]): Remove method.
(ns_image_set_size): New function.
* src/nsterm.m (ns_draw_fringe_bitmap): Cocoa and GNUstep both have
the same compositing functions, so remove unnecessary difference.
* src/xterm.c (x_composite_image): New function.
(x_draw_image_foreground): Use new x_composite_image function.
* doc/lispref/display.texi (Image Descriptors): Document
image-scaling-p and add resizing descriptors.
(ImageMagick Images): Remove resizing descriptors.
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/xterm.c b/src/xterm.c index e9cebcebba4..fbbf61d320d 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -38,11 +38,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 38 | #include <X11/extensions/Xfixes.h> | 38 | #include <X11/extensions/Xfixes.h> |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | /* Using Xft implies that XRender is available. */ | ||
| 42 | #ifdef HAVE_XFT | ||
| 43 | #include <X11/extensions/Xrender.h> | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #ifdef HAVE_XDBE | 41 | #ifdef HAVE_XDBE |
| 47 | #include <X11/extensions/Xdbe.h> | 42 | #include <X11/extensions/Xdbe.h> |
| 48 | #endif | 43 | #endif |
| @@ -2976,6 +2971,46 @@ x_draw_glyph_string_box (struct glyph_string *s) | |||
| 2976 | } | 2971 | } |
| 2977 | 2972 | ||
| 2978 | 2973 | ||
| 2974 | static void | ||
| 2975 | x_composite_image (struct glyph_string *s, Pixmap dest, | ||
| 2976 | int srcX, int srcY, int dstX, int dstY, | ||
| 2977 | int width, int height) | ||
| 2978 | { | ||
| 2979 | #ifdef HAVE_XRENDER | ||
| 2980 | if (s->img->picture) | ||
| 2981 | { | ||
| 2982 | Picture destination; | ||
| 2983 | XRenderPictFormat *default_format; | ||
| 2984 | XRenderPictureAttributes attr; | ||
| 2985 | |||
| 2986 | /* FIXME: Should we do this each time or would it make sense to | ||
| 2987 | store destination in the frame struct? */ | ||
| 2988 | default_format = XRenderFindVisualFormat (s->display, | ||
| 2989 | DefaultVisual (s->display, 0)); | ||
| 2990 | destination = XRenderCreatePicture (s->display, dest, | ||
| 2991 | default_format, 0, &attr); | ||
| 2992 | |||
| 2993 | /* FIXME: It may make sense to use PictOpSrc instead of | ||
| 2994 | PictOpOver, as I don't know if we care about alpha values too | ||
| 2995 | much here. */ | ||
| 2996 | XRenderComposite (s->display, PictOpOver, | ||
| 2997 | s->img->picture, s->img->mask_picture, destination, | ||
| 2998 | srcX, srcY, | ||
| 2999 | srcX, srcY, | ||
| 3000 | dstX, dstY, | ||
| 3001 | width, height); | ||
| 3002 | |||
| 3003 | XRenderFreePicture (s->display, destination); | ||
| 3004 | } | ||
| 3005 | else | ||
| 3006 | #endif | ||
| 3007 | XCopyArea (s->display, s->img->pixmap, | ||
| 3008 | dest, s->gc, | ||
| 3009 | srcX, srcY, | ||
| 3010 | width, height, dstX, dstY); | ||
| 3011 | } | ||
| 3012 | |||
| 3013 | |||
| 2979 | /* Draw foreground of image glyph string S. */ | 3014 | /* Draw foreground of image glyph string S. */ |
| 2980 | 3015 | ||
| 2981 | static void | 3016 | static void |
| @@ -3007,6 +3042,7 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 3007 | trust on the shape extension to be available | 3042 | trust on the shape extension to be available |
| 3008 | (XShapeCombineRegion). So, compute the rectangle to draw | 3043 | (XShapeCombineRegion). So, compute the rectangle to draw |
| 3009 | manually. */ | 3044 | manually. */ |
| 3045 | /* FIXME: Do we need to do this when using XRender compositing? */ | ||
| 3010 | unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin | 3046 | unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin |
| 3011 | | GCFunction); | 3047 | | GCFunction); |
| 3012 | XGCValues xgcv; | 3048 | XGCValues xgcv; |
| @@ -3024,10 +3060,8 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 3024 | image_rect.width = s->slice.width; | 3060 | image_rect.width = s->slice.width; |
| 3025 | image_rect.height = s->slice.height; | 3061 | image_rect.height = s->slice.height; |
| 3026 | if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) | 3062 | if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) |
| 3027 | XCopyArea (s->display, s->img->pixmap, | 3063 | x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y, |
| 3028 | FRAME_X_DRAWABLE (s->f), s->gc, | 3064 | r.x, r.y, r.width, r.height); |
| 3029 | s->slice.x + r.x - x, s->slice.y + r.y - y, | ||
| 3030 | r.width, r.height, r.x, r.y); | ||
| 3031 | } | 3065 | } |
| 3032 | else | 3066 | else |
| 3033 | { | 3067 | { |
| @@ -3039,10 +3073,8 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 3039 | image_rect.width = s->slice.width; | 3073 | image_rect.width = s->slice.width; |
| 3040 | image_rect.height = s->slice.height; | 3074 | image_rect.height = s->slice.height; |
| 3041 | if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) | 3075 | if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) |
| 3042 | XCopyArea (s->display, s->img->pixmap, | 3076 | x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y, |
| 3043 | FRAME_X_DRAWABLE (s->f), s->gc, | 3077 | r.x, r.y, r.width, r.height); |
| 3044 | s->slice.x + r.x - x, s->slice.y + r.y - y, | ||
| 3045 | r.width, r.height, r.x, r.y); | ||
| 3046 | 3078 | ||
| 3047 | /* When the image has a mask, we can expect that at | 3079 | /* When the image has a mask, we can expect that at |
| 3048 | least part of a mouse highlight or a block cursor will | 3080 | least part of a mouse highlight or a block cursor will |