Some cursors are hard to see on dark background
The new cursor rendering code that was added will render 1bpp XOR cursors as plain black cursors. This introduces a problem were the cursor is not visible on dark backgrounds. This change adds a white outlined rendering of the shape to those specific cursors.
This commit is contained in:
parent
96cf016028
commit
0954ac3ca5
74
xwin.c
74
xwin.c
@ -24,6 +24,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
@ -2910,13 +2911,14 @@ ui_destroy_glyph(RD_HGLYPH glyph)
|
||||
#define GET_BIT(ptr, bit) (*(ptr + bit / 8) & (1 << (7 - (bit % 8))))
|
||||
|
||||
static uint32
|
||||
get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp)
|
||||
get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp, uint8 * xor_flag)
|
||||
{
|
||||
uint32 offs;
|
||||
uint32 argb;
|
||||
uint8 alpha;
|
||||
uint8 *pxor;
|
||||
|
||||
*xor_flag = 0;
|
||||
switch (bpp)
|
||||
{
|
||||
case 1:
|
||||
@ -2929,11 +2931,8 @@ get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp)
|
||||
// andmask bit is low, we should
|
||||
// render a black pixle due to we can
|
||||
// not xor blit in X11.
|
||||
|
||||
// TODO: add outline to make this
|
||||
// prettier on black backgrounds.
|
||||
|
||||
argb = 0xff000000;
|
||||
*xor_flag = 1;
|
||||
}
|
||||
else
|
||||
argb = (alpha << 24) | (argb ? 0xffffff : 0x000000);
|
||||
@ -2956,14 +2955,55 @@ get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp)
|
||||
return argb;
|
||||
}
|
||||
|
||||
/* Copies the pixles from src to dest with given color and offset */
|
||||
static inline void
|
||||
xcursor_stencil(XcursorImage * src, XcursorImage * dst, int dx, int dy, uint32 argb)
|
||||
{
|
||||
uint32 x, y, si, di;
|
||||
assert(src->width == dst->width);
|
||||
assert(src->height == dst->height);
|
||||
|
||||
for (y = 0; y < src->height; y++)
|
||||
{
|
||||
for (x = 0; x < src->width; x++)
|
||||
{
|
||||
si = y * src->width + x;
|
||||
if (!src->pixels[si])
|
||||
continue;
|
||||
|
||||
if ((y + dy) < 0 || (y + dy) >= dst->height)
|
||||
continue;
|
||||
if ((x + dx) < 0 || (x + dx) >= dst->width)
|
||||
continue;
|
||||
di = (y + dy) * src->width + (x + dx);
|
||||
dst->pixels[di] = argb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
xcursor_merge(XcursorImage * src, XcursorImage * dst)
|
||||
{
|
||||
uint32 i;
|
||||
assert(src->width == dst->width);
|
||||
assert(src->height == dst->height);
|
||||
for (i = 0; i < src->width * src->height; i++)
|
||||
{
|
||||
if (!src->pixels[i])
|
||||
continue;
|
||||
dst->pixels[i] = src->pixels[i];
|
||||
}
|
||||
}
|
||||
|
||||
RD_HCURSOR
|
||||
ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
||||
int height, uint8 * andmask, uint8 * xormask, int bpp)
|
||||
{
|
||||
Cursor cursor;
|
||||
XcursorPixel *out;
|
||||
XcursorImage *cimg;
|
||||
XcursorImage *cimg, *tmp;
|
||||
uint32 x, y, oidx, idx, argb;
|
||||
uint8 outline, xor;
|
||||
|
||||
logger(GUI, Debug, "ui_create_cursor(): xhot=%d, yhot=%d, width=%d, height=%d, bpp=%d",
|
||||
xhot, yhot, width, height, bpp);
|
||||
@ -2986,6 +3026,8 @@ ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
||||
cimg->yhot = yhot;
|
||||
|
||||
out = cimg->pixels;
|
||||
xor = 0;
|
||||
outline = 0;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
@ -2999,11 +3041,29 @@ ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
||||
}
|
||||
|
||||
idx = y * width + x;
|
||||
argb = get_pixel(idx, andmask, xormask, bpp);
|
||||
argb = get_pixel(idx, andmask, xormask, bpp, &xor);
|
||||
out[oidx] = argb;
|
||||
if (xor)
|
||||
outline = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Render a white outline of cursor shape when xor
|
||||
// pixels are identified in cursor
|
||||
if (outline)
|
||||
{
|
||||
tmp = XcursorImageCreate(width, height);
|
||||
memset(tmp->pixels, 0, tmp->width * tmp->height * 4);
|
||||
xcursor_stencil(cimg, tmp, -1, 0, 0xffffffff);
|
||||
xcursor_stencil(cimg, tmp, 1, 0, 0xffffffff);
|
||||
xcursor_stencil(cimg, tmp, 0, -1, 0xffffffff);
|
||||
xcursor_stencil(cimg, tmp, 0, 1, 0xffffffff);
|
||||
xcursor_merge(cimg, tmp);
|
||||
xcursor_merge(tmp, cimg);
|
||||
XcursorImageDestroy(tmp);
|
||||
}
|
||||
|
||||
cursor = XcursorImageLoadCursor(g_display, cimg);
|
||||
XcursorImageDestroy(cimg);
|
||||
if (!cursor)
|
||||
|
Loading…
Reference in New Issue
Block a user