aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYuuki Harano2019-07-05 22:37:18 +0900
committerJeff Walsh2020-11-22 14:46:55 +1100
commit85441c96d74f82ca368b950aa0f5334297bf4fa0 (patch)
tree0bdc7d96aa602594cb18ba364e7f12347d7c8a76 /src
parent1d549fa0690d174446ff139bece6db5decd25eba (diff)
downloademacs-85441c96d74f82ca368b950aa0f5334297bf4fa0.tar.gz
emacs-85441c96d74f82ca368b950aa0f5334297bf4fa0.zip
Add Stipple support for PGTK
* ../src/pgtkterm.c (create_background_surface_by_face) (create_background_surface, x_draw_glyph_string_background) (x_draw_glyph_string_bg_rect, x_draw_image_glyph_string) (x_draw_stretch_glyph_string, pgtk_draw_fringe_bitmap): handle stipple * ../src/image.c (image_create_bitmap_from_file, ) (syms_of_image): Add pgtk support * ../lisp/faces.el (face-valid-attribute-values): add pgtk support stipple 対応。 stipple がまともに動いてなかったので修正。
Diffstat (limited to 'src')
-rw-r--r--src/image.c8
-rw-r--r--src/pgtkterm.c199
2 files changed, 126 insertions, 81 deletions
diff --git a/src/image.c b/src/image.c
index 9beb35c484b..0242b502581 100644
--- a/src/image.c
+++ b/src/image.c
@@ -507,12 +507,14 @@ image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
507#endif 507#endif
508 508
509#ifdef HAVE_PGTK 509#ifdef HAVE_PGTK
510 GError *err; 510 GError *err = NULL;
511 ptrdiff_t id; 511 ptrdiff_t id;
512 void * bitmap = gdk_pixbuf_new_from_file(SSDATA(file), &err); 512 void * bitmap = gdk_pixbuf_new_from_file(SSDATA(file), &err);
513 513
514 if (!bitmap) 514 if (!bitmap) {
515 g_error_free(err);
515 return -1; 516 return -1;
517 }
516 518
517 id = image_allocate_bitmap_record(f); 519 id = image_allocate_bitmap_record(f);
518 520
@@ -10698,7 +10700,7 @@ non-numeric, there is no explicit limit on the size of images. */);
10698 DEFSYM (Qxbm, "xbm"); 10700 DEFSYM (Qxbm, "xbm");
10699 add_image_type (Qxbm); 10701 add_image_type (Qxbm);
10700 10702
10701#if defined (HAVE_XPM) || defined (HAVE_NS) 10703#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (USE_CAIRO)
10702 DEFSYM (Qxpm, "xpm"); 10704 DEFSYM (Qxpm, "xpm");
10703 add_image_type (Qxpm); 10705 add_image_type (Qxpm);
10704#endif 10706#endif
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 3e3c73ce503..fb2520614f2 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -984,6 +984,66 @@ x_clear_glyph_string_rect (struct glyph_string *s, int x, int y, int w, int h)
984} 984}
985 985
986 986
987static cairo_surface_t *
988create_background_surface_by_face (struct frame *f, struct face *face, int x, int y, int width, int height)
989{
990 cairo_surface_t *surface = cairo_surface_create_similar (FRAME_CR_SURFACE (f),
991 CAIRO_CONTENT_COLOR,
992 width,
993 height);
994
995 {
996 cairo_t *cr = cairo_create (surface);
997
998 double r = ((face->background >> 16) & 0xff) / 255.0;
999 double g = ((face->background >> 8) & 0xff) / 255.0;
1000 double b = ((face->background >> 0) & 0xff) / 255.0;
1001 cairo_set_source_rgb (cr, r, g, b);
1002 cairo_paint (cr);
1003
1004 cairo_destroy (cr);
1005 }
1006
1007 if (face->stipple != 0) {
1008 GdkPixbuf *pixbuf = FRAME_DISPLAY_INFO (f)->bitmaps[face->stipple - 1].img;
1009 GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
1010 cairo_surface_t *mask = cairo_surface_create_similar_image (FRAME_CR_SURFACE (f),
1011 CAIRO_FORMAT_A1,
1012 width,
1013 height);
1014
1015 {
1016 cairo_t *cr = cairo_create (mask);
1017 gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
1018 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
1019 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
1020 cairo_paint (cr);
1021 cairo_destroy (cr);
1022 }
1023
1024 {
1025 cairo_t *cr = cairo_create (surface);
1026 double r = ((face->foreground >> 16) & 0xff) / 255.0;
1027 double g = ((face->foreground >> 8) & 0xff) / 255.0;
1028 double b = ((face->foreground >> 0) & 0xff) / 255.0;
1029 cairo_set_source_rgb (cr, r, g, b);
1030 cairo_mask_surface (cr, mask, 0, 0);
1031 cairo_destroy (cr);
1032 }
1033
1034 cairo_surface_destroy (mask);
1035 g_object_unref (pb);
1036 }
1037
1038 return surface;
1039}
1040
1041static cairo_surface_t *
1042create_background_surface (struct glyph_string *s, int x, int y, int width, int height)
1043{
1044 return create_background_surface_by_face (s->f, s->face, x, y, width, height);
1045}
1046
987/* Draw the background of glyph_string S. If S->background_filled_p 1047/* Draw the background of glyph_string S. If S->background_filled_p
988 is non-zero don't draw it. FORCE_P non-zero means draw the 1048 is non-zero don't draw it. FORCE_P non-zero means draw the
989 background even if it wouldn't be drawn normally. This is used 1049 background even if it wouldn't be drawn normally. This is used
@@ -1007,20 +1067,28 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
1007 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->font_not_found_p); 1067 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->font_not_found_p);
1008 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->extends_to_end_of_line_p); 1068 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", s->extends_to_end_of_line_p);
1009 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", force_p); 1069 PGTK_TRACE("x_draw_glyph_string_background: 2. %d.", force_p);
1010#if 0 1070
1011 if (s->stippled_p) 1071 if (s->stippled_p)
1012 { 1072 {
1013 /* Fill background with a stipple pattern. */ 1073 /* Fill background with a stipple pattern. */
1014 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); 1074
1015 x_fill_rectangle (s->f, s->gc, s->x, 1075 cairo_surface_t *bg = create_background_surface (s,
1016 s->y + box_line_width, 1076 s->x, s->y + box_line_width,
1017 s->background_width, 1077 s->background_width, s->height - 2 * box_line_width);
1018 s->height - 2 * box_line_width); 1078
1019 XSetFillStyle (s->display, s->gc, FillSolid); 1079 cairo_t *cr = pgtk_begin_cr_clip (s->f);
1080 cairo_set_source_surface (cr, bg, s->x, s->y + box_line_width);
1081 cairo_rectangle (cr,
1082 s->x, s->y + box_line_width,
1083 s->background_width, s->height - 2 * box_line_width);
1084 cairo_fill (cr);
1085 pgtk_end_cr_clip (s->f);
1086
1087 cairo_surface_destroy (bg);
1088
1020 s->background_filled_p = true; 1089 s->background_filled_p = true;
1021 } 1090 }
1022 else 1091 else
1023#endif
1024 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width 1092 if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1025 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust 1093 /* When xdisp.c ignores FONT_HEIGHT, we cannot trust
1026 font dimensions, since the actual glyphs might be 1094 font dimensions, since the actual glyphs might be
@@ -1821,16 +1889,21 @@ x_draw_image_relief (struct glyph_string *s)
1821static void 1889static void
1822x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h) 1890x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
1823{ 1891{
1824#if 0
1825 if (s->stippled_p) 1892 if (s->stippled_p)
1826 { 1893 {
1827 /* Fill background with a stipple pattern. */ 1894 /* Fill background with a stipple pattern. */
1828 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); 1895
1829 x_fill_rectangle (s->f, s->gc, x, y, w, h); 1896 cairo_surface_t *bg = create_background_surface (s, x, y, w, h);
1830 XSetFillStyle (s->display, s->gc, FillSolid); 1897
1898 cairo_t *cr = pgtk_begin_cr_clip (s->f);
1899 cairo_set_source_surface (cr, bg, x, y);
1900 cairo_rectangle (cr, x, y, w, h);
1901 cairo_fill (cr);
1902 pgtk_end_cr_clip (s->f);
1903
1904 cairo_surface_destroy (bg);
1831 } 1905 }
1832 else 1906 else
1833#endif
1834 x_clear_glyph_string_rect (s, x, y, w, h); 1907 x_clear_glyph_string_rect (s, x, y, w, h);
1835} 1908}
1836 1909
@@ -1881,7 +1954,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
1881 int box_line_hwidth = eabs (s->face->box_line_width); 1954 int box_line_hwidth = eabs (s->face->box_line_width);
1882 int box_line_vwidth = max (s->face->box_line_width, 0); 1955 int box_line_vwidth = max (s->face->box_line_width, 0);
1883 int height; 1956 int height;
1884 cairo_surface_t *surface = NULL;
1885 1957
1886 height = s->height; 1958 height = s->height;
1887 if (s->slice.y == 0) 1959 if (s->slice.y == 0)
@@ -1903,43 +1975,15 @@ x_draw_image_glyph_string (struct glyph_string *s)
1903 { 1975 {
1904 if (s->img->mask) 1976 if (s->img->mask)
1905 { 1977 {
1906 /* Create a pixmap as large as the glyph string. Fill it 1978 cairo_surface_t *bg = create_background_surface (s, s->x, s->y, s->background_width, s->height);
1907 with the background color. Copy the image to it, using
1908 its mask. Copy the temporary pixmap to the display. */
1909
1910 /* Create a pixmap as large as the glyph string. */
1911 surface = cairo_surface_create_similar(FRAME_CR_SURFACE(s->f), CAIRO_CONTENT_COLOR_ALPHA,
1912 s->background_width,
1913 s->height);
1914 1979
1915 /* Don't clip in the following because we're working on the 1980 cairo_t *cr = pgtk_begin_cr_clip (s->f);
1916 pixmap. */ 1981 cairo_set_source_surface (cr, bg, s->x, s->y);
1917 // XSetClipMask (s->display, s->gc, None); 1982 cairo_rectangle (cr, s->x, s->y, s->background_width, s->height);
1983 cairo_fill (cr);
1984 pgtk_end_cr_clip (s->f);
1918 1985
1919 /* Fill the pixmap with the background color/stipple. */ 1986 cairo_surface_destroy (bg);
1920#if 0
1921 if (s->stippled_p)
1922 {
1923 /* Fill background with a stipple pattern. */
1924 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1925 XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
1926 XFillRectangle (s->display, pixmap, s->gc,
1927 0, 0, s->background_width, s->height);
1928 XSetFillStyle (s->display, s->gc, FillSolid);
1929 XSetTSOrigin (s->display, s->gc, 0, 0);
1930 }
1931 else
1932#endif
1933 {
1934 cairo_t *cr = cairo_create(surface);
1935 int red = (s->xgcv.background >> 16) & 0xff;
1936 int green = (s->xgcv.background >> 8) & 0xff;
1937 int blue = (s->xgcv.background >> 0) & 0xff;
1938 cairo_set_source_rgb (cr, red / 255.0, green / 255.0, blue / 255.0);
1939 cairo_rectangle(cr, 0, 0, s->background_width, s->height);
1940 cairo_fill(cr);
1941 cairo_destroy(cr);
1942 }
1943 } 1987 }
1944 else 1988 else
1945 { 1989 {
@@ -1957,7 +2001,15 @@ x_draw_image_glyph_string (struct glyph_string *s)
1957 if (s->slice.y == 0) 2001 if (s->slice.y == 0)
1958 y += box_line_vwidth; 2002 y += box_line_vwidth;
1959 2003
1960 x_draw_glyph_string_bg_rect (s, x, y, width, height); 2004 cairo_surface_t *bg = create_background_surface (s, x, y, width, height);
2005
2006 cairo_t *cr = pgtk_begin_cr_clip (s->f);
2007 cairo_set_source_surface (cr, bg, x, y);
2008 cairo_rectangle (cr, x, y, width, height);
2009 cairo_fill (cr);
2010 pgtk_end_cr_clip (s->f);
2011
2012 cairo_surface_destroy (bg);
1961 } 2013 }
1962 2014
1963 s->background_filled_p = true; 2015 s->background_filled_p = true;
@@ -1979,18 +2031,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
1979 pgtk_end_cr_clip (s->f); 2031 pgtk_end_cr_clip (s->f);
1980 } 2032 }
1981 else 2033 else
1982 if (surface != NULL)
1983 {
1984 cairo_t *cr = pgtk_begin_cr_clip(s->f);
1985
1986 x_draw_image_foreground_1 (s, surface);
1987 x_set_glyph_string_clipping (s, cr);
1988
1989 cairo_set_source_surface(cr, surface, 0, 0);
1990 cairo_rectangle(cr, s->x, s->y, s->background_width, s->height);
1991 pgtk_end_cr_clip(s->f);
1992 }
1993 else
1994 x_draw_image_foreground (s); 2034 x_draw_image_foreground (s);
1995 2035
1996 /* If we must draw a relief around the image, do it. */ 2036 /* If we must draw a relief around the image, do it. */
@@ -1998,9 +2038,6 @@ x_draw_image_glyph_string (struct glyph_string *s)
1998 || s->hl == DRAW_IMAGE_RAISED 2038 || s->hl == DRAW_IMAGE_RAISED
1999 || s->hl == DRAW_IMAGE_SUNKEN) 2039 || s->hl == DRAW_IMAGE_SUNKEN)
2000 x_draw_image_relief (s); 2040 x_draw_image_relief (s);
2001
2002 if (surface != NULL)
2003 cairo_surface_destroy(surface);
2004} 2041}
2005 2042
2006/* Draw stretch glyph string S. */ 2043/* Draw stretch glyph string S. */
@@ -2071,16 +2108,18 @@ x_draw_stretch_glyph_string (struct glyph_string *s)
2071 get_glyph_string_clip_rect (s, &r); 2108 get_glyph_string_clip_rect (s, &r);
2072 x_set_clip_rectangles (s->f, cr, &r, 1); 2109 x_set_clip_rectangles (s->f, cr, &r, 1);
2073 2110
2074#if 0
2075 if (s->face->stipple) 2111 if (s->face->stipple)
2076 { 2112 {
2077 /* Fill background with a stipple pattern. */ 2113 /* Fill background with a stipple pattern. */
2078 XSetFillStyle (s->display, gc, FillOpaqueStippled); 2114 cairo_surface_t *bg = create_background_surface (s, x, y, w, h);
2079 x_fill_rectangle (s->f, gc, x, y, w, h); 2115 cairo_t *cr = pgtk_begin_cr_clip (s->f);
2080 XSetFillStyle (s->display, gc, FillSolid); 2116 cairo_set_source_surface (cr, bg, x, y);
2117 cairo_rectangle (cr, x, y, w, h);
2118 cairo_fill (cr);
2119 pgtk_end_cr_clip (s->f);
2120 cairo_surface_destroy (bg);
2081 } 2121 }
2082 else 2122 else
2083#endif
2084 { 2123 {
2085 pgtk_fill_rectangle(s->f, color, x, y, w, h); 2124 pgtk_fill_rectangle(s->f, color, x, y, w, h);
2086 } 2125 }
@@ -3195,15 +3234,19 @@ pgtk_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fr
3195 for something displayed in the text (e.g. face `region' on 3234 for something displayed in the text (e.g. face `region' on
3196 mono-displays, the fill style may have been changed to 3235 mono-displays, the fill style may have been changed to
3197 FillSolid in x_draw_glyph_string_background. */ 3236 FillSolid in x_draw_glyph_string_background. */
3198#if 0 3237 if (face->stipple) {
3199 if (face->stipple) 3238 cairo_surface_t *bg = create_background_surface_by_face(f, face, p->bx, p->by, p->nx, p->ny);
3200 XSetFillStyle (display, face->gc, FillOpaqueStippled); 3239 cairo_t *cr = pgtk_begin_cr_clip (f);
3201 else 3240 cairo_set_source_surface (cr, bg, p->bx, p->by);
3202#endif 3241 cairo_rectangle (cr, p->bx, p->by, p->nx, p->ny);
3242 cairo_fill (cr);
3243 pgtk_end_cr_clip (f);
3244 cairo_surface_destroy (bg);
3245 } else {
3203 pgtk_set_cr_source_with_color(f, face->background); 3246 pgtk_set_cr_source_with_color(f, face->background);
3204 3247 cairo_rectangle(cr, p->bx, p->by, p->nx, p->ny);
3205 cairo_rectangle(cr, p->bx, p->by, p->nx, p->ny); 3248 cairo_fill(cr);
3206 cairo_fill(cr); 3249 }
3207 } 3250 }
3208 3251
3209 PGTK_TRACE("which: %d, max_fringe_bmp: %d.", p->which, max_fringe_bmp); 3252 PGTK_TRACE("which: %d, max_fringe_bmp: %d.", p->which, max_fringe_bmp);