static void stroke_dialog_response (GtkWidget *widget, gint response_id, GtkWidget *dialog) { GimpStrokeOptions *options; GimpItem *item; GimpImage *image; GimpContext *context; GtkWidget *combo; item = g_object_get_data (G_OBJECT (dialog), "gimp-item"); options = g_object_get_data (G_OBJECT (dialog), "gimp-stroke-options"); combo = g_object_get_data (G_OBJECT (dialog), "gimp-tool-menu");; image = gimp_item_get_image (item); context = GIMP_VIEWABLE_DIALOG (dialog)->context; switch (response_id) { case RESPONSE_RESET: { GimpToolInfo *tool_info = gimp_context_get_tool (context); gimp_config_reset (GIMP_CONFIG (options)); gimp_container_view_select_item (GIMP_CONTAINER_VIEW (combo), GIMP_VIEWABLE (tool_info->paint_info)); } break; case GTK_RESPONSE_OK: { GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpStrokeOptions *saved_options; GError *error = NULL; if (! drawable) { gimp_message_literal (context->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, _("There is no active layer or channel " "to stroke to.")); return; } saved_options = g_object_get_data (G_OBJECT (context->gimp), "saved-stroke-options"); if (saved_options) g_object_ref (saved_options); else saved_options = gimp_stroke_options_new (context->gimp, context, TRUE); gimp_config_sync (G_OBJECT (options), G_OBJECT (saved_options), 0); g_object_set_data_full (G_OBJECT (context->gimp), "saved-stroke-options", saved_options, (GDestroyNotify) g_object_unref); if (! gimp_item_stroke (item, drawable, context, options, FALSE, TRUE, NULL, &error)) { gimp_message_literal (context->gimp, G_OBJECT (widget), GIMP_MESSAGE_WARNING, error ? error->message : "NULL"); g_clear_error (&error); return; } gimp_image_flush (image); } /* fallthrough */ default: gtk_widget_destroy (dialog); break; } }
static void gimp_real_initialize (Gimp *gimp, GimpInitStatusFunc status_callback) { static const GimpDataFactoryLoaderEntry brush_loader_entries[] = { { gimp_brush_load, GIMP_BRUSH_FILE_EXTENSION, FALSE }, { gimp_brush_load, GIMP_BRUSH_PIXMAP_FILE_EXTENSION, FALSE }, { gimp_brush_load_abr, GIMP_BRUSH_PS_FILE_EXTENSION, FALSE }, { gimp_brush_load_abr, GIMP_BRUSH_PSP_FILE_EXTENSION, FALSE }, { gimp_brush_generated_load, GIMP_BRUSH_GENERATED_FILE_EXTENSION, TRUE }, { gimp_brush_pipe_load, GIMP_BRUSH_PIPE_FILE_EXTENSION, FALSE } }; static const GimpDataFactoryLoaderEntry dynamics_loader_entries[] = { { gimp_dynamics_load, GIMP_DYNAMICS_FILE_EXTENSION, TRUE } }; static const GimpDataFactoryLoaderEntry mybrush_loader_entries[] = { { gimp_mybrush_load, GIMP_MYBRUSH_FILE_EXTENSION, FALSE } }; static const GimpDataFactoryLoaderEntry pattern_loader_entries[] = { { gimp_pattern_load, GIMP_PATTERN_FILE_EXTENSION, FALSE }, { gimp_pattern_load_pixbuf, NULL /* fallback loader */, FALSE } }; static const GimpDataFactoryLoaderEntry gradient_loader_entries[] = { { gimp_gradient_load, GIMP_GRADIENT_FILE_EXTENSION, TRUE }, { gimp_gradient_load_svg, GIMP_GRADIENT_SVG_FILE_EXTENSION, FALSE } }; static const GimpDataFactoryLoaderEntry palette_loader_entries[] = { { gimp_palette_load, GIMP_PALETTE_FILE_EXTENSION, TRUE } }; static const GimpDataFactoryLoaderEntry tool_preset_loader_entries[] = { { gimp_tool_preset_load, GIMP_TOOL_PRESET_FILE_EXTENSION, TRUE } }; GimpData *clipboard_brush; GimpData *clipboard_pattern; if (gimp->be_verbose) g_print ("INIT: %s\n", G_STRFUNC); status_callback (_("Initialization"), NULL, 0.0); gimp_fonts_init (gimp); gimp->brush_factory = gimp_data_factory_new (gimp, GIMP_TYPE_BRUSH, "brush-path", "brush-path-writable", brush_loader_entries, G_N_ELEMENTS (brush_loader_entries), gimp_brush_new, gimp_brush_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->brush_factory), "brush factory"); gimp->dynamics_factory = gimp_data_factory_new (gimp, GIMP_TYPE_DYNAMICS, "dynamics-path", "dynamics-path-writable", dynamics_loader_entries, G_N_ELEMENTS (dynamics_loader_entries), gimp_dynamics_new, gimp_dynamics_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->dynamics_factory), "dynamics factory"); gimp->mybrush_factory = gimp_data_factory_new (gimp, GIMP_TYPE_MYBRUSH, "mypaint-brush-path", "mypaint-brush-path-writable", mybrush_loader_entries, G_N_ELEMENTS (mybrush_loader_entries), NULL, NULL); gimp_object_set_static_name (GIMP_OBJECT (gimp->mybrush_factory), "mypaint brush factory"); gimp->pattern_factory = gimp_data_factory_new (gimp, GIMP_TYPE_PATTERN, "pattern-path", "pattern-path-writable", pattern_loader_entries, G_N_ELEMENTS (pattern_loader_entries), NULL, gimp_pattern_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->pattern_factory), "pattern factory"); gimp->gradient_factory = gimp_data_factory_new (gimp, GIMP_TYPE_GRADIENT, "gradient-path", "gradient-path-writable", gradient_loader_entries, G_N_ELEMENTS (gradient_loader_entries), gimp_gradient_new, gimp_gradient_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->gradient_factory), "gradient factory"); gimp->palette_factory = gimp_data_factory_new (gimp, GIMP_TYPE_PALETTE, "palette-path", "palette-path-writable", palette_loader_entries, G_N_ELEMENTS (palette_loader_entries), gimp_palette_new, gimp_palette_get_standard); gimp_object_set_static_name (GIMP_OBJECT (gimp->palette_factory), "palette factory"); gimp->tool_preset_factory = gimp_data_factory_new (gimp, GIMP_TYPE_TOOL_PRESET, "tool-preset-path", "tool-preset-path-writable", tool_preset_loader_entries, G_N_ELEMENTS (tool_preset_loader_entries), gimp_tool_preset_new, NULL); gimp_object_set_static_name (GIMP_OBJECT (gimp->tool_preset_factory), "tool preset factory"); gimp->tag_cache = gimp_tag_cache_new (); gimp_paint_init (gimp); /* Set the last values used to default values. */ gimp->image_new_last_template = gimp_config_duplicate (GIMP_CONFIG (gimp->config->default_image)); /* create user and default context */ gimp_contexts_init (gimp); /* add the builtin FG -> BG etc. gradients */ gimp_gradients_init (gimp); /* add the color history palette */ gimp_palettes_init (gimp); /* add the clipboard brush */ clipboard_brush = gimp_brush_clipboard_new (gimp); gimp_data_make_internal (GIMP_DATA (clipboard_brush), "gimp-brush-clipboard"); gimp_container_add (gimp_data_factory_get_container (gimp->brush_factory), GIMP_OBJECT (clipboard_brush)); g_object_unref (clipboard_brush); /* add the clipboard pattern */ clipboard_pattern = gimp_pattern_clipboard_new (gimp); gimp_data_make_internal (GIMP_DATA (clipboard_pattern), "gimp-pattern-clipboard"); gimp_container_add (gimp_data_factory_get_container (gimp->pattern_factory), GIMP_OBJECT (clipboard_pattern)); g_object_unref (clipboard_pattern); /* register all internal procedures */ status_callback (NULL, _("Internal Procedures"), 0.2); internal_procs_init (gimp->pdb); gimp_pdb_compat_procs_register (gimp->pdb, gimp->pdb_compat_mode); gimp_plug_in_manager_initialize (gimp->plug_in_manager, status_callback); status_callback (NULL, "", 1.0); }
static gboolean gimp_image_map_tool_initialize (GimpTool *tool, GimpDisplay *display, GError **error) { GimpImageMapTool *im_tool = GIMP_IMAGE_MAP_TOOL (tool); GimpToolInfo *tool_info = tool->tool_info; GimpImage *image = gimp_display_get_image (display); GimpDrawable *drawable = gimp_image_get_active_drawable (image); GimpDisplayShell *shell = gimp_display_get_shell (display); if (! drawable) 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 (im_tool->active_picker) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (im_tool->active_picker), FALSE); /* set display so the dialog can be hidden on display destruction */ tool->display = display; if (im_tool->config) gimp_config_reset (GIMP_CONFIG (im_tool->config)); if (! im_tool->gui) { GimpImageMapToolClass *klass = GIMP_IMAGE_MAP_TOOL_GET_CLASS (im_tool); GtkWidget *vbox; GtkWidget *hbox; GtkWidget *toggle; gchar *operation_name; /* disabled for at least GIMP 2.8 */ im_tool->overlay = FALSE; im_tool->gui = gimp_tool_gui_new (tool_info, im_tool->title, im_tool->description, im_tool->icon_name, im_tool->help_id, gtk_widget_get_screen (GTK_WIDGET (shell)), gimp_widget_get_monitor (GTK_WIDGET (shell)), im_tool->overlay, GIMP_STOCK_RESET, RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gimp_tool_gui_set_default_response (im_tool->gui, GTK_RESPONSE_OK); gimp_tool_gui_set_alternative_button_order (im_tool->gui, RESPONSE_RESET, GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); vbox = gimp_tool_gui_get_vbox (im_tool->gui); g_signal_connect_object (im_tool->gui, "response", G_CALLBACK (gimp_image_map_tool_response), G_OBJECT (im_tool), 0); if (im_tool->config && klass->settings_name) { GType type = G_TYPE_FROM_INSTANCE (im_tool->config); GimpContainer *settings; GFile *settings_file; GFile *default_folder; GtkWidget *settings_ui; settings = gimp_gegl_config_get_container (type); if (! gimp_list_get_sort_func (GIMP_LIST (settings))) gimp_list_set_sort_func (GIMP_LIST (settings), (GCompareFunc) gimp_settings_compare); settings_file = gimp_tool_info_get_options_file (tool_info, ".settings"); default_folder = gimp_directory_file (klass->settings_name, NULL); settings_ui = klass->get_settings_ui (im_tool, settings, settings_file, klass->import_dialog_title, klass->export_dialog_title, im_tool->help_id, default_folder, &im_tool->settings_box); g_object_unref (default_folder); g_object_unref (settings_file); gtk_box_pack_start (GTK_BOX (vbox), settings_ui, FALSE, FALSE, 0); gtk_widget_show (settings_ui); } /* The gamma hack toggle */ toggle = gtk_check_button_new_with_label ("Gamma hack (temp hack, please ignore)"); gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); gtk_widget_show (toggle); g_signal_connect (toggle, "toggled", G_CALLBACK (gamma_hack), im_tool); /* The preview and split view toggles */ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); toggle = gimp_prop_check_button_new (G_OBJECT (tool_info->tool_options), "preview", NULL); gtk_box_pack_start (GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_widget_show (toggle); toggle = gimp_prop_check_button_new (G_OBJECT (tool_info->tool_options), "preview-split", NULL); gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 0); gtk_widget_show (toggle); g_object_bind_property (G_OBJECT (tool_info->tool_options), "preview", toggle, "sensitive", G_BINDING_SYNC_CREATE); /* The area combo */ gegl_node_get (im_tool->operation, "operation", &operation_name, NULL); im_tool->region_combo = gimp_prop_enum_combo_box_new (G_OBJECT (tool_info->tool_options), "region", 0, 0); gtk_box_pack_end (GTK_BOX (vbox), im_tool->region_combo, FALSE, FALSE, 0); if (operation_name && gegl_operation_get_key (operation_name, "position-dependent")) { gtk_widget_show (im_tool->region_combo); } g_free (operation_name); /* Fill in subclass widgets */ gimp_image_map_tool_dialog (im_tool); } else { gimp_tool_gui_set_title (im_tool->gui, im_tool->title); gimp_tool_gui_set_description (im_tool->gui, im_tool->description); gimp_tool_gui_set_icon_name (im_tool->gui, im_tool->icon_name); gimp_tool_gui_set_help_id (im_tool->gui, im_tool->help_id); } gimp_tool_gui_set_shell (im_tool->gui, shell); gimp_tool_gui_set_viewable (im_tool->gui, GIMP_VIEWABLE (drawable)); gimp_tool_gui_show (im_tool->gui); im_tool->drawable = drawable; gimp_image_map_tool_create_map (im_tool); gimp_image_map_tool_preview (im_tool); return TRUE; }
static void gimp_hue_saturation_config_init (GimpHueSaturationConfig *self) { gimp_config_reset (GIMP_CONFIG (self)); }
static void gimp_tool_preset_set_options (GimpToolPreset *preset, GimpToolOptions *options) { if (preset->tool_options) { g_signal_handlers_disconnect_by_func (preset->tool_options, gimp_tool_preset_options_notify, preset); g_signal_handlers_disconnect_by_func (preset->tool_options, gimp_tool_preset_options_prop_name_changed, preset); g_object_unref (preset->tool_options); preset->tool_options = NULL; } if (options) { GimpContextPropMask serialize_props; preset->tool_options = GIMP_TOOL_OPTIONS (gimp_config_duplicate (GIMP_CONFIG (options))); serialize_props = gimp_context_get_serialize_properties (GIMP_CONTEXT (preset->tool_options)); gimp_context_set_serialize_properties (GIMP_CONTEXT (preset->tool_options), serialize_props | GIMP_CONTEXT_TOOL_MASK); if (! (serialize_props & GIMP_CONTEXT_FOREGROUND_MASK)) g_object_set (preset, "use-fg-bg", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_BRUSH_MASK)) g_object_set (preset, "use-brush", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_DYNAMICS_MASK)) g_object_set (preset, "use-dynamics", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_GRADIENT_MASK)) g_object_set (preset, "use-gradient", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_PATTERN_MASK)) g_object_set (preset, "use-pattern", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_PALETTE_MASK)) g_object_set (preset, "use-palette", FALSE, NULL); if (! (serialize_props & GIMP_CONTEXT_FONT_MASK)) g_object_set (preset, "use-font", FALSE, NULL); g_signal_connect (preset->tool_options, "notify", G_CALLBACK (gimp_tool_preset_options_notify), preset); g_signal_connect (preset->tool_options, "prop-name-changed", G_CALLBACK (gimp_tool_preset_options_prop_name_changed), preset); } g_object_notify (G_OBJECT (preset), "tool-options"); }
static void gimp_text_undo_pop (GimpUndo *undo, GimpUndoMode undo_mode, GimpUndoAccumulator *accum) { GimpTextUndo *text_undo = GIMP_TEXT_UNDO (undo); GimpTextLayer *layer = GIMP_TEXT_LAYER (GIMP_ITEM_UNDO (undo)->item); GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); switch (undo->undo_type) { case GIMP_UNDO_TEXT_LAYER: if (text_undo->pspec) { GValue *value; g_return_if_fail (layer->text != NULL); value = g_slice_new0 (GValue); g_value_init (value, text_undo->pspec->value_type); g_object_get_property (G_OBJECT (layer->text), text_undo->pspec->name, value); g_object_set_property (G_OBJECT (layer->text), text_undo->pspec->name, text_undo->value); g_value_unset (text_undo->value); g_slice_free (GValue, text_undo->value); text_undo->value = value; } else { GimpText *text; text = (layer->text ? gimp_config_duplicate (GIMP_CONFIG (layer->text)) : NULL); if (layer->text && text_undo->text) gimp_config_sync (G_OBJECT (text_undo->text), G_OBJECT (layer->text), 0); else gimp_text_layer_set_text (layer, text_undo->text); if (text_undo->text) g_object_unref (text_undo->text); text_undo->text = text; } break; case GIMP_UNDO_TEXT_LAYER_MODIFIED: { gboolean modified; #if 0 g_print ("setting layer->modified from %s to %s\n", layer->modified ? "TRUE" : "FALSE", text_undo->modified ? "TRUE" : "FALSE"); #endif modified = layer->modified; g_object_set (layer, "modified", text_undo->modified, NULL); text_undo->modified = modified; gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer)); } break; case GIMP_UNDO_TEXT_LAYER_CONVERT: { const Babl *format; format = gimp_drawable_get_format (GIMP_DRAWABLE (layer)); gimp_drawable_convert_type (GIMP_DRAWABLE (layer), gimp_item_get_image (GIMP_ITEM (layer)), gimp_babl_format_get_base_type (text_undo->format), gimp_babl_format_get_precision (text_undo->format), babl_format_has_alpha (text_undo->format), NULL, GEGL_DITHER_NONE, GEGL_DITHER_NONE, FALSE, NULL); text_undo->format = format; } break; default: g_assert_not_reached (); } }
static gboolean gimp_tool_preset_deserialize_property (GimpConfig *config, guint property_id, GValue *value, GParamSpec *pspec, GScanner *scanner, GTokenType *expected) { GimpToolPreset *tool_preset = GIMP_TOOL_PRESET (config); switch (property_id) { case PROP_TOOL_OPTIONS: { GObject *options; gchar *type_name; GType type; GimpContextPropMask serialize_props; if (! gimp_scanner_parse_string (scanner, &type_name)) { *expected = G_TOKEN_STRING; break; } type = g_type_from_name (type_name); if (! type) { g_scanner_error (scanner, "unable to determine type of '%s'", type_name); *expected = G_TOKEN_STRING; g_free (type_name); break; } if (! g_type_is_a (type, GIMP_TYPE_TOOL_OPTIONS)) { g_scanner_error (scanner, "'%s' is not a subclass of GimpToolOptions", type_name); *expected = G_TOKEN_STRING; g_free (type_name); break; } g_free (type_name); options = g_object_new (type, "gimp", tool_preset->gimp, NULL); /* Initialize all GimpContext object properties that can be * used by presets with some non-NULL object, so loading a * broken preset won't leave us with NULL objects that have * bad effects. See bug #742159. */ gimp_context_copy_properties (gimp_get_user_context (tool_preset->gimp), GIMP_CONTEXT (options), GIMP_CONTEXT_BRUSH_MASK | GIMP_CONTEXT_DYNAMICS_MASK | GIMP_CONTEXT_PATTERN_MASK | GIMP_CONTEXT_GRADIENT_MASK | GIMP_CONTEXT_PALETTE_MASK | GIMP_CONTEXT_FONT_MASK); if (! GIMP_CONFIG_GET_INTERFACE (options)->deserialize (GIMP_CONFIG (options), scanner, 1, NULL)) { g_object_unref (options); break; } /* we need both tool and tool-info on the options */ if (gimp_context_get_tool (GIMP_CONTEXT (options))) { g_object_set (options, "tool-info", gimp_context_get_tool (GIMP_CONTEXT (options)), NULL); } else if (GIMP_TOOL_OPTIONS (options)->tool_info) { g_object_set (options, "tool", GIMP_TOOL_OPTIONS (options)->tool_info, NULL); } else { /* if we have none, the options set_property() logic will * replace the NULL with its best guess */ g_object_set (options, "tool", NULL, "tool-info", NULL, NULL); } serialize_props = gimp_context_get_serialize_properties (GIMP_CONTEXT (options)); gimp_context_set_serialize_properties (GIMP_CONTEXT (options), serialize_props | GIMP_CONTEXT_TOOL_MASK); g_value_take_object (value, options); } break; default: return FALSE; } return TRUE; }
GimpCurvesConfig * gimp_levels_config_to_curves_config (GimpLevelsConfig *config) { GimpCurvesConfig *curves; GimpHistogramChannel channel; g_return_val_if_fail (GIMP_IS_LEVELS_CONFIG (config), NULL); curves = g_object_new (GIMP_TYPE_CURVES_CONFIG, NULL); for (channel = GIMP_HISTOGRAM_VALUE; channel <= GIMP_HISTOGRAM_ALPHA; channel++) { GimpCurve *curve = curves->curve[channel]; const gint n_points = gimp_curve_get_n_points (curve); static const gint n = 4; gint point = -1; gdouble gamma = config->gamma[channel]; gdouble delta_in; gdouble delta_out; gdouble x, y; /* clear the points set by default */ gimp_curve_set_point (curve, 0, -1, -1); gimp_curve_set_point (curve, n_points - 1, -1, -1); delta_in = config->high_input[channel] - config->low_input[channel]; delta_out = config->high_output[channel] - config->low_output[channel]; x = config->low_input[channel]; y = config->low_output[channel]; point = CLAMP (n_points * x, point + 1, n_points - 1 - n); gimp_curve_set_point (curve, point, x, y); if (delta_out != 0 && gamma != 1.0) { /* The Levels tool performs gamma correction, which is a * power law, while the Curves tool uses cubic Bézier * curves. Here we try to approximate this gamma correction * with a Bézier curve with 5 control points. Two of them * must be (low_input, low_output) and (high_input, * high_output), so we need to add 3 more control points in * the middle. */ gint i; if (gamma > 1) { /* Case no. 1: γ > 1 * * The curve should look like a horizontal * parabola. Since its curvature is greatest when x is * small, we add more control points there, so the * approximation is more accurate. I decided to set the * length of the consecutive segments to x₀, γ⋅x₀, γ²⋅x₀ * and γ³⋅x₀ and I saw that the curves looked * good. Still, this is completely arbitrary. */ gdouble dx = 0; gdouble x0; for (i = 0; i < n; ++i) dx = dx * gamma + 1; x0 = delta_in / dx; dx = 0; for (i = 1; i < n; ++i) { dx = dx * gamma + x0; x = config->low_input[channel] + dx; y = config->low_output[channel] + delta_out * gimp_operation_levels_map_input (config, channel, x); point = CLAMP (n_points * x, point + 1, n_points - 1 - n + i); gimp_curve_set_point (curve, point, x, y); } } else { /* Case no. 2: γ < 1 * * The curve is the same as the one in case no. 1, * observed through a reflexion along the y = x axis. So * if we invert γ and swap the x and y axes we can use * the same method as in case no. 1. */ GimpLevelsConfig *config_inv; gdouble dy = 0; gdouble y0; const gdouble gamma_inv = 1 / gamma; config_inv = gimp_config_duplicate (GIMP_CONFIG (config)); config_inv->gamma[channel] = gamma_inv; config_inv->low_input[channel] = config->low_output[channel]; config_inv->low_output[channel] = config->low_input[channel]; config_inv->high_input[channel] = config->high_output[channel]; config_inv->high_output[channel] = config->high_input[channel]; for (i = 0; i < n; ++i) dy = dy * gamma_inv + 1; y0 = delta_out / dy; dy = 0; for (i = 1; i < n; ++i) { dy = dy * gamma_inv + y0; y = config->low_output[channel] + dy; x = config->low_input[channel] + delta_in * gimp_operation_levels_map_input (config_inv, channel, y); point = CLAMP (n_points * x, point + 1, n_points - 1 - n + i); gimp_curve_set_point (curve, point, x, y); } g_object_unref (config_inv); } } x = config->high_input[channel]; y = config->high_output[channel]; point = CLAMP (n_points * x, point + 1, n_points - 1); gimp_curve_set_point (curve, point, x, y); } return curves; }
static void gimp_levels_config_init (GimpLevelsConfig *self) { gimp_config_reset (GIMP_CONFIG (self)); }
/** * gimp_rc_query: * @rc: a #GimpRc object. * @key: a string used as a key for the lookup. * * This function looks up @key in the object properties of @rc. If * there's a matching property, a string representation of its value * is returned. If no property is found, the list of unknown tokens * attached to the @rc object is searched. * * Return value: a newly allocated string representing the value or %NULL * if the key couldn't be found. **/ gchar * gimp_rc_query (GimpRc *rc, const gchar *key) { GObjectClass *klass; GObject *rc_object; GParamSpec **property_specs; GParamSpec *prop_spec; guint i, n_property_specs; gchar *retval = NULL; g_return_val_if_fail (GIMP_IS_RC (rc), NULL); g_return_val_if_fail (key != NULL, NULL); rc_object = G_OBJECT (rc); klass = G_OBJECT_GET_CLASS (rc); property_specs = g_object_class_list_properties (klass, &n_property_specs); if (!property_specs) return NULL; for (i = 0, prop_spec = NULL; i < n_property_specs && !prop_spec; i++) { prop_spec = property_specs[i]; if (! (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE) || strcmp (prop_spec->name, key)) { prop_spec = NULL; } } if (prop_spec) { GString *str = g_string_new (NULL); GValue value = { 0, }; g_value_init (&value, prop_spec->value_type); g_object_get_property (rc_object, prop_spec->name, &value); if (gimp_config_serialize_value (&value, str, FALSE)) retval = g_string_free (str, FALSE); else g_string_free (str, TRUE); g_value_unset (&value); } else { retval = g_strdup (gimp_rc_lookup_unknown_token (GIMP_CONFIG (rc), key)); } g_free (property_specs); if (!retval) { const gchar * const path_tokens[] = { "gimp_dir", "gimp_data_dir", "gimp_plug_in_dir", "gimp_plugin_dir", "gimp_sysconf_dir" }; for (i = 0; !retval && i < G_N_ELEMENTS (path_tokens); i++) if (strcmp (key, path_tokens[i]) == 0) retval = g_strdup_printf ("${%s}", path_tokens[i]); } if (retval) { gchar *tmp = gimp_config_path_expand (retval, FALSE, NULL); if (tmp) { g_free (retval); retval = tmp; } } return retval; }
GIMP_DATA_CLASS (parent_class)->dirty (data); } static const gchar * gimp_curve_get_extension (GimpData *data) { return GIMP_CURVE_FILE_EXTENSION; } static GimpData * gimp_curve_duplicate (GimpData *data) { GimpCurve *new = g_object_new (GIMP_TYPE_CURVE, NULL); gimp_config_copy (GIMP_CONFIG (data), GIMP_CONFIG (new), 0); return GIMP_DATA (new); } static gboolean gimp_curve_serialize (GimpConfig *config, GimpConfigWriter *writer, gpointer data) { return gimp_config_serialize_properties (config, writer); } static gboolean gimp_curve_deserialize (GimpConfig *config,