aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-03-27 11:04:46 +0900
committerYAMAMOTO Mitsuharu2019-03-27 11:12:18 +0900
commit2755cf1848b551436b9cc2eff6e4b882b10c07aa (patch)
tree0c496f95796f8417f69b5221412162763d1ef4bb /src
parentd7e442651777805958bd6bcbc8312a6cce147e4a (diff)
downloademacs-2755cf1848b551436b9cc2eff6e4b882b10c07aa.tar.gz
emacs-2755cf1848b551436b9cc2eff6e4b882b10c07aa.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h2
-rw-r--r--src/image.c7
-rw-r--r--src/xterm.c34
3 files changed, 31 insertions, 12 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 4d96e51d73b..1a536563532 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2938,7 +2938,7 @@ struct redisplay_interface
2938 2938
2939#ifdef HAVE_WINDOW_SYSTEM 2939#ifdef HAVE_WINDOW_SYSTEM
2940 2940
2941# if defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI 2941# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS || defined HAVE_NTGUI
2942# define HAVE_NATIVE_SCALING 2942# define HAVE_NATIVE_SCALING
2943# endif 2943# endif
2944 2944
diff --git a/src/image.c b/src/image.c
index 16c5978db6e..6e415ef1f70 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1878,7 +1878,10 @@ x_set_image_size (struct frame *f, struct image *img)
1878 img->height = height; 1878 img->height = height;
1879# endif 1879# endif
1880 1880
1881# ifdef HAVE_XRENDER 1881# ifdef USE_CAIRO
1882 img->width = width;
1883 img->height = height;
1884# elif defined HAVE_XRENDER
1882 if (img->picture) 1885 if (img->picture)
1883 { 1886 {
1884 double xscale = img->width / (double) width; 1887 double xscale = img->width / (double) width;
@@ -9918,7 +9921,7 @@ DEFUN ("image-scaling-p", Fimage_scaling_p, Simage_scaling_p, 0, 1, 0,
9918Return t if FRAME supports native scaling, nil otherwise. */) 9921Return t if FRAME supports native scaling, nil otherwise. */)
9919 (Lisp_Object frame) 9922 (Lisp_Object frame)
9920{ 9923{
9921#if defined (HAVE_NS) || defined (HAVE_NTGUI) 9924#if defined (USE_CAIRO) || defined (HAVE_NS) || defined (HAVE_NTGUI)
9922 return Qt; 9925 return Qt;
9923#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER) 9926#elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
9924 int event_basep, error_basep; 9927 int event_basep, error_basep;
diff --git a/src/xterm.c b/src/xterm.c
index 33eb0f3b5e3..f90d6713b02 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -480,13 +480,12 @@ x_cr_destroy_fringe_bitmap (int which)
480 480
481static void 481static void
482x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image, 482x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
483 int image_width, int image_height,
483 int src_x, int src_y, int width, int height, 484 int src_x, int src_y, int width, int height,
484 int dest_x, int dest_y, bool overlay_p) 485 int dest_x, int dest_y, bool overlay_p)
485{ 486{
486 cairo_t *cr; 487 cairo_t *cr = x_begin_cr_clip (f, gc);
487 cairo_format_t format;
488 488
489 cr = x_begin_cr_clip (f, gc);
490 if (overlay_p) 489 if (overlay_p)
491 cairo_rectangle (cr, dest_x, dest_y, width, height); 490 cairo_rectangle (cr, dest_x, dest_y, width, height);
492 else 491 else
@@ -495,18 +494,33 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
495 cairo_rectangle (cr, dest_x, dest_y, width, height); 494 cairo_rectangle (cr, dest_x, dest_y, width, height);
496 cairo_fill_preserve (cr); 495 cairo_fill_preserve (cr);
497 } 496 }
498 format = cairo_image_surface_get_format (image); 497
498 int orig_image_width = cairo_image_surface_get_width (image);
499 if (image_width == 0) image_width = orig_image_width;
500 int orig_image_height = cairo_image_surface_get_height (image);
501 if (image_height == 0) image_height = orig_image_height;
502
503 cairo_pattern_t *pattern = cairo_pattern_create_for_surface (image);
504 cairo_matrix_t matrix;
505 cairo_matrix_init_scale (&matrix, orig_image_width / (double) image_width,
506 orig_image_height / (double) image_height);
507 cairo_matrix_translate (&matrix, src_x - dest_x, src_y - dest_y);
508 cairo_pattern_set_matrix (pattern, &matrix);
509
510 cairo_format_t format = cairo_image_surface_get_format (image);
499 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1) 511 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
500 { 512 {
501 cairo_set_source_surface (cr, image, dest_x - src_x, dest_y - src_y); 513 cairo_set_source (cr, pattern);
502 cairo_fill (cr); 514 cairo_fill (cr);
503 } 515 }
504 else 516 else
505 { 517 {
506 x_set_cr_source_with_gc_foreground (f, gc); 518 x_set_cr_source_with_gc_foreground (f, gc);
507 cairo_clip (cr); 519 cairo_clip (cr);
508 cairo_mask_surface (cr, image, dest_x - src_x, dest_y - src_y); 520 cairo_mask (cr, pattern);
509 } 521 }
522 cairo_pattern_destroy (pattern);
523
510 x_end_cr_clip (f); 524 x_end_cr_clip (f);
511} 525}
512 526
@@ -1430,7 +1444,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
1430 : f->output_data.x->cursor_pixel) 1444 : f->output_data.x->cursor_pixel)
1431 : face->foreground)); 1445 : face->foreground));
1432 XSetBackground (display, gc, face->background); 1446 XSetBackground (display, gc, face->background);
1433 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh, 1447 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, 0, 0, p->dh,
1434 p->wd, p->h, p->x, p->y, p->overlay_p); 1448 p->wd, p->h, p->x, p->y, p->overlay_p);
1435 XSetForeground (display, gc, gcv.foreground); 1449 XSetForeground (display, gc, gcv.foreground);
1436 XSetBackground (display, gc, gcv.background); 1450 XSetBackground (display, gc, gcv.background);
@@ -3041,8 +3055,10 @@ x_draw_image_foreground (struct glyph_string *s)
3041 if (s->img->cr_data) 3055 if (s->img->cr_data)
3042 { 3056 {
3043 x_set_glyph_string_clipping (s); 3057 x_set_glyph_string_clipping (s);
3044 x_cr_draw_image (s->f, s->gc, s->img->cr_data, s->slice.x, s->slice.y, 3058 x_cr_draw_image (s->f, s->gc,
3045 s->slice.width, s->slice.height, x, y, true); 3059 s->img->cr_data, s->img->width, s->img->height,
3060 s->slice.x, s->slice.y, s->slice.width, s->slice.height,
3061 x, y, true);
3046 if (!s->img->mask) 3062 if (!s->img->mask)
3047 { 3063 {
3048 /* When the image has a mask, we can expect that at 3064 /* When the image has a mask, we can expect that at