app: port GimpDisplayShell pen drawing to cairo

This commit is contained in:
Michael Natterer
2010-08-23 21:59:27 +02:00
parent 3a1ba90507
commit 18d3882c5c
10 changed files with 68 additions and 123 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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__ */

View File

@ -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);

View File

@ -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;

View File

@ -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)