예제 #1
0
GimpLayer *
gimp_image_pick_layer (const GimpImage *image,
                       gint             x,
                       gint             y)
{
  GList *all_layers;
  GList *list;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  all_layers = gimp_image_get_layer_list (image);

  for (list = all_layers; list; list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      gint       off_x, off_y;

      gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);

      if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
                                        x - off_x, y - off_y) > 63)
        {
          g_list_free (all_layers);

          return layer;
        }
    }

  g_list_free (all_layers);

  return NULL;
}
예제 #2
0
static GValueArray *
selection_value_invoker (GimpProcedure      *procedure,
                         Gimp               *gimp,
                         GimpContext        *context,
                         GimpProgress       *progress,
                         const GValueArray  *args,
                         GError            **error)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  GimpImage *image;
  gint32 x;
  gint32 y;
  gint32 value = 0;

  image = gimp_value_get_image (&args->values[0], gimp);
  x = g_value_get_int (&args->values[1]);
  y = g_value_get_int (&args->values[2]);

  if (success)
    {
      value = gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)), x, y);
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_int (&return_vals->values[1], value);

  return return_vals;
}
예제 #3
0
GimpTextLayer *
gimp_image_pick_text_layer (const GimpImage *image,
                            gint             x,
                            gint             y)
{
  GList *all_layers;
  GList *list;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);

  all_layers = gimp_image_get_layer_list (image);

  for (list = all_layers; list; list = g_list_next (list))
    {
      GimpLayer *layer = list->data;
      gint       off_x, off_y;

      gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);

      if (GIMP_IS_TEXT_LAYER (layer) &&
          x >= off_x &&
          y >= off_y &&
          x <  off_x + gimp_item_get_width  (GIMP_ITEM (layer)) &&
          y <  off_y + gimp_item_get_height (GIMP_ITEM (layer)))
        {
          g_list_free (all_layers);

          return GIMP_TEXT_LAYER (layer);
        }
      else if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
                                             x - off_x, y - off_y) > 63)
        {
          /*  a normal layer covers any possible text layers below,
           *  bail out
           */

          break;
        }
    }

  g_list_free (all_layers);

  return NULL;
}
예제 #4
0
static GimpValueArray *
selection_value_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  GimpImage *image;
  gint32 x;
  gint32 y;
  gint32 value = 0;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  x = g_value_get_int (gimp_value_array_index (args, 1));
  y = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      gdouble val;

      val= gimp_pickable_get_opacity_at (GIMP_PICKABLE (gimp_image_get_mask (image)),
                                         x, y);

      value = ROUND (CLAMP (val, 0.0, 1.0) * 255.0);
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_int (gimp_value_array_index (return_vals, 1), value);

  return return_vals;
}
/*
 * This function is called if the user clicks and releases the left
 * button without moving it.  There are the things we might want
 * to do here:
 * 1) If there is an existing rectangle and we are inside it, we
 *    convert it into a selection.
 * 2) If there is an existing rectangle and we are outside it, we
 *    clear it.
 * 3) If there is no rectangle and there is a floating selection,
 *    we anchor it.
 * 4) If there is no rectangle and we are inside the selection, we
 *    create a rectangle from the selection bounds.
 * 5) If there is no rectangle and we are outside the selection,
 *    we clear the selection.
 */
static gboolean
gimp_rectangle_select_tool_execute (GimpRectangleTool *rectangle,
                                    gint               x,
                                    gint               y,
                                    gint               w,
                                    gint               h)
{
  GimpTool                       *tool = GIMP_TOOL (rectangle);
  GimpRectangleSelectTool        *rect_sel_tool;
  GimpRectangleSelectToolPrivate *priv;

  rect_sel_tool = GIMP_RECTANGLE_SELECT_TOOL (rectangle);
  priv          = GIMP_RECTANGLE_SELECT_TOOL_GET_PRIVATE (rect_sel_tool);

  if (w == 0 && h == 0 && tool->display != NULL)
    {
      GimpImage   *image     = gimp_display_get_image (tool->display);
      GimpChannel *selection = gimp_image_get_mask (image);
      gint         pressx;
      gint         pressy;

      if (gimp_image_get_floating_selection (image))
        {
          floating_sel_anchor (gimp_image_get_floating_selection (image));
          gimp_image_flush (image);
          return TRUE;
        }

      pressx = ROUND (priv->press_x);
      pressy = ROUND (priv->press_y);

      /*  if the click was inside the marching ants  */
      if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (selection),
                                        pressx, pressy) > 0.5)
        {
          gint x1, y1, x2, y2;

          if (gimp_channel_bounds (selection, &x1, &y1, &x2, &y2))
            {
              g_object_set (rectangle,
                            "x1", x1,
                            "y1", y1,
                            "x2", x2,
                            "y2", y2,
                            NULL);
            }

          gimp_rectangle_tool_set_function (rectangle,
                                            GIMP_RECTANGLE_TOOL_MOVING);

          return FALSE;
        }
      else
        {
          GimpTool       *tool = GIMP_TOOL (rectangle);
          GimpChannelOps  operation;

          /* prevent this change from halting the tool */
          gimp_tool_control_push_preserve (tool->control, TRUE);

          /* We can conceptually think of a click outside of the
           * selection as adding a 0px selection. Behave intuitivly
           * for the current selection mode
           */
          operation = gimp_rectangle_select_tool_get_operation (rect_sel_tool);
          switch (operation)
            {
            case GIMP_CHANNEL_OP_REPLACE:
            case GIMP_CHANNEL_OP_INTERSECT:
              gimp_channel_clear (selection, NULL, TRUE);
              gimp_image_flush (image);
              break;

            case GIMP_CHANNEL_OP_ADD:
            case GIMP_CHANNEL_OP_SUBTRACT:
            default:
              /* Do nothing */
              break;
            }

          gimp_tool_control_pop_preserve (tool->control);
        }
    }

  gimp_rectangle_select_tool_update_option_defaults (rect_sel_tool, FALSE);

  /* Reset the automatic undo/redo mechanism */
  priv->undo = NULL;
  priv->redo = NULL;

  return TRUE;
}