~ubuntu-branches/ubuntu/vivid/libspectre/vivid-proposed

« back to all changes in this revision

Viewing changes to libspectre/spectre-document.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Rosewarne
  • Date: 2008-01-06 21:58:55 UTC
  • Revision ID: james.westby@ubuntu.com-20080106215855-zmmkfhf4m3190zsj
Tags: upstream-0.2.0.ds
ImportĀ upstreamĀ versionĀ 0.2.0.ds

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of Libspectre.
 
2
 * 
 
3
 * Copyright (C) 2007 Albert Astals Cid <aacid@kde.org>
 
4
 * Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
 
5
 *
 
6
 * Libspectre 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 2, or (at your option)
 
9
 * any later version.
 
10
 *
 
11
 * Libspectre 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, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
 
 
25
/* For stat */
 
26
#include <sys/types.h>
 
27
#include <sys/stat.h>
 
28
#include <unistd.h>
 
29
 
 
30
#include "spectre-document.h"
 
31
#include "spectre-private.h"
 
32
#include "spectre-exporter.h"
 
33
#include "spectre-utils.h"
 
34
 
 
35
struct SpectreDocument
 
36
{
 
37
        struct document *doc;
 
38
        
 
39
        SpectreStatus    status;
 
40
 
 
41
        int              structured;
 
42
};
 
43
 
 
44
SpectreDocument *
 
45
spectre_document_new (void)
 
46
{
 
47
        SpectreDocument *doc;
 
48
 
 
49
        doc = calloc (1, sizeof (SpectreDocument));
 
50
        return doc;
 
51
}
 
52
 
 
53
void
 
54
spectre_document_load (SpectreDocument *document,
 
55
                       const char      *filename)
 
56
{
 
57
        _spectre_return_if_fail (document != NULL);
 
58
        _spectre_return_if_fail (filename != NULL);
 
59
        
 
60
        if (document->doc && strcmp (filename, document->doc->filename) == 0) {
 
61
                document->status = SPECTRE_STATUS_SUCCESS;
 
62
                return;
 
63
        }
 
64
 
 
65
        if (document->doc) {
 
66
                psdocdestroy (document->doc);
 
67
                document->doc = NULL;
 
68
        }
 
69
        
 
70
        document->doc = psscan (filename, SCANSTYLE_NORMAL);
 
71
        if (!document->doc) {
 
72
                /* FIXME: OOM | INVALID_PS */
 
73
                document->status = SPECTRE_STATUS_LOAD_ERROR;
 
74
                return;
 
75
        }
 
76
 
 
77
        document->structured = ((!document->doc->epsf && document->doc->numpages > 0) ||
 
78
                                (document->doc->epsf && document->doc->numpages > 1));
 
79
 
 
80
        if (document->status != SPECTRE_STATUS_SUCCESS)
 
81
                document->status = SPECTRE_STATUS_SUCCESS;
 
82
}
 
83
 
 
84
void
 
85
spectre_document_free (SpectreDocument *document)
 
86
{
 
87
        if (!document)
 
88
                return;
 
89
 
 
90
        if (document->doc) {
 
91
                psdocdestroy (document->doc);
 
92
                document->doc = NULL;
 
93
        }
 
94
 
 
95
        free (document);
 
96
}
 
97
 
 
98
SpectreStatus
 
99
spectre_document_status (SpectreDocument *document)
 
100
{
 
101
        _spectre_return_val_if_fail (document != NULL, SPECTRE_STATUS_DOCUMENT_NOT_LOADED);
 
102
        
 
103
        return document->status;
 
104
}
 
105
 
 
106
unsigned int
 
107
spectre_document_get_n_pages (SpectreDocument *document)
 
108
{
 
109
        _spectre_return_val_if_fail (document != NULL, 0);
 
110
        
 
111
        if (!document->doc) {
 
112
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
113
                return 0;
 
114
        }
 
115
        
 
116
        return document->structured ? document->doc->numpages : 1;
 
117
}
 
118
 
 
119
SpectreOrientation
 
120
spectre_document_get_orientation (SpectreDocument *document)
 
121
{
 
122
        int doc_orientation;
 
123
 
 
124
        _spectre_return_val_if_fail (document != NULL, SPECTRE_ORIENTATION_PORTRAIT);
 
125
        
 
126
        if (!document->doc) {
 
127
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
128
                return SPECTRE_ORIENTATION_PORTRAIT;
 
129
        }
 
130
 
 
131
        doc_orientation = document->doc->orientation != NONE ?
 
132
                document->doc->orientation : document->doc->default_page_orientation;
 
133
        
 
134
        switch (doc_orientation) {
 
135
        default:
 
136
        case PORTRAIT:
 
137
                return SPECTRE_ORIENTATION_PORTRAIT;
 
138
        case LANDSCAPE:
 
139
                return SPECTRE_ORIENTATION_LANDSCAPE;
 
140
        case SEASCAPE:
 
141
                return SPECTRE_ORIENTATION_REVERSE_LANDSCAPE;
 
142
        case UPSIDEDOWN:
 
143
                return SPECTRE_ORIENTATION_REVERSE_PORTRAIT;
 
144
        }
 
145
}
 
146
 
 
147
const char *
 
148
spectre_document_get_title (SpectreDocument *document)
 
149
{
 
150
        _spectre_return_val_if_fail (document != NULL, NULL);
 
151
        
 
152
        if (!document->doc) {
 
153
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
154
                return NULL;
 
155
        }
 
156
 
 
157
        return document->doc->title;
 
158
}
 
159
 
 
160
const char *
 
161
spectre_document_get_creator (SpectreDocument *document)
 
162
{
 
163
        _spectre_return_val_if_fail (document != NULL, NULL);
 
164
        
 
165
        if (!document->doc) {
 
166
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
167
                return NULL;
 
168
        }
 
169
 
 
170
        return document->doc->creator;
 
171
}
 
172
 
 
173
const char *
 
174
spectre_document_get_for (SpectreDocument *document)
 
175
{
 
176
        _spectre_return_val_if_fail (document != NULL, NULL);
 
177
        
 
178
        if (!document->doc) {
 
179
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
180
                return NULL;
 
181
        }
 
182
 
 
183
        return document->doc->fortext;
 
184
}
 
185
 
 
186
const char *
 
187
spectre_document_get_creation_date (SpectreDocument *document)
 
188
{
 
189
        _spectre_return_val_if_fail (document != NULL, NULL);
 
190
        
 
191
        if (!document->doc) {
 
192
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
193
                return NULL;
 
194
        }
 
195
        
 
196
        return document->doc->date;
 
197
}
 
198
 
 
199
const char *
 
200
spectre_document_get_format (SpectreDocument *document)
 
201
{
 
202
        _spectre_return_val_if_fail (document != NULL, NULL);
 
203
        
 
204
        if (!document->doc) {
 
205
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
206
                return NULL;
 
207
        }
 
208
 
 
209
        return document->doc->format;
 
210
}
 
211
 
 
212
int
 
213
spectre_document_is_eps (SpectreDocument *document)
 
214
{
 
215
        _spectre_return_val_if_fail (document != NULL, FALSE);
 
216
        
 
217
        if (!document->doc) {
 
218
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
219
                return FALSE;
 
220
        }
 
221
 
 
222
        return document->doc->epsf;
 
223
}
 
224
 
 
225
unsigned int 
 
226
spectre_document_get_language_level (SpectreDocument *document)
 
227
{
 
228
        _spectre_return_val_if_fail (document != NULL, 0);
 
229
        
 
230
        if (!document->doc) {
 
231
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
232
                return 0;
 
233
        }
 
234
 
 
235
        return document->doc->languagelevel ? atoi (document->doc->languagelevel) : 0;
 
236
}
 
237
 
 
238
SpectrePage *
 
239
spectre_document_get_page (SpectreDocument *document,
 
240
                           unsigned int     page_index)
 
241
{
 
242
        SpectrePage *page;
 
243
 
 
244
        _spectre_return_val_if_fail (document != NULL, NULL);
 
245
 
 
246
        if (page_index >= spectre_document_get_n_pages (document)) {
 
247
                document->status = SPECTRE_STATUS_INVALID_PAGE;
 
248
                return NULL;
 
249
        }
 
250
 
 
251
        if (!document->doc) {
 
252
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
253
                return NULL;
 
254
        }
 
255
        
 
256
        page = _spectre_page_new (page_index, document->doc);
 
257
        if (!page) {
 
258
                document->status = SPECTRE_STATUS_NO_MEMORY;
 
259
                return NULL;
 
260
        }
 
261
 
 
262
        if (document->status != SPECTRE_STATUS_SUCCESS)
 
263
                document->status = SPECTRE_STATUS_SUCCESS;
 
264
        
 
265
        return page;
 
266
}
 
267
 
 
268
SpectrePage *
 
269
spectre_document_get_page_by_label (SpectreDocument *document,
 
270
                                    const char      *label)
 
271
{
 
272
        unsigned int i;
 
273
        int page_index = -1;
 
274
 
 
275
        _spectre_return_val_if_fail (document != NULL, NULL);
 
276
        
 
277
        if (!label) {
 
278
                document->status = SPECTRE_STATUS_INVALID_PAGE;
 
279
                return NULL;
 
280
        }
 
281
 
 
282
        if (!document->doc) {
 
283
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
284
                return NULL;
 
285
        }
 
286
 
 
287
        for (i = 0; i < document->doc->numpages; i++) {
 
288
                if (strcmp (document->doc->pages[i].label, label) == 0) {
 
289
                        page_index = i;
 
290
                        break;
 
291
                }
 
292
        }
 
293
 
 
294
        if (page_index == -1) {
 
295
                document->status = SPECTRE_STATUS_INVALID_PAGE;
 
296
                return NULL;
 
297
        }
 
298
 
 
299
        return spectre_document_get_page (document, page_index);
 
300
}
 
301
 
 
302
void
 
303
spectre_document_render_full (SpectreDocument      *document,
 
304
                              SpectreRenderContext *rc,
 
305
                              unsigned char       **page_data,
 
306
                              int                  *row_length)
 
307
{
 
308
        SpectrePage *page;
 
309
 
 
310
        _spectre_return_if_fail (document != NULL);
 
311
        _spectre_return_if_fail (rc != NULL);
 
312
 
 
313
        if (!document->doc) {
 
314
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
315
                return;
 
316
        }
 
317
 
 
318
        page = spectre_document_get_page (document, 0);
 
319
        if (!page || document->status != SPECTRE_STATUS_SUCCESS) {
 
320
                spectre_page_free (page);
 
321
                return;
 
322
        }
 
323
                
 
324
        spectre_page_render (page, rc, page_data, row_length);
 
325
        document->status = spectre_page_status (page);
 
326
 
 
327
        spectre_page_free (page);
 
328
}
 
329
 
 
330
void
 
331
spectre_document_render (SpectreDocument *document,
 
332
                         unsigned char  **page_data,
 
333
                         int             *row_length)
 
334
{
 
335
        SpectreRenderContext *rc;
 
336
        
 
337
        _spectre_return_if_fail (document != NULL);
 
338
 
 
339
        rc = spectre_render_context_new ();
 
340
        spectre_document_render_full (document, rc, page_data, row_length);
 
341
        spectre_render_context_free (rc);
 
342
}
 
343
 
 
344
void
 
345
spectre_document_get_page_size (SpectreDocument *document,
 
346
                                int             *width,
 
347
                                int             *height)
 
348
{
 
349
        SpectrePage *page;
 
350
        int          w, h;
 
351
 
 
352
        _spectre_return_if_fail (document != NULL);
 
353
 
 
354
        if (!document->doc) {
 
355
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
356
                return;
 
357
        }
 
358
 
 
359
        page = spectre_document_get_page (document, 0);
 
360
        if (!page || document->status != SPECTRE_STATUS_SUCCESS) {
 
361
                spectre_page_free (page);
 
362
                return;
 
363
        }
 
364
                
 
365
        spectre_page_get_size (page, &w, &h);
 
366
        if (width)
 
367
                *width = w;
 
368
        if (height)
 
369
                *height = h;
 
370
        
 
371
        spectre_page_free (page);
 
372
}
 
373
 
 
374
void
 
375
spectre_document_save (SpectreDocument *document,
 
376
                       const char      *filename)
 
377
{
 
378
        struct stat stat_buf;
 
379
        FILE *from;
 
380
        FILE *to;
 
381
 
 
382
        _spectre_return_if_fail (document != NULL);
 
383
        _spectre_return_if_fail (filename != NULL);
 
384
 
 
385
        if (!document->doc) {
 
386
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
387
                return;
 
388
        }
 
389
        
 
390
        if (stat (document->doc->filename, &stat_buf) != 0) {
 
391
                document->status = SPECTRE_STATUS_SAVE_ERROR;
 
392
                return;
 
393
        }
 
394
 
 
395
        from = fopen (document->doc->filename, "r");
 
396
        if (!from) {
 
397
                document->status = SPECTRE_STATUS_SAVE_ERROR;
 
398
                return;
 
399
        }
 
400
 
 
401
        to = fopen (filename, "w");
 
402
        if (!to) {
 
403
                document->status = SPECTRE_STATUS_SAVE_ERROR;
 
404
                fclose (from);
 
405
                return;
 
406
        }
 
407
 
 
408
        pscopy (from, to, document->doc, 0, stat_buf.st_size - 1);
 
409
 
 
410
        fclose (from);
 
411
        fclose (to);
 
412
 
 
413
        document->status = SPECTRE_STATUS_SUCCESS;
 
414
}
 
415
 
 
416
void
 
417
spectre_document_save_to_pdf (SpectreDocument *document,
 
418
                              const char      *filename)
 
419
{
 
420
        SpectreExporter *exporter;
 
421
        SpectreStatus    status;
 
422
        unsigned int     i;
 
423
 
 
424
        _spectre_return_if_fail (document != NULL);
 
425
        _spectre_return_if_fail (filename != NULL);
 
426
 
 
427
        if (!document->doc) {
 
428
                document->status = SPECTRE_STATUS_DOCUMENT_NOT_LOADED;
 
429
                return;
 
430
        }
 
431
 
 
432
        exporter = spectre_exporter_new (document, SPECTRE_EXPORTER_FORMAT_PDF);
 
433
        if (!exporter) {
 
434
                document->status = SPECTRE_STATUS_NO_MEMORY;
 
435
                return;
 
436
        }
 
437
 
 
438
        status = spectre_exporter_begin (exporter, filename);
 
439
        if (status) {
 
440
                document->status = status == SPECTRE_STATUS_NO_MEMORY ?
 
441
                        SPECTRE_STATUS_NO_MEMORY : SPECTRE_STATUS_SAVE_ERROR;
 
442
                spectre_exporter_free (exporter);
 
443
                return;
 
444
        }
 
445
 
 
446
        for (i = 0; i < spectre_document_get_n_pages (document); i++) {
 
447
                status = spectre_exporter_do_page (exporter, i);
 
448
                if (status)
 
449
                        break;
 
450
        }
 
451
 
 
452
        if (status) {
 
453
                document->status = status == SPECTRE_STATUS_NO_MEMORY ?
 
454
                        SPECTRE_STATUS_NO_MEMORY : SPECTRE_STATUS_SAVE_ERROR;
 
455
                spectre_exporter_free (exporter);
 
456
                return;
 
457
        }
 
458
                
 
459
        status = spectre_exporter_end (exporter);
 
460
        spectre_exporter_free (exporter);
 
461
 
 
462
        if (status) {
 
463
                document->status = status == SPECTRE_STATUS_NO_MEMORY ?
 
464
                        SPECTRE_STATUS_NO_MEMORY : SPECTRE_STATUS_SAVE_ERROR;
 
465
        } else {
 
466
                document->status = SPECTRE_STATUS_SUCCESS;
 
467
        }
 
468
}
 
469
 
 
470
struct document *
 
471
_spectre_document_get_doc (SpectreDocument *document)
 
472
{
 
473
        return document->doc;
 
474
}