From 683e097d899152d84546bf38b6bf8a06dcef55d6 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 22 Sep 2010 22:19:28 +0200 Subject: [PATCH] app: add cairo drawing support in GimpDrawTool - add boolean "use_cairo" toggle to enable it per tool - split draw() in draw() and undraw() and add cairo variants of drawing - create canvas items in draw_line(), draw_handle() and draw_rectangle() - some related changes --- app/tools/gimpdrawtool.c | 145 +++++++++++++++++++++++++++++++++++++-- app/tools/gimpdrawtool.h | 6 ++ 2 files changed, 145 insertions(+), 6 deletions(-) diff --git a/app/tools/gimpdrawtool.c b/app/tools/gimpdrawtool.c index 4ddf25c18b..857403ce50 100644 --- a/app/tools/gimpdrawtool.c +++ b/app/tools/gimpdrawtool.c @@ -35,6 +35,9 @@ #include "vectors/gimpvectors.h" #include "display/gimpcanvas.h" +#include "display/gimpcanvashandle.h" +#include "display/gimpcanvasline.h" +#include "display/gimpcanvasrectangle.h" #include "display/gimpdisplay.h" #include "display/gimpdisplayshell.h" #include "display/gimpdisplayshell-transform.h" @@ -53,6 +56,7 @@ static void gimp_draw_tool_control (GimpTool *tool, GimpDisplay *display); static void gimp_draw_tool_draw (GimpDrawTool *draw_tool); +static void gimp_draw_tool_undraw (GimpDrawTool *draw_tool); static void gimp_draw_tool_real_draw (GimpDrawTool *draw_tool); static inline void gimp_draw_tool_shift_to_north_west @@ -150,11 +154,13 @@ gimp_draw_tool_control (GimpTool *tool, switch (action) { case GIMP_TOOL_ACTION_PAUSE: - gimp_draw_tool_pause (draw_tool); + if (! draw_tool->use_cairo) + gimp_draw_tool_pause (draw_tool); break; case GIMP_TOOL_ACTION_RESUME: - gimp_draw_tool_resume (draw_tool); + if (! draw_tool->use_cairo) + gimp_draw_tool_resume (draw_tool); break; case GIMP_TOOL_ACTION_HALT: @@ -171,9 +177,75 @@ gimp_draw_tool_draw (GimpDrawTool *draw_tool) if (draw_tool->paused_count == 0 && draw_tool->display) { - GIMP_DRAW_TOOL_GET_CLASS (draw_tool)->draw (draw_tool); + if (draw_tool->use_cairo) + { + GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display); + GdkWindow *window = gtk_widget_get_window (shell->canvas); + GList *list; - draw_tool->is_drawn = ! draw_tool->is_drawn; + if (draw_tool->items) + { + g_list_foreach (draw_tool->items, (GFunc) g_object_unref, NULL); + g_list_free (draw_tool->items); + draw_tool->items = NULL; + } + + GIMP_DRAW_TOOL_GET_CLASS (draw_tool)->draw (draw_tool); + + for (list = draw_tool->items; list; list = g_list_next (list)) + { + GimpCanvasItem *item = list->data; + GdkRegion *region; + + region = gimp_canvas_item_get_extents (item, shell); + gdk_window_invalidate_region (window, region, TRUE); + gdk_region_destroy (region); + } + } + else + { + GIMP_DRAW_TOOL_GET_CLASS (draw_tool)->draw (draw_tool); + } + + draw_tool->is_drawn = TRUE; + } +} + +static void +gimp_draw_tool_undraw (GimpDrawTool *draw_tool) +{ + if (draw_tool->paused_count == 0 && + draw_tool->display) + { + if (draw_tool->use_cairo) + { + GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display); + GdkWindow *window = gtk_widget_get_window (shell->canvas); + GList *list; + + for (list = draw_tool->items; list; list = g_list_next (list)) + { + GimpCanvasItem *item = list->data; + GdkRegion *region; + + region = gimp_canvas_item_get_extents (item, shell); + gdk_window_invalidate_region (window, region, TRUE); + gdk_region_destroy (region); + } + + if (draw_tool->items) + { + g_list_foreach (draw_tool->items, (GFunc) g_object_unref, NULL); + g_list_free (draw_tool->items); + draw_tool->items = NULL; + } + } + else + { + GIMP_DRAW_TOOL_GET_CLASS (draw_tool)->draw (draw_tool); + } + + draw_tool->is_drawn = FALSE; } } @@ -202,7 +274,7 @@ gimp_draw_tool_stop (GimpDrawTool *draw_tool) { g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); - gimp_draw_tool_draw (draw_tool); + gimp_draw_tool_undraw (draw_tool); draw_tool->display = NULL; } @@ -220,7 +292,7 @@ gimp_draw_tool_pause (GimpDrawTool *draw_tool) { g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); - gimp_draw_tool_draw (draw_tool); + gimp_draw_tool_undraw (draw_tool); draw_tool->paused_count++; } @@ -244,6 +316,34 @@ gimp_draw_tool_is_drawn (GimpDrawTool *draw_tool) return draw_tool->is_drawn; } +void +gimp_draw_tool_draw_items (GimpDrawTool *draw_tool, + cairo_t *cr) +{ + GimpDisplayShell *shell; + GdkWindow *window; + GList *list; + + g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); + g_return_if_fail (cr != NULL); + + if (! gimp_draw_tool_is_active (draw_tool) || + ! gimp_draw_tool_is_drawn (draw_tool)) + return; + + g_printerr ("%s: drawing!\n", G_STRFUNC); + + shell = gimp_display_get_shell (draw_tool->display); + window = gtk_widget_get_window (shell->canvas); + + for (list = draw_tool->items; list; list = g_list_next (list)) + { + GimpCanvasItem *item = list->data; + + gimp_canvas_item_draw (item, shell, cr); + } +} + /** * gimp_draw_tool_calc_distance: * @draw_tool: a #GimpDrawTool @@ -364,6 +464,17 @@ gimp_draw_tool_draw_line (GimpDrawTool *draw_tool, g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); + if (draw_tool->use_cairo) + { + GimpCanvasItem *item; + + item = gimp_canvas_line_new (x1, y1, x2, y2); + + draw_tool->items = g_list_append (draw_tool->items, item); + + return; + } + shell = gimp_display_get_shell (draw_tool->display); gimp_display_shell_transform_xy_f (shell, @@ -499,6 +610,17 @@ gimp_draw_tool_draw_rectangle (GimpDrawTool *draw_tool, g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); + if (draw_tool->use_cairo) + { + GimpCanvasItem *item; + + item = gimp_canvas_rectangle_new (x, y, width, height, filled); + + draw_tool->items = g_list_append (draw_tool->items, item); + + return; + } + shell = gimp_display_get_shell (draw_tool->display); gimp_display_shell_transform_xy_f (shell, @@ -725,6 +847,17 @@ gimp_draw_tool_draw_handle (GimpDrawTool *draw_tool, { g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool)); + if (draw_tool->use_cairo) + { + GimpCanvasItem *item; + + item = gimp_canvas_handle_new (type, anchor, x, y, width, height); + + draw_tool->items = g_list_append (draw_tool->items, item); + + return; + } + switch (type) { case GIMP_HANDLE_SQUARE: diff --git a/app/tools/gimpdrawtool.h b/app/tools/gimpdrawtool.h index 1d1660d0c0..e01a3171cc 100644 --- a/app/tools/gimpdrawtool.h +++ b/app/tools/gimpdrawtool.h @@ -42,6 +42,9 @@ struct _GimpDrawTool gint paused_count; /* count to keep track of multiple pauses */ gboolean is_drawn; /* is the stuff we draw currently visible */ + + gboolean use_cairo; + GList *items; }; struct _GimpDrawToolClass @@ -67,6 +70,9 @@ void gimp_draw_tool_resume (GimpDrawTool *draw_tool) gboolean gimp_draw_tool_is_drawn (GimpDrawTool *draw_tool); +void gimp_draw_tool_draw_items (GimpDrawTool *draw_tool, + cairo_t *cr); + gdouble gimp_draw_tool_calc_distance (GimpDrawTool *draw_tool, GimpDisplay *display, gdouble x1,