diff options
author | Po Lu <luangruo@yahoo.com> | 2022-12-22 15:50:12 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-12-22 15:51:15 +0800 |
commit | f681b76a7c43ff54f1aba276f09b8fa0e0dea578 (patch) | |
tree | 847994a0066d19183a996645f397c0a984be4d2e /src/xterm.c | |
parent | e98ab3f458b25812eff1b3a7ce6429caece4c891 (diff) | |
download | emacs-f681b76a7c43ff54f1aba276f09b8fa0e0dea578.tar.gz |
Simplify X premultipled pixel allocation code
* src/xterm.c (x_premultiply_pixel): New function.
(x_query_colors): Improve documentation.
(x_draw_fringe_bitmap, x_query_frame_background_color): Use
x_premultiply_pixel.
Diffstat (limited to 'src/xterm.c')
-rw-r--r-- | src/xterm.c | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/src/xterm.c b/src/xterm.c index 60d48165650..5947145ce06 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7645,6 +7645,46 @@ x_after_update_window_line (struct window *w, struct glyph_row *desired_row) #endif } +/* Generate a premultiplied pixel value for COLOR with ALPHA applied + on the given display. COLOR will be modified. The display must + use a visual that supports an alpha channel. + + This is possibly dead code on builds which do not support + XRender. */ + +#ifndef USE_CAIRO + +static unsigned long +x_premultiply_pixel (struct x_display_info *dpyinfo, + XColor *color, double alpha) +{ + unsigned long pixel; + + eassert (dpyinfo->alpha_bits); + + /* Multiply the RGB channels. */ + color->red *= alpha; + color->green *= alpha; + color->blue *= alpha; + + /* First, allocate a fully opaque pixel. */ + pixel = x_make_truecolor_pixel (dpyinfo, color->red, + color->green, + color->blue); + + /* Next, erase the alpha component. */ + pixel &= ~dpyinfo->alpha_mask; + + /* And add an alpha channel. */ + pixel |= (((unsigned long) (alpha * 65535) + >> (16 - dpyinfo->alpha_bits)) + << dpyinfo->alpha_offset); + + return pixel; +} + +#endif + static void x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fringe_bitmap_params *p) @@ -7734,18 +7774,15 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, if (FRAME_DISPLAY_INFO (f)->alpha_bits && f->alpha_background < 1.0) { + /* Extend the background color with an alpha channel + according to f->alpha_background. */ bg.pixel = background; x_query_colors (f, &bg, 1); - bg.red *= f->alpha_background; - bg.green *= f->alpha_background; - bg.blue *= f->alpha_background; - background = x_make_truecolor_pixel (FRAME_DISPLAY_INFO (f), - bg.red, bg.green, bg.blue); - background &= ~FRAME_DISPLAY_INFO (f)->alpha_mask; - background |= (((unsigned long) (f->alpha_background * 0xffff) - >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits)) - << FRAME_DISPLAY_INFO (f)->alpha_offset); + background + = x_premultiply_pixel (FRAME_DISPLAY_INFO (f), + &bg, + f->alpha_background); } /* Draw the bitmap. I believe these small pixmaps can be cached @@ -8894,7 +8931,11 @@ x_color_cells (Display *dpy, int *ncells) /* On frame F, translate pixel colors to RGB values for the NCOLORS - colors in COLORS. Use cached information, if available. */ + colors in COLORS. Use cached information, if available. + + Pixel values are in unsigned normalized format, meaning that + extending missing bits is done straightforwardly without any + complex colorspace conversions. */ void x_query_colors (struct frame *f, XColor *colors, int ncolors) @@ -8942,6 +8983,7 @@ x_query_colors (struct frame *f, XColor *colors, int ncolors) colors[i].green = (g * gmult) >> 16; colors[i].blue = (b * bmult) >> 16; } + return; } @@ -8984,16 +9026,10 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor) { bg.pixel = background; x_query_colors (f, &bg, 1); - bg.red *= f->alpha_background; - bg.green *= f->alpha_background; - bg.blue *= f->alpha_background; - - background = x_make_truecolor_pixel (FRAME_DISPLAY_INFO (f), - bg.red, bg.green, bg.blue); - background &= ~FRAME_DISPLAY_INFO (f)->alpha_mask; - background |= (((unsigned long) (f->alpha_background * 0xffff) - >> (16 - FRAME_DISPLAY_INFO (f)->alpha_bits)) - << FRAME_DISPLAY_INFO (f)->alpha_offset); + + background + = x_premultiply_pixel (FRAME_DISPLAY_INFO (f), + &bg, f->alpha_background); } #endif } |