diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-11-23 23:36:49 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-11-23 23:36:49 +0000 |
| commit | 0969085ddf607a7a98cf7fd6d9b10da5fbebe62d (patch) | |
| tree | 59b2bc9ed3412ab2de4c703ef30342dfe2401704 /src/extension/internal/pdfinput/pdf-input.cpp | |
| parent | refactor from lastApplied (diff) | |
| parent | Fixed a bug pointed by suv running from comand line, also removed another des... (diff) | |
| download | inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.tar.gz inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.zip | |
fixing to trunk
(bzr r12588.1.34)
Diffstat (limited to 'src/extension/internal/pdfinput/pdf-input.cpp')
| -rw-r--r-- | src/extension/internal/pdfinput/pdf-input.cpp | 259 |
1 files changed, 196 insertions, 63 deletions
diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 3155ac098..c8a7feabf 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -48,7 +48,7 @@ #include "inkscape.h" #include "util/units.h" -#include "dialogs/dialog-events.h" +#include "ui/dialog-events.h" #include <gtk/gtk.h> #include "ui/widget/spinbutton.h" #include "ui/widget/frame.h" @@ -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. */ @@ -605,7 +647,31 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { // Initialize the globalParams variable for poppler if (!globalParams) { +#ifdef ENABLE_OSX_APP_LOCATIONS + // + // data files for poppler are not relocatable (loaded from + // path defined at build time). This fails to work with relocatable + // application bundles for OS X. + // + // Workaround: + // 1. define $POPPLER_DATADIR env variable in app launcher script + // 2. pass custom $POPPLER_DATADIR via poppler's GlobalParams() + // + // relevant poppler commit: + // <http://cgit.freedesktop.org/poppler/poppler/commit/?id=869584a84eed507775ff1c3183fe484c14b6f77b> + // + // FIXES: Inkscape bug #956282, #1264793 + // TODO: report RFE upstream (full relocation support for OS X packaging) + // + gchar const *poppler_datadir = g_getenv("POPPLER_DATADIR"); + if (poppler_datadir != NULL) { + globalParams = new GlobalParams(poppler_datadir); + } else { + globalParams = new GlobalParams(); + } +#else globalParams = new GlobalParams(); +#endif // ENABLE_OSX_APP_LOCATIONS } // poppler does not use glib g_open. So on win32 we must use unicode call. code was copied from glib gstdio.c #ifndef WIN32 @@ -672,79 +738,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; |
