コード例 #1
0
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);
}
コード例 #2
0
ファイル: gimppaintoptions.c プロジェクト: davidyang5405/gimp
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;
}
コード例 #3
0
ファイル: gradients-cmds.c プロジェクト: jdburton/gimp-osx
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;
}
コード例 #4
0
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));
    }
}
コード例 #5
0
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);
        }
    }
}
コード例 #6
0
ファイル: gimppaintoptions.c プロジェクト: jdburton/gimp-osx
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;
}
コード例 #7
0
ファイル: gimpdrawable-blend.c プロジェクト: alfanak/gimp
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
    }
}
コード例 #8
0
ファイル: gradients-cmds.c プロジェクト: jdburton/gimp-osx
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;
}