Fix #49117: Larger Alternative for Frame Cursor

Internally our "Time" mouse cursor, it comprises up to four digits in
a 2x2 grid.  With each digit being just 7x7 pixels this is very small
on high DPI displays. This PR adds an alternative that shows 12x14
pixel digits, shown when the UI Scale > 1.45. It also changes both
small and large versions to not show a solid black background for
empty digit positions.

Pull Request: https://projects.blender.org/blender/blender/pulls/132767
This commit is contained in:
Harley Acheson
2025-01-16 02:59:49 +01:00
committed by Harley Acheson
parent eebdd83898
commit 1f33b401b3

View File

@@ -112,20 +112,7 @@ static GHOST_TStandardCursor convert_to_ghost_standard_cursor(WMCursorType curs)
}
}
static void window_set_custom_cursor(
wmWindow *win, const uchar mask[16][2], const uchar bitmap[16][2], int hotx, int hoty)
{
GHOST_SetCustomCursorShape(static_cast<GHOST_WindowHandle>(win->ghostwin),
(uint8_t *)bitmap,
(uint8_t *)mask,
16,
16,
hotx,
hoty,
true);
}
static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor)
static void window_set_custom_cursor(wmWindow *win, BCursor *cursor)
{
GHOST_SetCustomCursorShape(static_cast<GHOST_WindowHandle>(win->ghostwin),
(uint8_t *)cursor->bitmap,
@@ -177,7 +164,7 @@ void WM_cursor_set(wmWindow *win, int curs)
BCursor *bcursor = BlenderCursor[curs];
if (bcursor) {
/* Use custom bitmap cursor. */
window_set_custom_cursor_ex(win, bcursor);
window_set_custom_cursor(win, bcursor);
}
else {
/* Fallback to default cursor if no bitmap found. */
@@ -354,7 +341,73 @@ bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event)
return false;
}
void WM_cursor_time(wmWindow *win, int nr)
static bool wm_cursor_time_large(wmWindow *win, int nr)
{
/* 10 16x16 digits. */
const uchar number_bitmaps[][32] = {
{0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x1f, 0x1c, 0x38, 0x0c, 0x30, 0x0c,
0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30,
0x0c, 0x30, 0x1c, 0x38, 0xf8, 0x1f, 0xf0, 0x0f, 0x00, 0x00},
{0x00, 0x00, 0x80, 0x01, 0xc0, 0x01, 0xf0, 0x01, 0xbc, 0x01, 0x8c,
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
0x80, 0x01, 0x80, 0x01, 0xfc, 0x3f, 0xfc, 0x3f, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x1f, 0xf8, 0x3f, 0x1c, 0x30, 0x0c, 0x30, 0x00,
0x30, 0x00, 0x30, 0xe0, 0x3f, 0xf0, 0x1f, 0x38, 0x00, 0x1c, 0x00,
0x0c, 0x00, 0x0c, 0x00, 0xfc, 0x3f, 0xfc, 0x3f, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x1f, 0x1c, 0x38, 0x00, 0x30, 0x00,
0x30, 0x00, 0x38, 0xf0, 0x1f, 0xf0, 0x1f, 0x00, 0x38, 0x00, 0x30,
0x00, 0x30, 0x1c, 0x38, 0xf8, 0x1f, 0xf0, 0x0f, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x80, 0x0f, 0xc0, 0x0d, 0xe0, 0x0c, 0x70,
0x0c, 0x38, 0x0c, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0xfc, 0x3f, 0xfc, 0x3f, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x3f, 0xfc, 0x3f, 0x0c, 0x00, 0x0c, 0x00, 0x0c,
0x00, 0xfc, 0x0f, 0xfc, 0x1f, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30,
0x00, 0x30, 0x0c, 0x38, 0xfc, 0x1f, 0xf8, 0x0f, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x3f, 0xe0, 0x3f, 0x70, 0x00, 0x38, 0x00, 0x1c,
0x00, 0xfc, 0x0f, 0xfc, 0x1f, 0x0c, 0x38, 0x0c, 0x30, 0x0c, 0x30,
0x0c, 0x30, 0x1c, 0x38, 0xf8, 0x1f, 0xf0, 0x0f, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x3f, 0xfc, 0x3f, 0x0c, 0x30, 0x0c, 0x38, 0x00,
0x18, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x07,
0x00, 0x03, 0x80, 0x03, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x1f, 0x1c, 0x38, 0x0c, 0x30, 0x0c,
0x30, 0x1c, 0x38, 0xf8, 0x1f, 0xf8, 0x1f, 0x1c, 0x38, 0x0c, 0x30,
0x0c, 0x30, 0x1c, 0x38, 0xf8, 0x1f, 0xf0, 0x0f, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x1f, 0x1c, 0x38, 0x0c, 0x30, 0x0c,
0x30, 0x0c, 0x30, 0x1c, 0x30, 0xf8, 0x3f, 0xf0, 0x3f, 0x00, 0x38,
0x00, 0x1c, 0x00, 0x0e, 0xfc, 0x07, 0xfc, 0x03, 0x00, 0x00},
};
uchar mask[32][4] = {{0}};
uchar bitmap[32][4] = {{0}};
/* Print number bottom right justified. */
for (int idx = 3; nr && idx >= 0; idx--) {
const uchar *digit = number_bitmaps[nr % 10];
int x = idx % 2;
int y = idx / 2;
for (int i = 0; i < 16; i++) {
bitmap[i + y * 16][x * 2] = digit[i * 2];
bitmap[i + y * 16][(x * 2) + 1] = digit[(i * 2) + 1];
}
for (int i = 0; i < 16; i++) {
mask[i + y * 16][x * 2] = 0xFF;
mask[i + y * 16][(x * 2) + 1] = 0xFF;
}
nr /= 10;
}
return GHOST_SetCustomCursorShape(static_cast<GHOST_WindowHandle>(win->ghostwin),
(uint8_t *)bitmap,
(uint8_t *)mask,
32,
32,
15,
15,
false) == GHOST_kSuccess;
}
static void wm_cursor_time_small(wmWindow *win, int nr)
{
/* 10 8x8 digits. */
const char number_bitmaps[10][8] = {
@@ -369,15 +422,9 @@ void WM_cursor_time(wmWindow *win, int nr)
{0, 60, 66, 66, 60, 66, 66, 60},
{0, 56, 68, 68, 120, 64, 68, 56},
};
uchar mask[16][2];
uchar mask[16][2] = {{0}};
uchar bitmap[16][2] = {{0}};
if (win->lastcursor == 0) {
win->lastcursor = win->cursor;
}
memset(&mask, 0xFF, sizeof(mask));
/* Print number bottom right justified. */
for (int idx = 3; nr && idx >= 0; idx--) {
const char *digit = number_bitmaps[nr % 10];
@@ -387,10 +434,33 @@ void WM_cursor_time(wmWindow *win, int nr)
for (int i = 0; i < 8; i++) {
bitmap[i + y * 8][x] = digit[i];
}
for (int i = 0; i < 8; i++) {
mask[i + y * 8][x] = 0xFF;
}
nr /= 10;
}
window_set_custom_cursor(win, mask, bitmap, 7, 7);
GHOST_SetCustomCursorShape(static_cast<GHOST_WindowHandle>(win->ghostwin),
(uint8_t *)bitmap,
(uint8_t *)mask,
16,
16,
7,
7,
false);
}
void WM_cursor_time(wmWindow *win, int nr)
{
if (win->lastcursor == 0) {
win->lastcursor = win->cursor;
}
/* Use `U.ui_scale` instead of `UI_SCALE_FAC` here to ignore HiDPI/Retina scaling. */
if (U.ui_scale < 1.45f || !wm_cursor_time_large(win, nr)) {
wm_cursor_time_small(win, nr);
}
/* Unset current cursor value so it's properly reset to wmWindow.lastcursor. */
win->cursor = 0;
}