diff options
| author | Yuuki Harano | 2020-08-10 19:06:40 +0900 |
|---|---|---|
| committer | Jeff Walsh | 2020-11-24 12:24:40 +1100 |
| commit | be47e34e40d4a330e59c8dfabdf8b44a57905973 (patch) | |
| tree | f0d3d55528c5b1dcfaae337f32e34e2a464381df /src | |
| parent | 2d5ffa5595e2f83977cfe391bcaca0aba9f1f5b6 (diff) | |
| download | emacs-be47e34e40d4a330e59c8dfabdf8b44a57905973.tar.gz emacs-be47e34e40d4a330e59c8dfabdf8b44a57905973.zip | |
Re-port image drawing code from X
* src/pgtkterm.c (x_cr_draw_image): Re-port X code.
(x_draw_image_foreground): Re-port X code.
(x_draw_image_glyph_string): Re-port X code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/pgtkterm.c | 103 |
1 files changed, 74 insertions, 29 deletions
diff --git a/src/pgtkterm.c b/src/pgtkterm.c index dc36f38a5c7..aeec3f589ff 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c | |||
| @@ -1971,6 +1971,42 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, | |||
| 1971 | x_clear_glyph_string_rect (s, x, y, w, h); | 1971 | x_clear_glyph_string_rect (s, x, y, w, h); |
| 1972 | } | 1972 | } |
| 1973 | 1973 | ||
| 1974 | static void | ||
| 1975 | x_cr_draw_image (struct frame *f, Emacs_GC *gc, cairo_pattern_t *image, | ||
| 1976 | int src_x, int src_y, int width, int height, | ||
| 1977 | int dest_x, int dest_y, bool overlay_p) | ||
| 1978 | { | ||
| 1979 | cairo_t *cr = pgtk_begin_cr_clip (f); | ||
| 1980 | |||
| 1981 | if (overlay_p) | ||
| 1982 | cairo_rectangle (cr, dest_x, dest_y, width, height); | ||
| 1983 | else | ||
| 1984 | { | ||
| 1985 | pgtk_set_cr_source_with_gc_background (f, gc); | ||
| 1986 | cairo_rectangle (cr, dest_x, dest_y, width, height); | ||
| 1987 | cairo_fill_preserve (cr); | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | cairo_translate (cr, dest_x - src_x, dest_y - src_y); | ||
| 1991 | |||
| 1992 | cairo_surface_t *surface; | ||
| 1993 | cairo_pattern_get_surface (image, &surface); | ||
| 1994 | cairo_format_t format = cairo_image_surface_get_format (surface); | ||
| 1995 | if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1) | ||
| 1996 | { | ||
| 1997 | cairo_set_source (cr, image); | ||
| 1998 | cairo_fill (cr); | ||
| 1999 | } | ||
| 2000 | else | ||
| 2001 | { | ||
| 2002 | pgtk_set_cr_source_with_gc_foreground (f, gc); | ||
| 2003 | cairo_clip (cr); | ||
| 2004 | cairo_mask (cr, image); | ||
| 2005 | } | ||
| 2006 | |||
| 2007 | pgtk_end_cr_clip (f); | ||
| 2008 | } | ||
| 2009 | |||
| 1974 | /* Draw foreground of image glyph string S. */ | 2010 | /* Draw foreground of image glyph string S. */ |
| 1975 | 2011 | ||
| 1976 | static void | 2012 | static void |
| @@ -1982,7 +2018,8 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 1982 | /* If first glyph of S has a left box line, start drawing it to the | 2018 | /* If first glyph of S has a left box line, start drawing it to the |
| 1983 | right of that line. */ | 2019 | right of that line. */ |
| 1984 | if (s->face->box != FACE_NO_BOX | 2020 | if (s->face->box != FACE_NO_BOX |
| 1985 | && s->first_glyph->left_box_line_p && s->slice.x == 0) | 2021 | && s->first_glyph->left_box_line_p |
| 2022 | && s->slice.x == 0) | ||
| 1986 | x += max (s->face->box_vertical_line_width, 0); | 2023 | x += max (s->face->box_vertical_line_width, 0); |
| 1987 | 2024 | ||
| 1988 | /* If there is a margin around the image, adjust x- and y-position | 2025 | /* If there is a margin around the image, adjust x- and y-position |
| @@ -1992,9 +2029,35 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 1992 | if (s->slice.y == 0) | 2029 | if (s->slice.y == 0) |
| 1993 | y += s->img->vmargin; | 2030 | y += s->img->vmargin; |
| 1994 | 2031 | ||
| 1995 | /* Draw a rectangle if image could not be loaded. */ | 2032 | if (s->img->cr_data) |
| 1996 | pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y, | 2033 | { |
| 1997 | s->slice.width - 1, s->slice.height - 1); | 2034 | cairo_t *cr = pgtk_begin_cr_clip (s->f); |
| 2035 | x_set_glyph_string_clipping (s, cr); | ||
| 2036 | x_cr_draw_image (s->f, &s->xgcv, s->img->cr_data, | ||
| 2037 | s->slice.x, s->slice.y, s->slice.width, s->slice.height, | ||
| 2038 | x, y, true); | ||
| 2039 | if (!s->img->mask) | ||
| 2040 | { | ||
| 2041 | /* When the image has a mask, we can expect that at | ||
| 2042 | least part of a mouse highlight or a block cursor will | ||
| 2043 | be visible. If the image doesn't have a mask, make | ||
| 2044 | a block cursor visible by drawing a rectangle around | ||
| 2045 | the image. I believe it's looking better if we do | ||
| 2046 | nothing here for mouse-face. */ | ||
| 2047 | if (s->hl == DRAW_CURSOR) | ||
| 2048 | { | ||
| 2049 | int relief = eabs (s->img->relief); | ||
| 2050 | pgtk_draw_rectangle (s->f, s->xgcv.foreground, x - relief, y - relief, | ||
| 2051 | s->slice.width + relief*2 - 1, | ||
| 2052 | s->slice.height + relief*2 - 1); | ||
| 2053 | } | ||
| 2054 | } | ||
| 2055 | pgtk_end_cr_clip (s->f); | ||
| 2056 | } | ||
| 2057 | else | ||
| 2058 | /* Draw a rectangle if image could not be loaded. */ | ||
| 2059 | pgtk_draw_rectangle (s->f, s->xgcv.foreground, x, y, | ||
| 2060 | s->slice.width - 1, s->slice.height - 1); | ||
| 1998 | } | 2061 | } |
| 1999 | 2062 | ||
| 2000 | /* Draw image glyph string S. | 2063 | /* Draw image glyph string S. |
| @@ -2033,19 +2096,15 @@ x_draw_image_glyph_string (struct glyph_string *s) | |||
| 2033 | || s->img->vmargin | 2096 | || s->img->vmargin |
| 2034 | || s->img->mask | 2097 | || s->img->mask |
| 2035 | || s->img->pixmap == 0 | 2098 | || s->img->pixmap == 0 |
| 2036 | || s->stippled_p || s->width != s->background_width) | 2099 | || s->width != s->background_width) |
| 2037 | { | 2100 | { |
| 2038 | if (s->img->mask) | ||
| 2039 | { | ||
| 2040 | fill_background (s, s->x, s->y, s->background_width, s->height); | ||
| 2041 | } | ||
| 2042 | else | ||
| 2043 | { | 2101 | { |
| 2044 | int x = s->x; | 2102 | int x = s->x; |
| 2045 | int y = s->y; | 2103 | int y = s->y; |
| 2046 | int width = s->background_width; | 2104 | int width = s->background_width; |
| 2047 | 2105 | ||
| 2048 | if (s->first_glyph->left_box_line_p && s->slice.x == 0) | 2106 | if (s->first_glyph->left_box_line_p |
| 2107 | && s->slice.x == 0) | ||
| 2049 | { | 2108 | { |
| 2050 | x += box_line_hwidth; | 2109 | x += box_line_hwidth; |
| 2051 | width -= box_line_hwidth; | 2110 | width -= box_line_hwidth; |
| @@ -2054,33 +2113,19 @@ x_draw_image_glyph_string (struct glyph_string *s) | |||
| 2054 | if (s->slice.y == 0) | 2113 | if (s->slice.y == 0) |
| 2055 | y += box_line_vwidth; | 2114 | y += box_line_vwidth; |
| 2056 | 2115 | ||
| 2057 | fill_background (s, x, y, width, height); | 2116 | x_draw_glyph_string_bg_rect (s, x, y, width, height); |
| 2058 | } | 2117 | } |
| 2059 | 2118 | ||
| 2060 | s->background_filled_p = true; | 2119 | s->background_filled_p = true; |
| 2061 | } | 2120 | } |
| 2062 | 2121 | ||
| 2063 | /* Draw the foreground. */ | 2122 | /* Draw the foreground. */ |
| 2064 | if (s->img->cr_data) | 2123 | x_draw_image_foreground (s); |
| 2065 | { | ||
| 2066 | cairo_t *cr = pgtk_begin_cr_clip (s->f); | ||
| 2067 | |||
| 2068 | int x = s->x + s->img->hmargin; | ||
| 2069 | int y = s->y + s->img->vmargin; | ||
| 2070 | int width = s->background_width; | ||
| 2071 | |||
| 2072 | cairo_translate (cr, x - s->slice.x, y - s->slice.y); | ||
| 2073 | cairo_set_source (cr, s->img->cr_data); | ||
| 2074 | cairo_rectangle (cr, 0, 0, width, height); | ||
| 2075 | cairo_fill (cr); | ||
| 2076 | pgtk_end_cr_clip (s->f); | ||
| 2077 | } | ||
| 2078 | else | ||
| 2079 | x_draw_image_foreground (s); | ||
| 2080 | 2124 | ||
| 2081 | /* If we must draw a relief around the image, do it. */ | 2125 | /* If we must draw a relief around the image, do it. */ |
| 2082 | if (s->img->relief | 2126 | if (s->img->relief |
| 2083 | || s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | 2127 | || s->hl == DRAW_IMAGE_RAISED |
| 2128 | || s->hl == DRAW_IMAGE_SUNKEN) | ||
| 2084 | x_draw_image_relief (s); | 2129 | x_draw_image_relief (s); |
| 2085 | } | 2130 | } |
| 2086 | 2131 | ||