Ejemplo n.º 1
0
static TempBuf *
gimp_ink_get_paint_area (GimpPaintCore    *paint_core,
                         GimpDrawable     *drawable,
                         GimpPaintOptions *paint_options,
                         const GimpCoords *coords)
{
  GimpInk *ink = GIMP_INK (paint_core);
  gint     x, y;
  gint     width, height;
  gint     dwidth, dheight;
  gint     x1, y1, x2, y2;
  gint     bytes;

  bytes = gimp_drawable_bytes_with_alpha (drawable);

  gimp_blob_bounds (ink->cur_blob, &x, &y, &width, &height);

  dwidth  = gimp_item_get_width  (GIMP_ITEM (drawable));
  dheight = gimp_item_get_height (GIMP_ITEM (drawable));

  x1 = CLAMP (x / SUBSAMPLE - 1,            0, dwidth);
  y1 = CLAMP (y / SUBSAMPLE - 1,            0, dheight);
  x2 = CLAMP ((x + width)  / SUBSAMPLE + 2, 0, dwidth);
  y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight);

  /*  configure the canvas buffer  */
  if ((x2 - x1) && (y2 - y1))
    paint_core->canvas_buf = temp_buf_resize (paint_core->canvas_buf, bytes,
                                              x1, y1,
                                              (x2 - x1), (y2 - y1));
  else
    return NULL;

  return paint_core->canvas_buf;
}
Ejemplo n.º 2
0
static void
gimp_ink_undo_constructed (GObject *object)
{
  GimpInkUndo *ink_undo = GIMP_INK_UNDO (object);
  GimpInk     *ink;

  G_OBJECT_CLASS (parent_class)->constructed (object);

  g_assert (GIMP_IS_INK (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core));

  ink = GIMP_INK (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core);

  if (ink->start_blobs)
    {
      gint      i;
      GimpBlob *blob;

      for (i = 0; i < g_list_length (ink->start_blobs); i++)
        {
          blob = g_list_nth_data (ink->start_blobs, i);

          ink_undo->last_blobs = g_list_prepend (ink_undo->last_blobs,
                                                 gimp_blob_duplicate (blob));
        }
      ink_undo->last_blobs = g_list_reverse (ink_undo->last_blobs);
    }
}
Ejemplo n.º 3
0
static void
gimp_ink_paint (GimpPaintCore    *paint_core,
                GimpDrawable     *drawable,
                GimpPaintOptions *paint_options,
                const GimpCoords *coords,
                GimpPaintState    paint_state,
                guint32           time)
{
  GimpInk *ink = GIMP_INK (paint_core);
  GimpCoords last_coords;

  gimp_paint_core_get_last_coords (paint_core, &last_coords);

  switch (paint_state)
    {

    case GIMP_PAINT_STATE_INIT:

      if (coords->x == last_coords.x &&
          coords->y == last_coords.y)
        {
          /*  start with new blobs if we're not interpolating  */

          if (ink->start_blob)
            {
              g_free (ink->start_blob);
              ink->start_blob = NULL;
            }

          if (ink->last_blob)
            {
              g_free (ink->last_blob);
              ink->last_blob = NULL;
            }
        }
      else if (ink->last_blob)
        {
          /*  save the start blob of the line for undo otherwise  */

          if (ink->start_blob)
            g_free (ink->start_blob);

          ink->start_blob = gimp_blob_duplicate (ink->last_blob);
        }
      break;

    case GIMP_PAINT_STATE_MOTION:
      gimp_ink_motion (paint_core, drawable, paint_options, coords, time);
      break;

    case GIMP_PAINT_STATE_FINISH:
      break;
    }
}
Ejemplo n.º 4
0
static GeglBuffer *
gimp_ink_get_paint_buffer (GimpPaintCore    *paint_core,
                           GimpDrawable     *drawable,
                           GimpPaintOptions *paint_options,
                           const GimpCoords *coords,
                           gint             *paint_buffer_x,
                           gint             *paint_buffer_y)
{
  GimpInk *ink = GIMP_INK (paint_core);
  gint     x, y;
  gint     width, height;
  gint     dwidth, dheight;
  gint     x1, y1, x2, y2;

  gimp_blob_bounds (ink->cur_blob, &x, &y, &width, &height);

  dwidth  = gimp_item_get_width  (GIMP_ITEM (drawable));
  dheight = gimp_item_get_height (GIMP_ITEM (drawable));

  x1 = CLAMP (x / SUBSAMPLE - 1,            0, dwidth);
  y1 = CLAMP (y / SUBSAMPLE - 1,            0, dheight);
  x2 = CLAMP ((x + width)  / SUBSAMPLE + 2, 0, dwidth);
  y2 = CLAMP ((y + height) / SUBSAMPLE + 2, 0, dheight);

  /*  configure the canvas buffer  */
  if ((x2 - x1) && (y2 - y1))
    {
      GimpTempBuf *temp_buf;
      const Babl  *format;

      if (gimp_drawable_get_linear (drawable))
        format = babl_format ("RGBA float");
      else
        format = babl_format ("R'G'B'A float");

      temp_buf = gimp_temp_buf_new ((x2 - x1), (y2 - y1),
                                    format);

      *paint_buffer_x = x1;
      *paint_buffer_y = y1;

      if (paint_core->paint_buffer)
        g_object_unref (paint_core->paint_buffer);

      paint_core->paint_buffer = gimp_temp_buf_create_buffer (temp_buf);

      gimp_temp_buf_unref (temp_buf);

      return paint_core->paint_buffer;
    }

  return NULL;
}
Ejemplo n.º 5
0
static void
gimp_ink_undo_constructed (GObject *object)
{
  GimpInkUndo *ink_undo = GIMP_INK_UNDO (object);
  GimpInk     *ink;

  G_OBJECT_CLASS (parent_class)->constructed (object);

  g_assert (GIMP_IS_INK (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core));

  ink = GIMP_INK (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core);

  if (ink->start_blob)
    ink_undo->last_blob = gimp_blob_duplicate (ink->start_blob);
}
Ejemplo n.º 6
0
static void
gimp_ink_finalize (GObject *object)
{
  GimpInk *ink = GIMP_INK (object);

  if (ink->start_blob)
    {
      g_free (ink->start_blob);
      ink->start_blob = NULL;
    }

  if (ink->last_blob)
    {
      g_free (ink->last_blob);
      ink->last_blob = NULL;
    }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}
Ejemplo n.º 7
0
static void
gimp_ink_undo_pop (GimpUndo              *undo,
                   GimpUndoMode           undo_mode,
                   GimpUndoAccumulator   *accum)
{
  GimpInkUndo *ink_undo = GIMP_INK_UNDO (undo);

  GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);

  if (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core)
    {
      GimpInk  *ink = GIMP_INK (GIMP_PAINT_CORE_UNDO (ink_undo)->paint_core);
      GList    *tmp_blobs;

      tmp_blobs = ink->last_blobs;
      ink->last_blobs = ink_undo->last_blobs;
      ink_undo->last_blobs = tmp_blobs;
    }
}
Ejemplo n.º 8
0
static void
gimp_ink_motion (GimpPaintCore    *paint_core,
                 GimpDrawable     *drawable,
                 GimpPaintOptions *paint_options,
                 const GimpCoords *coords,
                 guint32           time)
{
  GimpInk        *ink        = GIMP_INK (paint_core);
  GimpInkOptions *options    = GIMP_INK_OPTIONS (paint_options);
  GimpContext    *context    = GIMP_CONTEXT (paint_options);
  GimpBlob       *blob_union = NULL;
  GimpBlob       *blob_to_render;
  GeglBuffer     *paint_buffer;
  gint            paint_buffer_x;
  gint            paint_buffer_y;
  GimpRGB         foreground;
  GeglColor      *color;

  if (! ink->last_blob)
    {
      ink->last_blob = ink_pen_ellipse (options,
                                        coords->x,
                                        coords->y,
                                        coords->pressure,
                                        coords->xtilt,
                                        coords->ytilt,
                                        100);

      if (ink->start_blob)
        g_free (ink->start_blob);

      ink->start_blob = gimp_blob_duplicate (ink->last_blob);

      blob_to_render = ink->last_blob;
    }
  else
    {
      GimpBlob *blob = ink_pen_ellipse (options,
                                        coords->x,
                                        coords->y,
                                        coords->pressure,
                                        coords->xtilt,
                                        coords->ytilt,
                                        coords->velocity * 100);

      blob_union = gimp_blob_convex_union (ink->last_blob, blob);

      g_free (ink->last_blob);
      ink->last_blob = blob;

      blob_to_render = blob_union;
    }

  /* Get the buffer */
  ink->cur_blob = blob_to_render;
  paint_buffer = gimp_paint_core_get_paint_buffer (paint_core, drawable,
                                                   paint_options, coords,
                                                   &paint_buffer_x,
                                                   &paint_buffer_y);
  ink->cur_blob = NULL;

  if (! paint_buffer)
    return;

  gimp_context_get_foreground (context, &foreground);
  color = gimp_gegl_color_new (&foreground);

  gegl_buffer_set_color (paint_buffer, NULL, color);
  g_object_unref (color);

  /*  draw the blob directly to the canvas_buffer  */
  render_blob (paint_core->canvas_buffer,
               GEGL_RECTANGLE (paint_core->paint_buffer_x,
                               paint_core->paint_buffer_y,
                               gegl_buffer_get_width  (paint_core->paint_buffer),
                               gegl_buffer_get_height (paint_core->paint_buffer)),
               blob_to_render);

  /*  draw the paint_area using the just rendered canvas_buffer as mask */
  gimp_paint_core_paste (paint_core,
                         paint_core->canvas_buffer,
                         GEGL_RECTANGLE (paint_core->paint_buffer_x,
                                         paint_core->paint_buffer_y,
                                         gegl_buffer_get_width  (paint_core->paint_buffer),
                                         gegl_buffer_get_height (paint_core->paint_buffer)),
                         drawable,
                         GIMP_OPACITY_OPAQUE,
                         gimp_context_get_opacity (context),
                         gimp_context_get_paint_mode (context),
                         GIMP_PAINT_CONSTANT);

  if (blob_union)
    g_free (blob_union);
}
Ejemplo n.º 9
0
static void
gimp_ink_motion (GimpPaintCore    *paint_core,
                 GimpDrawable     *drawable,
                 GimpPaintOptions *paint_options,
                 const GimpCoords *coords,
                 guint32           time)
{
  GimpInk        *ink     = GIMP_INK (paint_core);
  GimpInkOptions *options = GIMP_INK_OPTIONS (paint_options);
  GimpContext    *context = GIMP_CONTEXT (paint_options);
  GimpImage      *image;
  GimpBlob       *blob_union = NULL;
  GimpBlob       *blob_to_render;
  TempBuf        *area;
  guchar          col[MAX_CHANNELS];
  PixelRegion     blob_maskPR;

  image = gimp_item_get_image (GIMP_ITEM (drawable));

  if (! ink->last_blob)
    {
      ink->last_blob = ink_pen_ellipse (options,
                                        coords->x,
                                        coords->y,
                                        coords->pressure,
                                        coords->xtilt,
                                        coords->ytilt,
                                        100);

      if (ink->start_blob)
        g_free (ink->start_blob);

      ink->start_blob = gimp_blob_duplicate (ink->last_blob);

      blob_to_render = ink->last_blob;
    }
  else
    {
      GimpBlob *blob = ink_pen_ellipse (options,
                                        coords->x,
                                        coords->y,
                                        coords->pressure,
                                        coords->xtilt,
                                        coords->ytilt,
                                        coords->velocity * 100);

      blob_union = gimp_blob_convex_union (ink->last_blob, blob);

      g_free (ink->last_blob);
      ink->last_blob = blob;

      blob_to_render = blob_union;
    }

  /* Get the buffer */
  ink->cur_blob = blob_to_render;
  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options,
                                         coords);
  ink->cur_blob = NULL;

  if (! area)
    return;

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

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

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

  gimp_paint_core_validate_canvas_tiles (paint_core,
                                         paint_core->canvas_buf->x,
                                         paint_core->canvas_buf->y,
                                         paint_core->canvas_buf->width,
                                         paint_core->canvas_buf->height);

  /*  draw the blob directly to the canvas_tiles  */
  pixel_region_init (&blob_maskPR, paint_core->canvas_tiles,
                     paint_core->canvas_buf->x,
                     paint_core->canvas_buf->y,
                     paint_core->canvas_buf->width,
                     paint_core->canvas_buf->height,
                     TRUE);

  render_blob (blob_to_render, &blob_maskPR);

  /*  draw the canvas_buf using the just rendered canvas_tiles as mask */
  pixel_region_init (&blob_maskPR, paint_core->canvas_tiles,
                     paint_core->canvas_buf->x,
                     paint_core->canvas_buf->y,
                     paint_core->canvas_buf->width,
                     paint_core->canvas_buf->height,
                     FALSE);

  gimp_paint_core_paste (paint_core, &blob_maskPR, drawable,
                         GIMP_OPACITY_OPAQUE,
                         gimp_context_get_opacity (context),
                         gimp_context_get_paint_mode (context),
                         GIMP_PAINT_CONSTANT);

  if (blob_union)
    g_free (blob_union);
}