示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
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);
    }
}
示例#5
0
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);
            }
        }
    }
}
示例#6
0
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));
        }
    }
}
示例#7
0
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);
}
示例#8
0
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);
}