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

« back to all changes in this revision

Viewing changes to app/core/gimpdrawable-blend.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

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
24
24
#include <glib-object.h>
25
25
 
26
26
#include "libgimpbase/gimpbase.h"
 
27
#include "libgimpmath/gimpmath.h"
27
28
#include "libgimpcolor/gimpcolor.h"
28
29
 
29
30
#include "core-types.h"
30
31
 
 
32
#include "base/pixel-processor.h"
31
33
#include "base/pixel-region.h"
32
34
#include "base/tile.h"
33
35
#include "base/tile-manager.h"
48
50
typedef struct
49
51
{
50
52
  GimpGradient     *gradient;
 
53
  GimpContext      *context;
51
54
  gboolean          reverse;
52
55
  gdouble           offset;
53
56
  gdouble           sx, sy;
57
60
  gdouble           dist;
58
61
  gdouble           vec[2];
59
62
  GimpRepeatMode    repeat;
 
63
  GRand            *seed;
60
64
} RenderBlendData;
61
65
 
62
66
typedef struct
65
69
  guchar      *row_data;
66
70
  gint         bytes;
67
71
  gint         width;
68
 
  gboolean     dither;
69
72
  GRand       *dither_rand;
70
73
} PutPixelData;
71
74
 
86
89
                                                   gdouble   offset,
87
90
                                                   gdouble   x,
88
91
                                                   gdouble   y);
89
 
static gdouble  gradient_calc_radial_factor       (gdouble   dist,
90
 
                                                   gdouble   offset,
 
92
static gdouble  gradient_calc_radial_factor             (gdouble   dist,
 
93
                                                   gdouble   offset,
91
94
                                                   gdouble   x,
92
 
                                                   gdouble   y);
93
 
static gdouble  gradient_calc_linear_factor       (gdouble   dist,
 
95
                                                   gdouble   y);
 
96
static gdouble  gradient_calc_linear_factor             (gdouble   dist,
94
97
                                                   gdouble  *vec,
95
98
                                                   gdouble   offset,
96
99
                                                   gdouble   x,
97
100
                                                   gdouble   y);
98
 
static gdouble  gradient_calc_bilinear_factor     (gdouble   dist,
 
101
static gdouble  gradient_calc_bilinear_factor           (gdouble   dist,
99
102
                                                   gdouble  *vec,
100
103
                                                   gdouble   offset,
101
104
                                                   gdouble   x,
114
117
static gdouble  gradient_calc_shapeburst_dimpled_factor   (gdouble x,
115
118
                                                           gdouble y);
116
119
 
117
 
static void     gradient_precalc_shapeburst (GimpImage        *gimage,
118
 
                                             GimpDrawable     *drawable,
 
120
static void     gradient_precalc_shapeburst (GimpImage        *image,
 
121
                                             GimpDrawable     *drawable,
119
122
                                             PixelRegion      *PR,
120
123
                                             gdouble           dist,
121
124
                                             GimpProgress     *progress);
122
125
 
123
 
static void     gradient_render_pixel       (gdouble       x,
124
 
                                             gdouble       y,
125
 
                                             GimpRGB      *color,
126
 
                                             gpointer      render_data);
127
 
static void     gradient_put_pixel          (gint          x,
128
 
                                             gint          y,
129
 
                                             GimpRGB      *color,
130
 
                                             gpointer      put_pixel_data);
 
126
static void     gradient_render_pixel       (gdouble           x,
 
127
                                             gdouble           y,
 
128
                                             GimpRGB          *color,
 
129
                                             gpointer          render_data);
 
130
static void     gradient_put_pixel          (gint              x,
 
131
                                             gint              y,
 
132
                                             GimpRGB          *color,
 
133
                                             gpointer          put_pixel_data);
131
134
 
132
 
static void     gradient_fill_region        (GimpImage        *gimage,
 
135
static void     gradient_fill_region        (GimpImage        *image,
133
136
                                             GimpDrawable     *drawable,
134
137
                                             GimpContext      *context,
135
138
                                             PixelRegion      *PR,
150
153
                                             gdouble           ey,
151
154
                                             GimpProgress     *progress);
152
155
 
153
 
 
154
 
/*  variables for the shapeburst algs  */
 
156
static void     gradient_fill_single_region_rgb         (RenderBlendData *rbd,
 
157
                                                         PixelRegion     *PR);
 
158
static void     gradient_fill_single_region_rgb_dither  (RenderBlendData *rbd,
 
159
                                                         PixelRegion     *PR);
 
160
static void     gradient_fill_single_region_gray        (RenderBlendData *rbd,
 
161
                                                         PixelRegion     *PR);
 
162
static void     gradient_fill_single_region_gray_dither (RenderBlendData *rbd,
 
163
                                                         PixelRegion     *PR);
 
164
 
 
165
 
 
166
/*  variables for the shapeburst algorithms  */
155
167
 
156
168
static PixelRegion distR =
157
169
{
190
202
                     gdouble               endy,
191
203
                     GimpProgress         *progress)
192
204
{
193
 
  GimpImage   *gimage;
 
205
  GimpImage   *image;
194
206
  TileManager *buf_tiles;
195
207
  PixelRegion  bufPR;
196
208
  gint         bytes;
201
213
  g_return_if_fail (GIMP_IS_CONTEXT (context));
202
214
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
203
215
 
204
 
  gimage = gimp_item_get_image (GIMP_ITEM (drawable));
 
216
  image = gimp_item_get_image (GIMP_ITEM (drawable));
205
217
 
206
218
  if (! gimp_drawable_mask_intersect (drawable, &x, &y, &width, &height))
207
219
    return;
208
220
 
209
 
  gimp_set_busy (gimage->gimp);
210
 
 
211
 
  bytes = gimp_drawable_bytes (drawable);
 
221
  gimp_set_busy (image->gimp);
212
222
 
213
223
  /*  Always create an alpha temp buf (for generality) */
214
 
  if (! gimp_drawable_has_alpha (drawable))
215
 
    {
216
 
      bytes += 1;
217
 
    }
 
224
  bytes = gimp_drawable_bytes_with_alpha (drawable);
218
225
 
219
226
  buf_tiles = tile_manager_new (width, height, bytes);
220
227
  pixel_region_init (&bufPR, buf_tiles, 0, 0, width, height, TRUE);
221
228
 
222
 
  gradient_fill_region (gimage, drawable, context,
223
 
                        &bufPR, width, height,
224
 
                        blend_mode, gradient_type, offset, repeat, reverse,
225
 
                        supersample, max_depth, threshold, dither,
226
 
                        (startx - x), (starty - y),
227
 
                        (endx - x), (endy - y),
228
 
                        progress);
 
229
  gradient_fill_region (image, drawable, context,
 
230
                        &bufPR, width, height,
 
231
                        blend_mode, gradient_type, offset, repeat, reverse,
 
232
                        supersample, max_depth, threshold, dither,
 
233
                        (startx - x), (starty - y),
 
234
                        (endx - x), (endy - y),
 
235
                        progress);
229
236
 
230
237
  if (distR.tiles)
231
238
    {
245
252
  /*  free the temporary buffer  */
246
253
  tile_manager_unref (buf_tiles);
247
254
 
248
 
  gimp_unset_busy (gimage->gimp);
 
255
  gimp_unset_busy (image->gimp);
249
256
}
250
257
 
251
258
static gdouble
252
259
gradient_calc_conical_sym_factor (gdouble  dist,
253
 
                                  gdouble *axis,
254
 
                                  gdouble  offset,
255
 
                                  gdouble  x,
256
 
                                  gdouble  y)
 
260
                                  gdouble *axis,
 
261
                                  gdouble  offset,
 
262
                                  gdouble  x,
 
263
                                  gdouble  y)
257
264
{
258
 
  gdouble vec[2];
259
 
  gdouble r;
260
 
  gdouble rat;
261
 
 
262
265
  if (dist == 0.0)
263
266
    {
264
 
      rat = 0.0;
 
267
      return 0.0;
265
268
    }
266
269
  else if ((x != 0) || (y != 0))
267
270
    {
 
271
      gdouble vec[2];
 
272
      gdouble r;
 
273
      gdouble rat;
 
274
 
268
275
      /* Calculate offset from the start in pixels */
269
276
 
270
 
      r = sqrt (x * x + y * y);
 
277
      r = sqrt (SQR (x) + SQR (y));
271
278
 
272
279
      vec[0] = x / r;
273
280
      vec[1] = y / r;
275
282
      rat = axis[0] * vec[0] + axis[1] * vec[1]; /* Dot product */
276
283
 
277
284
      if (rat > 1.0)
278
 
        rat = 1.0;
 
285
        rat = 1.0;
279
286
      else if (rat < -1.0)
280
 
        rat = -1.0;
 
287
        rat = -1.0;
281
288
 
282
289
      /* This cool idea is courtesy Josh MacDonald,
283
290
       * Ali Rahimi --- two more XCF losers.  */
285
292
      rat = acos (rat) / G_PI;
286
293
      rat = pow (rat, (offset / 10.0) + 1.0);
287
294
 
288
 
      rat = CLAMP (rat, 0.0, 1.0);
 
295
      return CLAMP (rat, 0.0, 1.0);
289
296
    }
290
297
  else
291
298
    {
292
 
      rat = 0.5;
 
299
      return 0.5;
293
300
    }
294
 
 
295
 
  return rat;
296
301
}
297
302
 
298
303
static gdouble
299
304
gradient_calc_conical_asym_factor (gdouble  dist,
300
 
                                   gdouble *axis,
301
 
                                   gdouble  offset,
302
 
                                   gdouble  x,
303
 
                                   gdouble  y)
 
305
                                   gdouble *axis,
 
306
                                   gdouble  offset,
 
307
                                   gdouble  x,
 
308
                                   gdouble  y)
304
309
{
305
 
  gdouble ang0, ang1;
306
 
  gdouble ang;
307
 
  gdouble rat;
308
 
 
309
310
  if (dist == 0.0)
310
311
    {
311
 
      rat = 0.0;
 
312
      return 0.0;
 
313
    }
 
314
  else if (x != 0 || y != 0)
 
315
    {
 
316
      gdouble ang0, ang1;
 
317
      gdouble ang;
 
318
      gdouble rat;
 
319
 
 
320
      ang0 = atan2 (axis[0], axis[1]) + G_PI;
 
321
 
 
322
      ang1 = atan2 (x, y) + G_PI;
 
323
 
 
324
      ang = ang1 - ang0;
 
325
 
 
326
      if (ang < 0.0)
 
327
        ang += (2.0 * G_PI);
 
328
 
 
329
      rat = ang / (2.0 * G_PI);
 
330
      rat = pow (rat, (offset / 10.0) + 1.0);
 
331
 
 
332
      return CLAMP (rat, 0.0, 1.0);
312
333
    }
313
334
  else
314
335
    {
315
 
      if ((x != 0) || (y != 0))
316
 
        {
317
 
          ang0 = atan2 (axis[0], axis[1]) + G_PI;
318
 
          ang1 = atan2 (x, y) + G_PI;
319
 
 
320
 
          ang = ang1 - ang0;
321
 
 
322
 
          if (ang < 0.0)
323
 
            ang += (2.0 * G_PI);
324
 
 
325
 
          rat = ang / (2.0 * G_PI);
326
 
          rat = pow (rat, (offset / 10.0) + 1.0);
327
 
 
328
 
          rat = CLAMP (rat, 0.0, 1.0);
329
 
        }
330
 
      else
331
 
        {
332
 
          rat = 0.5; /* We are on middle point */
333
 
        }
 
336
      return 0.5; /* We are on middle point */
334
337
    }
335
 
 
336
 
  return rat;
337
338
}
338
339
 
339
340
static gdouble
340
341
gradient_calc_square_factor (gdouble dist,
341
 
                             gdouble offset,
342
 
                             gdouble x,
343
 
                             gdouble y)
 
342
                             gdouble offset,
 
343
                             gdouble x,
 
344
                             gdouble y)
344
345
{
345
 
  gdouble r;
346
 
  gdouble rat;
347
 
 
348
346
  if (dist == 0.0)
349
347
    {
350
 
      rat = 0.0;
 
348
      return 0.0;
351
349
    }
352
350
  else
353
351
    {
 
352
      gdouble r;
 
353
      gdouble rat;
 
354
 
354
355
      /* Calculate offset from start as a value in [0, 1] */
355
356
 
356
357
      offset = offset / 100.0;
359
360
      rat = r / dist;
360
361
 
361
362
      if (rat < offset)
362
 
        rat = 0.0;
 
363
        return 0.0;
363
364
      else if (offset == 1.0)
364
 
        rat = (rat >= 1.0) ? 1.0 : 0.0;
 
365
        return (rat >= 1.0) ? 1.0 : 0.0;
365
366
      else
366
 
        rat = (rat - offset) / (1.0 - offset);
 
367
        return (rat - offset) / (1.0 - offset);
367
368
    }
368
 
 
369
 
  return rat;
370
369
}
371
370
 
372
371
static gdouble
373
372
gradient_calc_radial_factor (gdouble dist,
374
 
                             gdouble offset,
375
 
                             gdouble x,
376
 
                             gdouble y)
 
373
                             gdouble offset,
 
374
                             gdouble x,
 
375
                             gdouble y)
377
376
{
378
 
  gdouble r;
379
 
  gdouble rat;
380
 
 
381
377
  if (dist == 0.0)
382
378
    {
383
 
      rat = 0.0;
 
379
      return 0.0;
384
380
    }
385
381
  else
386
382
    {
 
383
      gdouble r;
 
384
      gdouble rat;
 
385
 
387
386
      /* Calculate radial offset from start as a value in [0, 1] */
388
387
 
389
388
      offset = offset / 100.0;
392
391
      rat = r / dist;
393
392
 
394
393
      if (rat < offset)
395
 
        rat = 0.0;
 
394
        return 0.0;
396
395
      else if (offset == 1.0)
397
 
        rat = (rat >= 1.0) ? 1.0 : 0.0;
 
396
        return (rat >= 1.0) ? 1.0 : 0.0;
398
397
      else
399
 
        rat = (rat - offset) / (1.0 - offset);
 
398
        return (rat - offset) / (1.0 - offset);
400
399
    }
401
 
 
402
 
  return rat;
403
400
}
404
401
 
405
402
static gdouble
406
403
gradient_calc_linear_factor (gdouble  dist,
407
 
                             gdouble *vec,
408
 
                             gdouble  offset,
409
 
                             gdouble  x,
410
 
                             gdouble  y)
 
404
                             gdouble *vec,
 
405
                             gdouble  offset,
 
406
                             gdouble  x,
 
407
                             gdouble  y)
411
408
{
412
 
  gdouble r;
413
 
  gdouble rat;
414
 
 
415
409
  if (dist == 0.0)
416
410
    {
417
 
      rat = 0.0;
 
411
      return 0.0;
418
412
    }
419
413
  else
420
414
    {
 
415
      gdouble r;
 
416
      gdouble rat;
 
417
 
421
418
      offset = offset / 100.0;
422
419
 
423
420
      r   = vec[0] * x + vec[1] * y;
424
421
      rat = r / dist;
425
422
 
426
423
      if (rat >= 0.0 && rat < offset)
427
 
        rat = 0.0;
 
424
        return 0.0;
428
425
      else if (offset == 1.0)
429
 
        rat = (rat >= 1.0) ? 1.0 : 0.0;
 
426
        return (rat >= 1.0) ? 1.0 : 0.0;
430
427
      else if (rat < 0.0)
431
 
        rat = rat / (1.0 - offset);
 
428
        return rat / (1.0 - offset);
432
429
      else
433
 
        rat = (rat - offset) / (1.0 - offset);
 
430
        return (rat - offset) / (1.0 - offset);
434
431
    }
435
 
 
436
 
  return rat;
437
432
}
438
433
 
439
434
static gdouble
440
435
gradient_calc_bilinear_factor (gdouble  dist,
441
 
                               gdouble *vec,
442
 
                               gdouble  offset,
443
 
                               gdouble  x,
444
 
                               gdouble  y)
 
436
                               gdouble *vec,
 
437
                               gdouble  offset,
 
438
                               gdouble  x,
 
439
                               gdouble  y)
445
440
{
446
 
  gdouble r;
447
 
  gdouble rat;
448
 
 
449
441
  if (dist == 0.0)
450
442
    {
451
 
      rat = 0.0;
 
443
      return 0.0;
452
444
    }
453
445
  else
454
446
    {
 
447
      gdouble r;
 
448
      gdouble rat;
 
449
 
455
450
      /* Calculate linear offset from the start line outward */
456
451
 
457
452
      offset = offset / 100.0;
460
455
      rat = r / dist;
461
456
 
462
457
      if (fabs (rat) < offset)
463
 
        rat = 0.0;
 
458
        return 0.0;
464
459
      else if (offset == 1.0)
465
 
        rat = (rat == 1.0) ? 1.0 : 0.0;
 
460
        return (rat == 1.0) ? 1.0 : 0.0;
466
461
      else
467
 
        rat = (fabs (rat) - offset) / (1.0 - offset);
 
462
        return (fabs (rat) - offset) / (1.0 - offset);
468
463
    }
469
 
 
470
 
  return rat;
471
464
}
472
465
 
473
466
static gdouble
474
467
gradient_calc_spiral_factor (gdouble   dist,
475
 
                             gdouble  *axis,
476
 
                             gdouble   offset,
477
 
                             gdouble   x,
478
 
                             gdouble   y,
479
 
                             gboolean  clockwise)
 
468
                             gdouble  *axis,
 
469
                             gdouble   offset,
 
470
                             gdouble   x,
 
471
                             gdouble   y,
 
472
                             gboolean  clockwise)
480
473
{
481
 
  gdouble ang0, ang1;
482
 
  gdouble ang, r;
483
 
  gdouble rat;
484
 
 
485
474
  if (dist == 0.0)
486
475
    {
487
 
      rat = 0.0;
 
476
      return 0.0;
 
477
    }
 
478
  else if (x != 0.0 || y != 0.0)
 
479
    {
 
480
      gdouble ang0, ang1;
 
481
      gdouble ang;
 
482
      double  r;
 
483
 
 
484
      ang0 = atan2 (axis[0], axis[1]) + G_PI;
 
485
      ang1 = atan2 (x, y) + G_PI;
 
486
 
 
487
      if (clockwise)
 
488
        ang = ang1 - ang0;
 
489
      else
 
490
        ang = ang0 - ang1;
 
491
 
 
492
      if (ang < 0.0)
 
493
        ang += (2.0 * G_PI);
 
494
 
 
495
      r = sqrt (SQR (x) + SQR (y)) / dist;
 
496
 
 
497
      return fmod (ang / (2.0 * G_PI) + r + offset, 1.0);
488
498
    }
489
499
  else
490
500
    {
491
 
      if (x != 0.0 || y != 0.0)
492
 
        {
493
 
          ang0 = atan2 (axis[0], axis[1]) + G_PI;
494
 
          ang1 = atan2 (x, y) + G_PI;
495
 
 
496
 
          if (clockwise)
497
 
            ang = ang1 - ang0;
498
 
          else
499
 
            ang = ang0 - ang1;
500
 
 
501
 
          if (ang < 0.0)
502
 
            ang += (2.0 * G_PI);
503
 
 
504
 
          r = sqrt (x * x + y * y) / dist;
505
 
          rat = ang / (2.0 * G_PI) + r + offset;
506
 
          rat = fmod (rat, 1.0);
507
 
        }
508
 
      else
509
 
        rat = 0.5 ; /* We are on the middle point */
 
501
      return 0.5 ; /* We are on the middle point */
510
502
    }
511
 
 
512
 
  return rat;
513
503
}
514
504
 
515
505
static gdouble
516
506
gradient_calc_shapeburst_angular_factor (gdouble x,
517
 
                                         gdouble y)
 
507
                                         gdouble y)
518
508
{
519
 
  gint    ix, iy;
520
509
  Tile   *tile;
521
510
  gfloat  value;
 
511
  gint    ix = CLAMP (x, 0.0, distR.w - 0.7);
 
512
  gint    iy = CLAMP (y, 0.0, distR.h - 0.7);
522
513
 
523
 
  ix = (gint) CLAMP (x, 0.0, distR.w - 0.7);
524
 
  iy = (gint) CLAMP (y, 0.0, distR.h - 0.7);
525
514
  tile = tile_manager_get_tile (distR.tiles, ix, iy, TRUE, FALSE);
 
515
 
526
516
  value = 1.0 - *((gfloat *) tile_data_pointer (tile,
527
517
                                                ix % TILE_WIDTH,
528
518
                                                iy % TILE_HEIGHT));
 
519
 
529
520
  tile_release (tile, FALSE);
530
521
 
531
522
  return value;
534
525
 
535
526
static gdouble
536
527
gradient_calc_shapeburst_spherical_factor (gdouble x,
537
 
                                           gdouble y)
 
528
                                           gdouble y)
538
529
{
539
 
  gint    ix, iy;
540
530
  Tile   *tile;
541
531
  gfloat  value;
 
532
  gint    ix = CLAMP (x, 0.0, distR.w - 0.7);
 
533
  gint    iy = CLAMP (y, 0.0, distR.h - 0.7);
542
534
 
543
 
  ix = (gint) CLAMP (x, 0.0, distR.w - 0.7);
544
 
  iy = (gint) CLAMP (y, 0.0, distR.h - 0.7);
545
535
  tile = tile_manager_get_tile (distR.tiles, ix, iy, TRUE, FALSE);
 
536
 
546
537
  value = *((gfloat *) tile_data_pointer (tile,
547
538
                                          ix % TILE_WIDTH,
548
539
                                          iy % TILE_HEIGHT));
549
540
  value = 1.0 - sin (0.5 * G_PI * value);
 
541
 
550
542
  tile_release (tile, FALSE);
551
543
 
552
544
  return value;
555
547
 
556
548
static gdouble
557
549
gradient_calc_shapeburst_dimpled_factor (gdouble x,
558
 
                                         gdouble y)
 
550
                                         gdouble y)
559
551
{
560
 
  gint    ix, iy;
561
552
  Tile   *tile;
562
553
  gfloat  value;
 
554
  gint    ix = CLAMP (x, 0.0, distR.w - 0.7);
 
555
  gint    iy = CLAMP (y, 0.0, distR.h - 0.7);
563
556
 
564
 
  ix = (gint) CLAMP (x, 0.0, distR.w - 0.7);
565
 
  iy = (gint) CLAMP (y, 0.0, distR.h - 0.7);
566
557
  tile = tile_manager_get_tile (distR.tiles, ix, iy, TRUE, FALSE);
 
558
 
567
559
  value = *((gfloat *) tile_data_pointer (tile,
568
560
                                          ix % TILE_WIDTH,
569
561
                                          iy % TILE_HEIGHT));
570
562
  value = cos (0.5 * G_PI * value);
 
563
 
571
564
  tile_release (tile, FALSE);
572
565
 
573
566
  return value;
574
567
}
575
568
 
576
569
static void
577
 
gradient_precalc_shapeburst (GimpImage    *gimage,
578
 
                             GimpDrawable *drawable,
579
 
                             PixelRegion  *PR,
580
 
                             gdouble       dist,
 
570
gradient_precalc_shapeburst (GimpImage    *image,
 
571
                             GimpDrawable *drawable,
 
572
                             PixelRegion  *PR,
 
573
                             gdouble       dist,
581
574
                             GimpProgress *progress)
582
575
{
583
576
  GimpChannel *mask;
595
588
  tempR.tiles = tile_manager_new (PR->w, PR->h, 1);
596
589
  pixel_region_init (&tempR, tempR.tiles, 0, 0, PR->w, PR->h, TRUE);
597
590
 
598
 
  mask = gimp_image_get_mask (gimage);
 
591
  mask = gimp_image_get_mask (image);
599
592
 
600
 
  /*  If the gimage mask is not empty, use it as the shape burst source  */
 
593
  /*  If the image mask is not empty, use it as the shape burst source  */
601
594
  if (! gimp_channel_is_empty (mask))
602
595
    {
603
596
      PixelRegion maskR;
607
600
      gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
608
601
      gimp_item_offsets (GIMP_ITEM (drawable), &offx, &offy);
609
602
 
610
 
      pixel_region_init (&maskR, gimp_drawable_data (GIMP_DRAWABLE (mask)),
611
 
                         x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
 
603
      pixel_region_init (&maskR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
 
604
                         x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
612
605
 
613
606
      /*  copy the mask to the temp mask  */
614
607
      copy_region (&maskR, &tempR);
615
608
    }
616
 
  /*  otherwise...  */
617
609
  else
618
610
    {
619
611
      /*  If the intended drawable has an alpha channel, use that  */
620
612
      if (gimp_drawable_has_alpha (drawable))
621
 
        {
622
 
          PixelRegion drawableR;
623
 
 
624
 
          pixel_region_init (&drawableR, gimp_drawable_data (drawable),
625
 
                             PR->x, PR->y, PR->w, PR->h, FALSE);
626
 
 
627
 
          extract_alpha_region (&drawableR, NULL, &tempR);
628
 
        }
 
613
        {
 
614
          PixelRegion drawableR;
 
615
 
 
616
          pixel_region_init (&drawableR, gimp_drawable_get_tiles (drawable),
 
617
                             PR->x, PR->y, PR->w, PR->h, FALSE);
 
618
 
 
619
          extract_alpha_region (&drawableR, NULL, &tempR);
 
620
        }
629
621
      else
630
 
        {
631
 
          /*  Otherwise, just fill the shapeburst to white  */
632
 
          color_region (&tempR, white);
633
 
        }
 
622
        {
 
623
          /*  Otherwise, just fill the shapeburst to white  */
 
624
          color_region (&tempR, white);
 
625
        }
634
626
    }
635
627
 
636
628
  pixel_region_init (&tempR, tempR.tiles, 0, 0, PR->w, PR->h, TRUE);
646
638
      pixel_region_init (&distR, distR.tiles, 0, 0, PR->w, PR->h, TRUE);
647
639
 
648
640
      for (pr = pixel_regions_register (1, &distR);
649
 
           pr != NULL;
650
 
           pr = pixel_regions_process (pr))
651
 
        {
652
 
          distp = (gfloat *) distR.data;
653
 
          size  = distR.w * distR.h;
 
641
           pr != NULL;
 
642
           pr = pixel_regions_process (pr))
 
643
        {
 
644
          distp = (gfloat *) distR.data;
 
645
          size  = distR.w * distR.h;
654
646
 
655
 
          while (size--)
656
 
            *distp++ /= max_iteration;
657
 
        }
 
647
          while (size--)
 
648
            *distp++ /= max_iteration;
 
649
        }
658
650
 
659
651
      pixel_region_init (&distR, distR.tiles, 0, 0, PR->w, PR->h, FALSE);
660
652
    }
664
656
 
665
657
 
666
658
static void
667
 
gradient_render_pixel (double    x,
668
 
                       double    y,
669
 
                       GimpRGB  *color,
670
 
                       gpointer  render_data)
 
659
gradient_render_pixel (gdouble   x,
 
660
                       gdouble   y,
 
661
                       GimpRGB  *color,
 
662
                       gpointer  render_data)
671
663
{
672
664
  RenderBlendData *rbd = render_data;
673
665
  gdouble          factor;
677
669
  switch (rbd->gradient_type)
678
670
    {
679
671
    case GIMP_GRADIENT_LINEAR:
680
 
      factor = gradient_calc_linear_factor (rbd->dist, rbd->vec, rbd->offset,
681
 
                                            x - rbd->sx, y - rbd->sy);
 
672
      factor = gradient_calc_linear_factor (rbd->dist,
 
673
                                            rbd->vec, rbd->offset,
 
674
                                            x - rbd->sx, y - rbd->sy);
682
675
      break;
683
676
 
684
677
    case GIMP_GRADIENT_BILINEAR:
685
 
      factor = gradient_calc_bilinear_factor (rbd->dist, rbd->vec, rbd->offset,
686
 
                                              x - rbd->sx, y - rbd->sy);
 
678
      factor = gradient_calc_bilinear_factor (rbd->dist,
 
679
                                              rbd->vec, rbd->offset,
 
680
                                              x - rbd->sx, y - rbd->sy);
687
681
      break;
688
682
 
689
683
    case GIMP_GRADIENT_RADIAL:
690
 
      factor = gradient_calc_radial_factor (rbd->dist, rbd->offset,
691
 
                                            x - rbd->sx, y - rbd->sy);
 
684
      factor = gradient_calc_radial_factor (rbd->dist,
 
685
                                            rbd->offset,
 
686
                                            x - rbd->sx, y - rbd->sy);
692
687
      break;
693
688
 
694
689
    case GIMP_GRADIENT_SQUARE:
695
690
      factor = gradient_calc_square_factor (rbd->dist, rbd->offset,
696
 
                                            x - rbd->sx, y - rbd->sy);
 
691
                                            x - rbd->sx, y - rbd->sy);
697
692
      break;
698
693
 
699
694
    case GIMP_GRADIENT_CONICAL_SYMMETRIC:
700
 
      factor = gradient_calc_conical_sym_factor (rbd->dist, rbd->vec, rbd->offset,
701
 
                                                 x - rbd->sx, y - rbd->sy);
 
695
      factor = gradient_calc_conical_sym_factor (rbd->dist,
 
696
                                                 rbd->vec, rbd->offset,
 
697
                                                 x - rbd->sx, y - rbd->sy);
702
698
      break;
703
699
 
704
700
    case GIMP_GRADIENT_CONICAL_ASYMMETRIC:
705
 
      factor = gradient_calc_conical_asym_factor (rbd->dist, rbd->vec, rbd->offset,
706
 
                                                  x - rbd->sx, y - rbd->sy);
 
701
      factor = gradient_calc_conical_asym_factor (rbd->dist,
 
702
                                                  rbd->vec, rbd->offset,
 
703
                                                  x - rbd->sx, y - rbd->sy);
707
704
      break;
708
705
 
709
706
    case GIMP_GRADIENT_SHAPEBURST_ANGULAR:
719
716
      break;
720
717
 
721
718
    case GIMP_GRADIENT_SPIRAL_CLOCKWISE:
722
 
      factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset,
723
 
                                            x - rbd->sx, y - rbd->sy,TRUE);
 
719
      factor = gradient_calc_spiral_factor (rbd->dist,
 
720
                                            rbd->vec, rbd->offset,
 
721
                                            x - rbd->sx, y - rbd->sy, TRUE);
724
722
      break;
725
723
 
726
724
    case GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE:
727
 
      factor = gradient_calc_spiral_factor (rbd->dist, rbd->vec, rbd->offset,
728
 
                                            x - rbd->sx, y - rbd->sy,FALSE);
 
725
      factor = gradient_calc_spiral_factor (rbd->dist,
 
726
                                            rbd->vec, rbd->offset,
 
727
                                            x - rbd->sx, y - rbd->sy, FALSE);
729
728
      break;
730
729
 
731
730
    default:
765
764
 
766
765
  if (rbd->blend_mode == GIMP_CUSTOM_MODE)
767
766
    {
768
 
      gimp_gradient_get_color_at (rbd->gradient, factor, rbd->reverse, color);
 
767
      gimp_gradient_get_color_at (rbd->gradient, rbd->context, NULL,
 
768
                                  factor, rbd->reverse, color);
769
769
    }
770
770
  else
771
771
    {
790
790
 
791
791
static void
792
792
gradient_put_pixel (gint      x,
793
 
                    gint      y,
794
 
                    GimpRGB  *color,
795
 
                    gpointer  put_pixel_data)
 
793
                    gint      y,
 
794
                    GimpRGB  *color,
 
795
                    gpointer  put_pixel_data)
796
796
{
797
 
  PutPixelData  *ppd = put_pixel_data;
798
 
  guchar        *data;
799
 
 
800
 
  /* Paint */
801
 
 
802
 
  data = ppd->row_data + ppd->bytes * x;
 
797
  PutPixelData  *ppd  = put_pixel_data;
 
798
  guchar        *dest = ppd->row_data + ppd->bytes * x;
803
799
 
804
800
  if (ppd->bytes >= 3)
805
801
    {
806
 
      if (ppd->dither)
807
 
        {
808
 
          gdouble dither_prob;
809
 
          gdouble ftmp;
810
 
          gint    itmp;
811
 
 
812
 
          ftmp = color->r * 255.0;
813
 
          itmp = ftmp;
814
 
          dither_prob = ftmp - itmp;
815
 
 
816
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
817
 
            color->r += (1.0 / 255.0);
818
 
 
819
 
          ftmp = color->g * 255.0;
820
 
          itmp = ftmp;
821
 
          dither_prob = ftmp - itmp;
822
 
 
823
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
824
 
            color->g += (1.0 / 255.0);
825
 
 
826
 
          ftmp = color->b * 255.0;
827
 
          itmp = ftmp;
828
 
          dither_prob = ftmp - itmp;
829
 
 
830
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
831
 
            color->b += (1.0 / 255.0);
832
 
 
833
 
          ftmp = color->a * 255.0;
834
 
          itmp = ftmp;
835
 
          dither_prob = ftmp - itmp;
836
 
 
837
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
838
 
            color->a += (1.0 / 255.0);
839
 
 
840
 
          if (color->r > 1.0) color->r = 1.0;
841
 
          if (color->g > 1.0) color->g = 1.0;
842
 
          if (color->b > 1.0) color->b = 1.0;
843
 
          if (color->a > 1.0) color->a = 1.0;
844
 
        }
845
 
 
846
 
      *data++ = color->r * 255.0;
847
 
      *data++ = color->g * 255.0;
848
 
      *data++ = color->b * 255.0;
849
 
      *data++ = color->a * 255.0;
 
802
      if (ppd->dither_rand)
 
803
        {
 
804
          gint i = g_rand_int (ppd->dither_rand);
 
805
 
 
806
          *dest++ = color->r * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
807
          *dest++ = color->g * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
808
          *dest++ = color->b * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
809
          *dest++ = color->a * 255.0 + (gdouble) (i & 0xff) / 256.0;
 
810
        }
 
811
      else
 
812
        {
 
813
          *dest++ = ROUND (color->r * 255.0);
 
814
          *dest++ = ROUND (color->g * 255.0);
 
815
          *dest++ = ROUND (color->b * 255.0);
 
816
          *dest++ = ROUND (color->a * 255.0);
 
817
        }
850
818
    }
851
819
  else
852
820
    {
853
821
      /* Convert to grayscale */
854
 
      gdouble gray = gimp_rgb_intensity (color);
855
 
 
856
 
      if (ppd->dither)
857
 
        {
858
 
          gdouble dither_prob;
859
 
          gdouble ftmp;
860
 
          gint    itmp;
861
 
 
862
 
          ftmp = gray * 255.0;
863
 
          itmp = ftmp;
864
 
          dither_prob = ftmp - itmp;
865
 
 
866
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
867
 
            gray += (1.0 / 255.0);
868
 
 
869
 
          ftmp = color->a * 255.0;
870
 
          itmp = ftmp;
871
 
          dither_prob = ftmp - itmp;
872
 
 
873
 
          if (g_rand_double (ppd->dither_rand) < dither_prob)
874
 
            color->a += (1.0 / 255.0);
875
 
 
876
 
          if (gray > 1.0)     gray     = 1.0;
877
 
          if (color->a > 1.0) color->a = 1.0;
878
 
        }
879
 
 
880
 
      *data++ = gray * 255.0;
881
 
      *data++ = color->a * 255.0;
 
822
      gdouble gray = gimp_rgb_luminance (color);
 
823
 
 
824
      if (ppd->dither_rand)
 
825
        {
 
826
          gint i = g_rand_int (ppd->dither_rand);
 
827
 
 
828
          *dest++ = gray     * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
829
          *dest++ = color->a * 255.0 + (gdouble) (i & 0xff) / 256.0;
 
830
        }
 
831
      else
 
832
        {
 
833
          *dest++ = ROUND (gray     * 255.0);
 
834
          *dest++ = ROUND (color->a * 255.0);
 
835
        }
882
836
    }
883
837
 
884
838
  /* Paint whole row if we are on the rightmost pixel */
888
842
}
889
843
 
890
844
static void
891
 
gradient_fill_region (GimpImage        *gimage,
892
 
                      GimpDrawable     *drawable,
 
845
gradient_fill_region (GimpImage        *image,
 
846
                      GimpDrawable     *drawable,
893
847
                      GimpContext      *context,
894
 
                      PixelRegion      *PR,
895
 
                      gint              width,
896
 
                      gint              height,
897
 
                      GimpBlendMode     blend_mode,
898
 
                      GimpGradientType  gradient_type,
899
 
                      gdouble           offset,
900
 
                      GimpRepeatMode    repeat,
 
848
                      PixelRegion      *PR,
 
849
                      gint              width,
 
850
                      gint              height,
 
851
                      GimpBlendMode     blend_mode,
 
852
                      GimpGradientType  gradient_type,
 
853
                      gdouble           offset,
 
854
                      GimpRepeatMode    repeat,
901
855
                      gboolean          reverse,
902
 
                      gboolean          supersample,
903
 
                      gint              max_depth,
904
 
                      gdouble           threshold,
905
 
                      gboolean          dither,
906
 
                      gdouble           sx,
907
 
                      gdouble           sy,
908
 
                      gdouble           ex,
909
 
                      gdouble           ey,
910
 
                      GimpProgress     *progress)
 
856
                      gboolean          supersample,
 
857
                      gint              max_depth,
 
858
                      gdouble           threshold,
 
859
                      gboolean          dither,
 
860
                      gdouble           sx,
 
861
                      gdouble           sy,
 
862
                      gdouble           ex,
 
863
                      gdouble           ey,
 
864
                      GimpProgress     *progress)
911
865
{
912
 
  RenderBlendData  rbd;
913
 
  gint             x, y;
914
 
  gint             endx, endy;
915
 
  gpointer         pr;
916
 
  guchar          *data;
917
 
  GimpRGB          color;
918
 
  GRand           *dither_rand = NULL;
 
866
  RenderBlendData rbd;
919
867
 
920
868
  rbd.gradient = gimp_context_get_gradient (context);
 
869
  rbd.context  = context;
921
870
  rbd.reverse  = reverse;
922
871
 
 
872
  if (gimp_gradient_has_fg_bg_segments (rbd.gradient))
 
873
    rbd.gradient = gimp_gradient_flatten (rbd.gradient, context);
 
874
  else
 
875
    rbd.gradient = g_object_ref (rbd.gradient);
 
876
 
923
877
  gimp_context_get_foreground (context, &rbd.fg);
924
878
  gimp_context_get_background (context, &rbd.bg);
925
879
 
978
932
      rbd.dist = sqrt (SQR (ex - sx) + SQR (ey - sy));
979
933
 
980
934
      if (rbd.dist > 0.0)
981
 
        {
982
 
          rbd.vec[0] = (ex - sx) / rbd.dist;
983
 
          rbd.vec[1] = (ey - sy) / rbd.dist;
984
 
        }
 
935
        {
 
936
          rbd.vec[0] = (ex - sx) / rbd.dist;
 
937
          rbd.vec[1] = (ey - sy) / rbd.dist;
 
938
        }
985
939
 
986
940
      break;
987
941
 
989
943
    case GIMP_GRADIENT_SHAPEBURST_SPHERICAL:
990
944
    case GIMP_GRADIENT_SHAPEBURST_DIMPLED:
991
945
      rbd.dist = sqrt (SQR (ex - sx) + SQR (ey - sy));
992
 
      gradient_precalc_shapeburst (gimage, drawable, PR, rbd.dist, progress);
 
946
      gradient_precalc_shapeburst (image, drawable, PR, rbd.dist, progress);
993
947
      break;
994
948
 
995
949
    default:
1006
960
  rbd.gradient_type = gradient_type;
1007
961
  rbd.repeat        = repeat;
1008
962
 
1009
 
  if (dither)
1010
 
    dither_rand = g_rand_new ();
1011
 
 
1012
963
  /* Render the gradient! */
1013
964
 
1014
965
  if (supersample)
1019
970
      ppd.row_data    = g_malloc (width * PR->bytes);
1020
971
      ppd.bytes       = PR->bytes;
1021
972
      ppd.width       = width;
1022
 
      ppd.dither      = dither;
1023
 
      ppd.dither_rand = dither_rand;
 
973
      ppd.dither_rand = g_rand_new ();
1024
974
 
1025
975
      gimp_adaptive_supersample_area (0, 0, (width - 1), (height - 1),
1026
 
                                      max_depth, threshold,
1027
 
                                      gradient_render_pixel, &rbd,
1028
 
                                      gradient_put_pixel, &ppd,
1029
 
                                      progress ?
 
976
                                      max_depth, threshold,
 
977
                                      gradient_render_pixel, &rbd,
 
978
                                      gradient_put_pixel, &ppd,
 
979
                                      progress ?
1030
980
                                      gimp_progress_update_and_flush : NULL,
1031
981
                                      progress);
1032
982
 
 
983
      g_rand_free (ppd.dither_rand);
1033
984
      g_free (ppd.row_data);
1034
985
    }
1035
986
  else
1036
987
    {
1037
 
      gint max_progress  = PR->w * PR->h;
1038
 
      gint curr_progress = 0;
1039
 
 
1040
 
      for (pr = pixel_regions_register (1, PR);
1041
 
           pr != NULL;
1042
 
           pr = pixel_regions_process (pr))
1043
 
        {
1044
 
          data = PR->data;
1045
 
          endx = PR->x + PR->w;
1046
 
          endy = PR->y + PR->h;
1047
 
 
1048
 
          for (y = PR->y; y < endy; y++)
1049
 
            {
1050
 
              for (x = PR->x; x < endx; x++)
1051
 
                {
1052
 
                  gradient_render_pixel (x, y, &color, &rbd);
1053
 
 
1054
 
                  if (PR->bytes >= 3)
1055
 
                    {
1056
 
                      if (dither)
1057
 
                        {
1058
 
                          gdouble dither_prob;
1059
 
                          gdouble ftmp;
1060
 
                          gint    itmp;
1061
 
 
1062
 
                          ftmp = color.r * 255.0;
1063
 
                          itmp = ftmp;
1064
 
                          dither_prob = ftmp - itmp;
1065
 
 
1066
 
                          if (g_rand_double (dither_rand) < dither_prob)
1067
 
                            color.r += (1.0 / 255.0);
1068
 
 
1069
 
                          ftmp = color.g * 255.0;
1070
 
                          itmp = ftmp;
1071
 
                          dither_prob = ftmp - itmp;
1072
 
 
1073
 
                          if (g_rand_double (dither_rand) < dither_prob)
1074
 
                            color.g += (1.0 / 255.0);
1075
 
 
1076
 
                          ftmp = color.b * 255.0;
1077
 
                          itmp = ftmp;
1078
 
                          dither_prob = ftmp - itmp;
1079
 
 
1080
 
                          if (g_rand_double (dither_rand) < dither_prob)
1081
 
                            color.b += (1.0 / 255.0);
1082
 
 
1083
 
                          ftmp = color.a * 255.0;
1084
 
                          itmp = ftmp;
1085
 
                          dither_prob = ftmp - itmp;
1086
 
 
1087
 
                          if (g_rand_double (dither_rand) < dither_prob)
1088
 
                            color.a += (1.0 / 255.0);
1089
 
 
1090
 
                          if (color.r > 1.0) color.r = 1.0;
1091
 
                          if (color.g > 1.0) color.g = 1.0;
1092
 
                          if (color.b > 1.0) color.b = 1.0;
1093
 
                          if (color.a > 1.0) color.a = 1.0;
1094
 
                        }
1095
 
 
1096
 
                      *data++ = color.r * 255.0;
1097
 
                      *data++ = color.g * 255.0;
1098
 
                      *data++ = color.b * 255.0;
1099
 
                      *data++ = color.a * 255.0;
1100
 
                    }
1101
 
                  else
1102
 
                    {
1103
 
                      /* Convert to grayscale */
1104
 
                      gdouble gray = gimp_rgb_intensity (&color);
1105
 
 
1106
 
                      if (dither)
1107
 
                        {
1108
 
                          gdouble dither_prob;
1109
 
                          gdouble ftmp;
1110
 
                          gint    itmp;
1111
 
 
1112
 
                          ftmp = gray * 255.0;
1113
 
                          itmp = ftmp;
1114
 
                          dither_prob = ftmp - itmp;
1115
 
 
1116
 
                          if (g_rand_double (dither_rand) < dither_prob)
1117
 
                            gray += (1.0 / 255.0);
1118
 
 
1119
 
                          ftmp = color.a * 255.0;
1120
 
                          itmp = ftmp;
1121
 
                          dither_prob = ftmp - itmp;
1122
 
 
1123
 
                          if (g_rand_double (dither_rand) < dither_prob)
1124
 
                            color.a += (1.0 / 255.0);
1125
 
 
1126
 
                          if (gray > 1.0)    gray    = 1.0;
1127
 
                          if (color.a > 1.0) color.a = 1.0;
1128
 
                        }
1129
 
 
1130
 
                      *data++ = gray * 255.0;
1131
 
                      *data++ = color.a * 255.0;
1132
 
                    }
1133
 
                }
1134
 
            }
1135
 
 
1136
 
          if (progress)
1137
 
            {
1138
 
              curr_progress += PR->w * PR->h;
1139
 
 
1140
 
              gimp_progress_set_value (progress,
1141
 
                                       (gdouble) curr_progress /
1142
 
                                       (gdouble) max_progress);
1143
 
            }
1144
 
        }
 
988
      PixelProcessorFunc          func;
 
989
      PixelProcessorProgressFunc  progress_func = NULL;
 
990
 
 
991
      if (dither)
 
992
        {
 
993
          rbd.seed = g_rand_new ();
 
994
 
 
995
          if (PR->bytes >= 3)
 
996
            func = (PixelProcessorFunc) gradient_fill_single_region_rgb_dither;
 
997
          else
 
998
            func = (PixelProcessorFunc) gradient_fill_single_region_gray_dither;
 
999
        }
 
1000
      else
 
1001
        {
 
1002
          if (PR->bytes >= 3)
 
1003
            func = (PixelProcessorFunc) gradient_fill_single_region_rgb;
 
1004
          else
 
1005
            func = (PixelProcessorFunc) gradient_fill_single_region_gray;
 
1006
        }
 
1007
 
 
1008
      if (progress)
 
1009
        progress_func = (PixelProcessorProgressFunc) gimp_progress_set_value;
 
1010
 
 
1011
      pixel_regions_process_parallel_progress (func, &rbd,
 
1012
                                               progress_func, progress,
 
1013
                                               1, PR);
 
1014
 
 
1015
      if (dither)
 
1016
        g_rand_free (rbd.seed);
1145
1017
    }
1146
1018
 
1147
 
  if (dither)
1148
 
    g_rand_free (dither_rand);
 
1019
  g_object_unref (rbd.gradient);
 
1020
}
 
1021
 
 
1022
static void
 
1023
gradient_fill_single_region_rgb (RenderBlendData *rbd,
 
1024
                                 PixelRegion     *PR)
 
1025
{
 
1026
  guchar *dest = PR->data;
 
1027
  gint    endx = PR->x + PR->w;
 
1028
  gint    endy = PR->y + PR->h;
 
1029
  gint    x, y;
 
1030
 
 
1031
  for (y = PR->y; y < endy; y++)
 
1032
    for (x = PR->x; x < endx; x++)
 
1033
      {
 
1034
        GimpRGB  color;
 
1035
 
 
1036
        gradient_render_pixel (x, y, &color, rbd);
 
1037
 
 
1038
        *dest++ = ROUND (color.r * 255.0);
 
1039
        *dest++ = ROUND (color.g * 255.0);
 
1040
        *dest++ = ROUND (color.b * 255.0);
 
1041
        *dest++ = ROUND (color.a * 255.0);
 
1042
      }
 
1043
}
 
1044
 
 
1045
static void
 
1046
gradient_fill_single_region_rgb_dither (RenderBlendData *rbd,
 
1047
                                        PixelRegion     *PR)
 
1048
{
 
1049
  GRand  *dither_rand = g_rand_new_with_seed (g_rand_int (rbd->seed));
 
1050
  guchar *dest        = PR->data;
 
1051
  gint    endx        = PR->x + PR->w;
 
1052
  gint    endy        = PR->y + PR->h;
 
1053
  gint    x, y;
 
1054
 
 
1055
  for (y = PR->y; y < endy; y++)
 
1056
    for (x = PR->x; x < endx; x++)
 
1057
      {
 
1058
        GimpRGB  color;
 
1059
        gint     i = g_rand_int (dither_rand);
 
1060
 
 
1061
        gradient_render_pixel (x, y, &color, rbd);
 
1062
 
 
1063
        *dest++ = color.r * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
1064
        *dest++ = color.g * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
1065
        *dest++ = color.b * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
1066
        *dest++ = color.a * 255.0 + (gdouble) (i & 0xff) / 256.0;
 
1067
      }
 
1068
 
 
1069
  g_rand_free (dither_rand);
 
1070
}
 
1071
 
 
1072
static void
 
1073
gradient_fill_single_region_gray (RenderBlendData *rbd,
 
1074
                                  PixelRegion     *PR)
 
1075
{
 
1076
  guchar *dest = PR->data;
 
1077
  gint    endx = PR->x + PR->w;
 
1078
  gint    endy = PR->y + PR->h;
 
1079
  gint    x, y;
 
1080
 
 
1081
  for (y = PR->y; y < endy; y++)
 
1082
    for (x = PR->x; x < endx; x++)
 
1083
      {
 
1084
        GimpRGB  color;
 
1085
 
 
1086
        gradient_render_pixel (x, y, &color, rbd);
 
1087
 
 
1088
        *dest++ = gimp_rgb_luminance_uchar (&color);
 
1089
        *dest++ = ROUND (color.a * 255.0);
 
1090
      }
 
1091
}
 
1092
 
 
1093
static void
 
1094
gradient_fill_single_region_gray_dither (RenderBlendData *rbd,
 
1095
                                         PixelRegion     *PR)
 
1096
{
 
1097
  GRand  *dither_rand = g_rand_new_with_seed (g_rand_int (rbd->seed));
 
1098
  guchar *dest        = PR->data;
 
1099
  gint    endx        = PR->x + PR->w;
 
1100
  gint    endy        = PR->y + PR->h;
 
1101
  gint    x, y;
 
1102
 
 
1103
  for (y = PR->y; y < endy; y++)
 
1104
    for (x = PR->x; x < endx; x++)
 
1105
      {
 
1106
        GimpRGB  color;
 
1107
        gdouble  gray;
 
1108
        gint     i = g_rand_int (dither_rand);
 
1109
 
 
1110
        gradient_render_pixel (x, y, &color, rbd);
 
1111
 
 
1112
        gray = gimp_rgb_luminance (&color);
 
1113
 
 
1114
        *dest++ = gray    * 255.0 + (gdouble) (i & 0xff) / 256.0; i >>= 8;
 
1115
        *dest++ = color.a * 255.0 + (gdouble) (i & 0xff) / 256.0;
 
1116
      }
 
1117
 
 
1118
  g_rand_free (dither_rand);
1149
1119
}