diff options
| author | YAMAMOTO Mitsuharu | 2019-03-27 11:04:46 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-03-27 11:12:18 +0900 |
| commit | 2755cf1848b551436b9cc2eff6e4b882b10c07aa (patch) | |
| tree | 0c496f95796f8417f69b5221412162763d1ef4bb /src | |
| parent | d7e442651777805958bd6bcbc8312a6cce147e4a (diff) | |
| download | emacs-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.h | 2 | ||||
| -rw-r--r-- | src/image.c | 7 | ||||
| -rw-r--r-- | src/xterm.c | 34 |
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, | |||
| 9918 | Return t if FRAME supports native scaling, nil otherwise. */) | 9921 | Return 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 | ||
| 481 | static void | 481 | static void |
| 482 | x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image, | 482 | x_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 |