Пример #1
0
static void
paint_mask_to_canvas_tiles (GimpPaintCore *core,
                            PixelRegion   *paint_maskPR,
                            gdouble        paint_opacity)
{
  PixelRegion srcPR;

  /*   combine the paint mask and the canvas tiles  */
  pixel_region_init (&srcPR, core->canvas_tiles,
                     core->canvas_buf->x,
                     core->canvas_buf->y,
                     core->canvas_buf->width,
                     core->canvas_buf->height,
                     TRUE);

  /*  combine the mask to the canvas tiles  */
  combine_mask_and_region (&srcPR, paint_maskPR,
                           paint_opacity * 255.999, GIMP_IS_AIRBRUSH (core));
}
Пример #2
0
/* This works similarly to gimp_paint_core_paste. However, instead of
 * combining the canvas to the paint core drawable using one of the
 * combination modes, it uses a "replace" mode (i.e. transparent
 * pixels in the canvas erase the paint core drawable).

 * When not drawing on alpha-enabled images, it just paints using
 * NORMAL mode.
 */
void
gimp_paint_core_replace (GimpPaintCore            *core,
                         const GimpTempBuf        *paint_mask,
                         gint                      paint_mask_offset_x,
                         gint                      paint_mask_offset_y,
                         GimpDrawable             *drawable,
                         gdouble                   paint_opacity,
                         gdouble                   image_opacity,
                         GimpPaintApplicationMode  mode)
{
  GeglRectangle  mask_rect;
  GeglBuffer    *paint_mask_buffer;
  gint           width, height;

  if (! gimp_drawable_has_alpha (drawable))
    {
      gimp_paint_core_paste (core, paint_mask,
                             paint_mask_offset_x,
                             paint_mask_offset_y,
                             drawable,
                             paint_opacity,
                             image_opacity, GIMP_NORMAL_MODE,
                             mode);
      return;
    }

  width  = gegl_buffer_get_width  (core->paint_buffer);
  height = gegl_buffer_get_height (core->paint_buffer);

  if (mode == GIMP_PAINT_CONSTANT &&

      /* Some tools (ink) paint the mask to paint_core->canvas_buffer
       * directly. Don't need to copy it in this case.
       */
      paint_mask != NULL)
    {
      if (core->applicator)
        {
          paint_mask_buffer =
            gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);

          /* combine the paint mask and the canvas buffer */
          gimp_gegl_combine_mask_weird (paint_mask_buffer,
                                        GEGL_RECTANGLE (paint_mask_offset_x,
                                                        paint_mask_offset_y,
                                                        width, height),
                                        core->canvas_buffer,
                                        GEGL_RECTANGLE (core->paint_buffer_x,
                                                        core->paint_buffer_y,
                                                        width, height),
                                        paint_opacity,
                                        GIMP_IS_AIRBRUSH (core));

          g_object_unref (paint_mask_buffer);
        }
      else
        {
          /* Mix paint mask and canvas_buffer */
          combine_paint_mask_to_canvas_mask (paint_mask,
                                             paint_mask_offset_x,
                                             paint_mask_offset_y,
                                             core->canvas_buffer,
                                             core->paint_buffer_x,
                                             core->paint_buffer_y,
                                             paint_opacity,
                                             GIMP_IS_AIRBRUSH (core));
        }

      /* initialize the maskPR from the canvas buffer */
      paint_mask_buffer = g_object_ref (core->canvas_buffer);

      mask_rect = *GEGL_RECTANGLE (core->paint_buffer_x,
                                   core->paint_buffer_y,
                                   width, height);
    }
  else
    {
      paint_mask_buffer =
        gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);

      mask_rect = *GEGL_RECTANGLE (paint_mask_offset_x,
                                   paint_mask_offset_y,
                                   width, height);
    }

  /*  apply the paint area to the image  */
  gimp_drawable_replace_buffer (drawable, core->paint_buffer,
                                GEGL_RECTANGLE (0, 0, width, height),
                                FALSE, NULL,
                                image_opacity,
                                paint_mask_buffer, &mask_rect,
                                core->paint_buffer_x,
                                core->paint_buffer_y);

  g_object_unref (paint_mask_buffer);

  /*  Update the undo extents  */
  core->x1 = MIN (core->x1, core->paint_buffer_x);
  core->y1 = MIN (core->y1, core->paint_buffer_y);
  core->x2 = MAX (core->x2, core->paint_buffer_x + width);
  core->y2 = MAX (core->y2, core->paint_buffer_y + height);

  /*  Update the drawable  */
  gimp_drawable_update (drawable,
                        core->paint_buffer_x,
                        core->paint_buffer_y,
                        width, height);
}
Пример #3
0
void
gimp_paint_core_paste (GimpPaintCore            *core,
                       const GimpTempBuf        *paint_mask,
                       gint                      paint_mask_offset_x,
                       gint                      paint_mask_offset_y,
                       GimpDrawable             *drawable,
                       gdouble                   paint_opacity,
                       gdouble                   image_opacity,
                       GimpLayerModeEffects      paint_mode,
                       GimpPaintApplicationMode  mode)
{
  gint width  = gegl_buffer_get_width  (core->paint_buffer);
  gint height = gegl_buffer_get_height (core->paint_buffer);

  if (core->applicator)
    {
      /*  If the mode is CONSTANT:
       *   combine the canvas buf, the paint mask to the canvas buffer
       */
      if (mode == GIMP_PAINT_CONSTANT)
        {
          /* Some tools (ink) paint the mask to paint_core->canvas_buffer
           * directly. Don't need to copy it in this case.
           */
          if (paint_mask != NULL)
            {
              GeglBuffer *paint_mask_buffer =
                gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);

              gimp_gegl_combine_mask_weird (paint_mask_buffer,
                                            GEGL_RECTANGLE (paint_mask_offset_x,
                                                            paint_mask_offset_y,
                                                            width, height),
                                            core->canvas_buffer,
                                            GEGL_RECTANGLE (core->paint_buffer_x,
                                                            core->paint_buffer_y,
                                                            width, height),
                                            paint_opacity,
                                            GIMP_IS_AIRBRUSH (core));

              g_object_unref (paint_mask_buffer);
            }

          gimp_gegl_apply_mask (core->canvas_buffer,
                                GEGL_RECTANGLE (core->paint_buffer_x,
                                                core->paint_buffer_y,
                                                width, height),
                                core->paint_buffer,
                                GEGL_RECTANGLE (0, 0, width, height),
                                1.0);

          gimp_applicator_set_src_buffer (core->applicator,
                                          core->undo_buffer);
        }
      /*  Otherwise:
       *   combine the canvas buf and the paint mask to the canvas buf
       */
      else
        {
          GeglBuffer *paint_mask_buffer =
            gimp_temp_buf_create_buffer ((GimpTempBuf *) paint_mask);

          gimp_gegl_apply_mask (paint_mask_buffer,
                                GEGL_RECTANGLE (paint_mask_offset_x,
                                                paint_mask_offset_y,
                                                width, height),
                                core->paint_buffer,
                                GEGL_RECTANGLE (0, 0, width, height),
                                paint_opacity);

          g_object_unref (paint_mask_buffer);

          gimp_applicator_set_src_buffer (core->applicator,
                                          gimp_drawable_get_buffer (drawable));
        }

      gimp_applicator_set_apply_buffer (core->applicator,
                                        core->paint_buffer);
      gimp_applicator_set_apply_offset (core->applicator,
                                        core->paint_buffer_x,
                                        core->paint_buffer_y);

      gimp_applicator_set_mode (core->applicator,
                                image_opacity, paint_mode);

      /*  apply the paint area to the image  */
      gimp_applicator_blit (core->applicator,
                            GEGL_RECTANGLE (core->paint_buffer_x,
                                            core->paint_buffer_y,
                                            width, height));
    }
  else
    {
      GimpTempBuf *paint_buf = gimp_gegl_buffer_get_temp_buf (core->paint_buffer);
      GeglBuffer  *dest_buffer;
      GeglBuffer  *src_buffer;

      if (! paint_buf)
        return;

      if (core->comp_buffer)
        dest_buffer = core->comp_buffer;
      else
        dest_buffer = gimp_drawable_get_buffer (drawable);

      if (mode == GIMP_PAINT_CONSTANT)
        {
          /* This step is skipped by the ink tool, which writes
           * directly to canvas_buffer
           */
          if (paint_mask != NULL)
            {
              /* Mix paint mask and canvas_buffer */
              combine_paint_mask_to_canvas_mask (paint_mask,
                                                 paint_mask_offset_x,
                                                 paint_mask_offset_y,
                                                 core->canvas_buffer,
                                                 core->paint_buffer_x,
                                                 core->paint_buffer_y,
                                                 paint_opacity,
                                                 GIMP_IS_AIRBRUSH (core));
            }

          /* Write canvas_buffer to paint_buf */
          canvas_buffer_to_paint_buf_alpha (paint_buf,
                                            core->canvas_buffer,
                                            core->paint_buffer_x,
                                            core->paint_buffer_y);

          /* undo buf -> paint_buf -> dest_buffer */
          src_buffer = core->undo_buffer;
        }
      else
        {
          g_return_if_fail (paint_mask);

          /* Write paint_mask to paint_buf, does not modify canvas_buffer */
          paint_mask_to_paint_buffer (paint_mask,
                                      paint_mask_offset_x,
                                      paint_mask_offset_y,
                                      paint_buf,
                                      paint_opacity);

          /* dest_buffer -> paint_buf -> dest_buffer */
          src_buffer = dest_buffer;
        }

      do_layer_blend (src_buffer,
                      dest_buffer,
                      paint_buf,
                      core->mask_buffer,
                      image_opacity,
                      core->paint_buffer_x,
                      core->paint_buffer_y,
                      core->mask_x_offset,
                      core->mask_y_offset,
                      core->linear_mode,
                      paint_mode);

      if (core->comp_buffer)
        {
          mask_components_onto (src_buffer,
                                core->comp_buffer,
                                gimp_drawable_get_buffer (drawable),
                                GEGL_RECTANGLE(core->paint_buffer_x,
                                               core->paint_buffer_y,
                                               width,
                                               height),
                                gimp_drawable_get_active_mask (drawable),
                                core->linear_mode);
        }
    }

  /*  Update the undo extents  */
  core->x1 = MIN (core->x1, core->paint_buffer_x);
  core->y1 = MIN (core->y1, core->paint_buffer_y);
  core->x2 = MAX (core->x2, core->paint_buffer_x + width);
  core->y2 = MAX (core->y2, core->paint_buffer_y + height);

  /*  Update the drawable  */
  gimp_drawable_update (drawable,
                        core->paint_buffer_x,
                        core->paint_buffer_y,
                        width, height);
}
Пример #4
0
void
gimp_paint_core_paste (GimpPaintCore            *core,
                       GeglBuffer               *paint_mask,
                       const GeglRectangle      *paint_mask_rect,
                       GimpDrawable             *drawable,
                       gdouble                   paint_opacity,
                       gdouble                   image_opacity,
                       GimpLayerModeEffects      paint_mode,
                       GimpPaintApplicationMode  mode)
{
  GeglBuffer *base_buffer = NULL;
  gint        width       = gegl_buffer_get_width  (core->paint_buffer);
  gint        height      = gegl_buffer_get_height (core->paint_buffer);

  /*  If the mode is CONSTANT:
   *   combine the canvas buf, the paint mask to the canvas buffer
   */
  if (mode == GIMP_PAINT_CONSTANT)
    {
      /* Some tools (ink) paint the mask to paint_core->canvas_buffer
       * directly. Don't need to copy it in this case.
       */
      if (paint_mask != core->canvas_buffer)
        {
          gimp_gegl_combine_mask_weird (paint_mask, paint_mask_rect,
                                        core->canvas_buffer,
                                        GEGL_RECTANGLE (core->paint_buffer_x,
                                                        core->paint_buffer_y,
                                                        width, height),
                                        paint_opacity,
                                        GIMP_IS_AIRBRUSH (core));
        }

      gimp_gegl_apply_mask (core->canvas_buffer,
                            GEGL_RECTANGLE (core->paint_buffer_x,
                                            core->paint_buffer_y,
                                            width, height),
                            core->paint_buffer,
                            GEGL_RECTANGLE (0, 0, width, height),
                            1.0);

      base_buffer = core->undo_buffer;
    }
  /*  Otherwise:
   *   combine the canvas buf and the paint mask to the canvas buf
   */
  else
    {
      gimp_gegl_apply_mask (paint_mask, paint_mask_rect,
                            core->paint_buffer,
                            GEGL_RECTANGLE (0, 0, width, height),
                            paint_opacity);

      base_buffer = gimp_drawable_get_buffer (drawable);
    }

  /*  apply the paint area to the image  */
  gimp_applicator_apply (core->applicator,
                         base_buffer,
                         core->paint_buffer,
                         core->paint_buffer_x,
                         core->paint_buffer_y,
                         image_opacity, paint_mode);

  /*  Update the undo extents  */
  core->x1 = MIN (core->x1, core->paint_buffer_x);
  core->y1 = MIN (core->y1, core->paint_buffer_y);
  core->x2 = MAX (core->x2, core->paint_buffer_x + width);
  core->y2 = MAX (core->y2, core->paint_buffer_y + height);

  /*  Update the drawable  */
  gimp_drawable_update (drawable,
                        core->paint_buffer_x,
                        core->paint_buffer_y,
                        width, height);
}