static void gimp_blend_tool_create_graph (GimpBlendTool *blend_tool) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); GeglNode *graph, *output, *render; /* render_node is not supposed to be recreated */ g_return_if_fail (blend_tool->graph == NULL); graph = gegl_node_new (); output = gegl_node_get_output_proxy (graph, "output"); render = gegl_node_new_child (graph, "operation", "gimp:blend", NULL); gegl_node_link (render, output); blend_tool->graph = graph; blend_tool->render_node = render; gegl_node_set (render, "context", context, NULL); }
static void gimp_blend_tool_start_preview (GimpBlendTool *blend_tool, GimpDisplay *display) { GimpTool *tool = GIMP_TOOL (blend_tool); GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); tool->display = display; tool->drawable = drawable; if (blend_tool->grabbed_point != POINT_FILL_MODE) { gimp_blend_tool_create_image_map (blend_tool, drawable); /* Initially sync all of the properties */ gimp_gegl_config_proxy_sync (GIMP_OBJECT (options), blend_tool->render_node); /* Connect signal handlers for the gradient */ gimp_blend_tool_set_gradient (blend_tool, context->gradient); } if (! gimp_draw_tool_is_active (GIMP_DRAW_TOOL (blend_tool))) gimp_draw_tool_start (GIMP_DRAW_TOOL (blend_tool), display); }
static void gimp_blend_tool_create_image_map (GimpBlendTool *blend_tool, GimpDrawable *drawable) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); if (! blend_tool->graph) gimp_blend_tool_create_graph (blend_tool); blend_tool->image_map = gimp_image_map_new (drawable, C_("undo-type", "Blend"), blend_tool->graph, GIMP_STOCK_TOOL_BLEND); gimp_image_map_set_region (blend_tool->image_map, GIMP_IMAGE_MAP_REGION_DRAWABLE); g_signal_connect (blend_tool->image_map, "flush", G_CALLBACK (gimp_blend_tool_image_map_flush), blend_tool); gimp_image_map_set_mode (blend_tool->image_map, gimp_context_get_opacity (context), gimp_context_get_paint_mode (context)); }
static gboolean gimp_blend_tool_is_shapeburst (GimpBlendTool *blend_tool) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); return options->gradient_type >= GIMP_GRADIENT_SHAPEBURST_ANGULAR && options->gradient_type <= GIMP_GRADIENT_SHAPEBURST_DIMPLED; }
static void gimp_blend_tool_create_graph (GimpBlendTool *blend_tool) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); GeglNode *output; /* render_node is not supposed to be recreated */ g_return_if_fail (blend_tool->graph == NULL); blend_tool->graph = gegl_node_new (); blend_tool->dist_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:buffer-source", "buffer", blend_tool->dist_buffer, NULL); #if 0 blend_tool->subtract_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:subtract", NULL); blend_tool->divide_node = gegl_node_new_child (blend_tool->graph, "operation", "gegl:divide", NULL); #endif blend_tool->render_node = gegl_node_new_child (blend_tool->graph, "operation", "gimp:blend", "context", context, NULL); output = gegl_node_get_output_proxy (blend_tool->graph, "output"); gegl_node_link_many (blend_tool->dist_node, #if 0 blend_tool->subtract_node, blend_tool->divide_node, #endif blend_tool->render_node, output, NULL); gimp_blend_tool_update_graph (blend_tool); }
static void gimp_blend_tool_set_gradient (GimpBlendTool *blend_tool, GimpGradient *gradient) { GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (blend_tool); GimpContext *context = GIMP_CONTEXT (options); if (blend_tool->gradient) { g_signal_handlers_disconnect_by_func (blend_tool->gradient, G_CALLBACK (gimp_blend_tool_gradient_dirty), blend_tool); g_signal_handlers_disconnect_by_func (context, G_CALLBACK (gimp_blend_tool_gradient_dirty), blend_tool); g_object_unref (blend_tool->gradient); } blend_tool->gradient = gradient; if (blend_tool->gradient) { g_object_ref (gradient); g_signal_connect_swapped (blend_tool->gradient, "dirty", G_CALLBACK (gimp_blend_tool_gradient_dirty), blend_tool); if (gimp_gradient_has_fg_bg_segments (blend_tool->gradient)) { g_signal_connect_swapped (context, "background-changed", G_CALLBACK (gimp_blend_tool_gradient_dirty), blend_tool); g_signal_connect_swapped (context, "foreground-changed", G_CALLBACK (gimp_blend_tool_gradient_dirty), blend_tool); } if (blend_tool->render_node) gegl_node_set (blend_tool->render_node, "gradient", blend_tool->gradient, NULL); } }
static gboolean gimp_blend_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool); if (! GIMP_TOOL_CLASS (parent_class)->initialize (tool, display, error)) { return FALSE; } if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot modify the pixels of layer groups.")); return FALSE; } if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("The active layer's pixels are locked.")); return FALSE; } if (! gimp_item_is_visible (GIMP_ITEM (drawable))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("The active layer is not visible.")); return FALSE; } if (! gimp_context_get_gradient (GIMP_CONTEXT (options))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("No gradient available for use with this tool.")); return FALSE; } return TRUE; }
static void gimp_blend_tool_commit (GimpBlendTool *blend_tool) { GimpTool *tool = GIMP_TOOL (blend_tool); GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool); GimpPaintOptions *paint_options = GIMP_PAINT_OPTIONS (options); GimpContext *context = GIMP_CONTEXT (options); GimpImage *image = gimp_display_get_image (tool->display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpProgress *progress; gint off_x; gint off_y; progress = gimp_progress_start (GIMP_PROGRESS (tool), FALSE, _("Blending")); gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); gimp_drawable_blend (drawable, context, gimp_context_get_gradient (context), gimp_context_get_paint_mode (context), options->gradient_type, gimp_context_get_opacity (context), options->offset, paint_options->gradient_options->gradient_repeat, paint_options->gradient_options->gradient_reverse, options->supersample, options->supersample_depth, options->supersample_threshold, options->dither, blend_tool->start_x - off_x, blend_tool->start_y - off_y, blend_tool->end_x - off_x, blend_tool->end_y - off_y, progress); if (progress) gimp_progress_end (progress); gimp_image_flush (image); }
static void gimp_blend_tool_button_release (GimpTool *tool, const GimpCoords *coords, guint32 time, GdkModifierType state, GimpButtonReleaseType release_type, GimpDisplay *display) { GimpBlendTool *blend_tool = GIMP_BLEND_TOOL (tool); GimpBlendOptions *options = GIMP_BLEND_TOOL_GET_OPTIONS (tool); GimpPaintOptions *paint_options = GIMP_PAINT_OPTIONS (options); GimpContext *context = GIMP_CONTEXT (options); GimpImage *image = gimp_display_get_image (display); gimp_tool_pop_status (tool, display); gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool)); gimp_tool_control_halt (tool->control); if ((release_type != GIMP_BUTTON_RELEASE_CANCEL) && ((blend_tool->start_x != blend_tool->end_x) || (blend_tool->start_y != blend_tool->end_y))) { GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpProgress *progress; gint off_x; gint off_y; progress = gimp_progress_start (GIMP_PROGRESS (tool), _("Blending"), FALSE); gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); gimp_drawable_blend (drawable, context, GIMP_CUSTOM_MODE, gimp_context_get_paint_mode (context), options->gradient_type, gimp_context_get_opacity (context), options->offset, paint_options->gradient_options->gradient_repeat, paint_options->gradient_options->gradient_reverse, options->supersample, options->supersample_depth, options->supersample_threshold, options->dither, blend_tool->start_x - off_x, blend_tool->start_y - off_y, blend_tool->end_x - off_x, blend_tool->end_y - off_y, progress); if (progress) gimp_progress_end (progress); gimp_image_flush (image); } tool->display = NULL; tool->drawable = NULL; }