~ubuntu-branches/ubuntu/breezy/gimp/breezy

« back to all changes in this revision

Viewing changes to app/core/gimppalette.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-10-04 19:04:46 UTC
  • Revision ID: james.westby@ubuntu.com-20051004190446-ukh32kwk56s4sjhu
Tags: upstream-2.2.8
ImportĀ upstreamĀ versionĀ 2.2.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <stdlib.h>
 
22
#include <stdio.h>
 
23
#include <string.h>
 
24
#include <errno.h>
 
25
#ifdef HAVE_UNISTD_H
 
26
#include <unistd.h>
 
27
#endif
 
28
 
 
29
#include <glib-object.h>
 
30
 
 
31
#include "libgimpbase/gimpbase.h"
 
32
#include "libgimpcolor/gimpcolor.h"
 
33
 
 
34
#include "core-types.h"
 
35
 
 
36
#include "base/temp-buf.h"
 
37
 
 
38
#include "gimppalette.h"
 
39
 
 
40
#include "gimp-intl.h"
 
41
 
 
42
 
 
43
/*  local function prototypes  */
 
44
 
 
45
static void       gimp_palette_class_init       (GimpPaletteClass  *klass);
 
46
static void       gimp_palette_init             (GimpPalette       *palette);
 
47
 
 
48
static void       gimp_palette_finalize         (GObject           *object);
 
49
 
 
50
static gint64     gimp_palette_get_memsize      (GimpObject        *object,
 
51
                                                 gint64            *gui_size);
 
52
 
 
53
static void       gimp_palette_get_preview_size (GimpViewable      *viewable,
 
54
                                                 gint               size,
 
55
                                                 gboolean           popup,
 
56
                                                 gboolean           dot_for_dot,
 
57
                                                 gint              *width,
 
58
                                                 gint              *height);
 
59
static gboolean   gimp_palette_get_popup_size   (GimpViewable      *viewable,
 
60
                                                 gint               width,
 
61
                                                 gint               height,
 
62
                                                 gboolean           dot_for_dot,
 
63
                                                 gint              *popup_width,
 
64
                                                 gint              *popup_height);
 
65
static TempBuf  * gimp_palette_get_new_preview  (GimpViewable      *viewable,
 
66
                                                 gint               width,
 
67
                                                 gint               height);
 
68
static gchar    * gimp_palette_get_description  (GimpViewable      *viewable,
 
69
                                                 gchar            **tooltip);
 
70
static gboolean   gimp_palette_save             (GimpData          *data,
 
71
                                                 GError           **error);
 
72
static gchar    * gimp_palette_get_extension    (GimpData          *data);
 
73
static GimpData * gimp_palette_duplicate        (GimpData          *data,
 
74
                                                 gboolean           stingy_memory_use);
 
75
 
 
76
static void       gimp_palette_entry_free       (GimpPaletteEntry  *entry);
 
77
 
 
78
 
 
79
/*  private variables  */
 
80
 
 
81
static GimpDataClass *parent_class = NULL;
 
82
 
 
83
 
 
84
GType
 
85
gimp_palette_get_type (void)
 
86
{
 
87
  static GType palette_type = 0;
 
88
 
 
89
  if (! palette_type)
 
90
    {
 
91
      static const GTypeInfo palette_info =
 
92
      {
 
93
        sizeof (GimpPaletteClass),
 
94
        (GBaseInitFunc) NULL,
 
95
        (GBaseFinalizeFunc) NULL,
 
96
        (GClassInitFunc) gimp_palette_class_init,
 
97
        NULL,           /* class_finalize */
 
98
        NULL,           /* class_data     */
 
99
        sizeof (GimpPalette),
 
100
        0,              /* n_preallocs    */
 
101
        (GInstanceInitFunc) gimp_palette_init,
 
102
      };
 
103
 
 
104
      palette_type = g_type_register_static (GIMP_TYPE_DATA,
 
105
                                             "GimpPalette",
 
106
                                             &palette_info, 0);
 
107
    }
 
108
 
 
109
  return palette_type;
 
110
}
 
111
 
 
112
static void
 
113
gimp_palette_class_init (GimpPaletteClass *klass)
 
114
{
 
115
  GObjectClass      *object_class      = G_OBJECT_CLASS (klass);
 
116
  GimpObjectClass   *gimp_object_class = GIMP_OBJECT_CLASS (klass);
 
117
  GimpViewableClass *viewable_class    = GIMP_VIEWABLE_CLASS (klass);
 
118
  GimpDataClass     *data_class        = GIMP_DATA_CLASS (klass);
 
119
 
 
120
  parent_class = g_type_class_peek_parent (klass);
 
121
 
 
122
  object_class->finalize           = gimp_palette_finalize;
 
123
 
 
124
  gimp_object_class->get_memsize   = gimp_palette_get_memsize;
 
125
 
 
126
  viewable_class->default_stock_id = "gtk-select-color";
 
127
  viewable_class->get_preview_size = gimp_palette_get_preview_size;
 
128
  viewable_class->get_popup_size   = gimp_palette_get_popup_size;
 
129
  viewable_class->get_new_preview  = gimp_palette_get_new_preview;
 
130
  viewable_class->get_description  = gimp_palette_get_description;
 
131
 
 
132
  data_class->save                 = gimp_palette_save;
 
133
  data_class->get_extension        = gimp_palette_get_extension;
 
134
  data_class->duplicate            = gimp_palette_duplicate;
 
135
}
 
136
 
 
137
static void
 
138
gimp_palette_init (GimpPalette *palette)
 
139
{
 
140
  palette->colors    = NULL;
 
141
  palette->n_colors  = 0;
 
142
  palette->n_columns = 0;
 
143
}
 
144
 
 
145
static void
 
146
gimp_palette_finalize (GObject *object)
 
147
{
 
148
  GimpPalette *palette = GIMP_PALETTE (object);
 
149
 
 
150
  if (palette->colors)
 
151
    {
 
152
      g_list_foreach (palette->colors, (GFunc) gimp_palette_entry_free, NULL);
 
153
      g_list_free (palette->colors);
 
154
      palette->colors = NULL;
 
155
    }
 
156
 
 
157
  G_OBJECT_CLASS (parent_class)->finalize (object);
 
158
}
 
159
 
 
160
static gint64
 
161
gimp_palette_get_memsize (GimpObject *object,
 
162
                          gint64     *gui_size)
 
163
{
 
164
  GimpPalette *palette = GIMP_PALETTE (object);
 
165
  GList       *list;
 
166
  gint64       memsize = 0;
 
167
 
 
168
  for (list = palette->colors; list; list = g_list_next (list))
 
169
    {
 
170
      GimpPaletteEntry *entry = list->data;
 
171
 
 
172
      memsize += sizeof (GList) + sizeof (GimpPaletteEntry);
 
173
 
 
174
      if (entry->name)
 
175
        memsize += strlen (entry->name) + 1;
 
176
    }
 
177
 
 
178
  return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
 
179
                                                                  gui_size);
 
180
}
 
181
 
 
182
static void
 
183
gimp_palette_get_preview_size (GimpViewable *viewable,
 
184
                               gint          size,
 
185
                               gboolean      popup,
 
186
                               gboolean      dot_for_dot,
 
187
                               gint         *width,
 
188
                               gint         *height)
 
189
{
 
190
  *width  = size;
 
191
  *height = size / 2;
 
192
}
 
193
 
 
194
static gboolean
 
195
gimp_palette_get_popup_size (GimpViewable *viewable,
 
196
                             gint          width,
 
197
                             gint          height,
 
198
                             gboolean      dot_for_dot,
 
199
                             gint         *popup_width,
 
200
                             gint         *popup_height)
 
201
{
 
202
  GimpPalette *palette = GIMP_PALETTE (viewable);
 
203
  gint         p_width;
 
204
  gint         p_height;
 
205
 
 
206
  if (! palette->n_colors)
 
207
    return FALSE;
 
208
 
 
209
  if (palette->n_columns)
 
210
    p_width = palette->n_columns;
 
211
  else
 
212
    p_width = MIN (palette->n_colors, 16);
 
213
 
 
214
  p_height = MAX (1, palette->n_colors / p_width);
 
215
 
 
216
  if (p_width * 4 > width || p_height * 4 > height)
 
217
    {
 
218
      *popup_width  = p_width  * 4;
 
219
      *popup_height = p_height * 4;
 
220
 
 
221
      return TRUE;
 
222
    }
 
223
 
 
224
  return FALSE;
 
225
}
 
226
 
 
227
static TempBuf *
 
228
gimp_palette_get_new_preview (GimpViewable *viewable,
 
229
                              gint          width,
 
230
                              gint          height)
 
231
{
 
232
  GimpPalette *palette  = GIMP_PALETTE (viewable);
 
233
  TempBuf     *temp_buf;
 
234
  guchar      *buf;
 
235
  guchar      *b;
 
236
  GList       *list;
 
237
  guchar       white[3] = { 255, 255, 255 };
 
238
  gint         columns;
 
239
  gint         rows;
 
240
  gint         cell_size;
 
241
  gint         x, y;
 
242
 
 
243
  temp_buf = temp_buf_new (width, height, 3, 0, 0, white);
 
244
 
 
245
  if (palette->n_columns > 1)
 
246
    cell_size = MAX (4, width / palette->n_columns);
 
247
  else
 
248
    cell_size = 4;
 
249
 
 
250
  columns = width  / cell_size;
 
251
  rows    = height / cell_size;
 
252
 
 
253
  buf = temp_buf_data (temp_buf);
 
254
  b   = g_new (guchar, width * 3);
 
255
 
 
256
  list = palette->colors;
 
257
 
 
258
  for (y = 0; y < rows && list; y++)
 
259
    {
 
260
      gint i;
 
261
 
 
262
      memset (b, 255, width * 3);
 
263
 
 
264
      for (x = 0; x < columns && list; x++)
 
265
        {
 
266
          GimpPaletteEntry *entry = list->data;
 
267
 
 
268
          list = g_list_next (list);
 
269
 
 
270
          gimp_rgb_get_uchar (&entry->color,
 
271
                              &b[x * cell_size * 3 + 0],
 
272
                              &b[x * cell_size * 3 + 1],
 
273
                              &b[x * cell_size * 3 + 2]);
 
274
 
 
275
          for (i = 1; i < cell_size; i++)
 
276
            {
 
277
              b[(x * cell_size + i) * 3 + 0] = b[(x * cell_size) * 3 + 0];
 
278
              b[(x * cell_size + i) * 3 + 1] = b[(x * cell_size) * 3 + 1];
 
279
              b[(x * cell_size + i) * 3 + 2] = b[(x * cell_size) * 3 + 2];
 
280
            }
 
281
        }
 
282
 
 
283
      for (i = 0; i < cell_size; i++)
 
284
        memcpy (buf + ((y * cell_size + i) * width) * 3, b, width * 3);
 
285
    }
 
286
 
 
287
  g_free (b);
 
288
 
 
289
  return temp_buf;
 
290
}
 
291
 
 
292
static gchar *
 
293
gimp_palette_get_description (GimpViewable  *viewable,
 
294
                              gchar        **tooltip)
 
295
{
 
296
  GimpPalette *palette = GIMP_PALETTE (viewable);
 
297
 
 
298
  if (tooltip)
 
299
    *tooltip = NULL;
 
300
 
 
301
  return g_strdup_printf ("%s (%d)",
 
302
                          GIMP_OBJECT (palette)->name,
 
303
                          palette->n_colors);
 
304
}
 
305
 
 
306
GimpData *
 
307
gimp_palette_new (const gchar *name,
 
308
                  gboolean     stingy_memory_use)
 
309
{
 
310
  g_return_val_if_fail (name != NULL, NULL);
 
311
  g_return_val_if_fail (*name != '\0', NULL);
 
312
 
 
313
  return g_object_new (GIMP_TYPE_PALETTE,
 
314
                       "name", name,
 
315
                       NULL);
 
316
}
 
317
 
 
318
GimpData *
 
319
gimp_palette_get_standard (void)
 
320
{
 
321
  static GimpData *standard_palette = NULL;
 
322
 
 
323
  if (! standard_palette)
 
324
    {
 
325
      standard_palette = gimp_palette_new ("Standard", FALSE);
 
326
 
 
327
      standard_palette->dirty = FALSE;
 
328
      gimp_data_make_internal (standard_palette);
 
329
 
 
330
      g_object_ref (standard_palette);
 
331
    }
 
332
 
 
333
  return standard_palette;
 
334
}
 
335
 
 
336
GList *
 
337
gimp_palette_load (const gchar  *filename,
 
338
                   gboolean      stingy_memory_use,
 
339
                   GError      **error)
 
340
{
 
341
  GimpPalette      *palette;
 
342
  GimpPaletteEntry *entry;
 
343
  gchar             str[1024];
 
344
  gchar            *tok;
 
345
  FILE             *file;
 
346
  gint              r, g, b;
 
347
  gint              linenum;
 
348
 
 
349
  g_return_val_if_fail (filename != NULL, NULL);
 
350
  g_return_val_if_fail (g_path_is_absolute (filename), NULL);
 
351
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
352
 
 
353
  r = g = b = 0;
 
354
 
 
355
  file = fopen (filename, "r");
 
356
 
 
357
  if (! file)
 
358
    {
 
359
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
 
360
                   _("Could not open '%s' for reading: %s"),
 
361
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
 
362
      return NULL;
 
363
    }
 
364
 
 
365
  linenum = 0;
 
366
 
 
367
  fread (str, 13, 1, file);
 
368
  str[13] = '\0';
 
369
  linenum++;
 
370
  if (strcmp (str, "GIMP Palette\n"))
 
371
    {
 
372
      /* bad magic, but maybe it has \r\n at the end of lines? */
 
373
      if (!strcmp (str, "GIMP Palette\r"))
 
374
        g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
375
                     _("Fatal parse error in palette file '%s': "
 
376
                       "Missing magic header.\n"
 
377
                       "Does this file need converting from DOS?"),
 
378
                     gimp_filename_to_utf8 (filename));
 
379
      else
 
380
        g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
381
                     _("Fatal parse error in palette file '%s': "
 
382
                       "Missing magic header."),
 
383
                     gimp_filename_to_utf8 (filename));
 
384
 
 
385
      fclose (file);
 
386
 
 
387
      return NULL;
 
388
    }
 
389
 
 
390
  palette = g_object_new (GIMP_TYPE_PALETTE, NULL);
 
391
 
 
392
  if (! fgets (str, sizeof (str), file))
 
393
    {
 
394
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
395
                   _("Fatal parse error in palette file '%s': "
 
396
                     "Read error in line %d."),
 
397
                   gimp_filename_to_utf8 (filename), linenum);
 
398
      fclose (file);
 
399
      g_object_unref (palette);
 
400
      return NULL;
 
401
    }
 
402
 
 
403
  linenum++;
 
404
 
 
405
  if (! strncmp (str, "Name: ", strlen ("Name: ")))
 
406
    {
 
407
      gchar *utf8;
 
408
 
 
409
      utf8 = gimp_any_to_utf8 (&str[strlen ("Name: ")], -1,
 
410
                               _("Invalid UTF-8 string in palette file '%s'"),
 
411
                               gimp_filename_to_utf8 (filename));
 
412
      g_strstrip (utf8);
 
413
 
 
414
      gimp_object_set_name (GIMP_OBJECT (palette), utf8);
 
415
      g_free (utf8);
 
416
 
 
417
      if (! fgets (str, sizeof (str), file))
 
418
        {
 
419
          g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
420
                       _("Fatal parse error in palette file '%s': "
 
421
                         "Read error in line %d."),
 
422
                       gimp_filename_to_utf8 (filename), linenum);
 
423
          fclose (file);
 
424
          g_object_unref (palette);
 
425
          return NULL;
 
426
        }
 
427
 
 
428
      linenum++;
 
429
 
 
430
      if (! strncmp (str, "Columns: ", strlen ("Columns: ")))
 
431
        {
 
432
          gint columns;
 
433
 
 
434
          columns = atoi (g_strstrip (&str[strlen ("Columns: ")]));
 
435
 
 
436
          if (columns < 0 || columns > 256)
 
437
            {
 
438
              g_message (_("Reading palette file '%s': "
 
439
                           "Invalid number of columns in line %d. "
 
440
                           "Using default value."),
 
441
                         gimp_filename_to_utf8 (filename), linenum);
 
442
              columns = 0;
 
443
            }
 
444
 
 
445
          palette->n_columns = columns;
 
446
 
 
447
          if (! fgets (str, sizeof (str), file))
 
448
            {
 
449
              g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
450
                           _("Fatal parse error in palette file '%s': "
 
451
                             "Read error in line %d."),
 
452
                           gimp_filename_to_utf8 (filename), linenum);
 
453
              fclose (file);
 
454
              g_object_unref (palette);
 
455
              return NULL;
 
456
            }
 
457
 
 
458
          linenum++;
 
459
        }
 
460
    }
 
461
  else /* old palette format */
 
462
    {
 
463
      gchar *basename;
 
464
      gchar *utf8;
 
465
 
 
466
      basename = g_path_get_basename (filename);
 
467
 
 
468
      utf8 = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
 
469
      g_free (basename);
 
470
 
 
471
      gimp_object_set_name (GIMP_OBJECT (palette), utf8);
 
472
      g_free (utf8);
 
473
    }
 
474
 
 
475
  while (! feof (file))
 
476
    {
 
477
      if (str[0] != '#')
 
478
        {
 
479
          tok = strtok (str, " \t");
 
480
          if (tok)
 
481
            r = atoi (tok);
 
482
          else
 
483
            /* maybe we should just abort? */
 
484
            g_message (_("Reading palette file '%s': "
 
485
                         "Missing RED component in line %d."),
 
486
                       gimp_filename_to_utf8 (filename), linenum);
 
487
 
 
488
          tok = strtok (NULL, " \t");
 
489
          if (tok)
 
490
            g = atoi (tok);
 
491
          else
 
492
            g_message (_("Reading palette '%s': "
 
493
                         "Missing GREEN component in line %d."),
 
494
                       gimp_filename_to_utf8 (filename), linenum);
 
495
 
 
496
          tok = strtok (NULL, " \t");
 
497
          if (tok)
 
498
            b = atoi (tok);
 
499
          else
 
500
            g_message (_("Reading palette file '%s': "
 
501
                         "Missing BLUE component in line %d."),
 
502
                       gimp_filename_to_utf8 (filename), linenum);
 
503
 
 
504
          /* optional name */
 
505
          tok = strtok (NULL, "\n");
 
506
 
 
507
          if (r < 0 || r > 255 ||
 
508
              g < 0 || g > 255 ||
 
509
              b < 0 || b > 255)
 
510
            g_message (_("Reading palette file '%s': "
 
511
                         "RGB value out of range in line %d."),
 
512
                       gimp_filename_to_utf8 (filename), linenum);
 
513
 
 
514
          /* don't call gimp_palette_add_entry here, it's rather inefficient */
 
515
          entry = g_new0 (GimpPaletteEntry, 1);
 
516
 
 
517
          gimp_rgba_set_uchar (&entry->color,
 
518
                               (guchar) r,
 
519
                               (guchar) g,
 
520
                               (guchar) b,
 
521
                               255);
 
522
 
 
523
          entry->name     = g_strdup (tok ? tok : _("Untitled"));
 
524
          entry->position = palette->n_colors;
 
525
 
 
526
          palette->colors = g_list_prepend (palette->colors, entry);
 
527
          palette->n_colors++;
 
528
        }
 
529
 
 
530
      if (! fgets (str, sizeof (str), file))
 
531
        {
 
532
          if (feof (file))
 
533
            break;
 
534
 
 
535
          g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
 
536
                       _("Fatal parse error in palette file '%s': "
 
537
                         "Read error in line %d."),
 
538
                       gimp_filename_to_utf8 (filename), linenum);
 
539
          fclose (file);
 
540
          g_object_unref (palette);
 
541
          return NULL;
 
542
        }
 
543
 
 
544
      linenum++;
 
545
    }
 
546
 
 
547
  fclose (file);
 
548
 
 
549
  palette->colors = g_list_reverse (palette->colors);
 
550
 
 
551
  return g_list_prepend (NULL, palette);
 
552
}
 
553
 
 
554
static gboolean
 
555
gimp_palette_save (GimpData  *data,
 
556
                   GError   **error)
 
557
{
 
558
  GimpPalette *palette = GIMP_PALETTE (data);
 
559
  GList       *list;
 
560
  FILE        *file;
 
561
 
 
562
  file = fopen (data->filename, "w");
 
563
 
 
564
  if (! file)
 
565
    {
 
566
      g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_OPEN,
 
567
                   _("Could not open '%s' for writing: %s"),
 
568
                   gimp_filename_to_utf8 (data->filename),
 
569
                   g_strerror (errno));
 
570
      return FALSE;
 
571
    }
 
572
 
 
573
  fprintf (file, "GIMP Palette\n");
 
574
  fprintf (file, "Name: %s\n", GIMP_OBJECT (palette)->name);
 
575
  fprintf (file, "Columns: %d\n#\n", CLAMP (palette->n_columns, 0, 256));
 
576
 
 
577
  for (list = palette->colors; list; list = g_list_next (list))
 
578
    {
 
579
      GimpPaletteEntry *entry = list->data;
 
580
      guchar            r, g, b;
 
581
 
 
582
      gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
 
583
 
 
584
      fprintf (file, "%3d %3d %3d\t%s\n", r, g, b, entry->name);
 
585
    }
 
586
 
 
587
  fclose (file);
 
588
 
 
589
  return TRUE;
 
590
}
 
591
 
 
592
static gchar *
 
593
gimp_palette_get_extension (GimpData *data)
 
594
{
 
595
  return GIMP_PALETTE_FILE_EXTENSION;
 
596
}
 
597
 
 
598
static GimpData *
 
599
gimp_palette_duplicate (GimpData *data,
 
600
                        gboolean  stingy_memory_use)
 
601
{
 
602
  GimpPalette *palette = GIMP_PALETTE (data);
 
603
  GimpPalette *new;
 
604
  GList       *list;
 
605
 
 
606
  new = g_object_new (GIMP_TYPE_PALETTE, NULL);
 
607
 
 
608
  new->n_columns = palette->n_columns;
 
609
 
 
610
  for (list = palette->colors; list; list = g_list_next (list))
 
611
    {
 
612
      GimpPaletteEntry *entry = list->data;
 
613
 
 
614
      gimp_palette_add_entry (new, entry->name, &entry->color);
 
615
    }
 
616
 
 
617
  return GIMP_DATA (new);
 
618
}
 
619
 
 
620
GimpPaletteEntry *
 
621
gimp_palette_add_entry (GimpPalette   *palette,
 
622
                        const gchar   *name,
 
623
                        const GimpRGB *color)
 
624
{
 
625
  GimpPaletteEntry *entry;
 
626
 
 
627
  g_return_val_if_fail (GIMP_IS_PALETTE (palette), NULL);
 
628
  g_return_val_if_fail (color != NULL, NULL);
 
629
 
 
630
  entry = g_new0 (GimpPaletteEntry, 1);
 
631
 
 
632
  entry->color    = *color;
 
633
 
 
634
  entry->name     = g_strdup (name ? name : _("Untitled"));
 
635
  entry->position = palette->n_colors;
 
636
 
 
637
  palette->colors    = g_list_append (palette->colors, entry);
 
638
  palette->n_colors += 1;
 
639
 
 
640
  /*  will make the palette dirty too  */
 
641
  gimp_object_name_changed (GIMP_OBJECT (palette));
 
642
 
 
643
  return entry;
 
644
}
 
645
 
 
646
void
 
647
gimp_palette_delete_entry (GimpPalette      *palette,
 
648
                           GimpPaletteEntry *entry)
 
649
{
 
650
  GList *list;
 
651
  gint   pos = 0;
 
652
 
 
653
  g_return_if_fail (GIMP_IS_PALETTE (palette));
 
654
  g_return_if_fail (entry != NULL);
 
655
 
 
656
  if (g_list_find (palette->colors, entry))
 
657
    {
 
658
      pos = entry->position;
 
659
      gimp_palette_entry_free (entry);
 
660
 
 
661
      palette->colors = g_list_remove (palette->colors, entry);
 
662
 
 
663
      palette->n_colors--;
 
664
 
 
665
      for (list = g_list_nth (palette->colors, pos);
 
666
           list;
 
667
           list = g_list_next (list))
 
668
        {
 
669
          entry = (GimpPaletteEntry *) list->data;
 
670
 
 
671
          entry->position = pos++;
 
672
        }
 
673
 
 
674
      /*  will make the palette dirty too  */
 
675
      gimp_object_name_changed (GIMP_OBJECT (palette));
 
676
    }
 
677
}
 
678
 
 
679
void
 
680
gimp_palette_set_n_columns (GimpPalette *palette,
 
681
                            gint         n_columns)
 
682
{
 
683
  g_return_if_fail (GIMP_IS_PALETTE (palette));
 
684
 
 
685
  n_columns = CLAMP (n_columns, 0, 64);
 
686
 
 
687
  if (palette->n_columns != n_columns)
 
688
    {
 
689
      palette->n_columns = n_columns;
 
690
 
 
691
      gimp_data_dirty (GIMP_DATA (palette));
 
692
    }
 
693
}
 
694
 
 
695
gint
 
696
gimp_palette_get_n_columns  (GimpPalette *palette)
 
697
{
 
698
  g_return_val_if_fail (GIMP_IS_PALETTE (palette), 0);
 
699
 
 
700
  return palette->n_columns;
 
701
}
 
702
 
 
703
 
 
704
/*  private functions  */
 
705
 
 
706
static void
 
707
gimp_palette_entry_free (GimpPaletteEntry *entry)
 
708
{
 
709
  g_return_if_fail (entry != NULL);
 
710
 
 
711
  g_free (entry->name);
 
712
  g_free (entry);
 
713
}