diff options
| author | YAMAMOTO Mitsuharu | 2019-06-08 13:05:15 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-06-08 13:05:15 +0900 |
| commit | 88c49ac31898e7b2c29338ca55cae292c450f7be (patch) | |
| tree | 6130d1732acceaf2eef70327acb724c14171934d /src/xterm.c | |
| parent | 890a0826f3f68f4476f6ec0b56fe96c6bc047142 (diff) | |
| download | emacs-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.c | 38 |
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 | ||
| 439 | static int max_fringe_bmp = 0; | 439 | static int max_fringe_bmp = 0; |
| 440 | static cairo_surface_t **fringe_bmp = 0; | 440 | static cairo_pattern_t **fringe_bmp = 0; |
| 441 | 441 | ||
| 442 | static void | 442 | static void |
| 443 | x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd) | 443 | x_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 | ||
| 477 | static void | 480 | static 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 | ||
| 492 | static void | 495 | static void |
| 493 | x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image, | 496 | x_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) |