summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/pdf-input.cpp
diff options
context:
space:
mode:
authorAdib Taraben <theadib@gmail.com>2014-06-06 21:56:26 +0000
committertheAdib <theadib@gmail.com>2014-06-06 21:56:26 +0000
commit67668ace6f9afe7861fe220a7a2f1c28fd7e22d0 (patch)
tree5fce4e03db2cb598cc507878f16771298a3e4b76 /src/extension/internal/pdfinput/pdf-input.cpp
parentMake family-name comparisons case insensitive. (diff)
downloadinkscape-67668ace6f9afe7861fe220a7a2f1c28fd7e22d0.tar.gz
inkscape-67668ace6f9afe7861fe220a7a2f1c28fd7e22d0.zip
merge pdf import via poppler-cairo into native importer
(bzr r13409)
Diffstat (limited to 'src/extension/internal/pdfinput/pdf-input.cpp')
-rw-r--r--src/extension/internal/pdfinput/pdf-input.cpp233
1 files changed, 171 insertions, 62 deletions
diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp
index 3155ac098..63581bd8a 100644
--- a/src/extension/internal/pdfinput/pdf-input.cpp
+++ b/src/extension/internal/pdfinput/pdf-input.cpp
@@ -124,6 +124,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_labelPrecision = Gtk::manage(new class Gtk::Label(_("Precision of approximating gradient meshes:")));
_labelPrecisionWarning = Gtk::manage(new class Gtk::Label(_("<b>Note</b>: setting the precision too high may result in a large SVG file and slow performance.")));
+#ifdef HAVE_POPPLER_CAIRO
+ _importviaPopplerCheck = Gtk::manage(new class Gtk::CheckButton(_("import via Poppler")));
+#endif
#if WITH_GTKMM_3_0
_fallbackPrecisionSlider_adj = Gtk::Adjustment::create(2, 1, 256, 1, 10, 10);
_fallbackPrecisionSlider = Gtk::manage(new class Gtk::Scale(_fallbackPrecisionSlider_adj));
@@ -199,6 +202,12 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_labelPrecisionWarning->set_line_wrap(true);
_labelPrecisionWarning->set_use_markup(true);
_labelPrecisionWarning->set_selectable(false);
+#ifdef HAVE_POPPLER_CAIRO
+ _importviaPopplerCheck->set_can_focus();
+ _importviaPopplerCheck->set_relief(Gtk::RELIEF_NORMAL);
+ _importviaPopplerCheck->set_mode(true);
+ _importviaPopplerCheck->set_active(false);
+#endif
_fallbackPrecisionSlider->set_size_request(180,-1);
_fallbackPrecisionSlider->set_can_focus();
_fallbackPrecisionSlider->set_inverted(false);
@@ -230,6 +239,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL);
_embedImagesCheck->set_mode(true);
_embedImagesCheck->set_active(true);
+#ifdef HAVE_POPPLER_CAIRO
+ vbox3->pack_start(*_importviaPopplerCheck, Gtk::PACK_SHRINK, 0);
+#endif
vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 0);
vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0);
vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0);
@@ -274,6 +286,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/)
_pageSettingsFrame->show();
_labelPrecision->show();
_labelPrecisionWarning->show();
+#ifdef HAVE_POPPLER_CAIRO
+ _importviaPopplerCheck->show();
+#endif
_fallbackPrecisionSlider->show();
_labelPrecisionComment->show();
hbox6->show();
@@ -358,6 +373,14 @@ int PdfImportDialog::getSelectedPage() {
return _current_page;
}
+int PdfImportDialog::getImportMethod() {
+#ifdef HAVE_POPPLER_CAIRO
+ return (_importviaPopplerCheck->get_active()) ? 1 : 0;
+#else
+ return 0;
+#endif
+}
+
/**
* \brief Retrieves the current settings into a repr which SvgBuilder will use
* for determining the behaviour desired by the user
@@ -389,6 +412,13 @@ void PdfImportDialog::getImportSettings(Inkscape::XML::Node *prefs) {
} else {
prefs->setAttribute("embedImages", "0");
}
+#ifdef HAVE_POPPLER_CAIRO
+ if (_importviaPopplerCheck->get_active()) {
+ prefs->setAttribute("importviapoppler", "1");
+ } else {
+ prefs->setAttribute("importviapoppler", "0");
+ }
+#endif
}
/**
@@ -595,6 +625,18 @@ PdfInput::wasCancelled () {
return _cancelled;
}
+#ifdef HAVE_POPPLER_CAIRO
+/// helper method
+static cairo_status_t
+ _write_ustring_cb(void *closure, const unsigned char *data, unsigned int length)
+{
+ Glib::ustring* stream = static_cast<Glib::ustring*>(closure);
+ stream->append(reinterpret_cast<const char*>(data), length);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+#endif
+
/**
* Parses the selected page of the given PDF document using PdfParser.
*/
@@ -672,79 +714,146 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) {
page_num = 1;
Catalog *catalog = pdf_doc->getCatalog();
Page *page = catalog->getPage(page_num);
+
+ int is_importvia_poppler = 0;
+ if(dlg)
+ {
+#ifdef HAVE_POPPLER_CAIRO
+ is_importvia_poppler = dlg->getImportMethod();
+#endif
+ }
- SPDocument *doc = SPDocument::createNewDoc(NULL, TRUE, TRUE);
- bool saved = DocumentUndo::getUndoSensitive(doc);
- DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document
+ SPDocument *doc = NULL;
+ bool saved = false;
+ if(is_importvia_poppler == 0)
+ {
+ // native importer
+ doc = SPDocument::createNewDoc(NULL, TRUE, TRUE);
+ saved = DocumentUndo::getUndoSensitive(doc);
+ DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document
+
+ // Create builder
+ 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());
+
+ // Get preferences
+ Inkscape::XML::Node *prefs = builder->getPreferences();
+ if (dlg)
+ dlg->getImportSettings(prefs);
+
+ printf("pdf import via %s.", (is_importvia_poppler != 0) ? "poppler" : "native");
+
+ // Apply crop settings
+ PDFRectangle *clipToBox = NULL;
+ double crop_setting;
+ sp_repr_get_double(prefs, "cropTo", &crop_setting);
+ if ( crop_setting >= 0.0 ) { // Do page clipping
+ int crop_choice = (int)crop_setting;
+ switch (crop_choice) {
+ case 0: // Media box
+ clipToBox = page->getMediaBox();
+ break;
+ case 1: // Crop box
+ clipToBox = page->getCropBox();
+ break;
+ case 2: // Bleed box
+ clipToBox = page->getBleedBox();
+ break;
+ case 3: // Trim box
+ clipToBox = page->getTrimBox();
+ break;
+ case 4: // Art box
+ clipToBox = page->getArtBox();
+ break;
+ default:
+ break;
+ }
+ }
- // Create builder
- 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());
+ // Create parser
+ PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(),
+ page->getResourceDict(), page->getCropBox(), clipToBox);
- // Get preferences
- Inkscape::XML::Node *prefs = builder->getPreferences();
- if (dlg)
- dlg->getImportSettings(prefs);
-
- // Apply crop settings
- PDFRectangle *clipToBox = NULL;
- double crop_setting;
- sp_repr_get_double(prefs, "cropTo", &crop_setting);
- if ( crop_setting >= 0.0 ) { // Do page clipping
- int crop_choice = (int)crop_setting;
- switch (crop_choice) {
- case 0: // Media box
- clipToBox = page->getMediaBox();
- break;
- case 1: // Crop box
- clipToBox = page->getCropBox();
- break;
- case 2: // Bleed box
- clipToBox = page->getBleedBox();
- break;
- case 3: // Trim box
- clipToBox = page->getTrimBox();
- break;
- case 4: // Art box
- clipToBox = page->getArtBox();
- break;
- default:
- break;
+ // Set up approximation precision for parser
+ double color_delta;
+ sp_repr_get_double(prefs, "approximationPrecision", &color_delta);
+ if ( color_delta <= 0.0 ) {
+ color_delta = 1.0 / 2.0;
+ } else {
+ color_delta = 1.0 / color_delta;
+ }
+ for ( int i = 1 ; i <= pdfNumShadingTypes ; i++ ) {
+ pdf_parser->setApproximationPrecision(i, color_delta, 6);
}
- }
- // Create parser
- PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(),
- page->getResourceDict(), page->getCropBox(), clipToBox);
+ // Parse the document structure
+ Object obj;
+ page->getContents(&obj);
+ if (!obj.isNull()) {
+ pdf_parser->parse(&obj);
+ }
- // Set up approximation precision for parser
- double color_delta;
- sp_repr_get_double(prefs, "approximationPrecision", &color_delta);
- if ( color_delta <= 0.0 ) {
- color_delta = 1.0 / 2.0;
- } else {
- color_delta = 1.0 / color_delta;
- }
- for ( int i = 1 ; i <= pdfNumShadingTypes ; i++ ) {
- pdf_parser->setApproximationPrecision(i, color_delta, 6);
+ // Cleanup
+ obj.free();
+ delete pdf_parser;
+ delete builder;
+ g_free(docname);
}
+ else
+ {
+#ifdef HAVE_POPPLER_CAIRO
+ // the poppler import
+ gchar* filename_uri = g_filename_to_uri(uri, NULL, NULL);
+ GError *error = NULL;
+ /// @todo handle passwort
+ /// @todo check if win32 unicode needs special attention
+ PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, &error);
+
+ if(error != NULL) {
+ g_error_free (error);
+ }
- // Parse the document structure
- Object obj;
- page->getContents(&obj);
- if (!obj.isNull()) {
- pdf_parser->parse(&obj);
+ if (document != NULL)
+ {
+ double width, height;
+ PopplerPage* page = poppler_document_get_page(document, page_num - 1);
+ poppler_page_get_size(page, &width, &height);
+
+ Glib::ustring output;
+ cairo_surface_t* surface = cairo_svg_surface_create_for_stream(Inkscape::Extension::Internal::_write_ustring_cb,
+ &output, width, height);
+ cairo_t* cr = cairo_create(surface);
+
+ poppler_page_render_for_printing(page, cr);
+ cairo_show_page(cr);
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+ doc = SPDocument::createNewDocFromMem(output.c_str(), output.length(), TRUE);
+
+ // Cleanup
+ // delete output;
+ g_object_unref(G_OBJECT(page));
+ g_object_unref(G_OBJECT(document));
+ }
+ else
+ {
+ doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); // fallback create empthy document
+ }
+ saved = DocumentUndo::getUndoSensitive(doc);
+ DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document
+
+ // Cleanup
+ g_free(filename_uri);
+#endif
}
// Cleanup
- obj.free();
- delete pdf_parser;
- delete builder;
- g_free(docname);
delete pdf_doc;
delete dlg;