예제 #1
0
static GValueArray *
gimp_brush_select_run_callback (GimpPdbDialog *dialog,
                                GimpObject    *object,
                                gboolean       closing)
{
  GimpBrush   *brush = GIMP_BRUSH (object);
  GimpArray   *array;
  GValueArray *return_vals;

  array = gimp_array_new (temp_buf_data (brush->mask),
                          brush->mask->width *
                          brush->mask->height *
                          brush->mask->bytes,
                          TRUE);

  return_vals =
    gimp_pdb_execute_procedure_by_name (dialog->pdb,
                                        dialog->caller_context,
                                        NULL,
                                        dialog->callback_name,
                                        G_TYPE_STRING,        object->name,
                                        G_TYPE_DOUBLE,        gimp_context_get_opacity (dialog->context) * 100.0,
                                        GIMP_TYPE_INT32,      GIMP_BRUSH_SELECT (dialog)->spacing,
                                        GIMP_TYPE_INT32,      gimp_context_get_paint_mode (dialog->context),
                                        GIMP_TYPE_INT32,      brush->mask->width,
                                        GIMP_TYPE_INT32,      brush->mask->height,
                                        GIMP_TYPE_INT32,      array->length,
                                        GIMP_TYPE_INT8_ARRAY, array,
                                        GIMP_TYPE_INT32,      closing,
                                        G_TYPE_NONE);

  gimp_array_free (array);

  return return_vals;
}
예제 #2
0
TempBuf *
gimp_vectors_get_new_preview (GimpViewable *viewable,
                              GimpContext  *context,
                              gint          width,
                              gint          height)
{
  GimpVectors *vectors;
  GimpItem    *item;
  GimpStroke  *cur_stroke;
  gdouble      xscale, yscale;
  guchar      *data;
  TempBuf     *temp_buf;
  guchar       white[1] = { 255 };

  vectors = GIMP_VECTORS (viewable);
  item    = GIMP_ITEM (viewable);

  xscale = ((gdouble) width)  / gimp_image_get_width  (item->image);
  yscale = ((gdouble) height) / gimp_image_get_height (item->image);

  temp_buf = temp_buf_new (width, height, 1, 0, 0, white);
  data = temp_buf_data (temp_buf);

  for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL);
       cur_stroke;
       cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))
    {
      GArray   *coords;
      gboolean  closed;
      gint      i;

      coords = gimp_stroke_interpolate (cur_stroke, 0.5, &closed);

      if (coords)
        {
          for (i = 0; i < coords->len; i++)
            {
              GimpCoords point;
              gint       x, y;

              point = g_array_index (coords, GimpCoords, i);

              x = ROUND (point.x * xscale);
              y = ROUND (point.y * yscale);

              if (x >= 0 && y >= 0 && x < width && y < height)
                data[y * width + x] = 0;
            }

          g_array_free (coords, TRUE);
        }
    }

  return temp_buf;
}
예제 #3
0
static void
gimp_eraser_motion (GimpPaintCore    *paint_core,
                    GimpDrawable     *drawable,
                    GimpPaintOptions *paint_options)
{
  GimpEraserOptions *options = GIMP_ERASER_OPTIONS (paint_options);
  GimpContext       *context = GIMP_CONTEXT (paint_options);
  GimpImage         *image;
  gdouble            opacity;
  TempBuf           *area;
  guchar             col[MAX_CHANNELS];
  gdouble            hardness;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  opacity = gimp_paint_options_get_fade (paint_options, image,
                                         paint_core->pixel_dist);
  if (opacity == 0.0)
    return;

  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
  if (! area)
    return;

  gimp_image_get_background (image, context, gimp_drawable_type (drawable),
                             col);

  /*  set the alpha channel  */
  col[area->bytes - 1] = OPAQUE_OPACITY;

  /*  color the pixels  */
  color_pixels (temp_buf_data (area), col,
                area->width * area->height, area->bytes);

  opacity *= gimp_paint_options_get_dynamic_opacity (paint_options,
                                                     &paint_core->cur_coords);

  hardness = gimp_paint_options_get_dynamic_hardness (paint_options,
                                                      &paint_core->cur_coords);

  gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
                                MIN (opacity, GIMP_OPACITY_OPAQUE),
                                gimp_context_get_opacity (context),
                                (options->anti_erase ?
                                 GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE),
                                gimp_paint_options_get_brush_mode (paint_options),
                                hardness,
                                paint_options->application_mode);
}
예제 #4
0
static TempBuf *
gimp_brush_generated_calc (GimpBrushGenerated      *brush,
                           GimpBrushGeneratedShape  shape,
                           gfloat                   radius,
                           gint                     spikes,
                           gfloat                   hardness,
                           gfloat                   aspect_ratio,
                           gfloat                   angle,
                           GimpVector2             *xaxis,
                           GimpVector2             *yaxis)
{
  guchar      *centerp;
  guchar      *lookup;
  guchar       a;
  gint         half_width  = 0;
  gint         half_height = 0;
  gint         x, y;
  gdouble      c, s, cs, ss;
  GimpVector2  x_axis;
  GimpVector2  y_axis;
  TempBuf     *mask;

  gimp_brush_generated_get_half_size (brush,
                                      shape,
                                      radius,
                                      spikes,
                                      hardness,
                                      aspect_ratio,
                                      angle,
                                      &half_width, &half_height,
                                      &s, &c, &x_axis, &y_axis);

  mask = temp_buf_new (half_width  * 2 + 1,
                       half_height * 2 + 1,
                       1, half_width, half_height, NULL);

  centerp = temp_buf_data (mask) + half_height * mask->width + half_width;

  lookup = gimp_brush_generated_calc_lut (radius, hardness);

  cs = cos (- 2 * G_PI / spikes);
  ss = sin (- 2 * G_PI / spikes);

  /* for an even number of spikes compute one half and mirror it */
  for (y = (spikes % 2 ? -half_height : 0); y <= half_height; y++)
    {
      for (x = -half_width; x <= half_width; x++)
        {
          gdouble d  = 0;
          gdouble tx = c * x - s * y;
          gdouble ty = fabs (s * x + c * y);

          if (spikes > 2)
            {
              gdouble angle = atan2 (ty, tx);

              while (angle > G_PI / spikes)
                {
                  gdouble sx = tx;
                  gdouble sy = ty;

                  tx = cs * sx - ss * sy;
                  ty = ss * sx + cs * sy;

                  angle -= 2 * G_PI / spikes;
                }
            }

          ty *= aspect_ratio;

          switch (shape)
            {
            case GIMP_BRUSH_GENERATED_CIRCLE:
              d = sqrt (SQR (tx) + SQR (ty));
              break;
            case GIMP_BRUSH_GENERATED_SQUARE:
              d = MAX (fabs (tx), fabs (ty));
              break;
            case GIMP_BRUSH_GENERATED_DIAMOND:
              d = fabs (tx) + fabs (ty);
              break;
            }

          if (d < radius + 1)
            a = lookup[(gint) RINT (d * OVERSAMPLING)];
          else
            a = 0;

          centerp[y * mask->width + x] = a;

          if (spikes % 2 == 0)
            centerp[-1 * y * mask->width - x] = a;
        }
    }

  g_free (lookup);

  if (xaxis)
    *xaxis = x_axis;

  if (yaxis)
    *yaxis = y_axis;

  return mask;
}
예제 #5
0
static GValueArray *
brushes_get_brush_data_invoker (GimpProcedure     *procedure,
                                Gimp              *gimp,
                                GimpContext       *context,
                                GimpProgress      *progress,
                                const GValueArray *args)
{
  gboolean success = TRUE;
  GValueArray *return_vals;
  const gchar *name;
  gchar *actual_name = NULL;
  gdouble opacity = 0.0;
  gint32 spacing = 0;
  gint32 paint_mode = 0;
  gint32 width = 0;
  gint32 height = 0;
  gint32 length = 0;
  guint8 *mask_data = NULL;

  name = g_value_get_string (&args->values[0]);

  if (success)
    {
      GimpBrush *brush;

      if (name && strlen (name))
        {
          brush = (GimpBrush *)
            gimp_container_get_child_by_name (gimp->brush_factory->container, name);
        }
      else
        {
          brush = gimp_context_get_brush (context);
        }

      if (brush)
        {
          actual_name = g_strdup (gimp_object_get_name (GIMP_OBJECT (brush)));
          opacity     = 1.0;
          spacing     = gimp_brush_get_spacing (brush);
          paint_mode  = 0;
          width       = brush->mask->width;
          height      = brush->mask->height;
          length      = brush->mask->height * brush->mask->width;
          mask_data   = g_memdup (temp_buf_data (brush->mask), length);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success);

  if (success)
    {
      g_value_take_string (&return_vals->values[1], actual_name);
      g_value_set_double (&return_vals->values[2], opacity);
      g_value_set_int (&return_vals->values[3], spacing);
      g_value_set_enum (&return_vals->values[4], paint_mode);
      g_value_set_int (&return_vals->values[5], width);
      g_value_set_int (&return_vals->values[6], height);
      g_value_set_int (&return_vals->values[7], length);
      gimp_value_take_int8array (&return_vals->values[8], mask_data, length);
    }

  return return_vals;
}
예제 #6
0
void
_gimp_paintbrush_motion (GimpPaintCore    *paint_core,
                         GimpDrawable     *drawable,
                         GimpPaintOptions *paint_options,
                         gdouble           opacity)
{
  GimpBrushCore            *brush_core       = GIMP_BRUSH_CORE (paint_core);
  GimpContext              *context          = GIMP_CONTEXT (paint_options);
  GimpPressureOptions      *pressure_options = paint_options->pressure_options;
  GimpImage                *image;
  GimpRGB                   gradient_color;
  TempBuf                  *area;
  guchar                    col[MAX_CHANNELS];
  GimpPaintApplicationMode  paint_appl_mode;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  opacity *= gimp_paint_options_get_fade (paint_options, image,
                                          paint_core->pixel_dist);
  if (opacity == 0.0)
    return;

  paint_appl_mode = paint_options->application_mode;

  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
  if (! area)
    return;

  /* optionally take the color from the current gradient */
  if (gimp_paint_options_get_gradient_color (paint_options, image,
                                             paint_core->cur_coords.pressure,
                                             paint_core->pixel_dist,
                                             &gradient_color))
    {
      opacity *= gradient_color.a;

      gimp_rgb_get_uchar (&gradient_color,
                          &col[RED_PIX],
                          &col[GREEN_PIX],
                          &col[BLUE_PIX]);
      col[ALPHA_PIX] = OPAQUE_OPACITY;

      color_pixels (temp_buf_data (area), col,
                    area->width * area->height,
                    area->bytes);

      paint_appl_mode = GIMP_PAINT_INCREMENTAL;
    }
  /* otherwise check if the brush has a pixmap and use that to color the area */
  else if (brush_core->brush && brush_core->brush->pixmap)
    {
      gimp_brush_core_color_area_with_pixmap (brush_core, drawable,
                                              area,
                                              gimp_paint_options_get_brush_mode (paint_options));

      paint_appl_mode = GIMP_PAINT_INCREMENTAL;
    }
  /* otherwise fill the area with the foreground color */
  else
    {
      gimp_image_get_foreground (image, context, gimp_drawable_type (drawable),
                                 col);

      col[area->bytes - 1] = OPAQUE_OPACITY;

      color_pixels (temp_buf_data (area), col,
                    area->width * area->height,
                    area->bytes);
    }

  if (paint_core->use_pressure && pressure_options->opacity)
    opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure;

  /* finally, let the brush core paste the colored area on the canvas */
  gimp_brush_core_paste_canvas (brush_core, drawable,
                                MIN (opacity, GIMP_OPACITY_OPAQUE),
                                gimp_context_get_opacity (context),
                                gimp_context_get_paint_mode (context),
                                gimp_paint_options_get_brush_mode (paint_options),
                                paint_appl_mode);
}