summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/pdf-input.cpp
blob: b9e616025c95a54e2c48f91bee764996a9931032 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
 /** \file
 * Native PDF import using libpoppler.
 * 
 * Authors:
 *   miklos erdelyi
 *
 * Copyright (C) 2007 Authors
 *
 * Released under GNU GPL, read the file 'COPYING' for more information
 *
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#ifdef HAVE_POPPLER

#include "goo/GooString.h"
#include "ErrorCodes.h"
#include "GlobalParams.h"
#include "PDFDoc.h"
#include "Page.h"
#include "Catalog.h"

#include "pdf-input.h"
#include "extension/system.h"
#include "extension/input.h"
#include "svg-builder.h"
#include "pdf-parser.h"

#include "document-private.h"

namespace Inkscape {
namespace Extension {
namespace Internal {

/**
 * Parses the first page of the given PDF document using PdfParser.
 */
SPDocument *
PdfInput::open(::Inkscape::Extension::Input * mod, const gchar * uri) {

    // Initialize the globalParams variable for poppler
    if (!globalParams) {
        globalParams = new GlobalParams();
        g_message("Created globalParams");
    }
    GooString *filename_goo = new GooString(uri);
    PDFDoc *pdf_doc = new PDFDoc(filename_goo, NULL, NULL, NULL);   // TODO: Could ask for password
    if (!pdf_doc->isOk()) {
        int error = pdf_doc->getErrorCode();
        delete pdf_doc;
        if (error == errEncrypted) {
            g_message("Document is encrypted.");
        } else {
            g_message("Failed to load document from data (error %d)", error);
        }
 
        return NULL;
    }

    // Get needed page
    int page_num = 1;
    Catalog *catalog = pdf_doc->getCatalog();
    Page *page = catalog->getPage(page_num);

    double width, height;
    int rotate = page->getRotate();
    if (rotate == 90 || rotate == 270)  {
        width = page->getCropHeight();
        height = page->getCropWidth();
    } else {
        width = page->getCropWidth();
        height = page->getCropHeight();
    }
    
    SPDocument *doc = sp_document_new(NULL, TRUE, TRUE);
    bool saved = sp_document_get_undo_sensitive(doc);
    sp_document_set_undo_sensitive(doc, false); // No need to undo in this temporary document

    // Create builder and parser
    SvgBuilder *builder = new SvgBuilder(doc);
    PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1,
                                          page->getResourceDict(), page->getCropBox());

    // Parse the document structure
    Object obj;
    page->getContents(&obj);
    if (!obj.isNull()) {
        pdf_parser->saveState();
        pdf_parser->parse(&obj);
        pdf_parser->restoreState();
    }
    
    // Cleanup
    obj.free();
    delete pdf_parser;
    delete builder;

    // Restore undo
    sp_document_set_undo_sensitive(doc, saved);

    return doc;
}

#include "../clear-n_.h"

void
PdfInput::init(void) {
    Inkscape::Extension::Extension * ext;

    ext = Inkscape::Extension::build_from_mem(
        "<inkscape-extension>\n"
            "<name>PDF Input</name>\n"
            "<id>org.inkscape.input.pdf</id>\n"
            "<input>\n"
                "<extension>.pdf</extension>\n"
                "<mimetype>application/pdf</mimetype>\n"
                "<filetypename>Adobe PDF (*.pdf) [native]</filetypename>\n"
                "<filetypetooltip>PDF Document</filetypetooltip>\n"
            "</input>\n"
        "</inkscape-extension>", new PdfInput());
} // init

} } }  /* namespace Inkscape, Extension, Implementation */

#endif /* HAVE_POPPLER */

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :