=== modified file 'src/arc-context.cpp' --- old/src/arc-context.cpp 2010-08-11 06:43:24 +0000 +++ new/src/arc-context.cpp 2010-09-03 14:42:50 +0000 @@ -107,6 +107,7 @@ event_context->tolerance = 0; event_context->within_tolerance = false; event_context->item_to_select = NULL; + event_context->tool_url = "/tools/shapes/arc"; arc_context->item = NULL; === modified file 'src/event-context.cpp' --- old/src/event-context.cpp 2010-08-28 08:09:45 +0000 +++ new/src/event-context.cpp 2010-09-03 14:22:30 +0000 @@ -44,6 +44,7 @@ #include "desktop.h" #include "desktop-handles.h" #include "desktop-events.h" +#include "desktop-style.h" #include "widgets/desktop-widget.h" #include "sp-namedview.h" #include "selection.h" @@ -62,6 +63,7 @@ #include "ui/tool/control-point.h" #include "shape-editor.h" #include "sp-guide.h" +#include "color.h" static void sp_event_context_class_init(SPEventContextClass *klass); static void sp_event_context_init(SPEventContext *event_context); @@ -141,6 +143,7 @@ event_context->shape_editor = NULL; event_context->_delayed_snap_event = NULL; event_context->_dse_callback_in_process = false; + event_context->tool_url = NULL; } /** @@ -183,17 +186,37 @@ if (w->window) { /* fixme: */ if (ec->cursor_shape) { - GdkBitmap *bitmap = NULL; - GdkBitmap *mask = NULL; - sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, ec->cursor_shape); - if ((bitmap != NULL) && (mask != NULL)) { - if (ec->cursor) - gdk_cursor_unref(ec->cursor); - ec->cursor = gdk_cursor_new_from_pixmap(bitmap, mask, - &w->style->black, &w->style->white, ec->hot_x, - ec->hot_y); - g_object_unref(bitmap); - g_object_unref(mask); + GdkDisplay *display = gdk_display_get_default(); + if (ec->tool_url && gdk_display_supports_cursor_alpha(display) && gdk_display_supports_cursor_color(display)) { + guint32 fillColor = sp_desktop_get_color_tool(ec->desktop, ec->tool_url, true, 0); + guint32 strokeColor = sp_desktop_get_color_tool(ec->desktop, ec->tool_url, false, 0); + double fillOpacity = sp_desktop_get_opacity_tool(ec->desktop, ec->tool_url, true); + double strokeOpacity = sp_desktop_get_opacity_tool(ec->desktop, ec->tool_url, false); + GdkPixbuf *pixbuf = sp_cursor_pixbuf_from_xpm( + ec->cursor_shape, + w->style->black, w->style->white, + SP_RGBA32_U_COMPOSE(SP_RGBA32_R_U(fillColor),SP_RGBA32_G_U(fillColor),SP_RGBA32_B_U(fillColor),SP_COLOR_F_TO_U(fillOpacity)), + SP_RGBA32_U_COMPOSE(SP_RGBA32_R_U(strokeColor),SP_RGBA32_G_U(strokeColor),SP_RGBA32_B_U(strokeColor),SP_COLOR_F_TO_U(strokeOpacity)) + ); + if (pixbuf != NULL) { + if (ec->cursor) + gdk_cursor_unref(ec->cursor); + ec->cursor = gdk_cursor_new_from_pixbuf(display, pixbuf, ec->hot_x, ec->hot_y); + g_object_unref(pixbuf); + } + } else { + GdkBitmap *bitmap = NULL; + GdkBitmap *mask = NULL; + sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, ec->cursor_shape); + if ((bitmap != NULL) && (mask != NULL)) { + if (ec->cursor) + gdk_cursor_unref(ec->cursor); + ec->cursor = gdk_cursor_new_from_pixmap(bitmap, mask, + &w->style->black, &w->style->white, ec->hot_x, + ec->hot_y); + g_object_unref(bitmap); + g_object_unref(mask); + } } } gdk_window_set_cursor(w->window, ec->cursor); === modified file 'src/event-context.h' --- old/src/event-context.h 2010-02-14 08:18:22 +0000 +++ new/src/event-context.h 2010-09-03 14:20:54 +0000 @@ -128,6 +128,8 @@ DelayedSnapEvent *_delayed_snap_event; bool _dse_callback_in_process; + + char const * tool_url; ///< the (preferences) url for the tool (if a subclass corresponding to a tool is used) }; /** === modified file 'src/pixmaps/cursor-ellipse.xpm' --- old/src/pixmaps/cursor-ellipse.xpm 2007-09-16 14:44:48 +0000 +++ new/src/pixmaps/cursor-ellipse.xpm 2010-09-03 14:48:38 +0000 @@ -1,8 +1,10 @@ /* XPM */ static char const *cursor_ellipse_xpm[] = { -"32 32 3 1", +"32 32 5 1", " c None", ". c #FFFFFF", +"% c Stroke", +"* c Fill", "+ c #000000", " ... ", " .+. ", @@ -12,17 +14,17 @@ "....+.... ", " .+. ", " .+. ....... ", -" ... ....+++++.... ", -" ..+++.....+++.. ", -" ..+...........+.. ", -" ..+.............+.. ", -" .+...............+. ", -" .+...............+. ", -" .+...............+. ", -" ..+.............+.. ", -" ..+...........+.. ", -" ..+++.....+++.. ", -" ....+++++.... ", +" ... ....%%%%%.... ", +" ..%%%*****%%%.. ", +" ..%***********%.. ", +" ..%*************%.. ", +" .%***************%. ", +" .%***************%. ", +" .%***************%. ", +" ..%*************%.. ", +" ..%***********%.. ", +" ..%%%*****%%%.. ", +" ....%%%%%.... ", " ....... ", " ", " ", === modified file 'src/pixmaps/cursor-rect.xpm' --- old/src/pixmaps/cursor-rect.xpm 2007-09-16 14:44:48 +0000 +++ new/src/pixmaps/cursor-rect.xpm 2010-09-03 14:18:12 +0000 @@ -1,8 +1,10 @@ /* XPM */ static char const *cursor_rect_xpm[] = { -"32 32 3 1", +"32 32 5 1", " c None", ". c #FFFFFF", +"% c Stroke", +"* c Fill", "+ c #000000", " ... ", " .+. ", @@ -12,17 +14,17 @@ "....+.... ", " .+. ", " .+. ................. ", -" ... .+++++++++++++++. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+.............+. ", -" .+++++++++++++++. ", +" ... .%%%%%%%%%%%%%%%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%*************%. ", +" .%%%%%%%%%%%%%%%. ", " ................. ", " ", " ", === modified file 'src/pixmaps/cursor-star.xpm' --- old/src/pixmaps/cursor-star.xpm 2007-09-16 14:44:48 +0000 +++ new/src/pixmaps/cursor-star.xpm 2010-09-03 14:46:38 +0000 @@ -1,8 +1,10 @@ /* XPM */ static char const *cursor_star_xpm[] = { -"32 32 3 1", +"32 32 5 1", " c None", ". c #FFFFFF", +"% c Stroke", +"* c Fill", "+ c #000000", " ... ", " .+. ", @@ -10,21 +12,21 @@ "....+.... ", ".+++ +++. ", "....+.... .. ", -" .+. .++. ", -" .+. .++. ", -" ... .++. ", -" .+..+. ", -" ........+..+........ ", -" .++++++....++++++. ", -" .++..........++. ", -" ..++......++.. ", -" .+......+. ", -" .+......+. ", -" .+...++...+. ", -" .+.++..++.+. ", -" .+.+.. ..+.+. ", -" .++. .++. ", -" .+. .+. ", +" .+. .%%. ", +" .+. .%%. ", +" ... .%%. ", +" .%**%* ", +" ........%**%........ ", +" .%%%%%%****%%%%%%. ", +" .%%**********%%. ", +" ..%%******%%.. ", +" .%******%. ", +" .%******%. ", +" .%***%%***%. ", +" .%*%%..%%*%. ", +" .%*%.. ..%*%. ", +" .%%. .%%. ", +" .%. .%. ", " .. .. ", " ", " ", === modified file 'src/rect-context.cpp' --- old/src/rect-context.cpp 2010-08-11 06:43:24 +0000 +++ new/src/rect-context.cpp 2010-09-03 14:21:26 +0000 @@ -110,6 +110,7 @@ event_context->tolerance = 0; event_context->within_tolerance = false; event_context->item_to_select = NULL; + event_context->tool_url = "/tools/shapes/rect"; rect_context->item = NULL; === modified file 'src/sp-cursor.cpp' --- old/src/sp-cursor.cpp 2008-01-31 19:06:59 +0000 +++ new/src/sp-cursor.cpp 2010-09-03 14:23:26 +0000 @@ -16,6 +16,8 @@ #include #include #include +#include +#include "color.h" #include "sp-cursor.h" void @@ -32,7 +34,7 @@ g_return_if_fail (colors >= 3); int transparent_color = ' '; - int black_color = '.'; + std::string black_colors; char pixmap_buffer[(32 * 32)/8]; char mask_buffer[(32 * 32)/8]; @@ -51,12 +53,16 @@ p++; } - if (strcmp(p, "None") == 0) { + if (strcmp(p, "None") == 0) { transparent_color = ccode; } + if (strcmp(p, "Stroke") == 0) { + black_colors.push_back(ccode); + } + if (strcmp(p, "#000000") == 0) { - black_color = ccode; + black_colors.push_back(ccode); } } @@ -67,10 +73,10 @@ char maskv = 0; for (int pix = 0; pix < 8; pix++, x++){ - if (xpm[4+y][x] != transparent_color) { + if (xpm[1+colors+y][x] != transparent_color) { maskv |= 1 << pix; - if (xpm[4+y][x] == black_color) { + if (black_colors.find(xpm[1+colors+y][x]) != std::string::npos) { value |= 1 << pix; } } @@ -85,6 +91,73 @@ *mask = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32); } +static void free_cursor_data(guchar *pixels, gpointer data) { + delete [] reinterpret_cast(pixels); +} + +struct RGBA { + guchar v[4]; + RGBA() { v[0] = 0; v[1] = 0; v[2] = 0; v[3] = 0; } + RGBA(guchar r, guchar g, guchar b, guchar a) { v[0] = r; v[1] = g; v[2] = b; v[3] = a; } + operator guint32 const () const { return *reinterpret_cast(v); } +}; + +GdkPixbuf* +sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke) +{ + int height; + int width; + int colors; + int pix; + sscanf(xpm[0], "%d %d %d %d", &height, &width, &colors, &pix); + + //g_return_if_fail (height == 32); + //g_return_if_fail (width == 32); + //g_return_if_fail (colors >= 3); + + std::map colorMap; + + for (int i = 0; i < colors; i++) { + + char const *p = xpm[1 + i]; + char const ccode = *p; + + p++; + while (isspace(*p)) { + p++; + } + p++; + while (isspace(*p)) { + p++; + } + + if (strcmp(p, "None") == 0) { + colorMap.insert(std::make_pair(ccode, RGBA())); + } else if (strcmp(p, "Fill") == 0) { + colorMap.insert(std::make_pair(ccode, RGBA(SP_RGBA32_R_U(fill),SP_RGBA32_G_U(fill),SP_RGBA32_B_U(fill),SP_RGBA32_A_U(fill)))); + } else if (strcmp(p, "Stroke") == 0) { + colorMap.insert(std::make_pair(ccode, RGBA(SP_RGBA32_R_U(stroke),SP_RGBA32_G_U(stroke),SP_RGBA32_B_U(stroke),SP_RGBA32_A_U(stroke)))); + } else if (strcmp(p, "#000000") == 0) { + colorMap.insert(std::make_pair(ccode, RGBA(black.red,black.green,black.blue,255))); + } else if (strcmp(p, "#FFFFFF") == 0) { + colorMap.insert(std::make_pair(ccode, RGBA(white.red,white.green,white.blue,255))); + } else { + colorMap.insert(std::make_pair(ccode, RGBA())); + } + } + + guint32 *pixmap_buffer = new guint32[width * height]; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + std::map::const_iterator it = colorMap.find(xpm[1+colors+y][x]); + pixmap_buffer[y * width + x] = it==colorMap.end() ? 0u : it->second; + } + } + + return gdk_pixbuf_new_from_data(reinterpret_cast(pixmap_buffer), GDK_COLORSPACE_RGB, TRUE, 8, width, height, width*sizeof(guint32), free_cursor_data, NULL); +} + GdkCursor * sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y) { === modified file 'src/sp-cursor.h' --- old/src/sp-cursor.h 2007-09-16 14:42:04 +0000 +++ new/src/sp-cursor.h 2010-09-03 14:07:34 +0000 @@ -4,6 +4,7 @@ #include void sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar const *const *xpm); +GdkPixbuf* sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke); GdkCursor *sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y); #endif === modified file 'src/star-context.cpp' --- old/src/star-context.cpp 2010-08-11 06:43:24 +0000 +++ new/src/star-context.cpp 2010-09-03 14:44:46 +0000 @@ -111,6 +111,7 @@ event_context->tolerance = 0; event_context->within_tolerance = false; event_context->item_to_select = NULL; + event_context->tool_url = "/tools/shapes/star"; star_context->item = NULL;