about-dialog.c 22 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
18
19
20

#include "config.h"

Elliot Lee's avatar
Elliot Lee committed
21
22
#include <stdio.h>
#include <stdlib.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
23
#include <string.h>
Elliot Lee's avatar
Elliot Lee committed
24
#include <time.h>
Manish Singh's avatar
Manish Singh committed
25

26
#include <gtk/gtk.h>
Manish Singh's avatar
Manish Singh committed
27
#include <gdk/gdkkeysyms.h>
Manish Singh's avatar
Manish Singh committed
28

29
#include "libgimpmath/gimpmath.h"
30
#include "libgimpbase/gimpbase.h"
31
#include "libgimpwidgets/gimpwidgets.h"
32

33
#include "gui-types.h"
Sven Neumann's avatar
Sven Neumann committed
34

Michael Natterer's avatar
Michael Natterer committed
35
#include "core/gimptoolinfo.h"
36

37
#include "widgets/gimphelp-ids.h"
Michael Natterer's avatar
Michael Natterer committed
38
39
#include "widgets/gimpdnd.h"

40
#include "about-dialog.h"
Michael Natterer's avatar
Michael Natterer committed
41
#include "authors.h"
42

43
#include "gimp-intl.h"
44

45
46
47
48
49
50
51
52
53
54
55
56
static gchar *founders[] =
{
  N_("Version %s brought to you by"),
  "Spencer Kimball & Peter Mattis"
};

static gchar *translators[] =
{
  N_("Translation by"),
  N_("<Translator: insert your name here>"),
  N_("Contributions by")
};
57

58
59
60
61
62
63
typedef struct
{
  GtkWidget    *about_dialog;
  GtkWidget    *logo_area;
  GdkPixmap    *logo_pixmap;
  GdkRectangle  pixmaparea;
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  GdkRectangle  textarea;
  gdouble       text_size;
  gdouble       min_text_size;
  PangoLayout  *layout;
  PangoColor    foreground;
  PangoColor    background;

  gint          timer;

  gint          index;
  gboolean      visible;
  gint          textrange[2];
  gint          state;

} GimpAboutInfo;

PangoColor gradient[] =
{
    { 31868, 33153, 32382 },
    { 10000, 10000, 10000 },
    { 65535, 65535, 65535 },
};

static GimpAboutInfo about_info = { 0 };
89

90
91
static gboolean  about_dialog_load_logo   (GtkWidget      *window);
static void      about_dialog_destroy     (GtkObject      *object,
92
                                           gpointer        data);
93
static void      about_dialog_unmap       (GtkWidget      *widget,
94
                                           gpointer        data);
95
static gint      about_dialog_logo_expose (GtkWidget      *widget,
96
97
                                           GdkEventExpose *event,
                                           gpointer        data);
98
static gint      about_dialog_button      (GtkWidget      *widget,
99
100
                                           GdkEventButton *event,
                                           gpointer        data);
Manish Singh's avatar
Manish Singh committed
101
static gint      about_dialog_key         (GtkWidget      *widget,
102
103
                                           GdkEventKey    *event,
                                           gpointer        data);
104
static gboolean  about_dialog_timer       (gpointer        data);
Elliot Lee's avatar
Elliot Lee committed
105
106


107
static gboolean     double_speed     = FALSE;
Michael Natterer's avatar
Michael Natterer committed
108

109
static PangoFontDescription *font_desc = NULL;
110
111
112
static gchar      **scroll_text      = authors;
static gint         nscroll_texts    = G_N_ELEMENTS (authors);
static gint         shuffle_array[G_N_ELEMENTS (authors)];
113

Michael Natterer's avatar
Michael Natterer committed
114

115
GtkWidget *
116
about_dialog_create (void)
Elliot Lee's avatar
Elliot Lee committed
117
{
118
  GdkModifierType mask;
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
  if (! about_info.about_dialog)
    {
      GtkWidget *widget;

      about_info.textarea.x = 0;
      about_info.textarea.y = 265;
      about_info.textarea.width = 300;
      about_info.textarea.height = 60;

      about_info.foreground.red   = 65535;
      about_info.foreground.green = 65535;
      about_info.foreground.blue  = 65535;
      about_info.background.red   = 31868;
      about_info.background.green = 33153;
      about_info.background.blue  = 32382;

      about_info.visible = FALSE;
      about_info.state = 0;

      widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      about_info.about_dialog = widget;

      gtk_window_set_type_hint (GTK_WINDOW (widget),
                                GDK_WINDOW_TYPE_HINT_DIALOG);
      gtk_window_set_wmclass (GTK_WINDOW (widget), "about_dialog", "Gimp");
      gtk_window_set_title (GTK_WINDOW (widget), _("About The GIMP"));
      gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER);

      /* The window must not be resizeable, since otherwise
       * the copying of nonexisting parts of the image pixmap
       * would result in an endless loop due to the X-Server
       * generating expose events on the pixmap. */

      gtk_window_set_resizable (GTK_WINDOW (widget), FALSE);

      g_signal_connect (widget, "destroy",
                        G_CALLBACK (about_dialog_destroy),
                        NULL);
      g_signal_connect (widget, "unmap",
                        G_CALLBACK (about_dialog_unmap),
                        NULL);
      g_signal_connect (widget, "button_press_event",
                        G_CALLBACK (about_dialog_button),
                        NULL);
      g_signal_connect (widget, "key_press_event",
                        G_CALLBACK (about_dialog_key),
                        NULL);
      
      gtk_widget_set_events (widget, GDK_BUTTON_PRESS_MASK);

      if (! about_dialog_load_logo (widget))
        {
	  gtk_widget_destroy (widget);
	  about_info.about_dialog = NULL;
174
	  return NULL;
Elliot Lee's avatar
Elliot Lee committed
175
176
	}

177
178
      widget = gtk_drawing_area_new ();
      about_info.logo_area = widget;
Elliot Lee's avatar
Elliot Lee committed
179

180
181
182
183
184
185
186
      gtk_widget_set_size_request (widget,
                                   about_info.pixmaparea.width,
                                   about_info.pixmaparea.height);
      gtk_widget_set_events (widget, GDK_EXPOSURE_MASK);
      gtk_container_add (GTK_CONTAINER (about_info.about_dialog),
                         widget);
      gtk_widget_show (widget);
Elliot Lee's avatar
Elliot Lee committed
187

188
      g_signal_connect (widget, "expose_event",
189
190
191
			G_CALLBACK (about_dialog_logo_expose),
			NULL);

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
      gtk_widget_realize (widget);
      gdk_window_set_background (widget->window,
                                 &(widget->style)->black);

      about_info.layout = gtk_widget_create_pango_layout (about_info.logo_area, NULL);
      g_object_weak_ref (G_OBJECT (about_info.logo_area), 
                         (GWeakNotify) g_object_unref, about_info.layout);

      font_desc = pango_font_description_from_string ("Bitstream Vera Sans,"
                                                      "Trebuchet MS,"
                                                      "Helvetica,"
                                                      "Sans,"
                                                      "Bold 13");

      pango_layout_set_font_description (about_info.layout, font_desc);
      pango_layout_set_justify (about_info.layout, PANGO_ALIGN_CENTER);

Elliot Lee's avatar
Elliot Lee committed
209
210
    }

211
212
213
214
  /* for future enhancements */
  gdk_window_get_pointer (NULL, NULL, NULL, &mask);

  if (! GTK_WIDGET_VISIBLE (about_info.about_dialog))
Elliot Lee's avatar
Elliot Lee committed
215
    {
216
      if (! double_speed)
Elliot Lee's avatar
Elliot Lee committed
217
	{
218
	  GRand *gr = g_rand_new ();
219
          gint i;
220

221
	  for (i = 0; i < nscroll_texts; i++) 
222
223
224
	    {
	      shuffle_array[i] = i;
	    }
Elliot Lee's avatar
Elliot Lee committed
225

226
	  for (i = 0; i < nscroll_texts; i++) 
Elliot Lee's avatar
Elliot Lee committed
227
	    {
228
229
	      gint j;

230
	      j = g_rand_int_range (gr, 0, nscroll_texts);
231
	      if (i != j) 
232
233
234
235
236
237
238
		{
		  gint t;

		  t = shuffle_array[j];
		  shuffle_array[j] = shuffle_array[i];
		  shuffle_array[i] = t;
		}
Elliot Lee's avatar
Elliot Lee committed
239
	    }
240

241
          pango_layout_set_text (about_info.layout, "", -1);
242

243
	  g_rand_free (gr);
Elliot Lee's avatar
Elliot Lee committed
244
245
	}
    }
246

247
  gtk_window_present (GTK_WINDOW (about_info.about_dialog));
248

249
  return about_info.about_dialog;
Elliot Lee's avatar
Elliot Lee committed
250
251
}

252
static gboolean
Elliot Lee's avatar
Elliot Lee committed
253
254
about_dialog_load_logo (GtkWidget *window)
{
255
  gchar     *filename;
256
257
  GdkPixbuf *pixbuf;
  GdkGC     *gc;
258

259
  if (about_info.logo_pixmap)
Elliot Lee's avatar
Elliot Lee committed
260
261
    return TRUE;

262
  filename = g_build_filename (gimp_data_directory (), "images",
263
                               "gimp_logo.png", NULL);
Elliot Lee's avatar
Elliot Lee committed
264

265
266
  pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
  g_free (filename);
Elliot Lee's avatar
Elliot Lee committed
267

268
269
  if (! pixbuf)
    return FALSE;
Elliot Lee's avatar
Elliot Lee committed
270

271
272
273
274
  about_info.pixmaparea.x = 0;
  about_info.pixmaparea.y = 0;
  about_info.pixmaparea.width = gdk_pixbuf_get_width (pixbuf);
  about_info.pixmaparea.height = gdk_pixbuf_get_height (pixbuf);
Elliot Lee's avatar
Elliot Lee committed
275

276
  gtk_widget_realize (window);
Elliot Lee's avatar
Elliot Lee committed
277

278
279
280
  about_info.logo_pixmap = gdk_pixmap_new (window->window,
                                about_info.pixmaparea.width,
                                about_info.pixmaparea.height,
281
                                gtk_widget_get_visual (window)->depth);
Elliot Lee's avatar
Elliot Lee committed
282

283
  gc = gdk_gc_new (about_info.logo_pixmap);
Elliot Lee's avatar
Elliot Lee committed
284

285
286
287
288
289
  gdk_draw_pixbuf (GDK_DRAWABLE (about_info.logo_pixmap),
                   gc, pixbuf,
                   0, 0, 0, 0,
                   about_info.pixmaparea.width,
                   about_info.pixmaparea.height,
290
                   GDK_RGB_DITHER_NORMAL, 0, 0);
Elliot Lee's avatar
Elliot Lee committed
291

292
293
  g_object_unref (gc);
  g_object_unref (pixbuf);
Elliot Lee's avatar
Elliot Lee committed
294
295
296
297
298

  return TRUE;
}

static void
299
300
about_dialog_destroy (GtkObject *object,
		      gpointer   data)
Elliot Lee's avatar
Elliot Lee committed
301
{
302
  about_info.about_dialog = NULL;
303
  about_dialog_unmap (NULL, NULL);
Elliot Lee's avatar
Elliot Lee committed
304
305
306
}

static void
307
about_dialog_unmap (GtkWidget *widget,
308
                    gpointer   data)
Elliot Lee's avatar
Elliot Lee committed
309
{
310
  if (about_info.timer)
Elliot Lee's avatar
Elliot Lee committed
311
    {
312
313
      g_source_remove (about_info.timer);
      about_info.timer = 0;
Elliot Lee's avatar
Elliot Lee committed
314
315
316
    }
}

317
static gint
Elliot Lee's avatar
Elliot Lee committed
318
about_dialog_logo_expose (GtkWidget      *widget,
319
320
			  GdkEventExpose *event,
			  gpointer        data)
Elliot Lee's avatar
Elliot Lee committed
321
{
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  gint width, height;

  if (!about_info.timer)
    about_info.timer = g_timeout_add (30, about_dialog_timer, NULL);

  /* only operate on the region covered by the pixmap */
  if (! gdk_rectangle_intersect (&(about_info.pixmaparea),
                                 &(event->area),
                                 &(event->area)))
    return FALSE;

  gdk_gc_set_clip_rectangle (widget->style->black_gc, &(event->area));

  gdk_draw_drawable (widget->window,
                     widget->style->white_gc,
                     about_info.logo_pixmap,
                     event->area.x, event->area.y,
                     event->area.x, event->area.y,
                     event->area.width, event->area.height);

  if (about_info.visible == TRUE)
Elliot Lee's avatar
Elliot Lee committed
343
    {
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
      gint layout_x, layout_y;

      pango_layout_get_pixel_size (about_info.layout, &width, &height);

      layout_x = about_info.textarea.x +
                        (about_info.textarea.width - width) / 2;
      layout_y = about_info.textarea.y +
                        (about_info.textarea.height - height) / 2;
      
      if (about_info.textrange[1] > 0)
        {
          GdkRegion *covered_region = NULL;
          GdkRegion *rect_region;

          covered_region = gdk_pango_layout_get_clip_region
                              (about_info.layout,
                               layout_x, layout_y,
                               about_info.textrange, 1);

          rect_region = gdk_region_rectangle (&(event->area));

          gdk_region_intersect (covered_region, rect_region);
          gdk_region_destroy (rect_region);

          gdk_gc_set_clip_region (about_info.logo_area->style->text_gc[GTK_STATE_NORMAL],
                                  covered_region);
          gdk_region_destroy (covered_region);
        }

      gdk_draw_layout (widget->window,
                       widget->style->text_gc[GTK_STATE_NORMAL],
                       layout_x, layout_y,
                       about_info.layout);

Elliot Lee's avatar
Elliot Lee committed
378
379
    }

380
381
  gdk_gc_set_clip_rectangle (widget->style->black_gc, NULL);

Elliot Lee's avatar
Elliot Lee committed
382
383
384
  return FALSE;
}

385
static gint
Elliot Lee's avatar
Elliot Lee committed
386
about_dialog_button (GtkWidget      *widget,
387
388
		     GdkEventButton *event,
		     gpointer        data)
Elliot Lee's avatar
Elliot Lee committed
389
{
390
  gtk_widget_hide (about_info.about_dialog);
Elliot Lee's avatar
Elliot Lee committed
391
392
393
394

  return FALSE;
}

Manish Singh's avatar
Manish Singh committed
395
396
397
398
399
static gint
about_dialog_key (GtkWidget      *widget,
		  GdkEventKey    *event,
		  gpointer        data)
{
400
  /* placeholder */
Manish Singh's avatar
Manish Singh committed
401
402
403
404
  switch (event->keyval)
    {
    case GDK_a:
    case GDK_A:
405
406
    case GDK_b:
    case GDK_B:
Manish Singh's avatar
Manish Singh committed
407
    default:
408
        break;
Manish Singh's avatar
Manish Singh committed
409
    }
410
411
412
413
414
415
416
417
418
419
420
421
  
  return FALSE;
}

static gchar *
insert_spacers (const gchar *string)
{
  gchar *normalized, *ptr;
  gunichar unichr;
  GString *str;

  str = g_string_new (NULL);
Manish Singh's avatar
Manish Singh committed
422

423
424
425
426
  normalized = g_utf8_normalize (string, -1, G_NORMALIZE_DEFAULT_COMPOSE);
  ptr = normalized;

  while ((unichr = g_utf8_get_char (ptr)))
Manish Singh's avatar
Manish Singh committed
427
    {
428
429
430
431
      g_string_append_unichar (str, unichr);
      g_string_append_unichar (str, 0x200b);  /* ZERO WIDTH SPACE */
      ptr = g_utf8_next_char (ptr);
    }
432

433
  g_free (normalized);
434

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  return g_string_free (str, FALSE);
}

static void
mix_gradient (PangoColor *gradient, guint ncolors,
              PangoColor *target, gdouble pos)
{
  gint index;

  g_return_if_fail (gradient != NULL);
  g_return_if_fail (ncolors > 1);
  g_return_if_fail (target != NULL);
  g_return_if_fail (pos >= 0.0  &&  pos <= 1.0);

  if (pos == 1.0)
    {
      target->red   = gradient[ncolors-1].red;
      target->green = gradient[ncolors-1].green;
      target->blue  = gradient[ncolors-1].blue;
      return;
Manish Singh's avatar
Manish Singh committed
455
    }
456
457
458
459
460
461
462
  
  index = (int) floor (pos * (ncolors-1));
  pos = pos * (ncolors - 1) - index;

  target->red   = gradient[index].red   * (1.0 - pos) + gradient[index+1].red   * pos;
  target->green = gradient[index].green * (1.0 - pos) + gradient[index+1].green * pos;
  target->blue  = gradient[index].blue  * (1.0 - pos) + gradient[index+1].blue  * pos;
463

Manish Singh's avatar
Manish Singh committed
464
465
}

466
static void
467
468
469
mix_colors (PangoColor *start, PangoColor *end,
            PangoColor *target,
            gdouble pos)
470
{
471
472
473
474
475
476
477
478
479
  g_return_if_fail (start != NULL);
  g_return_if_fail (end != NULL);
  g_return_if_fail (target != NULL);
  g_return_if_fail (pos >= 0.0  &&  pos <= 1.0);

  target->red   = start->red   * (1.0 - pos) + end->red   * pos;
  target->green = start->green * (1.0 - pos) + end->green * pos;
  target->blue  = start->blue  * (1.0 - pos) + end->blue  * pos;
}
480

481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
static void
decorate_text (PangoLayout *layout, gint anim_type, gdouble time)
{
  gint letter_count = 0;
  gint text_length = 0;
  gint text_bytelen = 0;
  gint cluster_start, cluster_end;
  const gchar *text;
  const gchar *ptr;
  gunichar unichr;
  PangoAttrList *attrlist = NULL;
  PangoAttribute *attr;
  PangoRectangle irect = {0, 0, 0, 0};
  PangoRectangle lrect = {0, 0, 0, 0};
  PangoColor mix;

  mix_colors (&(about_info.background),
              &(about_info.foreground),
              &mix, time);

  text = pango_layout_get_text (layout);
  text_length = g_utf8_strlen (text, -1);
  text_bytelen = strlen (text);

  attrlist = pango_attr_list_new ();

  about_info.textrange[0] = 0;
  about_info.textrange[1] = text_bytelen;

  switch (anim_type)
  {
    case 0: /* Fade in */
      attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue);
      attr->start_index = 0;
      attr->end_index = text_bytelen;
      pango_attr_list_insert (attrlist, attr);
      break;

    case 1: /* Fade in, spread */
      attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue);
      attr->start_index = 0;
      attr->end_index = text_bytelen;
      pango_attr_list_change (attrlist, attr);

      ptr = text;

      cluster_start = 0;
      while ((unichr = g_utf8_get_char (ptr)))
        {
          ptr = g_utf8_next_char (ptr);
          cluster_end = (ptr - text);

          if (unichr == 0x200b)
            {
              lrect.width = (1.0 - time) * 15.0 * PANGO_SCALE + 0.5;
              attr = pango_attr_shape_new (&irect, &lrect);
              attr->start_index = cluster_start;
              attr->end_index = cluster_end;
              pango_attr_list_change (attrlist, attr);
            }
          cluster_start = cluster_end;
        }
      break;
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    case 2: /* Fade in, sinewave */
      attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue);
      attr->start_index = 0;
      attr->end_index = text_bytelen;
      pango_attr_list_change (attrlist, attr);

      ptr = text;

      cluster_start = 0;
      while ((unichr = g_utf8_get_char (ptr)))
        {
          if (unichr == 0x200b)
            {
              cluster_end = ptr - text;
              attr = pango_attr_rise_new ((1.0 -time) * 18000 *
                                          sin (4.0 * time +
                                               (float) letter_count * 0.7));
              attr->start_index = cluster_start;
              attr->end_index = cluster_end;
              pango_attr_list_change (attrlist, attr);

              letter_count++;
              cluster_start = cluster_end;
            }

          ptr = g_utf8_next_char (ptr);
        }
      break;
573

574
575
    case 3: /* letterwise Fade in */
      ptr = text;
576

577
578
579
580
581
582
      letter_count = 0;
      cluster_start = 0;
      while ((unichr = g_utf8_get_char (ptr)))
        {
          gint border;
          gdouble pos;
583

584
          border = (text_length + 15) * time - 15;
585

586
587
588
589
590
591
          if (letter_count < border)
            pos = 0;
          else if (letter_count > border + 15)
            pos = 1;
          else
            pos = ((gdouble) (letter_count - border)) / 15;
592

593
594
595
          mix_colors (&(about_info.foreground),
                      &(about_info.background),
                      &mix, pos);
596

597
          ptr = g_utf8_next_char (ptr);
598

599
          cluster_end = ptr - text;
600

601
602
603
604
          attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue);
          attr->start_index = cluster_start;
          attr->end_index = cluster_end;
          pango_attr_list_change (attrlist, attr);
605

606
607
          if (pos < 1.0)
            about_info.textrange[1] = cluster_end;
608

609
610
611
          letter_count++;
          cluster_start = cluster_end;
        }
612

613
      break;
614

615
616
    case 4: /* letterwise Fade in, triangular */
      ptr = text;
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
      letter_count = 0;
      cluster_start = 0;
      while ((unichr = g_utf8_get_char (ptr)))
        {
          gint border;
          gdouble pos;

          border = (text_length + 15) * time - 15;

          if (letter_count < border)
            pos = 1.0;
          else if (letter_count > border + 15)
            pos = 0.0;
          else
            pos = 1.0 - ((gdouble) (letter_count - border)) / 15;

          mix_gradient (gradient, G_N_ELEMENTS (gradient), &mix, pos);

          ptr = g_utf8_next_char (ptr);

          cluster_end = ptr - text;

          attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue);
          attr->start_index = cluster_start;
          attr->end_index = cluster_end;
          pango_attr_list_change (attrlist, attr);

          if (pos > 0.0)
            about_info.textrange[1] = cluster_end;
647

648
649
650
651
652
653
654
655
656
657
658
659
          letter_count++;
          cluster_start = cluster_end;
        }
      break;

    default:
      g_printerr ("Unknown animation type %d\n", anim_type);
  }

  
  pango_layout_set_attributes (layout, attrlist);
  pango_attr_list_unref (attrlist);
660

661
662
}

663
static gboolean
Elliot Lee's avatar
Elliot Lee committed
664
665
about_dialog_timer (gpointer data)
{
666
667
668
669
670
  static gint count = -1;
  gboolean return_val;
  gint width, height;
  gdouble size;
  gchar *text;
Elliot Lee's avatar
Elliot Lee committed
671
672
  return_val = TRUE;

673
  if (count == 0)
Elliot Lee's avatar
Elliot Lee committed
674
    {
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
      size = 13.0;
      text = NULL;
      if (about_info.state == 0)
        {
          about_info.visible = TRUE;
          if (about_info.index >= G_N_ELEMENTS (founders))
            {
              about_info.index = 0;
              about_info.state++;

              /* skip the translators section when the translator
               * did not provide a translation with his name
               */
              if (gettext (translators[1]) == translators[1])
                about_info.index = G_N_ELEMENTS (translators) - 1;
            }
          else
            {
              if (about_info.index == 0)
                {
                  gchar *tmp;
                  tmp = g_strdup_printf (gettext (founders[0]), GIMP_VERSION);
                  text = insert_spacers (tmp);
                  g_free (tmp);
                }
              else
                {
                  text = insert_spacers (gettext (founders[about_info.index]));
                }
              about_info.index++;
            }
        }
707

708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
      if (about_info.state == 1)
        {
          about_info.visible = TRUE;
          if (about_info.index >= G_N_ELEMENTS (translators))
            {
              about_info.index = 0;
              about_info.state++;
            }
          else
            {
              text = insert_spacers (gettext (translators[about_info.index]));
              about_info.index++;
            }
        }
      
      if (about_info.state == 2)
        {
          about_info.visible = TRUE;
        
          about_info.index += 1;
          if (about_info.index == nscroll_texts)
            about_info.index = 0;
        
          text = insert_spacers (scroll_text[shuffle_array[about_info.index]]);
        }
733

734
735
736
737
738
739
740
      if (text == NULL)
        {
          g_printerr ("TEXT == NULL\n");
          return TRUE;
        }
      pango_layout_set_text (about_info.layout, text, -1);
      pango_layout_set_attributes (about_info.layout, NULL);
Elliot Lee's avatar
Elliot Lee committed
741

742
743
      pango_font_description_set_size (font_desc, size * PANGO_SCALE);
      pango_layout_set_font_description (about_info.layout, font_desc);
Elliot Lee's avatar
Elliot Lee committed
744

745
      pango_layout_get_pixel_size (about_info.layout, &width, &height);
Elliot Lee's avatar
Elliot Lee committed
746

747
748
749
750
751
      while (width >= about_info.textarea.width && size >= 6.0)
        {
          size -= 0.5;
          pango_font_description_set_size (font_desc, size * PANGO_SCALE);
          pango_layout_set_font_description (about_info.layout, font_desc);
752

753
754
755
          pango_layout_get_pixel_size (about_info.layout, &width, &height);
        }
    }
Elliot Lee's avatar
Elliot Lee committed
756

757
  count++;
Elliot Lee's avatar
Elliot Lee committed
758

759
760
761
762
763
764
765
766
  if (count < 16)
    {
      decorate_text (about_info.layout, 4, ((float) count) / 15.0);
    }
  else if (count == 16)
    {
      about_info.timer = g_timeout_add (800, about_dialog_timer, NULL);
      return_val = FALSE;
Elliot Lee's avatar
Elliot Lee committed
767
    }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
  else if (count == 17)
    {
      about_info.timer = g_timeout_add (30, about_dialog_timer, NULL);
      return_val = FALSE;
    }
  else if (count < 33)
    {
      decorate_text (about_info.layout, 1, 1.0 - ((float) (count-17)) / 15.0);
    }
  else if (count == 33)
    {
      about_info.timer = g_timeout_add (300, about_dialog_timer, NULL);
      return_val = FALSE;
      about_info.visible = FALSE;
    }
  else
    {
      count = 0;
      about_info.timer = g_timeout_add (30, about_dialog_timer, NULL);
      return_val = FALSE;
      about_info.visible = FALSE;
    }

  gtk_widget_queue_draw_area (about_info.logo_area,
                              about_info.textarea.x,
                              about_info.textarea.y,
                              about_info.textarea.width,
                              about_info.textarea.height);
Elliot Lee's avatar
Elliot Lee committed
796
797
798

  return return_val;
}