From cb814cb0df20053ca3ef16ce55da474435daf045 Mon Sep 17 00:00:00 2001 From: miklosh Date: Sun, 19 Aug 2007 12:50:15 +0000 Subject: [PATCH] Added a PDF import settings dialog --- src/extension/internal/pdfinput/pdf-input.cpp | 499 +++++++++++++++++- src/extension/internal/pdfinput/pdf-input.h | 77 +++ .../internal/pdfinput/svg-builder.cpp | 11 +- src/extension/internal/pdfinput/svg-builder.h | 4 + 4 files changed, 585 insertions(+), 6 deletions(-) diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 47057cccf..75940ff56 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -31,12 +31,451 @@ #include "document-private.h" +#include + namespace Inkscape { namespace Extension { namespace Internal { /** - * Parses the first page of the given PDF document using PdfParser. + * \brief The PDF import dialog + * FIXME: Probably this should be placed into src/ui/dialog + */ + +static Glib::ustring crop_setting_choices[] = { + Glib::ustring(_("media box")), + Glib::ustring(_("crop box")), + Glib::ustring(_("trim box")), + Glib::ustring(_("bleed box")), + Glib::ustring(_("art box")) +}; + +PdfImportDialog::PdfImportDialog(PDFDoc *doc) +{ + + _pdf_doc = doc; + + cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); + okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); + _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); + + // Page number + Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage( + new class Gtk::Adjustment(1, 1, _pdf_doc->getNumPages(), 1, 10, 0)); + _pageNumberSpin = Gtk::manage(new class Gtk::SpinButton(*_pageNumberSpin_adj, 1, 1)); + hbox2 = Gtk::manage(new class Gtk::HBox(false, 0)); + + // Crop settings + _cropCheck = Gtk::manage(new class Gtk::CheckButton(_("Crop to:"))); + _cropTypeCombo = Gtk::manage(new class Gtk::ComboBoxText()); + int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); + for ( int i = 0 ; i < num_crop_choices ; i++ ) { + _cropTypeCombo->append_text(crop_setting_choices[i]); + } + _cropTypeCombo->set_active_text(crop_setting_choices[0]); + _cropTypeCombo->set_sensitive(false); + + hbox3 = Gtk::manage(new class Gtk::HBox(false, 0)); + vbox2 = Gtk::manage(new class Gtk::VBox(false, 0)); + alignment3 = Gtk::manage(new class Gtk::Alignment(0.5, 0.5, 1, 1)); + _labelPageSettings = Gtk::manage(new class Gtk::Label(_("Page Settings"))); + _pageSettingsFrame = Gtk::manage(new class Gtk::Frame()); + _labelPrecision = Gtk::manage(new class Gtk::Label(_("Precision of approximation for gradient meshes:"))); + + _fallbackPrecisionSlider_adj = Gtk::manage(new class Gtk::Adjustment(2, 1, 256, 1, 10, 10)); + _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(*_fallbackPrecisionSlider_adj)); + _fallbackPrecisionSlider->set_value(2.0); + _labelPrecisionComment = Gtk::manage(new class Gtk::Label(_("rough"))); + hbox6 = Gtk::manage(new class Gtk::HBox(false, 0)); + + // Text options + _labelText = Gtk::manage(new class Gtk::Label(_("Text handling:"))); + _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText()); + _textHandlingCombo->append_text(_("import text as text")); + _textHandlingCombo->set_active_text(_("import text as text")); + + hbox5 = Gtk::manage(new class Gtk::HBox(false, 0)); + _embedImagesCheck = Gtk::manage(new class Gtk::CheckButton(_("Embed images"))); + vbox3 = Gtk::manage(new class Gtk::VBox(false, 0)); + alignment4 = Gtk::manage(new class Gtk::Alignment(0.5, 0.5, 1, 1)); + _labelImportSettings = Gtk::manage(new class Gtk::Label(_("Import Settings"))); + _importSettingsFrame = Gtk::manage(new class Gtk::Frame()); + vbox1 = Gtk::manage(new class Gtk::VBox(false, 0)); + _previewArea = Gtk::manage(new class Gtk::DrawingArea()); + hbox1 = Gtk::manage(new class Gtk::HBox(false, 0)); + cancelbutton->set_flags(Gtk::CAN_FOCUS); + cancelbutton->set_flags(Gtk::CAN_DEFAULT); + cancelbutton->set_relief(Gtk::RELIEF_NORMAL); + okbutton->set_flags(Gtk::CAN_FOCUS); + okbutton->set_flags(Gtk::CAN_DEFAULT); + okbutton->set_relief(Gtk::RELIEF_NORMAL); + this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); + _labelSelect->set_alignment(0.5,0.5); + _labelSelect->set_padding(0,0); + _labelSelect->set_justify(Gtk::JUSTIFY_LEFT); + _labelSelect->set_line_wrap(false); + _labelSelect->set_use_markup(false); + _labelSelect->set_selectable(false); + _pageNumberSpin->set_flags(Gtk::CAN_FOCUS); + _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); + _pageNumberSpin->set_numeric(true); + _pageNumberSpin->set_digits(0); + _pageNumberSpin->set_wrap(false); + hbox2->pack_start(*_labelSelect, Gtk::PACK_SHRINK, 0); + hbox2->pack_start(*_pageNumberSpin, Gtk::PACK_SHRINK, 4); + _cropCheck->set_flags(Gtk::CAN_FOCUS); + _cropCheck->set_relief(Gtk::RELIEF_NORMAL); + _cropCheck->set_mode(true); + _cropCheck->set_active(false); + _cropTypeCombo->set_border_width(1); + hbox3->pack_start(*_cropCheck, Gtk::PACK_SHRINK, 0); + hbox3->pack_start(*_cropTypeCombo, Gtk::PACK_SHRINK, 4); + vbox2->pack_start(*hbox2); + vbox2->pack_start(*hbox3); + alignment3->add(*vbox2); + _labelPageSettings->set_alignment(0.5,0.5); + _labelPageSettings->set_padding(0,0); + _labelPageSettings->set_justify(Gtk::JUSTIFY_LEFT); + _labelPageSettings->set_line_wrap(false); + _labelPageSettings->set_use_markup(true); + _labelPageSettings->set_selectable(false); + _pageSettingsFrame->set_border_width(4); + _pageSettingsFrame->set_shadow_type(Gtk::SHADOW_ETCHED_IN); + _pageSettingsFrame->set_label_align(0,0.5); + _pageSettingsFrame->add(*alignment3); + _pageSettingsFrame->set_label_widget(*_labelPageSettings); + _labelPrecision->set_alignment(0.5,0.5); + _labelPrecision->set_padding(0,0); + _labelPrecision->set_justify(Gtk::JUSTIFY_LEFT); + _labelPrecision->set_line_wrap(false); + _labelPrecision->set_use_markup(false); + _labelPrecision->set_selectable(false); + _fallbackPrecisionSlider->set_size_request(180,-1); + _fallbackPrecisionSlider->set_flags(Gtk::CAN_FOCUS); + _fallbackPrecisionSlider->set_update_policy(Gtk::UPDATE_CONTINUOUS); + _fallbackPrecisionSlider->set_inverted(false); + _fallbackPrecisionSlider->set_digits(1); + _fallbackPrecisionSlider->set_draw_value(true); + _fallbackPrecisionSlider->set_value_pos(Gtk::POS_TOP); + _labelPrecisionComment->set_size_request(90,-1); + _labelPrecisionComment->set_alignment(0.5,0.5); + _labelPrecisionComment->set_padding(0,0); + _labelPrecisionComment->set_justify(Gtk::JUSTIFY_LEFT); + _labelPrecisionComment->set_line_wrap(false); + _labelPrecisionComment->set_use_markup(false); + _labelPrecisionComment->set_selectable(false); + hbox6->pack_start(*_fallbackPrecisionSlider, Gtk::PACK_SHRINK, 4); + hbox6->pack_start(*_labelPrecisionComment, Gtk::PACK_SHRINK, 4); + _labelText->set_alignment(0.5,0.5); + _labelText->set_padding(0,0); + _labelText->set_justify(Gtk::JUSTIFY_LEFT); + _labelText->set_line_wrap(false); + _labelText->set_use_markup(false); + _labelText->set_selectable(false); + hbox5->pack_start(*_labelText, Gtk::PACK_SHRINK, 0); + hbox5->pack_start(*_textHandlingCombo, Gtk::PACK_SHRINK, 0); + _embedImagesCheck->set_flags(Gtk::CAN_FOCUS); + _embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL); + _embedImagesCheck->set_mode(true); + _embedImagesCheck->set_active(true); + vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 4); + vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0); + vbox3->pack_start(*hbox5); + vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0); + alignment4->add(*vbox3); + _labelImportSettings->set_alignment(0.5,0.5); + _labelImportSettings->set_padding(0,0); + _labelImportSettings->set_justify(Gtk::JUSTIFY_LEFT); + _labelImportSettings->set_line_wrap(false); + _labelImportSettings->set_use_markup(true); + _labelImportSettings->set_selectable(false); + _importSettingsFrame->set_border_width(4); + _importSettingsFrame->set_shadow_type(Gtk::SHADOW_ETCHED_IN); + _importSettingsFrame->set_label_align(0,0.5); + _importSettingsFrame->add(*alignment4); + _importSettingsFrame->set_label_widget(*_labelImportSettings); + vbox1->pack_start(*_pageSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); + vbox1->pack_start(*_importSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); + hbox1->pack_start(*vbox1); + hbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 4); + this->get_vbox()->set_homogeneous(false); + this->get_vbox()->set_spacing(0); + this->get_vbox()->pack_start(*hbox1); + this->set_title(_("PDF Import Settings")); + this->set_modal(true); + this->property_window_position().set_value(Gtk::WIN_POS_NONE); + this->set_resizable(true); + this->property_destroy_with_parent().set_value(false); + this->set_has_separator(true); + this->add_action_widget(*cancelbutton, -6); + this->add_action_widget(*okbutton, -5); + cancelbutton->show(); + okbutton->show(); + _labelSelect->show(); + _pageNumberSpin->show(); + hbox2->show(); + _cropCheck->show(); + _cropTypeCombo->show(); + hbox3->show(); + vbox2->show(); + alignment3->show(); + _labelPageSettings->show(); + _pageSettingsFrame->show(); + _labelPrecision->show(); + _fallbackPrecisionSlider->show(); + _labelPrecisionComment->show(); + hbox6->show(); + _labelText->show(); + _textHandlingCombo->show(); + hbox5->show(); + _embedImagesCheck->show(); + vbox3->show(); + alignment4->show(); + _labelImportSettings->show(); + _importSettingsFrame->show(); + vbox1->show(); + _previewArea->show(); + hbox1->show(); + + // Connect signals + _previewArea->signal_expose_event().connect(sigc::mem_fun(*this, &PdfImportDialog::_onExposePreview)); + _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportDialog::_onPageNumberChanged)); + _cropCheck->signal_toggled().connect(sigc::mem_fun(*this, &PdfImportDialog::_onToggleCropping)); + _fallbackPrecisionSlider_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportDialog::_onPrecisionChanged)); + + // Create an OutputDev + _preview_output_dev = new CairoOutputDev(); + _preview_output_dev->startDoc(_pdf_doc->getXRef()); + + // Set default preview size + _preview_width = 200; + _preview_height = 300; + + // Init preview + _thumb_data = NULL; + _cairo_surface = NULL; + _pageNumberSpin_adj->set_value(1.0); +} + +PdfImportDialog::~PdfImportDialog() { + if (_preview_output_dev) { + delete _preview_output_dev; + } + if (_cairo_surface) { + cairo_surface_destroy(_cairo_surface); + } + if (_thumb_data) { + delete _thumb_data; + } +} + +bool PdfImportDialog::showDialog() { + show(); + gint b = run(); + hide(); + if ( b == Gtk::RESPONSE_OK ) { + return TRUE; + } else { + return FALSE; + } +} + +int PdfImportDialog::getSelectedPage() { + return _current_page; +} + +/** + * \brief Retrieves the current settings into a repr which SvgBuilder will use + * for determining the behaviour desired by the user + */ +void PdfImportDialog::getImportSettings(Inkscape::XML::Node *prefs) { + sp_repr_set_svg_double(prefs, "selectedPage", (double)_current_page); + if (_cropCheck->get_active()) { + Glib::ustring current_choice = _cropTypeCombo->get_active_text(); + int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); + int i = 0; + for ( ; i < num_crop_choices ; i++ ) { + if ( current_choice == crop_setting_choices[i] ) { + break; + } + } + sp_repr_set_svg_double(prefs, "cropTo", (double)i); + } else { + sp_repr_set_svg_double(prefs, "cropTo", -1.0); + } + sp_repr_set_svg_double(prefs, "approximationPrecision", + _fallbackPrecisionSlider->get_value()); + if (_embedImagesCheck->get_active()) { + prefs->setAttribute("embedImages", "1"); + } else { + prefs->setAttribute("embedImages", "0"); + } +} + +/** + * \brief Redisplay the comment on the current approximation precision setting + * Evenly divides the interval of possible values between the available labels. + */ +void PdfImportDialog::_onPrecisionChanged() { + + static Glib::ustring precision_comments[] = { + Glib::ustring(_("rough")), + Glib::ustring(_("medium")), + Glib::ustring(_("fine")), + Glib::ustring(_("very fine")) + }; + + double min = _fallbackPrecisionSlider_adj->get_lower(); + double max = _fallbackPrecisionSlider_adj->get_upper(); + int num_intervals = sizeof(precision_comments) / sizeof(precision_comments[0]); + double interval_len = ( max - min ) / (double)num_intervals; + double value = _fallbackPrecisionSlider_adj->get_value(); + int comment_idx = (int)floor( ( value - min ) / interval_len ); + _labelPrecisionComment->set_label(precision_comments[comment_idx]); +} + +void PdfImportDialog::_onToggleCropping() { + _cropTypeCombo->set_sensitive(_cropCheck->get_active()); +} + +void PdfImportDialog::_onPageNumberChanged() { + int page = _pageNumberSpin->get_value_as_int(); + _current_page = CLAMP(page, 1, _pdf_doc->getCatalog()->getNumPages()); + _setPreviewPage(_current_page); +} + +/** + * \brief Copies image data from a Cairo surface to a pixbuf + * + * Borrowed from libpoppler, from the file poppler-page.cc + * Copyright (C) 2005, Red Hat, Inc. + * + */ +static void copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, + unsigned char *data, + GdkPixbuf *pixbuf) +{ + int cairo_width, cairo_height, cairo_rowstride; + unsigned char *pixbuf_data, *dst, *cairo_data; + int pixbuf_rowstride, pixbuf_n_channels; + unsigned int *src; + int x, y; + + cairo_width = cairo_image_surface_get_width (surface); + cairo_height = cairo_image_surface_get_height (surface); + cairo_rowstride = cairo_width * 4; + cairo_data = data; + + pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); + pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + if (cairo_width > gdk_pixbuf_get_width (pixbuf)) + cairo_width = gdk_pixbuf_get_width (pixbuf); + if (cairo_height > gdk_pixbuf_get_height (pixbuf)) + cairo_height = gdk_pixbuf_get_height (pixbuf); + for (y = 0; y < cairo_height; y++) + { + src = (unsigned int *) (cairo_data + y * cairo_rowstride); + dst = pixbuf_data + y * pixbuf_rowstride; + for (x = 0; x < cairo_width; x++) + { + dst[0] = (*src >> 16) & 0xff; + dst[1] = (*src >> 8) & 0xff; + dst[2] = (*src >> 0) & 0xff; + if (pixbuf_n_channels == 4) + dst[3] = (*src >> 24) & 0xff; + dst += pixbuf_n_channels; + src++; + } + } +} + +/** + * \brief Updates the preview area with the previously rendered thumbnail + */ +bool PdfImportDialog::_onExposePreview(GdkEventExpose *event) { + + Glib::RefPtr thumb = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, + 8, _thumb_width, _thumb_height); + // Set background to white + thumb->fill(0xffffffff); + Glib::RefPtr back_pixmap = Gdk::Pixmap::create(_previewArea->get_window(), + _thumb_width, _thumb_height, -1); + back_pixmap->draw_pixbuf(Glib::RefPtr(), thumb, 0, 0, 0, 0, + static_cast(_thumb_width), + static_cast(_thumb_height), + Gdk::RGB_DITHER_NONE, 0, 0); + _previewArea->get_window()->set_back_pixmap(back_pixmap, false); + _previewArea->get_window()->clear(); + // Copy the thumbnail image from the Cairo surface + copy_cairo_surface_to_pixbuf(_cairo_surface, _thumb_data, thumb->gobj()); + _previewArea->get_window()->draw_pixbuf(Glib::RefPtr(), thumb, + 0, 0, 0, 0, -1, -1, + Gdk::RGB_DITHER_NONE, 0, 0); + + return true; +} + +/** + * \brief Renders the given page's thumbnail using Cairo + */ +void PdfImportDialog::_setPreviewPage(int page) { + + _previewed_page = _pdf_doc->getCatalog()->getPage(page); + // TODO: When available, obtain the thumbnail from the PDF document itself + // Get page size by accounting for rotation + double width, height; + int rotate = _previewed_page->getRotate(); + if ( rotate == 90 || rotate == 270 ) { + height = _previewed_page->getCropWidth(); + width = _previewed_page->getCropHeight(); + } else { + width = _previewed_page->getCropWidth(); + height = _previewed_page->getCropHeight(); + } + // Calculate the needed scaling for the page + double scale_x = (double)_preview_width / width; + double scale_y = (double)_preview_height / height; + double scale_factor = ( scale_x > scale_y ) ? scale_y : scale_x; + // Create new Cairo surface + _thumb_width = (int)ceil( width * scale_factor ); + _thumb_height = (int)ceil( height * scale_factor ); + int rowstride = _thumb_width * 4; + if (_thumb_data) { + delete _thumb_data; + } + _thumb_data = new unsigned char[ rowstride * _thumb_height ]; + if (_cairo_surface) { + cairo_surface_destroy(_cairo_surface); + } + _cairo_surface = cairo_image_surface_create_for_data(_thumb_data, + CAIRO_FORMAT_ARGB32, _thumb_width, _thumb_height, rowstride); + cairo_t *cr = cairo_create(_cairo_surface); + cairo_scale(cr, scale_factor, scale_factor); // Use Cairo for resizing the image + _preview_output_dev->setCairo(cr); + // Render page + _previewed_page->displaySlice(_preview_output_dev, + 72.0, 72.0, 0, + FALSE, /* useMediaBox */ + TRUE, /* crop */ + 0, 0, + (int)ceil(_previewed_page->getCropWidth()), + (int)ceil(_previewed_page->getCropHeight()), + FALSE, /* printing */ + _pdf_doc->getCatalog()); + // Clean up + _preview_output_dev->setCairo(NULL); + cairo_destroy(cr); + // Redraw preview area + _previewArea->set_size_request(_preview_width, _preview_height); + _previewArea->queue_draw(); +} + +//////////////////////////////////////////////////////////////////////////////// + +/** + * Parses the selected page of the given PDF document using PdfParser. */ SPDocument * PdfInput::open(::Inkscape::Extension::Input * mod, const gchar * uri) { @@ -58,9 +497,16 @@ PdfInput::open(::Inkscape::Extension::Input * mod, const gchar * uri) { return NULL; } + PdfImportDialog *dlg = new PdfImportDialog(pdf_doc); + if (!dlg->showDialog()) { + delete dlg; + delete pdf_doc; + + return NULL; + } // Get needed page - int page_num = 1; + int page_num = dlg->getSelectedPage(); Catalog *catalog = pdf_doc->getCatalog(); Page *page = catalog->getPage(page_num); @@ -68,16 +514,61 @@ PdfInput::open(::Inkscape::Extension::Input * mod, const gchar * uri) { 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 + // 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(); + 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; + } + } + + // Create parser PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(), - page->getResourceDict(), page->getCropBox()); + page->getResourceDict(), page->getCropBox(), clipToBox); + // 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); + } + // Parse the document structure Object obj; page->getContents(&obj); diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h index abbfc838e..b7d3de774 100644 --- a/src/extension/internal/pdfinput/pdf-input.h +++ b/src/extension/internal/pdfinput/pdf-input.h @@ -20,10 +20,87 @@ #include "../../implementation/implementation.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PDFDoc.h" +#include "CairoOutputDev.h" + namespace Inkscape { namespace Extension { namespace Internal { +class PdfImportDialog : public Gtk::Dialog +{ +public: + PdfImportDialog(PDFDoc *doc); + virtual ~PdfImportDialog(); + + bool showDialog(); + int getSelectedPage(); + void getImportSettings(Inkscape::XML::Node *prefs); + +private: + void _setPreviewPage(int page); + + // Signal handlers + bool _onExposePreview(GdkEventExpose *event); + void _onPageNumberChanged(); + void _onToggleCropping(); + void _onPrecisionChanged(); + + class Gtk::Button * cancelbutton; + class Gtk::Button * okbutton; + class Gtk::Label * _labelSelect; + class Gtk::SpinButton * _pageNumberSpin; + class Gtk::HBox * hbox2; + class Gtk::CheckButton * _cropCheck; + class Gtk::ComboBoxText * _cropTypeCombo; + class Gtk::HBox * hbox3; + class Gtk::VBox * vbox2; + class Gtk::Alignment * alignment3; + class Gtk::Label * _labelPageSettings; + class Gtk::Frame * _pageSettingsFrame; + class Gtk::Label * _labelPrecision; + class Gtk::HScale * _fallbackPrecisionSlider; + class Gtk::Adjustment *_fallbackPrecisionSlider_adj; + class Gtk::Label * _labelPrecisionComment; + class Gtk::HBox * hbox6; + class Gtk::Label * _labelText; + class Gtk::ComboBoxText * _textHandlingCombo; + class Gtk::HBox * hbox5; + class Gtk::CheckButton * _embedImagesCheck; + class Gtk::VBox * vbox3; + class Gtk::Alignment * alignment4; + class Gtk::Label * _labelImportSettings; + class Gtk::Frame * _importSettingsFrame; + class Gtk::VBox * vbox1; + class Gtk::DrawingArea * _previewArea; + class Gtk::HBox * hbox1; + + PDFDoc *_pdf_doc; // Document to be imported + int _current_page; // Current selected page + Page *_previewed_page; // Currently previewed page + unsigned char *_thumb_data; // Thumbnail image data + int _thumb_width, _thumb_height; // Thumbnail size + int _preview_width, _preview_height; // Size of the preview area + cairo_surface_t *_cairo_surface; + CairoOutputDev *_preview_output_dev; +}; + + class PdfInput: public Inkscape::Extension::Implementation::Implementation { PdfInput () { }; public: diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 14f9c6102..7f801d4b4 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -84,6 +84,10 @@ SvgBuilder::SvgBuilder(SPDocument *document, gchar *docname, XRef *xref) { _container = _root = _doc->rroot; _root->setAttribute("xml:space", "preserve"); _init(); + + // Set default preference settings + _preferences = _xml_doc->createElement("svgbuilder:prefs"); + _preferences->setAttribute("embedImages", "1"); } SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) { @@ -92,6 +96,7 @@ SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) { _docname = parent->_docname; _xref = parent->_xref; _xml_doc = parent->_xml_doc; + _preferences = parent->_preferences; _container = this->_root = root; _init(); } @@ -1329,13 +1334,15 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height png_destroy_write_struct(&png_ptr, &info_ptr); return NULL; } - + // Decide whether we should embed this image + double attr_value = 1.0; + sp_repr_get_double(_preferences, "embedImages", &attr_value); + bool embed_image = ( attr_value != 0.0 ); // Set read/write functions Inkscape::IO::StringOutputStream base64_string; Inkscape::IO::Base64OutputStream base64_stream(base64_string); FILE *fp; gchar *file_name; - bool embed_image = true; if (embed_image) { base64_stream.setColumnWidth(0); // Disable line breaks png_set_write_fn(png_ptr, &base64_stream, png_write_base64stream, png_flush_base64stream); diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index 9298884a1..96525ba2b 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -103,6 +103,9 @@ public: void setDocumentSize(double width, double height); // Document size in px void setAsLayer(char *layer_name=NULL); void setGroupOpacity(double opacity); + Inkscape::XML::Node *getPreferences() { + return _preferences; + } // Handling the node stack Inkscape::XML::Node *pushGroup(); @@ -220,6 +223,7 @@ private: Inkscape::XML::Document *_xml_doc; Inkscape::XML::Node *_root; // Root node from the point of view of this SvgBuilder Inkscape::XML::Node *_container; // Current container (group/pattern/mask) + Inkscape::XML::Node *_preferences; // Preferences container node double _width, _height; // Document size in px }; -- 2.30.2