static void gimp_view_renderer_gradient_render (GimpViewRenderer *renderer, GtkWidget *widget) { GimpViewRendererGradient *rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer); GimpGradient *gradient = GIMP_GRADIENT (renderer->viewable); GimpGradientSegment *seg = NULL; GimpColorTransform *transform; guchar *buf; guchar *dest; gint dest_stride; gint x; gint y; gdouble dx, cur_x; GimpRGB color; buf = g_alloca (4 * renderer->width); dx = (rendergrad->right - rendergrad->left) / (renderer->width - 1); cur_x = rendergrad->left; for (x = 0, dest = buf; x < renderer->width; x++, dest += 4) { guchar r, g, b, a; seg = gimp_gradient_get_color_at (gradient, renderer->context, seg, cur_x, rendergrad->reverse, &color); cur_x += dx; gimp_rgba_get_uchar (&color, &r, &g, &b, &a); GIMP_CAIRO_ARGB32_SET_PIXEL (dest, r, g, b, a); } if (! renderer->surface) renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, renderer->width, renderer->height); cairo_surface_flush (renderer->surface); dest = cairo_image_surface_get_data (renderer->surface); dest_stride = cairo_image_surface_get_stride (renderer->surface); transform = gimp_view_renderer_get_color_transform (renderer, widget, babl_format ("cairo-ARGB32"), babl_format ("cairo-ARGB32")); if (transform) gimp_color_transform_process_pixels (transform, babl_format ("cairo-ARGB32"), buf, babl_format ("cairo-ARGB32"), buf, renderer->width); for (y = 0; y < renderer->height; y++, dest += dest_stride) { memcpy (dest, buf, renderer->width * 4); } cairo_surface_mark_dirty (renderer->surface); }
void gradient_editor_load_right_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpDataEditor *data_editor = GIMP_DATA_EDITOR (data); GimpGradient *gradient; GimpGradientSegment *seg; GimpRGB color; GimpGradientColor color_type = GIMP_GRADIENT_COLOR_FIXED; gradient = GIMP_GRADIENT (data_editor->data); switch (value) { case GRADIENT_EDITOR_COLOR_NEIGHBOR_ENDPOINT: if (editor->control_sel_r->next != NULL) seg = editor->control_sel_r->next; else seg = gimp_gradient_segment_get_first (editor->control_sel_r); color = seg->left_color; color_type = seg->left_color_type; break; case GRADIENT_EDITOR_COLOR_OTHER_ENDPOINT: color = editor->control_sel_l->left_color; color_type = editor->control_sel_l->left_color_type; break; case GRADIENT_EDITOR_COLOR_FOREGROUND: gimp_context_get_foreground (data_editor->context, &color); break; case GRADIENT_EDITOR_COLOR_BACKGROUND: gimp_context_get_background (data_editor->context, &color); break; default: /* Load a color */ color = editor->saved_colors[value - GRADIENT_EDITOR_COLOR_FIRST_CUSTOM]; break; } gimp_data_freeze (GIMP_DATA (gradient)); gimp_gradient_segment_range_blend (gradient, editor->control_sel_l, editor->control_sel_r, &editor->control_sel_l->left_color, &color, TRUE, TRUE); gimp_gradient_segment_set_right_color_type (gradient, editor->control_sel_l, color_type); gimp_data_thaw (GIMP_DATA (gradient)); }
static void gradient_preview_drop_gradient (GtkWidget *widget, gint x, gint y, GimpViewable *viewable, gpointer data) { GimpContext *context = GIMP_CONTEXT (data); gimp_context_set_gradient (context, GIMP_GRADIENT (viewable)); }
void gradient_editor_redistribute_cmd_callback (GtkAction *action, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); gimp_gradient_segment_range_redistribute_handles (gradient, editor->control_sel_l, editor->control_sel_r); }
void gradient_editor_save_right_cmd_callback (GtkAction *action, gint value, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); gimp_gradient_segment_get_right_color (gradient, editor->control_sel_r, &editor->saved_colors[value]); }
void gradient_editor_split_midpoint_cmd_callback (GtkAction *action, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpDataEditor *data_editor = GIMP_DATA_EDITOR (data); GimpGradient *gradient = GIMP_GRADIENT (data_editor->data); gimp_gradient_segment_range_split_midpoint (gradient, data_editor->context, editor->control_sel_l, editor->control_sel_r, &editor->control_sel_l, &editor->control_sel_r); }
void gradient_editor_blend_opacity_cmd_callback (GtkAction *action, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); gimp_gradient_segment_range_blend (gradient, editor->control_sel_l, editor->control_sel_r, &editor->control_sel_l->left_color, &editor->control_sel_r->right_color, FALSE, TRUE); }
static void gradient_editor_right_color_update (GimpColorDialog *dialog, const GimpRGB *color, GimpColorDialogState state, GimpGradientEditor *editor) { GimpGradient *gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); switch (state) { case GIMP_COLOR_DIALOG_UPDATE: gimp_gradient_segment_range_blend (gradient, editor->control_sel_l, editor->control_sel_r, &editor->control_sel_l->left_color, color, TRUE, TRUE); break; case GIMP_COLOR_DIALOG_OK: gimp_gradient_segment_range_blend (gradient, editor->control_sel_l, editor->control_sel_r, &editor->control_sel_l->left_color, color, TRUE, TRUE); gimp_gradient_segments_free (editor->right_saved_segments); gtk_widget_destroy (editor->color_dialog); editor->color_dialog = NULL; gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE); gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, GIMP_EDITOR (editor)->popup_data); break; case GIMP_COLOR_DIALOG_CANCEL: gradient_editor_replace_selection (editor, editor->right_saved_segments); if (! editor->right_saved_dirty) gimp_data_clean (GIMP_DATA (gradient)); gimp_viewable_invalidate_preview (GIMP_VIEWABLE (gradient)); gtk_widget_destroy (editor->color_dialog); editor->color_dialog = NULL; gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE); gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, GIMP_EDITOR (editor)->popup_data); break; } }
static GimpGradient * gimp_gradients_add_gradient (Gimp *gimp, const gchar *name, const gchar *id) { GimpGradient *gradient; gradient = GIMP_GRADIENT (gimp_gradient_new (gimp_get_user_context (gimp), name)); gimp_data_make_internal (GIMP_DATA (gradient), id); gimp_container_add (gimp_data_factory_get_container (gimp->gradient_factory), GIMP_OBJECT (gradient)); g_object_unref (gradient); g_object_set_data (G_OBJECT (gimp), id, gradient); return gradient; }
static void gradient_editor_replace_selection (GimpGradientEditor *editor, GimpGradientSegment *replace_seg) { GimpGradient *gradient; GimpGradientSegment *lseg, *rseg; GimpGradientSegment *replace_last; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); /* Remember left and right segments */ lseg = editor->control_sel_l->prev; rseg = editor->control_sel_r->next; replace_last = gimp_gradient_segment_get_last (replace_seg); /* Free old selection */ editor->control_sel_r->next = NULL; gimp_gradient_segments_free (editor->control_sel_l); /* Link in new segments */ if (lseg) lseg->next = replace_seg; else gradient->segments = replace_seg; replace_seg->prev = lseg; if (rseg) rseg->prev = replace_last; replace_last->next = rseg; editor->control_sel_l = replace_seg; editor->control_sel_r = replace_last; }
static void gradient_editor_replicate_response (GtkWidget *widget, gint response_id, GimpGradientEditor *editor) { gtk_widget_destroy (widget); gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE); gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, GIMP_EDITOR (editor)->popup_data); if (response_id == GTK_RESPONSE_OK) { GimpGradient *gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); gimp_gradient_segment_range_replicate (gradient, editor->control_sel_l, editor->control_sel_r, editor->replicate_times, &editor->control_sel_l, &editor->control_sel_r); } }
void gradient_editor_left_color_cmd_callback (GtkAction *action, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); editor->left_saved_dirty = gimp_data_is_dirty (GIMP_DATA (gradient)); editor->left_saved_segments = gradient_editor_save_selection (editor); editor->color_dialog = gimp_color_dialog_new (GIMP_VIEWABLE (gradient), GIMP_DATA_EDITOR (editor)->context, _("Left Endpoint Color"), GIMP_STOCK_GRADIENT, _("Gradient Segment's Left Endpoint Color"), GTK_WIDGET (editor), gimp_dialog_factory_get_singleton (), "gimp-gradient-editor-color-dialog", &editor->control_sel_l->left_color, TRUE, TRUE); g_signal_connect (editor->color_dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &editor->color_dialog); g_signal_connect (editor->color_dialog, "update", G_CALLBACK (gradient_editor_left_color_update), editor); gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE); gimp_ui_manager_update (GIMP_EDITOR (editor)->ui_manager, GIMP_EDITOR (editor)->popup_data); gtk_window_present (GTK_WINDOW (editor->color_dialog)); }
void gradient_editor_right_color_type_cmd_callback (GtkAction *action, GtkAction *current, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gint value; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); if (gradient && value >= 0) { GimpGradientColor color_type = value; GimpRGB color; gimp_gradient_get_color_at (gradient, GIMP_DATA_EDITOR (editor)->context, editor->control_sel_r, editor->control_sel_r->right, FALSE, &color); gimp_data_freeze (GIMP_DATA (gradient)); gimp_gradient_segment_set_right_color_type (gradient, editor->control_sel_r, color_type); if (color_type == GIMP_GRADIENT_COLOR_FIXED) gimp_gradient_segment_set_right_color (gradient, editor->control_sel_r, &color); gimp_data_thaw (GIMP_DATA (gradient)); } }
static void gimp_view_renderer_gradient_invalidate (GimpViewRenderer *renderer) { GimpViewRendererGradient *rendergrad; gboolean has_fg_bg_segments = FALSE; rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer); if (renderer->viewable) has_fg_bg_segments = gimp_gradient_has_fg_bg_segments (GIMP_GRADIENT (renderer->viewable)); if (rendergrad->has_fg_bg_segments != has_fg_bg_segments) { if (renderer->context) { if (rendergrad->has_fg_bg_segments) { g_signal_handlers_disconnect_by_func (renderer->context, gimp_view_renderer_gradient_fg_bg_changed, renderer); } else { g_signal_connect (renderer->context, "foreground-changed", G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), renderer); g_signal_connect (renderer->context, "background-changed", G_CALLBACK (gimp_view_renderer_gradient_fg_bg_changed), renderer); } } rendergrad->has_fg_bg_segments = has_fg_bg_segments; } GIMP_VIEW_RENDERER_CLASS (parent_class)->invalidate (renderer); }
void gradient_editor_coloring_type_cmd_callback (GtkAction *action, GtkAction *current, gpointer data) { GimpGradientEditor *editor = GIMP_GRADIENT_EDITOR (data); GimpGradient *gradient; gint value; gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data); value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); if (gradient && value >= 0) { GimpGradientSegmentColor color = value; gimp_gradient_segment_range_set_coloring_type (gradient, editor->control_sel_l, editor->control_sel_r, color); } }
gboolean gimp_gradient_save (GimpData *data, GError **error) { GimpGradient *gradient = GIMP_GRADIENT (data); GimpGradientSegment *seg; gint num_segments; FILE *file; file = g_fopen (data->filename, "wb"); if (! file) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN, _("Could not open '%s' for writing: %s"), gimp_filename_to_utf8 (data->filename), g_strerror (errno)); return FALSE; } /* File format is: * * GIMP Gradient * Name: name * number_of_segments * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring left_color_type * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring right_color_type * ... */ fprintf (file, "GIMP Gradient\n"); fprintf (file, "Name: %s\n", GIMP_OBJECT (gradient)->name); /* Count number of segments */ num_segments = 0; seg = gradient->segments; while (seg) { num_segments++; seg = seg->next; } /* Write rest of file */ fprintf (file, "%d\n", num_segments); for (seg = gradient->segments; seg; seg = seg->next) { gchar buf[11][G_ASCII_DTOSTR_BUF_SIZE]; g_ascii_formatd (buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left); g_ascii_formatd (buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->middle); g_ascii_formatd (buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right); g_ascii_formatd (buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.r); g_ascii_formatd (buf[4], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.g); g_ascii_formatd (buf[5], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.b); g_ascii_formatd (buf[6], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.a); g_ascii_formatd (buf[7], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.r); g_ascii_formatd (buf[8], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.g); g_ascii_formatd (buf[9], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.b); g_ascii_formatd (buf[10], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.a); fprintf (file, "%s %s %s %s %s %s %s %s %s %s %s %d %d %d %d\n", buf[0], buf[1], buf[2], /* left, middle, right */ buf[3], buf[4], buf[5], buf[6], /* left color */ buf[7], buf[8], buf[9], buf[10], /* right color */ (gint) seg->type, (gint) seg->color, (gint) seg->left_color_type, (gint) seg->right_color_type); } fclose (file); return TRUE; }
gboolean gimp_gradient_save (GimpData *data, GOutputStream *output, GError **error) { GimpGradient *gradient = GIMP_GRADIENT (data); GString *string; GimpGradientSegment *seg; gint num_segments; /* File format is: * * GIMP Gradient * Name: name * number_of_segments * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring left_color_type * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring right_color_type * ... */ string = g_string_new ("GIMP Gradient\n"); g_string_append_printf (string, "Name: %s\n", gimp_object_get_name (gradient)); /* Count number of segments */ num_segments = 0; seg = gradient->segments; while (seg) { num_segments++; seg = seg->next; } /* Write rest of file */ g_string_append_printf (string, "%d\n", num_segments); for (seg = gradient->segments; seg; seg = seg->next) { gchar buf[11][G_ASCII_DTOSTR_BUF_SIZE]; g_ascii_formatd (buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left); g_ascii_formatd (buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->middle); g_ascii_formatd (buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right); g_ascii_formatd (buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.r); g_ascii_formatd (buf[4], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.g); g_ascii_formatd (buf[5], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.b); g_ascii_formatd (buf[6], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.a); g_ascii_formatd (buf[7], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.r); g_ascii_formatd (buf[8], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.g); g_ascii_formatd (buf[9], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.b); g_ascii_formatd (buf[10], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.a); g_string_append_printf (string, "%s %s %s %s %s %s %s %s %s %s %s %d %d %d %d\n", buf[0], buf[1], buf[2], /* left, middle, right */ buf[3], buf[4], buf[5], buf[6], /* left color */ buf[7], buf[8], buf[9], buf[10], /* right color */ (gint) seg->type, (gint) seg->color, (gint) seg->left_color_type, (gint) seg->right_color_type); } if (! g_output_stream_write_all (output, string->str, string->len, NULL, NULL, error)) { g_string_free (string, TRUE); return FALSE; } g_string_free (string, TRUE); return TRUE; }