Skip to content

Commit

Permalink
Pixmap: Fix import of bitmap data.
Browse files Browse the repository at this point in the history
Custom (1-bit) cursors now actually look correct.
  • Loading branch information
waddlesplash committed Nov 21, 2023
1 parent 07f4710 commit 6b5ad44
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
7 changes: 7 additions & 0 deletions xlib/Bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ extern "C" {
#define ROUNDDOWN(a, b) (((a) / (b)) * (b))
#define ROUNDUP(a, b) ROUNDDOWN((a) + (b) - 1, b)

static uint8_t
REVERSE_BITS(uint8_t b)
{
// http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv
return ((b * 0x0202020202ULL) & 0x010884422010ULL) % 0x3ff;
}

#ifdef __cplusplus
} // extern "C"
#endif
12 changes: 11 additions & 1 deletion xlib/Pixmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
*/

#include <X11/Xlib.h>

#include <interface/Bitmap.h>
#include <support/StackOrHeapArray.h>

#include "Drawing.h"
#include "Drawables.h"
Expand Down Expand Up @@ -41,9 +43,17 @@ extern "C" Pixmap
XCreateBitmapFromData(Display* display, Drawable d,
const char* data, unsigned int width, unsigned int height)
{
const int32 bpr = (width + 7) / 8, bytesLength = bpr * height;

// Bitmap data is "MSB first", but we need "LSB first" for the import.
// Additionally, B_GRAY1 interprets a 1 as 0x00 and 0 as 0xFF, so we need to invert.
BStackOrHeapArray<uint8, 128> converted(bpr * height);
for (int i = 0; i < bytesLength; i++)
converted[i] = ~REVERSE_BITS(data[i]);

BRect rect(brect_from_xrect(make_xrect(0, 0, width, height)));
XPixmap* pixmap = new XPixmap(display, rect, 1);
pixmap->offscreen()->ImportBits(data, width * height, ROUNDUP(width, 8), 0, B_GRAY1);
pixmap->offscreen()->ImportBits(converted, width * height, bpr, 0, B_GRAY1);
return pixmap->id();
}

Expand Down

0 comments on commit 6b5ad44

Please sign in to comment.