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/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <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))))
|
#define GET_BIT(ptr, bit) (*(ptr + bit / 8) & (1 << (7 - (bit % 8))))
|
||||||
|
|
||||||
static uint32
|
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 offs;
|
||||||
uint32 argb;
|
uint32 argb;
|
||||||
uint8 alpha;
|
uint8 alpha;
|
||||||
uint8 *pxor;
|
uint8 *pxor;
|
||||||
|
|
||||||
|
*xor_flag = 0;
|
||||||
switch (bpp)
|
switch (bpp)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@ -2929,11 +2931,8 @@ get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp)
|
|||||||
// andmask bit is low, we should
|
// andmask bit is low, we should
|
||||||
// render a black pixle due to we can
|
// render a black pixle due to we can
|
||||||
// not xor blit in X11.
|
// not xor blit in X11.
|
||||||
|
|
||||||
// TODO: add outline to make this
|
|
||||||
// prettier on black backgrounds.
|
|
||||||
|
|
||||||
argb = 0xff000000;
|
argb = 0xff000000;
|
||||||
|
*xor_flag = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
argb = (alpha << 24) | (argb ? 0xffffff : 0x000000);
|
argb = (alpha << 24) | (argb ? 0xffffff : 0x000000);
|
||||||
@ -2956,14 +2955,55 @@ get_pixel(uint32 idx, uint8 * andmask, uint8 * xormask, int bpp)
|
|||||||
return argb;
|
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
|
RD_HCURSOR
|
||||||
ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
||||||
int height, uint8 * andmask, uint8 * xormask, int bpp)
|
int height, uint8 * andmask, uint8 * xormask, int bpp)
|
||||||
{
|
{
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
XcursorPixel *out;
|
XcursorPixel *out;
|
||||||
XcursorImage *cimg;
|
XcursorImage *cimg, *tmp;
|
||||||
uint32 x, y, oidx, idx, argb;
|
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",
|
logger(GUI, Debug, "ui_create_cursor(): xhot=%d, yhot=%d, width=%d, height=%d, bpp=%d",
|
||||||
xhot, yhot, width, height, bpp);
|
xhot, yhot, width, height, bpp);
|
||||||
@ -2986,6 +3026,8 @@ ui_create_cursor(unsigned int xhot, unsigned int yhot, int width,
|
|||||||
cimg->yhot = yhot;
|
cimg->yhot = yhot;
|
||||||
|
|
||||||
out = cimg->pixels;
|
out = cimg->pixels;
|
||||||
|
xor = 0;
|
||||||
|
outline = 0;
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
for (x = 0; x < width; x++)
|
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;
|
idx = y * width + x;
|
||||||
argb = get_pixel(idx, andmask, xormask, bpp);
|
argb = get_pixel(idx, andmask, xormask, bpp, &xor);
|
||||||
out[oidx] = argb;
|
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);
|
cursor = XcursorImageLoadCursor(g_display, cimg);
|
||||||
XcursorImageDestroy(cimg);
|
XcursorImageDestroy(cimg);
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
|
Loading…
Reference in New Issue
Block a user