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

« back to all changes in this revision

Viewing changes to app/paint/gimpink.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
22
22
 
23
23
#include <glib-object.h>
24
24
 
 
25
#include "libgimpmath/gimpmath.h"
 
26
 
25
27
#include "paint-types.h"
26
28
 
27
29
#include "base/pixel-region.h"
33
35
 
34
36
#include "core/gimpdrawable.h"
35
37
#include "core/gimpimage.h"
 
38
#include "core/gimpimage-undo.h"
36
39
 
37
40
#include "gimpinkoptions.h"
38
41
#include "gimpink.h"
39
42
#include "gimpink-blob.h"
40
 
#include "gimpink-undo.h"
 
43
#include "gimpinkundo.h"
41
44
 
42
45
#include "gimp-intl.h"
43
46
 
47
50
 
48
51
/*  local function prototypes  */
49
52
 
50
 
static void      gimp_ink_class_init     (GimpInkClass     *klass);
51
 
static void      gimp_ink_init           (GimpInk          *ink);
52
 
 
53
53
static void      gimp_ink_finalize       (GObject          *object);
54
54
 
55
55
static void      gimp_ink_paint          (GimpPaintCore    *paint_core,
60
60
static TempBuf * gimp_ink_get_paint_area (GimpPaintCore    *paint_core,
61
61
                                          GimpDrawable     *drawable,
62
62
                                          GimpPaintOptions *paint_options);
 
63
static GimpUndo* gimp_ink_push_undo      (GimpPaintCore    *core,
 
64
                                          GimpImage        *image,
 
65
                                          const gchar      *undo_desc);
63
66
 
64
67
static void      gimp_ink_motion         (GimpPaintCore    *paint_core,
65
68
                                          GimpDrawable     *drawable,
90
93
                                          PixelRegion      *dest);
91
94
 
92
95
 
93
 
static GimpPaintCoreClass *parent_class = NULL;
 
96
G_DEFINE_TYPE (GimpInk, gimp_ink, GIMP_TYPE_PAINT_CORE)
 
97
 
 
98
#define parent_class gimp_ink_parent_class
94
99
 
95
100
 
96
101
void
100
105
  (* callback) (gimp,
101
106
                GIMP_TYPE_INK,
102
107
                GIMP_TYPE_INK_OPTIONS,
103
 
                _("Ink"));
104
 
}
105
 
 
106
 
GType
107
 
gimp_ink_get_type (void)
108
 
{
109
 
  static GType type = 0;
110
 
 
111
 
  if (! type)
112
 
    {
113
 
      static const GTypeInfo info =
114
 
      {
115
 
        sizeof (GimpInkClass),
116
 
        (GBaseInitFunc) NULL,
117
 
        (GBaseFinalizeFunc) NULL,
118
 
        (GClassInitFunc) gimp_ink_class_init,
119
 
        NULL,           /* class_finalize */
120
 
        NULL,           /* class_data     */
121
 
        sizeof (GimpInk),
122
 
        0,              /* n_preallocs    */
123
 
        (GInstanceInitFunc) gimp_ink_init,
124
 
      };
125
 
 
126
 
      type = g_type_register_static (GIMP_TYPE_PAINT_CORE,
127
 
                                     "GimpInk",
128
 
                                     &info, 0);
129
 
    }
130
 
 
131
 
  return type;
 
108
                "gimp-ink",
 
109
                _("Ink"),
 
110
                "gimp-tool-ink");
132
111
}
133
112
 
134
113
static void
137
116
  GObjectClass       *object_class     = G_OBJECT_CLASS (klass);
138
117
  GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
139
118
 
140
 
  parent_class = g_type_class_peek_parent (klass);
141
 
 
142
 
  object_class->finalize  = gimp_ink_finalize;
 
119
  object_class->finalize           = gimp_ink_finalize;
143
120
 
144
121
  paint_core_class->paint          = gimp_ink_paint;
145
122
  paint_core_class->get_paint_area = gimp_ink_get_paint_area;
255
232
  return paint_core->canvas_buf;
256
233
}
257
234
 
 
235
static GimpUndo *
 
236
gimp_ink_push_undo (GimpPaintCore *core,
 
237
                    GimpImage     *image,
 
238
                    const gchar   *undo_desc)
 
239
{
 
240
  return gimp_image_undo_push (image, GIMP_TYPE_INK_UNDO,
 
241
                               GIMP_UNDO_INK, undo_desc,
 
242
                               0,
 
243
                               "paint-core", core,
 
244
                               NULL);
 
245
}
 
246
 
258
247
static void
259
248
gimp_ink_motion (GimpPaintCore    *paint_core,
260
249
                 GimpDrawable     *drawable,
264
253
  GimpInk        *ink     = GIMP_INK (paint_core);
265
254
  GimpInkOptions *options = GIMP_INK_OPTIONS (paint_options);
266
255
  GimpContext    *context = GIMP_CONTEXT (paint_options);
267
 
  GimpImage      *gimage;
 
256
  GimpImage      *image;
268
257
  Blob           *blob_union = NULL;
269
258
  Blob           *blob_to_render;
270
259
  TempBuf        *area;
271
260
  guchar          col[MAX_CHANNELS];
272
261
  PixelRegion     blob_maskPR;
273
262
 
274
 
  gimage = gimp_item_get_image (GIMP_ITEM (drawable));
 
263
  image = gimp_item_get_image (GIMP_ITEM (drawable));
275
264
 
276
265
  if (! ink->last_blob)
277
266
    {
350
339
      blob_to_render = blob_union;
351
340
    }
352
341
 
353
 
  /* Get the the buffer */
 
342
  /* Get the buffer */
354
343
  ink->cur_blob = blob_to_render;
355
344
  area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options);
356
345
  ink->cur_blob = NULL;
358
347
  if (! area)
359
348
    return;
360
349
 
361
 
  gimp_image_get_foreground (gimage, drawable, context, col);
 
350
  gimp_image_get_foreground (image, context, gimp_drawable_type (drawable),
 
351
                             col);
362
352
 
363
353
  /*  set the alpha channel  */
364
354
  col[paint_core->canvas_buf->bytes - 1] = OPAQUE_OPACITY;
404
394
static Blob *
405
395
ink_pen_ellipse (GimpInkOptions *options,
406
396
                 gdouble         x_center,
407
 
                 gdouble         y_center,
408
 
                 gdouble         pressure,
409
 
                 gdouble         xtilt,
410
 
                 gdouble         ytilt,
411
 
                 gdouble         velocity)
 
397
                 gdouble         y_center,
 
398
                 gdouble         pressure,
 
399
                 gdouble         xtilt,
 
400
                 gdouble         ytilt,
 
401
                 gdouble         velocity)
412
402
{
413
403
  BlobFunc blob_function;
414
404
  gdouble  size;
618
608
 */
619
609
static void
620
610
insert_sort (gint *data,
621
 
             gint  n)
 
611
             gint  n)
622
612
{
623
613
  gint i, j, k;
624
614
  gint tmp1, tmp2;
629
619
      tmp2 = data[i + 1];
630
620
      j = 0;
631
621
      while (data[j] < tmp1)
632
 
        j += 2;
 
622
        j += 2;
633
623
 
634
624
      for (k = i; k > j; k -= 2)
635
 
        {
636
 
          data[k]     = data[k - 2];
637
 
          data[k + 1] = data[k - 1];
638
 
        }
 
625
        {
 
626
          data[k]     = data[k - 2];
 
627
          data[k + 1] = data[k - 1];
 
628
        }
639
629
 
640
630
      data[j]     = tmp1;
641
631
      data[j + 1] = tmp2;
644
634
 
645
635
static void
646
636
fill_run (guchar *dest,
647
 
          guchar  alpha,
648
 
          gint    w)
 
637
          guchar  alpha,
 
638
          gint    w)
649
639
{
650
640
  if (alpha == 255)
651
641
    {
663
653
 
664
654
static void
665
655
render_blob_line (Blob   *blob,
666
 
                  guchar *dest,
667
 
                  gint    x,
668
 
                  gint    y,
669
 
                  gint    width)
 
656
                  guchar *dest,
 
657
                  gint    x,
 
658
                  gint    y,
 
659
                  gint    width)
670
660
{
671
661
  gint  buf[4 * SUBSAMPLE];
672
662
  gint *data    = buf;
673
663
  gint  n       = 0;
674
664
  gint  i, j;
675
665
  gint  current = 0;  /* number of filled rows at this point
676
 
                       * in the scan line
677
 
                       */
 
666
                       * in the scan line
 
667
                       */
678
668
  gint last_x;
679
669
 
680
670
  /* Sort start and ends for all lines */
683
673
  for (i = 0; i < SUBSAMPLE; i++)
684
674
    {
685
675
      if (j >= blob->height)
686
 
        break;
 
676
        break;
687
677
 
688
678
      if ((j > 0) && (blob->data[j].left <= blob->data[j].right))
689
 
        {
690
 
          data[2 * n]                     = blob->data[j].left;
691
 
          data[2 * n + 1]                 = ROW_START;
692
 
          data[2 * SUBSAMPLE + 2 * n]     = blob->data[j].right;
693
 
          data[2 * SUBSAMPLE + 2 * n + 1] = ROW_STOP;
694
 
          n++;
695
 
        }
 
679
        {
 
680
          data[2 * n]                     = blob->data[j].left;
 
681
          data[2 * n + 1]                 = ROW_START;
 
682
          data[2 * SUBSAMPLE + 2 * n]     = blob->data[j].right;
 
683
          data[2 * SUBSAMPLE + 2 * n + 1] = ROW_STOP;
 
684
          n++;
 
685
        }
696
686
      j++;
697
687
    }
698
688
 
700
690
  if (n < SUBSAMPLE)
701
691
    {
702
692
      for (i = 0; i < 2 * n; i++)
703
 
        data[2 * n + i] = data[2 * SUBSAMPLE + i];
 
693
        data[2 * n + i] = data[2 * SUBSAMPLE + i];
704
694
    }
705
695
 
706
696
  /*   Now count start and end separately */
713
703
  while ((n > 0) && (data[0] < SUBSAMPLE*x))
714
704
    {
715
705
      if (data[1] == ROW_START)
716
 
        current++;
 
706
        current++;
717
707
      else
718
 
        current--;
 
708
        current--;
719
709
      data += 2;
720
710
      n--;
721
711
    }
733
723
 
734
724
      /* Fill in portion leading up to this pixel */
735
725
      if (current && cur_x != last_x)
736
 
        fill_run (dest + last_x, (255 * current) / SUBSAMPLE, cur_x - last_x);
 
726
        fill_run (dest + last_x, (255 * current) / SUBSAMPLE, cur_x - last_x);
737
727
 
738
728
      /* Compute the value for this pixel */
739
729
      pixel = current * SUBSAMPLE;
740
730
 
741
731
      while (i<n)
742
 
        {
743
 
          gint tmp_x = data[2 * i] / SUBSAMPLE;
744
 
 
745
 
          if (tmp_x - x != cur_x)
746
 
            break;
747
 
 
748
 
          if (data[2 * i + 1] == ROW_START)
749
 
            {
750
 
              current++;
751
 
              pixel += ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
752
 
            }
753
 
          else
754
 
            {
755
 
              current--;
756
 
              pixel -= ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
757
 
            }
758
 
 
759
 
          i++;
760
 
        }
 
732
        {
 
733
          gint tmp_x = data[2 * i] / SUBSAMPLE;
 
734
 
 
735
          if (tmp_x - x != cur_x)
 
736
            break;
 
737
 
 
738
          if (data[2 * i + 1] == ROW_START)
 
739
            {
 
740
              current++;
 
741
              pixel += ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
 
742
            }
 
743
          else
 
744
            {
 
745
              current--;
 
746
              pixel -= ((tmp_x + 1) * SUBSAMPLE) - data[2 * i];
 
747
            }
 
748
 
 
749
          i++;
 
750
        }
761
751
 
762
752
      dest[cur_x] = MAX (dest[cur_x], (pixel * 255) / (SUBSAMPLE * SUBSAMPLE));
763
753
 
785
775
      s = dest->data;
786
776
 
787
777
      for (i=0; i<h; i++)
788
 
        {
789
 
          render_blob_line (blob, s,
790
 
                            dest->x, dest->y + i, dest->w);
791
 
          s += dest->rowstride;
792
 
        }
 
778
        {
 
779
          render_blob_line (blob, s,
 
780
                            dest->x, dest->y + i, dest->w);
 
781
          s += dest->rowstride;
 
782
        }
793
783
    }
794
784
}