aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-06-08 13:05:15 +0900
committerYAMAMOTO Mitsuharu2019-06-08 13:05:15 +0900
commit88c49ac31898e7b2c29338ca55cae292c450f7be (patch)
tree6130d1732acceaf2eef70327acb724c14171934d /src/xterm.c
parent890a0826f3f68f4476f6ec0b56fe96c6bc047142 (diff)
downloademacs-88c49ac31898e7b2c29338ca55cae292c450f7be.tar.gz
emacs-88c49ac31898e7b2c29338ca55cae292c450f7be.zip
Implement native image rotation and cropping on cairo
* src/dispextern.h (struct image) [USE_CAIRO]: * src/image.c (free_image, image_clear_image_1) (image_set_crop, image_set_size, image_set_rotation) (image_create_x_image_and_pixmap) [USE_CAIRO]: #ifdef out HAVE_XRENDER part. * src/image.c (cr_create_surface_from_pix_containers) [USE_CAIRO]: Rename from cr_create_surface_from_pix_containers. Change arguments to pair of Emacs_Pix_Container:s. Move block_input and unblock_input to caller. (cr_put_image_to_cr_data) [USE_CAIRO]: New function. (prepare_image_for_display) [USE_CAIRO]: Use it. (image_set_transform) [USE_CAIRO]: Create dummy solid color pattern equipped with transformation matrix and set it to img->cr_data. * src/xterm.c (fringe_bmp) [USE_CAIRO]: Change type to cairo_pattern_t **. (x_cr_define_fringe_bitmap, x_cr_destroy_fringe_bitmap) [USE_CAIRO]: Create or destroy cairo pattern. (x_cr_draw_image) [USE_CAIRO]: Remove arguments image_width and image_height. Change type of image to cairo pattern. All callers changed. * src/gtkutil.c (xg_get_image_for_pixmap) [USE_CAIRO]: Get cairo surface from img->cr_data, which is of cairo pattern now.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/src/xterm.c b/src/xterm.c
index c064647da0c..e0edd9c1a40 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -437,13 +437,14 @@ x_set_cr_source_with_gc_background (struct frame *f, GC gc)
437/* Fringe bitmaps. */ 437/* Fringe bitmaps. */
438 438
439static int max_fringe_bmp = 0; 439static int max_fringe_bmp = 0;
440static cairo_surface_t **fringe_bmp = 0; 440static cairo_pattern_t **fringe_bmp = 0;
441 441
442static void 442static void
443x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd) 443x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
444{ 444{
445 int i, stride; 445 int i, stride;
446 cairo_surface_t *surface; 446 cairo_surface_t *surface;
447 cairo_pattern_t *pattern;
447 unsigned char *data; 448 unsigned char *data;
448 449
449 if (which >= max_fringe_bmp) 450 if (which >= max_fringe_bmp)
@@ -468,10 +469,12 @@ x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
468 } 469 }
469 470
470 cairo_surface_mark_dirty (surface); 471 cairo_surface_mark_dirty (surface);
472 pattern = cairo_pattern_create_for_surface (surface);
473 cairo_surface_destroy (surface);
471 474
472 unblock_input (); 475 unblock_input ();
473 476
474 fringe_bmp[which] = surface; 477 fringe_bmp[which] = pattern;
475} 478}
476 479
477static void 480static void
@@ -483,15 +486,14 @@ x_cr_destroy_fringe_bitmap (int which)
483 if (fringe_bmp[which]) 486 if (fringe_bmp[which])
484 { 487 {
485 block_input (); 488 block_input ();
486 cairo_surface_destroy (fringe_bmp[which]); 489 cairo_pattern_destroy (fringe_bmp[which]);
487 unblock_input (); 490 unblock_input ();
488 } 491 }
489 fringe_bmp[which] = 0; 492 fringe_bmp[which] = 0;
490} 493}
491 494
492static void 495static void
493x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image, 496x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
494 int image_width, int image_height,
495 int src_x, int src_y, int width, int height, 497 int src_x, int src_y, int width, int height,
496 int dest_x, int dest_y, bool overlay_p) 498 int dest_x, int dest_y, bool overlay_p)
497{ 499{
@@ -506,31 +508,22 @@ x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
506 cairo_fill_preserve (cr); 508 cairo_fill_preserve (cr);
507 } 509 }
508 510
509 int orig_image_width = cairo_image_surface_get_width (image); 511 cairo_translate (cr, dest_x - src_x, dest_y - src_y);
510 if (image_width == 0) image_width = orig_image_width;
511 int orig_image_height = cairo_image_surface_get_height (image);
512 if (image_height == 0) image_height = orig_image_height;
513
514 cairo_pattern_t *pattern = cairo_pattern_create_for_surface (image);
515 cairo_matrix_t matrix;
516 cairo_matrix_init_scale (&matrix, orig_image_width / (double) image_width,
517 orig_image_height / (double) image_height);
518 cairo_matrix_translate (&matrix, src_x - dest_x, src_y - dest_y);
519 cairo_pattern_set_matrix (pattern, &matrix);
520 512
521 cairo_format_t format = cairo_image_surface_get_format (image); 513 cairo_surface_t *surface;
514 cairo_pattern_get_surface (image, &surface);
515 cairo_format_t format = cairo_image_surface_get_format (surface);
522 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1) 516 if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
523 { 517 {
524 cairo_set_source (cr, pattern); 518 cairo_set_source (cr, image);
525 cairo_fill (cr); 519 cairo_fill (cr);
526 } 520 }
527 else 521 else
528 { 522 {
529 x_set_cr_source_with_gc_foreground (f, gc); 523 x_set_cr_source_with_gc_foreground (f, gc);
530 cairo_clip (cr); 524 cairo_clip (cr);
531 cairo_mask (cr, pattern); 525 cairo_mask (cr, image);
532 } 526 }
533 cairo_pattern_destroy (pattern);
534 527
535 x_end_cr_clip (f); 528 x_end_cr_clip (f);
536} 529}
@@ -1352,7 +1345,7 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
1352 : f->output_data.x->cursor_pixel) 1345 : f->output_data.x->cursor_pixel)
1353 : face->foreground)); 1346 : face->foreground));
1354 XSetBackground (display, gc, face->background); 1347 XSetBackground (display, gc, face->background);
1355 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, 0, 0, p->dh, 1348 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1356 p->wd, p->h, p->x, p->y, p->overlay_p); 1349 p->wd, p->h, p->x, p->y, p->overlay_p);
1357 XSetForeground (display, gc, gcv.foreground); 1350 XSetForeground (display, gc, gcv.foreground);
1358 XSetBackground (display, gc, gcv.background); 1351 XSetBackground (display, gc, gcv.background);
@@ -2929,8 +2922,7 @@ x_draw_image_foreground (struct glyph_string *s)
2929 if (s->img->cr_data) 2922 if (s->img->cr_data)
2930 { 2923 {
2931 x_set_glyph_string_clipping (s); 2924 x_set_glyph_string_clipping (s);
2932 x_cr_draw_image (s->f, s->gc, 2925 x_cr_draw_image (s->f, s->gc, s->img->cr_data,
2933 s->img->cr_data, s->img->width, s->img->height,
2934 s->slice.x, s->slice.y, s->slice.width, s->slice.height, 2926 s->slice.x, s->slice.y, s->slice.width, s->slice.height,
2935 x, y, true); 2927 x, y, true);
2936 if (!s->img->mask) 2928 if (!s->img->mask)