From 18d3882c5c4a9e210506cb1b37facee939299587 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Mon, 23 Aug 2010 21:59:27 +0200 Subject: [PATCH] app: port GimpDisplayShell pen drawing to cairo --- app/display/gimpcanvas.c | 27 ------- app/display/gimpcanvas.h | 3 - app/display/gimpdisplayshell-draw.c | 102 ++++++------------------ app/display/gimpdisplayshell-draw.h | 3 +- app/display/gimpdisplayshell-handlers.c | 6 -- app/display/gimpdisplayshell-style.c | 34 ++++++++ app/display/gimpdisplayshell-style.h | 5 ++ app/display/gimpdisplayshell.c | 6 -- app/display/gimpdisplayshell.h | 1 - app/tools/gimpforegroundselecttool.c | 4 + 10 files changed, 68 insertions(+), 123 deletions(-) diff --git a/app/display/gimpcanvas.c b/app/display/gimpcanvas.c index d252dd0bff..77227e66f3 100644 --- a/app/display/gimpcanvas.c +++ b/app/display/gimpcanvas.c @@ -407,7 +407,6 @@ gimp_canvas_gc_new (GimpCanvas *canvas, values.stipple = canvas->stipple[0]; break; - case GIMP_CANVAS_STYLE_CUSTOM: default: return NULL; } @@ -953,32 +952,6 @@ gimp_canvas_set_stipple_index (GimpCanvas *canvas, gdk_gc_set_stipple (canvas->gc[style], canvas->stipple[index]); } -/** - * gimp_canvas_set_custom_gc: - * @canvas: a #GimpCanvas widget - * @gc: a #GdkGC; - * - * The #GimpCanvas widget has an extra style for a custom #GdkGC. This - * function allows you to set the @gc for the %GIMP_CANVAS_STYLE_CUSTOM. - * Drawing with the custom style only works if you set a #GdkGC - * earlier. Since the custom #GdkGC can under certain circumstances - * be destroyed by #GimpCanvas, you should always set the custom gc - * before calling a #GimpCanvas drawing function with - * %GIMP_CANVAS_STYLE_CUSTOM. - **/ -void -gimp_canvas_set_custom_gc (GimpCanvas *canvas, - GdkGC *gc) -{ - if (gc) - g_object_ref (gc); - - if (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]) - g_object_unref (canvas->gc[GIMP_CANVAS_STYLE_CUSTOM]); - - canvas->gc[GIMP_CANVAS_STYLE_CUSTOM] = gc; -} - /** * gimp_canvas_set_bg_color: * @canvas: a #GimpCanvas widget diff --git a/app/display/gimpcanvas.h b/app/display/gimpcanvas.h index e085706302..2be5ec3300 100644 --- a/app/display/gimpcanvas.h +++ b/app/display/gimpcanvas.h @@ -35,7 +35,6 @@ typedef enum GIMP_CANVAS_STYLE_LAYER_BOUNDARY, GIMP_CANVAS_STYLE_LAYER_GROUP_BOUNDARY, GIMP_CANVAS_STYLE_LAYER_MASK_ACTIVE, - GIMP_CANVAS_STYLE_CUSTOM, GIMP_CANVAS_NUM_STYLES } GimpCanvasStyle; @@ -154,8 +153,6 @@ void gimp_canvas_set_clip_region (GimpCanvas *canvas, void gimp_canvas_set_stipple_index (GimpCanvas *canvas, GimpCanvasStyle style, guint index); -void gimp_canvas_set_custom_gc (GimpCanvas *canvas, - GdkGC *gc); void gimp_canvas_set_bg_color (GimpCanvas *canvas, GimpRGB *color); diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index 180cff36ec..b6d209f2fc 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -55,13 +55,6 @@ #include "gimpdisplayshell-transform.h" -/* local function prototypes */ - -static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell, - GimpContext *context, - GimpActiveColor active); - - /* public functions */ /** @@ -394,46 +387,45 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell, void gimp_display_shell_draw_pen (GimpDisplayShell *shell, + cairo_t *cr, const GimpVector2 *points, - gint num_points, + gint n_points, GimpContext *context, GimpActiveColor color, gint width) { - GimpCanvas *canvas; - GdkGC *gc; - GdkGCValues values; - GdkPoint *coords; + gint i; + gint x, y; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (cr != NULL); g_return_if_fail (GIMP_IS_CONTEXT (context)); - g_return_if_fail (num_points == 0 || points != NULL); + g_return_if_fail (n_points == 0 || points != NULL); - canvas = GIMP_CANVAS (shell->canvas); + if (n_points == 0) + return; - coords = g_new (GdkPoint, MAX (2, num_points)); + gimp_display_shell_set_pen_style (shell, cr, context, color, width); - gimp_display_shell_transform_points (shell, - points, coords, num_points, FALSE); + gimp_display_shell_transform_xy (shell, + points[0].x, points[0].y, + &x, &y, FALSE); - if (num_points == 1) + cairo_move_to (cr, x, y); + + for (i = 1; i < n_points; i++) { - coords[1] = coords[0]; - num_points = 2; + gimp_display_shell_transform_xy (shell, + points[i].x, points[i].y, + &x, &y, FALSE); + + cairo_line_to (cr, x, y); } - gc = gimp_display_shell_get_pen_gc (shell, context, color); + if (i == 1) + cairo_line_to (cr, x, y); - values.line_width = MAX (1, width); - gdk_gc_set_values (gc, &values, GDK_GC_LINE_WIDTH); - - gimp_canvas_set_custom_gc (canvas, gc); - - gimp_canvas_draw_lines (canvas, GIMP_CANVAS_STYLE_CUSTOM, coords, num_points); - - gimp_canvas_set_custom_gc (canvas, NULL); - - g_free (coords); + cairo_stroke (cr); } void @@ -695,51 +687,3 @@ gimp_display_shell_draw_area (GimpDisplayShell *shell, } } } - - -/* private functions */ - -static GdkGC * -gimp_display_shell_get_pen_gc (GimpDisplayShell *shell, - GimpContext *context, - GimpActiveColor active) -{ - GdkGCValues values; - GimpRGB rgb; - GdkColor color; - - if (shell->pen_gc) - return shell->pen_gc; - - values.line_style = GDK_LINE_SOLID; - values.cap_style = GDK_CAP_ROUND; - values.join_style = GDK_JOIN_ROUND; - - shell->pen_gc = gdk_gc_new_with_values (gtk_widget_get_window (shell->canvas), - &values, (GDK_GC_LINE_STYLE | - GDK_GC_CAP_STYLE | - GDK_GC_JOIN_STYLE)); - - switch (active) - { - case GIMP_ACTIVE_COLOR_FOREGROUND: - gimp_context_get_foreground (context, &rgb); - break; - - case GIMP_ACTIVE_COLOR_BACKGROUND: - gimp_context_get_background (context, &rgb); - break; - } - - gimp_rgb_get_gdk_color (&rgb, &color); - gdk_gc_set_rgb_fg_color (shell->pen_gc, &color); - - g_object_add_weak_pointer (G_OBJECT (shell->pen_gc), - (gpointer) &shell->pen_gc); - - g_signal_connect_object (context, "notify", - G_CALLBACK (g_object_unref), - shell->pen_gc, G_CONNECT_SWAPPED); - - return shell->pen_gc; -} diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h index 88e5fdec38..b4d8aadc8f 100644 --- a/app/display/gimpdisplayshell-draw.h +++ b/app/display/gimpdisplayshell-draw.h @@ -36,8 +36,9 @@ void gimp_display_shell_draw_guides (GimpDisplayShell *shell, void gimp_display_shell_draw_grid (GimpDisplayShell *shell, cairo_t *cr); void gimp_display_shell_draw_pen (GimpDisplayShell *shell, + cairo_t *cr, const GimpVector2 *points, - gint num_points, + gint n_points, GimpContext *context, GimpActiveColor color, gint width); diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c index f494e858f9..b919849a9e 100644 --- a/app/display/gimpdisplayshell-handlers.c +++ b/app/display/gimpdisplayshell-handlers.c @@ -304,12 +304,6 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell) gimp_display_shell_icon_update_stop (shell); - if (shell->pen_gc) - { - g_object_unref (shell->pen_gc); - shell->pen_gc = NULL; - } - g_signal_handlers_disconnect_by_func (shell->display->config, gimp_display_shell_quality_notify_handler, shell); diff --git a/app/display/gimpdisplayshell-style.c b/app/display/gimpdisplayshell-style.c index 25bb49faea..cfba3b6a07 100644 --- a/app/display/gimpdisplayshell-style.c +++ b/app/display/gimpdisplayshell-style.c @@ -28,6 +28,7 @@ #include "display-types.h" +#include "core/gimpcontext.h" #include "core/gimpgrid.h" #include "gimpdisplayshell.h" @@ -148,6 +149,39 @@ gimp_display_shell_set_cursor_style (GimpDisplayShell *shell, cairo_translate (cr, 0.5, 0.5); } +void +gimp_display_shell_set_pen_style (GimpDisplayShell *shell, + cairo_t *cr, + GimpContext *context, + GimpActiveColor active, + gint width) +{ + GimpRGB rgb; + + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); + g_return_if_fail (cr != NULL); + g_return_if_fail (GIMP_IS_CONTEXT (context)); + + cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); + cairo_set_line_width (cr, width); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_translate (cr, 0.5, 0.5); + + switch (active) + { + case GIMP_ACTIVE_COLOR_FOREGROUND: + gimp_context_get_foreground (context, &rgb); + break; + + case GIMP_ACTIVE_COLOR_BACKGROUND: + gimp_context_get_background (context, &rgb); + break; + } + + cairo_set_source_rgb (cr, rgb.r, rgb.g, rgb.b); +} + /* private functions */ diff --git a/app/display/gimpdisplayshell-style.h b/app/display/gimpdisplayshell-style.h index 83bc3c5f1a..a71f683b3b 100644 --- a/app/display/gimpdisplayshell-style.h +++ b/app/display/gimpdisplayshell-style.h @@ -33,6 +33,11 @@ void gimp_display_shell_set_grid_style (GimpDisplayShell *shell, GimpGrid *grid); void gimp_display_shell_set_cursor_style (GimpDisplayShell *shell, cairo_t *cr); +void gimp_display_shell_set_pen_style (GimpDisplayShell *shell, + cairo_t *cr, + GimpContext *context, + GimpActiveColor active, + gint width); #endif /* __GIMP_DISPLAY_SHELL_STYLE_H__ */ diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 2860db3aad..c72310aa1e 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -938,12 +938,6 @@ gimp_display_shell_unrealize (GtkWidget *widget) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (widget); - if (shell->pen_gc) - { - g_object_unref (shell->pen_gc); - shell->pen_gc = NULL; - } - if (shell->nav_popup) gtk_widget_unrealize (shell->nav_popup); diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index d4ebfc905c..bfd4d9816c 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -115,7 +115,6 @@ struct _GimpDisplayShell GList *children; GtkWidget *canvas; /* GimpCanvas widget */ - GdkGC *pen_gc; /* GC for felt pen drawing */ GtkAdjustment *hsbdata; /* adjustments */ GtkAdjustment *vsbdata; diff --git a/app/tools/gimpforegroundselecttool.c b/app/tools/gimpforegroundselecttool.c index 99ebbfd006..196e127b19 100644 --- a/app/tools/gimpforegroundselecttool.c +++ b/app/tools/gimpforegroundselecttool.c @@ -571,7 +571,10 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool) if (fg_select->stroke) { + GimpDisplayShell *shell = gimp_display_get_shell (draw_tool->display); + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (shell->canvas)); gimp_display_shell_draw_pen (gimp_display_get_shell (draw_tool->display), + cr, (const GimpVector2 *)fg_select->stroke->data, fg_select->stroke->len, GIMP_CONTEXT (options), @@ -579,6 +582,7 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool) GIMP_ACTIVE_COLOR_BACKGROUND : GIMP_ACTIVE_COLOR_FOREGROUND), options->stroke_width); + cairo_destroy (cr); } if (fg_select->mask)