emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 79896d3eb7: Improve portability of alpha channel handling on True


From: Po Lu
Subject: master 79896d3eb7: Improve portability of alpha channel handling on TrueColor visuals
Date: Mon, 31 Jan 2022 05:05:54 -0500 (EST)

branch: master
commit 79896d3eb7f0d2e351196e5c896e21001b75f436
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Improve portability of alpha channel handling on TrueColor visuals
    
    * src/xfns.c (select_visual): Always ask for a TrueColor visual.
    * src/xfont.c (xfont_draw):
    * src/xftfont.c (xftfont_draw): Test `alpha_bits' instead of
    n_planes.
    * src/xterm.c (x_fill_rectangle, x_clear_rectangle): Likewise.
    (x_query_colors, x_alloc_nearest_color): Remove code that
    hard-coded alpha mask.
    (x_term_init): Calculate alpha bits and offset and populate
    field appropriately.
    * src/xterm.h (struct x_display_info): New fields `alpha_bits'
    and `alpha_offset'.
    (x_make_truecolor_pixel): Stop hardcoding the value of the alpha
    mask.
---
 src/xfns.c    |  5 ++-
 src/xfont.c   |  2 +-
 src/xftfont.c |  2 +-
 src/xterm.c   | 97 +++++++++++++++++++++++++++++++++++------------------------
 src/xterm.h   | 11 ++++---
 5 files changed, 71 insertions(+), 46 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 8887b92241..656e68f099 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6401,8 +6401,11 @@ select_visual (struct x_display_info *dpyinfo)
       /* First attempt to use 32-bit visual if available */
 
       vinfo_template.depth = 32;
+      vinfo_template.class = TrueColor;
 
-      vinfo = XGetVisualInfo (dpy, VisualScreenMask | VisualDepthMask,
+      vinfo = XGetVisualInfo (dpy, (VisualScreenMask
+                                   | VisualDepthMask
+                                   | VisualClassMask),
                              &vinfo_template, &n_visuals);
 
       if (n_visuals > 0)
diff --git a/src/xfont.c b/src/xfont.c
index 78f5f19bc8..684c28ab21 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -1005,7 +1005,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int 
x, int y,
 
 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
   if (with_background
-      && FRAME_DISPLAY_INFO (s->f)->n_planes == 32
+      && FRAME_DISPLAY_INFO (s->f)->alpha_bits
       && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
     {
       x_xr_ensure_picture (s->f);
diff --git a/src/xftfont.c b/src/xftfont.c
index cfbf7cdc7a..6a2b2086df 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -503,7 +503,7 @@ xftfont_draw (struct glyph_string *s, int from, int to, int 
x, int y,
 
 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
       if (with_background
-         && FRAME_DISPLAY_INFO (s->f)->n_planes == 32
+         && FRAME_DISPLAY_INFO (s->f)->alpha_bits
          && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
        {
          x_xr_ensure_picture (s->f);
diff --git a/src/xterm.c b/src/xterm.c
index edafd88211..dc4e53759e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1356,7 +1356,7 @@ x_fill_rectangle (struct frame *f, GC gc, int x, int y, 
int width, int height,
 #else
 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
   if (respect_alpha_background
-      && FRAME_DISPLAY_INFO (f)->n_planes == 32
+      && FRAME_DISPLAY_INFO (f)->alpha_bits
       && FRAME_CHECK_XR_VERSION (f, 0, 2))
     {
       x_xr_ensure_picture (f);
@@ -1398,7 +1398,7 @@ x_clear_rectangle (struct frame *f, GC gc, int x, int y, 
int width, int height,
 #else
 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
   if (respect_alpha_background
-      && FRAME_DISPLAY_INFO (f)->n_planes == 32
+      && FRAME_DISPLAY_INFO (f)->alpha_bits
       && FRAME_CHECK_XR_VERSION (f, 0, 2))
     {
       x_xr_ensure_picture (f);
@@ -2976,12 +2976,6 @@ x_query_colors (struct frame *f, XColor *colors, int 
ncolors)
          colors[i].green = (g * gmult) >> 16;
          colors[i].blue = (b * bmult) >> 16;
        }
-
-      if (FRAME_DISPLAY_INFO (f)->n_planes == 32)
-       {
-         for (i = 0; i < ncolors; ++i)
-           colors[i].pixel |= ((unsigned long) 0xFF << 24);
-       }
       return;
     }
 
@@ -2999,12 +2993,6 @@ x_query_colors (struct frame *f, XColor *colors, int 
ncolors)
     }
 
   XQueryColors (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), colors, ncolors);
-
-  if (FRAME_DISPLAY_INFO (f)->n_planes == 32)
-    {
-      for (i = 0; i < ncolors; ++i)
-       colors[i].pixel |= ((unsigned long) 0xFF << 24);
-    }
 }
 
 /* Store F's background color into *BGCOLOR.  */
@@ -3158,7 +3146,9 @@ x_alloc_nearest_color (struct frame *f, Colormap cmap, 
XColor *color)
 
   gamma_correct (f, color);
 
-  if (dpyinfo->red_bits > 0)
+  if (dpyinfo->red_bits > 0
+      && (dpyinfo->n_planes != 32
+         || dpyinfo->alpha_bits > 0))
     {
       color->pixel = x_make_truecolor_pixel (dpyinfo,
                                             color->red,
@@ -15539,16 +15529,21 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
 
   reset_mouse_highlight (&dpyinfo->mouse_highlight);
 
-  /* See if we can construct pixel values from RGB values.  */
-  if (dpyinfo->visual->class == TrueColor)
+#ifdef HAVE_XRENDER
+  int event_base, error_base;
+  dpyinfo->xrender_supported_p
+    = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
+
+  if (dpyinfo->xrender_supported_p)
     {
-      get_bits_and_offset (dpyinfo->visual->red_mask,
-                           &dpyinfo->red_bits, &dpyinfo->red_offset);
-      get_bits_and_offset (dpyinfo->visual->blue_mask,
-                           &dpyinfo->blue_bits, &dpyinfo->blue_offset);
-      get_bits_and_offset (dpyinfo->visual->green_mask,
-                           &dpyinfo->green_bits, &dpyinfo->green_offset);
+      if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
+                               &dpyinfo->xrender_minor))
+       dpyinfo->xrender_supported_p = false;
+      else
+       dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
+                                                       dpyinfo->visual);
     }
+#endif
 
   /* See if a private colormap is requested.  */
   if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
@@ -15570,6 +15565,46 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
     dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
                                      dpyinfo->visual, AllocNone);
 
+  /* See if we can construct pixel values from RGB values.  */
+  if (dpyinfo->visual->class == TrueColor)
+    {
+      get_bits_and_offset (dpyinfo->visual->red_mask,
+                           &dpyinfo->red_bits, &dpyinfo->red_offset);
+      get_bits_and_offset (dpyinfo->visual->blue_mask,
+                           &dpyinfo->blue_bits, &dpyinfo->blue_offset);
+      get_bits_and_offset (dpyinfo->visual->green_mask,
+                           &dpyinfo->green_bits, &dpyinfo->green_offset);
+
+#ifdef HAVE_XRENDER
+      if (dpyinfo->pict_format)
+       {
+         get_bits_and_offset (((unsigned long) 
dpyinfo->pict_format->direct.alphaMask
+                               << dpyinfo->pict_format->direct.alpha),
+                              &dpyinfo->alpha_bits, &dpyinfo->alpha_offset);
+       }
+      else
+#endif
+       {
+         XColor xc;
+         unsigned long alpha_mask;
+         xc.red = 65535;
+         xc.green = 65535;
+         xc.blue = 65535;
+
+         if (XAllocColor (dpyinfo->display,
+                          dpyinfo->cmap, &xc) != 0)
+           {
+             alpha_mask = xc.pixel & ~(dpyinfo->visual->red_mask
+                                       | dpyinfo->visual->blue_mask
+                                       | dpyinfo->visual->green_mask);
+
+             if (alpha_mask)
+               get_bits_and_offset (alpha_mask, &dpyinfo->alpha_bits,
+                                    &dpyinfo->alpha_offset);
+           }
+       }
+    }
+
 #ifdef HAVE_XDBE
   dpyinfo->supports_xdbe = false;
   int xdbe_major;
@@ -15682,22 +15717,6 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
     }
 #endif
 
-#ifdef HAVE_XRENDER
-  int event_base, error_base;
-  dpyinfo->xrender_supported_p
-    = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
-
-  if (dpyinfo->xrender_supported_p)
-    {
-      if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
-                               &dpyinfo->xrender_minor))
-       dpyinfo->xrender_supported_p = false;
-      else
-       dpyinfo->pict_format = XRenderFindVisualFormat (dpyinfo->display,
-                                                       dpyinfo->visual);
-    }
-#endif
-
 #ifdef HAVE_XFIXES
   int xfixes_event_base, xfixes_error_base;
   dpyinfo->xfixes_supported_p
diff --git a/src/xterm.h b/src/xterm.h
index 5e17d5b721..c8c491a7d3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -460,8 +460,8 @@ struct x_display_info
   int ncolor_cells;
 
   /* Bits and shifts to use to compose pixel values on TrueColor visuals.  */
-  int red_bits, blue_bits, green_bits;
-  int red_offset, blue_offset, green_offset;
+  int red_bits, blue_bits, green_bits, alpha_bits;
+  int red_offset, blue_offset, green_offset, alpha_offset;
 
   /* The type of window manager we have.  If we move FRAME_OUTER_WINDOW
      to x/y 0/0, some window managers (type A) puts the window manager
@@ -1285,8 +1285,11 @@ x_make_truecolor_pixel (struct x_display_info *dpyinfo, 
int r, int g, int b)
   pg = (g >> (16 - dpyinfo->green_bits)) << dpyinfo->green_offset;
   pb = (b >> (16 - dpyinfo->blue_bits))  << dpyinfo->blue_offset;
 
-  if (dpyinfo->n_planes == 32)
-    pa = ((unsigned long) 0xFF << 24);
+  if (dpyinfo->alpha_bits)
+    pa = (((unsigned long) 0xffff >> (16 - dpyinfo->alpha_bits))
+         << dpyinfo->alpha_offset);
+  else
+    pa = 0;
 
   /* Assemble the pixel color.  */
   return pr | pg | pb | pa;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]