Code

Applying patch #1415498 by James Kilfiger / zeimusu - Allow color & transparency...
[inkscape.git] / src / sp-cursor.cpp
1 #define __SP_CURSOR_C__
3 /*
4  * Some convenience stuff
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *
9  * Copyright (C) 1999-2002 authors
10  * Copyright (C) 2001-2002 Ximian, Inc.
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #include <string.h>
16 #include <ctype.h>
17 #include "sp-cursor.h"
19 void sp_cursor_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, gchar **xpm)
20 {
21     int height;
22     int width;
23     int colors;
24     int pix;
25     sscanf(xpm[0], "%d %d %d %d", &height, &width, &colors, &pix);
27     g_return_if_fail (height == 32);
28     g_return_if_fail (width == 32);
29     g_return_if_fail (colors >= 3);
31     int transparent_color = ' ';
32     int black_color = '.';
33         
34     char pixmap_buffer[(32 * 32)/8];
35     char mask_buffer[(32 * 32)/8];
37     for (int i = 0; i < colors; i++) {
39         char const *p = xpm[1 + i];
40         char const ccode = *p;
42         p++;
43         while (isspace(*p)) {
44             p++;
45         }
46         p++;
47         while (isspace(*p)) {
48             p++;
49         }
51         if (strcmp(p, "None") == 0) {
52             transparent_color = ccode;
53         }
54         
55         if (strcmp(p, "#000000") == 0) {
56             black_color = ccode;
57         }
58     }
60     for (int y = 0; y < 32; y++) {
61         for (int x = 0; x < 32; ) {
62             
63             char value = 0;
64             char maskv = 0;
65                         
66             for (int pix = 0; pix < 8; pix++, x++){
67                 if (xpm [4+y][x] != transparent_color) {
68                     maskv |= 1 << pix;
70                     if (xpm [4+y][x] == black_color) {
71                         value |= 1 << pix;
72                     }
73                 }
74             }
75             
76             pixmap_buffer[(y * 4 + x/8)-1] = value;
77             mask_buffer[(y * 4 + x/8)-1] = maskv;
78         }
79     }
81     *bitmap = gdk_bitmap_create_from_data(NULL, pixmap_buffer, 32, 32);
82     *mask   = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32);
83 }
85 GdkCursor *sp_cursor_new_from_xpm (gchar **xpm, gint hot_x, gint hot_y)
86 {
87 GdkDisplay *display=gdk_display_get_default();
88     if (
89             gdk_display_supports_cursor_alpha(display) & 
90             gdk_display_supports_cursor_color(display)
91        )
92     {
93         GdkPixbuf *pixbuf=NULL;
94         GdkCursor *new_cursor=NULL;
95         pixbuf=gdk_pixbuf_new_from_xpm_data((const char**)xpm);
96         if (pixbuf != NULL){
97             new_cursor = gdk_cursor_new_from_pixbuf(display,pixbuf,hot_x,hot_y);
98         }
99         return new_cursor;
100     }
101     else
102     {
103         GdkColor const fg = { 0, 0, 0, 0 };
104         GdkColor const bg = { 0, 65535, 65535, 65535 };
105  
106         GdkBitmap *bitmap = NULL;
107         GdkBitmap *mask = NULL;
109         sp_cursor_bitmap_and_mask_from_xpm (&bitmap, &mask, xpm);
110         if ( bitmap != NULL && mask != NULL ) {
111             GdkCursor *new_cursor = gdk_cursor_new_from_pixmap (bitmap, mask,
112                     &fg, &bg,
113                     hot_x, hot_y);
114             g_object_unref (bitmap);
115             g_object_unref (mask);
116             return new_cursor;
117         }
118     }
119     return NULL;
122 /*
123   Local Variables:
124   mode:c++
125   c-file-style:"stroustrup"
126   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
127   indent-tabs-mode:nil
128   fill-column:99
129   End:
130 */
131 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :