~ubuntu-branches/ubuntu/oneiric/evince/oneiric-updates

« back to all changes in this revision

Viewing changes to backend/ps/ps-document.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette, Josselin Mouette, Marc 'HE' Brockschmidt
  • Date: 2008-12-31 16:41:58 UTC
  • mfrom: (1.1.36 upstream)
  • mto: (1.5.1 sid)
  • mto: This revision was merged to the branch mainline in revision 109.
  • Revision ID: james.westby@ubuntu.com-20081231164158-xnobl1sokvvc6ho8
Tags: 2.24.2-1
[ Josselin Mouette ]
* README.Debian: document that you need to install poppler-data.
  Closes: #506836.

[ Marc 'HE' Brockschmidt ]
* debian/control: Make the Gnome team maintainer. I'm not doing the job
   anyway.

[ Josselin Mouette ]
* New upstream release.
* Require nautilus 2.22 to build the extension for the correct 
  version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Ghostscript widget for GTK/GNOME
2
 
 *
3
 
 * Copyright (C) 1998 - 2005 the Free Software Foundation
4
 
 *
5
 
 * Authors: Jonathan Blandford, Jaka Mocnik, Carlos Garcia Campos
6
 
 *
7
 
 * Based on code by: Federico Mena (Quartic), Szekeres Istvan (Pista)
8
 
 *
9
 
 * This library is free software; you can redistribute it and/or
10
 
 * modify it under the terms of the GNU Library General Public
11
 
 * License as published by the Free Software Foundation; either
12
 
 * version 2 of the License, or (at your option) any later version.
13
 
 *
14
 
 * This library is distributed in the hope that it will be useful,
15
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 
 * Library General Public License for more details.
18
 
 *
19
 
 * You should have received a copy of the GNU Library General Public
20
 
 * License along with this library; if not, write to the
21
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22
 
 * Boston, MA 02111-1307, USA.
23
 
 */
24
 
 
25
 
#include "config.h"
26
 
 
27
 
#include <glib/gstdio.h>
28
 
#include <glib/gi18n.h>
29
 
#include <gdk/gdkpixbuf.h>
30
 
#include <string.h>
31
 
#include <stdlib.h>
32
 
 
33
 
#include "ps-document.h"
34
 
#include "ps-interpreter.h"
35
 
#include "ps.h"
36
 
#include "gstypes.h"
37
 
#include "gsdefaults.h"
38
 
#include "ev-file-exporter.h"
39
 
#include "ev-async-renderer.h"
40
 
#include "ev-document-thumbnails.h"
41
 
#include "ev-document-misc.h"
42
 
 
43
 
struct _PSDocument {
44
 
        GObject object;
45
 
 
46
 
        gchar *filename;
47
 
        struct document *doc;
48
 
        gboolean structured_doc;
49
 
 
50
 
        PSInterpreter *gs;
51
 
 
52
 
        /* Document Thumbnails */
53
 
        PSInterpreter   *thumbs_gs;
54
 
        GdkPixbuf       *thumbnail;
55
 
        EvRenderContext *thumbs_rc;
56
 
        GMutex          *thumbs_mutex;
57
 
        GCond           *thumbs_cond;
58
 
        
59
 
        /* File exporter */
60
 
        gint  *ps_export_pagelist;
61
 
        gchar *ps_export_filename;
62
 
};
63
 
 
64
 
struct _PSDocumentClass {
65
 
        GObjectClass parent_class;
66
 
}; 
67
 
 
68
 
static void     ps_document_document_iface_init            (EvDocumentIface           *iface);
69
 
static void     ps_document_file_exporter_iface_init       (EvFileExporterIface       *iface);
70
 
static void     ps_async_renderer_iface_init               (EvAsyncRendererIface      *iface);
71
 
static void     ps_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface);
72
 
 
73
 
static void     ps_interpreter_page_rendered               (PSInterpreter             *gs,
74
 
                                                            GdkPixbuf                 *pixbuf,
75
 
                                                            PSDocument                *ps_document);
76
 
 
77
 
EV_BACKEND_REGISTER_WITH_CODE (PSDocument, ps_document,
78
 
                         {
79
 
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
80
 
                                                                 ps_document_document_thumbnails_iface_init);
81
 
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_FILE_EXPORTER,
82
 
                                                                 ps_document_file_exporter_iface_init);
83
 
                                 EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_ASYNC_RENDERER,
84
 
                                                                 ps_async_renderer_iface_init);
85
 
                         });
86
 
 
87
 
/* PSDocument */
88
 
static void
89
 
ps_document_init (PSDocument *ps_document)
90
 
{
91
 
}
92
 
 
93
 
static void
94
 
ps_document_dispose (GObject *object)
95
 
{
96
 
        PSDocument *ps_document = PS_DOCUMENT (object);
97
 
 
98
 
        if (ps_document->gs) {
99
 
                g_object_unref (ps_document->gs);
100
 
                ps_document->gs = NULL;
101
 
        }
102
 
 
103
 
        if (ps_document->thumbs_gs) {
104
 
                g_object_unref (ps_document->thumbs_gs);
105
 
                ps_document->thumbs_gs = NULL;
106
 
        }
107
 
        
108
 
        if (ps_document->filename) {
109
 
                g_free (ps_document->filename);
110
 
                ps_document->filename = NULL;
111
 
        }
112
 
 
113
 
        if (ps_document->doc) {
114
 
                psfree (ps_document->doc);
115
 
                ps_document->doc = NULL;
116
 
        }
117
 
 
118
 
        if (ps_document->thumbnail) {
119
 
                g_object_unref (ps_document->thumbnail);
120
 
                ps_document->thumbnail = NULL;
121
 
        }
122
 
 
123
 
        if (ps_document->thumbs_mutex) {
124
 
                g_mutex_free (ps_document->thumbs_mutex);
125
 
                ps_document->thumbs_mutex = NULL;
126
 
        }
127
 
        
128
 
        if (ps_document->thumbs_cond) {
129
 
                g_cond_free (ps_document->thumbs_cond);
130
 
                ps_document->thumbs_cond = NULL;
131
 
        }
132
 
 
133
 
        if (ps_document->thumbs_rc) {
134
 
                g_object_unref (ps_document->thumbs_rc);
135
 
                ps_document->thumbs_rc = NULL;
136
 
        }
137
 
 
138
 
        G_OBJECT_CLASS (ps_document_parent_class)->dispose (object);
139
 
}
140
 
 
141
 
static void
142
 
ps_document_class_init (PSDocumentClass *klass)
143
 
{
144
 
        GObjectClass *object_class;
145
 
 
146
 
        object_class = G_OBJECT_CLASS (klass);
147
 
 
148
 
        object_class->dispose = ps_document_dispose;
149
 
}
150
 
 
151
 
/* EvDocumentIface */
152
 
static gboolean
153
 
document_load (PSDocument *ps_document, const gchar *fname, GError **error)
154
 
{
155
 
        FILE *fd;
156
 
        
157
 
        ps_document->filename = g_strdup (fname);
158
 
 
159
 
        /*
160
 
         * We need to make sure that the file is loadable/exists!
161
 
         * otherwise we want to exit without loading new stuff...
162
 
         */
163
 
        if (!g_file_test (fname, G_FILE_TEST_IS_REGULAR)) {
164
 
                gchar *filename_dsp;
165
 
 
166
 
                filename_dsp = g_filename_display_name (fname);
167
 
                g_set_error (error,
168
 
                             G_FILE_ERROR,
169
 
                             G_FILE_ERROR_NOENT,
170
 
                             _("Cannot open file “%s”."),
171
 
                             filename_dsp);
172
 
                g_free (filename_dsp);
173
 
                
174
 
                return FALSE;
175
 
        }
176
 
 
177
 
        if ((fd = fopen (ps_document->filename, "r")) == NULL) {
178
 
                gchar *filename_dsp;
179
 
 
180
 
                filename_dsp = g_filename_display_name (fname);
181
 
                g_set_error (error,
182
 
                             G_FILE_ERROR,
183
 
                             G_FILE_ERROR_NOENT,
184
 
                             _("Cannot open file “%s”."),
185
 
                             filename_dsp);
186
 
                g_free (filename_dsp);
187
 
                
188
 
                return FALSE;
189
 
        }
190
 
        
191
 
        /* we grab the vital statistics!!! */
192
 
        ps_document->doc = psscan (fd, TRUE, ps_document->filename);
193
 
        fclose (fd);
194
 
        if (!ps_document->doc)
195
 
                return FALSE;
196
 
 
197
 
        ps_document->structured_doc =
198
 
                ((!ps_document->doc->epsf && ps_document->doc->numpages > 0) ||
199
 
                 (ps_document->doc->epsf && ps_document->doc->numpages > 1));
200
 
 
201
 
        ps_document->gs = ps_interpreter_new (ps_document->filename,
202
 
                                              ps_document->doc);
203
 
        g_signal_connect (G_OBJECT (ps_document->gs), "page_rendered",
204
 
                          G_CALLBACK (ps_interpreter_page_rendered),
205
 
                          (gpointer) ps_document);
206
 
        
207
 
        return TRUE;
208
 
}
209
 
 
210
 
static gboolean
211
 
ps_document_load (EvDocument  *document,
212
 
                  const char  *uri,
213
 
                  GError     **error)
214
 
{
215
 
        char *filename;
216
 
        char *gs_path;
217
 
        gboolean result;
218
 
 
219
 
        filename = g_filename_from_uri (uri, NULL, error);
220
 
        if (!filename)
221
 
                return FALSE;
222
 
 
223
 
        gs_path = g_find_program_in_path ("gs");
224
 
        if (!gs_path) {
225
 
                gchar *filename_dsp;
226
 
                
227
 
                filename_dsp = g_filename_display_name (filename);
228
 
                g_set_error (error,
229
 
                             G_FILE_ERROR,
230
 
                             G_FILE_ERROR_NOENT,
231
 
                             _("Failed to load document “%s”. Ghostscript interpreter was not found in path"),
232
 
                             filename);
233
 
                g_free (filename_dsp);
234
 
                g_free (filename);
235
 
                
236
 
                return FALSE;
237
 
        }
238
 
        g_free (gs_path);
239
 
 
240
 
        result = document_load (PS_DOCUMENT (document), filename, error);
241
 
        if (!result && !(*error)) {
242
 
                gchar *filename_dsp;
243
 
                
244
 
                filename_dsp = g_filename_display_name (filename);
245
 
                g_set_error (error,
246
 
                             G_FILE_ERROR,
247
 
                             G_FILE_ERROR_FAILED,
248
 
                             _("Failed to load document “%s”"),
249
 
                             filename_dsp);
250
 
                g_free (filename_dsp);
251
 
        }
252
 
        
253
 
        g_free (filename);
254
 
 
255
 
        return result;
256
 
}
257
 
 
258
 
static gboolean
259
 
save_document (PSDocument *document, const char *filename)
260
 
{
261
 
        gboolean result = TRUE;
262
 
        GtkGSDocSink *sink = gtk_gs_doc_sink_new ();
263
 
        FILE *f, *src_file;
264
 
        gchar *buf;
265
 
 
266
 
        src_file = fopen (document->filename, "r");
267
 
        if (src_file) {
268
 
                struct stat stat_rec;
269
 
 
270
 
                if (stat (document->filename, &stat_rec) == 0) {
271
 
                        pscopy (src_file, sink, 0, stat_rec.st_size - 1);
272
 
                }
273
 
 
274
 
                fclose (src_file);
275
 
        }
276
 
        
277
 
        buf = gtk_gs_doc_sink_get_buffer (sink);
278
 
        if (buf == NULL) {
279
 
                return FALSE;
280
 
        }
281
 
        
282
 
        f = fopen (filename, "w");
283
 
        if (f) {
284
 
                fputs (buf, f);
285
 
                fclose (f);
286
 
        } else {
287
 
                result = FALSE;
288
 
        }
289
 
 
290
 
        g_free (buf);
291
 
        gtk_gs_doc_sink_free (sink);
292
 
        g_free (sink);
293
 
 
294
 
        return result;
295
 
}
296
 
 
297
 
static gboolean
298
 
save_page_list (PSDocument *document, int *page_list, const char *filename)
299
 
{
300
 
        gboolean result = TRUE;
301
 
        GtkGSDocSink *sink = gtk_gs_doc_sink_new ();
302
 
        FILE *f;
303
 
        gchar *buf;
304
 
 
305
 
        pscopydoc (sink, document->filename, 
306
 
                   document->doc, page_list);
307
 
        
308
 
        buf = gtk_gs_doc_sink_get_buffer (sink);
309
 
        
310
 
        f = fopen (filename, "w");
311
 
        if (f) {
312
 
                fputs (buf, f);
313
 
                fclose (f);
314
 
        } else {
315
 
                result = FALSE;
316
 
        }
317
 
 
318
 
        g_free (buf);
319
 
        gtk_gs_doc_sink_free (sink);
320
 
        g_free (sink);
321
 
 
322
 
        return result;
323
 
}
324
 
 
325
 
static gboolean
326
 
ps_document_save (EvDocument  *document,
327
 
                  const char  *uri,
328
 
                  GError     **error)
329
 
{
330
 
        PSDocument *ps = PS_DOCUMENT (document);
331
 
        gboolean result;
332
 
        char *filename;
333
 
 
334
 
        filename = g_filename_from_uri (uri, NULL, error);
335
 
        if (!filename)
336
 
                return FALSE;
337
 
 
338
 
        result = save_document (ps, filename);
339
 
 
340
 
        g_free (filename);
341
 
 
342
 
        return result;
343
 
}
344
 
 
345
 
static int
346
 
ps_document_get_n_pages (EvDocument *document)
347
 
{
348
 
        PSDocument *ps = PS_DOCUMENT (document);
349
 
 
350
 
        if (!ps->filename || !ps->doc) {
351
 
                return -1;
352
 
        }
353
 
 
354
 
        return ps->structured_doc ? ps->doc->numpages : 1;
355
 
}
356
 
 
357
 
static gint
358
 
ps_document_get_page_rotation (PSDocument *ps_document,
359
 
                               int         page)
360
 
{
361
 
        gint rotation = GTK_GS_ORIENTATION_NONE;
362
 
 
363
 
        g_assert (ps_document->doc != NULL);
364
 
        
365
 
        if (ps_document->structured_doc) {
366
 
                if (ps_document->doc->pages[page].orientation != GTK_GS_ORIENTATION_NONE)
367
 
                        rotation = ps_document->doc->pages[page].orientation;
368
 
                else
369
 
                        rotation = ps_document->doc->default_page_orientation;
370
 
        }
371
 
 
372
 
        if (rotation == GTK_GS_ORIENTATION_NONE)
373
 
                rotation = ps_document->doc->orientation;
374
 
 
375
 
        if (rotation == GTK_GS_ORIENTATION_NONE)
376
 
                rotation = GTK_GS_ORIENTATION_PORTRAIT;
377
 
 
378
 
        return rotation;
379
 
}
380
 
 
381
 
static void
382
 
ps_document_get_page_size (EvDocument *document,
383
 
                           int         page,
384
 
                           double     *width,
385
 
                           double     *height)
386
 
{
387
 
        PSDocument *ps_document = PS_DOCUMENT (document);
388
 
        int urx, ury, llx, lly;
389
 
        gdouble pwidth, pheight;
390
 
        gdouble page_width, page_height;
391
 
        gint rotate;
392
 
 
393
 
        psgetpagebox (ps_document->doc, page, &urx, &ury, &llx, &lly);
394
 
 
395
 
        pwidth = (urx - llx) + 0.5;
396
 
        pheight = (ury - lly) + 0.5;
397
 
 
398
 
        rotate = ps_document_get_page_rotation (ps_document, page);
399
 
        if (rotate == 90 || rotate == 270) {
400
 
                page_height = pwidth;
401
 
                page_width = pheight;
402
 
        } else {
403
 
                page_width = pwidth;
404
 
                page_height = pheight;
405
 
        }
406
 
        
407
 
        if (width) {
408
 
                *width = page_width;
409
 
        }
410
 
 
411
 
        if (height) {
412
 
                *height = page_height;
413
 
        }
414
 
}
415
 
 
416
 
static EvDocumentInfo *
417
 
ps_document_get_info (EvDocument *document)
418
 
{
419
 
        EvDocumentInfo *info;
420
 
        PSDocument *ps = PS_DOCUMENT (document);
421
 
        int urx, ury, llx, lly;
422
 
 
423
 
        info = g_new0 (EvDocumentInfo, 1);
424
 
        info->fields_mask = EV_DOCUMENT_INFO_TITLE |
425
 
                            EV_DOCUMENT_INFO_FORMAT |
426
 
                            EV_DOCUMENT_INFO_CREATOR |
427
 
                            EV_DOCUMENT_INFO_N_PAGES |
428
 
                            EV_DOCUMENT_INFO_PAPER_SIZE;
429
 
 
430
 
        info->title = g_strdup (ps->doc->title);
431
 
        info->format = ps->doc->epsf ? g_strdup (_("Encapsulated PostScript"))
432
 
                                     : g_strdup (_("PostScript"));
433
 
        info->creator = g_strdup (ps->doc->creator);
434
 
        info->n_pages = ev_document_get_n_pages (document);
435
 
        
436
 
        psgetpagebox (PS_DOCUMENT (document)->doc, 0, &urx, &ury, &llx, &lly);
437
 
 
438
 
        info->paper_width  = (urx - llx) / 72.0f * 25.4f;
439
 
        info->paper_height = (ury - lly) / 72.0f * 25.4f;
440
 
 
441
 
        return info;
442
 
}
443
 
 
444
 
static void
445
 
ps_document_document_iface_init (EvDocumentIface *iface)
446
 
{
447
 
        iface->load = ps_document_load;
448
 
        iface->save = ps_document_save;
449
 
        iface->get_n_pages = ps_document_get_n_pages;
450
 
        iface->get_page_size = ps_document_get_page_size;
451
 
        iface->get_info = ps_document_get_info;
452
 
}
453
 
 
454
 
/* EvAsyncRendererIface */
455
 
static void
456
 
ps_interpreter_page_rendered (PSInterpreter *gs,
457
 
                              GdkPixbuf     *pixbuf,
458
 
                              PSDocument    *ps_document)
459
 
{
460
 
        g_signal_emit_by_name (ps_document, "render_finished", pixbuf);
461
 
}
462
 
 
463
 
static void
464
 
ps_async_renderer_render_pixbuf (EvAsyncRenderer *renderer,
465
 
                                 gint             page,
466
 
                                 gdouble          scale,
467
 
                                 gint             rotation)
468
 
{
469
 
        PSDocument *ps_document = PS_DOCUMENT (renderer);
470
 
 
471
 
        g_return_if_fail (PS_IS_INTERPRETER (ps_document->gs));
472
 
 
473
 
        rotation = (rotation + ps_document_get_page_rotation (ps_document, page)) % 360;
474
 
 
475
 
        ps_interpreter_render_page (ps_document->gs, page, scale, rotation);
476
 
}
477
 
 
478
 
static void
479
 
ps_async_renderer_iface_init (EvAsyncRendererIface *iface)
480
 
{
481
 
        iface->render_pixbuf = ps_async_renderer_render_pixbuf;
482
 
}
483
 
 
484
 
/* EvDocumentThumbnailsIface */
485
 
static void
486
 
ps_interpreter_thumbnail_rendered (PSInterpreter *gs,
487
 
                                   GdkPixbuf     *pixbuf,
488
 
                                   PSDocument    *ps_document)
489
 
{
490
 
        if (ps_document->thumbnail)
491
 
                g_object_unref (ps_document->thumbnail);
492
 
        ps_document->thumbnail = g_object_ref (pixbuf);
493
 
 
494
 
        g_cond_broadcast (ps_document->thumbs_cond);
495
 
}
496
 
 
497
 
static gboolean
498
 
ps_document_render_thumbnail (PSDocument *ps_document)
499
 
{
500
 
        ps_interpreter_render_page (ps_document->thumbs_gs,
501
 
                                    ps_document->thumbs_rc->page,
502
 
                                    ps_document->thumbs_rc->scale,
503
 
                                    ps_document->thumbs_rc->rotation);
504
 
 
505
 
        return FALSE;
506
 
}
507
 
 
508
 
static GdkPixbuf *
509
 
ps_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document_thumbnails,
510
 
                                      EvRenderContext      *rc, 
511
 
                                      gboolean              border)
512
 
{
513
 
        PSDocument *ps_document;
514
 
        GdkPixbuf  *pixbuf = NULL;
515
 
 
516
 
        ps_document = PS_DOCUMENT (document_thumbnails);
517
 
        
518
 
        g_return_val_if_fail (ps_document->filename != NULL, NULL);
519
 
        g_return_val_if_fail (ps_document->doc != NULL, NULL);
520
 
                
521
 
        if (!ps_document->thumbs_gs) {
522
 
                ps_document->thumbs_gs = ps_interpreter_new (ps_document->filename,
523
 
                                                             ps_document->doc);
524
 
                g_signal_connect (G_OBJECT (ps_document->thumbs_gs), "page_rendered",
525
 
                                  G_CALLBACK (ps_interpreter_thumbnail_rendered),
526
 
                                  (gpointer) ps_document);
527
 
        }
528
 
 
529
 
        if (!ps_document->thumbs_mutex)
530
 
                ps_document->thumbs_mutex = g_mutex_new ();
531
 
        ps_document->thumbs_cond = g_cond_new ();
532
 
 
533
 
        if (ps_document->thumbs_rc)
534
 
                g_object_unref (ps_document->thumbs_rc);
535
 
        ps_document->thumbs_rc = g_object_ref (rc);
536
 
 
537
 
        ev_document_doc_mutex_unlock ();
538
 
        g_mutex_lock (ps_document->thumbs_mutex);
539
 
        g_idle_add ((GSourceFunc)ps_document_render_thumbnail, ps_document);
540
 
        g_cond_wait (ps_document->thumbs_cond, ps_document->thumbs_mutex);
541
 
        g_cond_free (ps_document->thumbs_cond);
542
 
        ps_document->thumbs_cond = NULL;
543
 
        g_mutex_unlock (ps_document->thumbs_mutex);
544
 
        ev_document_doc_mutex_lock ();
545
 
        
546
 
        pixbuf = ps_document->thumbnail;
547
 
        ps_document->thumbnail = NULL;
548
 
        
549
 
        if (border) {
550
 
                GdkPixbuf *border_pixbuf;
551
 
                
552
 
                border_pixbuf = ev_document_misc_get_thumbnail_frame (-1, -1, pixbuf);
553
 
                g_object_unref (pixbuf);
554
 
                pixbuf = border_pixbuf;
555
 
        }
556
 
 
557
 
        return pixbuf;
558
 
}
559
 
 
560
 
static void
561
 
ps_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnails,
562
 
                                       EvRenderContext      *rc, 
563
 
                                       gint                 *width,
564
 
                                       gint                 *height)
565
 
{
566
 
        PSDocument *ps_document;
567
 
        gdouble     page_width, page_height;
568
 
 
569
 
        ps_document = PS_DOCUMENT (document_thumbnails);
570
 
        
571
 
        ps_document_get_page_size (EV_DOCUMENT (ps_document),
572
 
                                   rc->page,
573
 
                                   &page_width, &page_height);
574
 
        
575
 
        if (rc->rotation == 90 || rc->rotation == 270) {
576
 
                *width = (gint) (page_height * rc->scale);
577
 
                *height = (gint) (page_width * rc->scale);
578
 
        } else {
579
 
                *width = (gint) (page_width * rc->scale);
580
 
                *height = (gint) (page_height * rc->scale);
581
 
        }
582
 
}
583
 
 
584
 
static void
585
 
ps_document_document_thumbnails_iface_init (EvDocumentThumbnailsIface *iface)
586
 
{
587
 
        iface->get_thumbnail = ps_document_thumbnails_get_thumbnail;
588
 
        iface->get_dimensions = ps_document_thumbnails_get_dimensions;
589
 
}
590
 
 
591
 
/* EvFileExporterIface */
592
 
static void
593
 
ps_document_file_exporter_begin (EvFileExporter        *exporter,
594
 
                                 EvFileExporterContext *fc)
595
 
{
596
 
        PSDocument *document = PS_DOCUMENT (exporter);
597
 
 
598
 
        if (document->structured_doc) {
599
 
                g_free (document->ps_export_pagelist);
600
 
        
601
 
                document->ps_export_pagelist = g_new0 (int, document->doc->numpages);
602
 
        }
603
 
 
604
 
        document->ps_export_filename = g_strdup (fc->filename);
605
 
}
606
 
 
607
 
static void
608
 
ps_document_file_exporter_do_page (EvFileExporter  *exporter,
609
 
                                   EvRenderContext *rc)
610
 
{
611
 
        PSDocument *document = PS_DOCUMENT (exporter);
612
 
        
613
 
        if (document->structured_doc) {
614
 
                document->ps_export_pagelist[rc->page] = 1;
615
 
        }
616
 
}
617
 
 
618
 
static void
619
 
ps_document_file_exporter_end (EvFileExporter *exporter)
620
 
{
621
 
        PSDocument *document = PS_DOCUMENT (exporter);
622
 
 
623
 
        if (!document->structured_doc) {
624
 
                save_document (document, document->ps_export_filename);
625
 
        } else {
626
 
                save_page_list (document, document->ps_export_pagelist,
627
 
                                document->ps_export_filename);
628
 
                g_free (document->ps_export_pagelist);
629
 
                g_free (document->ps_export_filename);  
630
 
                document->ps_export_pagelist = NULL;
631
 
                document->ps_export_filename = NULL;
632
 
        }
633
 
}
634
 
 
635
 
static EvFileExporterCapabilities
636
 
ps_document_file_exporter_get_capabilities (EvFileExporter *exporter)
637
 
{
638
 
        return  EV_FILE_EXPORTER_CAN_PAGE_SET |
639
 
                EV_FILE_EXPORTER_CAN_GENERATE_PS;
640
 
}
641
 
 
642
 
static void
643
 
ps_document_file_exporter_iface_init (EvFileExporterIface *iface)
644
 
{
645
 
        iface->begin = ps_document_file_exporter_begin;
646
 
        iface->do_page = ps_document_file_exporter_do_page;
647
 
        iface->end = ps_document_file_exporter_end;
648
 
        iface->get_capabilities = ps_document_file_exporter_get_capabilities;
649
 
}