X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2Fxo-paint.c;h=6361af72e2d30cdc83dba3b189f89859330c1a2d;hb=7e6e62ac799f806e47f88ba0573fa320c016e8e5;hp=7ab18469f3006edaa2eacc5e3f523cc4f0fbed75;hpb=55606436ae30328c0f8230004dccd483b9e50c19;p=xournal.git diff --git a/src/xo-paint.c b/src/xo-paint.c index 7ab1846..6361af7 100644 --- a/src/xo-paint.c +++ b/src/xo-paint.c @@ -16,6 +16,76 @@ #include "xo-misc.h" #include "xo-paint.h" +/***** Win32 fix for gdk_cursor_new_from_pixmap() by Dirk Gerrits ****/ + +#ifdef WIN32 +gboolean colors_too_similar(const GdkColor *colora, const GdkColor *colorb) +{ + return (abs(colora->red - colorb->red) < 256 && + abs(colora->green - colorb->green) < 256 && + abs(colora->blue - colorb->blue) < 256); +} + +/* gdk_cursor_new_from_pixmap is broken on Windows. + this is a workaround using gdk_cursor_new_from_pixbuf. */ +GdkCursor* fixed_gdk_cursor_new_from_pixmap(GdkPixmap *source, GdkPixmap *mask, + const GdkColor *fg, const GdkColor *bg, + gint x, gint y) +{ + GdkPixmap *rgb_pixmap; + GdkGC *gc; + GdkPixbuf *rgb_pixbuf, *rgba_pixbuf; + GdkCursor *cursor; + int width, height; + + /* HACK! It seems impossible to work with RGBA pixmaps directly in + GDK-Win32. Instead we pick some third color, different from fg + and bg, and use that as the 'transparent color'. We do this using + colors_too_similar (see above) because two colors could be + unequal in GdkColor's 16-bit/sample, but equal in GdkPixbuf's + 8-bit/sample. */ + GdkColor candidates[3] = {{0,65535,0,0}, {0,0,65535,0}, {0,0,0,65535}}; + GdkColor *trans = &candidates[0]; + if (colors_too_similar(trans, fg) || colors_too_similar(trans, bg)) { + trans = &candidates[1]; + if (colors_too_similar(trans, fg) || colors_too_similar(trans, bg)) { + trans = &candidates[2]; + } + } /* trans is now guaranteed to be unique from fg and bg */ + + /* create an empty pixmap to hold the cursor image */ + gdk_drawable_get_size(source, &width, &height); + rgb_pixmap = gdk_pixmap_new(NULL, width, height, 24); + + /* blit the bitmaps defining the cursor onto a transparent background */ + gc = gdk_gc_new(rgb_pixmap); + gdk_gc_set_fill(gc, GDK_SOLID); + gdk_gc_set_rgb_fg_color(gc, trans); + gdk_draw_rectangle(rgb_pixmap, gc, TRUE, 0, 0, width, height); + gdk_gc_set_fill(gc, GDK_OPAQUE_STIPPLED); + gdk_gc_set_stipple(gc, source); + gdk_gc_set_clip_mask(gc, mask); + gdk_gc_set_rgb_fg_color(gc, fg); + gdk_gc_set_rgb_bg_color(gc, bg); + gdk_draw_rectangle(rgb_pixmap, gc, TRUE, 0, 0, width, height); + gdk_gc_unref(gc); + + /* create a cursor out of the created pixmap */ + rgb_pixbuf = gdk_pixbuf_get_from_drawable( + NULL, rgb_pixmap, gdk_colormap_get_system(), 0, 0, 0, 0, width, height); + gdk_pixmap_unref(rgb_pixmap); + rgba_pixbuf = gdk_pixbuf_add_alpha( + rgb_pixbuf, TRUE, trans->red, trans->green, trans->blue); + gdk_pixbuf_unref(rgb_pixbuf); + cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), rgba_pixbuf, x, y); + gdk_pixbuf_unref(rgba_pixbuf); + + return cursor; +} +#define gdk_cursor_new_from_pixmap fixed_gdk_cursor_new_from_pixmap +#endif + + /************** drawing nice cursors *********/ static char cursor_pen_bits[] = {