mirror of https://github.com/GNOME/gimp.git
app/display/gimpcanvas.c (gimp_canvas_set_custom_gc) do not drop the
2005-08-06 Sven Neumann <sven@gimp.org> * app/display/gimpcanvas.c (gimp_canvas_set_custom_gc) do not drop the reference if the same custom GC is being set again. * app/display/gimpdisplayshell-draw.[ch] * app/display/gimpdisplayshell-handlers.c * app/display/gimpdisplayshell.[ch]: added GC and methods to draw on the canvas with a solid pen. * app/tools/gimpforegroundselectoptions.[ch] * app/tools/gimpforegroundselecttool.c: draw using the new pen functions. Scale the stroke width with the display scale.
This commit is contained in:
parent
90d861bec2
commit
d89f04d500
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2005-08-06 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/display/gimpcanvas.c (gimp_canvas_set_custom_gc) do not
|
||||
drop the reference if the same custom GC is being set again.
|
||||
|
||||
* app/display/gimpdisplayshell-draw.[ch]
|
||||
* app/display/gimpdisplayshell-handlers.c
|
||||
* app/display/gimpdisplayshell.[ch]: added GC and methods to draw
|
||||
on the canvas with a solid pen.
|
||||
|
||||
* app/tools/gimpforegroundselectoptions.[ch]
|
||||
* app/tools/gimpforegroundselecttool.c: draw using the new pen
|
||||
functions. Scale the stroke width with the display scale.
|
||||
|
||||
2005-08-06 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/core/gimppalette-import.c:
|
||||
|
|
|
@ -823,13 +823,13 @@ 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;
|
||||
|
||||
if (gc)
|
||||
g_object_ref (gc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "display-types.h"
|
||||
|
||||
#include "core/gimp-utils.h"
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpgrid.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-guides.h"
|
||||
|
@ -48,6 +49,10 @@
|
|||
|
||||
static GdkGC * gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
|
||||
GimpGrid *grid);
|
||||
static GdkGC * gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
|
||||
GimpContext *context,
|
||||
GimpActiveColor active,
|
||||
gint width);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
@ -293,6 +298,42 @@ gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gimp_display_shell_draw_pen (GimpDisplayShell *shell,
|
||||
const GimpVector2 *points,
|
||||
gint num_points,
|
||||
GimpContext *context,
|
||||
GimpActiveColor color,
|
||||
gint width)
|
||||
{
|
||||
GimpCanvas *canvas;
|
||||
GdkGC *gc;
|
||||
GdkPoint *coords;
|
||||
gint i;
|
||||
|
||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
||||
g_return_if_fail (GIMP_IS_CONTEXT (context));
|
||||
g_return_if_fail (num_points == 0 || points != NULL);
|
||||
|
||||
canvas = GIMP_CANVAS (shell->canvas);
|
||||
|
||||
coords = g_new (GdkPoint, num_points);
|
||||
|
||||
for (i = 0; i < num_points ; i++)
|
||||
gimp_display_shell_transform_xy (shell,
|
||||
points[i].x, points[i].y,
|
||||
&coords[i].x, &coords[i].y,
|
||||
FALSE);
|
||||
|
||||
gc = gimp_display_shell_get_pen_gc (shell, context, color, 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);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_display_shell_draw_sample_point (GimpDisplayShell *shell,
|
||||
GimpSamplePoint *sample_point,
|
||||
|
@ -568,10 +609,58 @@ gimp_display_shell_get_grid_gc (GimpDisplayShell *shell,
|
|||
GDK_GC_JOIN_STYLE));
|
||||
|
||||
gimp_rgb_get_gdk_color (&grid->fgcolor, &fg);
|
||||
gimp_rgb_get_gdk_color (&grid->bgcolor, &bg);
|
||||
|
||||
gdk_gc_set_rgb_fg_color (shell->grid_gc, &fg);
|
||||
|
||||
gimp_rgb_get_gdk_color (&grid->bgcolor, &bg);
|
||||
gdk_gc_set_rgb_bg_color (shell->grid_gc, &bg);
|
||||
|
||||
return shell->grid_gc;
|
||||
}
|
||||
|
||||
static GdkGC *
|
||||
gimp_display_shell_get_pen_gc (GimpDisplayShell *shell,
|
||||
GimpContext *context,
|
||||
GimpActiveColor active,
|
||||
gint width)
|
||||
{
|
||||
GdkGCValues values;
|
||||
GimpRGB rgb;
|
||||
GdkColor color;
|
||||
|
||||
if (shell->pen_gc)
|
||||
return shell->pen_gc;
|
||||
|
||||
values.line_width = MAX (1, width);
|
||||
values.line_style = GDK_LINE_SOLID;
|
||||
values.cap_style = GDK_CAP_ROUND;
|
||||
values.join_style = GDK_JOIN_MITER;
|
||||
|
||||
shell->pen_gc = gdk_gc_new_with_values (shell->canvas->window,
|
||||
&values, (GDK_GC_LINE_WIDTH |
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,12 @@ void gimp_display_shell_draw_guide (GimpDisplayShell *shell,
|
|||
void gimp_display_shell_draw_guides (GimpDisplayShell *shell);
|
||||
void gimp_display_shell_draw_grid (GimpDisplayShell *shell,
|
||||
const GdkRectangle *area);
|
||||
void gimp_display_shell_draw_pen (GimpDisplayShell *shell,
|
||||
const GimpVector2 *points,
|
||||
gint num_points,
|
||||
GimpContext *context,
|
||||
GimpActiveColor color,
|
||||
gint width);
|
||||
void gimp_display_shell_draw_sample_point (GimpDisplayShell *shell,
|
||||
GimpSamplePoint *sample_point,
|
||||
gboolean active);
|
||||
|
|
|
@ -273,6 +273,12 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
|
|||
shell->grid_gc = NULL;
|
||||
}
|
||||
|
||||
if (shell->pen_gc)
|
||||
{
|
||||
g_object_unref (shell->pen_gc);
|
||||
shell->pen_gc = NULL;
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (gimage->gimp->config,
|
||||
gimp_display_shell_ants_speed_notify_handler,
|
||||
shell);
|
||||
|
|
|
@ -254,6 +254,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
|
|||
|
||||
shell->canvas = NULL;
|
||||
shell->grid_gc = NULL;
|
||||
shell->pen_gc = NULL;
|
||||
|
||||
shell->hsbdata = NULL;
|
||||
shell->vsbdata = NULL;
|
||||
|
@ -271,9 +272,9 @@ gimp_display_shell_init (GimpDisplayShell *shell)
|
|||
shell->menubar = NULL;
|
||||
shell->statusbar = NULL;
|
||||
|
||||
shell->render_buf = g_malloc (GIMP_RENDER_BUF_WIDTH *
|
||||
GIMP_RENDER_BUF_HEIGHT *
|
||||
3);
|
||||
shell->render_buf = g_new (guchar,
|
||||
GIMP_RENDER_BUF_WIDTH *
|
||||
GIMP_RENDER_BUF_HEIGHT * 3);
|
||||
|
||||
shell->title_idle_id = 0;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ struct _GimpDisplayShell
|
|||
|
||||
GtkWidget *canvas; /* GimpCanvas widget */
|
||||
GdkGC *grid_gc; /* GC for grid drawing */
|
||||
GdkGC *pen_gc; /* GC for felt pen drawing */
|
||||
|
||||
GtkAdjustment *hsbdata; /* adjustments */
|
||||
GtkAdjustment *vsbdata;
|
||||
|
|
|
@ -93,10 +93,10 @@ gimp_foreground_select_options_class_init (GimpForegroundSelectOptionsClass *kla
|
|||
"background", NULL,
|
||||
FALSE,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_STROKE_WIDTH,
|
||||
"stroke-width", NULL,
|
||||
0.0, 2000.0, 6.0,
|
||||
0);
|
||||
GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_STROKE_WIDTH,
|
||||
"stroke-width", NULL,
|
||||
1, 100, 6,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -113,7 +113,7 @@ gimp_foreground_select_options_set_property (GObject *object,
|
|||
options->background = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_STROKE_WIDTH:
|
||||
options->stroke_width = g_value_get_double (value);
|
||||
options->stroke_width = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
|
@ -135,7 +135,7 @@ gimp_foreground_select_options_get_property (GObject *object,
|
|||
g_value_set_boolean (value, options->background);
|
||||
break;
|
||||
case PROP_STROKE_WIDTH:
|
||||
g_value_set_double (value, options->stroke_width);
|
||||
g_value_set_int (value, options->stroke_width);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
|
|
|
@ -39,7 +39,7 @@ struct _GimpForegroundSelectOptions
|
|||
GimpSelectionOptions parent_instance;
|
||||
|
||||
gboolean background;
|
||||
gdouble stroke_width;
|
||||
gint stroke_width;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "display/gimpdisplay.h"
|
||||
#include "display/gimpdisplayshell.h"
|
||||
#include "display/gimpdisplayshell-draw.h"
|
||||
|
||||
#include "gimpforegroundselecttool.h"
|
||||
#include "gimpforegroundselectoptions.h"
|
||||
|
@ -52,7 +53,7 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
gdouble width;
|
||||
gint width;
|
||||
gboolean background;
|
||||
gint num_points;
|
||||
GimpVector2 *points;
|
||||
|
@ -105,6 +106,7 @@ static void gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg
|
|||
GimpDisplay *gdisp);
|
||||
|
||||
static void gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
||||
GimpDisplay *gdisp,
|
||||
FgSelectStroke *stroke);
|
||||
|
||||
static void gimp_foreground_select_tool_push_stroke (GimpForegroundSelectTool *fg_select,
|
||||
|
@ -123,7 +125,7 @@ gimp_foreground_select_tool_register (GimpToolRegisterCallback callback,
|
|||
(* callback) (GIMP_TYPE_FOREGROUND_SELECT_TOOL,
|
||||
GIMP_TYPE_FOREGROUND_SELECT_OPTIONS,
|
||||
gimp_foreground_select_options_gui,
|
||||
0,
|
||||
GIMP_CONTEXT_FOREGROUND_MASK | GIMP_CONTEXT_BACKGROUND_MASK,
|
||||
"gimp-foreground-select-tool",
|
||||
_("Foreground Select"),
|
||||
_("Extract foreground using SIOX algorithm"),
|
||||
|
@ -443,7 +445,7 @@ gimp_foreground_select_tool_motion (GimpTool *tool,
|
|||
GimpVector2,
|
||||
fg_select->stroke->len - 1);
|
||||
|
||||
if (last->x != coords->x || last->y != coords->y)
|
||||
if (last->x != (gint) coords->x || last->y != (gint) coords->y)
|
||||
{
|
||||
GimpVector2 point = gimp_vector2_new (coords->x, coords->y);
|
||||
|
||||
|
@ -468,10 +470,19 @@ gimp_foreground_select_tool_draw (GimpDrawTool *draw_tool)
|
|||
|
||||
if (fg_select->stroke)
|
||||
{
|
||||
const gdouble *points = (const gdouble *) fg_select->stroke->data;
|
||||
GimpTool *tool = GIMP_TOOL (draw_tool);
|
||||
GimpForegroundSelectOptions *options;
|
||||
|
||||
gimp_draw_tool_draw_lines (draw_tool,
|
||||
points, fg_select->stroke->len, FALSE, FALSE);
|
||||
options = GIMP_FOREGROUND_SELECT_OPTIONS (tool->tool_info->tool_options);
|
||||
|
||||
gimp_display_shell_draw_pen (GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell),
|
||||
(const GimpVector2 *)fg_select->stroke->data,
|
||||
fg_select->stroke->len,
|
||||
GIMP_CONTEXT (options),
|
||||
(options->background ?
|
||||
GIMP_ACTIVE_COLOR_BACKGROUND :
|
||||
GIMP_ACTIVE_COLOR_FOREGROUND),
|
||||
options->stroke_width);
|
||||
}
|
||||
|
||||
if (! fg_select->mask)
|
||||
|
@ -516,16 +527,16 @@ gimp_foreground_select_tool_select (GimpFreeSelectTool *free_sel,
|
|||
width = x2 - x;
|
||||
height = y2 - y;
|
||||
|
||||
/* apply foreground and background markers */
|
||||
for (list = fg_select->strokes; list; list = list->next)
|
||||
gimp_foreground_select_tool_stroke (mask, gdisp, list->data);
|
||||
|
||||
/* restrict working area to double the size of the bounding box */
|
||||
x = MAX (0, x - width / 2);
|
||||
y = MAX (0, y - height / 2);
|
||||
width = MIN (width * 2, gimp_item_width (GIMP_ITEM (mask)) - x);
|
||||
height = MIN (height * 2, gimp_item_height (GIMP_ITEM (mask)) - y);
|
||||
|
||||
/* apply foreground and background markers */
|
||||
for (list = fg_select->strokes; list; list = list->next)
|
||||
gimp_foreground_select_tool_stroke (mask, list->data);
|
||||
|
||||
gimp_drawable_foreground_extract_rect (drawable,
|
||||
GIMP_FOREGROUND_EXTRACT_SIOX,
|
||||
GIMP_DRAWABLE (mask),
|
||||
|
@ -615,14 +626,16 @@ gimp_foreground_select_tool_apply (GimpForegroundSelectTool *fg_select,
|
|||
|
||||
static void
|
||||
gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
||||
GimpDisplay *gdisp,
|
||||
FgSelectStroke *stroke)
|
||||
{
|
||||
GimpScanConvert *scan_convert = gimp_scan_convert_new ();
|
||||
GimpItem *item = GIMP_ITEM (mask);
|
||||
GimpChannel *channel = gimp_channel_new (gimp_item_get_image (item),
|
||||
gimp_item_width (item),
|
||||
gimp_item_height (item),
|
||||
"tmp", NULL);
|
||||
GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (gdisp->shell);
|
||||
GimpScanConvert *scan_convert = gimp_scan_convert_new ();
|
||||
GimpItem *item = GIMP_ITEM (mask);
|
||||
GimpChannel *channel = gimp_channel_new (gimp_item_get_image (item),
|
||||
gimp_item_width (item),
|
||||
gimp_item_height (item),
|
||||
"tmp", NULL);
|
||||
|
||||
/* FIXME: We should be able to get away w/o a temporary drawable
|
||||
* by doing some changes to GimpScanConvert.
|
||||
|
@ -631,7 +644,7 @@ gimp_foreground_select_tool_stroke (GimpChannel *mask,
|
|||
gimp_scan_convert_add_polyline (scan_convert,
|
||||
stroke->num_points, stroke->points, FALSE);
|
||||
gimp_scan_convert_stroke (scan_convert,
|
||||
stroke->width,
|
||||
SCALEFACTOR_Y (shell) * stroke->width,
|
||||
GIMP_JOIN_MITER, GIMP_CAP_ROUND, 10.0,
|
||||
0.0, NULL);
|
||||
gimp_scan_convert_render (scan_convert,
|
||||
|
|
Loading…
Reference in New Issue