1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  * Film plug-in (C) 1997 Peter Kirchgessner
4  * e-mail: pkirchg@aol.com, WWW: http://members.aol.com/pkirchg
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 /*
21  * This plug-in generates a film roll with several images
22  */
23 
24 #include "config.h"
25 
26 #include <string.h>
27 
28 #include <libgimp/gimp.h>
29 #include <libgimp/gimpui.h>
30 
31 #include "libgimp/stdplugins-intl.h"
32 
33 
34 #define PLUG_IN_PROC        "plug-in-film"
35 #define PLUG_IN_BINARY      "film"
36 #define PLUG_IN_ROLE        "gimp-film"
37 
38 /* Maximum number of pictures per film */
39 #define MAX_FILM_PICTURES   64
40 #define COLOR_BUTTON_WIDTH  50
41 #define COLOR_BUTTON_HEIGHT 20
42 
43 #define FONT_LEN            256
44 
45 /* Define how the plug-in works. Values marked (r) are with regard */
46 /* to film_height (i.e. it should be a value from 0.0 to 1.0) */
47 typedef struct
48 {
49   gint     film_height;           /* height of the film */
50   GimpRGB  film_color;            /* color of film */
51   gdouble  picture_height;        /* height of picture (r) */
52   gdouble  picture_space;         /* space between pictures (r) */
53   gdouble  hole_offset;           /* distance from hole to edge of film (r) */
54   gdouble  hole_width;            /* width of hole (r) */
55   gdouble  hole_height;           /* height of holes (r) */
56   gdouble  hole_space;            /* distance of holes (r) */
57   gdouble  number_height;         /* height of picture numbering (r) */
58   gint     number_start;          /* number for first picture */
59   GimpRGB  number_color;          /* color of number */
60   gchar    number_font[FONT_LEN]; /* font family to use for numbering */
61   gint     number_pos[2];         /* flags where to draw numbers (top/bottom) */
62   gint     keep_height;           /* flag if to keep max. image height */
63   gint     num_images;            /* number of images */
64   gint32   image[MAX_FILM_PICTURES]; /* list of image IDs */
65 } FilmVals;
66 
67 /* Data to use for the dialog */
68 typedef struct
69 {
70   GtkObject    *advanced_adj[7];
71   GtkTreeModel *image_list_all;
72   GtkTreeModel *image_list_film;
73 } FilmInterface;
74 
75 
76 /* Declare local functions
77  */
78 static void      query  (void);
79 static void      run    (const gchar      *name,
80                          gint              nparams,
81                          const GimpParam  *param,
82                          gint             *nreturn_vals,
83                          GimpParam       **return_vals);
84 
85 
86 static gint32    create_new_image   (const gchar    *filename,
87                                      guint           width,
88                                      guint           height,
89                                      GimpImageType   gdtype,
90                                      gint32         *layer_ID);
91 
92 static gchar   * compose_image_name (gint32          image_ID);
93 
94 static gint32    film               (void);
95 
96 static gboolean  check_filmvals     (void);
97 
98 static void      set_pixels         (gint            numpix,
99                                      guchar         *dst,
100                                      GimpRGB        *color);
101 
102 static guchar  * create_hole_rgb    (gint            width,
103                                      gint            height);
104 
105 static void      draw_number        (gint32          layer_ID,
106                                      gint            num,
107                                      gint            x,
108                                      gint            y,
109                                      gint            height);
110 
111 
112 static void        add_list_item_callback (GtkWidget        *widget,
113                                            GtkTreeSelection *sel);
114 static void        del_list_item_callback (GtkWidget        *widget,
115                                            GtkTreeSelection *sel);
116 
117 static GtkTreeModel * add_image_list      (gboolean        add_box_flag,
118                                            gint            n,
119                                            gint32         *image_id,
120                                            GtkWidget      *hbox);
121 
122 static gboolean    film_dialog               (gint32                image_ID);
123 static void        film_reset_callback       (GtkWidget            *widget,
124                                               gpointer              data);
125 static void        film_font_select_callback (GimpFontSelectButton *button,
126                                               const gchar          *name,
127                                               gboolean              closing,
128                                               gpointer              data);
129 
130 
131 const GimpPlugInInfo PLUG_IN_INFO =
132 {
133   NULL,  /* init_proc  */
134   NULL,  /* quit_proc  */
135   query, /* query_proc */
136   run,   /* run_proc   */
137 };
138 
139 static gdouble advanced_defaults[] =
140 {
141   0.695,           /* Picture height */
142   0.040,           /* Picture spacing */
143   0.058,           /* Hole offset to edge of film */
144   0.052,           /* Hole width */
145   0.081,           /* Hole height */
146   0.081,           /* Hole distance */
147   0.052            /* Image number height */
148 };
149 
150 static FilmVals filmvals =
151 {
152   256,             /* Height of film */
153   { 0.0, 0.0, 0.0, 1.0 }, /* Color of film */
154   0.695,           /* Picture height */
155   0.040,           /* Picture spacing */
156   0.058,           /* Hole offset to edge of film */
157   0.052,           /* Hole width */
158   0.081,           /* Hole height */
159   0.081,           /* Hole distance */
160   0.052,           /* Image number height */
161   1,               /* Start index of numbering */
162   { 0.93, 0.61, 0.0, 1.0 }, /* Color of number */
163   "Monospace",     /* Font family for numbering */
164   { TRUE, TRUE },  /* Numbering on top and bottom */
165   0,               /* Don't keep max. image height */
166   0,               /* Number of images */
167   { 0 }            /* Input image list */
168 };
169 
170 
171 static FilmInterface filmint =
172 {
173   { NULL },   /* advanced adjustments */
174   NULL, NULL  /* image list widgets */
175 };
176 
177 
178 static GimpRunMode run_mode;
179 
180 
MAIN()181 MAIN ()
182 
183 static void
184 query (void)
185 {
186   static const GimpParamDef args[] =
187   {
188     { GIMP_PDB_INT32,      "run-mode",     "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
189     { GIMP_PDB_IMAGE,      "image",        "Input image (only used as default image in interactive mode)" },
190     { GIMP_PDB_DRAWABLE,   "drawable",     "Input drawable (not used)" },
191     { GIMP_PDB_INT32,      "film-height",  "Height of film (0: fit to images)" },
192     { GIMP_PDB_COLOR,      "film-color",   "Color of the film" },
193     { GIMP_PDB_INT32,      "number-start", "Start index for numbering" },
194     { GIMP_PDB_STRING,     "number-font",  "Font for drawing numbers" },
195     { GIMP_PDB_COLOR,      "number-color", "Color for numbers" },
196     { GIMP_PDB_INT32,      "at-top",       "Flag for drawing numbers at top of film" },
197     { GIMP_PDB_INT32,      "at-bottom",    "Flag for drawing numbers at bottom of film" },
198     { GIMP_PDB_INT32,      "num-images",   "Number of images to be used for film" },
199     { GIMP_PDB_INT32ARRAY, "image-ids",    "num-images image IDs to be used for film" }
200   };
201 
202   static const GimpParamDef return_vals[] =
203   {
204     { GIMP_PDB_IMAGE, "new-image", "Output image" }
205   };
206 
207   gimp_install_procedure (PLUG_IN_PROC,
208                           N_("Combine several images on a film strip"),
209                           "Compose several images to a roll film",
210                           "Peter Kirchgessner",
211                           "Peter Kirchgessner (peter@kirchgessner.net)",
212                           "1997",
213                           N_("_Filmstrip..."),
214                           "INDEXED*, GRAY*, RGB*",
215                           GIMP_PLUGIN,
216                           G_N_ELEMENTS (args),
217                           G_N_ELEMENTS (return_vals),
218                           args, return_vals);
219 
220   gimp_plugin_menu_register (PLUG_IN_PROC, "<Image>/Filters/Combine");
221 }
222 
223 static void
run(const gchar * name,gint nparams,const GimpParam * param,gint * nreturn_vals,GimpParam ** return_vals)224 run (const gchar      *name,
225      gint              nparams,
226      const GimpParam  *param,
227      gint             *nreturn_vals,
228      GimpParam       **return_vals)
229 {
230   static GimpParam  values[2];
231   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
232   gint32            image_ID;
233   gint              k;
234 
235   INIT_I18N ();
236   gegl_init (NULL, NULL);
237 
238   run_mode = param[0].data.d_int32;
239 
240   *nreturn_vals = 2;
241   *return_vals  = values;
242 
243   values[0].type          = GIMP_PDB_STATUS;
244   values[0].data.d_status = status;
245   values[1].type          = GIMP_PDB_IMAGE;
246   values[1].data.d_int32  = -1;
247 
248   switch (run_mode)
249     {
250     case GIMP_RUN_INTERACTIVE:
251       /*  Possibly retrieve data  */
252       gimp_get_data (PLUG_IN_PROC, &filmvals);
253 
254       /*  First acquire information with a dialog  */
255       if (! film_dialog (param[1].data.d_int32))
256         return;
257       break;
258 
259     case GIMP_RUN_NONINTERACTIVE:
260       /*  Make sure all the arguments are there!  */
261       /* Also we want to have some images to compose */
262       if ((nparams != 12) || (param[10].data.d_int32 < 1))
263         {
264           status = GIMP_PDB_CALLING_ERROR;
265         }
266       else
267         {
268           filmvals.keep_height       = (param[3].data.d_int32 <= 0);
269           filmvals.film_height       = (filmvals.keep_height ?
270                                         128 : param[3].data.d_int32);
271           filmvals.film_color        = param[4].data.d_color;
272           filmvals.number_start      = param[5].data.d_int32;
273           g_strlcpy (filmvals.number_font, param[6].data.d_string, FONT_LEN);
274           filmvals.number_color      = param[7].data.d_color;
275           filmvals.number_pos[0]     = param[8].data.d_int32;
276           filmvals.number_pos[1]     = param[9].data.d_int32;
277           filmvals.num_images        = param[10].data.d_int32;
278           if (filmvals.num_images > MAX_FILM_PICTURES)
279             filmvals.num_images = MAX_FILM_PICTURES;
280           for (k = 0; k < filmvals.num_images; k++)
281             filmvals.image[k] = param[11].data.d_int32array[k];
282         }
283       break;
284 
285     case GIMP_RUN_WITH_LAST_VALS:
286       /*  Possibly retrieve data  */
287       gimp_get_data (PLUG_IN_PROC, &filmvals);
288       break;
289 
290     default:
291       break;
292     }
293 
294   if (! check_filmvals ())
295     status = GIMP_PDB_CALLING_ERROR;
296 
297   if (status == GIMP_PDB_SUCCESS)
298     {
299       gimp_progress_init (_("Composing images"));
300 
301       image_ID = film ();
302 
303       if (image_ID < 0)
304         {
305           status = GIMP_PDB_EXECUTION_ERROR;
306         }
307       else
308         {
309           values[1].data.d_int32 = image_ID;
310           gimp_image_undo_enable (image_ID);
311           gimp_image_clean_all (image_ID);
312           if (run_mode != GIMP_RUN_NONINTERACTIVE)
313             gimp_display_new (image_ID);
314         }
315 
316       /*  Store data  */
317       if (run_mode == GIMP_RUN_INTERACTIVE)
318         gimp_set_data (PLUG_IN_PROC, &filmvals, sizeof (FilmVals));
319     }
320 
321   values[0].data.d_status = status;
322 }
323 
324 /* Compose a roll film image from several images */
325 static gint32
film(void)326 film (void)
327 {
328   gint          width, height;
329   guchar       *hole;
330   gint          film_height, film_width;
331   gint          picture_width, picture_height;
332   gint          picture_space, picture_x0, picture_y0;
333   gint          hole_offset, hole_width, hole_height, hole_space, hole_x;
334   gint          number_height, num_images, num_pictures;
335   gint          j, k, picture_count;
336   gdouble       f;
337   gint          num_layers;
338   gint32       *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst;
339   gint          image_ID_tmp;
340   gint32       *layers;
341   gint          new_layer;
342   gint          floating_sel;
343 
344   /* initialize */
345 
346   layers = NULL;
347 
348   num_images = filmvals.num_images;
349   image_ID_src = filmvals.image;
350 
351   if (num_images <= 0)
352     return (-1);
353 
354   gimp_context_push ();
355   gimp_context_set_foreground (&filmvals.number_color);
356   gimp_context_set_background (&filmvals.film_color);
357 
358   if (filmvals.keep_height) /* Search maximum picture height */
359     {
360       picture_height = 0;
361       for (j = 0; j < num_images; j++)
362         {
363           height = gimp_image_height (image_ID_src[j]);
364           if (height > picture_height) picture_height = height;
365         }
366       film_height = (int)(picture_height / filmvals.picture_height + 0.5);
367       filmvals.film_height = film_height;
368     }
369   else
370     {
371       film_height = filmvals.film_height;
372       picture_height = (int)(film_height * filmvals.picture_height + 0.5);
373     }
374 
375   picture_space = (int)(film_height * filmvals.picture_space + 0.5);
376   picture_y0 = (film_height - picture_height)/2;
377 
378   number_height = film_height * filmvals.number_height;
379 
380   /* Calculate total film width */
381   film_width = 0;
382   num_pictures = 0;
383   for (j = 0; j < num_images; j++)
384     {
385       layers = gimp_image_get_layers (image_ID_src[j], &num_layers);
386       /* Get scaled image size */
387       width = gimp_image_width (image_ID_src[j]);
388       height = gimp_image_height (image_ID_src[j]);
389       f = ((double)picture_height) / (double)height;
390       picture_width = width * f;
391 
392       for (k = 0; k < num_layers; k++)
393         {
394           if (gimp_layer_is_floating_sel (layers[k]))
395             continue;
396 
397           film_width += (picture_space/2);  /* Leading space */
398           film_width += picture_width;      /* Scaled image width */
399           film_width += (picture_space/2);  /* Trailing space */
400           num_pictures++;
401         }
402 
403       g_free (layers);
404     }
405 
406 #ifdef FILM_DEBUG
407   g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width);
408   g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n",
409               picture_height, picture_space, picture_y0);
410   g_printerr ("Number of pictures = %d\n", num_pictures);
411 #endif
412 
413   image_ID_dst = create_new_image (_("Untitled"),
414                                    (guint) film_width, (guint) film_height,
415                                    GIMP_RGB_IMAGE, &layer_ID_dst);
416 
417   /* Fill film background */
418   gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND);
419 
420   /* Draw all the holes */
421   hole_offset = film_height * filmvals.hole_offset;
422   hole_width  = film_height * filmvals.hole_width;
423   hole_height = film_height * filmvals.hole_height;
424   hole_space  = film_height * filmvals.hole_space;
425   hole_x = hole_space / 2;
426 
427 #ifdef FILM_DEBUG
428   g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n",
429               hole_x, hole_offset, hole_width, hole_height, hole_space );
430 #endif
431 
432   hole = create_hole_rgb (hole_width, hole_height);
433   if (hole)
434     {
435       GeglBuffer *buffer = gimp_drawable_get_buffer (layer_ID_dst);
436 
437       while (hole_x < film_width)
438         {
439           gegl_buffer_set (buffer,
440                            GEGL_RECTANGLE (hole_x,
441                                            hole_offset,
442                                            hole_width,
443                                            hole_height), 0,
444                            babl_format ("R'G'B' u8"), hole,
445                            GEGL_AUTO_ROWSTRIDE);
446 
447           gegl_buffer_set (buffer,
448                            GEGL_RECTANGLE (hole_x,
449                                            film_height - hole_offset - hole_height,
450                                            hole_width,
451                                            hole_height), 0,
452                            babl_format ("R'G'B' u8"), hole,
453                            GEGL_AUTO_ROWSTRIDE);
454 
455           hole_x += hole_width + hole_space;
456         }
457 
458       g_object_unref (buffer);
459       g_free (hole);
460     }
461 
462   /* Compose all images and layers */
463   picture_x0 = 0;
464   picture_count = 0;
465   for (j = 0; j < num_images; j++)
466     {
467       image_ID_tmp = gimp_image_duplicate (image_ID_src[j]);
468       width = gimp_image_width (image_ID_tmp);
469       height = gimp_image_height (image_ID_tmp);
470       f = ((gdouble) picture_height) / (gdouble) height;
471       picture_width = width * f;
472       if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB)
473         gimp_image_convert_rgb (image_ID_tmp);
474       gimp_image_scale (image_ID_tmp, picture_width, picture_height);
475 
476       layers = gimp_image_get_layers (image_ID_tmp, &num_layers);
477       for (k = 0; k < num_layers; k++)
478         {
479           if (gimp_layer_is_floating_sel (layers[k]))
480             continue;
481 
482           picture_x0 += picture_space / 2;
483 
484           layer_ID_src = layers[k];
485           gimp_layer_resize_to_image_size (layer_ID_src);
486           new_layer = gimp_layer_new_from_drawable (layer_ID_src,
487                                                     image_ID_dst);
488           gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1);
489           gimp_layer_set_offsets (new_layer, picture_x0, picture_y0);
490 
491           /* Draw picture numbers */
492           if ((number_height > 0) &&
493               (filmvals.number_pos[0] || filmvals.number_pos[1]))
494             {
495               if (filmvals.number_pos[0])
496                 draw_number (layer_ID_dst,
497                              filmvals.number_start + picture_count,
498                              picture_x0 + picture_width/2,
499                              (hole_offset-number_height)/2, number_height);
500               if (filmvals.number_pos[1])
501                 draw_number (layer_ID_dst,
502                              filmvals.number_start + picture_count,
503                              picture_x0 + picture_width/2,
504                              film_height - (hole_offset + number_height)/2,
505                              number_height);
506             }
507 
508           picture_x0 += picture_width + (picture_space/2);
509 
510           gimp_progress_update (((gdouble) (picture_count + 1)) /
511                                 (gdouble) num_pictures);
512 
513           picture_count++;
514         }
515 
516       g_free (layers);
517       gimp_image_delete (image_ID_tmp);
518     }
519   gimp_progress_update (1.0);
520 
521   gimp_image_flatten (image_ID_dst);
522 
523   /* Drawing text/numbers leaves us with a floating selection. Stop it */
524   floating_sel = gimp_image_get_floating_sel (image_ID_dst);
525   if (floating_sel != -1)
526     gimp_floating_sel_anchor (floating_sel);
527 
528   gimp_context_pop ();
529 
530   return image_ID_dst;
531 }
532 
533 /* Check filmvals. Unreasonable values are reset to a default. */
534 /* If this is not possible, FALSE is returned. Otherwise TRUE is returned. */
535 static gboolean
check_filmvals(void)536 check_filmvals (void)
537 {
538   if (filmvals.film_height < 10)
539     filmvals.film_height = 10;
540 
541   if (filmvals.number_start < 0)
542     filmvals.number_start = 0;
543 
544   if (filmvals.number_font[0] == '\0')
545     strcpy (filmvals.number_font, "Monospace");
546 
547   if (filmvals.num_images < 1)
548     return FALSE;
549 
550   return TRUE;
551 }
552 
553 /* Assigns numpix pixels starting at dst with color r,g,b */
554 static void
set_pixels(gint numpix,guchar * dst,GimpRGB * color)555 set_pixels (gint     numpix,
556             guchar  *dst,
557             GimpRGB *color)
558 {
559   register gint   k;
560   register guchar ur, ug, ub, *udest;
561 
562   ur = color->r * 255.999;
563   ug = color->g * 255.999;
564   ub = color->b * 255.999;
565   k = numpix;
566   udest = dst;
567 
568   while (k-- > 0)
569     {
570       *(udest++) = ur;
571       *(udest++) = ug;
572       *(udest++) = ub;
573     }
574 }
575 
576 /* Create the RGB-pixels that make up the hole */
577 static guchar *
create_hole_rgb(gint width,gint height)578 create_hole_rgb (gint width,
579                  gint height)
580 {
581   guchar *hole, *top, *bottom;
582   gint    radius, length, k;
583 
584   hole = g_new (guchar, width * height * 3);
585 
586   /* Fill a rectangle with white */
587   memset (hole, 255, width * height * 3);
588   radius = height / 4;
589   if (radius > width / 2)
590     radius = width / 2;
591   top = hole;
592   bottom = hole + (height-1)*width*3;
593   for (k = radius-1; k > 0; k--)  /* Rounding corners */
594     {
595       length = (int)(radius - sqrt ((gdouble) (radius * radius - k * k))
596                      - 0.5);
597       if (length > 0)
598         {
599           set_pixels (length, top, &filmvals.film_color);
600           set_pixels (length, top + (width-length)*3, &filmvals.film_color);
601           set_pixels (length, bottom, &filmvals.film_color);
602           set_pixels (length, bottom + (width-length)*3, &filmvals.film_color);
603         }
604       top += width*3;
605       bottom -= width*3;
606     }
607 
608   return hole;
609 }
610 
611 /* Draw the number of the picture onto the film */
612 static void
draw_number(gint32 layer_ID,gint num,gint x,gint y,gint height)613 draw_number (gint32 layer_ID,
614              gint   num,
615              gint   x,
616              gint   y,
617              gint   height)
618 {
619   gchar         buf[32];
620   gint          k, delta, max_delta;
621   gint32        image_ID;
622   gint32        text_layer_ID;
623   gint          text_width, text_height, text_ascent, descent;
624   gchar        *fontname = filmvals.number_font;
625 
626   g_snprintf (buf, sizeof (buf), "%d", num);
627 
628   image_ID = gimp_item_get_image (layer_ID);
629 
630   max_delta = height / 10;
631   if (max_delta < 1)
632     max_delta = 1;
633 
634   /* Numbers don't need the descent. Inquire it and move the text down */
635   for (k = 0; k < max_delta * 2 + 1; k++)
636     {
637       /* Try different font sizes if inquire of extent failed */
638       gboolean success;
639 
640       delta = (k+1) / 2;
641 
642       if ((k & 1) == 0)
643         delta = -delta;
644 
645       success = gimp_text_get_extents_fontname (buf,
646                                                 height + delta, GIMP_PIXELS,
647                                                 fontname,
648                                                 &text_width, &text_height,
649                                                 &text_ascent, &descent);
650 
651       if (success)
652         {
653           height += delta;
654           break;
655         }
656     }
657 
658   text_layer_ID = gimp_text_fontname (image_ID, layer_ID,
659                                       x, y + descent / 2,
660                                       buf, 1, FALSE,
661                                       height, GIMP_PIXELS,
662                                       fontname);
663 
664   if (text_layer_ID == -1)
665     g_message ("draw_number: Error in drawing text\n");
666 }
667 
668 /* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
669 static gint32
create_new_image(const gchar * filename,guint width,guint height,GimpImageType gdtype,gint32 * layer_ID)670 create_new_image (const gchar    *filename,
671                   guint           width,
672                   guint           height,
673                   GimpImageType   gdtype,
674                   gint32         *layer_ID)
675 {
676   gint32            image_ID;
677   GimpImageBaseType gitype;
678 
679   if ((gdtype == GIMP_GRAY_IMAGE) || (gdtype == GIMP_GRAYA_IMAGE))
680     gitype = GIMP_GRAY;
681   else if ((gdtype == GIMP_INDEXED_IMAGE) || (gdtype == GIMP_INDEXEDA_IMAGE))
682     gitype = GIMP_INDEXED;
683   else
684     gitype = GIMP_RGB;
685 
686   image_ID = gimp_image_new (width, height, gitype);
687   gimp_image_set_filename (image_ID, filename);
688 
689   gimp_image_undo_disable (image_ID);
690   *layer_ID = gimp_layer_new (image_ID, _("Background"), width, height,
691                               gdtype,
692                               100,
693                               gimp_image_get_default_new_layer_mode (image_ID));
694   gimp_image_insert_layer (image_ID, *layer_ID, -1, 0);
695 
696   return image_ID;
697 }
698 
699 static gchar *
compose_image_name(gint32 image_ID)700 compose_image_name (gint32 image_ID)
701 {
702   gchar *image_name;
703   gchar *name;
704 
705   /* Compose a name of the basename and the image-ID */
706 
707   name = gimp_image_get_name (image_ID);
708 
709   image_name = g_strdup_printf ("%s-%d", name, image_ID);
710 
711   g_free (name);
712 
713   return image_name;
714 }
715 
716 static void
add_list_item_callback(GtkWidget * widget,GtkTreeSelection * sel)717 add_list_item_callback (GtkWidget        *widget,
718                         GtkTreeSelection *sel)
719 {
720   GtkTreeModel *model;
721   GList        *paths;
722   GList        *list;
723 
724   paths = gtk_tree_selection_get_selected_rows (sel, &model);
725 
726   for (list = paths; list; list = g_list_next (list))
727     {
728       GtkTreeIter iter;
729 
730       if (gtk_tree_model_get_iter (model, &iter, list->data))
731         {
732           gint32  image_ID;
733           gchar  *name;
734 
735           gtk_tree_model_get (model, &iter,
736                               0, &image_ID,
737                               1, &name,
738                               -1);
739 
740           gtk_list_store_append (GTK_LIST_STORE (filmint.image_list_film),
741                                  &iter);
742 
743           gtk_list_store_set (GTK_LIST_STORE (filmint.image_list_film),
744                               &iter,
745                               0, image_ID,
746                               1, name,
747                               -1);
748 
749           g_free (name);
750         }
751 
752       gtk_tree_path_free (list->data);
753     }
754 
755   g_list_free (paths);
756 }
757 
758 static void
del_list_item_callback(GtkWidget * widget,GtkTreeSelection * sel)759 del_list_item_callback (GtkWidget        *widget,
760                         GtkTreeSelection *sel)
761 {
762   GtkTreeModel *model;
763   GList        *paths;
764   GList        *references = NULL;
765   GList        *list;
766 
767   paths = gtk_tree_selection_get_selected_rows (sel, &model);
768 
769   for (list = paths; list; list = g_list_next (list))
770     {
771       GtkTreeRowReference *ref;
772 
773       ref = gtk_tree_row_reference_new (model, list->data);
774       references = g_list_prepend (references, ref);
775       gtk_tree_path_free (list->data);
776     }
777 
778   g_list_free (paths);
779 
780   for (list = references; list; list = g_list_next (list))
781     {
782       GtkTreePath *path;
783       GtkTreeIter  iter;
784 
785       path = gtk_tree_row_reference_get_path (list->data);
786 
787       if (gtk_tree_model_get_iter (model, &iter, path))
788         gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
789 
790       gtk_tree_path_free (path);
791       gtk_tree_row_reference_free (list->data);
792     }
793 
794   g_list_free (references);
795 }
796 
797 static GtkTreeModel *
add_image_list(gboolean add_box_flag,gint n,gint32 * image_id,GtkWidget * hbox)798 add_image_list (gboolean   add_box_flag,
799                 gint       n,
800                 gint32    *image_id,
801                 GtkWidget *hbox)
802 {
803   GtkWidget        *vbox;
804   GtkWidget        *label;
805   GtkWidget        *scrolled_win;
806   GtkWidget        *tv;
807   GtkWidget        *button;
808   GtkListStore     *store;
809   GtkTreeSelection *sel;
810   gint              i;
811 
812   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
813   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
814   gtk_widget_show (vbox);
815 
816   label = gtk_label_new (add_box_flag ?
817                          _("Available images:") :
818                          _("On film:"));
819   gtk_label_set_xalign (GTK_LABEL (label), 0.0);
820   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
821   gtk_widget_show (label);
822 
823   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
824   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
825                                        GTK_SHADOW_IN);
826   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
827                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
828   gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
829   gtk_widget_show (scrolled_win);
830 
831   store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
832   tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
833   g_object_unref (store);
834 
835   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), FALSE);
836 
837   if (! add_box_flag)
838     gtk_tree_view_set_reorderable (GTK_TREE_VIEW (tv), TRUE);
839 
840   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), 0, NULL,
841                                                gtk_cell_renderer_text_new (),
842                                                "text", 1,
843                                                NULL);
844 
845   gtk_container_add (GTK_CONTAINER (scrolled_win), tv);
846   gtk_widget_show (tv);
847 
848   sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
849   gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE);
850 
851   for (i = 0; i < n; i++)
852     {
853       GtkTreeIter  iter;
854       gchar       *name;
855 
856       gtk_list_store_append (store, &iter);
857 
858       name = compose_image_name (image_id[i]);
859 
860       gtk_list_store_set (store, &iter,
861                           0, image_id[i],
862                           1, name,
863                           -1);
864 
865       g_free (name);
866     }
867 
868   button = gtk_button_new_with_mnemonic (add_box_flag ?
869                                          _("_Add") : _("_Remove"));
870   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
871   gtk_widget_show (button);
872 
873   g_signal_connect (button, "clicked",
874                     add_box_flag ?
875                     G_CALLBACK (add_list_item_callback) :
876                     G_CALLBACK (del_list_item_callback),
877                     sel);
878 
879   return GTK_TREE_MODEL (store);
880 }
881 
882 static void
create_selection_tab(GtkWidget * notebook,gint32 image_ID)883 create_selection_tab (GtkWidget *notebook,
884                       gint32     image_ID)
885 {
886   GimpColorConfig *config;
887   GtkSizeGroup    *group;
888   GtkWidget       *vbox;
889   GtkWidget       *vbox2;
890   GtkWidget       *hbox;
891   GtkWidget       *table;
892   GtkWidget       *label;
893   GtkWidget       *frame;
894   GtkWidget       *toggle;
895   GtkWidget       *spinbutton;
896   GtkAdjustment   *adj;
897   GtkWidget       *button;
898   GtkWidget       *font_button;
899   gint32          *image_id_list;
900   gint             nimages, j;
901 
902   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
903   gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
904   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), hbox,
905                             gtk_label_new_with_mnemonic (_("Selection")));
906   gtk_widget_show (hbox);
907 
908   vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
909   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
910   gtk_widget_show (vbox2);
911 
912   group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
913 
914   /* Film height/color */
915   frame = gimp_frame_new (_("Filmstrip"));
916   gtk_box_pack_start (GTK_BOX (vbox2), frame, FALSE, FALSE, 0);
917   gtk_widget_show (frame);
918 
919   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
920   gtk_container_add (GTK_CONTAINER (frame), vbox);
921   gtk_widget_show (vbox);
922 
923   /* Keep maximum image height */
924   toggle = gtk_check_button_new_with_mnemonic (_("_Fit height to images"));
925   gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
926   gtk_widget_show (toggle);
927 
928   g_signal_connect (toggle, "toggled",
929                     G_CALLBACK (gimp_toggle_button_update),
930                     &filmvals.keep_height);
931 
932   table = gtk_table_new (2, 2, FALSE);
933   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
934   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
935   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
936   gtk_widget_show (table);
937 
938   /* Film height */
939   adj = GTK_ADJUSTMENT (gtk_adjustment_new (filmvals.film_height, 10,
940                                             GIMP_MAX_IMAGE_SIZE, 1, 10, 0));
941   spinbutton = gimp_spin_button_new (adj, 1, 0);
942   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
943 
944   label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
945                                      _("_Height:"), 0.0, 0.5,
946                                      spinbutton, 1, TRUE);
947   gtk_size_group_add_widget (group, label);
948   g_object_unref (group);
949 
950   g_signal_connect (adj, "value-changed",
951                     G_CALLBACK (gimp_int_adjustment_update),
952                     &filmvals.film_height);
953 
954   g_object_bind_property (toggle,     "active",
955                           spinbutton, "sensitive",
956                           G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
957   g_object_bind_property (toggle,     "active",
958                           /* FIXME: eeeeeek */
959                           g_list_nth_data (gtk_container_get_children (GTK_CONTAINER (table)), 1), "sensitive",
960                           G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
961 
962   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
963                                 filmvals.keep_height);
964 
965   /* Film color */
966   button = gimp_color_button_new (_("Select Film Color"),
967                                   COLOR_BUTTON_WIDTH, COLOR_BUTTON_HEIGHT,
968                                   &filmvals.film_color,
969                                   GIMP_COLOR_AREA_FLAT);
970   label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
971                                      _("Co_lor:"), 0.0, 0.5,
972                                      button, 1, FALSE);
973   gtk_size_group_add_widget (group, label);
974 
975   g_signal_connect (button, "color-changed",
976                     G_CALLBACK (gimp_color_button_get_color),
977                     &filmvals.film_color);
978 
979   config = gimp_get_color_configuration ();
980   gimp_color_button_set_color_config (GIMP_COLOR_BUTTON (button), config);
981 
982   /* Film numbering: Startindex/Font/color */
983   frame = gimp_frame_new (_("Numbering"));
984   gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0);
985   gtk_widget_show (frame);
986 
987   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
988   gtk_container_add (GTK_CONTAINER (frame), vbox);
989   gtk_widget_show (vbox);
990 
991   table = gtk_table_new (3, 2, FALSE);
992   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
993   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
994   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
995   gtk_widget_show (table);
996 
997   /* Startindex */
998   adj = GTK_ADJUSTMENT (gtk_adjustment_new (filmvals.number_start, 0,
999                                             GIMP_MAX_IMAGE_SIZE, 1, 10, 0));
1000   spinbutton = gimp_spin_button_new (adj, 1, 0);
1001   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
1002 
1003   label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
1004                                      _("Start _index:"), 0.0, 0.5,
1005                                      spinbutton, 1, TRUE);
1006   gtk_size_group_add_widget (group, label);
1007 
1008   g_signal_connect (adj, "value-changed",
1009                     G_CALLBACK (gimp_int_adjustment_update),
1010                     &filmvals.number_start);
1011 
1012   /* Fontfamily for numbering */
1013   font_button = gimp_font_select_button_new (NULL, filmvals.number_font);
1014   g_signal_connect (font_button, "font-set",
1015                     G_CALLBACK (film_font_select_callback), &filmvals);
1016   label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
1017                                      _("_Font:"), 0.0, 0.5,
1018                                      font_button, 1, FALSE);
1019   gtk_size_group_add_widget (group, label);
1020 
1021   /* Numbering color */
1022   button = gimp_color_button_new (_("Select Number Color"),
1023                                   COLOR_BUTTON_WIDTH, COLOR_BUTTON_HEIGHT,
1024                                   &filmvals.number_color,
1025                                   GIMP_COLOR_AREA_FLAT);
1026   label = gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
1027                                      _("Co_lor:"), 0.0, 0.5,
1028                                      button, 1, FALSE);
1029   gtk_size_group_add_widget (group, label);
1030 
1031   g_signal_connect (button, "color-changed",
1032                     G_CALLBACK (gimp_color_button_get_color),
1033                     &filmvals.number_color);
1034 
1035   gimp_color_button_set_color_config (GIMP_COLOR_BUTTON (button), config);
1036   g_object_unref (config);
1037 
1038   for (j = 0; j < 2; j++)
1039     {
1040       toggle = gtk_check_button_new_with_mnemonic (j ? _("At _bottom")
1041                                                    : _("At _top"));
1042       gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
1043       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle),
1044                                     filmvals.number_pos[j]);
1045       gtk_widget_show (toggle);
1046 
1047       g_signal_connect (toggle, "toggled",
1048                         G_CALLBACK (gimp_toggle_button_update),
1049                         &filmvals.number_pos[j]);
1050     }
1051 
1052 
1053   /*** The right frame keeps the image selection ***/
1054   frame = gimp_frame_new (_("Image Selection"));
1055   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
1056   gtk_widget_show (frame);
1057 
1058   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1059   gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
1060   gtk_container_add (GTK_CONTAINER (frame), hbox);
1061 
1062   /* Get a list of all image names */
1063   image_id_list = gimp_image_list (&nimages);
1064   filmint.image_list_all = add_image_list (TRUE, nimages, image_id_list, hbox);
1065 
1066   /* Get a list of the images used for the film */
1067   filmint.image_list_film = add_image_list (FALSE, 1, &image_ID, hbox);
1068 
1069   gtk_widget_show (hbox);
1070 }
1071 
1072 static void
create_advanced_tab(GtkWidget * notebook)1073 create_advanced_tab (GtkWidget *notebook)
1074 {
1075   GtkWidget *vbox;
1076   GtkWidget *hbox;
1077   GtkWidget *table;
1078   GtkWidget *frame;
1079   GtkObject *adj;
1080   GtkWidget *button;
1081   gint       row;
1082 
1083   frame = gimp_frame_new (_("All Values are Fractions of the Strip Height"));
1084   gtk_container_set_border_width (GTK_CONTAINER (frame), 12);
1085   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame,
1086                             gtk_label_new_with_mnemonic (_("Ad_vanced")));
1087   gtk_widget_show (frame);
1088 
1089   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
1090   gtk_container_add (GTK_CONTAINER (frame), vbox);
1091   gtk_widget_show (vbox);
1092 
1093   table = gtk_table_new (7, 3, FALSE);
1094   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1095   gtk_table_set_col_spacings (GTK_TABLE (table), 6);
1096   gtk_table_set_row_spacing (GTK_TABLE (table), 1, 12);
1097   gtk_table_set_row_spacing (GTK_TABLE (table), 5, 12);
1098   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
1099   gtk_widget_show (table);
1100 
1101   row = 0;
1102 
1103   filmint.advanced_adj[0] = adj =
1104     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1105                           _("Image _height:"), 0, 0,
1106                           filmvals.picture_height,
1107                           0.0, 1.0, 0.001, 0.01, 3,
1108                           TRUE, 0, 0,
1109                           NULL, NULL);
1110   g_signal_connect (adj, "value-changed",
1111                     G_CALLBACK (gimp_double_adjustment_update),
1112                     &filmvals.picture_height);
1113 
1114   filmint.advanced_adj[1] = adj =
1115     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1116                           _("Image spac_ing:"), 0, 0,
1117                           filmvals.picture_space,
1118                           0.0, 1.0, 0.001, 0.01, 3,
1119                           TRUE, 0, 0,
1120                           NULL, NULL);
1121   g_signal_connect (adj, "value-changed",
1122                     G_CALLBACK (gimp_double_adjustment_update),
1123                     &filmvals.picture_space);
1124 
1125   filmint.advanced_adj[2] = adj =
1126     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1127                           _("_Hole offset:"), 0, 0,
1128                           filmvals.hole_offset,
1129                           0.0, 1.0, 0.001, 0.01, 3,
1130                           TRUE, 0, 0,
1131                           NULL, NULL);
1132   g_signal_connect (adj, "value-changed",
1133                     G_CALLBACK (gimp_double_adjustment_update),
1134                     &filmvals.hole_offset);
1135 
1136   filmint.advanced_adj[3] = adj =
1137     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1138                           _("Ho_le width:"), 0, 0,
1139                           filmvals.hole_width,
1140                           0.0, 1.0, 0.001, 0.01, 3,
1141                           TRUE, 0, 0,
1142                           NULL, NULL);
1143   g_signal_connect (adj, "value-changed",
1144                     G_CALLBACK (gimp_double_adjustment_update),
1145                     &filmvals.hole_width);
1146 
1147   filmint.advanced_adj[4] = adj =
1148     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1149                           _("Hol_e height:"), 0, 0,
1150                           filmvals.hole_height,
1151                           0.0, 1.0, 0.001, 0.01, 3,
1152                           TRUE, 0, 0,
1153                           NULL, NULL);
1154   g_signal_connect (adj, "value-changed",
1155                     G_CALLBACK (gimp_double_adjustment_update),
1156                     &filmvals.hole_height);
1157 
1158   filmint.advanced_adj[5] = adj =
1159     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1160                           _("Hole sp_acing:"), 0, 0,
1161                           filmvals.hole_space,
1162                           0.0, 1.0, 0.001, 0.01, 3,
1163                           TRUE, 0, 0,
1164                           NULL, NULL);
1165   g_signal_connect (adj, "value-changed",
1166                     G_CALLBACK (gimp_double_adjustment_update),
1167                     &filmvals.hole_space);
1168 
1169   filmint.advanced_adj[6] = adj =
1170     gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
1171                           _("_Number height:"), 0, 0,
1172                           filmvals.number_height,
1173                           0.0, 1.0, 0.001, 0.01, 3,
1174                           TRUE, 0, 0,
1175                           NULL, NULL);
1176   g_signal_connect (adj, "value-changed",
1177                     G_CALLBACK (gimp_double_adjustment_update),
1178                     &filmvals.number_height);
1179 
1180   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1181   gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1182   gtk_widget_show (hbox);
1183 
1184   button = gtk_button_new_with_mnemonic (_("Re_set"));
1185   gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
1186   gtk_widget_show (button);
1187 
1188   g_signal_connect (button, "clicked",
1189                     G_CALLBACK (film_reset_callback),
1190                     NULL);
1191 }
1192 
1193 static gboolean
film_dialog(gint32 image_ID)1194 film_dialog (gint32 image_ID)
1195 {
1196   GtkWidget *dlg;
1197   GtkWidget *main_vbox;
1198   GtkWidget *notebook;
1199   gboolean   run;
1200 
1201   gimp_ui_init (PLUG_IN_BINARY, TRUE);
1202 
1203   dlg = gimp_dialog_new (_("Filmstrip"), PLUG_IN_ROLE,
1204                          NULL, 0,
1205                          gimp_standard_help_func, PLUG_IN_PROC,
1206 
1207                          _("_Cancel"), GTK_RESPONSE_CANCEL,
1208                          _("_OK"),     GTK_RESPONSE_OK,
1209 
1210                          NULL);
1211 
1212   gtk_dialog_set_alternative_button_order (GTK_DIALOG (dlg),
1213                                            GTK_RESPONSE_OK,
1214                                            GTK_RESPONSE_CANCEL,
1215                                            -1);
1216 
1217   gimp_window_set_transient (GTK_WINDOW (dlg));
1218 
1219   main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
1220   gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
1221   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
1222                       main_vbox, TRUE, TRUE, 0);
1223   gtk_widget_show (main_vbox);
1224 
1225   notebook = gtk_notebook_new ();
1226   gtk_box_pack_start (GTK_BOX (main_vbox), notebook, TRUE, TRUE, 0);
1227 
1228   create_selection_tab (notebook, image_ID);
1229   create_advanced_tab (notebook);
1230 
1231   gtk_widget_show (notebook);
1232 
1233   gtk_widget_show (dlg);
1234 
1235   run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
1236 
1237   if (run)
1238     {
1239       gint        num_images = 0;
1240       gboolean    iter_valid;
1241       GtkTreeIter iter;
1242 
1243       for (iter_valid = gtk_tree_model_get_iter_first (filmint.image_list_film,
1244                                                        &iter);
1245            iter_valid;
1246            iter_valid = gtk_tree_model_iter_next (filmint.image_list_film,
1247                                                   &iter))
1248         {
1249           gint image_ID;
1250 
1251           gtk_tree_model_get (filmint.image_list_film, &iter,
1252                               0, &image_ID,
1253                               -1);
1254 
1255           if ((image_ID >= 0) && (num_images < MAX_FILM_PICTURES))
1256             filmvals.image[num_images++] = image_ID;
1257         }
1258 
1259       filmvals.num_images = num_images;
1260     }
1261 
1262   gtk_widget_destroy (dlg);
1263 
1264   return run;
1265 }
1266 
1267 static void
film_reset_callback(GtkWidget * widget,gpointer data)1268 film_reset_callback (GtkWidget *widget,
1269                      gpointer   data)
1270 {
1271   gint i;
1272 
1273   for (i = 0; i < G_N_ELEMENTS (advanced_defaults) ; i++)
1274     gtk_adjustment_set_value (GTK_ADJUSTMENT (filmint.advanced_adj[i]),
1275                               advanced_defaults[i]);
1276 }
1277 
1278 static void
film_font_select_callback(GimpFontSelectButton * button,const gchar * name,gboolean closing,gpointer data)1279 film_font_select_callback (GimpFontSelectButton *button,
1280                            const gchar          *name,
1281                            gboolean              closing,
1282                            gpointer              data)
1283 {
1284   FilmVals *vals = (FilmVals *) data;
1285 
1286   g_strlcpy (vals->number_font, name, FONT_LEN);
1287 }
1288