aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuuki Harano2019-07-29 21:31:42 +0900
committerJeff Walsh2020-11-22 14:46:56 +1100
commitfd61a86ea593fec0fc8967550f515596dc596601 (patch)
tree60033e01d952532fe7187ea400383ffb85f700bc
parentae3bb140912827c38e7033c07851a94ba710428d (diff)
downloademacs-fd61a86ea593fec0fc8967550f515596dc596601.tar.gz
emacs-fd61a86ea593fec0fc8967550f515596dc596601.zip
improve some efficiency - simplify draws
* src/pgtkterm.h (struct pgtk_bitmap_record): * src/pgtkterm.c (create_background_surface_by_face): * src/image.c (image_create_pattern_from_pixbuf) (image_create_bitmap_from_data, image_create_bitmap_from_file): 少し効率化。
-rw-r--r--src/image.c70
-rw-r--r--src/pgtkterm.c35
-rw-r--r--src/pgtkterm.h1
3 files changed, 73 insertions, 33 deletions
diff --git a/src/image.c b/src/image.c
index 0242b502581..0b85cf8634a 100644
--- a/src/image.c
+++ b/src/image.c
@@ -400,6 +400,32 @@ image_reference_bitmap (struct frame *f, ptrdiff_t id)
400 ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; 400 ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
401} 401}
402 402
403#ifdef HAVE_PGTK
404static cairo_pattern_t *
405image_create_pattern_from_pixbuf (struct frame *f, GdkPixbuf *pixbuf)
406{
407 GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
408 cairo_surface_t *surface = cairo_surface_create_similar_image (f->output_data.pgtk->cr_surface,
409 CAIRO_FORMAT_A1,
410 gdk_pixbuf_get_width (pb),
411 gdk_pixbuf_get_height (pb));
412
413 cairo_t *cr = cairo_create (surface);
414 gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
415 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
416 cairo_paint (cr);
417 cairo_destroy (cr);
418
419 cairo_pattern_t *pat = cairo_pattern_create_for_surface (surface);
420 cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
421
422 cairo_surface_destroy (surface);
423 g_object_unref (pb);
424
425 return pat;
426}
427#endif
428
403/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */ 429/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
404 430
405ptrdiff_t 431ptrdiff_t
@@ -435,11 +461,39 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
435#endif 461#endif
436 462
437#ifdef HAVE_PGTK 463#ifdef HAVE_PGTK
438 Emacs_Pixmap bitmap = image_pix_container_create_from_bitmap_data(f, bits, 464 GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
439 width, 465 FALSE,
440 height, 466 8,
441 0xffffffff, 467 width,
442 0xff000000); 468 height);
469 {
470 char *sp = bits;
471 int mask = 0x01;
472 unsigned char *buf = gdk_pixbuf_get_pixels (pixbuf);
473 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
474 for (int y = 0; y < height; y++) {
475 unsigned char *dp = buf + rowstride * y;
476 for (int x = 0; x < width; x++) {
477 if (*sp & mask) {
478 *dp++ = 0xff;
479 *dp++ = 0xff;
480 *dp++ = 0xff;
481 } else {
482 *dp++ = 0x00;
483 *dp++ = 0x00;
484 *dp++ = 0x00;
485 }
486 if ((mask <<= 1) >= 0x100) {
487 mask = 0x01;
488 sp++;
489 }
490 }
491 if (mask != 0x01) {
492 mask = 0x01;
493 sp++;
494 }
495 }
496 }
443#endif 497#endif
444 498
445 id = image_allocate_bitmap_record (f); 499 id = image_allocate_bitmap_record (f);
@@ -450,8 +504,9 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
450#endif 504#endif
451 505
452#ifdef HAVE_PGTK 506#ifdef HAVE_PGTK
453 dpyinfo->bitmaps[id - 1].img = bitmap; 507 dpyinfo->bitmaps[id - 1].img = pixbuf;
454 dpyinfo->bitmaps[id - 1].depth = 1; 508 dpyinfo->bitmaps[id - 1].depth = 1;
509 dpyinfo->bitmaps[id - 1].pattern = image_create_pattern_from_pixbuf (f, pixbuf);
455#endif 510#endif
456 511
457 dpyinfo->bitmaps[id - 1].file = NULL; 512 dpyinfo->bitmaps[id - 1].file = NULL;
@@ -524,6 +579,7 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
524 //dpyinfo->bitmaps[id - 1].depth = 1; 579 //dpyinfo->bitmaps[id - 1].depth = 1;
525 dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap); 580 dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap);
526 dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap); 581 dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap);
582 dpyinfo->bitmaps[id - 1].pattern = image_create_pattern_from_pixbuf (f, bitmap);
527 return id; 583 return id;
528#endif 584#endif
529 585
@@ -600,6 +656,8 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
600#endif 656#endif
601 657
602#ifdef HAVE_PGTK 658#ifdef HAVE_PGTK
659 if (bm->pattern != NULL)
660 cairo_pattern_destroy (bm->pattern);
603#endif 661#endif
604 662
605 if (bm->file) 663 if (bm->file)
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 4665a934718..3e8357e7749 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -1024,34 +1024,15 @@ create_background_surface_by_face (struct frame *f, struct face *face, int x, in
1024 } 1024 }
1025 1025
1026 if (face->stipple != 0) { 1026 if (face->stipple != 0) {
1027 GdkPixbuf *pixbuf = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].img; 1027 cairo_pattern_t *mask = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].pattern;
1028 GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
1029 cairo_surface_t *mask = cairo_surface_create_similar_image (FRAME_CR_SURFACE (f),
1030 CAIRO_FORMAT_A1,
1031 width,
1032 height);
1033 1028
1034 { 1029 cairo_t *cr = cairo_create (surface);
1035 cairo_t *cr = cairo_create (mask); 1030 double r = ((face->foreground >> 16) & 0xff) / 255.0;
1036 gdk_cairo_set_source_pixbuf (cr, pb, 0, 0); 1031 double g = ((face->foreground >> 8) & 0xff) / 255.0;
1037 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT); 1032 double b = ((face->foreground >> 0) & 0xff) / 255.0;
1038 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); 1033 cairo_set_source_rgb (cr, r, g, b);
1039 cairo_paint (cr); 1034 cairo_mask (cr, mask);
1040 cairo_destroy (cr); 1035 cairo_destroy (cr);
1041 }
1042
1043 {
1044 cairo_t *cr = cairo_create (surface);
1045 double r = ((face->foreground >> 16) & 0xff) / 255.0;
1046 double g = ((face->foreground >> 8) & 0xff) / 255.0;
1047 double b = ((face->foreground >> 0) & 0xff) / 255.0;
1048 cairo_set_source_rgb (cr, r, g, b);
1049 cairo_mask_surface (cr, mask, 0, 0);
1050 cairo_destroy (cr);
1051 }
1052
1053 cairo_surface_destroy (mask);
1054 g_object_unref (pb);
1055 } 1036 }
1056 1037
1057 return surface; 1038 return surface;
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 4c6ef0f6bb8..8caf31f8e43 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -54,6 +54,7 @@ struct pgtk_bitmap_record
54 char *file; 54 char *file;
55 int refcount; 55 int refcount;
56 int height, width, depth; 56 int height, width, depth;
57 cairo_pattern_t *pattern;
57}; 58};
58 59
59#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) 60#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))