summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/pdf-input.cpp
blob: 47057cccf09584c8f777f9701a439cea33466ebb (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
140
141
142
143
144
145
146
147
 /** \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();
    }
    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);

    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
    gchar *docname = g_path_get_basename(uri);
    gchar *dot = g_strrstr(docname, ".");
    if (dot) {
        *dot = 0;
    }
    SvgBuilder *builder = new SvgBuilder(doc, docname, pdf_doc->getXRef());
    PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(),
                                          page->getResourceDict(), page->getCropBox());

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

    // Restore undo
    sp_document_set_undo_sensitive(doc, saved);

    return doc;
}

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

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

    /* PDF in */
    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) [via poppler]</filetypename>\n"
                "<filetypetooltip>Adobe Portable Document Format</filetypetooltip>\n"
            "</input>\n"
        "</inkscape-extension>", new PdfInput());

    /* AI in */
    ext = Inkscape::Extension::build_from_mem(
        "<inkscape-extension>\n"
            "<name>AI Input</name>\n"
            "<id>org.inkscape.input.ai</id>\n"
            "<input>\n"
                "<extension>.ai</extension>\n"
                "<mimetype>image/x-adobe-illustrator</mimetype>\n"
                "<filetypename>Adobe Illustrator (*.ai) [PDF-based]</filetypename>\n"
                "<filetypetooltip>Open files saved with recent versions of Adobe Illustrator</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 :