Commit 2755cf18 authored by YAMAMOTO Mitsuharu's avatar YAMAMOTO Mitsuharu

Support native image resizing on cairo

* src/xterm.c (x_cr_draw_image): Add arguments image_width and
image_height and support scaling.  All callers changed.
* src/image.c (Fimage_scaling_p): Return t when USE_CAIRO.
(x_set_image_size) [USE_CAIRO]: Record the scaled dimensions
in the image struct.
* src/dispextern.h (HAVE_NATIVE_SCALING): Define when
USE_CAIRO as well.

* etc/NEWS: Update the announcement of native image scaling.
parent d7e44265
Pipeline #1086 failed with stage
in 53 minutes and 3 seconds
......@@ -1718,9 +1718,9 @@ the process. That way 'make-process' can start remote processes.
+++
** Emacs now supports resizing (scaling) of images without ImageMagick.
All modern systems are supported by this feature. (On GNU and Unix
systems, the XRender extension to X11 is required for this to be
available; the configure script will test for it and, if found, enable
scaling.)
systems, Cairo drawing or the XRender extension to X11 is required for
this to be available; the configure script will test for it and, if
found, enable scaling.)
The new function 'image-scaling-p' can be used to test whether any
given frame supports resizing.
......
......@@ -2938,7 +2938,7 @@ struct redisplay_interface
#ifdef HAVE_WINDOW_SYSTEM
# if defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI
# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI
# define HAVE_NATIVE_SCALING
# endif
......
......@@ -1878,7 +1878,10 @@ x_set_image_size (struct frame *f, struct image *img)
img->height = height;
# endif
# ifdef HAVE_XRENDER
# ifdef USE_CAIRO
img->width = width;
img->height = height;
# elif defined HAVE_XRENDER
if (img->picture)
{
double xscale = img->width / (double) width;
......@@ -9918,7 +9921,7 @@ DEFUN ("image-scaling-p", Fimage_scaling_p, Simage_scaling_p, 0, 1, 0,
Return t if FRAME supports native scaling, nil otherwise. */)
(Lisp_Object frame)
{
#if defined (HAVE_NS) || defined (HAVE_NTGUI)
#if defined (USE_CAIRO) || defined (HAVE_NS) || defined (HAVE_NTGUI)
return Qt;
#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
int event_basep, error_basep;
......
......@@ -480,13 +480,12 @@ x_cr_destroy_fringe_bitmap (int which)
static void
x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
int image_width, int image_height,
int src_x, int src_y, int width, int height,
int dest_x, int dest_y, bool overlay_p)
{
cairo_t *cr;
cairo_format_t format;
cairo_t *cr = x_begin_cr_clip (f, gc);
cr = x_begin_cr_clip (f, gc);
if (overlay_p)
cairo_rectangle (cr, dest_x, dest_y, width, height);
else
......@@ -495,18 +494,33 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
cairo_rectangle (cr, dest_x, dest_y, width, height);
cairo_fill_preserve (cr);
}
format = cairo_image_surface_get_format (image);
int orig_image_width = cairo_image_surface_get_width (image);
if (image_width == 0) image_width = orig_image_width;
int orig_image_height = cairo_image_surface_get_height (image);
if (image_height == 0) image_height = orig_image_height;
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (image);
cairo_matrix_t matrix;
cairo_matrix_init_scale (&matrix, orig_image_width / (double) image_width,
orig_image_height / (double) image_height);
cairo_matrix_translate (&matrix, src_x - dest_x, src_y - dest_y);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_format_t format = cairo_image_surface_get_format (image);
if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
{
cairo_set_source_surface (cr, image, dest_x - src_x, dest_y - src_y);
cairo_set_source (cr, pattern);
cairo_fill (cr);
}
else
{
x_set_cr_source_with_gc_foreground (f, gc);
cairo_clip (cr);
cairo_mask_surface (cr, image, dest_x - src_x, dest_y - src_y);
cairo_mask (cr, pattern);
}
cairo_pattern_destroy (pattern);
x_end_cr_clip (f);
}
......@@ -1430,7 +1444,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
: f->output_data.x->cursor_pixel)
: face->foreground));
XSetBackground (display, gc, face->background);
x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, 0, 0, p->dh,
p->wd, p->h, p->x, p->y, p->overlay_p);
XSetForeground (display, gc, gcv.foreground);
XSetBackground (display, gc, gcv.background);
......@@ -3041,8 +3055,10 @@ x_draw_image_foreground (struct glyph_string *s)
if (s->img->cr_data)
{
x_set_glyph_string_clipping (s);
x_cr_draw_image (s->f, s->gc, s->img->cr_data, s->slice.x, s->slice.y,
s->slice.width, s->slice.height, x, y, true);
x_cr_draw_image (s->f, s->gc,
s->img->cr_data, s->img->width, s->img->height,
s->slice.x, s->slice.y, s->slice.width, s->slice.height,
x, y, true);
if (!s->img->mask)
{
/* When the image has a mask, we can expect that at
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment