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); }
gboolean gimp_paint_options_get_gradient_color (GimpPaintOptions *paint_options, GimpImage *image, gdouble grad_point, gdouble pixel_dist, GimpRGB *color) { GimpDynamics *dynamics; g_return_val_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options), FALSE); g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (color != NULL, FALSE); dynamics = gimp_context_get_dynamics (GIMP_CONTEXT (paint_options)); if (gimp_dynamics_is_output_enabled (dynamics, GIMP_DYNAMICS_OUTPUT_COLOR)) { GimpGradientOptions *gradient_options = paint_options->gradient_options; GimpGradient *gradient; gradient = gimp_context_get_gradient (GIMP_CONTEXT (paint_options)); gimp_gradient_get_color_at (gradient, GIMP_CONTEXT (paint_options), NULL, grad_point, gradient_options->gradient_reverse, color); return TRUE; } return FALSE; }
static GValueArray * gradients_sample_uniform_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GValueArray *args, GError **error) { gboolean success = TRUE; GValueArray *return_vals; gint32 num_samples; gboolean reverse; gint32 array_length = 0; gdouble *color_samples = NULL; num_samples = g_value_get_int (&args->values[0]); reverse = g_value_get_boolean (&args->values[1]); if (success) { GimpGradient *gradient; GimpGradientSegment *seg = NULL; gdouble pos, delta; GimpRGB color; gdouble *pv; pos = 0.0; delta = 1.0 / (num_samples - 1); array_length = num_samples * 4; pv = color_samples = g_new (gdouble, array_length); gradient = gimp_context_get_gradient (context); while (num_samples--) { seg = gimp_gradient_get_color_at (gradient, context, seg, pos, reverse, &color); *pv++ = color.r; *pv++ = color.g; *pv++ = color.b; *pv++ = color.a; pos += delta; } } return_vals = gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); if (success) { g_value_set_int (&return_vals->values[1], array_length); gimp_value_take_floatarray (&return_vals->values[2], color_samples, array_length); } return return_vals; }
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 gradient_render_pixel (gdouble x, gdouble y, GimpRGB *color, gpointer render_data) { RenderBlendData *rbd = render_data; gdouble factor; /* Calculate blending factor */ switch (rbd->gradient_type) { case GIMP_GRADIENT_LINEAR: factor = gradient_calc_linear_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_BILINEAR: factor = gradient_calc_bilinear_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_RADIAL: factor = gradient_calc_radial_factor (rbd->dist, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_SQUARE: factor = gradient_calc_square_factor (rbd->dist, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_CONICAL_SYMMETRIC: factor = gradient_calc_conical_sym_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_CONICAL_ASYMMETRIC: factor = gradient_calc_conical_asym_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_SHAPEBURST_ANGULAR: factor = gradient_calc_shapeburst_angular_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SHAPEBURST_SPHERICAL: factor = gradient_calc_shapeburst_spherical_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SHAPEBURST_DIMPLED: factor = gradient_calc_shapeburst_dimpled_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SPIRAL_CLOCKWISE: factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy, TRUE); break; case GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE: factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy, FALSE); break; default: g_assert_not_reached (); return; } /* Adjust for repeat */ switch (rbd->repeat) { case GIMP_REPEAT_NONE: factor = CLAMP (factor, 0.0, 1.0); break; case GIMP_REPEAT_SAWTOOTH: factor = factor - floor (factor); break; case GIMP_REPEAT_TRIANGULAR: { guint ifactor; if (factor < 0.0) factor = -factor; ifactor = (guint) factor; factor = factor - floor (factor); if (ifactor & 1) factor = 1.0 - factor; } break; } /* Blend the colors */ if (rbd->blend_mode == GIMP_CUSTOM_MODE) { #ifdef USE_GRADIENT_CACHE *color = rbd->gradient_cache[(gint) (factor * (rbd->gradient_cache_size - 1))]; #else gimp_gradient_get_color_at (rbd->gradient, rbd->context, NULL, factor, rbd->reverse, color); #endif } else { /* Blend values */ if (rbd->reverse) factor = 1.0 - factor; color->r = rbd->fg.r + (rbd->bg.r - rbd->fg.r) * factor; color->g = rbd->fg.g + (rbd->bg.g - rbd->fg.g) * factor; color->b = rbd->fg.b + (rbd->bg.b - rbd->fg.b) * factor; color->a = rbd->fg.a + (rbd->bg.a - rbd->fg.a) * factor; if (rbd->blend_mode == GIMP_FG_BG_HSV_MODE) { GimpHSV hsv = *((GimpHSV *) color); gimp_hsv_to_rgb (&hsv, color); } } }
gboolean gimp_paint_options_get_gradient_color (GimpPaintOptions *paint_options, GimpImage *image, gdouble grad_point, gdouble pixel_dist, GimpRGB *color) { GimpGradientOptions *gradient_options; GimpGradient *gradient; g_return_val_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options), FALSE); g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (color != NULL, FALSE); gradient_options = paint_options->gradient_options; gradient = gimp_context_get_gradient (GIMP_CONTEXT (paint_options)); if (paint_options->pressure_options->color || paint_options->velocity_options->color || paint_options->random_options->color) { gimp_gradient_get_color_at (gradient, GIMP_CONTEXT (paint_options), NULL, grad_point, gradient_options->gradient_reverse, color); return TRUE; } else if (gradient_options->use_gradient) { gdouble gradient_length = 0.0; gdouble unit_factor; gdouble pos; switch (gradient_options->gradient_unit) { case GIMP_UNIT_PIXEL: gradient_length = gradient_options->gradient_length; break; case GIMP_UNIT_PERCENT: gradient_length = (MAX (gimp_image_get_width (image), gimp_image_get_height (image)) * gradient_options->gradient_length / 100); break; default: { gdouble xres; gdouble yres; gimp_image_get_resolution (image, &xres, &yres); unit_factor = gimp_unit_get_factor (gradient_options->gradient_unit); gradient_length = (gradient_options->gradient_length * MAX (xres, yres) / unit_factor); } break; } if (gradient_length > 0.0) pos = pixel_dist / gradient_length; else pos = 1.0; /* for no repeat, set pos close to 1.0 after the first chunk */ if (gradient_options->gradient_repeat == GIMP_REPEAT_NONE && pos >= 1.0) pos = 0.9999999; if (((gint) pos & 1) && gradient_options->gradient_repeat != GIMP_REPEAT_SAWTOOTH) pos = 1.0 - (pos - (gint) pos); else pos = pos - (gint) pos; gimp_gradient_get_color_at (gradient, GIMP_CONTEXT (paint_options), NULL, pos, gradient_options->gradient_reverse, color); return TRUE; } return FALSE; }
static void gradient_render_pixel (gdouble x, gdouble y, GimpRGB *color, gpointer render_data) { RenderBlendData *rbd = render_data; gdouble factor; /* Calculate blending factor */ switch (rbd->gradient_type) { case GIMP_GRADIENT_LINEAR: factor = gradient_calc_linear_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_BILINEAR: factor = gradient_calc_bilinear_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_RADIAL: factor = gradient_calc_radial_factor (rbd->dist, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_SQUARE: factor = gradient_calc_square_factor (rbd->dist, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_CONICAL_SYMMETRIC: factor = gradient_calc_conical_sym_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_CONICAL_ASYMMETRIC: factor = gradient_calc_conical_asym_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy); break; case GIMP_GRADIENT_SHAPEBURST_ANGULAR: factor = gradient_calc_shapeburst_angular_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SHAPEBURST_SPHERICAL: factor = gradient_calc_shapeburst_spherical_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SHAPEBURST_DIMPLED: factor = gradient_calc_shapeburst_dimpled_factor (rbd->dist_buffer, x, y); break; case GIMP_GRADIENT_SPIRAL_CLOCKWISE: factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy, TRUE); break; case GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE: factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset, x - rbd->sx, y - rbd->sy, FALSE); break; default: g_assert_not_reached (); return; } /* Adjust for repeat */ switch (rbd->repeat) { case GIMP_REPEAT_TRUNCATE: break; case GIMP_REPEAT_NONE: factor = CLAMP (factor, 0.0, 1.0); break; case GIMP_REPEAT_SAWTOOTH: factor = factor - floor (factor); break; case GIMP_REPEAT_TRIANGULAR: { guint ifactor; if (factor < 0.0) factor = -factor; ifactor = (guint) factor; factor = factor - floor (factor); if (ifactor & 1) factor = 1.0 - factor; } break; } /* Blend the colors */ if (factor < 0.0 || factor > 1.0) { color->r = color->g = color->b = 0; color->a = GIMP_OPACITY_TRANSPARENT; } else { #ifdef USE_GRADIENT_CACHE *color = rbd->gradient_cache[(gint) (factor * (rbd->gradient_cache_size - 1))]; #else gimp_gradient_get_color_at (rbd->gradient, rbd->context, NULL, factor, rbd->reverse, color); #endif } }
static GValueArray * gradients_get_gradient_data_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GValueArray *args, GError **error) { gboolean success = TRUE; GValueArray *return_vals; const gchar *name; gint32 sample_size; gboolean reverse; gchar *actual_name = NULL; gint32 width = 0; gdouble *grad_data = NULL; name = g_value_get_string (&args->values[0]); sample_size = g_value_get_int (&args->values[1]); reverse = g_value_get_boolean (&args->values[2]); if (success) { GimpGradient *gradient; if (sample_size < 1 || sample_size > 10000) sample_size = GIMP_GRADIENT_DEFAULT_SAMPLE_SIZE; if (name && strlen (name)) gradient = gimp_pdb_get_gradient (gimp, name, FALSE, error); else gradient = gimp_context_get_gradient (context); if (gradient) { GimpGradientSegment *seg = NULL; gdouble *pv; gdouble pos, delta; GimpRGB color; pos = 0.0; delta = 1.0 / (sample_size - 1); actual_name = g_strdup (gimp_object_get_name (GIMP_OBJECT (gradient))); grad_data = g_new (gdouble, sample_size * 4); width = sample_size * 4; pv = grad_data; while (sample_size) { seg = gimp_gradient_get_color_at (gradient, context, seg, pos, reverse, &color); *pv++ = color.r; *pv++ = color.g; *pv++ = color.b; *pv++ = color.a; pos += delta; } } else success = FALSE; } return_vals = gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); if (success) { g_value_take_string (&return_vals->values[1], actual_name); g_value_set_int (&return_vals->values[2], width); gimp_value_take_floatarray (&return_vals->values[3], grad_data, width); } return return_vals; }