~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/paint/gimpclone.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: james.westby@ubuntu.com-20070502163303-6wchheivjxgjtlna
Tags: upstream-2.3.16
ImportĀ upstreamĀ versionĀ 2.3.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
23
23
 
24
24
#include <glib-object.h>
25
25
 
 
26
#include "libgimpbase/gimpbase.h"
 
27
 
26
28
#include "paint-types.h"
27
29
 
28
30
#include "base/pixel-region.h"
29
31
#include "base/temp-buf.h"
 
32
#include "base/tile-manager.h"
30
33
 
31
34
#include "paint-funcs/paint-funcs.h"
32
35
 
34
37
#include "core/gimpdrawable.h"
35
38
#include "core/gimpimage.h"
36
39
#include "core/gimppattern.h"
 
40
#include "core/gimppickable.h"
37
41
 
38
42
#include "gimpclone.h"
39
43
#include "gimpcloneoptions.h"
41
45
#include "gimp-intl.h"
42
46
 
43
47
 
44
 
static void   gimp_clone_class_init       (GimpCloneClass   *klass);
45
 
static void   gimp_clone_init             (GimpClone        *clone);
46
 
 
47
 
static void   gimp_clone_paint            (GimpPaintCore    *paint_core,
48
 
                                           GimpDrawable     *drawable,
49
 
                                           GimpPaintOptions *paint_options,
50
 
                                           GimpPaintState    paint_state,
51
 
                                           guint32           time);
52
 
static void   gimp_clone_motion           (GimpPaintCore    *paint_core,
53
 
                                           GimpDrawable     *drawable,
54
 
                                           GimpPaintOptions *paint_options);
55
 
 
56
 
static void   gimp_clone_line_image       (GimpImage        *dest,
57
 
                                           GimpImage        *src,
58
 
                                           GimpDrawable     *d_drawable,
59
 
                                           GimpDrawable     *s_drawable,
60
 
                                           guchar           *s,
61
 
                                           guchar           *d,
62
 
                                           gint              has_alpha,
63
 
                                           gint              src_bytes,
64
 
                                           gint              dest_bytes,
65
 
                                           gint              width);
66
 
static void   gimp_clone_line_pattern     (GimpImage        *dest,
67
 
                                           GimpDrawable     *drawable,
68
 
                                           GimpPattern      *pattern,
69
 
                                           guchar           *d,
70
 
                                           gint              x,
71
 
                                           gint              y,
72
 
                                           gint              bytes,
73
 
                                           gint              width);
74
 
 
75
 
static void   gimp_clone_set_src_drawable (GimpClone        *clone,
76
 
                                           GimpDrawable     *drawable);
77
 
 
78
 
 
79
 
static GimpBrushCoreClass *parent_class = NULL;
 
48
static gboolean gimp_clone_start        (GimpPaintCore    *paint_core,
 
49
                                         GimpDrawable     *drawable,
 
50
                                         GimpPaintOptions *paint_options,
 
51
                                         GimpCoords       *coords,
 
52
                                         GError          **error);
 
53
 
 
54
static void     gimp_clone_motion       (GimpSourceCore   *source_core,
 
55
                                         GimpDrawable     *drawable,
 
56
                                         GimpPaintOptions *paint_options,
 
57
                                         gdouble           opacity,
 
58
                                         GimpPickable     *src_pickable,
 
59
                                         PixelRegion      *srcPR,
 
60
                                         gint              src_offset_x,
 
61
                                         gint              src_offset_y,
 
62
                                         TempBuf          *paint_area,
 
63
                                         gint              paint_area_offset_x,
 
64
                                         gint              paint_area_offset_y,
 
65
                                         gint              paint_area_width,
 
66
                                         gint              paint_area_height);
 
67
 
 
68
static void     gimp_clone_line_image   (GimpImage        *dest_image,
 
69
                                         GimpImageType     dest_type,
 
70
                                         GimpImage        *src_image,
 
71
                                         GimpImageType     src_type,
 
72
                                         guchar           *s,
 
73
                                         guchar           *d,
 
74
                                         gint              src_bytes,
 
75
                                         gint              dest_bytes,
 
76
                                         gint              width);
 
77
static void     gimp_clone_line_pattern (GimpImage        *dest_image,
 
78
                                         GimpImageType     dest_type,
 
79
                                         GimpPattern      *pattern,
 
80
                                         guchar           *d,
 
81
                                         gint              x,
 
82
                                         gint              y,
 
83
                                         gint              dest_bytes,
 
84
                                         gint              width);
 
85
 
 
86
 
 
87
G_DEFINE_TYPE (GimpClone, gimp_clone, GIMP_TYPE_SOURCE_CORE)
 
88
 
 
89
#define parent_class gimp_clone_parent_class
80
90
 
81
91
 
82
92
void
86
96
  (* callback) (gimp,
87
97
                GIMP_TYPE_CLONE,
88
98
                GIMP_TYPE_CLONE_OPTIONS,
89
 
                _("Clone"));
90
 
}
91
 
 
92
 
GType
93
 
gimp_clone_get_type (void)
94
 
{
95
 
  static GType type = 0;
96
 
 
97
 
  if (! type)
98
 
    {
99
 
      static const GTypeInfo info =
100
 
      {
101
 
        sizeof (GimpCloneClass),
102
 
        (GBaseInitFunc) NULL,
103
 
        (GBaseFinalizeFunc) NULL,
104
 
        (GClassInitFunc) gimp_clone_class_init,
105
 
        NULL,           /* class_finalize */
106
 
        NULL,           /* class_data     */
107
 
        sizeof (GimpClone),
108
 
        0,              /* n_preallocs    */
109
 
        (GInstanceInitFunc) gimp_clone_init,
110
 
      };
111
 
 
112
 
      type = g_type_register_static (GIMP_TYPE_BRUSH_CORE,
113
 
                                     "GimpClone",
114
 
                                     &info, 0);
115
 
    }
116
 
 
117
 
  return type;
 
99
                "gimp-clone",
 
100
                _("Clone"),
 
101
                "gimp-tool-clone");
118
102
}
119
103
 
120
104
static void
121
105
gimp_clone_class_init (GimpCloneClass *klass)
122
106
{
123
 
  GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
124
 
  GimpBrushCoreClass *brush_core_class = GIMP_BRUSH_CORE_CLASS (klass);
125
 
 
126
 
  parent_class = g_type_class_peek_parent (klass);
127
 
 
128
 
  paint_core_class->paint                  = gimp_clone_paint;
129
 
 
130
 
  brush_core_class->handles_changing_brush = TRUE;
 
107
  GimpPaintCoreClass  *paint_core_class  = GIMP_PAINT_CORE_CLASS (klass);
 
108
  GimpSourceCoreClass *source_core_class = GIMP_SOURCE_CORE_CLASS (klass);
 
109
 
 
110
  paint_core_class->start   = gimp_clone_start;
 
111
 
 
112
  source_core_class->motion = gimp_clone_motion;
131
113
}
132
114
 
133
115
static void
134
116
gimp_clone_init (GimpClone *clone)
135
117
{
136
 
  clone->set_source   = FALSE;
137
 
 
138
 
  clone->src_drawable = NULL;
139
 
  clone->src_x        = 0.0;
140
 
  clone->src_y        = 0.0;
141
 
 
142
 
  clone->orig_src_x   = 0;
143
 
  clone->orig_src_y   = 0;
144
 
 
145
 
  clone->offset_x     = 0;
146
 
  clone->offset_y     = 0;
147
 
  clone->first_stroke = TRUE;
148
118
}
149
119
 
150
 
static void
151
 
gimp_clone_paint (GimpPaintCore    *paint_core,
152
 
                  GimpDrawable     *drawable,
153
 
                  GimpPaintOptions *paint_options,
154
 
                  GimpPaintState    paint_state,
155
 
                  guint32           time)
 
120
static gboolean
 
121
gimp_clone_start (GimpPaintCore     *paint_core,
 
122
                  GimpDrawable      *drawable,
 
123
                  GimpPaintOptions  *paint_options,
 
124
                  GimpCoords        *coords,
 
125
                  GError           **error)
156
126
{
157
 
  GimpClone        *clone   = GIMP_CLONE (paint_core);
158
127
  GimpCloneOptions *options = GIMP_CLONE_OPTIONS (paint_options);
159
 
  GimpContext      *context = GIMP_CONTEXT (paint_options);
160
 
 
161
 
  switch (paint_state)
162
 
    {
163
 
    case GIMP_PAINT_STATE_INIT:
164
 
      if (clone->set_source)
165
 
        {
166
 
          gimp_clone_set_src_drawable (clone, drawable);
167
 
 
168
 
          clone->src_x = paint_core->cur_coords.x;
169
 
          clone->src_y = paint_core->cur_coords.y;
170
 
 
171
 
          clone->first_stroke = TRUE;
172
 
        }
173
 
      else if (options->align_mode == GIMP_CLONE_ALIGN_NO)
174
 
        {
175
 
          clone->orig_src_x = clone->src_x;
176
 
          clone->orig_src_y = clone->src_y;
177
 
 
178
 
          clone->first_stroke = TRUE;
179
 
        }
180
 
 
181
 
      if (options->clone_type == GIMP_PATTERN_CLONE)
182
 
        if (! gimp_context_get_pattern (context))
183
 
          g_message (_("No patterns available for this operation."));
184
 
      break;
185
 
 
186
 
    case GIMP_PAINT_STATE_MOTION:
187
 
      if (clone->set_source)
188
 
        {
189
 
          /*  If the control key is down, move the src target and return */
190
 
 
191
 
          clone->src_x = paint_core->cur_coords.x;
192
 
          clone->src_y = paint_core->cur_coords.y;
193
 
 
194
 
          clone->first_stroke = TRUE;
195
 
        }
196
 
      else
197
 
        {
198
 
          /*  otherwise, update the target  */
199
 
 
200
 
          gint dest_x;
201
 
          gint dest_y;
202
 
 
203
 
          dest_x = paint_core->cur_coords.x;
204
 
          dest_y = paint_core->cur_coords.y;
205
 
 
206
 
          if (options->align_mode == GIMP_CLONE_ALIGN_REGISTERED)
207
 
            {
208
 
              clone->offset_x = 0;
209
 
              clone->offset_y = 0;
210
 
            }
211
 
          else if (clone->first_stroke)
212
 
            {
213
 
              clone->offset_x = clone->src_x - dest_x;
214
 
              clone->offset_y = clone->src_y - dest_y;
215
 
 
216
 
              clone->first_stroke = FALSE;
217
 
            }
218
 
 
219
 
          clone->src_x = dest_x + clone->offset_x;
220
 
          clone->src_y = dest_y + clone->offset_y;
221
 
 
222
 
          gimp_clone_motion (paint_core, drawable, paint_options);
223
 
        }
224
 
      break;
225
 
 
226
 
    case GIMP_PAINT_STATE_FINISH:
227
 
      if (options->align_mode == GIMP_CLONE_ALIGN_NO && ! clone->first_stroke)
228
 
        {
229
 
          clone->src_x = clone->orig_src_x;
230
 
          clone->src_y = clone->orig_src_y;
231
 
        }
232
 
      break;
233
 
 
234
 
    default:
235
 
      break;
236
 
    }
 
128
 
 
129
  if (! GIMP_PAINT_CORE_CLASS (parent_class)->start (paint_core, drawable,
 
130
                                                     paint_options, coords,
 
131
                                                     error))
 
132
    {
 
133
      return FALSE;
 
134
    }
 
135
 
 
136
  if (options->clone_type == GIMP_PATTERN_CLONE)
 
137
    {
 
138
      if (! gimp_context_get_pattern (GIMP_CONTEXT (options)))
 
139
        {
 
140
          g_set_error (error, 0, 0,
 
141
                       _("No patterns available for use with this tool."));
 
142
          return FALSE;
 
143
        }
 
144
    }
 
145
 
 
146
  return TRUE;
237
147
}
238
148
 
239
149
static void
240
 
gimp_clone_motion (GimpPaintCore    *paint_core,
 
150
gimp_clone_motion (GimpSourceCore   *source_core,
241
151
                   GimpDrawable     *drawable,
242
 
                   GimpPaintOptions *paint_options)
 
152
                   GimpPaintOptions *paint_options,
 
153
                   gdouble           opacity,
 
154
                   GimpPickable     *src_pickable,
 
155
                   PixelRegion      *srcPR,
 
156
                   gint              src_offset_x,
 
157
                   gint              src_offset_y,
 
158
                   TempBuf          *paint_area,
 
159
                   gint              paint_area_offset_x,
 
160
                   gint              paint_area_offset_y,
 
161
                   gint              paint_area_width,
 
162
                   gint              paint_area_height)
243
163
{
244
 
  GimpClone           *clone            = GIMP_CLONE (paint_core);
245
 
  GimpCloneOptions    *options          = GIMP_CLONE_OPTIONS (paint_options);
246
 
  GimpContext         *context          = GIMP_CONTEXT (paint_options);
247
 
  GimpPressureOptions *pressure_options = paint_options->pressure_options;
248
 
  GimpImage           *gimage;
249
 
  GimpImage           *src_gimage = NULL;
250
 
  guchar              *s;
251
 
  guchar              *d;
252
 
  TempBuf             *area;
253
 
  gpointer             pr = NULL;
254
 
  gint                 y;
255
 
  gint                 x1, y1, x2, y2;
256
 
  gint                 has_alpha = -1;
257
 
  PixelRegion          srcPR, destPR;
258
 
  GimpPattern         *pattern = NULL;
259
 
  gdouble              opacity;
260
 
  gint                 offset_x;
261
 
  gint                 offset_y;
262
 
 
263
 
  gimage = gimp_item_get_image (GIMP_ITEM (drawable));
264
 
 
265
 
  opacity = gimp_paint_options_get_fade (paint_options, gimage,
266
 
                                         paint_core->pixel_dist);
267
 
  if (opacity == 0.0)
268
 
    return;
269
 
 
270
 
  /*  make local copies because we change them  */
271
 
  offset_x = clone->offset_x;
272
 
  offset_y = clone->offset_y;
273
 
 
274
 
  /*  Make sure we still have a source if we are doing image cloning */
275
 
  if (options->clone_type == GIMP_IMAGE_CLONE)
276
 
    {
277
 
      if (! clone->src_drawable)
278
 
        return;
279
 
 
280
 
      if (! (src_gimage = gimp_item_get_image (GIMP_ITEM (clone->src_drawable))))
281
 
        return;
282
 
 
283
 
      /*  Determine whether the source image has an alpha channel  */
284
 
      has_alpha = gimp_drawable_has_alpha (clone->src_drawable);
285
 
    }
286
 
 
287
 
  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
288
 
  if (! area)
289
 
    return;
 
164
  GimpPaintCore     *paint_core     = GIMP_PAINT_CORE (source_core);
 
165
  GimpCloneOptions  *options        = GIMP_CLONE_OPTIONS (paint_options);
 
166
  GimpSourceOptions *source_options = GIMP_SOURCE_OPTIONS (paint_options);
 
167
  GimpContext       *context        = GIMP_CONTEXT (paint_options);
 
168
  GimpImage         *src_image      = NULL;
 
169
  GimpImageType      src_type       = 0;
 
170
  GimpImageType      dest_type;
 
171
  GimpImage         *image;
 
172
  gpointer           pr = NULL;
 
173
  gint               y;
 
174
  PixelRegion        destPR;
 
175
  GimpPattern       *pattern = NULL;
 
176
 
 
177
  image = gimp_item_get_image (GIMP_ITEM (drawable));
290
178
 
291
179
  switch (options->clone_type)
292
180
    {
293
181
    case GIMP_IMAGE_CLONE:
294
 
      /*  Set the paint area to transparent  */
295
 
      temp_buf_data_clear (area);
296
 
 
297
 
      x1 = CLAMP (area->x + offset_x,
298
 
                  0, gimp_item_width  (GIMP_ITEM (clone->src_drawable)));
299
 
      y1 = CLAMP (area->y + offset_y,
300
 
                  0, gimp_item_height (GIMP_ITEM (clone->src_drawable)));
301
 
      x2 = CLAMP (area->x + offset_x + area->width,
302
 
                  0, gimp_item_width  (GIMP_ITEM (clone->src_drawable)));
303
 
      y2 = CLAMP (area->y + offset_y + area->height,
304
 
                  0, gimp_item_height (GIMP_ITEM (clone->src_drawable)));
305
 
 
306
 
      if (!(x2 - x1) || !(y2 - y1))
307
 
        return;
308
 
 
309
 
      /*  If the source gimage is different from the destination,
310
 
       *  then we should copy straight from the destination image
311
 
       *  to the canvas.
312
 
       *  Otherwise, we need a call to get_orig_image to make sure
313
 
       *  we get a copy of the unblemished (offset) image
314
 
       */
315
 
      if (clone->src_drawable != drawable)
316
 
        {
317
 
          pixel_region_init (&srcPR, gimp_drawable_data (clone->src_drawable),
318
 
                             x1, y1, (x2 - x1), (y2 - y1), FALSE);
319
 
        }
320
 
      else
321
 
        {
322
 
          TempBuf *orig;
323
 
 
324
 
          /*  get the original image  */
325
 
          orig = gimp_paint_core_get_orig_image (paint_core, clone->src_drawable,
326
 
                                                 x1, y1, x2, y2);
327
 
 
328
 
          srcPR.bytes     = orig->bytes;
329
 
          srcPR.x         = 0;
330
 
          srcPR.y         = 0;
331
 
          srcPR.w         = x2 - x1;
332
 
          srcPR.h         = y2 - y1;
333
 
          srcPR.rowstride = srcPR.bytes * orig->width;
334
 
          srcPR.data      = temp_buf_data (orig);
335
 
        }
336
 
 
337
 
      offset_x = x1 - (area->x + offset_x);
338
 
      offset_y = y1 - (area->y + offset_y);
339
 
 
340
 
      /*  configure the destination  */
341
 
      destPR.bytes     = area->bytes;
342
 
      destPR.x         = 0;
343
 
      destPR.y         = 0;
344
 
      destPR.w         = srcPR.w;
345
 
      destPR.h         = srcPR.h;
346
 
      destPR.rowstride = destPR.bytes * area->width;
347
 
      destPR.data      = (temp_buf_data (area) +
348
 
                          offset_y * destPR.rowstride +
349
 
                          offset_x * destPR.bytes);
350
 
 
351
 
      pr = pixel_regions_register (2, &srcPR, &destPR);
 
182
      src_image = gimp_pickable_get_image (src_pickable);
 
183
 
 
184
      src_type = gimp_pickable_get_image_type (src_pickable);
 
185
 
 
186
      if (gimp_pickable_get_bytes (src_pickable) < srcPR->bytes)
 
187
        src_type = GIMP_IMAGE_TYPE_WITH_ALPHA (src_type);
 
188
 
 
189
      pixel_region_init_temp_buf (&destPR, paint_area,
 
190
                                  paint_area_offset_x, paint_area_offset_y,
 
191
                                  paint_area_width, paint_area_height);
 
192
 
 
193
      pr = pixel_regions_register (2, srcPR, &destPR);
352
194
      break;
353
195
 
354
196
    case GIMP_PATTERN_CLONE:
355
197
      pattern = gimp_context_get_pattern (context);
356
198
 
357
 
      if (!pattern)
358
 
        return;
359
 
 
360
 
      /*  configure the destination  */
361
 
      destPR.bytes     = area->bytes;
362
 
      destPR.x         = 0;
363
 
      destPR.y         = 0;
364
 
      destPR.w         = area->width;
365
 
      destPR.h         = area->height;
366
 
      destPR.rowstride = destPR.bytes * area->width;
367
 
      destPR.data      = temp_buf_data (area);
 
199
      pixel_region_init_temp_buf (&destPR, paint_area,
 
200
                                  0, 0,
 
201
                                  paint_area->width, paint_area->height);
368
202
 
369
203
      pr = pixel_regions_register (1, &destPR);
370
204
      break;
371
205
    }
372
206
 
 
207
  dest_type = gimp_drawable_type (drawable);
 
208
 
373
209
  for (; pr != NULL; pr = pixel_regions_process (pr))
374
210
    {
375
 
      s = srcPR.data;
376
 
      d = destPR.data;
 
211
      guchar *s = srcPR->data;
 
212
      guchar *d = destPR.data;
377
213
 
378
214
      for (y = 0; y < destPR.h; y++)
379
215
        {
380
216
          switch (options->clone_type)
381
217
            {
382
218
            case GIMP_IMAGE_CLONE:
383
 
              gimp_clone_line_image (gimage, src_gimage,
384
 
                                     drawable, clone->src_drawable,
385
 
                                     s, d, has_alpha,
386
 
                                     srcPR.bytes, destPR.bytes, destPR.w);
387
 
              s += srcPR.rowstride;
 
219
              gimp_clone_line_image (image, dest_type,
 
220
                                     src_image, src_type,
 
221
                                     s, d,
 
222
                                     srcPR->bytes, destPR.bytes, destPR.w);
 
223
              s += srcPR->rowstride;
388
224
              break;
389
225
 
390
226
            case GIMP_PATTERN_CLONE:
391
 
              gimp_clone_line_pattern (gimage, drawable,
 
227
              gimp_clone_line_pattern (image, dest_type,
392
228
                                       pattern, d,
393
 
                                       area->x + offset_x,
394
 
                                       area->y + y + offset_y,
 
229
                                       paint_area->x     + src_offset_x,
 
230
                                       paint_area->y + y + src_offset_y,
395
231
                                       destPR.bytes, destPR.w);
396
232
              break;
397
233
            }
400
236
        }
401
237
    }
402
238
 
403
 
  if (pressure_options->opacity)
 
239
  if (paint_options->pressure_options->opacity)
404
240
    opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure;
405
241
 
406
242
  gimp_brush_core_paste_canvas (GIMP_BRUSH_CORE (paint_core), drawable,
408
244
                                gimp_context_get_opacity (context),
409
245
                                gimp_context_get_paint_mode (context),
410
246
                                gimp_paint_options_get_brush_mode (paint_options),
411
 
                                GIMP_PAINT_CONSTANT);
 
247
 
 
248
                                /* In fixed mode, paint incremental so the
 
249
                                 * individual brushes are properly applied
 
250
                                 * on top of each other.
 
251
                                 * Otherwise the stuff we paint is seamless
 
252
                                 * and we don't need intermediate masking.
 
253
                                 */
 
254
                                source_options->align_mode ==
 
255
                                GIMP_SOURCE_ALIGN_FIXED ?
 
256
                                GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT);
412
257
}
413
258
 
414
259
static void
415
 
gimp_clone_line_image (GimpImage    *dest,
416
 
                       GimpImage    *src,
417
 
                       GimpDrawable *d_drawable,
418
 
                       GimpDrawable *s_drawable,
419
 
                       guchar       *s,
420
 
                       guchar       *d,
421
 
                       gint          has_alpha,
422
 
                       gint          src_bytes,
423
 
                       gint          dest_bytes,
424
 
                       gint          width)
 
260
gimp_clone_line_image (GimpImage     *dest_image,
 
261
                       GimpImageType  dest_type,
 
262
                       GimpImage     *src_image,
 
263
                       GimpImageType  src_type,
 
264
                       guchar        *s,
 
265
                       guchar        *d,
 
266
                       gint           src_bytes,
 
267
                       gint           dest_bytes,
 
268
                       gint           width)
425
269
{
426
270
  guchar rgba[MAX_CHANNELS];
427
271
  gint   alpha;
430
274
 
431
275
  while (width--)
432
276
    {
433
 
      gimp_image_get_color (src, gimp_drawable_type (s_drawable), s, rgba);
434
 
      gimp_image_transform_color (dest, d_drawable, d, GIMP_RGB, rgba);
 
277
      gimp_image_get_color (src_image, src_type, s, rgba);
 
278
      gimp_image_transform_color (dest_image, dest_type, d,
 
279
                                  GIMP_RGB, rgba);
435
280
 
436
281
      d[alpha] = rgba[ALPHA_PIX];
437
282
 
441
286
}
442
287
 
443
288
static void
444
 
gimp_clone_line_pattern (GimpImage    *dest,
445
 
                         GimpDrawable *drawable,
446
 
                         GimpPattern  *pattern,
447
 
                         guchar       *d,
448
 
                         gint          x,
449
 
                         gint          y,
450
 
                         gint          bytes,
451
 
                         gint          width)
 
289
gimp_clone_line_pattern (GimpImage     *dest_image,
 
290
                         GimpImageType  dest_type,
 
291
                         GimpPattern   *pattern,
 
292
                         guchar        *d,
 
293
                         gint           x,
 
294
                         gint           y,
 
295
                         gint           dest_bytes,
 
296
                         gint           width)
452
297
{
453
298
  guchar            *pat, *p;
454
299
  GimpImageBaseType  color_type;
471
316
  color_type = (pat_bytes == 3 ||
472
317
                pat_bytes == 4) ? GIMP_RGB : GIMP_GRAY;
473
318
 
474
 
  alpha = bytes - 1;
 
319
  alpha = dest_bytes - 1;
475
320
 
476
321
  for (i = 0; i < width; i++)
477
322
    {
478
323
      p = pat + ((i + x) % pattern->mask->width) * pat_bytes;
479
324
 
480
 
      gimp_image_transform_color (dest, drawable, d, color_type, p);
 
325
      gimp_image_transform_color (dest_image, dest_type, d,
 
326
                                  color_type, p);
481
327
 
482
328
      if (pat_bytes == 2 || pat_bytes == 4)
483
329
        d[alpha] = p[pat_bytes - 1];
484
330
      else
485
331
        d[alpha] = OPAQUE_OPACITY;
486
332
 
487
 
      d += bytes;
488
 
    }
489
 
}
490
 
 
491
 
static void
492
 
gimp_clone_src_drawable_disconnect_cb (GimpDrawable *drawable,
493
 
                                       GimpClone    *clone)
494
 
{
495
 
  if (drawable == clone->src_drawable)
496
 
    {
497
 
      clone->src_drawable = NULL;
498
 
    }
499
 
}
500
 
 
501
 
static void
502
 
gimp_clone_set_src_drawable (GimpClone    *clone,
503
 
                             GimpDrawable *drawable)
504
 
{
505
 
  if (clone->src_drawable == drawable)
506
 
    return;
507
 
 
508
 
  if (clone->src_drawable)
509
 
    g_signal_handlers_disconnect_by_func (clone->src_drawable,
510
 
                                          gimp_clone_src_drawable_disconnect_cb,
511
 
                                          clone);
512
 
 
513
 
  clone->src_drawable = drawable;
514
 
 
515
 
  if (clone->src_drawable)
516
 
    {
517
 
      g_signal_connect (clone->src_drawable, "disconnect",
518
 
                        G_CALLBACK (gimp_clone_src_drawable_disconnect_cb),
519
 
                        clone);
 
333
      d += dest_bytes;
520
334
    }
521
335
}