aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-02-10 18:43:08 +0800
committerPo Lu2022-02-10 18:45:35 +0800
commite16a78c44e05237b98207a7cee4b0666b7e1ac2a (patch)
tree851dcf0a3fe04ef08560a57d75bff802ca3bd7a2 /src
parent849895d0db9c8879dedd6658f66b28b1613358ff (diff)
downloademacs-e16a78c44e05237b98207a7cee4b0666b7e1ac2a.tar.gz
emacs-e16a78c44e05237b98207a7cee4b0666b7e1ac2a.zip
Correctly allocate colors in xftfont
* src/xftfont.c (struct xftface_info): New fields `bg_allocated_p' and `fg_allocated_p'. (xftfont_get_colors): Actually allocate colors and tell the caller whether colors were allocated. (xftfont_prepare_face): Set allocated fields. (xftfont_done_face): (xftfont_draw): Free colors that were allocated.
Diffstat (limited to 'src')
-rw-r--r--src/xftfont.c71
1 files changed, 64 insertions, 7 deletions
diff --git a/src/xftfont.c b/src/xftfont.c
index 6a2b2086df8..e27c6cf3146 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -49,19 +49,26 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
49 49
50struct xftface_info 50struct xftface_info
51{ 51{
52 bool bg_allocated_p;
53 bool fg_allocated_p;
52 XftColor xft_fg; /* color for face->foreground */ 54 XftColor xft_fg; /* color for face->foreground */
53 XftColor xft_bg; /* color for face->background */ 55 XftColor xft_bg; /* color for face->background */
54}; 56};
55 57
56/* Setup foreground and background colors of GC into FG and BG. If 58/* Setup foreground and background colors of GC into FG and BG. If
57 XFTFACE_INFO is not NULL, reuse the colors in it if possible. BG 59 XFTFACE_INFO is not NULL, reuse the colors in it if possible. BG
58 may be NULL. */ 60 may be NULL. Return whether or not colors were allocated in
61 BG_ALLOCATED_P and FG_ALLOCATED_P. */
59 62
60static void 63static void
61xftfont_get_colors (struct frame *f, struct face *face, GC gc, 64xftfont_get_colors (struct frame *f, struct face *face, GC gc,
62 struct xftface_info *xftface_info, 65 struct xftface_info *xftface_info,
63 XftColor *fg, XftColor *bg) 66 XftColor *fg, XftColor *bg,
67 bool *bg_allocated_p, bool *fg_allocated_p)
64{ 68{
69 *bg_allocated_p = false;
70 *fg_allocated_p = false;
71
65 if (xftface_info && face->gc == gc) 72 if (xftface_info && face->gc == gc)
66 { 73 {
67 *fg = xftface_info->xft_fg; 74 *fg = xftface_info->xft_fg;
@@ -94,20 +101,39 @@ xftfont_get_colors (struct frame *f, struct face *face, GC gc,
94 { 101 {
95 XColor colors[2]; 102 XColor colors[2];
96 103
97 colors[0].pixel = fg->pixel = xgcv.foreground; 104 colors[0].pixel = xgcv.foreground;
98 if (bg) 105 if (bg)
99 colors[1].pixel = bg->pixel = xgcv.background; 106 colors[1].pixel = xgcv.background;
100 x_query_colors (f, colors, bg ? 2 : 1); 107 x_query_colors (f, colors, bg ? 2 : 1);
101 fg->color.alpha = 0xFFFF; 108 fg->color.alpha = 0xFFFF;
102 fg->color.red = colors[0].red; 109 fg->color.red = colors[0].red;
103 fg->color.green = colors[0].green; 110 fg->color.green = colors[0].green;
104 fg->color.blue = colors[0].blue; 111 fg->color.blue = colors[0].blue;
112
113 if (!XftColorAllocValue (FRAME_X_DISPLAY (f),
114 FRAME_X_VISUAL (f),
115 FRAME_X_COLORMAP (f),
116 &fg->color, fg))
117 /* This color should've been allocated when creating the
118 GC. */
119 emacs_abort ();
120 else
121 *fg_allocated_p = true;
122
105 if (bg) 123 if (bg)
106 { 124 {
107 bg->color.alpha = 0xFFFF; 125 bg->color.alpha = 0xFFFF;
108 bg->color.red = colors[1].red; 126 bg->color.red = colors[1].red;
109 bg->color.green = colors[1].green; 127 bg->color.green = colors[1].green;
110 bg->color.blue = colors[1].blue; 128 bg->color.blue = colors[1].blue;
129
130 if (!XftColorAllocValue (FRAME_X_DISPLAY (f),
131 FRAME_X_VISUAL (f),
132 FRAME_X_COLORMAP (f),
133 &bg->color, bg))
134 emacs_abort ();
135 else
136 *bg_allocated_p = true;
111 } 137 }
112 } 138 }
113 unblock_input (); 139 unblock_input ();
@@ -360,9 +386,12 @@ xftfont_prepare_face (struct frame *f, struct face *face)
360 } 386 }
361#endif 387#endif
362 388
363 xftface_info = xmalloc (sizeof *xftface_info); 389 xftface_info = xzalloc (sizeof *xftface_info);
364 xftfont_get_colors (f, face, face->gc, NULL, 390 xftfont_get_colors (f, face, face->gc, NULL,
365 &xftface_info->xft_fg, &xftface_info->xft_bg); 391 &xftface_info->xft_fg,
392 &xftface_info->xft_bg,
393 &xftface_info->bg_allocated_p,
394 &xftface_info->fg_allocated_p);
366 face->extra = xftface_info; 395 face->extra = xftface_info;
367} 396}
368 397
@@ -381,6 +410,18 @@ xftfont_done_face (struct frame *f, struct face *face)
381 xftface_info = (struct xftface_info *) face->extra; 410 xftface_info = (struct xftface_info *) face->extra;
382 if (xftface_info) 411 if (xftface_info)
383 { 412 {
413 if (xftface_info->fg_allocated_p)
414 XftColorFree (FRAME_X_DISPLAY (f),
415 FRAME_X_VISUAL (f),
416 FRAME_X_COLORMAP (f),
417 &xftface_info->xft_fg);
418
419 if (xftface_info->bg_allocated_p)
420 XftColorFree (FRAME_X_DISPLAY (f),
421 FRAME_X_VISUAL (f),
422 FRAME_X_COLORMAP (f),
423 &xftface_info->xft_bg);
424
384 xfree (xftface_info); 425 xfree (xftface_info);
385 face->extra = NULL; 426 face->extra = NULL;
386 } 427 }
@@ -469,13 +510,16 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
469 XftDraw *xft_draw = xftfont_get_xft_draw (f); 510 XftDraw *xft_draw = xftfont_get_xft_draw (f);
470 FT_UInt *code; 511 FT_UInt *code;
471 XftColor fg, bg; 512 XftColor fg, bg;
513 bool bg_allocated_p, fg_allocated_p;
472 int len = to - from; 514 int len = to - from;
473 int i; 515 int i;
474 516
475 if (s->font == face->font) 517 if (s->font == face->font)
476 xftface_info = (struct xftface_info *) face->extra; 518 xftface_info = (struct xftface_info *) face->extra;
477 xftfont_get_colors (f, face, s->gc, xftface_info, 519 xftfont_get_colors (f, face, s->gc, xftface_info,
478 &fg, with_background ? &bg : NULL); 520 &fg, with_background ? &bg : NULL,
521 &bg_allocated_p, &fg_allocated_p);
522
479 if (s->num_clips > 0) 523 if (s->num_clips > 0)
480 XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips); 524 XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips);
481 else 525 else
@@ -550,6 +594,19 @@ xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
550 FRAME_X_DRAWABLE in order to draw: we cached the drawable in the 594 FRAME_X_DRAWABLE in order to draw: we cached the drawable in the
551 XftDraw structure. */ 595 XftDraw structure. */
552 x_mark_frame_dirty (f); 596 x_mark_frame_dirty (f);
597
598 if (bg_allocated_p)
599 XftColorFree (FRAME_X_DISPLAY (f),
600 FRAME_X_VISUAL (f),
601 FRAME_X_COLORMAP (f),
602 &bg);
603
604 if (fg_allocated_p)
605 XftColorFree (FRAME_X_DISPLAY (f),
606 FRAME_X_VISUAL (f),
607 FRAME_X_COLORMAP (f),
608 &fg);
609
553 unblock_input (); 610 unblock_input ();
554 return len; 611 return len;
555} 612}