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; }
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; }
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; }
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; }