diff options
author | Alan Third <alan@idiocy.org> | 2019-01-02 21:00:09 +0000 |
---|---|---|
committer | Alan Third <alan@idiocy.org> | 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.tar.bz2 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/>. */ #include <X11/extensions/Xfixes.h> #endif -/* Using Xft implies that XRender is available. */ -#ifdef HAVE_XFT -#include <X11/extensions/Xrender.h> -#endif - #ifdef HAVE_XDBE #include <X11/extensions/Xdbe.h> #endif @@ -2976,6 +2971,46 @@ x_draw_glyph_string_box (struct glyph_string *s) } +static void +x_composite_image (struct glyph_string *s, Pixmap dest, + int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ +#ifdef HAVE_XRENDER + if (s->img->picture) + { + Picture destination; + XRenderPictFormat *default_format; + XRenderPictureAttributes attr; + + /* FIXME: Should we do this each time or would it make sense to + store destination in the frame struct? */ + default_format = XRenderFindVisualFormat (s->display, + DefaultVisual (s->display, 0)); + destination = XRenderCreatePicture (s->display, dest, + default_format, 0, &attr); + + /* FIXME: It may make sense to use PictOpSrc instead of + PictOpOver, as I don't know if we care about alpha values too + much here. */ + XRenderComposite (s->display, PictOpOver, + s->img->picture, s->img->mask_picture, destination, + srcX, srcY, + srcX, srcY, + dstX, dstY, + width, height); + + XRenderFreePicture (s->display, destination); + } + else +#endif + XCopyArea (s->display, s->img->pixmap, + dest, s->gc, + srcX, srcY, + width, height, dstX, dstY); +} + + /* Draw foreground of image glyph string S. */ static void @@ -3007,6 +3042,7 @@ x_draw_image_foreground (struct glyph_string *s) trust on the shape extension to be available (XShapeCombineRegion). So, compute the rectangle to draw manually. */ + /* FIXME: Do we need to do this when using XRender compositing? */ unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin | GCFunction); XGCValues xgcv; @@ -3024,10 +3060,8 @@ x_draw_image_foreground (struct glyph_string *s) image_rect.width = s->slice.width; image_rect.height = s->slice.height; if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) - XCopyArea (s->display, s->img->pixmap, - FRAME_X_DRAWABLE (s->f), s->gc, - s->slice.x + r.x - x, s->slice.y + r.y - y, - r.width, r.height, r.x, r.y); + x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y, + r.x, r.y, r.width, r.height); } else { @@ -3039,10 +3073,8 @@ x_draw_image_foreground (struct glyph_string *s) image_rect.width = s->slice.width; image_rect.height = s->slice.height; if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) - XCopyArea (s->display, s->img->pixmap, - FRAME_X_DRAWABLE (s->f), s->gc, - s->slice.x + r.x - x, s->slice.y + r.y - y, - r.width, r.height, r.x, r.y); + x_composite_image (s, FRAME_X_DRAWABLE (s->f), s->slice.x + r.x - x, s->slice.y + r.y - y, + r.x, r.y, r.width, r.height); /* When the image has a mask, we can expect that at least part of a mouse highlight or a block cursor will |