~ubuntu-branches/ubuntu/trusty/evince/trusty-proposed

« back to all changes in this revision

Viewing changes to shell/ev-transition-animation.c

Tags: upstream-2.21.90
ImportĀ upstreamĀ versionĀ 2.21.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ev-transition-animation.c
 
2
 *  this file is part of evince, a gnome document viewer
 
3
 *
 
4
 * Copyright (C) 2007 Carlos Garnacho <carlos@imendio.com>
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Library General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library 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 GNU
 
14
 * Library General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Library General Public
 
17
 * License along with this library; if not, write to the
 
18
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
19
 * Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <cairo.h>
 
23
#include <gdk/gdk.h>
 
24
#include "ev-transition-animation.h"
 
25
#include "ev-timeline.h"
 
26
 
 
27
#define EV_TRANSITION_ANIMATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_TRANSITION_ANIMATION, EvTransitionAnimationPriv))
 
28
#define N_BLINDS 6
 
29
 
 
30
typedef struct EvTransitionAnimationPriv EvTransitionAnimationPriv;
 
31
 
 
32
struct EvTransitionAnimationPriv {
 
33
        EvTransitionEffect *effect;
 
34
        cairo_surface_t *origin_surface;
 
35
        cairo_surface_t *dest_surface;
 
36
};
 
37
 
 
38
enum {
 
39
        PROP_0,
 
40
        PROP_EFFECT,
 
41
        PROP_ORIGIN_SURFACE,
 
42
        PROP_DEST_SURFACE
 
43
};
 
44
 
 
45
 
 
46
G_DEFINE_TYPE (EvTransitionAnimation, ev_transition_animation, EV_TYPE_TIMELINE)
 
47
 
 
48
 
 
49
static void
 
50
ev_transition_animation_init (EvTransitionAnimation *animation)
 
51
{
 
52
}
 
53
 
 
54
static void
 
55
ev_transition_animation_set_property (GObject      *object,
 
56
                                      guint         prop_id,
 
57
                                      const GValue *value,
 
58
                                      GParamSpec   *pspec)
 
59
{
 
60
        EvTransitionAnimationPriv *priv;
 
61
 
 
62
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object);
 
63
 
 
64
        switch (prop_id) {
 
65
        case PROP_EFFECT:
 
66
                if (priv->effect)
 
67
                        g_object_unref (priv->effect);
 
68
 
 
69
                priv->effect = g_value_dup_object (value);
 
70
                break;
 
71
        case PROP_ORIGIN_SURFACE:
 
72
                ev_transition_animation_set_origin_surface (EV_TRANSITION_ANIMATION (object),
 
73
                                                            g_value_get_pointer (value));
 
74
                break;
 
75
        case PROP_DEST_SURFACE:
 
76
                ev_transition_animation_set_dest_surface (EV_TRANSITION_ANIMATION (object),
 
77
                                                          g_value_get_pointer (value));
 
78
                break;
 
79
        default:
 
80
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
81
        }
 
82
}
 
83
 
 
84
static void
 
85
ev_transition_animation_get_property (GObject      *object,
 
86
                                      guint         prop_id,
 
87
                                      GValue       *value,
 
88
                                      GParamSpec   *pspec)
 
89
{
 
90
        EvTransitionAnimationPriv *priv;
 
91
 
 
92
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object);
 
93
 
 
94
        switch (prop_id) {
 
95
        case PROP_EFFECT:
 
96
                g_value_set_object (value, priv->effect);
 
97
                break;
 
98
        case PROP_ORIGIN_SURFACE:
 
99
                g_value_set_pointer (value, priv->origin_surface);
 
100
                break;
 
101
        case PROP_DEST_SURFACE:
 
102
                g_value_set_pointer (value, priv->dest_surface);
 
103
                break;
 
104
        default:
 
105
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
106
        }
 
107
}
 
108
 
 
109
static void
 
110
ev_transition_animation_finalize (GObject *object)
 
111
{
 
112
        EvTransitionAnimationPriv *priv;
 
113
 
 
114
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object);
 
115
 
 
116
        if (priv->effect)
 
117
                g_object_unref (priv->effect);
 
118
 
 
119
        if (priv->origin_surface)
 
120
                cairo_surface_destroy (priv->origin_surface);
 
121
 
 
122
        if (priv->dest_surface)
 
123
                cairo_surface_destroy (priv->dest_surface);
 
124
 
 
125
        G_OBJECT_CLASS (ev_transition_animation_parent_class)->finalize (object);
 
126
}
 
127
 
 
128
static GObject *
 
129
ev_transition_animation_constructor (GType                  type,
 
130
                                     guint                  n_construct_properties,
 
131
                                     GObjectConstructParam *construct_params)
 
132
{
 
133
        GObject *object;
 
134
        EvTransitionAnimationPriv *priv;
 
135
        EvTransitionEffect *effect;
 
136
        gint duration;
 
137
 
 
138
        object = G_OBJECT_CLASS (ev_transition_animation_parent_class)->constructor (type,
 
139
                                                                                     n_construct_properties,
 
140
                                                                                     construct_params);
 
141
 
 
142
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object);
 
143
        effect = priv->effect;
 
144
 
 
145
        g_object_get (effect, "duration", &duration, NULL);
 
146
        ev_timeline_set_duration (EV_TIMELINE (object), duration * 1000);
 
147
 
 
148
        return object;
 
149
}
 
150
 
 
151
static void
 
152
ev_transition_animation_class_init (EvTransitionAnimationClass *klass)
 
153
{
 
154
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
155
 
 
156
        object_class->set_property = ev_transition_animation_set_property;
 
157
        object_class->get_property = ev_transition_animation_get_property;
 
158
        object_class->finalize = ev_transition_animation_finalize;
 
159
        object_class->constructor = ev_transition_animation_constructor;
 
160
 
 
161
        g_object_class_install_property (object_class,
 
162
                                         PROP_EFFECT,
 
163
                                         g_param_spec_object ("effect",
 
164
                                                              "Effect",
 
165
                                                              "Transition effect description",
 
166
                                                              EV_TYPE_TRANSITION_EFFECT,
 
167
                                                              G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
 
168
        g_object_class_install_property (object_class,
 
169
                                         PROP_ORIGIN_SURFACE,
 
170
                                         g_param_spec_pointer ("origin-surface",
 
171
                                                               "Origin surface",
 
172
                                                               "Cairo surface from which the animation will happen",
 
173
                                                               G_PARAM_READWRITE));
 
174
        g_object_class_install_property (object_class,
 
175
                                         PROP_DEST_SURFACE,
 
176
                                         g_param_spec_pointer ("dest-surface",
 
177
                                                               "Destination surface",
 
178
                                                               "Cairo surface to which the animation will happen",
 
179
                                                               G_PARAM_READWRITE));
 
180
 
 
181
        g_type_class_add_private (klass, sizeof (EvTransitionAnimationPriv));
 
182
}
 
183
 
 
184
static void
 
185
paint_surface (cairo_t         *cr,
 
186
               cairo_surface_t *surface,
 
187
               gdouble          x_offset,
 
188
               gdouble          y_offset,
 
189
               gdouble          alpha,
 
190
               GdkRectangle     page_area)
 
191
{
 
192
        gint width, height;
 
193
 
 
194
        gdk_cairo_rectangle (cr, &page_area);
 
195
        cairo_clip (cr);
 
196
 
 
197
        width = cairo_image_surface_get_width (surface);
 
198
        height = cairo_image_surface_get_height (surface);
 
199
 
 
200
        cairo_save (cr);
 
201
 
 
202
        if (width != page_area.width || height != page_area.height) {
 
203
                cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_FAST);
 
204
                cairo_scale (cr,
 
205
                             (gdouble) page_area.width / width,
 
206
                             (gdouble) page_area.height / height);
 
207
        }
 
208
 
 
209
        cairo_surface_set_device_offset (surface, x_offset, y_offset);
 
210
        cairo_set_source_surface (cr, surface, 0, 0);
 
211
 
 
212
        if (alpha == 0.)
 
213
                cairo_paint (cr);
 
214
        else
 
215
                cairo_paint_with_alpha (cr, alpha);
 
216
 
 
217
        cairo_restore (cr);
 
218
}
 
219
 
 
220
/* animations */
 
221
static void
 
222
ev_transition_animation_split (cairo_t               *cr,
 
223
                               EvTransitionAnimation *animation,
 
224
                               EvTransitionEffect    *effect,
 
225
                               gdouble                progress,
 
226
                               GdkRectangle           page_area)
 
227
{
 
228
        EvTransitionAnimationPriv *priv;
 
229
        EvTransitionEffectAlignment alignment;
 
230
        EvTransitionEffectDirection direction;
 
231
        gint width, height;
 
232
 
 
233
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
234
        width = page_area.width;
 
235
        height = page_area.height;
 
236
 
 
237
        g_object_get (effect,
 
238
                      "alignment", &alignment,
 
239
                      "direction", &direction,
 
240
                      NULL);
 
241
 
 
242
        if (direction == EV_TRANSITION_DIRECTION_INWARD) {
 
243
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
244
 
 
245
                if (alignment == EV_TRANSITION_ALIGNMENT_HORIZONTAL) {
 
246
                        cairo_rectangle (cr,
 
247
                                         0,
 
248
                                         height * progress / 2,
 
249
                                         width,
 
250
                                         height * (1 - progress));
 
251
                } else {
 
252
                        cairo_rectangle (cr,
 
253
                                         width * progress / 2,
 
254
                                         0,
 
255
                                         width * (1 - progress),
 
256
                                         height);
 
257
                }
 
258
 
 
259
                cairo_clip (cr);
 
260
 
 
261
                paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
262
        } else {
 
263
                paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
264
 
 
265
                if (alignment == EV_TRANSITION_ALIGNMENT_HORIZONTAL) {
 
266
                        cairo_rectangle (cr,
 
267
                                         0,
 
268
                                         (height / 2) - (height * progress / 2),
 
269
                                         width,
 
270
                                         height * progress);
 
271
                } else {
 
272
                        cairo_rectangle (cr,
 
273
                                         (width / 2) - (width * progress / 2),
 
274
                                         0,
 
275
                                         width * progress,
 
276
                                         height);
 
277
                }
 
278
 
 
279
                cairo_clip (cr);
 
280
 
 
281
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
282
        }
 
283
}
 
284
 
 
285
static void
 
286
ev_transition_animation_blinds (cairo_t               *cr,
 
287
                                EvTransitionAnimation *animation,
 
288
                                EvTransitionEffect    *effect,
 
289
                                gdouble                progress,
 
290
                                GdkRectangle           page_area)
 
291
{
 
292
        EvTransitionAnimationPriv *priv;
 
293
        EvTransitionEffectAlignment alignment;
 
294
        gint width, height, i;
 
295
 
 
296
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
297
        width = page_area.width;
 
298
        height = page_area.height;
 
299
 
 
300
        g_object_get (effect,
 
301
                      "alignment", &alignment,
 
302
                      NULL);
 
303
 
 
304
        paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
305
 
 
306
        for (i = 0; i < N_BLINDS; i++) {
 
307
                cairo_save (cr);
 
308
 
 
309
                if (alignment == EV_TRANSITION_ALIGNMENT_HORIZONTAL) {
 
310
                        cairo_rectangle (cr,
 
311
                                         0,
 
312
                                         height / N_BLINDS * i,
 
313
                                         width,
 
314
                                         height / N_BLINDS * progress);
 
315
                } else {
 
316
                        cairo_rectangle (cr,
 
317
                                         width / N_BLINDS * i,
 
318
                                         0,
 
319
                                         width / N_BLINDS * progress,
 
320
                                         height);
 
321
                }
 
322
 
 
323
                cairo_clip (cr);
 
324
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
325
                cairo_restore (cr);
 
326
        }
 
327
}
 
328
 
 
329
static void
 
330
ev_transition_animation_box (cairo_t               *cr,
 
331
                             EvTransitionAnimation *animation,
 
332
                             EvTransitionEffect    *effect,
 
333
                             gdouble                progress,
 
334
                             GdkRectangle           page_area)
 
335
{
 
336
        EvTransitionAnimationPriv *priv;
 
337
        EvTransitionEffectDirection direction;
 
338
        gint width, height;
 
339
 
 
340
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
341
        width = page_area.width;
 
342
        height = page_area.height;
 
343
 
 
344
        g_object_get (effect,
 
345
                      "direction", &direction,
 
346
                      NULL);
 
347
 
 
348
        if (direction == EV_TRANSITION_DIRECTION_INWARD) {
 
349
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
350
 
 
351
                cairo_rectangle (cr,
 
352
                                 width * progress / 2,
 
353
                                 height * progress / 2,
 
354
                                 width * (1 - progress),
 
355
                                 height * (1 - progress));
 
356
                cairo_clip (cr);
 
357
 
 
358
                paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
359
        } else {
 
360
                paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
361
 
 
362
                cairo_rectangle (cr,
 
363
                                 (width / 2) - (width * progress / 2),
 
364
                                 (height / 2) - (height * progress / 2),
 
365
                                 width * progress,
 
366
                                 height * progress);
 
367
                cairo_clip (cr);
 
368
 
 
369
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
370
        }
 
371
}
 
372
 
 
373
static void
 
374
ev_transition_animation_wipe (cairo_t               *cr,
 
375
                              EvTransitionAnimation *animation,
 
376
                              EvTransitionEffect    *effect,
 
377
                              gdouble                progress,
 
378
                              GdkRectangle           page_area)
 
379
{
 
380
        EvTransitionAnimationPriv *priv;
 
381
        gint width, height;
 
382
        gint angle;
 
383
 
 
384
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
385
        width = page_area.width;
 
386
        height = page_area.height;
 
387
 
 
388
        g_object_get (effect,
 
389
                      "angle", &angle,
 
390
                      NULL);
 
391
 
 
392
        paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
393
 
 
394
        if (angle == 0) {
 
395
                /* left to right */
 
396
                cairo_rectangle (cr,
 
397
                                 0, 0,
 
398
                                 width * progress,
 
399
                                 height);
 
400
        } else if (angle <= 90) {
 
401
                /* bottom to top */
 
402
                cairo_rectangle (cr,
 
403
                                 0,
 
404
                                 height * (1 - progress),
 
405
                                 width,
 
406
                                 height * progress);
 
407
        } else if (angle <= 180) {
 
408
                /* right to left */
 
409
                cairo_rectangle (cr,
 
410
                                 width * (1 - progress),
 
411
                                 0,
 
412
                                 width * progress,
 
413
                                 height);
 
414
        } else if (angle <= 270) {
 
415
                /* top to bottom */
 
416
                cairo_rectangle (cr,
 
417
                                 0, 0,
 
418
                                 width,
 
419
                                 height * progress);
 
420
        }
 
421
 
 
422
        cairo_clip (cr);
 
423
 
 
424
        paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
425
}
 
426
 
 
427
static void
 
428
ev_transition_animation_dissolve (cairo_t               *cr,
 
429
                                  EvTransitionAnimation *animation,
 
430
                                  EvTransitionEffect    *effect,
 
431
                                  gdouble                progress,
 
432
                                  GdkRectangle           page_area)
 
433
{
 
434
        EvTransitionAnimationPriv *priv;
 
435
 
 
436
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
437
 
 
438
        paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
439
        paint_surface (cr, priv->origin_surface, 0, 0, 1 - progress, page_area);
 
440
}
 
441
 
 
442
static void
 
443
ev_transition_animation_push (cairo_t               *cr,
 
444
                              EvTransitionAnimation *animation,
 
445
                              EvTransitionEffect    *effect,
 
446
                              gdouble                progress,
 
447
                              GdkRectangle           page_area)
 
448
{
 
449
        EvTransitionAnimationPriv *priv;
 
450
        gint width, height;
 
451
        gint angle;
 
452
 
 
453
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
454
        width = page_area.width;
 
455
        height = page_area.height;
 
456
 
 
457
        g_object_get (effect,
 
458
                      "angle", &angle,
 
459
                      NULL);
 
460
 
 
461
        if (angle == 0) {
 
462
                /* left to right */
 
463
                paint_surface (cr, priv->origin_surface, - (width * progress), 0, 0, page_area);
 
464
                paint_surface (cr, priv->dest_surface, width * (1 - progress), 0, 0, page_area);
 
465
        } else {
 
466
                /* top to bottom */
 
467
                paint_surface (cr, priv->origin_surface, 0, - (height * progress), 0, page_area);
 
468
                paint_surface (cr, priv->dest_surface, 0, height * (1 - progress), 0, page_area);
 
469
        }
 
470
}
 
471
 
 
472
static void
 
473
ev_transition_animation_cover (cairo_t               *cr,
 
474
                               EvTransitionAnimation *animation,
 
475
                               EvTransitionEffect    *effect,
 
476
                               gdouble                progress,
 
477
                               GdkRectangle           page_area)
 
478
{
 
479
        EvTransitionAnimationPriv *priv;
 
480
        gint width, height;
 
481
        gint angle;
 
482
 
 
483
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
484
        width = page_area.width;
 
485
        height = page_area.height;
 
486
 
 
487
        g_object_get (effect,
 
488
                      "angle", &angle,
 
489
                      NULL);
 
490
 
 
491
        paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
492
 
 
493
        if (angle == 0) {
 
494
                /* left to right */
 
495
                paint_surface (cr, priv->dest_surface, width * (1 - progress), 0, 0, page_area);
 
496
        } else {
 
497
                /* top to bottom */
 
498
                paint_surface (cr, priv->dest_surface, 0, height * (1 - progress), 0, page_area);
 
499
        }
 
500
}
 
501
 
 
502
static void
 
503
ev_transition_animation_uncover (cairo_t               *cr,
 
504
                                 EvTransitionAnimation *animation,
 
505
                                 EvTransitionEffect    *effect,
 
506
                                 gdouble                progress,
 
507
                                 GdkRectangle           page_area)
 
508
{
 
509
        EvTransitionAnimationPriv *priv;
 
510
        gint width, height;
 
511
        gint angle;
 
512
 
 
513
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
514
        width = page_area.width;
 
515
        height = page_area.height;
 
516
 
 
517
        g_object_get (effect,
 
518
                      "angle", &angle,
 
519
                      NULL);
 
520
 
 
521
        paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
522
 
 
523
        if (angle == 0) {
 
524
                /* left to right */
 
525
                paint_surface (cr, priv->origin_surface, - (width * progress), 0, 0, page_area);
 
526
        } else {
 
527
                /* top to bottom */
 
528
                paint_surface (cr, priv->origin_surface, 0, - (height * progress), 0, page_area);
 
529
        }
 
530
}
 
531
 
 
532
static void
 
533
ev_transition_animation_fade (cairo_t               *cr,
 
534
                              EvTransitionAnimation *animation,
 
535
                              EvTransitionEffect    *effect,
 
536
                              gdouble                progress,
 
537
                              GdkRectangle           page_area)
 
538
{
 
539
        EvTransitionAnimationPriv *priv;
 
540
 
 
541
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
542
 
 
543
        paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
544
        paint_surface (cr, priv->dest_surface, 0, 0, progress, page_area);
 
545
}
 
546
 
 
547
void
 
548
ev_transition_animation_paint (EvTransitionAnimation *animation,
 
549
                               cairo_t               *cr,
 
550
                               GdkRectangle           page_area)
 
551
{
 
552
        EvTransitionAnimationPriv *priv;
 
553
        EvTransitionEffectType type;
 
554
        gdouble progress;
 
555
 
 
556
        g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation));
 
557
 
 
558
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
559
        g_object_get (priv->effect, "type", &type, NULL);
 
560
        progress = ev_timeline_get_progress (EV_TIMELINE (animation));
 
561
 
 
562
        if (!priv->dest_surface) {
 
563
                /* animation is still not ready, paint the origin surface */
 
564
                paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area);
 
565
                return;
 
566
        }
 
567
 
 
568
        switch (type) {
 
569
        case EV_TRANSITION_EFFECT_REPLACE:
 
570
                /* just paint the destination slide */
 
571
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
572
                break;
 
573
        case EV_TRANSITION_EFFECT_SPLIT:
 
574
                ev_transition_animation_split (cr, animation, priv->effect, progress, page_area);
 
575
                break;
 
576
        case EV_TRANSITION_EFFECT_BLINDS:
 
577
                ev_transition_animation_blinds (cr, animation, priv->effect, progress, page_area);
 
578
                break;
 
579
        case EV_TRANSITION_EFFECT_BOX:
 
580
                ev_transition_animation_box (cr, animation, priv->effect, progress, page_area);
 
581
                break;
 
582
        case EV_TRANSITION_EFFECT_WIPE:
 
583
                ev_transition_animation_wipe (cr, animation, priv->effect, progress, page_area);
 
584
                break;
 
585
        case EV_TRANSITION_EFFECT_DISSOLVE:
 
586
                ev_transition_animation_dissolve (cr, animation, priv->effect, progress, page_area);
 
587
                break;
 
588
        case EV_TRANSITION_EFFECT_PUSH:
 
589
                ev_transition_animation_push (cr, animation, priv->effect, progress, page_area);
 
590
                break;
 
591
        case EV_TRANSITION_EFFECT_COVER:
 
592
                ev_transition_animation_cover (cr, animation, priv->effect, progress, page_area);
 
593
                break;
 
594
        case EV_TRANSITION_EFFECT_UNCOVER:
 
595
                ev_transition_animation_uncover (cr, animation, priv->effect, progress, page_area);
 
596
                break;
 
597
        case EV_TRANSITION_EFFECT_FADE:
 
598
                ev_transition_animation_fade (cr, animation, priv->effect, progress, page_area);
 
599
                break;
 
600
        default: {
 
601
                GEnumValue *enum_value;
 
602
 
 
603
                enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_TRANSITION_EFFECT_TYPE), type);
 
604
 
 
605
                g_warning ("Unimplemented transition animation: '%s', "
 
606
                           "please post a bug report in Evince bugzilla "
 
607
                           "(http://bugzilla.gnome.org) with a testcase.",
 
608
                           enum_value->value_nick);
 
609
 
 
610
                /* just paint the destination slide */
 
611
                paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area);
 
612
                }
 
613
        }
 
614
}
 
615
 
 
616
EvTransitionAnimation *
 
617
ev_transition_animation_new (EvTransitionEffect *effect)
 
618
{
 
619
        g_return_val_if_fail (EV_IS_TRANSITION_EFFECT (effect), NULL);
 
620
 
 
621
        return g_object_new (EV_TYPE_TRANSITION_ANIMATION,
 
622
                             "effect", effect,
 
623
                             NULL);
 
624
}
 
625
 
 
626
void
 
627
ev_transition_animation_set_origin_surface (EvTransitionAnimation *animation,
 
628
                                            cairo_surface_t       *origin_surface)
 
629
{
 
630
        EvTransitionAnimationPriv *priv;
 
631
        cairo_surface_t *surface;
 
632
 
 
633
        g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation));
 
634
 
 
635
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
636
 
 
637
        surface = cairo_surface_reference (origin_surface);
 
638
 
 
639
        if (priv->origin_surface)
 
640
                cairo_surface_destroy (priv->origin_surface);
 
641
 
 
642
        priv->origin_surface = surface;
 
643
        g_object_notify (G_OBJECT (animation), "origin-surface");
 
644
 
 
645
        if (priv->origin_surface && priv->dest_surface)
 
646
                ev_timeline_start (EV_TIMELINE (animation));
 
647
}
 
648
 
 
649
void
 
650
ev_transition_animation_set_dest_surface (EvTransitionAnimation *animation,
 
651
                                          cairo_surface_t       *dest_surface)
 
652
{
 
653
        EvTransitionAnimationPriv *priv;
 
654
        cairo_surface_t *surface;
 
655
 
 
656
        g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation));
 
657
 
 
658
        priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation);
 
659
 
 
660
        surface = cairo_surface_reference (dest_surface);
 
661
 
 
662
        if (priv->dest_surface)
 
663
                cairo_surface_destroy (priv->dest_surface);
 
664
 
 
665
        priv->dest_surface = surface;
 
666
        g_object_notify (G_OBJECT (animation), "dest-surface");
 
667
 
 
668
        if (priv->origin_surface && priv->dest_surface)
 
669
                ev_timeline_start (EV_TIMELINE (animation));
 
670
}