summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
authorAlan Third <alan@idiocy.org>2019-01-02 21:00:09 +0000
committerAlan Third <alan@idiocy.org>2019-01-10 19:24:20 +0000
commita1b7a3f2a3957a399d6c3c7bcffa07ac67da82fc (patch)
tree478594bd679f2db099fcb6320750f24fcedf5fc6 /src/xterm.c
parentc342b26371480316024e1e5d63cd8b3f035dda69 (diff)
downloademacs-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.c58
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