From db3eb121df6f89a3e4e77c2b8d031adb08b5b11f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 17 Feb 2016 13:51:08 +0800 Subject: [PATCH 1/2] wayland: Pre-multiply alpha of custom cursor images Since the Wayland SHM buffer format is implicitly premultiplied and the GLFWimage pixels are defined to be non-premultiplied, we need to convert the non-premultiplied pixels to premultiplied when filling the buffer. --- src/internal.h | 7 +++++++ src/wl_window.c | 10 ++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/internal.h b/src/internal.h index 2fe2aee47..2fc47b77f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -233,6 +233,13 @@ typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const c y = t; \ } +// Helper for non-premultiplied alpha to premultiplied alpha conversion +static inline unsigned char _glfwMultiplyAlpha(unsigned char alpha, + unsigned char value) +{ + return (unsigned char) ((value * (unsigned int) alpha) / 255); +} + //======================================================================== // Platform-independent structures diff --git a/src/wl_window.c b/src/wl_window.c index 75aa912e4..db0752ecb 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -571,10 +571,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, unsigned char* target = data; for (i = 0; i < image->width * image->height; i++, source += 4) { - *target++ = source[2]; - *target++ = source[1]; - *target++ = source[0]; - *target++ = source[3]; + unsigned char alpha = source[3]; + + *target++ = _glfwMultiplyAlpha(alpha, source[2]); + *target++ = _glfwMultiplyAlpha(alpha, source[1]); + *target++ = _glfwMultiplyAlpha(alpha, source[0]); + *target++ = alpha; } cursor->wl.buffer = From 0556601a29d6332ab27b9236ed84f4f9a8cd84f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 17 Feb 2016 13:53:57 +0800 Subject: [PATCH 2/2] x11: Premultiply alpha of custom cursor pixel As with Wayland, X11 expects cursor pixels to have the alpha premultiplied, so lets convert the non-premultiplied pixels to premultiplied pixels. Fixes issue 353. --- src/x11_init.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/x11_init.c b/src/x11_init.c index e17a7170c..a521c993a 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -705,10 +705,12 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot) for (i = 0; i < image->width * image->height; i++, target++, source += 4) { - *target = (source[3] << 24) | - (source[0] << 16) | - (source[1] << 8) | - source[2]; + unsigned char alpha = source[3]; + + *target = (alpha << 24) | + (_glfwMultiplyAlpha(alpha, source[0]) << 16) | + (_glfwMultiplyAlpha(alpha, source[1]) << 8) | + _glfwMultiplyAlpha(alpha, source[2]); } cursor = XcursorImageLoadCursor(_glfw.x11.display, native);