static void gimp_source_tool_cursor_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, GimpDisplay *display) { GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool); GimpSourceOptions *options = GIMP_SOURCE_TOOL_GET_OPTIONS (tool); GimpCursorType cursor = GIMP_CURSOR_MOUSE; GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE; if (gimp_source_core_use_source (GIMP_SOURCE_CORE (paint_tool->core), options)) { GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask (); if ((state & (toggle_mask | GDK_SHIFT_MASK)) == toggle_mask) { cursor = GIMP_CURSOR_CROSSHAIR_SMALL; } else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable) { modifier = GIMP_CURSOR_MODIFIER_BAD; } } gimp_tool_control_set_cursor (tool->control, cursor); gimp_tool_control_set_cursor_modifier (tool->control, modifier); GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display); }
static gboolean gimp_source_core_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords, GError **error) { GimpSourceCore *source_core = GIMP_SOURCE_CORE (paint_core); GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options); if (! GIMP_PAINT_CORE_CLASS (parent_class)->start (paint_core, drawable, paint_options, coords, error)) { return FALSE; } paint_core->use_saved_proj = FALSE; if (! source_core->set_source && gimp_source_core_use_source (source_core, options)) { if (! source_core->src_drawable) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Set a source image first.")); return FALSE; } if (options->sample_merged && gimp_item_get_image (GIMP_ITEM (source_core->src_drawable)) == gimp_item_get_image (GIMP_ITEM (drawable))) { paint_core->use_saved_proj = TRUE; } } return TRUE; }
static void gimp_source_tool_modifier_key (GimpTool *tool, GdkModifierType key, gboolean press, GdkModifierType state, GimpDisplay *display) { GimpSourceTool *source_tool = GIMP_SOURCE_TOOL (tool); GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool); GimpSourceOptions *options = GIMP_SOURCE_TOOL_GET_OPTIONS (tool); if (gimp_source_core_use_source (GIMP_SOURCE_CORE (paint_tool->core), options) && key == gimp_get_toggle_behavior_mask ()) { gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); if (press) { paint_tool->status = source_tool->status_set_source; source_tool->show_source_outline = FALSE; } else { paint_tool->status = source_tool->status_paint; source_tool->show_source_outline = TRUE; } gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } GIMP_TOOL_CLASS (parent_class)->modifier_key (tool, key, press, state, display); }
void gimp_source_core_motion (GimpSourceCore *source_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, GimpSymmetry *sym) { GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core); GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options); GimpDynamics *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics; GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); GimpPickable *src_pickable = NULL; GeglBuffer *src_buffer = NULL; GeglRectangle src_rect; gint base_src_offset_x; gint base_src_offset_y; gint src_offset_x; gint src_offset_y; GeglBuffer *paint_buffer; gint paint_buffer_x; gint paint_buffer_y; gint paint_area_offset_x; gint paint_area_offset_y; gint paint_area_width; gint paint_area_height; gdouble fade_point; gdouble opacity; GeglNode *op; GimpCoords *origin; GimpCoords *coords; gint n_strokes; gint i; fade_point = gimp_paint_options_get_fade (paint_options, image, paint_core->pixel_dist); origin = gimp_symmetry_get_origin (sym); /* Some settings are based on the original stroke. */ opacity = gimp_dynamics_get_linear_value (dynamics, GIMP_DYNAMICS_OUTPUT_OPACITY, origin, paint_options, fade_point); if (opacity == 0.0) return; base_src_offset_x = source_core->offset_x; base_src_offset_y = source_core->offset_y; if (gimp_source_core_use_source (source_core, options)) { src_pickable = GIMP_PICKABLE (source_core->src_drawable); if (options->sample_merged) { GimpImage *src_image = gimp_pickable_get_image (src_pickable); gint off_x, off_y; src_pickable = GIMP_PICKABLE (src_image); gimp_item_get_offset (GIMP_ITEM (source_core->src_drawable), &off_x, &off_y); base_src_offset_x += off_x; base_src_offset_y += off_y; } gimp_pickable_flush (src_pickable); } gimp_brush_core_eval_transform_dynamics (GIMP_BRUSH_CORE (paint_core), drawable, paint_options, origin); n_strokes = gimp_symmetry_get_size (sym); for (i = 0; i < n_strokes; i++) { coords = gimp_symmetry_get_coords (sym, i); paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable, paint_options, coords, &paint_buffer_x, &paint_buffer_y, NULL, NULL); if (! paint_buffer) continue; paint_area_offset_x = 0; paint_area_offset_y = 0; paint_area_width = gegl_buffer_get_width (paint_buffer); paint_area_height = gegl_buffer_get_height (paint_buffer); src_offset_x = base_src_offset_x; src_offset_y = base_src_offset_y; if (gimp_source_core_use_source (source_core, options)) { /* When using a source, use the same for every stroke. */ src_offset_x = src_offset_x - coords->x + origin->x; src_offset_y = src_offset_y - coords->y + origin->y; src_buffer = GIMP_SOURCE_CORE_GET_CLASS (source_core)->get_source (source_core, drawable, paint_options, src_pickable, src_offset_x, src_offset_y, paint_buffer, paint_buffer_x, paint_buffer_y, &paint_area_offset_x, &paint_area_offset_y, &paint_area_width, &paint_area_height, &src_rect); if (! src_buffer) continue; } /* Set the paint buffer to transparent */ gegl_buffer_clear (paint_buffer, NULL); op = gimp_symmetry_get_operation (sym, i, gegl_buffer_get_width (paint_buffer), gegl_buffer_get_height (paint_buffer)); GIMP_SOURCE_CORE_GET_CLASS (source_core)->motion (source_core, drawable, paint_options, coords, op, opacity, src_pickable, src_buffer, &src_rect, src_offset_x, src_offset_y, paint_buffer, paint_buffer_x, paint_buffer_y, paint_area_offset_x, paint_area_offset_y, paint_area_width, paint_area_height); if (src_buffer) g_object_unref (src_buffer); } }
static void gimp_source_tool_draw (GimpDrawTool *draw_tool) { GimpSourceTool *source_tool = GIMP_SOURCE_TOOL (draw_tool); GimpSourceOptions *options = GIMP_SOURCE_TOOL_GET_OPTIONS (draw_tool); GimpSourceCore *source; source = GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (draw_tool)->core); GIMP_DRAW_TOOL_CLASS (parent_class)->draw (draw_tool); if (gimp_source_core_use_source (source, options) && source->src_drawable && source_tool->src_display) { GimpDisplayShell *src_shell; gint off_x; gint off_y; src_shell = gimp_display_get_shell (source_tool->src_display); gimp_item_get_offset (GIMP_ITEM (source->src_drawable), &off_x, &off_y); if (source_tool->src_outline) { gimp_display_shell_remove_tool_item (src_shell, source_tool->src_outline); source_tool->src_outline = NULL; } if (source_tool->show_source_outline) { source_tool->src_outline = gimp_brush_tool_create_outline (GIMP_BRUSH_TOOL (source_tool), source_tool->src_display, source_tool->src_x + off_x, source_tool->src_y + off_y); if (source_tool->src_outline) { gimp_display_shell_add_tool_item (src_shell, source_tool->src_outline); g_object_unref (source_tool->src_outline); } } if (source_tool->src_outline) { if (source_tool->src_handle) { gimp_display_shell_remove_tool_item (src_shell, source_tool->src_handle); source_tool->src_handle = NULL; } } else { if (! source_tool->src_handle) { source_tool->src_handle = gimp_canvas_handle_new (src_shell, GIMP_HANDLE_CROSS, GIMP_HANDLE_ANCHOR_CENTER, source_tool->src_x + off_x, source_tool->src_y + off_y, GIMP_TOOL_HANDLE_SIZE_CROSS, GIMP_TOOL_HANDLE_SIZE_CROSS); gimp_display_shell_add_tool_item (src_shell, source_tool->src_handle); g_object_unref (source_tool->src_handle); } else { gimp_canvas_handle_set_position (source_tool->src_handle, source_tool->src_x + off_x, source_tool->src_y + off_y); } } } }
static void gimp_source_tool_oper_update (GimpTool *tool, const GimpCoords *coords, GdkModifierType state, gboolean proximity, GimpDisplay *display) { GimpPaintTool *paint_tool = GIMP_PAINT_TOOL (tool); GimpSourceTool *source_tool = GIMP_SOURCE_TOOL (tool); GimpSourceOptions *options = GIMP_SOURCE_TOOL_GET_OPTIONS (tool); GimpSourceCore *source; source = GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core); if (proximity) { if (gimp_source_core_use_source (source, options)) paint_tool->status_ctrl = source_tool->status_set_source_ctrl; else paint_tool->status_ctrl = NULL; } GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, proximity, display); if (gimp_source_core_use_source (source, options)) { if (source->src_drawable == NULL) { GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask (); if (state & toggle_mask) { gimp_tool_replace_status (tool, display, "%s", source_tool->status_set_source); } else { gimp_tool_replace_status (tool, display, "%s-%s", gimp_get_mod_string (toggle_mask), source_tool->status_set_source); } } else { gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool)); source_tool->src_x = source->src_x; source_tool->src_y = source->src_y; if (! source->first_stroke) { switch (options->align_mode) { case GIMP_SOURCE_ALIGN_YES: source_tool->src_x = coords->x + source->offset_x; source_tool->src_y = coords->y + source->offset_y; break; case GIMP_SOURCE_ALIGN_REGISTERED: source_tool->src_x = coords->x; source_tool->src_y = coords->y; break; default: break; } } gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool)); } } }
void gimp_source_core_motion (GimpSourceCore *source_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords) { GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core); GimpSourceOptions *options = GIMP_SOURCE_OPTIONS (paint_options); GimpDynamics *dynamics = GIMP_BRUSH_CORE (paint_core)->dynamics; GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); GimpPickable *src_pickable = NULL; GeglBuffer *src_buffer = NULL; GeglRectangle src_rect; gint src_offset_x; gint src_offset_y; GeglBuffer *paint_buffer; gint paint_buffer_x; gint paint_buffer_y; gint paint_area_offset_x; gint paint_area_offset_y; gint paint_area_width; gint paint_area_height; gdouble fade_point; gdouble opacity; fade_point = gimp_paint_options_get_fade (paint_options, image, paint_core->pixel_dist); opacity = gimp_dynamics_get_linear_value (dynamics, GIMP_DYNAMICS_OUTPUT_OPACITY, coords, paint_options, fade_point); if (opacity == 0.0) return; src_offset_x = source_core->offset_x; src_offset_y = source_core->offset_y; if (gimp_source_core_use_source (source_core, options)) { src_pickable = GIMP_PICKABLE (source_core->src_drawable); if (options->sample_merged) { GimpImage *src_image = gimp_pickable_get_image (src_pickable); gint off_x, off_y; src_pickable = GIMP_PICKABLE (src_image); gimp_item_get_offset (GIMP_ITEM (source_core->src_drawable), &off_x, &off_y); src_offset_x += off_x; src_offset_y += off_y; } gimp_pickable_flush (src_pickable); } paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable, paint_options, coords, &paint_buffer_x, &paint_buffer_y); if (! paint_buffer) return; paint_area_offset_x = 0; paint_area_offset_y = 0; paint_area_width = gegl_buffer_get_width (paint_buffer); paint_area_height = gegl_buffer_get_height (paint_buffer); if (gimp_source_core_use_source (source_core, options)) { src_buffer = GIMP_SOURCE_CORE_GET_CLASS (source_core)->get_source (source_core, drawable, paint_options, src_pickable, src_offset_x, src_offset_y, paint_buffer, paint_buffer_x, paint_buffer_y, &paint_area_offset_x, &paint_area_offset_y, &paint_area_width, &paint_area_height, &src_rect); if (! src_buffer) return; } /* Set the paint buffer to transparent */ gegl_buffer_clear (paint_buffer, NULL); GIMP_SOURCE_CORE_GET_CLASS (source_core)->motion (source_core, drawable, paint_options, coords, opacity, src_pickable, src_buffer, &src_rect, src_offset_x, src_offset_y, paint_buffer, paint_buffer_x, paint_buffer_y, paint_area_offset_x, paint_area_offset_y, paint_area_width, paint_area_height); if (src_buffer) g_object_unref (src_buffer); }
static void gimp_clone_motion (GimpSourceCore *source_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, const GimpCoords *coords, gdouble opacity, GimpPickable *src_pickable, GeglBuffer *src_buffer, GeglRectangle *src_rect, gint src_offset_x, gint src_offset_y, GeglBuffer *paint_buffer, gint paint_buffer_x, gint paint_buffer_y, gint paint_area_offset_x, gint paint_area_offset_y, gint paint_area_width, gint paint_area_height) { GimpPaintCore *paint_core = GIMP_PAINT_CORE (source_core); GimpCloneOptions *options = GIMP_CLONE_OPTIONS (paint_options); GimpSourceOptions *source_options = GIMP_SOURCE_OPTIONS (paint_options); GimpContext *context = GIMP_CONTEXT (paint_options); GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable)); gdouble fade_point; gdouble force; if (gimp_source_core_use_source (source_core, source_options)) { gegl_buffer_copy (src_buffer, GEGL_RECTANGLE (src_rect->x, src_rect->y, paint_area_width, paint_area_height), paint_buffer, GEGL_RECTANGLE (paint_area_offset_x, paint_area_offset_y, 0, 0)); } else if (options->clone_type == GIMP_PATTERN_CLONE) { GimpPattern *pattern = gimp_context_get_pattern (context); GeglBuffer *src_buffer = gimp_pattern_create_buffer (pattern); gegl_buffer_set_pattern (paint_buffer, GEGL_RECTANGLE (paint_area_offset_x, paint_area_offset_y, paint_area_width, paint_area_height), src_buffer, - paint_buffer_x - src_offset_x, - paint_buffer_y - src_offset_y); g_object_unref (src_buffer); } else { g_return_if_reached (); } fade_point = gimp_paint_options_get_fade (paint_options, image, paint_core->pixel_dist); force = gimp_dynamics_get_linear_value (GIMP_BRUSH_CORE (paint_core)->dynamics, GIMP_DYNAMICS_OUTPUT_FORCE, coords, paint_options, fade_point); gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable, coords, MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), gimp_paint_options_get_brush_mode (paint_options), force, /* In fixed mode, paint incremental so the * individual brushes are properly applied * on top of each other. * Otherwise the stuff we paint is seamless * and we don't need intermediate masking. */ source_options->align_mode == GIMP_SOURCE_ALIGN_FIXED ? GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT); }